1 /* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
3 * Conky, a system monitor, based on torsmo
5 * Any original torsmo code is licensed under the BSD license
7 * All code written since the fork of torsmo is licensed under the GPL
9 * Please see COPYING for details
11 * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
12 * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
14 * All rights reserved.
16 * This program is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33 #include "text_object.h"
37 unsigned int show;//length of scrolling field in # of characters requested by conf file
39 unsigned int start;//current position of first letter of text?
40 unsigned int junk;//to keep track of any padding we add
44 void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_crash)
46 struct scroll_data *sd;
49 sd = malloc(sizeof(struct scroll_data));
50 memset(sd, 0, sizeof(struct scroll_data));
52 sd->resetcolor = get_current_text_color();
54 if (!arg || sscanf(arg, "%u %n", &sd->show, &n1) <= 0)//get 1st arg: show = field length; n1 = number of bytes read from the input so far by this call
55 CRIT_ERR(obj, free_at_crash, "scroll needs arguments: <length> [<step>] <text>");
57 sscanf(arg + n1, "%u %n", &sd->step, &n2);//gets step size; n2 is bytes of data required to store that
58 if (*(arg + n1 + n2)) {//trying to read the first byte of text to scroll, i wonder what happens if it's a zero?
59 n1 += n2;//n1 is now total bytes of all args read, or the number of bytes to skip if you want the text from arg
61 sd->step = 1;//default step size is 1 if it wasn't specified, although that was set above anyways.
63 sd->text = malloc(strlen(arg + n1) + sd->show + 1);//changes the text pointer to point to an array of 2x text + 1;
65 //i think it's trying to check if there is more text to display than space to fit it.
66 // if (strlen(arg) > sd->show) {//if the total text and parameters is more than the size to display just the text? why aren't we subtracting n1 from the left side?
68 if (strlen(arg + n1) > sd->show) {//better, we need to skip past the parameters
69 for(n2 = 0; (unsigned int) n2 < sd->show; n2++) {//i guess this would clear half of the array starting at the beginning, if it was set to 2 x text as above lame code does
70 sd->text[n2] = ' ';//here we are padding spaces that end up BEFORE the text.
73 sd->text[n2] = 0;//terminates the string
76 sd->text[0] = 0;//empty string, strcat probably explodes if you don't do this
78 strcat(sd->text, arg + n1);//copies only the text into sd.text, appending to any existing blank space.
80 obj->sub = malloc(sizeof(struct text_object));
81 extract_variable_text_internal(obj->sub, sd->text);
83 obj->data.opaque = sd;
86 void print_scroll(struct text_object *obj, char *p, int p_max_size, struct information *cur)
88 struct scroll_data *sd = obj->data.opaque;
89 unsigned int j, colorchanges = 0, frontcolorchanges = 0, visibcolorchanges = 0, strend;
91 char buf[max_user_text];
96 generate_text_internal(buf, max_user_text, *obj->sub, cur);
97 for(j = 0; buf[j] != 0; j++) {
99 case '\n': //place all the lines behind each other with LINESEPARATOR between them
100 #define LINESEPARATOR '|'
101 buf[j]=LINESEPARATOR;
108 //(r)trim any incoming strings. some functions might return data with extra spaces on the end...
114 (k=len-1;k>=0&&buf[k]==' ';k--)
118 //count left padding but don't trim it because it's potentially needed for scrolling... (i commented this out because probably the only spaces on the front of the string
119 //will be ours that we added above, should be more efficient to just keep track of those. but maybe this will be useful some day so i've left it here.
121 // while (buf[k]==' ') {
126 //no scrolling necessary if the length of the text to scroll is shorter than the requested space from the conf
127 //if (strlen(buf) - colorchanges <= sd->show) {
128 if (strlen(buf) - junk - sd->junk - colorchanges <= sd->show) {
129 //ok we can really trim the left spaces now since we aren't scrolling it...
130 while ( buf[0] != '\0' && strchr ( &buf[0], ' ' ) != NULL ) {
131 memmove( &buf[0], &buf[1], strlen(buf) );
133 snprintf(p, p_max_size, "%s", buf);
136 //make sure a colorchange at the front is not part of the string we are going to show
137 while(*(buf + sd->start) == SPECIAL_CHAR) {
140 //place all chars that should be visible in p, including colorchanges
141 for(j=0; j < sd->show + visibcolorchanges; j++) {
142 p[j] = *(buf + sd->start + j);
143 if(p[j] == SPECIAL_CHAR) {
146 //if there is still room fill it with spaces
149 for(; j < sd->show + visibcolorchanges; j++) {
153 //count colorchanges in front of the visible part and place that many colorchanges in front of the visible part
154 for(j = 0; j < sd->start; j++) {
155 if(buf[j] == SPECIAL_CHAR) frontcolorchanges++;
157 pwithcolors=malloc(strlen(p) + 1 + colorchanges - visibcolorchanges);
158 for(j = 0; j < frontcolorchanges; j++) {
159 pwithcolors[j] = SPECIAL_CHAR;
162 strcat(pwithcolors,p);
163 strend = strlen(pwithcolors);
164 //and place the colorchanges not in front or in the visible part behind the visible part
165 for(j = 0; j < colorchanges - frontcolorchanges - visibcolorchanges; j++) {
166 pwithcolors[strend + j] = SPECIAL_CHAR;
168 pwithcolors[strend + j] = 0;
169 strcpy(p, pwithcolors);
172 sd->start += sd->step;
173 if(buf[sd->start] == 0 || sd->start > strlen(buf)){
177 //reset color when scroll is finished
178 new_fg(p + strlen(p), sd->resetcolor);
182 void free_scroll(struct text_object *obj)
184 struct scroll_data *sd = obj->data.opaque;
192 free_text_objects(obj->sub, 1);
196 free(obj->data.opaque);
197 obj->data.opaque = NULL;