1 /*--- adesklets.c --------------------------------------------------------------
2 Copyright (C) 2004, 2005, 2006 Sylvain Fourmanoit <syfou@users.sourceforge.net>
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to
6 deal in the Software without restriction, including without limitation the
7 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 sell copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies of the Software and its documentation and acknowledgment shall be
13 given in the documentation and software packages that this Software was
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 ------------------------------------------------------------------------------*/
23 #include "adesklets.h" /* Application main header */
25 /*----------------------------------------------------------------------------*/
26 #define welcome(stream) fprintf(stream,\
27 "%s\n[%s]\n",WELCOME_LINE_1,WELCOME_LINE_2)
29 /*----------------------------------------------------------------------------*/
30 t_adesklets adesklets
= {
32 NULL
, /* Display * display */
33 NULL
, /* Visual * visual */
35 0, /* Window window */
37 X_POLLING_PERIOD
, /* int polling */
38 0, /* int transparency */
39 X_DISPLAY_SUPPORT
, /* int background_grab */
40 -1, /* int user_background_image */
42 BASE_EVENT_MASK
, /* long event_mask */
43 0, /* long user_event_mask */
44 NULL
, /* cfgfile_item * params */
45 NULL
, /* vector * menus */
46 NULL
, /* vector * images */
47 NULL
, /* vector * fonts */
48 NULL
, /* vector * color_ranges */
49 NULL
, /* vector * color_modifiers */
50 NULL
, /* vector * imlib_filters */
51 NULL
, /* vector * polygons */
52 NULL
, /* vector * variables */
53 "", /* char * lock_filename */
54 NULL
, /* FILE * lock */
55 0, /* int quit_flag */
56 0, /* int restart_flag */
57 0 /* int user_quit_flag */
60 /*----------------------------------------------------------------------------*/
61 /* Termination handler prototype for adesklets_free()
63 void termination_handler(int);
65 /*----------------------------------------------------------------------------*/
66 /* Reinstate the menus in pristine state: only one default menu with two
67 or three items: Move (if applicable), Restart (if applicable)
68 and Quit - all managed internally.
69 If an already filled menu could not get reset, returns 0 instead
73 adesklets_menus_reset(void)
79 adesklets
.menus
=vector_free(adesklets
.menus
);
81 if ((adesklets
.menus
=vector_init())) {
82 adesklets
.menus
->vector_free_item
=xmenu_vector_free_item
;
84 #ifndef X_DISPLAY_MISSING
85 // if(!xwindow_window_managed(adesklets.display,adesklets.window))
86 if (!adesklets
.managed
)
88 xmenu_push_item(menu
,"Move");
89 /* A lock file is needed if we want
90 the restart mechanism to work */
91 if (adesklets
.lock
) xmenu_push_item(menu
,"Restart");
92 xmenu_push_item(menu
,"Quit");
93 vector_push(adesklets
.menus
,menu
);
99 /*----------------------------------------------------------------------------*/
100 /* Recompute the background image based on present main window
101 width and height. Also create or resize foreground image as needed.
102 Returns 1 if both final and background images were dutifully produced,
106 adesklets_images_reset_background(int force_size
, ...)
108 int i
, j
, old_width
, old_height
, foreground_active
, background_active
;
115 /* Get window dimension by all means necessary */
117 va_start(ap
,force_size
);
118 width
=va_arg(ap
,uint
);
119 height
=va_arg(ap
,uint
);
122 #ifndef X_DISPLAY_MISSING
123 if (!xwindow_window_size(adesklets
.display
,adesklets
.window
,&width
,&height
))
127 /* Save context states */
128 xwindow_context_save(IMLIB_BLEND
|IMLIB_COLOR
|IMLIB_IMAGE
);
130 /* Record if Imlib's context image has to be changed at the end */
131 image
=imlib_context_get_image();
132 foreground_active
=(image
&& image
==adesklets
.images
->content
[0]);
133 background_active
=(image
&& image
==adesklets
.images
->content
[1]);
135 /* Determine what images to resize */
136 if ((index
=vector_init())) {
137 /* Always resize foreground */
138 if((pos
=malloc(sizeof(int)))) {
140 vector_push(index
,pos
);
142 /* Resize background when:
143 - We do not have X support
144 - We have X support, but there is no X connection or no window
145 - We have X support, there is a valid X connection and window,
146 but we do not grab the background
148 if(!X_DISPLAY_SUPPORT
||
149 !adesklets
.background_grab
||
150 !adesklets
.display
|| !adesklets
.window
) {
151 if((pos
=malloc(sizeof(int)))) {
153 vector_push(index
,pos
);
156 /* Resize user selected background when:
159 if(adesklets
.user_background_image
!=-1) {
160 if ((pos
=malloc(sizeof(int)))) {
161 *pos
=adesklets
.user_background_image
;
162 vector_push(index
,pos
);
167 /* Create/update image(s) */
168 for(j
=0;index
&& j
<index
->pos
;++j
) {
169 i
=*((int*)index
->content
[j
]);
170 if (!adesklets
.images
->content
[i
]) {
171 /* Create new final window image */
172 if ((adesklets
.images
->content
[i
]=imlib_create_image(width
,height
))) {
174 imlib_context_set_image(adesklets
.images
->content
[i
]);
176 /* Make sure it has an alpha channel */
177 imlib_image_set_has_alpha(1);
179 /* Fill image with transparent black for foreground,
180 and opaque black for background, if applicable */
181 imlib_context_set_blend(0);
182 imlib_context_set_color(0, 0, 0, (i
==0)?0:255);
183 imlib_image_fill_rectangle(0,0,width
,height
);
186 /* Update (by resizing image) */
187 imlib_context_set_image(adesklets
.images
->content
[i
]);
188 old_width
=imlib_image_get_width();
189 old_height
=imlib_image_get_height();
190 if((width
!=old_width
|| height
!=old_height
) &&
191 (image
=imlib_create_image(width
,height
))){
193 imlib_context_set_image(image
);
195 /* Make sure it has an alpha channel */
196 imlib_image_set_has_alpha(1);
198 /* Fill image with opaque black */
199 imlib_context_set_blend(0);
200 imlib_context_set_color(0,0,0,255);
201 imlib_image_fill_rectangle(0,0,width
,height
);
203 /* Finally, copy the original foreground image, with scaling */
204 imlib_blend_image_onto_image(adesklets
.images
->content
[i
],1,
205 0,0,old_width
,old_height
,
208 /* Clean up : free original image */
209 imlib_context_set_image(adesklets
.images
->content
[i
]);
211 adesklets
.images
->content
[i
]=image
;
216 #ifndef X_DISPLAY_MISSING
217 if(adesklets
.background_grab
&& adesklets
.display
&& adesklets
.window
) {
218 /* If it exists, free background image */
219 adesklets
.images
->content
[1]=
220 image_vector_free_item(adesklets
.images
->content
[1]);
222 /* Create new background image */
223 adesklets
.images
->content
[1]=
224 xwindow_grab_background(adesklets
.display
,adesklets
.params
->scr
,
226 if (adesklets
.user_event_mask
&BackgroundGrabMask
)
227 event("backgroundgrab\n");
230 /* Free index, if applicable */
233 /* Switch back to original context */
234 xwindow_context_restore();
236 /* Modify active image if it was originally set on foreground */
237 if(foreground_active
) imlib_context_set_image(adesklets
.images
->content
[0]);
238 if(background_active
) imlib_context_set_image(adesklets
.images
->content
[1]);
240 return adesklets
.images
->content
[0] && adesklets
.images
->content
[1];
243 /*----------------------------------------------------------------------------*/
244 /* Reinstate the image vector in pristine state,
245 including the regeneration of final and background image.
246 Take care of dangling context image, if applicable.
247 Returns 1 if successful, 0 in case of failure.
250 adesklets_images_reset(void)
253 if (adesklets
.images
)
254 adesklets
.images
=vector_free(adesklets
.images
);
255 if (!adesklets
.images
)
256 if((adesklets
.images
=vector_init())) {
257 adesklets
.images
->vector_free_item
=image_vector_free_item
;
258 adesklets
.user_background_image
=-1;
259 /* Recreate Final window and background images */
260 if((result
=adesklets_images_reset_background(0))) {
261 adesklets
.images
->pos
=2;
262 /* Reset current image if useful */
263 if (imlib_context_get_image()!=adesklets
.images
->content
[0] &&
264 imlib_context_get_image()!=adesklets
.images
->content
[1])
265 imlib_context_set_image(adesklets
.images
->content
[0]);
271 /*----------------------------------------------------------------------------*/
272 /* Set/Reset main window. Also call adesklets_menu_reset and
273 adeslets_images_reset as needed. */
275 adesklets_window_reset(int managed
)
278 #ifndef X_DISPLAY_MISSING
281 XWindowAttributes attr
;
282 XTextProperty text_prop_name
;
284 const char * name
= PACKAGE
;
285 const long valuemask
= CWBackPixmap
;
287 /* Determine if the old window was mapped, then destroy it as needed */
288 if(adesklets
.display
) {
289 if(adesklets
.window
) {
290 mapped
=(XGetWindowAttributes(adesklets
.display
,
291 adesklets
.window
,&attr
))?
292 (attr
.map_state
!=IsUnmapped
):0;
293 XDestroyWindow(adesklets
.display
,adesklets
.window
);
297 /* Determine new window dimensions */
298 width
=(adesklets
.window
)?attr
.width
:1;
299 height
=(adesklets
.window
)?attr
.height
:1;
301 xwindow_error_reset();
302 /* Create main desklet window */
303 adesklets
.root
=(managed
)?
304 RootWindow(adesklets
.display
,adesklets
.params
->scr
):
305 xwindow_get_root_window(adesklets
.display
,
306 adesklets
.params
->scr
);
307 debug("Root window is : 0x%x\n", adesklets
.root
);
310 XCreateWindow(adesklets
.display
,
312 adesklets
.params
->x
, adesklets
.params
->y
,
314 DefaultDepth(adesklets
.display
,
315 adesklets
.params
->scr
),
318 (managed
)?valuemask
:(valuemask
|CWOverrideRedirect
),
319 &XDefaultWindowAttributes
);
321 if (xwindow_error_check()) {
322 /* Set this window size */
323 xwindow_resize_window(adesklets
.display
,adesklets
.window
,
324 adesklets
.params
,width
,height
,1);
325 /* Set this window event mask */
326 XSelectInput(adesklets
.display
,adesklets
.window
,adesklets
.event_mask
);
328 /* Set this window as imlib2's default drawable */
329 imlib_context_set_drawable(adesklets
.window
);
331 /* Set window stacking order, and various properties if applicable */
333 XRaiseWindow(adesklets
.display
,adesklets
.window
);
335 if (XmbTextListToTextProperty(adesklets
.display
,
338 &text_prop_name
)==Success
)
339 XSetWMName(adesklets
.display
, adesklets
.window
, &text_prop_name
);
341 /* Window delete protocol registration */
342 if ((atom
=XInternAtom(adesklets
.display
,
343 "WM_DELETE_WINDOW",False
))!=None
)
344 XSetWMProtocols(adesklets
.display
,
345 adesklets
.window
, &atom
, 1);
348 XLowerWindow(adesklets
.display
,adesklets
.window
);
350 /* Map the window if needed */
351 if (mapped
) XMapWindow(adesklets
.display
,adesklets
.window
);
353 /* Eventually add capture of PropertyNotify on root window:
354 used for dynamic background reinitialisation */
355 XSelectInput(adesklets
.display
,
356 DefaultRootWindow(adesklets
.display
),
357 ((adesklets
.background_grab
)?PropertyChangeMask
:0));
359 /* Store new value */
360 adesklets
.managed
= managed
;
364 adesklets
.window
=(Window
)0;
366 adesklets
.window
=(Window
)0;
371 /*----------------------------------------------------------------------------*/
372 /* Reste to nothing the vector of fonts, color_ranges and color_modifiers.
373 Returns 1 if successful, 0 otherwise.
375 #define ADESKLETS_RESET_FUNCTION(name)\
377 adesklets_ ## name ## s_reset(void)\
380 if(adesklets.name ## s)\
381 adesklets.name ## s=vector_free(adesklets.name ## s);\
382 if(!adesklets.name ## s) {\
383 if((adesklets.name ## s=vector_init())) {\
384 adesklets.name## s->vector_free_item=\
385 name ## _vector_free_item;\
386 imlib_context_set_ ## name(NULL);\
393 ADESKLETS_RESET_FUNCTION(font
)
394 ADESKLETS_RESET_FUNCTION(color_range
)
395 ADESKLETS_RESET_FUNCTION(color_modifier
)
396 ADESKLETS_RESET_FUNCTION(filter
)
397 #undef ADESKLETS_RESET_FUNCTION
399 /*----------------------------------------------------------------------------*/
400 /* Reset to nothing a generic vector of something; you need
401 to provide a reference to the vector and another to a
402 vector_free_item_func function
405 adesklets_generic_reset(vector
** vec
, vector_free_item_func func
)
409 *vec
=vector_free(*vec
);
411 if((*vec
=vector_init())) {
412 (*vec
)->vector_free_item
=func
;
419 /*----------------------------------------------------------------------------*/
420 /* Generate placeholder function using preceeding generic function
422 #define ADESKLETS_RESET_FUNCTION(name) \
424 adesklets_ ## name ## s_reset(void) \
426 return adesklets_generic_reset(&adesklets.name ## s,\
427 name ## _vector_free_item);\
430 ADESKLETS_RESET_FUNCTION(polygon
)
431 ADESKLETS_RESET_FUNCTION(variable
)
432 #undef ADESKLETS_RESET_FUNCTION
434 /*----------------------------------------------------------------------------*/
435 /* Wrapper for xmenu_fire() that intercepts non-maskable events
436 from default menu ("Move", "Restart" and "Quit" events)
439 adesklets_menu_fire(int index
, char ** return_str
)
441 #ifndef X_DISPLAY_MISSING
443 if(index
>=0 && index
<adesklets
.menus
->pos
) {
444 *return_str
=xmenu_fire(adesklets
.display
,adesklets
.params
->scr
,
446 adesklets
.images
->content
[
447 (adesklets
.user_background_image
==-1)?
448 1:adesklets
.user_background_image
],
449 adesklets
.images
->content
[0],
450 adesklets
.transparency
,
452 /* Intercept default actions move and quit on the way back */
453 if(index
==0 && *return_str
) {
454 /* For move: verify the main window is not managed,
455 to avoid false move due to user-added "Move" */
457 #ifndef X_DISPLAY_MISSING
458 !adesklets
.managed
&&
460 strcmp(*return_str
,"Move")==0) {
461 if(xwindow_move_window(adesklets
.display
,
462 adesklets
.root
, adesklets
.window
,
464 XMapWindow(adesklets
.display
,adesklets
.window
);
465 if(!adesklets
.params
->no_update
)
466 cfgfile_update(adesklets
.params
);
470 /* For restart: verify there is a lock file open,
471 to avoid false restart due to user-added "Restart"
472 item in default menu */
473 if(adesklets
.lock
&& strcmp(*return_str
,"Restart")==0) {
475 adesklets
.restart_flag
=1;
478 if(strcmp(*return_str
,"Quit")==0) {
479 adesklets
.user_quit_flag
=adesklets
.quit_flag
=1;
494 /*----------------------------------------------------------------------------*/
495 /* Return 1 if current image is potentially shown on screen, 0 otherwise.
496 Mainly used to determine needs for screen updates */
501 image
= imlib_context_get_image();
503 return (image
==adesklets
.images
->content
[0]) ||
504 (adesklets
.transparency
&&
505 ((adesklets
.user_background_image
!=-1 &&
506 image
==adesklets
.images
->content
[adesklets
.user_background_image
]) ||
507 (image
==adesklets
.images
->content
[1])));
510 /*----------------------------------------------------------------------------*/
511 void usage(const char * name
)
513 int em
= (int)(getenv("ADESKLETS_EMBEDDED")!=NULL
);
515 printf("Usage: %s [OPTIONS] [script_id]\n\
516 adesklets interpreter and desklets launcher\n\n", name
);
518 -h, --help Display this help message\n");
521 -v, --version Get package version\n\
522 -f, --file In interpreter mode, use file as\n\
523 input stream instead of stdin\n");
525 #ifdef FRONTEND_SHELL_DRIVER
526 printf("Warning: for some reason, the shell frontend driver was not used.\n");
528 printf("Warning: the shell frontend driver support was not compiled in.\n");
532 /*----------------------------------------------------------------------------*/
534 adesklets_init(int argc
, char ** argv
)
537 char * adesklets_id
, * polling
;
538 char str
[CFGFILE_NAME_SIZE
];
541 struct sigaction new_action
, old_action
;
543 const char * OPTIONS
[] = {"-h", "--help", "-f", "--file", "-v", "--version" };
545 /* Seek --help string: otherwise, it is either a script name of junk */
547 if(strncmp(argv
[1],OPTIONS
[0],strlen(OPTIONS
[0]))==0 ||
548 strncmp(argv
[1],OPTIONS
[1],strlen(OPTIONS
[1]))==0) {
552 if (strncmp(argv
[1],OPTIONS
[4],strlen(OPTIONS
[4]))==0 ||
553 strncmp(argv
[1],OPTIONS
[5],strlen(OPTIONS
[5]))==0) {
554 printf("%s %s\n",PACKAGE
,VERSION
);
557 if (strncmp(argv
[1],OPTIONS
[2],strlen(OPTIONS
[2]))==0 ||
558 strncmp(argv
[1],OPTIONS
[3],strlen(OPTIONS
[3]))==0) {
560 if (!((file
=fopen(argv
[2],"r"))&&
561 dup2(fileno(file
),fileno(stdin
))>=0)) {
563 fprintf(stderr
,"Could not open file '%s' for reading\n",
577 /* Get original parent process id */
578 adesklets
.ppid
=getppid();
580 /* Get desklet ID from environment */
581 adesklets_id
= getenv("ADESKLETS_ID");
583 /* Get polling period from environment */
584 if ((polling
= getenv("ADESKLETS_POLLING"))) {
585 adesklets
.polling
= atoi(polling
);
586 adesklets
.polling
= (adesklets
.polling
<= 0)?
587 X_POLLING_PERIOD
:(1000000/adesklets
.polling
);
590 /* Set stdout and stderr to be unbuffered: this is needed
591 for proper pipe operation. stderr is always
593 if (setvbuf(stdout
,NULL
,_IONBF
,0)!=0) {
594 fprintf(stderr
,"Could not remove stdout buffer\n");
597 if (setvbuf(stderr
,NULL
,_IONBF
,0)!=0) {
598 fprintf(stderr
,"Could not remove stderr buffer\n");
602 /* Determine if interactive use */
603 command
.interactive
=isatty(fileno(stdin
));
605 /* Retrieve all parameters from config file */
606 adesklets
.params
= cfgfile_getinfo((!command
.interactive
)?argv
[pos
]:NULL
,
607 ((adesklets_id
!=NULL
)?
608 atoi(adesklets_id
):-1));
610 /* Make sure ADESKLETS_ID is set in current environment */
612 if (sprintf(str
,"%u",adesklets
.params
->id
)>0)
613 setenv("ADESKLETS_ID",str
,1);
615 /* If interactive use, print welcome message */
616 if(command
.interactive
) {
618 printf("Press TAB for hints.\n");
619 /* But if not, build and acquire lock file name */
620 } else if (adesklets_valid_desklet(argv
[pos
],0)) {
621 strncpy(str
,argv
[1],CFGFILE_NAME_SIZE
-1);
622 str
[CFGFILE_NAME_SIZE
-1]=0;
623 if (snprintf(adesklets
.lock_filename
,CFGFILE_NAME_SIZE
-1,
624 "%s/%s_uid%u_%s_%u.lock",
628 (char*)basename(str
),
629 adesklets
.params
->id
)<CFGFILE_NAME_SIZE
)
630 adesklets
.lock_filename
[CFGFILE_NAME_SIZE
-1]=0;
631 /* Now, lock the file: this will wait forever */
632 if ((adesklets
.lock
=fdopen(open(adesklets
.lock_filename
,
633 O_CREAT
|O_TRUNC
|O_WRONLY
,
637 lock
.l_whence
=SEEK_SET
;
640 debug("Lock file: acquiring %s\n",adesklets
.lock_filename
);
642 TRY(fcntl(fileno(adesklets
.lock
),F_SETLKW
,&lock
));
644 /* Write PPID and PID to lock file */
645 fprintf(adesklets
.lock
,"%d %d\n",adesklets
.ppid
,getpid());
646 fflush(adesklets
.lock
);
648 debug("Lock file: could not get lock\n");
649 fclose(adesklets
.lock
);
655 /* Force config file entry removal (or, at least, no registration)
656 at next update if invalid */
657 adesklets
.params
->no_update
=!
658 adesklets_valid_desklet(adesklets
.params
->applet
,1);
660 #ifndef X_DISPLAY_MISSING
661 /* Perform X Windows initialisation */
662 if ((adesklets
.display
=XOpenDisplay(NULL
))) {
663 /* Correct screen determination */
664 adesklets
.params
->scr
=(adesklets
.params
->scr
>=0 &&
665 adesklets
.params
->scr
<
666 ScreenCount(adesklets
.display
))?
667 adesklets
.params
->scr
:
668 DefaultScreen(adesklets
.display
);
670 /* X related imlib2 settings */
671 adesklets
.visual
=imlib_get_best_visual(adesklets
.display
,
672 adesklets
.params
->scr
,
674 imlib_context_set_display(adesklets
.display
);
675 imlib_context_set_visual(adesklets
.visual
);
676 imlib_context_set_colormap(DefaultColormap(adesklets
.display
,
677 adesklets
.params
->scr
));
679 /* Create main desklet window: managed if interactive,
681 adesklets_window_reset(command
.interactive
);
682 /* Install custom error handler */
683 XSetErrorHandler(xwindow_non_fatal_error_handler
);
687 debug("Could not connect to X server '%s'\n",XDisplayName(NULL
));
691 /* Locate true type fonts system-wide */
692 xwindow_locate_truetype_fonts();
694 /* Various Others imlib2 settings */
695 imlib_set_cache_size(2048*1024);
696 imlib_set_font_cache_size(512*1024);
697 imlib_set_color_usage(128);
698 imlib_context_set_dither(1);
699 imlib_context_set_blend(1);
700 imlib_context_set_color(255,255,255,255);
702 /* Set events in proper echo mode: no echo if interactive, echo otherwise. */
703 events_echo
=!command
.interactive
;
705 /* Initial settings */
706 if (adesklets_menus_reset()) {
707 if (adesklets_images_reset()) {
708 if (adesklets_fonts_reset()) {
709 if (adesklets_color_ranges_reset()) {
710 if (adesklets_color_modifiers_reset()) {
711 if (adesklets_filters_reset()) {
712 if (adesklets_polygons_reset()) {
713 if (adesklets_variables_reset()) {
714 /* Setup command interpreter */
715 if(command_interpreter_reset()) {
716 #ifdef FORCE_EXTENDED_CHARACTERS_INPUT
717 rl_variable_bind("input-meta", "on");
718 rl_variable_bind("convert-meta", "off");
719 rl_variable_bind("output-meta", "on");
721 /* Finally, set up event handler. This code snipset
722 was copied verbatim from the GNU C Library
723 Reference Manual (sigaction Function
725 new_action
.sa_handler
= termination_handler
;
726 sigemptyset (&new_action
.sa_mask
);
727 new_action
.sa_flags
= 0;
728 sigaction (SIGINT
, NULL
, &old_action
);
729 if (old_action
.sa_handler
!= SIG_IGN
)
730 sigaction (SIGINT
, &new_action
, NULL
);
731 sigaction (SIGHUP
, NULL
, &old_action
);
732 if (old_action
.sa_handler
!= SIG_IGN
)
733 sigaction (SIGHUP
, &new_action
, NULL
);
734 sigaction (SIGTERM
, NULL
, &old_action
);
735 if (old_action
.sa_handler
!= SIG_IGN
)
736 sigaction (SIGTERM
, &new_action
, NULL
);
737 /* If applicable, make an initial setup of
738 config file, just in case */
739 if (X_DISPLAY_SUPPORT
&&
740 adesklets
.display
&& adesklets
.window
)
741 cfgfile_update(adesklets
.params
);
745 fprintf(stderr
, "Cannot initialize command interpreter\n");
747 fprintf(stderr
, "Cannot initialize variables\n");
749 fprintf(stderr
, "Cannot initialize imlib polygons\n");
751 fprintf(stderr
, "Cannot initialize imlib filters\n");
753 fprintf(stderr
, "Cannot initialize imlib color modifiers\n");
755 fprintf(stderr
, "Cannot initialize imlib color ranges\n");
757 fprintf(stderr
, "Cannot initialize imlib fonts\n");
759 fprintf(stderr
, "Cannot initialize imlib images\n");
761 fprintf(stderr
, "Cannot initialize menus\n");
766 /*----------------------------------------------------------------------------*/
768 adesklets_events_loop(void)
775 #ifndef X_DISPLAY_MISSING
779 struct timespec sleep_time
;
780 command_enum command_type
;
782 #ifndef X_DISPLAY_MISSING
785 #ifdef HAVE_READLINE_HISTORY_H
786 HIST_ENTRY
** history
;
792 Imlib_Updates updates
;
796 Imlib_Color_Range color_range
;
797 Imlib_Color_Modifier color_modifier
;
799 ImlibPolygon polygon
;
800 Imlib_Load_Error error
;
804 debug("---------------------------------------------------------------\n");
806 updates
= imlib_updates_init();
809 command
.message_out
=0;
810 variable_expansion(adesklets
.variables
,&command
.line
);
811 params
=command_splitter(command
.line
,&command_type
);
813 if (!command
.recording
||
814 command_type
==CMD_PLAY
||
815 command_type
==CMD_START_RECORDING
||
816 command_type
==CMD_STOP_RECORDING
) {
817 switch(command_type
) {
819 /* NOTE : for semi-automated generation of an adesklets'
820 API for scripting languages, you should include
821 a prototype declaration similar to this one
822 in a comment (multi-lines comments allowed)
823 directly below case declaration. Look at protoize.sh
824 for further details. Commands that are also
825 Imlib2 primitives do not need to have prototypes
828 prototype(double gate) */
829 if (command
.replay_pos
) {
830 if (params
->pos
>=2) {
831 angle
=atof(params
->content
[1]);
832 #ifndef X_DISPLAY_MISSING
833 if (command
.replay_abort_on_events
) {
834 sleep_time
.tv_sec
=0; sleep_time
.tv_nsec
=adesklets
.polling
/10;
835 while (angle
>command_gate_chronometer())
836 if (adesklets
.display
&& adesklets
.window
&&
837 (XCheckWindowEvent(adesklets
.display
,
838 DefaultRootWindow(adesklets
.display
),
839 PropertyChangeMask
, &ev
) ||
840 XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
841 adesklets
.event_mask
,&ev
) ||
842 XCheckTypedWindowEvent(adesklets
.display
,adesklets
.window
,
843 ClientMessage
,&ev
))) {
844 XPutBackEvent(adesklets
.display
,&ev
);
847 nanosleep(&sleep_time
,NULL
);
850 if ((angle
-=command_gate_chronometer())>0) {
851 sleep_time
.tv_sec
=(time_t)angle
;
852 sleep_time
.tv_nsec
=(long)((angle
-floor(angle
))*1E9
);
854 debug("Sleep time: %f, or %d %d\n",
855 angle,sleep_time.tv_sec,sleep_time.tv_nsec);
857 nanosleep(&sleep_time
,NULL
);
859 #ifndef X_DISPLAY_MISSING
863 command_error("time gate not given\n");
865 command_error("ignoring timer gate, interpreter not replaying\n");
868 /* prototype([const char * command]) */
872 strcmp(params
->content
[1],COMMANDS
[i
].name
);
874 if (COMMANDS
[i
].name
)
875 command_ok("%s - %s\n",COMMANDS
[i
].name
, COMMANDS
[i
].doc
);
877 command_error("no help on '%s'\n", (char*)params
->content
[1]);
879 for(i
=0;COMMANDS
[i
].name
;++i
)
880 command_printf("%-25s -\t%s\n",COMMANDS
[i
].name
, COMMANDS
[i
].doc
);
884 /* prototype(void) */
885 command_ok("pong!\n");
888 /* prototype([int delay]) */
890 (((i
=atoi(params
->content
[1]))>0)?i
:5):5;
891 debug("Pausing for %d seconds.\n",i
);
895 /* prototype(void) */
896 command_ok("%s %s\n",PACKAGE
,VERSION
);
899 /* prototype(void) */
900 command_ok("adesklets id %u\n", adesklets
.params
->id
);
903 /* prototype([const char * filename]) */
904 #ifdef HAVE_READLINE_HISTORY_H
905 if ((history
=history_list())) {
906 for(i
=0;history
[i
];++i
);
907 command_printf("%d commands in history\n",i
);
908 if((file
=(params
->pos
>=2)?
909 fopen(command_subsplitter(command
.line
,1),"w"):stdout
)) {
910 for(i
=0;history
[i
];++i
)
911 if (params
->pos
>=2 || !command
.interactive
)
912 fprintf(file
,"%s\n",history
[i
]->line
);
914 fprintf(file
,"%d\t%s\n",i
,history
[i
]->line
);
915 if(file
!=stdout
) fclose(file
);
917 command_error("could not open output file for writing\n");
919 command_error("could not retrieve history list\n");
921 command_error("history support not compiled in\n");
925 /* prototype([const * char name, const * char value]) */
926 if ((i
=params
->pos
)>1) {
927 /* Verify variable name does not include a dollar character */
929 ((char*)params
->content
[1])[j
] &&
930 ((char*)params
->content
[1])[j
]!='$';
932 if (j
==strlen((char*)params
->content
[1])) {
933 /* First, search for existing variable */
935 vector_find(adesklets
.variables
,(uint
*)&j
,
936 variable_search_func
,(void*)params
->content
[1]);
938 /* Then, if it exists, just delete it */
940 vector_delete(adesklets
.variables
,(uint
)j
);
943 command_error("variable '%s' does not exist\n",
947 /* Then, set it back if there is a new content */
948 vector_push(adesklets
.variables
,
949 (void*)variable_create(
950 (char*)params
->content
[1],
951 (char*)command_subsplitter(command
.line
,2)));
954 command_error("variable name contains '$'\n");
956 /* Print out all variables */
957 command_printf("%d variable(s)\n", adesklets
.variables
->pos
);
958 for (i
=0;i
<adesklets
.variables
->pos
;++i
)
959 command_printf("%s=%s\n",
960 ((var_item
*)adesklets
.variables
->content
[i
])->name
,
961 ((var_item
*)adesklets
.variables
->content
[i
])->value
);
965 /* prototype(void) */
966 adesklets_variables_reset();
969 /* prototype(const char * string) */
971 case CMD_START_RECORDING
:
972 /* prototype(void) */
973 #ifdef HAVE_READLINE_HISTORY_H
974 /* This is a special case: you have to make sure to abort
975 current macro recording if called recursively from direct mode.
977 But this is not enough: you also need to ckeck we are not inside
978 a replay loop (indirect mode) because it would still be possible
979 to insert hidden calls to 'start_recording' inside a macro using
980 textual expansion (text variables) */
981 if (!command
.recording
&& !command
.replay_pos
)
982 command
.recording
=history_size()+1;
984 /* In non interactive mode, purge newly created history
986 if (command
.recording
&& !command
.interactive
)
987 for(i
=history_size()-1;i
>=command
.recording
-1;--i
)
988 free_history_entry(remove_history(i
));
989 command
.recording
=command
.replay_pos
=0;
990 command_error("cannot call this while already recording or \
991 replaying, aborded\n");
994 command_error("compiled without GNU history support\n");
997 case CMD_STOP_RECORDING
:
998 /* prototype(void) */
999 #ifdef HAVE_READLINE_HISTORY_H
1000 if (!command
.replay_pos
) {
1001 if (command
.recording
) {
1002 --command
.recording
;
1004 if(!command
.interactive
)
1005 /* In case of non interactive use, remove
1006 the reference to the 'stop_record' command */
1007 free_history_entry(remove_history(j
));
1008 if (command
.recording
!=j
)
1009 command_ok("recorded_commands %d %d\n",
1013 command_error("no command recorded\n");
1015 command_error("no recording taking place right now\n");
1017 command_error("cannot call stop while replaying, replay aborded\n");
1018 command
.recording
=0;
1020 command_error("compiled without GNU history support\n");
1023 case CMD_PLAY_GET_ABORT_ON_EVENTS
:
1024 /* prototype(void) */
1025 command_ok("abort_on_event %d\n",command
.replay_abort_on_events
);
1027 case CMD_PLAY_SET_ABORT_ON_EVENTS
:
1028 /* prototype(bool abort) */
1029 if (!command
.replay_pos
) {
1031 command
.replay_abort_on_events
=atoi((char*)params
->content
[1]);
1033 command_error("abort on event value not given\n");
1035 command_error("cannot be called inside a replay\n");
1038 /* prototype(int beginning, int end) */
1039 #ifdef HAVE_READLINE_HISTORY_H
1040 if (!command
.recording
&& !command
.replay_pos
) {
1041 if (params
->pos
>=3) {
1042 if (((i
=atoi(params
->content
[1]))<(j
=history_size())) &&
1043 ((k
=atoi(params
->content
[2]))<j
)) {
1044 if (i
>=0 && k
>=0 && (i
<=k
)) {
1045 gettimeofday(&command
.replay_time
,NULL
);
1046 command
.replay_pos
=i
+1;
1047 command
.replay_stop
=k
;
1050 command_error("invalid limits\n");
1052 command_error("limits out of range\n");
1054 command_error("missing start and stop limits\n");
1056 command
.recording
=command
.replay_pos
=0;
1057 command_error("cannot call this now, aborded\n");
1060 command_error("compiled without GNU history support\n");
1063 case CMD_CONTEXT_GET_DITHER
:
1064 command_ok("context dither %hhu\n",imlib_context_get_dither());
1066 case CMD_CONTEXT_GET_ANTI_ALIAS
:
1067 command_ok("context antialias %hhu\n",imlib_context_get_anti_alias());
1069 case CMD_CONTEXT_GET_BLEND
:
1070 command_ok("context blend %hhu\n",imlib_context_get_blend());
1072 case CMD_CONTEXT_GET_OPERATION
:
1073 i
=imlib_context_get_operation();
1074 command_ok("context operation %d (%s)\n",
1077 case CMD_CONTEXT_GET_CLIPRECT
:
1078 /* prototype(void) */
1079 imlib_context_get_cliprect(&x
,&y
,&i
,&j
);
1080 command_ok("context cliprect %d %d %d %d\n",x
,y
,i
,j
);
1082 case CMD_CONTEXT_GET_IMAGE
:
1083 image
=imlib_context_get_image();
1084 for(i
=0;i
<adesklets
.images
->pos
;++i
)
1085 if(adesklets
.images
->content
[i
]==image
)
1086 command_ok("context image %d\n",i
);
1088 case CMD_CONTEXT_GET_FONT
:
1089 if ((font
=imlib_context_get_font())) {
1090 for(i
=0;i
<adesklets
.fonts
->pos
;++i
)
1091 if(adesklets
.fonts
->content
[i
]==font
)
1092 command_ok("context font %d\n",i
);
1094 command_ok("context font -1 (unset)\n");
1096 case CMD_CONTEXT_GET_COLOR_RANGE
:
1097 if ((color_range
=imlib_context_get_color_range())) {
1098 for(i
=0;i
<adesklets
.color_ranges
->pos
;++i
)
1099 if(adesklets
.color_ranges
->content
[i
]==color_range
)
1100 command_ok("context colorrange %d\n",i
);
1102 command_ok("context colorrange -1 (unset)\n");
1104 case CMD_CONTEXT_GET_COLOR_MODIFIER
:
1105 if ((color_modifier
=imlib_context_get_color_modifier())) {
1106 for(i
=0;i
<adesklets
.color_modifiers
->pos
;++i
)
1107 if(adesklets
.color_modifiers
->content
[i
]==color_modifier
)
1108 command_ok("context colormodifier %d\n",i
);
1110 command_ok("context colormodifier -1 (unset)\n");
1112 case CMD_CONTEXT_GET_FILTER
:
1113 if ((filter
=imlib_context_get_filter())) {
1114 for(i
=0;i
<adesklets
.filters
->pos
;++i
)
1115 if(adesklets
.filters
->content
[i
]==filter
)
1116 command_ok("context filter %d\n",i
);
1118 command_ok("context filter -1 (unset)\n");
1120 case CMD_CONTEXT_GET_COLOR
:
1121 /* prototype(void) */
1122 imlib_context_get_color(&x
,&y
,&i
,&j
);
1123 command_ok("context color %hhu %hhu %hhu %hhu\n",
1124 x
&255,y
&255,i
&255,j
&255);
1126 case CMD_CONTEXT_GET_ANGLE
:
1127 angle
=imlib_context_get_angle();
1128 command_ok("context angle %4.2f\n",angle
);
1130 case CMD_CONTEXT_GET_DIRECTION
:
1131 i
=imlib_context_get_direction();
1132 command_ok("context direction %d (%s)\n",
1135 case CMD_CONTEXT_SET_DITHER
:
1136 /* prototype(bool dither) */
1138 imlib_context_set_dither((char)atoi(params
->content
[1]));
1140 command_error("dither value not given\n");
1142 case CMD_CONTEXT_SET_ANTI_ALIAS
:
1143 /* prototype(bool anti_alias) */
1145 imlib_context_set_anti_alias((char)atoi(params
->content
[1]));
1147 command_error("anti alias value not given\n");
1149 case CMD_CONTEXT_SET_BLEND
:
1150 /* prototype(bool blend) */
1152 imlib_context_set_blend((char)atoi(params
->content
[1]));
1154 command_error("blend value not given\n");
1156 case CMD_CONTEXT_SET_OPERATION
:
1157 /* prototype(enum OPERATIONS operation) */
1158 if(params
->pos
>=2) {
1159 for(i
=0;OPERATIONS
[i
];++i
)
1160 if(strncmp(OPERATIONS
[i
],params
->content
[1],
1161 strlen(params
->content
[1]))==0)
1163 imlib_context_set_operation((OPERATIONS
[i
])?
1164 i
:((j
=atoi(params
->content
[1])))<4?j
:0);
1166 command_error("operation not given\n");
1168 case CMD_CONTEXT_SET_CLIPRECT
:
1169 if (params
->pos
>=5) {
1170 if ((x
=atoi((char*)params
->content
[1]))>=0 &&
1171 (y
=atoi((char*)params
->content
[2]))>=0 &&
1172 (i
=atoi((char*)params
->content
[3]))>=0 &&
1173 (j
=atoi((char*)params
->content
[4]))>=0) {
1174 imlib_context_set_cliprect(x
,y
,i
,j
);
1176 command_error("clipping rectangle coordinates out of range\n");
1178 command_error("clipping rectangle description not given\n");
1180 case CMD_CONTEXT_SET_IMAGE
:
1181 if (params
->pos
>=2) {
1182 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1183 i
<adesklets
.images
->pos
) {
1184 imlib_context_set_image(adesklets
.images
->content
[i
]);
1186 command_error("image ID %d out of range\n",i
);
1188 command_error("image ID not given\n");
1190 case CMD_CONTEXT_SET_FONT
:
1191 /* prototype([int font]) */
1193 if (params
->pos
>=2) {
1194 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1195 i
<adesklets
.fonts
->pos
) {
1196 imlib_context_set_font(adesklets
.fonts
->content
[i
]);
1200 imlib_context_set_font(NULL
);
1202 command_error("font ID %d out of range\n",i
);
1206 imlib_context_set_font(NULL
);
1208 if(j
) command_ok("context font unset\n");
1210 case CMD_CONTEXT_SET_COLOR_RANGE
:
1211 /* prototype([int color_range]) */
1213 if (params
->pos
>=2) {
1214 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1215 i
<adesklets
.color_ranges
->pos
) {
1216 imlib_context_set_color_range(adesklets
.color_ranges
->content
[i
]);
1220 imlib_context_set_color_range(NULL
);
1222 command_error("color range ID %d out of range\n",i
);
1226 imlib_context_set_color_range(NULL
);
1228 if(j
) command_ok("context color range unset\n");
1230 case CMD_CONTEXT_SET_COLOR_MODIFIER
:
1231 /* prototype([int color_modifier]) */
1233 if (params
->pos
>=2) {
1234 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1235 i
<adesklets
.color_modifiers
->pos
) {
1236 imlib_context_set_color_modifier(
1237 adesklets
.color_modifiers
->content
[i
]);
1241 imlib_context_set_color_modifier(NULL
);
1243 command_error("color modifier ID %d out of range\n",i
);
1247 imlib_context_set_color_modifier(NULL
);
1249 if(j
) command_ok("context color modifier unset\n");
1251 case CMD_CONTEXT_SET_FILTER
:
1252 /* prototype([int filter]) */
1254 if (params
->pos
>=2) {
1255 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1256 i
<adesklets
.filters
->pos
) {
1257 imlib_context_set_filter(adesklets
.filters
->content
[i
]);
1261 imlib_context_set_filter(NULL
);
1263 command_error("filter ID %d out of range\n",i
);
1267 imlib_context_set_filter(NULL
);
1269 if(j
) command_ok("context filter unset\n");
1271 case CMD_CONTEXT_SET_COLOR
:
1273 imlib_context_set_color(atoi(params
->content
[1]),
1274 atoi(params
->content
[2]),
1275 atoi(params
->content
[3]),
1276 atoi(params
->content
[4]));
1278 command_error("color RGBA description not given\n");
1280 case CMD_CONTEXT_SET_ANGLE
:
1281 if (params
->pos
>=2) {
1282 imlib_context_set_angle(atof(params
->content
[1]));
1284 command_error("angle not given\n");
1286 case CMD_CONTEXT_SET_DIRECTION
:
1287 /* prototype(enum DIRECTIONS direction) */
1288 if(params
->pos
>=2) {
1289 for(i
=0;DIRECTIONS
[i
];++i
)
1290 if(strncmp(DIRECTIONS
[i
],params
->content
[1],
1291 strlen(params
->content
[1]))==0)
1293 imlib_context_set_direction((DIRECTIONS
[i
])?
1294 i
:((j
=atoi(params
->content
[1])))<5?j
:0);
1296 command_error("direction not given\n");
1298 case CMD_ADD_COLOR_TO_COLOR_RANGE
:
1299 if(imlib_context_get_color_range()) {
1300 i
=(params
->pos
>=2)?atoi(params
->content
[1]):0;
1301 imlib_add_color_to_color_range(i
);
1303 command_error("no color range selected\n");
1305 case CMD_BLEND_IMAGE_ONTO_IMAGE
:
1306 if (params
->pos
>=11) {
1307 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1308 i
<adesklets
.images
->pos
) {
1309 imlib_blend_image_onto_image(adesklets
.images
->content
[i
],
1310 atoi(params
->content
[2]),
1311 atoi(params
->content
[3]),
1312 atoi(params
->content
[4]),
1313 atoi(params
->content
[5]),
1314 atoi(params
->content
[6]),
1315 atoi(params
->content
[7]),
1316 atoi(params
->content
[8]),
1317 atoi(params
->content
[9]),
1318 atoi(params
->content
[10]));
1319 if (image_is_shown())
1320 updates
= imlib_update_append_rect(updates
,
1321 atoi(params
->content
[7]),
1322 atoi(params
->content
[8]),
1323 atoi(params
->content
[9]),
1324 atoi(params
->content
[10]));
1326 command_error("image ID %d out of range\n",i
);
1328 command_error("not enough parameters given - need ten\n");
1330 case CMD_BLEND_IMAGE_ONTO_IMAGE_AT_ANGLE
:
1331 if (params
->pos
>=11) {
1332 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1333 i
<adesklets
.images
->pos
) {
1334 imlib_blend_image_onto_image_at_angle(
1335 adesklets
.images
->content
[i
],
1336 atoi(params
->content
[2]),
1337 atoi(params
->content
[3]),
1338 atoi(params
->content
[4]),
1339 atoi(params
->content
[5]),
1340 atoi(params
->content
[6]),
1341 atoi(params
->content
[7]),
1342 atoi(params
->content
[8]),
1343 atoi(params
->content
[9]),
1344 atoi(params
->content
[10]));
1345 if (image_is_shown())
1346 /* We do not bother: we update everything */
1347 updates
= imlib_update_append_rect(updates
,
1349 imlib_image_get_width(),
1350 imlib_image_get_height());
1352 command_error("image ID %d out of range\n",i
);
1354 command_error("not enough parameters given - need ten\n");
1356 case CMD_BLEND_IMAGE_ONTO_IMAGE_SKEWED
:
1357 if (params
->pos
>=12) {
1358 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1359 i
<adesklets
.images
->pos
) {
1360 imlib_blend_image_onto_image_skewed(adesklets
.images
->content
[i
],
1361 atoi(params
->content
[2]),
1362 atoi(params
->content
[3]),
1363 atoi(params
->content
[4]),
1364 atoi(params
->content
[5]),
1365 atoi(params
->content
[6]),
1366 atoi(params
->content
[7]),
1367 atoi(params
->content
[8]),
1368 atoi(params
->content
[9]),
1369 atoi(params
->content
[10]),
1370 atoi(params
->content
[11]),
1371 atoi(params
->content
[12]));
1372 if (image_is_shown())
1373 /* We do not bother: we update everything */
1374 updates
= imlib_update_append_rect(updates
,
1376 imlib_image_get_width(),
1377 imlib_image_get_height());
1379 command_error("image ID %d out of range\n",i
);
1381 command_error("not enough parameters given - need twelve\n");
1383 case CMD_APPLY_FILTER
:
1384 /* WARNING: there is a initialisation bug in imlib2 prior
1385 version 1.2.0 (cvs of 11/20/04) that sets the dynamic filters
1386 never to work if an image loader is not used
1387 at least once before (this has to do with
1388 lt_dlinit() being called at the wrong place...).
1389 We can do nothing about this: upgrade your imlib2 lib!
1391 prototype(const char * script)
1393 if(params
->pos
>=2) {
1394 menu_str
=command_subsplitter(command
.line
,1);
1395 if(!strstr(menu_str
,"[]")) {
1396 imlib_apply_filter(menu_str
);
1397 if (image_is_shown())
1398 updates
=imlib_update_append_rect(updates
,0,0,
1399 imlib_image_get_width(),
1400 imlib_image_get_height());
1403 command_error("variadic filters forbidden\n");
1405 command_error("filter description not given\n");
1408 "tint(x=0,y=0,w=100,h=100,alpha=100,red=155,green=25,blue=25);"
1411 case CMD_GET_TEXT_SIZE
:
1412 /* prototype(const char * text) */
1413 if(imlib_context_get_font()) {
1414 if(params
->pos
>=2) {
1415 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,1));
1416 imlib_get_text_size(menu_str
,
1419 command_ok("text size %d %d\n",i
,j
);
1421 command_error("text string not given or blank\n");
1423 command_error("no font selected.\n");
1425 case CMD_GET_TEXT_ADVANCE
:
1426 /* prototype(const char * text) */
1427 if(imlib_context_get_font()) {
1428 if(params
->pos
>=2) {
1429 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,1));
1430 imlib_get_text_advance(menu_str
,&i
,&j
);
1432 command_ok("text advance %d %d\n",i
,j
);
1434 command_error("text string not given or blank\n");
1436 command_error("no font selected.\n");
1439 if(imlib_context_get_font()) {
1440 if(params
->pos
>=4) {
1441 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,3));
1442 imlib_text_draw(atoi(params
->content
[1]),
1443 atoi(params
->content
[2]),
1445 if (image_is_shown()) {
1446 imlib_get_text_size(menu_str
,&x
,&y
);
1447 updates
= imlib_update_append_rect(updates
,
1448 atoi(params
->content
[1]),
1449 atoi(params
->content
[2]),
1454 command_error("text string not given or blank\n");
1456 command_error("no font selected.\n");
1458 case CMD_MODIFY_COLOR_MODIFIER_GAMMA
:
1459 if(imlib_context_get_color_modifier()) {
1460 if(params
->pos
>=2) {
1461 imlib_modify_color_modifier_gamma(atof(params
->content
[1]));
1463 command_error("gamma value not given\n");
1465 command_error("no context color modifier selected\n");
1467 case CMD_MODIFY_COLOR_MODIFIER_BRIGHTNESS
:
1468 if(imlib_context_get_color_modifier()) {
1469 if(params
->pos
>=2) {
1470 imlib_modify_color_modifier_brightness(atof(params
->content
[1]));
1472 command_error("brightness value not given\n");
1474 command_error("no context color modifier selected\n");
1476 case CMD_MODIFY_COLOR_MODIFIER_CONTRAST
:
1477 if(imlib_context_get_color_modifier()) {
1478 if(params
->pos
>=2) {
1479 imlib_modify_color_modifier_contrast(atof(params
->content
[1]));
1481 command_error("contrast value not given\n");
1483 command_error("no context color modifier selected\n");
1485 case CMD_GET_COLOR_MODIFIER_TABLES
:
1486 /* prototype(void) */
1487 /* Throw all 1024 table entries in RGBA orders */
1488 if(imlib_context_get_color_modifier()) {
1489 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1490 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1491 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1492 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1493 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1494 tables
[2],tables
[3]);
1497 command_printf("%hhu ", tables
[i
][j
]);
1498 command_printf("\n");
1500 command_error("memory allocation problem\n");
1502 if(tables
[i
]) free(tables
[i
]);
1504 command_error("no context color modifier selected\n");
1507 case CMD_SET_COLOR_MODIFIER_TABLES
:
1508 /* prototype(unsigned char * table) */
1509 if(imlib_context_get_color_modifier()) {
1510 if (params
->pos
==1025) {
1511 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1512 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1513 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1514 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1517 tables
[i
][j
]=(DATA8
)atoi(params
->content
[(i
*256)+j
+1]);
1518 imlib_set_color_modifier_tables(tables
[0],tables
[1],
1519 tables
[2],tables
[3]);
1520 command_ok("set_color_modifier_tables\n");
1522 command_error("memory allocation problem");
1524 if(tables
[i
]) free(tables
[i
]);
1526 command_error("Invalid number of entries - need 1024\n");
1528 command_error("no context color modifier selected\n");
1530 case CMD_GET_COLOR_MODIFIER_VALUE
:
1531 /* prototype(enum RGBA_TABLES table, int index) */
1532 /* NOTE: this is not an original imlib2 function.
1533 it was included as a convenience for
1535 if(imlib_context_get_color_modifier()) {
1536 if (params
->pos
>=3) {
1537 for(i
=0;RGBA_TABLES
[i
];++i
)
1538 if(strncmp(RGBA_TABLES
[i
],
1540 strlen(params
->content
[1]))==0)
1542 i
=(RGBA_TABLES
[i
])?i
:atoi(params
->content
[1])%4;
1544 if((j
=atoi(params
->content
[2]))<256 && j
>=0) {
1545 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1546 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1547 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1548 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1549 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1550 tables
[2],tables
[3]);
1551 command_ok("value %s %hhu\n",
1553 (char)tables
[i
][j
]&255);
1556 command_error("memory allocation problem\n");
1558 if(tables
[i
]) free(tables
[i
]);
1560 command_error("index value %d out of range\n",j
);
1562 command_error("parameters not given - need two\n");
1564 command_error("no context color modifier selected\n");
1566 case CMD_SET_COLOR_MODIFIER_VALUE
:
1567 /* prototype(enum RGBA_TABLES table, int index, int value) */
1568 /* NOTE: this is not an original imlib2 function.
1569 it was included as a convenience for
1571 if(imlib_context_get_color_modifier()) {
1572 if (params
->pos
>=4) {
1573 for(i
=0;RGBA_TABLES
[i
];++i
)
1574 if(strncmp(RGBA_TABLES
[i
],
1576 strlen(params
->content
[1]))==0)
1578 i
=(RGBA_TABLES
[i
])?i
:atoi(params
->content
[1])%4;
1580 if((j
=atoi(params
->content
[2]))<256 && j
>=0) {
1581 if ((x
=atoi(params
->content
[3]))<256 && x
>=0) {
1582 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1583 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1584 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1585 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1586 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1587 tables
[2],tables
[3]);
1589 imlib_set_color_modifier_tables(tables
[0],tables
[1],
1590 tables
[2],tables
[3]);
1592 command_error("memory allocation problem\n");
1594 if(tables
[i
]) free(tables
[i
]);
1596 command_error("value %d out of range\n",x
);
1598 command_error("index value %d out of range\n",j
);
1600 command_error("parameters not given - need three\n");
1602 command_error("no context color modifier selected\n");
1604 case CMD_APPLY_COLOR_MODIFIER
:
1605 if(imlib_context_get_color_modifier()) {
1606 imlib_apply_color_modifier();
1607 if(image_is_shown())
1608 updates
=imlib_update_append_rect(updates
,0,0,
1609 imlib_image_get_width(),
1610 imlib_image_get_height());
1612 command_error("no context color modifier selected\n");
1614 case CMD_APPLY_COLOR_MODIFIER_TO_RECTANGLE
:
1615 if(imlib_context_get_color_modifier()) {
1616 if (params
->pos
>=5) {
1617 imlib_apply_color_modifier_to_rectangle(
1618 (x
=atoi(params
->content
[1])),
1619 (y
=atoi(params
->content
[2])),
1620 (i
=atoi(params
->content
[3])),
1621 (j
=atoi(params
->content
[4])));
1622 if (image_is_shown())
1623 updates
=imlib_update_append_rect(updates
,x
,y
,i
,j
);
1625 command_error("rectangles coordinates not given\n");
1627 command_error("no context color modifier selected\n");
1629 case CMD_LOAD_IMAGE_WITHOUT_CACHE
:
1630 if (params
->pos
>=2) {
1631 menu_str
=command_subsplitter(command
.line
,1);
1632 if ((image
=imlib_load_image_without_cache(menu_str
))) {
1633 if (vector_push(adesklets
.images
,image
))
1634 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1636 command_error("memory allocation problem\n");
1638 command_error("could not load image '%s'\n", menu_str
);
1640 command_error("image file name not given\n");
1642 case CMD_LOAD_IMAGE
:
1643 if (params
->pos
>=2) {
1644 menu_str
=command_subsplitter(command
.line
,1);
1645 if ((image
=imlib_load_image_with_error_return(menu_str
,&error
))) {
1646 if (vector_push(adesklets
.images
,image
))
1647 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1649 command_error("memory allocation problem\n");
1651 command_error("could not load image '%s' - %s\n",
1652 menu_str
,LOAD_ERRORS
[(int)error
]);
1654 command_error("image file name not given\n");
1656 case CMD_SAVE_IMAGE
:
1657 if (params
->pos
>=2) {
1658 menu_str
=command_subsplitter(command
.line
,1);
1659 imlib_save_image_with_error_return(menu_str
,&error
);
1660 if(error
!=IMLIB_LOAD_ERROR_NONE
)
1661 command_error("%s\n",LOAD_ERRORS
[(int)error
]);
1663 command_error("image file name not given\n");
1665 case CMD_CREATE_IMAGE
:
1666 if (params
->pos
>=3) {
1667 if((i
=atoi(params
->content
[1]))>0 &&
1668 (j
=atoi(params
->content
[2]))>0) {
1669 if((image
=imlib_create_image(i
,j
))) {
1670 xwindow_context_save(IMLIB_IMAGE
|IMLIB_BLEND
|IMLIB_COLOR
);
1671 imlib_context_set_image(image
);
1672 imlib_image_set_has_alpha(1);
1673 imlib_context_set_blend(0);
1674 imlib_context_set_color(0,0,0,0);
1675 imlib_image_fill_rectangle(0,0,i
,j
);
1676 xwindow_context_restore();
1677 if (vector_push(adesklets
.images
,image
))
1678 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1680 command_error("memory allocation problem\n");
1682 command_error("imlib image allocation error\n");
1684 command_error("image dimensions out of range\n");
1686 command_error("image dimensions were not given\n");
1688 case CMD_CREATE_IMAGE_USING_DATA
:
1689 /* This uses imlib_create_image_using_copied_data(),
1690 so DATA * data can be freed afterward.
1691 As in CMD_IMAGE_GET_DATA, data is expected to be
1693 if (params
->pos
>=3) {
1694 if ((width
=atoi(params
->content
[1]))>0 &&
1695 (height
=atoi(params
->content
[2]))>0) {
1696 if(width
*height
*4==params
->pos
-3) {
1697 if((data
=(DATA32
*)malloc(sizeof(DATA32
)*width
*height
))) {
1698 for(i
=0;i
<width
*height
;++i
)
1700 ((atoi((char*)params
->content
[i
*4+3])&255)<<16)|
1701 ((atoi((char*)params
->content
[i
*4+4])&255)<<8)|
1702 ((atoi((char*)params
->content
[i
*4+5])&255)<<0)|
1703 ((atoi((char*)params
->content
[i
*4+6])&255)<<24);
1704 if ((image
=imlib_create_image_using_copied_data(width
,
1707 xwindow_context_save(IMLIB_IMAGE
);
1708 imlib_context_set_image(image
);
1709 imlib_image_set_has_alpha(1);
1710 xwindow_context_restore();
1711 if(vector_push(adesklets
.images
,image
))
1712 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1714 command_error("memory allocation problem");
1716 command_error("imlib image allocation error\n");
1720 command_error("memory allocation problem\n");
1722 command_error("image dimensions and data lenght mismatch\n");
1724 command_error("image dimensions out of range\n");
1726 command_error("image dimensions were not given\n");
1728 case CMD_CLONE_IMAGE
:
1729 if((image
=imlib_clone_image())) {
1730 if (vector_push(adesklets
.images
,image
))
1731 command_ok("cloned image %d\n",adesklets
.images
->pos
-1);
1733 command_error("memory allocation problem");
1735 command_error("imlib image allocation error\n");
1737 case CMD_FREE_IMAGE
:
1738 /* This does not react as imlib_free_image:
1739 - image ID has to be given
1740 - If current context image is freed, context
1741 is put back on foreground image
1742 - If image corresponding to user_background_image
1743 is freed, user_background_image is reset.
1745 prototype(int image)
1747 if(params
->pos
>=2) {
1748 if((i
=atoi((char*)params
->content
[1]))<adesklets
.images
->pos
&&
1751 j
=(imlib_context_get_image()==adesklets
.images
->content
[i
]);
1752 if (vector_delete(adesklets
.images
,i
)) {
1753 if(i
==adesklets
.user_background_image
) {
1754 adesklets
.user_background_image
=-1;
1755 xwindow_context_save(IMLIB_IMAGE
);
1756 imlib_context_set_image(adesklets
.images
->content
[0]);
1757 updates
=imlib_update_append_rect(updates
,0,0,
1758 imlib_image_get_width(),
1759 imlib_image_get_height());
1760 xwindow_context_restore();
1763 if(i
<adesklets
.user_background_image
)
1764 --adesklets
.user_background_image
;
1766 imlib_context_set_image(adesklets
.images
->content
[0]);
1768 command_error("memory desallocation problem\n");
1770 command_error("it is forbidden to unload image %d\n",i
);
1772 command_error("image ID %d out of range\n",i
);
1774 command_error("image ID not given\n");
1777 if(params
->pos
>=2) {
1778 if (strlen(params
->content
[1])>=3 &&
1779 index(params
->content
[1],'/')) {
1780 if ((font
=imlib_load_font(params
->content
[1]))) {
1781 if(vector_push(adesklets
.fonts
,font
))
1782 command_ok("new font %d\n", adesklets
.fonts
->pos
-1);
1784 command_error("memory allocation problem");
1786 command_error("font '%s' could not be loaded\n",
1787 (char*)params
->content
[1]);
1790 "font description incorrect - should be `name/size'\n");
1792 command_error("font description not given\n");
1795 /* This does not react as imlib_free_font:
1796 - font ID has to be given
1797 - If current font is freed, context
1802 if(params
->pos
>=2) {
1803 if((i
=atoi((char*)params
->content
[1]))
1804 <adesklets
.fonts
->pos
&&
1806 j
=(imlib_context_get_font()==
1807 adesklets
.fonts
->content
[i
]);
1808 if (vector_delete(adesklets
.fonts
,i
)) {
1810 imlib_context_set_font(NULL
);
1812 command_error("memory desallocation problem\n");
1814 command_error("font ID %d out of range\n",i
);
1816 command_error("font ID not given\n");
1818 case CMD_LIST_FONTS
:
1819 /* prototype(void) */
1820 list
=imlib_list_fonts(&j
);
1821 command_printf("%d fonts found\n",j
);
1823 command_printf("%s ",list
[i
]);
1824 command_printf("\n");
1825 imlib_free_font_list(list
,j
);
1827 case CMD_LIST_FONT_PATH
:
1828 /* prototype(void) */
1829 list
=imlib_list_font_path(&j
);
1830 command_printf("%d font_path found\n",j
);
1832 command_printf("%s\n",list
[i
]);
1834 case CMD_ADD_PATH_TO_FONT_PATH
:
1835 if(params
->pos
>=2) {
1836 imlib_add_path_to_font_path(command_subsplitter(command
.line
,1));
1838 command_error("font path not given\n");
1840 case CMD_REMOVE_PATH_FROM_FONT_PATH
:
1841 if(params
->pos
>=2) {
1842 imlib_remove_path_from_font_path(
1843 command_subsplitter(command
.line
,1));
1844 debug("%s\n",command_subsplitter(command
.line
,1));
1846 command_error("font path not given\n");
1848 case CMD_CREATE_COLOR_RANGE
:
1849 if((color_range
=imlib_create_color_range())) {
1850 if(vector_push(adesklets
.color_ranges
,color_range
))
1851 command_ok("new colorrange %d\n",adesklets
.color_ranges
->pos
-1);
1853 command_error("memory allocation problem\n");
1855 command_error("imlib allocation problem\n");
1857 case CMD_FREE_COLOR_RANGE
:
1858 /* This does not react as imlib_free_color_range:
1859 - color_range ID has to be given
1860 - If current color range is freed, context
1863 prototype(int color_range)
1865 if(params
->pos
>=2) {
1866 if((i
=atoi((char*)params
->content
[1]))
1867 <adesklets
.color_ranges
->pos
&&
1869 j
=(imlib_context_get_color_range()==
1870 adesklets
.color_ranges
->content
[i
]);
1871 if (vector_delete(adesklets
.color_ranges
,i
)) {
1873 imlib_context_set_color_range(NULL
);
1875 command_error("memory desallocation problem\n");
1877 command_error("color range ID %d out of range\n",i
);
1879 command_error("color range ID not given\n");
1881 case CMD_CREATE_FILTER
:
1882 /* prototype(void) */
1883 if((filter
=imlib_create_filter(0))) {
1884 if(vector_push(adesklets
.filters
,filter
))
1885 command_ok("new filter %d\n",adesklets
.filters
->pos
-1);
1887 command_error("memory allocation problem\n");
1889 command_error("imlib allocation problem\n");
1891 case CMD_FREE_FILTER
:
1892 /* This does not react as imlib_free_filter:
1893 - filter ID has to be given
1894 - If current filter is freed, context
1897 prototype(int filter)
1899 if(params
->pos
>=2) {
1900 if((i
=atoi((char*)params
->content
[1]))
1901 <adesklets
.filters
->pos
&&
1903 j
=(imlib_context_get_filter()==
1904 adesklets
.filters
->content
[i
]);
1905 if (vector_delete(adesklets
.filters
,i
)) {
1907 imlib_context_set_filter(NULL
);
1909 command_error("memory desallocation problem\n");
1911 command_error("filter ID %d out of range\n",i
);
1913 command_error("filter ID not given\n");
1915 case CMD_CREATE_COLOR_MODIFIER
:
1916 if((color_modifier
=imlib_create_color_modifier())) {
1917 if(vector_push(adesklets
.color_modifiers
,color_modifier
))
1918 command_ok("new colormodifier %d\n",
1919 adesklets
.color_modifiers
->pos
-1);
1921 command_error("memory allocation problem\n");
1923 command_error("imlib allocation problem\n");
1925 case CMD_FREE_COLOR_MODIFIER
:
1926 /* This does not react as imlib_free_color_modifier:
1927 - color_range ID has to be given
1928 - If current color modifier is freed, context
1931 prototype(int color_modifier)
1933 if(params
->pos
>=2) {
1934 if((i
=atoi((char*)params
->content
[1]))
1935 <adesklets
.color_modifiers
->pos
&&
1937 j
=(imlib_context_get_color_modifier()==
1938 adesklets
.color_modifiers
->content
[i
]);
1939 if (vector_delete(adesklets
.color_modifiers
,i
)) {
1941 imlib_context_set_color_modifier(NULL
);
1943 command_error("memory desallocation problem\n");
1945 command_error("color modifier ID %d out of range\n",i
);
1947 command_error("color modifier ID not given\n");
1949 case CMD_POLYGON_NEW
:
1950 if((polygon
=imlib_polygon_new())) {
1951 if(vector_push(adesklets
.polygons
,polygon
))
1952 command_ok("new polygon %d\n",adesklets
.polygons
->pos
-1);
1954 command_error("memory allocation problem\n");
1956 command_error("imlib allocation problem\n");
1958 case CMD_POLYGON_FREE
:
1959 if(params
->pos
>=2) {
1960 if((i
=atoi(params
->content
[1]))>=0 &&
1961 i
<adesklets
.polygons
->pos
) {
1962 if(!vector_delete(adesklets
.polygons
,i
))
1963 command_error("memory desallocation problem\n");
1965 command_error("polygon ID %d out of range\n",i
);
1967 command_error("polygon ID not given\n");
1969 case CMD_POLYGON_ADD_POINT
:
1970 if(params
->pos
>=4) {
1971 if((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
1972 imlib_polygon_add_point(adesklets
.polygons
->content
[i
],
1973 atoi(params
->content
[2]),
1974 atoi(params
->content
[3]));
1976 command_error("polygon ID %d out of range\n",i
);
1978 command_error("not enough parameters given - need 3\n");
1980 case CMD_IMAGES_RESET_ALL
:
1981 /* prototype(void) */
1982 adesklets_images_reset();
1984 case CMD_IMAGES_INFO
:
1985 /* prototype(void) */
1986 xwindow_context_save(IMLIB_IMAGE
);
1987 command_printf("%d images\n",adesklets
.images
->pos
);
1988 for(i
=0;i
<adesklets
.images
->pos
;++i
) {
1989 imlib_context_set_image(adesklets
.images
->content
[i
]);
1990 command_printf("id %d width %d height %d alpha %hhu filename %s\n",
1992 imlib_image_get_width(), imlib_image_get_height(),
1993 imlib_image_has_alpha(), imlib_image_get_filename());
1995 xwindow_context_restore();
1997 case CMD_FONTS_RESET_ALL
:
1998 /* prototype(void) */
1999 adesklets_fonts_reset();
2001 case CMD_FONTS_INFO
:
2002 /* prototype(void) */
2003 command_printf("%d fonts\n",adesklets
.fonts
->pos
);
2005 case CMD_COLOR_RANGES_RESET_ALL
:
2006 /* prototype(void) */
2007 adesklets_color_ranges_reset();
2009 case CMD_COLOR_RANGES_INFO
:
2010 /* prototype(void) */
2011 command_printf("%d color ranges\n",adesklets
.color_ranges
->pos
);
2013 case CMD_COLOR_MODIFIERS_RESET_ALL
:
2014 /* prototype(void) */
2015 adesklets_color_modifiers_reset();
2017 case CMD_COLOR_MODIFIERS_INFO
:
2018 /* prototype(void) */
2019 command_printf("%d color modifiers\n",adesklets
.color_modifiers
->pos
);
2021 case CMD_FILTERS_RESET_ALL
:
2022 /* prototype(void) */
2023 adesklets_filters_reset();
2025 case CMD_FILTERS_INFO
:
2026 /* prototype(void) */
2027 command_printf("%d filters\n",adesklets
.filters
->pos
);
2029 case CMD_POLYGONS_RESET_ALL
:
2030 /* prototype(void) */
2031 adesklets_polygons_reset();
2033 case CMD_POLYGONS_INFO
:
2034 /* prototype(void) */
2035 command_printf("%d polygons\n",adesklets
.polygons
->pos
);
2037 case CMD_IMAGE_HAS_ALPHA
:
2038 command_ok("image alpha %hhu\n",imlib_image_has_alpha());
2040 case CMD_IMAGE_GET_WIDTH
:
2041 command_ok("image width %d\n",imlib_image_get_width());
2043 case CMD_IMAGE_GET_HEIGHT
:
2044 command_ok("image height %d\n",imlib_image_get_height());
2046 case CMD_IMAGE_GET_FILENAME
:
2047 command_ok("image filename %s\n",imlib_image_get_filename());
2049 case CMD_IMAGE_GET_DATA
:
2050 /* This uses imlib_image_get_data_for_reading_only(),
2051 so there is no need to invalidate image. Print final result
2053 if((data
=imlib_image_get_data_for_reading_only())) {
2054 width
=imlib_image_get_width();
2055 height
=imlib_image_get_height();
2056 command_printf("image data - %d %d\n",width
,height
);
2057 for(i
=0;i
<width
*height
;++i
)
2058 command_printf("%hhu %hhu %hhu %hhu ",
2059 ((data
[i
]&(255<<16))>>16),
2060 ((data
[i
]&(255<<8))>>8),
2062 ((data
[i
]&(255<<24))>>24));
2063 command_printf("\n");
2065 command_error("imlib data fetch problem\n");
2067 case CMD_IMAGE_QUERY_PIXEL
:
2068 /* prototype(int x, int y) */
2069 if (params
->pos
>=2) {
2070 imlib_image_query_pixel(atoi(params
->content
[1]),
2071 atoi(params
->content
[2]),
2073 command_ok("pixel value %hhu %hhu %hhu %hhu\n",
2074 (char)color
.red
&255,(char)color
.green
&255,
2075 (char)color
.blue
&255,(char)color
.alpha
&255);
2077 command_error("pixel coordinates not given\n");
2079 case CMD_IMAGE_SET_HAS_ALPHA
:
2080 /* prototype(bool has_alpha) */
2082 imlib_image_set_has_alpha((char)atoi(params
->content
[1]));
2084 command_error("alpha value not given\n");
2086 case CMD_IMAGE_SET_CHANGES_ON_DISK
:
2087 /* prototype(void) */
2088 imlib_image_set_changes_on_disk();
2090 case CMD_IMAGE_SET_FORMAT
:
2092 imlib_image_set_format(params
->content
[1]);
2094 command_error("format string not given\n");
2096 case CMD_IMAGE_FILTER_RECURSE
:
2097 /* prototype(void) */
2098 if(imlib_context_get_filter()) {
2099 for(i
=0,j
=imlib_image_get_width();i
<j
;++i
) {
2100 imlib_image_filter();
2102 if(i
%(j
/10)==(j
/10)-1)
2103 debug("We are %d0 percents through.\n", (i
+1)*10/j
);
2106 if(image_is_shown())
2107 updates
=imlib_update_append_rect(updates
,0,0,
2108 imlib_image_get_width(),
2109 imlib_image_get_height());
2112 command_error("no filter selected\n");
2114 case CMD_IMAGE_DRAW_LINE
:
2115 if(params
->pos
>=5) {
2116 imlib_image_draw_line(atoi(params
->content
[1]),
2117 atoi(params
->content
[2]),
2118 atoi(params
->content
[3]),
2119 atoi(params
->content
[4]),0);
2120 if (image_is_shown())
2121 updates
= imlib_update_append_rect(updates
,
2122 atoi(params
->content
[1]),
2123 atoi(params
->content
[2]),
2124 atoi(params
->content
[3])-
2125 atoi(params
->content
[1]),
2126 atoi(params
->content
[4])-
2127 atoi(params
->content
[2]));
2129 command_error("line coordinates not given\n");
2131 case CMD_IMAGE_DRAW_RECTANGLE
:
2132 if(params
->pos
>=5) {
2133 imlib_image_draw_rectangle(atoi(params
->content
[1]),
2134 atoi(params
->content
[2]),
2135 atoi(params
->content
[3]),
2136 atoi(params
->content
[4]));
2137 if (image_is_shown())
2138 updates
= imlib_update_append_rect(updates
,
2139 atoi(params
->content
[1]),
2140 atoi(params
->content
[2]),
2141 atoi(params
->content
[3]),
2142 atoi(params
->content
[4]));
2144 command_error("rectangle description not given\n");
2146 case CMD_IMAGE_FILL_RECTANGLE
:
2147 if(params
->pos
>=5) {
2148 imlib_image_fill_rectangle(atoi(params
->content
[1]),
2149 atoi(params
->content
[2]),
2150 atoi(params
->content
[3]),
2151 atoi(params
->content
[4]));
2152 if (image_is_shown())
2153 updates
= imlib_update_append_rect(updates
,
2154 atoi(params
->content
[1]),
2155 atoi(params
->content
[2]),
2156 atoi(params
->content
[3]),
2157 atoi(params
->content
[4]));
2159 command_error("rectangle description not given\n");
2161 case CMD_IMAGE_FILL_COLOR_RANGE_RECTANGLE
:
2162 if (imlib_context_get_color_range()) {
2163 if(params
->pos
>=6) {
2164 imlib_image_fill_color_range_rectangle(atoi(params
->content
[1]),
2165 atoi(params
->content
[2]),
2166 atoi(params
->content
[3]),
2167 atoi(params
->content
[4]),
2168 atof(params
->content
[5]));
2169 if (image_is_shown())
2170 updates
= imlib_update_append_rect(updates
,
2171 atoi(params
->content
[1]),
2172 atoi(params
->content
[2]),
2173 atoi(params
->content
[3]),
2174 atoi(params
->content
[4]));
2176 command_error("not enough parameters given - need five\n");
2178 command_error("no color range selected\n");
2180 case CMD_IMAGE_DRAW_ELLIPSE
:
2181 if(params
->pos
>=5) {
2182 imlib_image_draw_ellipse(atoi(params
->content
[1]),
2183 atoi(params
->content
[2]),
2184 atoi(params
->content
[3]),
2185 atoi(params
->content
[4]));
2186 if (image_is_shown())
2187 updates
= imlib_update_append_rect(updates
,
2188 atoi(params
->content
[1])-
2189 atoi(params
->content
[3]),
2190 atoi(params
->content
[2])-
2191 atoi(params
->content
[4]),
2192 2*atoi(params
->content
[3]),
2193 2*atoi(params
->content
[4]));
2195 command_error("ellipse description not given\n");
2197 case CMD_IMAGE_FILL_ELLIPSE
:
2198 if(params
->pos
>=5) {
2199 imlib_image_fill_ellipse(atoi(params
->content
[1]),
2200 atoi(params
->content
[2]),
2201 atoi(params
->content
[3]),
2202 atoi(params
->content
[4]));
2203 if (image_is_shown())
2204 updates
= imlib_update_append_rect(updates
,
2205 atoi(params
->content
[1])-
2206 atoi(params
->content
[3]),
2207 atoi(params
->content
[2])-
2208 atoi(params
->content
[4]),
2209 2*atoi(params
->content
[3]),
2210 2*atoi(params
->content
[4]));
2212 command_error("ellipse description not given\n");
2214 case CMD_IMAGE_COPY_ALPHA_TO_IMAGE
:
2215 if(params
->pos
>=4) {
2216 if((i
=atoi(params
->content
[1]))>=0 &&
2217 i
<adesklets
.images
->pos
) {
2218 imlib_image_copy_alpha_to_image(adesklets
.images
->content
[i
],
2219 atoi(params
->content
[2]),
2220 atoi(params
->content
[3]));
2221 if(image_is_shown()) {
2222 xwindow_context_save(IMLIB_IMAGE
);
2223 imlib_context_set_image(adesklets
.images
->content
[i
]);
2224 updates
= imlib_update_append_rect(updates
,
2225 atoi(params
->content
[2]),
2226 atoi(params
->content
[3]),
2227 imlib_image_get_width(),
2228 imlib_image_get_height());
2229 xwindow_context_restore();
2232 command_error("image ID out of range\n");
2234 command_error("parameters not given\n");
2236 case CMD_IMAGE_COPY_ALPHA_RECTANGLE_TO_IMAGE
:
2237 if(params
->pos
>=8) {
2238 if((i
=atoi(params
->content
[1]))>=0 &&
2239 i
<adesklets
.images
->pos
) {
2240 imlib_image_copy_alpha_rectangle_to_image(
2241 adesklets
.images
->content
[i
],
2242 atoi(params
->content
[2]),
2243 atoi(params
->content
[3]),
2244 atoi(params
->content
[4]),
2245 atoi(params
->content
[5]),
2246 atoi(params
->content
[6]),
2247 atoi(params
->content
[7]));
2249 if(image_is_shown())
2250 updates
= imlib_update_append_rect(updates
,
2251 atoi(params
->content
[6]),
2252 atoi(params
->content
[7]),
2253 atoi(params
->content
[4]),
2254 atoi(params
->content
[5]));
2256 command_error("image ID out of range\n");
2258 command_error("parameters not given - need height\n");
2260 case CMD_IMAGE_DRAW_POLYGON
:
2261 if (params
->pos
>=3) {
2262 if ((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
2263 imlib_image_draw_polygon(adesklets
.polygons
->content
[i
],
2264 ((char*)params
->content
[2])[0]);
2265 if(image_is_shown()) {
2266 imlib_polygon_get_bounds(adesklets
.polygons
->content
[i
],
2268 updates
= imlib_update_append_rect(updates
,x
,y
,i
-x
,j
-y
);
2271 command_error("polygon ID %d out of range\n",i
);
2273 command_error("parameters not given\n");
2275 case CMD_IMAGE_FILL_POLYGON
:
2276 if (params
->pos
>=2) {
2277 if ((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
2278 imlib_image_fill_polygon(adesklets
.polygons
->content
[i
]);
2279 if(image_is_shown()) {
2280 imlib_polygon_get_bounds(adesklets
.polygons
->content
[i
],
2282 updates
= imlib_update_append_rect(updates
,x
,y
,i
-x
,j
-y
);
2285 command_error("polygon ID %d out of range\n",i
);
2287 command_error("polygon ID not given\n");
2289 case CMD_IMAGE_FLIP_HORIZONTAL
:
2290 imlib_image_flip_horizontal();
2291 if (image_is_shown())
2292 updates
=imlib_update_append_rect(updates
,0,0,
2293 imlib_image_get_width(),
2294 imlib_image_get_height());
2296 case CMD_IMAGE_FLIP_VERTICAL
:
2297 imlib_image_flip_vertical();
2298 if (image_is_shown())
2299 updates
=imlib_update_append_rect(updates
,0,0,
2300 imlib_image_get_width(),
2301 imlib_image_get_height());
2303 case CMD_IMAGE_FLIP_DIAGONAL
:
2304 if(((image
=imlib_context_get_image()))!=
2305 adesklets
.images
->content
[0] &&
2306 image
!= adesklets
.images
->content
[1] &&
2307 (adesklets
.user_background_image
==-1 ||
2308 image
!= adesklets
.images
->content
[
2309 adesklets
.user_background_image
]))
2310 imlib_image_flip_diagonal();
2312 command_error("operation forbidden on this image\n");
2314 case CMD_IMAGE_ORIENTATE
:
2315 if (params
->pos
>=2) {
2316 if((i
=atoi(params
->content
[1])%4)%2==0 ||
2317 (((image
=imlib_context_get_image())!=
2318 adesklets
.images
->content
[0] &&
2319 image
!= adesklets
.images
->content
[1])))
2320 imlib_image_orientate(i
);
2322 command_error("operation forbidden on this image\n");
2324 command_error("orientation not given\n");
2326 case CMD_IMAGE_BLUR
:
2327 if (params
->pos
>=2) {
2328 imlib_image_blur(atof(params
->content
[1]));
2329 updates
=imlib_update_append_rect(updates
,0,0,
2330 imlib_image_get_width(),
2331 imlib_image_get_height());
2333 command_error("Blur radius not given\n");
2335 case CMD_IMAGE_SHARPEN
:
2336 if (params
->pos
>=2) {
2337 imlib_image_sharpen(atof(params
->content
[1]));
2338 updates
=imlib_update_append_rect(updates
,0,0,
2339 imlib_image_get_width(),
2340 imlib_image_get_height());
2342 command_error("Sharpen radius not given\n");
2344 #define FILTER_SET(op)\
2345 if(imlib_context_get_filter()) {\
2346 if (params->pos>=7)\
2347 imlib_filter_set ## op(atoi(params->content[1]),\
2348 atoi(params->content[2]),\
2349 atoi(params->content[3]),\
2350 atoi(params->content[4]),\
2351 atoi(params->content[5]),\
2352 atoi(params->content[6]));\
2354 command_error("missing parameters - need six\n");\
2356 command_error("no filter selected\n")
2357 case CMD_FILTER_SET
:
2358 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2361 case CMD_FILTER_SET_RED
:
2362 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2365 case CMD_FILTER_SET_GREEN
:
2366 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2369 case CMD_FILTER_SET_BLUE
:
2370 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2373 case CMD_FILTER_SET_ALPHA
:
2374 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2378 #define FILTER_SET(op)\
2379 if(imlib_context_get_filter()) {\
2380 if (params->pos>=5)\
2381 imlib_filter_ ## op(atoi(params->content[1]),\
2382 atoi(params->content[2]),\
2383 atoi(params->content[3]),\
2384 atoi(params->content[4]));\
2386 command_error("missing parameters - need four\n");\
2388 command_error("no filter selected\n")
2389 case CMD_FILTER_CONSTANTS
:
2390 /* prototype(int a, int r, int g, int b) */
2391 FILTER_SET(constants
);
2393 case CMD_FILTER_DIVISORS
:
2394 /* prototype(int a, int r, int g, int b) */
2395 FILTER_SET(divisors
);
2399 /* prototype(int menu) */
2400 #ifndef X_DISPLAY_MISSING
2401 if (adesklets
.display
&& adesklets
.window
) {
2402 if(params
->pos
>=2) {
2403 i
=atoi((char*)params
->content
[1]);
2404 if (adesklets_menu_fire(i
,(char**)&menu_str
)) {
2405 if (adesklets
.user_event_mask
&MenuFireMask
)
2406 event("menufire %d %s\n",i
,menu_str
);
2408 command_error("menu fire error\n");
2411 command_error("menu ID not given\n");
2414 command_error("X connection or window missing\n");
2416 case CMD_MENU_RESET_ALL
:
2417 /* prototype(void) */
2418 if (!adesklets_menus_reset())
2419 command_error("internal consistency problem with menu\n");
2421 case CMD_MENU_ADD_MENU
:
2422 /* prototype(void) */
2423 if (!vector_push(adesklets
.menus
,xmenu_init()))
2424 command_error("could not add a new menu\n");
2426 command_ok("new menu %d\n",adesklets
.menus
->pos
-1);
2428 case CMD_MENU_ADD_SUBMENU
:
2429 /* prototype(const char * submenu) */
2430 if (params
->pos
>=2) {
2431 if (!xmenu_push_submenu(MENU(adesklets
.menus
->pos
-1),
2433 strlen(COMMANDS
[CMD_MENU_ADD_SUBMENU
].name
)))
2434 command_error("could not create submenu\n");
2436 if ((menu_str=dupstr_utf8(command_subsplitter(command.line,1)))) {
2437 if (!xmenu_push_submenu(MENU(adesklets.menus->pos-1),menu_str))
2438 command_error("could not create submenu\n");
2443 command_error("submenu description not given\n");
2445 case CMD_MENU_ADD_ITEM
:
2446 /* prototype(const char * add_item) */
2447 if(params
->pos
>=2) {
2448 if(!xmenu_push_item(MENU(adesklets
.menus
->pos
-1),
2450 strlen(COMMANDS
[CMD_MENU_ADD_ITEM
].name
)))
2451 command_error("could not create item\n");
2453 command_error("item description not given\n");
2455 case CMD_MENU_ADD_SEPARATOR
:
2456 /* prototype(void) */
2457 if(!xmenu_push_item(MENU(adesklets
.menus
->pos
-1),"-"))
2458 command_error("could not add separator\n");
2460 case CMD_MENU_END_SUBMENU
:
2461 /* prototype(void) */
2462 if(!xmenu_end_submenu(MENU(adesklets
.menus
->pos
-1)))
2463 command_error("could not end submenu\n");
2465 case CMD_EVENT_CATCH
:
2466 /* prototype(voidvoid) */
2467 #ifndef X_DISPLAY_MISSING
2468 if (adesklets
.display
&& adesklets
.window
) {
2469 if(params
->pos
>=2) {
2470 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2471 if(strncmp(X_WINDOW_EVENTS
[i
].name
,params
->content
[1],
2472 strlen(X_WINDOW_EVENTS
[i
].name
))==0)
2474 adesklets
.user_event_mask
|=
2475 X_WINDOW_EVENTS
[(X_WINDOW_EVENTS
[i
].name
)?
2476 i
:atoi(params
->content
[1])%i
].mask
;
2477 adesklets
.event_mask
=(BASE_EVENT_MASK
)|
2478 (adesklets
.user_event_mask
&
2479 ~(BackgroundGrabMask
|MenuFireMask
));
2480 XSelectInput(adesklets
.display
,adesklets
.window
,
2481 adesklets
.event_mask
);
2483 command_error("event to catch not given\n");
2486 command_error("X connection or window missing\n");
2488 case CMD_EVENT_UNCATCH
:
2489 /* prototype(voidvoid) */
2490 #ifndef X_DISPLAY_MISSING
2491 if(adesklets
.display
&& adesklets
.window
) {
2492 if(params
->pos
>=2) {
2493 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2494 if(strncmp(X_WINDOW_EVENTS
[i
].name
,params
->content
[1],
2495 strlen(X_WINDOW_EVENTS
[i
].name
))==0)
2497 mask
=X_WINDOW_EVENTS
[(X_WINDOW_EVENTS
[i
].name
)?
2498 i
:atoi(params
->content
[1])%i
].mask
;
2499 /* If event was already selected, purge all remaining
2500 events of that type if applicable */
2501 if(mask
!=BackgroundGrabMask
&&
2502 mask
!=MenuFireMask
&&
2503 (adesklets
.event_mask
&mask
) &&
2504 !((BASE_EVENT_MASK
)&mask
))
2505 while(XCheckWindowEvent(adesklets
.display
,
2506 adesklets
.window
,mask
,&ev
));
2507 adesklets
.user_event_mask
&=~mask
;
2508 adesklets
.event_mask
=(BASE_EVENT_MASK
)|
2509 (adesklets
.user_event_mask
2510 &~(BackgroundGrabMask
|MenuFireMask
));
2511 XSelectInput(adesklets
.display
,adesklets
.window
,
2512 adesklets
.event_mask
);
2514 command_error("event to uncatch not given\n");
2517 command_error("X connection or window missing\n");
2519 case CMD_EVENTS_RESET_ALL
:
2520 /* prototype(voidvoid) */
2521 #ifndef X_DISPLAY_MISSING
2522 if(adesklets
.display
&& adesklets
.window
) {
2523 XSelectInput(adesklets
.display
,adesklets
.window
,
2525 while(XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
2526 adesklets
.user_event_mask
&
2527 ~(BASE_EVENT_MASK
)&~BackgroundGrabMask
&
2530 adesklets
.user_event_mask
=0;
2531 adesklets
.event_mask
=BASE_EVENT_MASK
;
2534 command_error("X connection or window missing\n");
2536 case CMD_EVENTS_INFO
:
2537 /* prototype(void) */
2538 #ifndef X_DISPLAY_MISSING
2539 if (adesklets
.display
&& adesklets
.window
) {
2540 for(i
=0,j
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2541 if(adesklets
.user_event_mask
&X_WINDOW_EVENTS
[i
].mask
)
2543 command_printf("%d events caught\n",j
);
2544 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2545 if(adesklets
.user_event_mask
&X_WINDOW_EVENTS
[i
].mask
)
2546 command_printf("%d (%s)\n",i
, X_WINDOW_EVENTS
[i
].name
);
2549 command_error("X connection or window missing\n");
2551 case CMD_EVENTS_GET_ECHO
:
2552 /* prototype(void) */
2553 command_ok("events echo %d\n", events_echo
);
2555 case CMD_EVENTS_SET_ECHO
:
2556 /* prototype(voidvoid) */
2557 if(params
->pos
>=2) {
2558 if (events_echo
!=(i
=atoi(params
->content
[1]))) {
2565 command_error("echo value not given\n");
2567 case CMD_EVENTS_GET_SEND_SIGUSR1
:
2568 /* prototype(void) */
2569 command_ok("events send_sigusr1 %d\n",(events_ppid
)?1:0);
2571 case CMD_EVENTS_SET_SEND_SIGUSR1
:
2572 /* prototype(voidvoid) */
2574 events_ppid
=(atoi(params
->content
[1]))?adesklets
.ppid
:0;
2576 command_error("send SIGUSR1 status not given\n");
2578 case CMD_EVENTS_PURGE
:
2579 /* prototype(voidvoid) */
2580 command_printf("%d events to purge\n",(events
)?events
->pos
:0);
2583 case CMD_WINDOW_RESET
:
2584 /* prototype(enum WINDOW_MANAGER manager) */
2585 if(params
->pos
>=2) {
2586 for(i
=0;WINDOW_MANAGER
[i
];++i
)
2587 if(strncmp(WINDOW_MANAGER
[i
],params
->content
[1],
2588 strlen(params
->content
[1]))==0)
2590 if (adesklets_window_reset((WINDOW_MANAGER
[i
])?i
:
2591 atoi(params
->content
[1]))) {
2592 if (adesklets_menus_reset()) {
2593 if (!adesklets_images_reset_background(0))
2594 command_error("could not reset background images\n");
2596 command_error("could not reset menus\n");
2598 command_error("could not reset main window\n");
2600 command_error("Window manager status not given\n");
2602 case CMD_WINDOW_SHOW
:
2603 /* prototype(void) */
2604 #ifndef X_DISPLAY_MISSING
2605 if (adesklets
.display
&& adesklets
.window
) {
2606 if (!XMapWindow(adesklets
.display
,adesklets
.window
))
2607 command_error("could not map the window\n");
2610 command_error("X connection or window missing\n");
2612 case CMD_WINDOW_HIDE
:
2613 /* prototype(void) */
2614 #ifndef X_DISPLAY_MISSING
2615 if (adesklets
.display
&& adesklets
.window
) {
2616 if(!XUnmapWindow(adesklets
.display
,adesklets
.window
))
2617 command_error("could not unmap the window\n");
2620 command_error("X connection or window missing\n");
2622 case CMD_WINDOW_RESIZE
:
2623 /* prototype(int width, int height) */
2624 if (params
->pos
>=3) {
2625 if((i
=atoi(params
->content
[1]))>0 &&
2626 (j
=atoi(params
->content
[2]))>0) {
2627 #ifndef X_DISPLAY_MISSING
2628 if (adesklets
.display
&& adesklets
.window
) {
2629 if (!xwindow_resize_window(adesklets
.display
,adesklets
.window
,
2630 adesklets
.params
,i
,j
,0))
2631 command_error("did not resize window\n");
2634 if (!adesklets_images_reset_background(1,i
,j
))
2635 command_error("no window, and could not resize images\n");
2636 #ifndef X_DISPLAY_MISSING
2639 } else command_error("resize out of range\n");
2640 } else command_error("resize dimensions no given\n");
2642 case CMD_WINDOW_GET_TRANSPARENCY
:
2643 /* prototype(void) */
2644 command_ok("window transparency %d\n",adesklets
.transparency
);
2646 case CMD_WINDOW_GET_BACKGROUND_GRAB
:
2647 /* prototype(void) */
2648 if(X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
)
2649 command_ok("window backgroundgrab %d\n",adesklets
.background_grab
);
2652 "background grab irrelevant - no X window connection or window\n");
2654 case CMD_WINDOW_GET_BACKGROUND_IMAGE
:
2655 /* prototype(void) */
2656 if(X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
)
2657 command_ok("background image %d\n",
2658 (adesklets
.user_background_image
!=-1)?
2659 adesklets
.user_background_image
:1);
2662 "background window irrelevant - no X window connection or window\n");
2664 case CMD_WINDOW_GET_MANAGED_STATUS
:
2665 /* prototype(void) */
2666 #ifndef X_DISPLAY_MISSING
2667 if(adesklets
.display
&& adesklets
.window
) {
2668 command_ok("window managedstatus %d (%s)\n",
2670 WINDOW_MANAGER
[adesklets
.managed
]);
2672 command_error("X connection or window missing\n");
2674 command_error("X connection or window missing\n");
2677 case CMD_WINDOW_SET_TRANSPARENCY
:
2678 /* prototype(bool transparency) */
2679 if (params
->pos
>=2) {
2680 i
=atoi((char*)params
->content
[1]);
2681 if (adesklets
.transparency
!=i
) {
2682 adesklets
.transparency
=i
;
2683 /* If there is a chance, invalidate the entire window */
2684 #ifndef X_DISPLAY_MISSING
2685 xwindow_window_size(adesklets
.display
,adesklets
.window
,
2687 updates
= imlib_update_append_rect(updates
,
2688 0,0,(int)width
,(int)height
);
2691 } else command_error("transparency value not given\n");
2693 case CMD_WINDOW_SET_BACKGROUND_GRAB
:
2694 /* prototype(bool grab) */
2695 if (params
->pos
>=2) {
2696 if (adesklets
.background_grab
!=(i
=atoi(params
->content
[1]))) {
2697 if ((adesklets
.background_grab
=i
))
2698 adesklets_images_reset_background(0);
2700 xwindow_context_save(IMLIB_IMAGE
|IMLIB_BLEND
|IMLIB_COLOR
);
2701 imlib_context_set_image(adesklets
.images
->content
[1]);
2702 imlib_context_set_color(0,0,0,255);
2703 imlib_context_set_blend(0);
2704 imlib_image_fill_rectangle(0,0,
2705 imlib_image_get_width(),
2706 imlib_image_get_height());
2707 xwindow_context_restore();
2710 #ifndef X_DISPLAY_MISSING
2711 xwindow_window_size(adesklets
.display
,adesklets
.window
,
2713 updates
= imlib_update_append_rect(updates
,
2714 0,0,(int)width
,(int)height
);
2718 command_error("background grab value not given\n");
2720 case CMD_WINDOW_SET_BACKGROUND_IMAGE
:
2721 /* prototype(int image) */
2722 if (X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
) {
2723 if(params
->pos
>=2) {
2724 if((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.images
->pos
) {
2726 xwindow_context_save(IMLIB_IMAGE
);
2727 imlib_context_set_image(adesklets
.images
->content
[0]);
2728 j
=imlib_image_get_width();
2729 k
=imlib_image_get_height();
2731 imlib_context_set_image(adesklets
.images
->content
[i
]);
2732 x
=imlib_image_get_width();
2733 y
=imlib_image_get_height();
2735 adesklets
.user_background_image
=i
;
2736 updates
= imlib_update_append_rect(updates
,
2740 command_error("incorrect dimensions image\n");
2742 /* Drop silently reset to actual foreground */
2743 adesklets
.user_background_image
=-1;
2744 updates
= imlib_update_append_rect(updates
,
2747 xwindow_context_restore();
2750 "foreground image cannot be selected as background\n");
2752 command_error("image ID %d out of range\n",i
);
2754 command_error("background image ID not given\n");
2757 "background window irrelevant - no X window connection or window\n");
2759 case CMD_SCREEN_GET_WIDTH
:
2760 /* prototype(void) */
2761 #ifndef X_DISPLAY_MISSING
2762 if (adesklets
.display
) {
2763 command_ok("screen width %d\n",
2764 WidthOfScreen(ScreenOfDisplay(adesklets
.display
,
2765 adesklets
.params
->scr
)));
2767 command_error("X connection missing\n");
2769 command_error("X connection missing\n");
2772 case CMD_SCREEN_GET_HEIGHT
:
2773 /* prototype(void) */
2774 #ifndef X_DISPLAY_MISSING
2775 if(adesklets
.display
) {
2776 command_ok("screen height %d\n",
2777 HeightOfScreen(ScreenOfDisplay(adesklets
.display
,
2778 adesklets
.params
->scr
)));
2780 command_error("X connection missing\n");
2782 command_error("X connection missing\n");
2785 case CMD_SCREEN_GET_DEPTH
:
2786 /* prototype(void) */
2787 if(adesklets
.display
)
2788 command_ok("screen depth %d\n",adesklets
.depth
);
2790 command_error("X connection missing\n");
2792 case CMD_GET_CHARSET
:
2793 /* prototype(void) */
2795 if (command
.from_page
)
2796 command_ok("charset %s\n",command
.from_page
);
2799 command_ok("charset -1 (unset)\n");
2801 case CMD_SET_CHARSET
:
2802 /* prototype(const char * charset) */
2804 if (params
->pos
>=2) {
2805 if ((cd
=iconv_open("UTF8",params
->content
[1]))!=(iconv_t
)(-1)) {
2807 iconv_close(command
.cd
);
2810 if (command
.from_page
) {
2811 free(command
.from_page
);
2812 command
.from_page
=NULL
;
2814 command
.from_page
=dupstr(params
->content
[1]);
2817 command_error("could not establish conversion from '%s' to 'UTF8'\n",
2818 params
->content
[1]);
2821 iconv_close(command
.cd
);
2824 if (command
.from_page
) {
2825 free(command
.from_page
);
2826 command
.from_page
=NULL
;
2828 command_ok("charset -1 (unset)\n");
2831 command_error("charset conversion not compiled in\n");
2834 case CMD_CHARSET_STATUS
:
2835 /* prototype(void) */
2837 command_ok("charset_status 1\n");
2839 command_ok("charset_status 0 (charset conversion not compiled in)\n");
2843 /* prototype(void) */
2844 #ifndef X_DISPLAY_MISSING
2845 command_ok("x_status %d (%s%s')\n",(adesklets
.display
)?1:0,
2846 (adesklets
.display
)?"connected to '":"disconnected from '",
2847 XDisplayName(NULL
));
2849 command_ok("x_status 0 (X Window support not compiled in)\n");
2853 /* prototype(void) */
2854 command_ok("quitting...\n");
2855 adesklets
.quit_flag
=1;
2858 if(blank_line(command
.line
))
2859 command
.message_out
=1;
2861 command_error("syntax error\n");
2862 } /* switch(command_type) */
2863 } /* if command.recording */
2864 if (!command
.message_out
) command_ok("%s\n",command
.line
);
2865 vector_free(params
);
2867 command
.ready
=0; ++command
.rank
;
2868 if (command
.interactive
&& !command
.replay_pos
&&
2869 !adesklets
.quit_flag
&& !adesklets
.restart_flag
)
2870 command_interpreter_reset();
2871 } else {printf("\n"); adesklets
.quit_flag
=1;} /* if (command.line) */
2872 } /* if(command.ready) */
2874 #ifndef X_DISPLAY_MISSING
2875 while(adesklets
.display
&& adesklets
.window
&&
2876 (XCheckWindowEvent(adesklets
.display
,
2877 DefaultRootWindow(adesklets
.display
),
2878 PropertyChangeMask
, &ev
) ||
2879 XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
2880 adesklets
.event_mask
,&ev
) ||
2881 XCheckTypedWindowEvent(adesklets
.display
,adesklets
.window
,
2882 ClientMessage
,&ev
))) {
2885 /* Refresh updates list */
2886 updates
= imlib_update_append_rect(updates
,
2887 ev
.xexpose
.x
,ev
.xexpose
.y
,
2888 ev
.xexpose
.width
,ev
.xexpose
.height
);
2890 case PropertyNotify
:
2891 /* This event is generated from root window only:
2892 we use it to check for dynamic root window background change,
2893 as enlightment has used it for years. Look at
2894 xwindow_updated_background() for details */
2895 if (ev
.xproperty
.atom
!= None
&&
2896 ev
.xproperty
.atom
== XInternAtom (adesklets
.display
,
2897 "_XROOTPMAP_ID", True
) &&
2898 adesklets
.background_grab
&&
2899 xwindow_updated_background(adesklets
.display
,
2900 ev
.xproperty
.window
,
2902 /* Recompute the background images */
2903 adesklets_images_reset_background(0);
2905 /* Because the setting of background_pixmap as ParentRelative
2906 on the main window, there is no need to invalidate
2907 it here: an Expose event will be automatically generated. */
2910 /* Fire default menu on left button click */
2911 if(ev
.xbutton
.button
==3) {
2912 #ifdef CONTROL_ON_CONTEXT_MENU
2913 if (ev
.xbutton
.state
& ControlMask
) {
2915 if ((adesklets_menu_fire(0,&menu_str
)) &&
2916 (adesklets
.user_event_mask
&MenuFireMask
))
2917 event("menufire 0 %s\n",menu_str
);
2918 #ifdef CONTROL_ON_CONTEXT_MENU
2920 ev
.xbutton
.window
= adesklets
.root
;
2921 XSendEvent(adesklets
.display
, ev
.xbutton
.window
,
2922 False
, ButtonPressMask
, &ev
);
2923 debug("menu call redirected to root\n");
2927 if(adesklets
.user_event_mask
&ButtonPressMask
)
2928 event("buttonpress %d %d %d\n",
2929 ev
.xbutton
.x
,ev
.xbutton
.y
,ev
.xbutton
.button
);
2932 if(ev
.xbutton
.button
!=3)
2933 event("buttonrelease %d %d %d\n",
2934 ev
.xbutton
.x
,ev
.xbutton
.y
,ev
.xbutton
.button
);
2937 event("motionnotify %d %d\n",
2938 ev
.xmotion
.x
, ev
.xmotion
.y
);
2941 event("enternotify %d %d\n",
2942 ev
.xcrossing
.x
, ev
.xcrossing
.y
);
2945 event("leavenotify %d %d\n",
2946 ev
.xcrossing
.x
, ev
.xcrossing
.y
);
2948 case ConfigureNotify
:
2949 if (ev
.xconfigure
.window
==adesklets
.window
)
2950 if (xwindow_window_moved_or_resized(ev
.xconfigure
.x
,
2952 ev
.xconfigure
.width
,
2953 ev
.xconfigure
.height
))
2954 adesklets_images_reset_background(0);
2957 /* Check for the "WM_WINDOW_DELETE" protocol */
2958 if (ev
.xclient
.data
.l
[0] == XInternAtom(adesklets
.display
,
2961 debug("Message from window manager: quitting!\n");
2962 adesklets
.user_quit_flag
=adesklets
.quit_flag
=1;
2964 debug("Unknown client message sent.\n");
2967 /* Untreated cases */
2972 /* Now, performs main window updates as needed */
2973 xwindow_update_window(adesklets
.window
, &updates
,
2974 adesklets
.images
->content
[
2975 (adesklets
.user_background_image
!=-1)?
2976 adesklets
.user_background_image
:1],
2977 adesklets
.images
->content
[0],
2978 adesklets
.transparency
);
2980 if(updates
) imlib_updates_free(updates
);
2982 } while(!adesklets
.quit_flag
&& !adesklets
.restart_flag
&&
2983 (command_replayer() || command_interpreter(adesklets
.polling
)));
2986 /*----------------------------------------------------------------------------*/
2987 int adesklets_free(void)
2992 debug("---------------------------------------------------------------\n");
2993 /* Ultimate update : take care of potential applet removal
2994 if user asked for it. */
2995 adesklets
.params
->no_update
|=adesklets
.user_quit_flag
;
2996 cfgfile_update(adesklets
.params
);
2998 /* X Windows cleanup */
2999 #ifndef X_DISPLAY_MISSING
3000 if(adesklets
.display
) {
3001 if(adesklets
.window
) {
3002 XUnmapWindow(adesklets
.display
,adesklets
.window
);
3003 XDestroyWindow(adesklets
.display
,adesklets
.window
);
3005 XCloseDisplay(adesklets
.display
);
3009 /* For terminal reset, if it was not cleanly performed
3010 (will happen when quitting from the default left click
3011 menu, for instance) */
3012 rl_callback_handler_remove();
3014 /* Send SIGTERM notification signal to parent process:
3015 in all case but restart, adesklets do not
3016 go further to ensure parent termination. */
3017 kill(adesklets
.ppid
,SIGTERM
);
3019 /* if Lock exist: handle possible restart */
3020 if(adesklets
.lock
) {
3021 if(adesklets
.restart_flag
) {
3022 /* Wait for adesklets parent process to exit
3023 SIGKILL_TIMEOUT seconds, then send a SIGKILL. */
3024 for(i
=0;i
<SIGKILL_TIMEOUT
&& adesklets
.ppid
==getppid();++i
)
3026 if (i
==SIGKILL_TIMEOUT
) kill(adesklets
.ppid
,SIGKILL
);
3027 while(adesklets
.ppid
==getppid()) sleep(1);
3029 /* Redirect stdout and stderr to /dev/null to avoid
3030 output buffer overflow */
3031 if ((fd_null
=open("/dev/null",O_WRONLY
))>=0) {
3036 execl(adesklets
.params
->applet
,
3037 adesklets
.params
->applet
,
3039 /* debug("Restart: could not exec `%s'",adesklets.params->applet); */
3044 /* Release the lock */
3045 lock
.l_type
=F_UNLCK
;
3046 lock
.l_whence
=SEEK_SET
;
3049 fcntl(fileno(adesklets
.lock
),F_SETLK
,&lock
);
3050 fclose(adesklets
.lock
);
3052 /* Try to unlink the lock file:
3053 thanks to POSIX, this will fail gracefully
3054 if a process is still using the file */
3055 unlink(adesklets
.lock_filename
);
3058 /* Free structures */
3059 if(events
) vector_free(events
);
3060 adesklets
.menus
=vector_free(adesklets
.menus
);
3061 adesklets
.images
=vector_free(adesklets
.images
);
3062 adesklets
.fonts
=vector_free(adesklets
.fonts
);
3063 adesklets
.color_ranges
=vector_free(adesklets
.color_ranges
);
3064 adesklets
.color_modifiers
=vector_free(adesklets
.color_modifiers
);
3065 adesklets
.filters
=vector_free(adesklets
.filters
);
3066 adesklets
.polygons
=vector_free(adesklets
.polygons
);
3067 adesklets
.variables
=vector_free(adesklets
.variables
);
3069 return !adesklets
.menus
&&
3070 !adesklets
.images
&&
3072 !adesklets
.color_ranges
&&
3073 !adesklets
.color_modifiers
&&
3074 !adesklets
.filters
&&
3075 !adesklets
.polygons
&&
3076 !adesklets
.variables
;
3079 /*----------------------------------------------------------------------------*/
3080 /* Signal wrapper for adesklets_free()
3083 termination_handler(int signum
)
3085 exit((adesklets_free())?EXIT_SUCCESS
:EXIT_FAILURE
);
3088 /*----------------------------------------------------------------------------*/
3089 /* Since we cannot verify if applet is a script of a binary without trying
3090 to execute it, we require it to have both read and execute permissions for
3091 the current user... Better _portable_ solution is welcomed.
3094 adesklets_valid_desklet(char * applet
, int register_flag
)
3099 if((register_flag
&& applet
[0]=='/') || !register_flag
)
3100 result
=(access(applet
,R_OK
|X_OK
)==0);
3104 /*----------------------------------------------------------------------------*/
3105 /* Our image generator function (have a look at command.c) */
3107 image_generator(const char * text
, int state
)
3109 return generic_index_generator(text
,state
,adesklets
.images
->pos
);
3112 /*----------------------------------------------------------------------------*/
3113 /* Our font name generator function (have a look at command.c) */
3115 base_font_generator(const char * text
, int state
)
3119 static char ** fonts
;
3122 fonts
=imlib_list_fonts(&number
);
3124 if(!(result
=generic_generator(text
,state
,fonts
,number
))) {
3125 imlib_free_font_list(fonts
,number
);
3130 /*----------------------------------------------------------------------------*/
3132 base_font_path_generator(const char * text
, int state
)
3135 static char ** font_path
;
3138 font_path
=imlib_list_font_path(&number
);
3140 return generic_generator(text
,state
,font_path
,number
);
3143 /*----------------------------------------------------------------------------*/
3145 font_generator (const char * text
, int state
)
3147 return generic_index_generator(text
,state
,adesklets
.fonts
->pos
);
3150 /*----------------------------------------------------------------------------*/
3152 font_generator_with_null (const char * text
, int state
)
3154 return generic_index_generator_with_null(text
,state
,adesklets
.fonts
->pos
);
3157 /*----------------------------------------------------------------------------*/
3158 /* Our menu generator function (have a look at command.c) */
3160 menu_generator(const char * text
, int state
)
3162 return generic_index_generator(text
,state
,adesklets
.menus
->pos
);
3165 /*----------------------------------------------------------------------------*/
3166 /* Our color ranges generator function (have a look at command.c) */
3168 color_range_generator(const char * text
, int state
)
3170 return generic_index_generator(text
,state
,adesklets
.color_ranges
->pos
);
3173 /*----------------------------------------------------------------------------*/
3174 /* Our color ranges generator function (have a look at command.c) */
3176 color_range_generator_with_null(const char * text
, int state
)
3178 return generic_index_generator_with_null(text
,state
,
3179 adesklets
.color_ranges
->pos
);
3182 /*----------------------------------------------------------------------------*/
3183 /* Our color modifiers generator function (have a look at command.c) */
3185 color_modifier_generator(const char * text
, int state
)
3187 return generic_index_generator(text
,state
,adesklets
.color_modifiers
->pos
);
3190 /*----------------------------------------------------------------------------*/
3191 /* Our color modifiers generator function (have a look at command.c) */
3193 color_modifier_generator_with_null(const char * text
, int state
)
3195 return generic_index_generator_with_null(text
,state
,
3196 adesklets
.color_modifiers
->pos
);
3199 /*----------------------------------------------------------------------------*/
3200 /* Our filters generator function (have a look at command.c) */
3202 filter_generator(const char * text
, int state
)
3204 return generic_index_generator(text
,state
,adesklets
.filters
->pos
);
3207 /*----------------------------------------------------------------------------*/
3208 /* Our filters generator function (have a look at command.c) */
3210 filter_generator_with_null(const char * text
, int state
)
3212 return generic_index_generator_with_null(text
,state
,
3213 adesklets
.filters
->pos
);
3216 /*----------------------------------------------------------------------------*/
3217 /* Our polygon generator function (have a look at command.c) */
3219 polygon_generator(const char * text
, int state
)
3221 return generic_index_generator(text
,state
,adesklets
.polygons
->pos
);
3224 /*----------------------------------------------------------------------------*/
3225 /* We have to put this generator here because variables vector is part of
3226 the adesklets structure */
3228 variable_generator(const char * text
, int state
)
3230 static int list_index
, len
;
3238 while (list_index
<adesklets
.variables
->pos
) {
3239 name
=((var_item
*)adesklets
.variables
->content
[list_index
])->name
;
3241 if(strncmp(name
,text
,len
)==0)
3242 return dupstr(name
);
3248 /*----------------------------------------------------------------------------*/
3250 /* Generic generator mecanism: used for different wrappers.*/
3252 char * generic_generator(const char * text, int state,
3253 char ** names, int number)
3255 static int list_index, len;
3263 while((number==-1 || list_index<number) &&
3264 (name=names[list_index])) {
3266 if(strncmp(name,text,len)==0)
3267 return(dupstr(name));