1 /*
2 * GKrellMBgChg: a GKrellM plugin to change the desktop wallpaper
3 * Copyright (C) 2002-2010 Stefan Bender
4 * Author: Stefan Bender <stefan@bender-suhl.de>
5 *
6 * This program is free software which I release under the GNU General Public
7 * License. You may redistribute and/or modify this program under the terms of
8 * that license as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * For more information, see the README and LICENSE files.
21 */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #if !defined(WIN32)
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #endif
29
30 #include "gkrellmbgchg.h"
31
32 /* Uncomment this or add -DGKBG_DEBUG to compiler's option to see a
33 lot of debug output. */
34 /* #define GKBG_DEBUG */
35 #ifdef GKBG_DEBUG
36 #define GKBG_debug(fmt, ...) fprintf(stderr, "debug: " fmt "\n", ##__VA_ARGS__)
37 #else
38 #define GKBG_debug(fmt, ...)
39 #endif
40
41 static GtkWidget *gkrellm_vbox;
42
43 static GkrellmKrell *krell_time;
44 static GkrellmPanel *panel;
45 static GkrellmMonitor *monitor;
46 static GkrellmDecal *decal_wu;
47 static GkrellmTicks *pGK;
48 static gint style_id;
49
50 /* all the stuff we need goes into this */
51 struct bg_ctx {
52 GList *idb;
53 GList *idb_orig;
54 GRand *bgchg_rand;
55 GtkTooltips *tip;
56 gint32 cur_img;
57 gint seconds_left;
58 gint locked;
59 };
60 /* so we have only this global (still) */
61 static struct bg_ctx *pbg_ctx;
62
63 /* config widgets */
64 static GtkWidget *entry_format_str;
65 static GtkWidget *entry_idb;
66 static GtkWidget *wait_seconds_spin_button;
67 static GtkWidget *scroll_adj_spin_button;
68 static GtkWidget *entry_command;
69 static GtkWidget *parse_cmd_entry;
70 #if !defined(WIN32)
71 static GtkWidget *auto_update_entry;
72 #endif
73 static GtkWidget *ignore_entry;
74 static GtkWidget *randomise_entry;
75 static GtkWidget *reset_entry;
76 static GtkWidget *reset_entry2;
77 static GtkWidget *change_on_load;
78 static GtkWidget *change_on_apply;
79 static GtkWidget *remember_locked_state;
80 static GtkWidget *remember_image_number;
81 static GtkWidget *simple_scroll_adj;
82 static GtkWidget *center_text;
83 static GtkWidget *display_text;
84 static GtkWidget *display_krell;
85
86 struct bg_monitor {
87 gint wait_seconds; /* sec. between updates */
88 gint randomise; /* randomise images? */
89 gint reset; /* reset the counter if lock is released */
90 gint reset_config; /* reset the counter on "apply" */
91 gchar format_string[128]; /* output format string */
92 gchar command[256]; /* command to change bg */
93 gboolean parse_cmd_output; /* parse command's output */
94 gchar idb[256]; /* full path to image database */
95 gint change_on_load; /* change image on load */
96 gint change_on_apply; /* change image on config changes */
97 gint remember_locked_state;
98 gint locked_last_run; /* was it locked the last time? */
99 gint remember_image_number;
100 gint32 image_nr_last_run; /* the number when we last shut down */
101 gint simple_scroll_adj; /* mouse wheel adjusts timer w/o "shift" */
102 gint scroll_adj_time; /* time that the mouse wheel adjusts */
103 gboolean center_text; /* Center time text */
104 gboolean display_text; /* Display text countdown */
105 gboolean display_krell; /* Display krell - slider */
106 gboolean ignore; /* discard files we can not stat */
107 #if !defined(WIN32)
108 gboolean auto_update; /* auto update image list if changed? */
109 time_t idb_mtime; /* IDB file mtime */
110 #endif
111 };
112
113 static struct bg_monitor bgmon = {
114 .wait_seconds = 600,
115 .randomise = 1,
116 .reset = 0,
117 .reset_config = 0,
118 .format_string = "$t",
119 #if defined(WIN32)
120 .command = "",
121 #else
122 .command = "Esetroot -f",
123 #endif
124 .parse_cmd_output = 0,
125 .idb = "~/images.idb",
126 .change_on_load = 0,
127 .change_on_apply = 0,
128 .remember_locked_state = 0,
129 .locked_last_run = 0,
130 .remember_image_number = 0,
131 .image_nr_last_run = -1,
132 .simple_scroll_adj = 0,
133 .scroll_adj_time = 60,
134 .center_text = 1,
135 .display_text = 1,
136 .display_krell = 1,
137 .ignore = 0
138 #if !defined(WIN32)
139 ,
140 .auto_update = 0,
141 .idb_mtime = 0
142 #endif
143 };
144
145 struct idb_entry {
146 gchar *filename;
147 };
148
149 /* returns the pointer to the successfully opened file and
150 * NULL if something weird happened or the file was not modified
151 * and `force' was not set (to 1). */
open_imagelist(gchar * filename,int force)152 FILE *open_imagelist( gchar *filename, int force )
153 {
154 FILE *file;
155 gchar *tmp;
156 #if !defined(WIN32)
157 struct stat buf;
158 #endif
159 if( filename ) {
160 if( !strncmp( filename, "~/", MIN(2, strlen(filename)) ) )
161 tmp = g_strdup_printf( "%s/%s", g_get_home_dir(), filename+2 );
162 else
163 tmp = g_strdup_printf( "%s", filename );
164 } else return NULL;
165 GKBG_debug("bgmon.idb = %s; tmp = %s", bgmon.idb, tmp);
166
167 #if !defined(WIN32)
168 /* don't load if no force and not modified */
169 if( stat( tmp, &buf ) == -1 ) {
170 /* something went wrong, we just don't care what for now */
171 GKBG_debug("stat: error on `%s'", tmp);
172 return NULL;
173 }
174 if( !force && bgmon.idb_mtime == buf.st_mtime) {
175 GKBG_debug("%s was not modified", tmp);
176 return NULL;
177 }
178 #endif
179
180 GKBG_debug("opening database `%s'", tmp);
181 if( (file = fopen( tmp, "r" )) == NULL) {
182 /* fwiw, print an error message to stderr */
183 fprintf( stderr, _("Could not open image database. (%s)\n"), _(tmp) );
184 if( tmp!=bgmon.idb ) g_free( tmp );
185 return NULL;
186 }
187 if( tmp!=bgmon.idb ) g_free( tmp );
188
189 #if !defined(WIN32)
190 bgmon.idb_mtime = buf.st_mtime;
191 #endif
192
193 return file;
194 }
195
196 /* Randomise image list in a non-repeating manner. */
randomise_image_list()197 static void randomise_image_list()
198 {
199 GList *gl = NULL;
200 GList *entry = NULL, *tentry = NULL;
201 guint gll = g_list_length( pbg_ctx->idb );
202 int i, tmp;
203 gint32 randval;
204 gint gli[gll];
205
206 /* Save the original list */
207 pbg_ctx->idb_orig = g_list_copy(pbg_ctx->idb);
208
209 /* Randomise the index list */
210 for( i = 0; i < gll; i++ ) gli[i] = i;
211 for( i = 0; i < gll; i++ ) {
212 randval = g_rand_int_range( pbg_ctx->bgchg_rand, 0, gll );
213 tmp = gli[i];
214 gli[i] = gli[randval];
215 gli[randval] = tmp;
216 };
217
218 /* save old image entry */
219 if( pbg_ctx->cur_img > -1 && pbg_ctx->cur_img < gll )
220 entry = g_list_nth( pbg_ctx->idb, pbg_ctx->cur_img );
221
222 /* Create new list from randomised index list */
223 for( i = 0; i < gll; i++ )
224 gl = g_list_append( gl, ((struct idb_entry *)g_list_nth( pbg_ctx->idb, gli[i] )->data));
225
226 /* exchange entries if remembering is set and the image is in the list */
227 if( bgmon.remember_image_number && entry ) {
228 i = g_list_index( gl, entry->data);
229 tentry = g_list_nth( gl, i );
230 gl = g_list_remove_link( gl, tentry );
231 gl = g_list_prepend( gl, tentry->data );
232 }
233
234 /* Switch to the randomised list */
235 g_list_free(pbg_ctx->idb); pbg_ctx->idb = gl;
236
237 /* begin with zero */
238 pbg_ctx->cur_img = 0;
239
240 /* Uncomment code below to show indices and filenames */
241 /*
242 for( i = 0; i < gll; i++ ) printf(" %d ", gli[i]);
243 fprintf(stderr, "\n");
244
245 gchar *fname = NULL;
246 for( i = 0; i < gll; i++ ) {
247 fname = g_strdup( ((struct idb_entry *)g_list_nth( pbg_ctx->idb, i )->data)->filename );
248 fprintf(stderr, "%d <%s>\n", i, fname );
249 }
250 g_free( fname );
251 */
252 }
253
254 /* returns 0 if list was updated (= normal operation), 1 otherwise */
255 /* force - whether to load list even if not modified */
update_image_list(int force)256 static int update_image_list(int force)
257 {
258 gchar *tmp = NULL;
259 #if !defined(MAXPATHLEN)
260 gchar *tmp2 = NULL;
261 #endif
262 gchar c;
263 gint num=1;
264 FILE *idb_file;
265 struct idb_entry *idb_e;
266
267 if((idb_file = open_imagelist( bgmon.idb, force )) == NULL) return 1;
268
269 if(pbg_ctx->idb != NULL) { g_list_free(pbg_ctx->idb); pbg_ctx->idb = NULL; }
270
271 tmp = g_malloc( num*BUFFSIZE );
272 while(!feof(idb_file)) {
273
274 /* skip leading blanks and tabs */
275 while( ((c = fgetc( idb_file )) == 0x20 || c == '\t') && !feof( idb_file ));
276
277 if( c == '#' ) { /* skip entry */
278 while( ((char)fgetc( idb_file ) != '\n') && !feof( idb_file ) );
279 continue;
280 }
281
282 if( c == '\n' ) continue;
283
284 *tmp=c; /* copy entry */
285 /* abort on error and eof when no bytes were read */
286 if( !fgets( tmp+1, (num*BUFFSIZE)-1, idb_file ) ) continue;
287 #if !defined(MAXPATHLEN)
288 while( tmp[strlen(tmp)-1]!='\n' && !feof( idb_file ) ) {
289 if( (tmp2 = g_realloc( tmp, ++num*BUFFSIZE )) == NULL ) break;
290 tmp = tmp2;
291 if( !fgets( tmp+strlen(tmp), BUFFSIZE, idb_file ) ) break;
292 }
293 #endif
294 if( tmp[strlen(tmp)-1]=='\n' )
295 tmp[strlen(tmp)-1] = 0x00; /* strip trailing newline */
296 #if defined(MAXPATHLEN)
297 else if( !feof( idb_file ) )
298 /* skip to eol or eof */
299 while( ((char)fgetc( idb_file ) != '\n') && !feof( idb_file ) );
300 #endif
301
302 /* ignore the file if doesn't exist */
303 if( bgmon.ignore && !g_file_test( tmp, G_FILE_TEST_EXISTS ) ) {
304 GKBG_debug( "ignoring `%s'", tmp );
305 } else {
306 idb_e = (struct idb_entry *)calloc( 1, sizeof( struct idb_entry ));
307 idb_e->filename = g_strdup( tmp );
308 pbg_ctx->idb = g_list_append( pbg_ctx->idb, idb_e );
309 }
310
311 }
312
313 g_free( tmp );
314 fclose(idb_file);
315
316 if( bgmon.randomise )
317 randomise_image_list();
318 else
319 pbg_ctx->cur_img = bgmon.image_nr_last_run;
320
321 return 0;
322 }
323
324
325
326
update_image(gint32 inr)327 static void update_image(gint32 inr)
328 {
329 gchar *fname = NULL, *tiptext = NULL, *ch, *tmp = NULL, *tag, *value;
330 gint count = 0;
331 double val;
332 guint gll = g_list_length( pbg_ctx->idb );
333
334 GKBG_debug("update_image(%i) [%i]", inr, gll);
335
336
337 #if !defined(WIN32)
338 /*
339 * Auto update
340 */
341 if( bgmon.auto_update && !update_image_list(0)) {
342 GKBG_debug("list modified.");
343 inr = -1;
344 }
345 #endif
346
347
348 /*
349 * Choose file
350 */
351 /* nothing to change, if there are not at least 2 images,
352 however, if list was just updated image in it may be different. */
353 if( !gll || (inr!=-1 && gll==1) ) return;
354 /* start over, if the number is larger than the database's length */
355 if( gll < inr ) inr = -1;
356
357 /* If randomising, images are already randomised; hence we just
358 increment index no matter what. */
359 if( inr == -1) { /* -1 means change */
360 if( ++pbg_ctx->cur_img >= gll ) {
361 if( bgmon.randomise ) randomise_image_list();
362 pbg_ctx->cur_img=0;
363 }
364 /* make sure GKrellM will save the image number */
365 gkrellm_config_modified();
366 } else pbg_ctx->cur_img = inr;
367 fname = g_strdup( ((struct idb_entry *)g_list_nth( pbg_ctx->idb, pbg_ctx->cur_img )->data)->filename );
368
369
370
371 /*
372 * Make command string
373 */
374 pbg_ctx->seconds_left = bgmon.wait_seconds;
375 #if defined(WIN32)
376 if (bgmon.parse_cmd_output) {
377 #endif
378
379 for (ch = bgmon.command; *ch; ) {
380 if (*ch++=='%') {
381 switch (*ch) {
382 case '%': if (count==0) count = 1; break;
383 case 's': ++count; break;
384 default: count = 2;
385 }
386 if (*ch) ++ch;
387 }
388 }
389
390 /* If there was exactly one '%s' in command use it as format */
391 tmp = count==1
392 ? g_strdup_printf( bgmon.command, g_shell_quote(fname) )
393 : g_strdup_printf( "%s %s", bgmon.command, g_shell_quote(fname) );
394 GKBG_debug("command: %s", tmp);
395
396 #if defined(WIN32)
397 }
398 #endif
399
400
401 /*
402 * Parse output
403 */
404 if (bgmon.parse_cmd_output) {
405
406 if (!g_spawn_command_line_sync(tmp, &ch, NULL, &count, NULL)) {
407 count = 1;
408 }
409 free(tmp);
410
411 /* Failed */
412 if (count) {
413 pbg_ctx->seconds_left = 10;
414 return;
415 }
416
417 /* Parse */
418 for (tmp = ch; *ch; ) {
419 for (tag = ch; *ch && *ch!=':'; ++ch);
420 if (!*ch) break;
421 *ch++ = 0;
422 for (value = ch; *ch && *ch!='\n'; ++ch);
423 if (!*ch) break;
424 *ch++ = 0;
425
426 if (!strcmp(tag, "file")) {
427 if (fname) free(fname);
428 fname = g_strdup(value);
429 } else if (!strcmp(tag, "tooltip")) {
430 if (tiptext) free(tiptext);
431 tiptext = g_strdup(value);
432 } else if (strcmp(tag, "time")) {
433 continue;
434 }
435
436 if (*value=='+' || *value=='-') {
437 count = strtol(value, &value, 0);
438 if (!*value) pbg_ctx->seconds_left += count;
439 } else if (*value=='*' || *value=='x') {
440 val = strtod(value+1, &value);
441 if (!*value && val>0) pbg_ctx->seconds_left *= val;
442 } else if (*value=='/') {
443 val = strtod(value+1, &value);
444 if (!*value && val>0) pbg_ctx->seconds_left /= val;
445 } else if (*value=='<') {
446 count = strtol(value+1, &value, 0);
447 if (!*value && value>0 && pbg_ctx->seconds_left<count)
448 pbg_ctx->seconds_left = count;
449 } else if (*value=='>') {
450 count = strtol(value+1, &value, 0);
451 if (!*value && value>0 && pbg_ctx->seconds_left>count)
452 pbg_ctx->seconds_left = count;
453 } else {
454 count = strtol(value, &value, 0);
455 if (!*value && count>=0) pbg_ctx->seconds_left = count;
456 }
457 }
458 free(tmp);
459
460
461 #if !defined(WIN32)
462 /*
463 * Don't parse output
464 */
465 } else {
466 g_spawn_command_line_async( tmp, NULL );
467 g_free( tmp );
468 #endif
469 }
470
471
472 #if defined(WIN32)
473 /*
474 * Set background under Win32
475 */
476 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, fname, 0);
477 #endif
478
479
480 /*
481 * Set tool tip text
482 */
483 if( tiptext == NULL && fname ) {
484 for (tiptext = ch = fname; *ch; ++ch) {
485 if (*ch=='/' && *(ch+1)) tiptext = ch+1;
486 }
487 tiptext = g_locale_to_utf8( tiptext, -1, NULL, NULL, NULL);
488 }
489 gtk_tooltips_set_tip( pbg_ctx->tip, panel->drawing_area, tiptext, NULL );
490 gtk_tooltips_enable( pbg_ctx->tip );
491 g_free( tiptext );
492 g_free( fname );
493 }
494
495
496
497
update_decals_text(gchar * text)498 static void update_decals_text( gchar *text )
499 {
500 gchar *s, buf[48];
501
502 if( pbg_ctx->locked ) return;
503
504 text[0] = '\0';
505 for( s=bgmon.format_string; *s!='\0'; s++ ) {
506 buf[0] = *s; buf[1]='\0';
507 if( *s == '$' && *(s+1) !='\0' )
508 switch( *(s+1) ) {
509 case 's':
510 g_snprintf( buf, 12, "%d", pbg_ctx->seconds_left );
511 s++;
512 break;
513 case 'S':
514 g_snprintf( buf, 12, "%d", bgmon.wait_seconds - pbg_ctx->seconds_left );
515 s++;
516 break;
517 case 'm':
518 g_snprintf( buf, 12, "%d", pbg_ctx->seconds_left / 60 );
519 s++;
520 break;
521 case 'M':
522 g_snprintf( buf, 12, "%d", (bgmon.wait_seconds-pbg_ctx->seconds_left) / 60 );
523 s++;
524 break;
525 case 't':
526 if (bgmon.wait_seconds > 3600) { /* If over an hour, display hh:mm */
527 gint hours = pbg_ctx->seconds_left / 3600;
528 g_snprintf( buf, 12, "%.2d:%.2d",
529 hours, (pbg_ctx->seconds_left - hours*3600)/ 60 );
530 } else
531 g_snprintf( buf, 12, "%.2d:%.2d",
532 pbg_ctx->seconds_left / 60, pbg_ctx->seconds_left % 60 );
533 s++;
534 break;
535 case 'T':
536 if (bgmon.wait_seconds > 3600) { /* If over an hour, display hh:mm */
537 gint hours = (bgmon.wait_seconds-pbg_ctx->seconds_left) / 3600;
538 g_snprintf( buf, 12, "%.2d:%.2d",
539 hours,
540 (bgmon.wait_seconds-hours*3600-pbg_ctx->seconds_left) / 60 );
541 } else
542 g_snprintf( buf, 12, "%.2d:%.2d",
543 (bgmon.wait_seconds-pbg_ctx->seconds_left) / 60,
544 (bgmon.wait_seconds-pbg_ctx->seconds_left) % 60 );
545 s++;
546 break;
547 }
548 strncat( text, buf,
549 (strlen(text)+strlen(buf)) > TEXTSIZE ? TEXTSIZE - strlen(text) : strlen(buf) );
550 }
551 text = g_locale_to_utf8( text, -1, NULL, NULL, NULL );
552 }
553
update_krell(void)554 static void update_krell(void)
555 {
556 if ( ! bgmon.display_krell ) return;
557 gkrellm_update_krell( panel, krell_time, (gulong) bgmon.wait_seconds - pbg_ctx->seconds_left );
558 }
559
update_plugin(void)560 static void update_plugin(void)
561 {
562 int w = 0, c = 0;
563 gchar text[TEXTSIZE] = "locked";
564
565 if(pGK->second_tick && !pbg_ctx->locked && !(pbg_ctx->seconds_left--)) {
566 update_image(-1);
567 }
568
569 if(!(pGK->timer_ticks % 2)) return;
570
571 if( !pbg_ctx->locked ) update_decals_text( text );
572
573 /* No need to do these calculations every time... FIXME */
574 if ( bgmon.center_text ) {
575 GkrellmMargin *m =gkrellm_get_style_margins(gkrellm_panel_style(style_id));
576 w = gkrellm_gdk_string_width(gkrellm_panel_textstyle(style_id)->font, text);
577 c = (gkrellm_chart_width() - w ) / 2 - m->left;
578 }
579 gkrellm_decal_text_set_offset(decal_wu, c, 2);
580 if ( bgmon.display_text )
581 gkrellm_draw_decal_text( panel, decal_wu, text, -1 );
582
583 update_krell();
584 gkrellm_draw_panel_layers( panel );
585 }
586
panel_expose_event(GtkWidget * widget,GdkEventExpose * ev)587 static gint panel_expose_event( GtkWidget *widget, GdkEventExpose *ev)
588 {
589 if( widget == panel->drawing_area ) {
590 gdk_draw_pixmap( widget->window,
591 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
592 panel->pixmap,
593 ev->area.x, ev->area.y,
594 ev->area.x, ev->area.y,
595 ev->area.width, ev->area.height );
596 }
597 return FALSE;
598 }
599
cb_panel_scroll(GtkWidget * widget,GdkEventScroll * ev)600 static gint cb_panel_scroll( GtkWidget *widget, GdkEventScroll *ev )
601 {
602 gint shift_modifier = (ev->state & GDK_SHIFT_MASK) ? !bgmon.simple_scroll_adj : bgmon.simple_scroll_adj;
603 gint prev_locked = pbg_ctx->locked;
604
605 if (ev->direction == GDK_SCROLL_UP) {
606 if( !shift_modifier ) pbg_ctx->locked = 1;
607 else pbg_ctx->seconds_left += bgmon.scroll_adj_time;
608 } else if (ev->direction == GDK_SCROLL_DOWN) {
609 if( !shift_modifier && pbg_ctx->locked) {
610 pbg_ctx->locked = 0;
611 if( bgmon.reset ) pbg_ctx->seconds_left = bgmon.wait_seconds;
612 } else if( shift_modifier ) {
613 pbg_ctx->seconds_left -= bgmon.scroll_adj_time;
614 if( pbg_ctx->seconds_left < 0 ) pbg_ctx->seconds_left = 1;
615 }
616 }
617
618 /* make sure GKrellM will save the lock state if it changed */
619 if ( prev_locked != pbg_ctx->locked ) gkrellm_config_modified();
620
621 return FALSE;
622 }
623
cb_button_press(GtkWidget * widget,GdkEventButton * ev)624 static gint cb_button_press( GtkWidget *widget, GdkEventButton *ev )
625 {
626 gint shift_modifier = (ev->state & GDK_SHIFT_MASK ) ? 1 : 0;
627
628 switch( ev->button ) {
629 /* left */
630 case 1:
631 if( shift_modifier ) { /* shift+left -> lock/unlock the bg */
632 if( pbg_ctx->locked ) {
633 pbg_ctx->locked = 0;
634 if( bgmon.reset ) pbg_ctx->seconds_left = bgmon.wait_seconds;
635 } else pbg_ctx->locked = 1;
636 /* make sure GKrellM will save the lock state */
637 gkrellm_config_modified();
638 } else {
639 update_image(-1);
640 }
641 break;
642 /* middle */
643 case 2:
644 update_image_list(1);
645 break;
646 /* right */
647 case 3:
648 if( shift_modifier ) {/* shift+right -> lock/unlock the bg */
649 if( pbg_ctx->locked ) {
650 pbg_ctx->locked = 0;
651 if( bgmon.reset ) pbg_ctx->seconds_left = bgmon.wait_seconds;
652 } else pbg_ctx->locked = 1;
653 /* make sure GKrellM will save the lock state */
654 gkrellm_config_modified();
655 } else
656 gkrellm_open_config_window( monitor );
657 break;
658 }
659
660 return FALSE;
661 }
662
create_plugin(GtkWidget * vbox,gint first_create)663 static void create_plugin( GtkWidget *vbox, gint first_create )
664 {
665 GkrellmPiximage *krell_img;
666 GkrellmStyle *style;
667 GkrellmTextstyle *ts;
668 gchar text[TEXTSIZE] = "bgchg" ;
669
670 gkrellm_vbox = vbox;
671
672 if (first_create) panel = gkrellm_panel_new0 ();
673 else gkrellm_destroy_decal_list( panel );
674
675 style = gkrellm_meter_style( style_id );
676 krell_img = gkrellm_krell_meter_piximage( style_id );
677 ts = gkrellm_panel_textstyle( style_id );
678 panel->textstyle = ts;
679
680 krell_time = gkrellm_create_krell( panel, krell_img, style );
681 gkrellm_monotonic_krell_values(krell_time, FALSE);
682 gkrellm_set_krell_full_scale( krell_time, bgmon.wait_seconds, 1 );
683 if ( ! bgmon.display_krell )
684 gkrellm_remove_krell( panel, krell_time );
685
686 decal_wu = gkrellm_create_decal_text( panel, "Apif0", ts, style, -1, -1, -1 );
687
688 gkrellm_panel_configure( panel, NULL, style );
689 gkrellm_panel_create( vbox, monitor, panel );
690
691 gkrellm_draw_decal_text( panel, decal_wu, text, -1 );
692
693 if(first_create) {
694 g_signal_connect( G_OBJECT (panel->drawing_area), "expose_event",
695 G_CALLBACK(panel_expose_event), NULL );
696 g_signal_connect( G_OBJECT (panel->drawing_area), "button_press_event",
697 G_CALLBACK(cb_button_press), NULL );
698 g_signal_connect(G_OBJECT(panel->drawing_area),"scroll_event",
699 G_CALLBACK(cb_panel_scroll), NULL);
700
701 pbg_ctx = g_malloc( sizeof(struct bg_ctx) );
702 memset( pbg_ctx, 0x00, sizeof(struct bg_ctx) );
703 if (bgmon.remember_image_number) pbg_ctx->cur_img = bgmon.image_nr_last_run;
704 else pbg_ctx->cur_img = -1;
705 } else pbg_ctx->cur_img = -1;
706
707 pbg_ctx->tip = gtk_tooltips_new();
708 gtk_tooltips_enable( pbg_ctx->tip );
709
710 pbg_ctx->bgchg_rand = g_rand_new_with_seed( (guint32)time(NULL) );
711
712 if (bgmon.remember_locked_state) pbg_ctx->locked = bgmon.locked_last_run;
713 else pbg_ctx->locked = 0;
714 pbg_ctx->seconds_left = bgmon.wait_seconds;
715
716 update_image_list(1);
717 if (bgmon.change_on_load) update_image( pbg_ctx->cur_img );
718 update_krell();
719
720 gkrellm_draw_panel_layers( panel );
721 }
722
723 static gchar *plugin_info_text[] = {
724 "<b>GKrellMBgChg ",
725 "is a GKrellM plugin which periodically changes\n",
726 "your desktop background. It also allows you to monitor the time\n",
727 "between the updates in various ways. It is possible, to force a\n",
728 "change by clicking on the panel.\n\n",
729 "<h>Mouse Actions:\n\n",
730 "<b>- Left ", "changes the background image and resets the timer,\n",
731 "\t+<Shift> toggles the background lock.\n",
732 "<b>- Middle ", "reloads the images from the image database\n",
733 "\t(see \"Image Database\" below).\n",
734 "<b>- Right ", "opens the GKrellM Background Changer config window.\n",
735 "\t+<Shift> toggles the background lock.\n\n",
736 "<b>Mouse Wheel Actions:\n\n",
737 "<b>- Up ", "\"locks\" the current background image (if you like it very much).\n",
738 "\t+<Shift> prolongs the timer by the seconds given below.\n",
739 "<b>- Down ", "\"unlocks\" the image and the counter continues.\n",
740 "\t+<Shift> shortens the timer by the seconds given below.\n",
741 "The option \"Mouse wheel adjusts timer\" below exchanges the\n",
742 "<Shift>-behaviour of the mouse wheel.\n\n",
743 "<h>Configuration:\n\n",
744 "<b>- Format String\n",
745 "\tThe text output format is controlled by this string (default: $s).\n",
746 "<b>\t$s ", "are the seconds that are remaining to the next update\n",
747 "<b>\t$S ", "are the seconds that passed since the last change\n",
748 "<b>\t$m ", "are the minutes that are remaining to the next update\n",
749 "<b>\t$M ", "are the minutes that passed since the last change\n",
750 "<b>\t$t ", "is the time remaining to the next update, displayed as '-mm:ss'\n",
751 "<b>\t$T ", "is the time that passed since the last change, displayed as 'mm:ss'.\n\n",
752 #if defined(WIN32)
753 "<b>- Background Info Command\n",
754 "\tProgram to return information such as timeout, filename and tooltip.\n"
755 "\tIt is used only if Use Background Info Command is checked.\n"
756 "\tSee ", "<b>README: Tips and Tricks", " for info about output format\n",
757 "\tand some ideas.\n"
758 "\tdefault: empty",
759 "<b>- Use Background Info Command\n",
760 "\tWhether to use Background Info Command. This option is experimental.\n",
761 "\tdefault: ", "<b>off\n\n",
762 #else
763 "<b>- Background Change Command\n",
764 "\tProgram to use to set the desktop background image (including args).\n",
765 "\tIf the command has exactly one '%s' it will be replaced by the\n",
766 "\tproperly quoted background file name.\n",
767 "\tCommon cases are:\n",
768 "\tfor plain X11: ", "<b>xsetbg -fullscreen\n",
769 "\tusing Eterm's Esetroot: ", "<b>Esetroot -f\n",
770 "\tfor Gnome2 set it to:\n\t\t",
771 "<b>gconftool-2 --type=string --set /desktop/gnome/background/picture_filename\n",
772 "\tand for KDE 3.x:\n\t\t",
773 "<b>dcop kdesktop KBackgroundIface setWallpaper %s 6\n",
774 "\tdefault: ", "<b>Esetroot -f\n\n",
775 "<b>- Parse Background Change Command output\n",
776 "\tWhether to parse output of Background Change Command. This allows\n",
777 "\tsetting such information as tooltip and timeout from the command.\n",
778 "\tSee ", "<b>README: Tips and Tricks", " for info about output format\n",
779 "\tand some ideas. This option is experimental.\n",
780 "\tdefault: ", "<b>off\n\n",
781 #endif
782 "<b>- Image Database\n",
783 "\tFull path to a file containing all the images (full path/line) to be\n",
784 "\tused by the plugin. (e.g. the output from: ", "<b>find / -name *.jpg | sort", ")\n",
785 "\tEntries starting with a '#' will be ", "<i>ignored.\n",
786 "\tdefault: ", "<b>~/images.idb\n\n",
787 #if !defined(WIN32)
788 "<b>- Auto update image list\n",
789 "\tSelect whether the image list should be automatically updated \n",
790 "\twhen the image database file is modified.\n",
791 "\tdefault: ", "<b>off\n\n",
792 "<b>- Ignore not found images\n",
793 "\tIgnore image files that could not be found.\n",
794 "\tdefault: ", "<b>off\n\n",
795 #endif
796 "<b>- Randomise images\n",
797 "\tSelect whether the image list should be randomised or not.\n",
798 "<b>\tNote: ", "If it is not set, it will ", "<i>always ",
799 "start at the first image in the list.\n",
800 "\tdefault: ", "<b>on\n\n",
801 "<b>- Reset timer on \"lock\" release\n",
802 "\tReset the timer to the initial value when the \"image lock\" is released.\n",
803 "\tdefault: ", "<b>off\n\n",
804 "<b>- Reset timer on config changes\n",
805 "\tReset the timer on config changes, i.e. when you hit \"apply\" button.\n",
806 "\tdefault: ", "<b>off\n\n",
807 "<b>- Change wallpaper on load\n",
808 "\tChanges the wallpaper when the plugin loads.\n",
809 "\tdefault: ", "<b>off\n\n",
810 "<b>- Change wallpaper on config changes\n",
811 "\tChanges the wallpaper when the config changes.\n",
812 "\tdefault: ", "<b>off\n\n",
813 "<b>- Remember \"locked\" state from last run\n",
814 "\tRemembers whether the current wallpaper was \"locked\"\n",
815 "\tor not when GKrellM last shut down. Use with change-on-load\n",
816 "\toption off to load a new wallpaper ", "<i>only", " on request.\n",
817 "\tdefault: ", "<b>off\n\n",
818 "<b>- Remember image number from last run\n",
819 "\tRemembers the image number from the database that was\n",
820 "\tshown when GKrellM last shut down. It starts the next time with\n",
821 "\tthis image if the image list didn't change.\n",
822 "\tdefault: ", "<b>off\n\n",
823 "<b>- Center text\n",
824 "\tCenters the displayed text.\n",
825 "\tdefault: ", "<b>on\n\n",
826 "<b>- Display text\n",
827 "\tToggles the text on or off.\n",
828 "\tdefault: ", "<b>on\n\n",
829 "<b>- Display krell/slider\n",
830 "\tToggles the krell on or off.\n",
831 "\tdefault: ", "<b>on\n\n",
832 "<b>- Mouse wheel adjusts timer\n",
833 "\tWhen selected, scrolling the mouse wheel adjusts the time\n",
834 "\trather than \"lock\" the image. Otherwise the adjustment\n",
835 "\tworks in combination with the <Shift>-key.\n",
836 "\tdefault: ", "<b>off\n\n",
837 "<b>- Mouse wheel adjusts the timer by nnn seconds\n",
838 "\tThis is the amount of seconds by which the timer is adjusted\n",
839 "\twhen scrolling the mouse wheel while holding the <Shift>-key.\n",
840 "\tSee also \"Mouse wheel adjusts timer.\"\n",
841 "\tdefault: ", "<b>60\n"
842 };
843
create_bgchg_tab(GtkWidget * tab)844 static void create_bgchg_tab( GtkWidget *tab )
845 {
846 GtkWidget *tabs, *vbox, *hbox;
847 GtkWidget *label, *frame;
848 GtkWidget *text;
849 GtkAdjustment *adj, *mouse_wheel_adj;
850 gchar *about_text = NULL;
851
852 tabs = gtk_notebook_new();
853 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs),GTK_POS_TOP);
854 gtk_box_pack_start(GTK_BOX(tab),tabs,TRUE,TRUE,0);
855
856 /* options */
857 frame = gtk_frame_new(NULL);
858 gtk_container_border_width(GTK_CONTAINER(frame),3);
859 label = gtk_label_new(_("Options"));
860 gtk_notebook_append_page(GTK_NOTEBOOK(tabs),frame,label);
861
862 vbox = gtk_vbox_new(FALSE,0);
863 gtk_container_add(GTK_CONTAINER(frame),vbox);
864
865 hbox = gtk_hbox_new(FALSE, 0);
866 label = gtk_label_new(_("Format String"));
867 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4);
868 entry_format_str = gtk_entry_new_with_max_length(127);
869 gtk_entry_set_text(GTK_ENTRY(entry_format_str),bgmon.format_string);
870 gtk_box_pack_start(GTK_BOX(hbox), entry_format_str, FALSE, FALSE, 4);
871 gtk_container_add(GTK_CONTAINER(vbox),hbox);
872
873 hbox = gtk_hbox_new(FALSE, 0);
874 #if defined(WIN32)
875 label = gtk_label_new(_("Background Info Command"));
876 #else
877 label = gtk_label_new(_("Background Change Command"));
878 #endif
879 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4);
880 entry_command = gtk_entry_new_with_max_length(255);
881 gtk_entry_set_text(GTK_ENTRY(entry_command),bgmon.command);
882 gtk_box_pack_start(GTK_BOX(hbox), entry_command, TRUE, TRUE, 4);
883 gtk_container_add(GTK_CONTAINER(vbox),hbox);
884
885 #if defined(WIN32)
886 parse_cmd_entry = gtk_check_button_new_with_label( _("Use Background Info Command (experimental)"));
887 #else
888 parse_cmd_entry = gtk_check_button_new_with_label( _("Parse Background Change Command output (experimental)"));
889 #endif
890 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( parse_cmd_entry ), bgmon.parse_cmd_output );
891 gtk_container_add( GTK_CONTAINER(vbox), parse_cmd_entry );
892
893
894 hbox = gtk_hbox_new(FALSE, 0);
895 label = gtk_label_new(_("Image Database"));
896 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4);
897 entry_idb = gtk_entry_new_with_max_length(255);
898 gtk_entry_set_text(GTK_ENTRY(entry_idb),bgmon.idb);
899 gtk_box_pack_start(GTK_BOX(hbox), entry_idb, TRUE, TRUE, 4);
900 gtk_container_add(GTK_CONTAINER(vbox),hbox);
901
902 hbox = gtk_hbox_new(FALSE, 0);
903 adj = (GtkAdjustment *) gtk_adjustment_new(bgmon.wait_seconds,
904 1.0, 99999.0, 1.0, 5.0, 0.0);
905 wait_seconds_spin_button = gtk_spin_button_new(adj, 0.5, 0);
906 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(wait_seconds_spin_button), TRUE);
907 gtk_box_pack_start(GTK_BOX(hbox), wait_seconds_spin_button, FALSE, FALSE, 4);
908 label = gtk_label_new(_("Seconds between image changes"));
909 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
910 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4);
911 gtk_container_add(GTK_CONTAINER(vbox),hbox);
912
913 #if !defined(WIN32)
914 auto_update_entry = gtk_check_button_new_with_label( _("Auto update image list"));
915 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( auto_update_entry ), bgmon.auto_update );
916 gtk_container_add( GTK_CONTAINER(vbox), auto_update_entry );
917 #endif
918
919 ignore_entry = gtk_check_button_new_with_label( _("Ignore not found images"));
920 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( ignore_entry ), bgmon.ignore );
921 gtk_container_add( GTK_CONTAINER(vbox), ignore_entry );
922
923 randomise_entry = gtk_check_button_new_with_label( _("Randomise images"));
924 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( randomise_entry ), bgmon.randomise );
925 gtk_container_add( GTK_CONTAINER(vbox), randomise_entry );
926
927 reset_entry = gtk_check_button_new_with_label( _("Reset timer on \"lock\" release"));
928 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( reset_entry ), bgmon.reset );
929 gtk_container_add( GTK_CONTAINER(vbox), reset_entry );
930
931 reset_entry2 = gtk_check_button_new_with_label( _("Reset timer on config changes"));
932 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( reset_entry2 ), bgmon.reset_config );
933 gtk_container_add( GTK_CONTAINER(vbox), reset_entry2 );
934
935 change_on_load = gtk_check_button_new_with_label(_("Change wallpaper on load"));
936 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( change_on_load ), bgmon.change_on_load );
937 gtk_container_add( GTK_CONTAINER(vbox), change_on_load );
938
939 change_on_apply = gtk_check_button_new_with_label(_("Change wallpaper on config changes"));
940 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( change_on_apply ), bgmon.change_on_apply );
941 gtk_container_add( GTK_CONTAINER(vbox), change_on_apply );
942
943 remember_locked_state = gtk_check_button_new_with_label(_("Remember \"locked\" state from last run"));
944 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( remember_locked_state ), bgmon.remember_locked_state );
945 gtk_container_add( GTK_CONTAINER(vbox), remember_locked_state );
946
947 remember_image_number = gtk_check_button_new_with_label(_("Remember image number from last run"));
948 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( remember_image_number ), bgmon.remember_image_number );
949 gtk_container_add( GTK_CONTAINER(vbox), remember_image_number );
950
951 center_text = gtk_check_button_new_with_label(_("Center text"));
952 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( center_text ), bgmon.center_text );
953 gtk_container_add( GTK_CONTAINER(vbox), center_text );
954
955 display_text = gtk_check_button_new_with_label(_("Display text"));
956 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( display_text ), bgmon.display_text );
957 gtk_container_add( GTK_CONTAINER(vbox), display_text );
958
959 display_krell = gtk_check_button_new_with_label(_("Display krell/slider"));
960 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( display_krell ), bgmon.display_krell );
961 gtk_container_add( GTK_CONTAINER(vbox), display_krell );
962
963 simple_scroll_adj = gtk_check_button_new_with_label(_("Mouse wheel adjusts timer"));
964 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( simple_scroll_adj ), bgmon.simple_scroll_adj );
965 gtk_container_add( GTK_CONTAINER(vbox), simple_scroll_adj );
966
967 hbox = gtk_hbox_new (FALSE, 5);
968 gtk_widget_show (hbox);
969 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
970
971 label = gtk_label_new (_("Mouse wheel adjusts the timer by"));
972 gtk_widget_show (label);
973 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
974 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
975
976 mouse_wheel_adj = (GtkAdjustment *) gtk_adjustment_new (bgmon.scroll_adj_time, 1, 1000, 1, 10, 0);
977 scroll_adj_spin_button = gtk_spin_button_new (GTK_ADJUSTMENT (mouse_wheel_adj), 1, 0);
978 gtk_widget_show (scroll_adj_spin_button);
979 gtk_box_pack_start (GTK_BOX (hbox), scroll_adj_spin_button, FALSE, TRUE, 0);
980
981 label = gtk_label_new (_("second(s)"));
982 gtk_widget_show (label);
983 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
984 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
985
986 /* info */
987 vbox = gkrellm_gtk_framed_notebook_page(tabs,_("Info"));
988 text = gkrellm_gtk_scrolled_text_view(vbox, NULL,
989 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
990 gkrellm_gtk_text_view_append_strings(text, _(plugin_info_text),
991 sizeof(plugin_info_text) / sizeof(gchar *));
992
993 /* about */
994 about_text = g_strdup_printf(
995 "GKrellMBgChg %s\n" \
996 "GKrellM Background Changer Plugin\n\n" \
997 "Copyright © 2002-2010 Stefan Bender\n" \
998 "stefan@bender-suhl.de\n" \
999 "http://www.bender-suhl.de/stefan/english/comp/gkrellmbgchg.html\n\n" \
1000 "Released under the GNU General Public Licence",
1001 GKRELLMBGCHG_VERSION);
1002
1003 text = gtk_label_new(about_text);
1004 label = gtk_label_new(_("About"));
1005 gtk_notebook_append_page(GTK_NOTEBOOK(tabs),text,label);
1006 g_free(about_text);
1007 }
1008
apply_config(void)1009 static void apply_config(void)
1010 {
1011 const gchar *s;
1012
1013 /* update config vars */
1014 bgmon.wait_seconds = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wait_seconds_spin_button));
1015 s = gtk_entry_get_text(GTK_ENTRY(entry_format_str));
1016 strcpy(bgmon.format_string,s);
1017 s = gtk_entry_get_text(GTK_ENTRY(entry_idb));
1018 strcpy(bgmon.idb,s);
1019 #if !defined(WIN32)
1020 bgmon.auto_update = GTK_TOGGLE_BUTTON( auto_update_entry )->active;
1021 #endif
1022 bgmon.ignore = GTK_TOGGLE_BUTTON( ignore_entry )->active;
1023 s = gtk_entry_get_text(GTK_ENTRY(entry_command));
1024 strcpy(bgmon.command,s);
1025 bgmon.parse_cmd_output = GTK_TOGGLE_BUTTON( parse_cmd_entry )->active;
1026 bgmon.randomise = GTK_TOGGLE_BUTTON( randomise_entry )->active;
1027 bgmon.reset = GTK_TOGGLE_BUTTON( reset_entry )->active;
1028 bgmon.reset_config = GTK_TOGGLE_BUTTON( reset_entry2 )->active;
1029 bgmon.change_on_load = GTK_TOGGLE_BUTTON( change_on_load )->active;
1030 bgmon.change_on_apply = GTK_TOGGLE_BUTTON( change_on_apply )->active;
1031 bgmon.remember_locked_state = GTK_TOGGLE_BUTTON( remember_locked_state )->active;
1032 bgmon.remember_image_number = GTK_TOGGLE_BUTTON( remember_image_number )->active;
1033 bgmon.simple_scroll_adj = GTK_TOGGLE_BUTTON( simple_scroll_adj )->active;
1034 bgmon.display_text = GTK_TOGGLE_BUTTON( display_text )->active;
1035 bgmon.center_text = GTK_TOGGLE_BUTTON( center_text )->active;
1036 bgmon.display_krell = GTK_TOGGLE_BUTTON( display_krell )->active;
1037
1038 /* create new panel, not the first time */
1039 if( bgmon.reset_config ) pbg_ctx->seconds_left = bgmon.wait_seconds;
1040 update_image_list(1);
1041 if( bgmon.change_on_apply ) update_image(-1);
1042
1043 if ( bgmon.display_text )
1044 gkrellm_make_decal_visible( panel, decal_wu );
1045 else
1046 gkrellm_make_decal_invisible( panel, decal_wu );
1047 if ( bgmon.display_krell )
1048 gkrellm_insert_krell( panel, krell_time, 1 );
1049 else
1050 gkrellm_remove_krell( panel, krell_time );
1051 }
1052
save_config(FILE * f)1053 static void save_config( FILE *f)
1054 {
1055 fprintf( f, "%s wait_seconds %d\n", CONFIG_KEYWORD, bgmon.wait_seconds );
1056 #if !defined(WIN32)
1057 fprintf( f, "%s auto_update %d\n", CONFIG_KEYWORD, bgmon.auto_update );
1058 #endif
1059 fprintf( f, "%s ignore %d\n", CONFIG_KEYWORD, bgmon.ignore );
1060 fprintf( f, "%s command %s\n", CONFIG_KEYWORD, bgmon.command );
1061 fprintf( f, "%s parse_cmd_output %d\n", CONFIG_KEYWORD, bgmon.parse_cmd_output );
1062 fprintf( f, "%s randomise %d\n", CONFIG_KEYWORD, bgmon.randomise );
1063 fprintf( f, "%s reset %d\n", CONFIG_KEYWORD, bgmon.reset );
1064 fprintf( f, "%s reset_config %d\n", CONFIG_KEYWORD, bgmon.reset_config );
1065 fprintf( f, "%s format_string %s\n", CONFIG_KEYWORD, bgmon.format_string );
1066 fprintf( f, "%s idb %s\n", CONFIG_KEYWORD, bgmon.idb );
1067 fprintf( f, "%s change_on_load %d\n", CONFIG_KEYWORD, bgmon.change_on_load );
1068 fprintf( f, "%s change_on_apply %d\n", CONFIG_KEYWORD, bgmon.change_on_apply );
1069 fprintf( f, "%s remember_locked_state %d\n", CONFIG_KEYWORD, bgmon.remember_locked_state );
1070 fprintf( f, "%s locked_last_run %d\n", CONFIG_KEYWORD, pbg_ctx->locked );
1071 fprintf( f, "%s remember_image_number %d\n", CONFIG_KEYWORD, bgmon.remember_image_number );
1072 if (!pbg_ctx->idb || pbg_ctx->cur_img < 0) {
1073 fprintf( f, "%s image_nr_last_run %d\n", CONFIG_KEYWORD, 0 );
1074 } else if (!pbg_ctx->idb_orig) {
1075 fprintf( f, "%s image_nr_last_run %d\n", CONFIG_KEYWORD,
1076 pbg_ctx->cur_img );
1077 } else {
1078 GList *list = g_list_nth(pbg_ctx->idb, pbg_ctx->cur_img);
1079 fprintf( f, "%s image_nr_last_run %d\n", CONFIG_KEYWORD,
1080 list ? g_list_index( pbg_ctx->idb_orig, list->data) : 0);
1081 }
1082 fprintf( f, "%s simple_scroll_adj %d\n", CONFIG_KEYWORD, bgmon.simple_scroll_adj );
1083 fprintf( f, "%s scroll_adj_time %d\n", CONFIG_KEYWORD, bgmon.scroll_adj_time );
1084 fprintf( f, "%s center_text %d\n", CONFIG_KEYWORD, bgmon.center_text );
1085 fprintf( f, "%s display_text %d\n", CONFIG_KEYWORD, bgmon.display_text );
1086 fprintf( f, "%s display_krell %d\n", CONFIG_KEYWORD, bgmon.display_krell );
1087 }
1088
load_config(gchar * arg)1089 static void load_config( gchar *arg )
1090 {
1091 gchar *command, *p;
1092
1093 for( p = arg; *p && isspace(*p); p++ );
1094 for( ; *p && !isspace(*p); p++ );
1095
1096 command = g_malloc( (p-arg+1)*sizeof(char) );
1097 memset( command, 0x00, p-arg+1 );
1098 memcpy( command, arg, p-arg );
1099
1100 for( ; *p && isspace(*p); p++ );
1101
1102 if( !strcmp(command, "wait_seconds") ) bgmon.wait_seconds = atoi( p );
1103 #if !defined(WIN32)
1104 else if( !strcmp(command, "auto_update") ) bgmon.auto_update = atoi( p );
1105 #endif
1106 else if( !strcmp(command, "ignore") ) bgmon.ignore = atoi( p );
1107 else if( !strcmp(command, "command") ) strcpy( bgmon.command, p );
1108 else if( !strcmp(command, "parse_cmd_output") ) bgmon.parse_cmd_output = atoi( p );
1109 else if( !strcmp(command, "randomise") ) bgmon.randomise = atoi( p );
1110 else if( !strcmp(command, "reset") ) bgmon.reset = atoi( p );
1111 else if( !strcmp(command, "reset_config") ) bgmon.reset_config = atoi( p );
1112 else if( !strcmp(command, "format_string") ) strcpy( bgmon.format_string, p );
1113 else if( !strcmp(command, "idb") ) strcpy( bgmon.idb, p );
1114 else if( !strcmp(command, "change_on_load") ) bgmon.change_on_load = atoi( p );
1115 else if( !strcmp(command, "change_on_apply") ) bgmon.change_on_apply = atoi( p );
1116 else if( !strcmp(command, "remember_locked_state") ) bgmon.remember_locked_state = atoi( p );
1117 else if( !strcmp(command, "locked_last_run") ) bgmon.locked_last_run = atoi( p );
1118 else if( !strcmp(command, "remember_image_number") ) bgmon.remember_image_number = atoi( p );
1119 else if( !strcmp(command, "image_nr_last_run") ) bgmon.image_nr_last_run = atoi( p );
1120 else if( !strcmp(command, "simple_scroll_adj") ) bgmon.simple_scroll_adj = atoi( p );
1121 else if( !strcmp(command, "scroll_adj_time") ) bgmon.scroll_adj_time = atoi( p );
1122 else if( !strcmp(command, "center_text") ) bgmon.center_text = atoi( p );
1123 else if( !strcmp(command, "display_text") ) bgmon.display_text = atoi( p );
1124 else if( !strcmp(command, "display_krell") ) bgmon.display_krell = atoi( p );
1125
1126 g_free( command );
1127 }
1128
bgchg_atexit()1129 void bgchg_atexit()
1130 {
1131 g_free( pbg_ctx );
1132 }
1133
1134 static GkrellmMonitor plugin_mon = {
1135 .name = CONFIG_NAME,
1136 .id = 0,
1137 .create_monitor = create_plugin,
1138 .update_monitor = update_plugin,
1139 .create_config = create_bgchg_tab,
1140 .apply_config = apply_config,
1141 .save_user_config = save_config,
1142 .load_user_config = load_config,
1143 .config_keyword = CONFIG_KEYWORD,
1144 .undef2 = NULL,
1145 .undef1 = NULL,
1146 .privat = NULL,
1147 .insert_before_id = PLACEMENT,
1148 .handle = NULL,
1149 .path = NULL
1150 };
1151
1152 #if defined(WIN32)
1153 __declspec(dllexport) GkrellmMonitor *
gkrellm_init_plugin(win32_plugin_callbacks * calls)1154 gkrellm_init_plugin(win32_plugin_callbacks* calls)
1155 #else
1156 GkrellmMonitor *gkrellm_init_plugin()
1157 #endif
1158 {
1159 #if defined(WIN32)
1160 callbacks = calls;
1161 #endif
1162
1163 g_atexit( bgchg_atexit );
1164
1165 pGK = gkrellm_ticks();
1166 style_id = gkrellm_add_meter_style( &plugin_mon, STYLE_NAME );
1167 monitor = &plugin_mon;
1168 return &plugin_mon;
1169 }
1170