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 0, /* int transparency */
38 X_DISPLAY_SUPPORT
, /* int background_grab */
39 -1, /* int user_background_image */
41 BASE_EVENT_MASK
, /* long event_mask */
42 0, /* long user_event_mask */
43 NULL
, /* cfgfile_item * params */
44 NULL
, /* vector * menus */
45 NULL
, /* vector * images */
46 NULL
, /* vector * fonts */
47 NULL
, /* vector * color_ranges */
48 NULL
, /* vector * color_modifiers */
49 NULL
, /* vector * imlib_filters */
50 NULL
, /* vector * polygons */
51 NULL
, /* vector * variables */
52 "", /* char * lock_filename */
53 NULL
, /* FILE * lock */
54 0, /* int quit_flag */
55 0, /* int restart_flag */
56 0 /* int user_quit_flag */
59 /*----------------------------------------------------------------------------*/
60 /* Termination handler prototype for adesklets_free()
62 void termination_handler(int);
64 /*----------------------------------------------------------------------------*/
65 /* Reinstate the menus in pristine state: only one default menu with two
66 or three items: Move (if applicable), Restart (if applicable)
67 and Quit - all managed internally.
68 If an already filled menu could not get reset, returns 0 instead
72 adesklets_menus_reset(void)
78 adesklets
.menus
=vector_free(adesklets
.menus
);
80 if ((adesklets
.menus
=vector_init())) {
81 adesklets
.menus
->vector_free_item
=xmenu_vector_free_item
;
83 #ifndef X_DISPLAY_MISSING
84 // if(!xwindow_window_managed(adesklets.display,adesklets.window))
85 if (!adesklets
.managed
)
87 xmenu_push_item(menu
,"Move");
88 /* A lock file is needed if we want
89 the restart mechanism to work */
90 if (adesklets
.lock
) xmenu_push_item(menu
,"Restart");
91 xmenu_push_item(menu
,"Quit");
92 vector_push(adesklets
.menus
,menu
);
98 /*----------------------------------------------------------------------------*/
99 /* Recompute the background image based on present main window
100 width and height. Also create or resize foreground image as needed.
101 Returns 1 if both final and background images were dutifully produced,
105 adesklets_images_reset_background(int force_size
, ...)
107 int i
, j
, old_width
, old_height
, foreground_active
, background_active
;
114 /* Get window dimension by all means necessary */
116 va_start(ap
,force_size
);
117 width
=va_arg(ap
,uint
);
118 height
=va_arg(ap
,uint
);
121 #ifndef X_DISPLAY_MISSING
122 if (!xwindow_window_size(adesklets
.display
,adesklets
.window
,&width
,&height
))
126 /* Save context states */
127 xwindow_context_save(IMLIB_BLEND
|IMLIB_COLOR
|IMLIB_IMAGE
);
129 /* Record if Imlib's context image has to be changed at the end */
130 image
=imlib_context_get_image();
131 foreground_active
=(image
&& image
==adesklets
.images
->content
[0]);
132 background_active
=(image
&& image
==adesklets
.images
->content
[1]);
134 /* Determine what images to resize */
135 if ((index
=vector_init())) {
136 /* Always resize foreground */
137 if((pos
=malloc(sizeof(int)))) {
139 vector_push(index
,pos
);
141 /* Resize background when:
142 - We do not have X support
143 - We have X support, but there is no X connection or no window
144 - We have X support, there is a valid X connection and window,
145 but we do not grab the background
147 if(!X_DISPLAY_SUPPORT
||
148 !adesklets
.background_grab
||
149 !adesklets
.display
|| !adesklets
.window
) {
150 if((pos
=malloc(sizeof(int)))) {
152 vector_push(index
,pos
);
155 /* Resize user selected background when:
158 if(adesklets
.user_background_image
!=-1) {
159 if ((pos
=malloc(sizeof(int)))) {
160 *pos
=adesklets
.user_background_image
;
161 vector_push(index
,pos
);
166 /* Create/update image(s) */
167 for(j
=0;index
&& j
<index
->pos
;++j
) {
168 i
=*((int*)index
->content
[j
]);
169 if (!adesklets
.images
->content
[i
]) {
170 /* Create new final window image */
171 if ((adesklets
.images
->content
[i
]=imlib_create_image(width
,height
))) {
173 imlib_context_set_image(adesklets
.images
->content
[i
]);
175 /* Make sure it has an alpha channel */
176 imlib_image_set_has_alpha(1);
178 /* Fill image with transparent black for foreground,
179 and opaque black for background, if applicable */
180 imlib_context_set_blend(0);
181 imlib_context_set_color(0, 0, 0, (i
==0)?0:255);
182 imlib_image_fill_rectangle(0,0,width
,height
);
185 /* Update (by resizing image) */
186 imlib_context_set_image(adesklets
.images
->content
[i
]);
187 old_width
=imlib_image_get_width();
188 old_height
=imlib_image_get_height();
189 if((width
!=old_width
|| height
!=old_height
) &&
190 (image
=imlib_create_image(width
,height
))){
192 imlib_context_set_image(image
);
194 /* Make sure it has an alpha channel */
195 imlib_image_set_has_alpha(1);
197 /* Fill image with opaque black */
198 imlib_context_set_blend(0);
199 imlib_context_set_color(0,0,0,255);
200 imlib_image_fill_rectangle(0,0,width
,height
);
202 /* Finally, copy the original foreground image, with scaling */
203 imlib_blend_image_onto_image(adesklets
.images
->content
[i
],1,
204 0,0,old_width
,old_height
,
207 /* Clean up : free original image */
208 imlib_context_set_image(adesklets
.images
->content
[i
]);
210 adesklets
.images
->content
[i
]=image
;
215 #ifndef X_DISPLAY_MISSING
216 if(adesklets
.background_grab
&& adesklets
.display
&& adesklets
.window
) {
217 /* If it exists, free background image */
218 adesklets
.images
->content
[1]=
219 image_vector_free_item(adesklets
.images
->content
[1]);
221 /* Create new background image */
222 adesklets
.images
->content
[1]=
223 xwindow_grab_background(adesklets
.display
,adesklets
.params
->scr
,
225 if (adesklets
.user_event_mask
&BackgroundGrabMask
)
226 event("backgroundgrab\n");
229 /* Free index, if applicable */
232 /* Switch back to original context */
233 xwindow_context_restore();
235 /* Modify active image if it was originally set on foreground */
236 if(foreground_active
) imlib_context_set_image(adesklets
.images
->content
[0]);
237 if(background_active
) imlib_context_set_image(adesklets
.images
->content
[1]);
239 return adesklets
.images
->content
[0] && adesklets
.images
->content
[1];
242 /*----------------------------------------------------------------------------*/
243 /* Reinstate the image vector in pristine state,
244 including the regeneration of final and background image.
245 Take care of dangling context image, if applicable.
246 Returns 1 if successful, 0 in case of failure.
249 adesklets_images_reset(void)
252 if (adesklets
.images
)
253 adesklets
.images
=vector_free(adesklets
.images
);
254 if (!adesklets
.images
)
255 if((adesklets
.images
=vector_init())) {
256 adesklets
.images
->vector_free_item
=image_vector_free_item
;
257 adesklets
.user_background_image
=-1;
258 /* Recreate Final window and background images */
259 if((result
=adesklets_images_reset_background(0))) {
260 adesklets
.images
->pos
=2;
261 /* Reset current image if useful */
262 if (imlib_context_get_image()!=adesklets
.images
->content
[0] &&
263 imlib_context_get_image()!=adesklets
.images
->content
[1])
264 imlib_context_set_image(adesklets
.images
->content
[0]);
270 /*----------------------------------------------------------------------------*/
271 /* Set/Reset main window. Also call adesklets_menu_reset and
272 adeslets_images_reset as needed. */
274 adesklets_window_reset(int managed
)
277 #ifndef X_DISPLAY_MISSING
280 XWindowAttributes attr
;
281 XTextProperty text_prop_name
;
283 const char * name
= PACKAGE
;
284 const long valuemask
= CWBackPixmap
;
286 /* Determine if the old window was mapped, then destroy it as needed */
287 if(adesklets
.display
) {
288 if(adesklets
.window
) {
289 mapped
=(XGetWindowAttributes(adesklets
.display
,
290 adesklets
.window
,&attr
))?
291 (attr
.map_state
!=IsUnmapped
):0;
292 XDestroyWindow(adesklets
.display
,adesklets
.window
);
296 /* Determine new window dimensions */
297 width
=(adesklets
.window
)?attr
.width
:1;
298 height
=(adesklets
.window
)?attr
.height
:1;
300 xwindow_error_reset();
301 /* Create main desklet window */
302 adesklets
.root
=(managed
)?
303 RootWindow(adesklets
.display
,adesklets
.params
->scr
):
304 xwindow_get_root_window(adesklets
.display
,
305 adesklets
.params
->scr
);
306 debug("Root window is : 0x%x\n", adesklets
.root
);
309 XCreateWindow(adesklets
.display
,
311 adesklets
.params
->x
, adesklets
.params
->y
,
313 DefaultDepth(adesklets
.display
,
314 adesklets
.params
->scr
),
317 (managed
)?valuemask
:(valuemask
|CWOverrideRedirect
),
318 &XDefaultWindowAttributes
);
320 if (xwindow_error_check()) {
321 /* Set this window size */
322 xwindow_resize_window(adesklets
.display
,adesklets
.window
,
323 adesklets
.params
,width
,height
,1);
324 /* Set this window event mask */
325 XSelectInput(adesklets
.display
,adesklets
.window
,adesklets
.event_mask
);
327 /* Set this window as imlib2's default drawable */
328 imlib_context_set_drawable(adesklets
.window
);
330 /* Set window stacking order, and various properties if applicable */
332 XRaiseWindow(adesklets
.display
,adesklets
.window
);
334 if (XmbTextListToTextProperty(adesklets
.display
,
337 &text_prop_name
)==Success
)
338 XSetWMName(adesklets
.display
, adesklets
.window
, &text_prop_name
);
340 /* Window delete protocol registration */
341 if ((atom
=XInternAtom(adesklets
.display
,
342 "WM_DELETE_WINDOW",False
))!=None
)
343 XSetWMProtocols(adesklets
.display
,
344 adesklets
.window
, &atom
, 1);
347 XLowerWindow(adesklets
.display
,adesklets
.window
);
349 /* Map the window if needed */
350 if (mapped
) XMapWindow(adesklets
.display
,adesklets
.window
);
352 /* Eventually add capture of PropertyNotify on root window:
353 used for dynamic background reinitialisation */
354 XSelectInput(adesklets
.display
,
355 DefaultRootWindow(adesklets
.display
),
356 ((adesklets
.background_grab
)?PropertyChangeMask
:0));
358 /* Store new value */
359 adesklets
.managed
= managed
;
363 adesklets
.window
=(Window
)0;
365 adesklets
.window
=(Window
)0;
370 /*----------------------------------------------------------------------------*/
371 /* Reste to nothing the vector of fonts, color_ranges and color_modifiers.
372 Returns 1 if successful, 0 otherwise.
374 #define ADESKLETS_RESET_FUNCTION(name)\
376 adesklets_ ## name ## s_reset(void)\
379 if(adesklets.name ## s)\
380 adesklets.name ## s=vector_free(adesklets.name ## s);\
381 if(!adesklets.name ## s) {\
382 if((adesklets.name ## s=vector_init())) {\
383 adesklets.name## s->vector_free_item=\
384 name ## _vector_free_item;\
385 imlib_context_set_ ## name(NULL);\
392 ADESKLETS_RESET_FUNCTION(font
)
393 ADESKLETS_RESET_FUNCTION(color_range
)
394 ADESKLETS_RESET_FUNCTION(color_modifier
)
395 ADESKLETS_RESET_FUNCTION(filter
)
396 #undef ADESKLETS_RESET_FUNCTION
398 /*----------------------------------------------------------------------------*/
399 /* Reset to nothing a generic vector of something; you need
400 to provide a reference to the vector and another to a
401 vector_free_item_func function
404 adesklets_generic_reset(vector
** vec
, vector_free_item_func func
)
408 *vec
=vector_free(*vec
);
410 if((*vec
=vector_init())) {
411 (*vec
)->vector_free_item
=func
;
418 /*----------------------------------------------------------------------------*/
419 /* Generate placeholder function using preceeding generic function
421 #define ADESKLETS_RESET_FUNCTION(name) \
423 adesklets_ ## name ## s_reset(void) \
425 return adesklets_generic_reset(&adesklets.name ## s,\
426 name ## _vector_free_item);\
429 ADESKLETS_RESET_FUNCTION(polygon
)
430 ADESKLETS_RESET_FUNCTION(variable
)
431 #undef ADESKLETS_RESET_FUNCTION
433 /*----------------------------------------------------------------------------*/
434 /* Wrapper for xmenu_fire() that intercepts non-maskable events
435 from default menu ("Move", "Restart" and "Quit" events)
438 adesklets_menu_fire(int index
, char ** return_str
)
440 #ifndef X_DISPLAY_MISSING
442 if(index
>=0 && index
<adesklets
.menus
->pos
) {
443 *return_str
=xmenu_fire(adesklets
.display
,adesklets
.params
->scr
,
445 adesklets
.images
->content
[
446 (adesklets
.user_background_image
==-1)?
447 1:adesklets
.user_background_image
],
448 adesklets
.images
->content
[0],
449 adesklets
.transparency
,
451 /* Intercept default actions move and quit on the way back */
452 if(index
==0 && *return_str
) {
453 /* For move: verify the main window is not managed,
454 to avoid false move due to user-added "Move" */
456 #ifndef X_DISPLAY_MISSING
457 !adesklets
.managed
&&
459 strcmp(*return_str
,"Move")==0) {
460 if(xwindow_move_window(adesklets
.display
,
461 adesklets
.root
, adesklets
.window
,
463 XMapWindow(adesklets
.display
,adesklets
.window
);
464 if(!adesklets
.params
->no_update
)
465 cfgfile_update(adesklets
.params
);
469 /* For restart: verify there is a lock file open,
470 to avoid false restart due to user-added "Restart"
471 item in default menu */
472 if(adesklets
.lock
&& strcmp(*return_str
,"Restart")==0) {
474 adesklets
.restart_flag
=1;
477 if(strcmp(*return_str
,"Quit")==0) {
478 adesklets
.user_quit_flag
=adesklets
.quit_flag
=1;
493 /*----------------------------------------------------------------------------*/
494 /* Return 1 if current image is potentially shown on screen, 0 otherwise.
495 Mainly used to determine needs for screen updates */
500 image
= imlib_context_get_image();
502 return (image
==adesklets
.images
->content
[0]) ||
503 (adesklets
.transparency
&&
504 ((adesklets
.user_background_image
!=-1 &&
505 image
==adesklets
.images
->content
[adesklets
.user_background_image
]) ||
506 (image
==adesklets
.images
->content
[1])));
509 /*----------------------------------------------------------------------------*/
510 void usage(const char * name
)
512 int em
= (int)getenv("ADESKLETS_EMBEDDED");
514 printf("Usage: %s [OPTIONS] [script_id]\n\
515 adesklets interpreter and desklets launcher\n\n", name
);
517 -h, --help Display this help message\n");
520 -v, --version Get package version\n\
521 -f, --file In interpreter mode, use file as\n\
522 input stream instead of stdin\n");
524 #ifdef FRONTEND_SHELL_DRIVER
525 printf("Warning: for some reason, the shell frontend driver was not used.\n");
527 printf("Warning: the shell frontend driver support was not compiled in.\n");
531 /*----------------------------------------------------------------------------*/
533 adesklets_init(int argc
, char ** argv
)
537 char str
[CFGFILE_NAME_SIZE
];
540 struct sigaction new_action
, old_action
;
542 const char * OPTIONS
[] = {"-h", "--help", "-f", "--file", "-v", "--version" };
544 /* Seek --help string: otherwise, it is either a script name of junk */
546 if(strncmp(argv
[1],OPTIONS
[0],strlen(OPTIONS
[0]))==0 ||
547 strncmp(argv
[1],OPTIONS
[1],strlen(OPTIONS
[1]))==0) {
551 if (strncmp(argv
[1],OPTIONS
[4],strlen(OPTIONS
[4]))==0 ||
552 strncmp(argv
[1],OPTIONS
[5],strlen(OPTIONS
[5]))==0) {
553 printf("%s %s\n",PACKAGE
,VERSION
);
556 if (strncmp(argv
[1],OPTIONS
[2],strlen(OPTIONS
[2]))==0 ||
557 strncmp(argv
[1],OPTIONS
[3],strlen(OPTIONS
[3]))==0) {
559 if (!((file
=fopen(argv
[2],"r"))&&
560 dup2(fileno(file
),fileno(stdin
))>=0)) {
562 fprintf(stderr
,"Could not open file '%s' for reading\n",
576 /* Get original parent process id */
577 adesklets
.ppid
=getppid();
579 /* Get desklet ID from environment */
580 adesklets_id
= getenv("ADESKLETS_ID");
582 /* Set stdout and stderr to be unbuffered: this is needed
583 for proper pipe operation. stderr is always
585 if (setvbuf(stdout
,NULL
,_IONBF
,0)!=0) {
586 fprintf(stderr
,"Could not remove stdout buffer\n");
589 if (setvbuf(stderr
,NULL
,_IONBF
,0)!=0) {
590 fprintf(stderr
,"Could not remove stderr buffer\n");
594 /* Determine if interactive use */
595 command
.interactive
=isatty(fileno(stdin
));
597 /* Retrieve all parameters from config file */
598 adesklets
.params
= cfgfile_getinfo((!command
.interactive
)?argv
[pos
]:NULL
,
599 ((uint
)(adesklets_id
)?
600 atoi(adesklets_id
):-1));
602 /* Make sure ADESKLETS_ID is set in current environment */
604 if (sprintf(str
,"%u",adesklets
.params
->id
)>0)
605 setenv("ADESKLETS_ID",str
,1);
607 /* If interactive use, print welcome message */
608 if(command
.interactive
) {
610 printf("Press TAB for hints.\n");
611 /* But if not, build and acquire lock file name */
612 } else if (adesklets_valid_desklet(argv
[pos
],0)) {
613 strncpy(str
,argv
[1],CFGFILE_NAME_SIZE
-1);
614 str
[CFGFILE_NAME_SIZE
-1]=0;
615 if (snprintf(adesklets
.lock_filename
,CFGFILE_NAME_SIZE
-1,
616 "%s/%s_uid%u_%s_%u.lock",
620 (char*)basename(str
),
621 adesklets
.params
->id
)<CFGFILE_NAME_SIZE
)
622 adesklets
.lock_filename
[CFGFILE_NAME_SIZE
-1]=0;
623 /* Now, lock the file: this will wait forever */
624 if ((adesklets
.lock
=fdopen(open(adesklets
.lock_filename
,
625 O_CREAT
|O_TRUNC
|O_WRONLY
,
629 lock
.l_whence
=SEEK_SET
;
632 debug("Lock file: acquiring %s\n",adesklets
.lock_filename
);
634 TRY(fcntl(fileno(adesklets
.lock
),F_SETLKW
,&lock
));
636 /* Write PPID and PID to lock file */
637 fprintf(adesklets
.lock
,"%d %d\n",adesklets
.ppid
,getpid());
638 fflush(adesklets
.lock
);
640 debug("Lock file: could not get lock\n");
641 fclose(adesklets
.lock
);
647 /* Force config file entry removal (or, at least, no registration)
648 at next update if invalid */
649 adesklets
.params
->no_update
=!
650 adesklets_valid_desklet(adesklets
.params
->applet
,1);
652 #ifndef X_DISPLAY_MISSING
653 /* Perform X Windows initialisation */
654 if ((adesklets
.display
=XOpenDisplay(NULL
))) {
655 /* Correct screen determination */
656 adesklets
.params
->scr
=(adesklets
.params
->scr
>=0 &&
657 adesklets
.params
->scr
<
658 ScreenCount(adesklets
.display
))?
659 adesklets
.params
->scr
:
660 DefaultScreen(adesklets
.display
);
662 /* X related imlib2 settings */
663 adesklets
.visual
=imlib_get_best_visual(adesklets
.display
,
664 adesklets
.params
->scr
,
666 imlib_context_set_display(adesklets
.display
);
667 imlib_context_set_visual(adesklets
.visual
);
668 imlib_context_set_colormap(DefaultColormap(adesklets
.display
,
669 adesklets
.params
->scr
));
671 /* Create main desklet window: managed if interactive,
673 adesklets_window_reset(command
.interactive
);
674 /* Install custom error handler */
675 XSetErrorHandler(xwindow_non_fatal_error_handler
);
679 debug("Could not connect to X server '%s'\n",XDisplayName(NULL
));
683 /* Locate true type fonts system-wide */
684 xwindow_locate_truetype_fonts();
686 /* Various Others imlib2 settings */
687 imlib_set_cache_size(2048*1024);
688 imlib_set_font_cache_size(512*1024);
689 imlib_set_color_usage(128);
690 imlib_context_set_dither(1);
691 imlib_context_set_blend(1);
692 imlib_context_set_color(255,255,255,255);
694 /* Set events in proper echo mode: no echo if interactive, echo otherwise. */
695 events_echo
=!command
.interactive
;
697 /* Initial settings */
698 if (adesklets_menus_reset()) {
699 if (adesklets_images_reset()) {
700 if (adesklets_fonts_reset()) {
701 if (adesklets_color_ranges_reset()) {
702 if (adesklets_color_modifiers_reset()) {
703 if (adesklets_filters_reset()) {
704 if (adesklets_polygons_reset()) {
705 if (adesklets_variables_reset()) {
706 /* Setup command interpreter */
707 if(command_interpreter_reset()) {
708 #ifdef FORCE_EXTENDED_CHARACTERS_INPUT
709 rl_variable_bind("input-meta", "on");
710 rl_variable_bind("convert-meta", "off");
711 rl_variable_bind("output-meta", "on");
713 /* Finally, set up event handler. This code snipset
714 was copied verbatim from the GNU C Library
715 Reference Manual (sigaction Function
717 new_action
.sa_handler
= termination_handler
;
718 sigemptyset (&new_action
.sa_mask
);
719 new_action
.sa_flags
= 0;
720 sigaction (SIGINT
, NULL
, &old_action
);
721 if (old_action
.sa_handler
!= SIG_IGN
)
722 sigaction (SIGINT
, &new_action
, NULL
);
723 sigaction (SIGHUP
, NULL
, &old_action
);
724 if (old_action
.sa_handler
!= SIG_IGN
)
725 sigaction (SIGHUP
, &new_action
, NULL
);
726 sigaction (SIGTERM
, NULL
, &old_action
);
727 if (old_action
.sa_handler
!= SIG_IGN
)
728 sigaction (SIGTERM
, &new_action
, NULL
);
729 /* If applicable, make an initial setup of
730 config file, just in case */
731 if (X_DISPLAY_SUPPORT
&&
732 adesklets
.display
&& adesklets
.window
)
733 cfgfile_update(adesklets
.params
);
737 fprintf(stderr
, "Cannot initialize command interpreter\n");
739 fprintf(stderr
, "Cannot initialize variables\n");
741 fprintf(stderr
, "Cannot initialize imlib polygons\n");
743 fprintf(stderr
, "Cannot initialize imlib filters\n");
745 fprintf(stderr
, "Cannot initialize imlib color modifiers\n");
747 fprintf(stderr
, "Cannot initialize imlib color ranges\n");
749 fprintf(stderr
, "Cannot initialize imlib fonts\n");
751 fprintf(stderr
, "Cannot initialize imlib images\n");
753 fprintf(stderr
, "Cannot initialize menus\n");
758 /*----------------------------------------------------------------------------*/
760 adesklets_events_loop(void)
767 #ifndef X_DISPLAY_MISSING
771 struct timespec sleep_time
;
772 command_enum command_type
;
774 #ifndef X_DISPLAY_MISSING
777 #ifdef HAVE_READLINE_HISTORY_H
778 HIST_ENTRY
** history
;
784 Imlib_Updates updates
;
788 Imlib_Color_Range color_range
;
789 Imlib_Color_Modifier color_modifier
;
791 ImlibPolygon polygon
;
792 Imlib_Load_Error error
;
796 debug("---------------------------------------------------------------\n");
798 updates
= imlib_updates_init();
801 command
.message_out
=0;
802 variable_expansion(adesklets
.variables
,&command
.line
);
803 params
=command_splitter(command
.line
,&command_type
);
805 if (!command
.recording
||
806 command_type
==CMD_PLAY
||
807 command_type
==CMD_START_RECORDING
||
808 command_type
==CMD_STOP_RECORDING
) {
809 switch(command_type
) {
811 /* NOTE : for semi-automated generation of an adesklets'
812 API for scripting languages, you should include
813 a prototype declaration similar to this one
814 in a comment (multi-lines comments allowed)
815 directly below case declaration. Look at protoize.sh
816 for further details. Commands that are also
817 Imlib2 primitives do not need to have prototypes
820 prototype(double gate) */
821 if (command
.replay_pos
) {
822 if (params
->pos
>=2) {
823 angle
=atof(params
->content
[1]);
824 #ifndef X_DISPLAY_MISSING
825 if (command
.replay_abort_on_events
) {
826 sleep_time
.tv_sec
=0; sleep_time
.tv_nsec
=X_POLLING_PERIOD
/10;
827 while (angle
>command_gate_chronometer())
828 if (adesklets
.display
&& adesklets
.window
&&
829 (XCheckWindowEvent(adesklets
.display
,
830 DefaultRootWindow(adesklets
.display
),
831 PropertyChangeMask
, &ev
) ||
832 XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
833 adesklets
.event_mask
,&ev
) ||
834 XCheckTypedWindowEvent(adesklets
.display
,adesklets
.window
,
835 ClientMessage
,&ev
))) {
836 XPutBackEvent(adesklets
.display
,&ev
);
839 nanosleep(&sleep_time
,NULL
);
842 if ((angle
-=command_gate_chronometer())>0) {
843 sleep_time
.tv_sec
=(time_t)angle
;
844 sleep_time
.tv_nsec
=(long)((angle
-floor(angle
))*1E9
);
846 debug("Sleep time: %f, or %d %d\n",
847 angle,sleep_time.tv_sec,sleep_time.tv_nsec);
849 nanosleep(&sleep_time
,NULL
);
851 #ifndef X_DISPLAY_MISSING
855 command_error("time gate not given\n");
857 command_error("ignoring timer gate, interpreter not replaying\n");
860 /* prototype([const char * command]) */
864 strcmp(params
->content
[1],COMMANDS
[i
].name
);
866 if (COMMANDS
[i
].name
)
867 command_ok("%s - %s\n",COMMANDS
[i
].name
, COMMANDS
[i
].doc
);
869 command_error("no help on '%s'\n", (char*)params
->content
[1]);
871 for(i
=0;COMMANDS
[i
].name
;++i
)
872 command_printf("%-25s -\t%s\n",COMMANDS
[i
].name
, COMMANDS
[i
].doc
);
876 /* prototype(void) */
877 command_ok("pong!\n");
880 /* prototype([int delay]) */
882 (((i
=atoi(params
->content
[1]))>0)?i
:5):5;
883 debug("Pausing for %d seconds.\n",i
);
887 /* prototype(void) */
888 command_ok("%s %s\n",PACKAGE
,VERSION
);
891 /* prototype(void) */
892 command_ok("adesklets id %u\n", adesklets
.params
->id
);
895 /* prototype([const char * filename]) */
896 #ifdef HAVE_READLINE_HISTORY_H
897 if ((history
=history_list())) {
898 for(i
=0;history
[i
];++i
);
899 command_printf("%d commands in history\n",i
);
900 if((file
=(params
->pos
>=2)?
901 fopen(command_subsplitter(command
.line
,1),"w"):stdout
)) {
902 for(i
=0;history
[i
];++i
)
903 if (params
->pos
>=2 || !command
.interactive
)
904 fprintf(file
,"%s\n",history
[i
]->line
);
906 fprintf(file
,"%d\t%s\n",i
,history
[i
]->line
);
907 if(file
!=stdout
) fclose(file
);
909 command_error("could not open output file for writing\n");
911 command_error("could not retrieve history list\n");
913 command_error("history support not compiled in\n");
917 /* prototype([const * char name, const * char value]) */
918 if ((i
=params
->pos
)>1) {
919 /* Verify variable name does not include a dollar character */
921 ((char*)params
->content
[1])[j
] &&
922 ((char*)params
->content
[1])[j
]!='$';
924 if (j
==strlen((char*)params
->content
[1])) {
925 /* First, search for existing variable */
927 vector_find(adesklets
.variables
,(uint
*)&j
,
928 variable_search_func
,(void*)params
->content
[1]);
930 /* Then, if it exists, just delete it */
932 vector_delete(adesklets
.variables
,(uint
)j
);
935 command_error("variable '%s' does not exist\n",
939 /* Then, set it back if there is a new content */
940 vector_push(adesklets
.variables
,
941 (void*)variable_create(
942 (char*)params
->content
[1],
943 (char*)command_subsplitter(command
.line
,2)));
946 command_error("variable name contains '$'\n");
948 /* Print out all variables */
949 command_printf("%d variable(s)\n", adesklets
.variables
->pos
);
950 for (i
=0;i
<adesklets
.variables
->pos
;++i
)
951 command_printf("%s=%s\n",
952 ((var_item
*)adesklets
.variables
->content
[i
])->name
,
953 ((var_item
*)adesklets
.variables
->content
[i
])->value
);
957 /* prototype(void) */
958 adesklets_variables_reset();
961 /* prototype(const char * string) */
963 case CMD_START_RECORDING
:
964 /* prototype(void) */
965 #ifdef HAVE_READLINE_HISTORY_H
966 /* This is a special case: you have to make sure to abort
967 current macro recording if called recursively from direct mode.
969 But this is not enough: you also need to ckeck we are not inside
970 a replay loop (indirect mode) because it would still be possible
971 to insert hidden calls to 'start_recording' inside a macro using
972 textual expansion (text variables) */
973 if (!command
.recording
&& !command
.replay_pos
)
974 command
.recording
=history_size()+1;
976 /* In non interactive mode, purge newly created history
978 if (command
.recording
&& !command
.interactive
)
979 for(i
=history_size()-1;i
>=command
.recording
-1;--i
)
980 free_history_entry(remove_history(i
));
981 command
.recording
=command
.replay_pos
=0;
982 command_error("cannot call this while already recording or \
983 replaying, aborded\n");
986 command_error("compiled without GNU history support\n");
989 case CMD_STOP_RECORDING
:
990 /* prototype(void) */
991 #ifdef HAVE_READLINE_HISTORY_H
992 if (!command
.replay_pos
) {
993 if (command
.recording
) {
996 if(!command
.interactive
)
997 /* In case of non interactive use, remove
998 the reference to the 'stop_record' command */
999 free_history_entry(remove_history(j
));
1000 if (command
.recording
!=j
)
1001 command_ok("recorded_commands %d %d\n",
1005 command_error("no command recorded\n");
1007 command_error("no recording taking place right now\n");
1009 command_error("cannot call stop while replaying, replay aborded\n");
1010 command
.recording
=0;
1012 command_error("compiled without GNU history support\n");
1015 case CMD_PLAY_GET_ABORT_ON_EVENTS
:
1016 /* prototype(void) */
1017 command_ok("abort_on_event %d\n",command
.replay_abort_on_events
);
1019 case CMD_PLAY_SET_ABORT_ON_EVENTS
:
1020 /* prototype(bool abort) */
1021 if (!command
.replay_pos
) {
1023 command
.replay_abort_on_events
=atoi((char*)params
->content
[1]);
1025 command_error("abort on event value not given\n");
1027 command_error("cannot be called inside a replay\n");
1030 /* prototype(int beginning, int end) */
1031 #ifdef HAVE_READLINE_HISTORY_H
1032 if (!command
.recording
&& !command
.replay_pos
) {
1033 if (params
->pos
>=3) {
1034 if (((i
=atoi(params
->content
[1]))<(j
=history_size())) &&
1035 ((k
=atoi(params
->content
[2]))<j
)) {
1036 if (i
>=0 && k
>=0 && (i
<=k
)) {
1037 gettimeofday(&command
.replay_time
,NULL
);
1038 command
.replay_pos
=i
+1;
1039 command
.replay_stop
=k
;
1042 command_error("invalid limits\n");
1044 command_error("limits out of range\n");
1046 command_error("missing start and stop limits\n");
1048 command
.recording
=command
.replay_pos
=0;
1049 command_error("cannot call this now, aborded\n");
1052 command_error("compiled without GNU history support\n");
1055 case CMD_CONTEXT_GET_DITHER
:
1056 command_ok("context dither %hhu\n",imlib_context_get_dither());
1058 case CMD_CONTEXT_GET_ANTI_ALIAS
:
1059 command_ok("context antialias %hhu\n",imlib_context_get_anti_alias());
1061 case CMD_CONTEXT_GET_BLEND
:
1062 command_ok("context blend %hhu\n",imlib_context_get_blend());
1064 case CMD_CONTEXT_GET_OPERATION
:
1065 i
=imlib_context_get_operation();
1066 command_ok("context operation %d (%s)\n",
1069 case CMD_CONTEXT_GET_CLIPRECT
:
1070 /* prototype(void) */
1071 imlib_context_get_cliprect(&x
,&y
,&i
,&j
);
1072 command_ok("context cliprect %d %d %d %d\n",x
,y
,i
,j
);
1074 case CMD_CONTEXT_GET_IMAGE
:
1075 image
=imlib_context_get_image();
1076 for(i
=0;i
<adesklets
.images
->pos
;++i
)
1077 if(adesklets
.images
->content
[i
]==image
)
1078 command_ok("context image %d\n",i
);
1080 case CMD_CONTEXT_GET_FONT
:
1081 if ((font
=imlib_context_get_font())) {
1082 for(i
=0;i
<adesklets
.fonts
->pos
;++i
)
1083 if(adesklets
.fonts
->content
[i
]==font
)
1084 command_ok("context font %d\n",i
);
1086 command_ok("context font -1 (unset)\n");
1088 case CMD_CONTEXT_GET_COLOR_RANGE
:
1089 if ((color_range
=imlib_context_get_color_range())) {
1090 for(i
=0;i
<adesklets
.color_ranges
->pos
;++i
)
1091 if(adesklets
.color_ranges
->content
[i
]==color_range
)
1092 command_ok("context colorrange %d\n",i
);
1094 command_ok("context colorrange -1 (unset)\n");
1096 case CMD_CONTEXT_GET_COLOR_MODIFIER
:
1097 if ((color_modifier
=imlib_context_get_color_modifier())) {
1098 for(i
=0;i
<adesklets
.color_modifiers
->pos
;++i
)
1099 if(adesklets
.color_modifiers
->content
[i
]==color_modifier
)
1100 command_ok("context colormodifier %d\n",i
);
1102 command_ok("context colormodifier -1 (unset)\n");
1104 case CMD_CONTEXT_GET_FILTER
:
1105 if ((filter
=imlib_context_get_filter())) {
1106 for(i
=0;i
<adesklets
.filters
->pos
;++i
)
1107 if(adesklets
.filters
->content
[i
]==filter
)
1108 command_ok("context filter %d\n",i
);
1110 command_ok("context filter -1 (unset)\n");
1112 case CMD_CONTEXT_GET_COLOR
:
1113 /* prototype(void) */
1114 imlib_context_get_color(&x
,&y
,&i
,&j
);
1115 command_ok("context color %hhu %hhu %hhu %hhu\n",
1116 x
&255,y
&255,i
&255,j
&255);
1118 case CMD_CONTEXT_GET_ANGLE
:
1119 angle
=imlib_context_get_angle();
1120 command_ok("context angle %4.2f\n",angle
);
1122 case CMD_CONTEXT_GET_DIRECTION
:
1123 i
=imlib_context_get_direction();
1124 command_ok("context direction %d (%s)\n",
1127 case CMD_CONTEXT_SET_DITHER
:
1128 /* prototype(bool dither) */
1130 imlib_context_set_dither((char)atoi(params
->content
[1]));
1132 command_error("dither value not given\n");
1134 case CMD_CONTEXT_SET_ANTI_ALIAS
:
1135 /* prototype(bool anti_alias) */
1137 imlib_context_set_anti_alias((char)atoi(params
->content
[1]));
1139 command_error("anti alias value not given\n");
1141 case CMD_CONTEXT_SET_BLEND
:
1142 /* prototype(bool blend) */
1144 imlib_context_set_blend((char)atoi(params
->content
[1]));
1146 command_error("blend value not given\n");
1148 case CMD_CONTEXT_SET_OPERATION
:
1149 /* prototype(enum OPERATIONS operation) */
1150 if(params
->pos
>=2) {
1151 for(i
=0;OPERATIONS
[i
];++i
)
1152 if(strncmp(OPERATIONS
[i
],params
->content
[1],
1153 strlen(params
->content
[1]))==0)
1155 imlib_context_set_operation((OPERATIONS
[i
])?
1156 i
:((j
=atoi(params
->content
[1])))<4?j
:0);
1158 command_error("operation not given\n");
1160 case CMD_CONTEXT_SET_CLIPRECT
:
1161 if (params
->pos
>=5) {
1162 if ((x
=atoi((char*)params
->content
[1]))>=0 &&
1163 (y
=atoi((char*)params
->content
[2]))>=0 &&
1164 (i
=atoi((char*)params
->content
[3]))>=0 &&
1165 (j
=atoi((char*)params
->content
[4]))>=0) {
1166 imlib_context_set_cliprect(x
,y
,i
,j
);
1168 command_error("clipping rectangle coordinates out of range\n");
1170 command_error("clipping rectangle description not given\n");
1172 case CMD_CONTEXT_SET_IMAGE
:
1173 if (params
->pos
>=2) {
1174 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1175 i
<adesklets
.images
->pos
) {
1176 imlib_context_set_image(adesklets
.images
->content
[i
]);
1178 command_error("image ID %d out of range\n",i
);
1180 command_error("image ID not given\n");
1182 case CMD_CONTEXT_SET_FONT
:
1183 /* prototype([int font]) */
1185 if (params
->pos
>=2) {
1186 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1187 i
<adesklets
.fonts
->pos
) {
1188 imlib_context_set_font(adesklets
.fonts
->content
[i
]);
1192 imlib_context_set_font(NULL
);
1194 command_error("font ID %d out of range\n",i
);
1198 imlib_context_set_font(NULL
);
1200 if(j
) command_ok("context font unset\n");
1202 case CMD_CONTEXT_SET_COLOR_RANGE
:
1203 /* prototype([int color_range]) */
1205 if (params
->pos
>=2) {
1206 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1207 i
<adesklets
.color_ranges
->pos
) {
1208 imlib_context_set_color_range(adesklets
.color_ranges
->content
[i
]);
1212 imlib_context_set_color_range(NULL
);
1214 command_error("color range ID %d out of range\n",i
);
1218 imlib_context_set_color_range(NULL
);
1220 if(j
) command_ok("context color range unset\n");
1222 case CMD_CONTEXT_SET_COLOR_MODIFIER
:
1223 /* prototype([int color_modifier]) */
1225 if (params
->pos
>=2) {
1226 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1227 i
<adesklets
.color_modifiers
->pos
) {
1228 imlib_context_set_color_modifier(
1229 adesklets
.color_modifiers
->content
[i
]);
1233 imlib_context_set_color_modifier(NULL
);
1235 command_error("color modifier ID %d out of range\n",i
);
1239 imlib_context_set_color_modifier(NULL
);
1241 if(j
) command_ok("context color modifier unset\n");
1243 case CMD_CONTEXT_SET_FILTER
:
1244 /* prototype([int filter]) */
1246 if (params
->pos
>=2) {
1247 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1248 i
<adesklets
.filters
->pos
) {
1249 imlib_context_set_filter(adesklets
.filters
->content
[i
]);
1253 imlib_context_set_filter(NULL
);
1255 command_error("filter ID %d out of range\n",i
);
1259 imlib_context_set_filter(NULL
);
1261 if(j
) command_ok("context filter unset\n");
1263 case CMD_CONTEXT_SET_COLOR
:
1265 imlib_context_set_color(atoi(params
->content
[1]),
1266 atoi(params
->content
[2]),
1267 atoi(params
->content
[3]),
1268 atoi(params
->content
[4]));
1270 command_error("color RGBA description not given\n");
1272 case CMD_CONTEXT_SET_ANGLE
:
1273 if (params
->pos
>=2) {
1274 imlib_context_set_angle(atof(params
->content
[1]));
1276 command_error("angle not given\n");
1278 case CMD_CONTEXT_SET_DIRECTION
:
1279 /* prototype(enum DIRECTIONS direction) */
1280 if(params
->pos
>=2) {
1281 for(i
=0;DIRECTIONS
[i
];++i
)
1282 if(strncmp(DIRECTIONS
[i
],params
->content
[1],
1283 strlen(params
->content
[1]))==0)
1285 imlib_context_set_direction((DIRECTIONS
[i
])?
1286 i
:((j
=atoi(params
->content
[1])))<5?j
:0);
1288 command_error("direction not given\n");
1290 case CMD_ADD_COLOR_TO_COLOR_RANGE
:
1291 if(imlib_context_get_color_range()) {
1292 i
=(params
->pos
>=2)?atoi(params
->content
[1]):0;
1293 imlib_add_color_to_color_range(i
);
1295 command_error("no color range selected\n");
1297 case CMD_BLEND_IMAGE_ONTO_IMAGE
:
1298 if (params
->pos
>=11) {
1299 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1300 i
<adesklets
.images
->pos
) {
1301 imlib_blend_image_onto_image(adesklets
.images
->content
[i
],
1302 atoi(params
->content
[2]),
1303 atoi(params
->content
[3]),
1304 atoi(params
->content
[4]),
1305 atoi(params
->content
[5]),
1306 atoi(params
->content
[6]),
1307 atoi(params
->content
[7]),
1308 atoi(params
->content
[8]),
1309 atoi(params
->content
[9]),
1310 atoi(params
->content
[10]));
1311 if (image_is_shown())
1312 updates
= imlib_update_append_rect(updates
,
1313 atoi(params
->content
[7]),
1314 atoi(params
->content
[8]),
1315 atoi(params
->content
[9]),
1316 atoi(params
->content
[10]));
1318 command_error("image ID %d out of range\n",i
);
1320 command_error("not enough parameters given - need ten\n");
1322 case CMD_BLEND_IMAGE_ONTO_IMAGE_AT_ANGLE
:
1323 if (params
->pos
>=11) {
1324 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1325 i
<adesklets
.images
->pos
) {
1326 imlib_blend_image_onto_image_at_angle(
1327 adesklets
.images
->content
[i
],
1328 atoi(params
->content
[2]),
1329 atoi(params
->content
[3]),
1330 atoi(params
->content
[4]),
1331 atoi(params
->content
[5]),
1332 atoi(params
->content
[6]),
1333 atoi(params
->content
[7]),
1334 atoi(params
->content
[8]),
1335 atoi(params
->content
[9]),
1336 atoi(params
->content
[10]));
1337 if (image_is_shown())
1338 /* We do not bother: we update everything */
1339 updates
= imlib_update_append_rect(updates
,
1341 imlib_image_get_width(),
1342 imlib_image_get_height());
1344 command_error("image ID %d out of range\n",i
);
1346 command_error("not enough parameters given - need ten\n");
1348 case CMD_BLEND_IMAGE_ONTO_IMAGE_SKEWED
:
1349 if (params
->pos
>=12) {
1350 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1351 i
<adesklets
.images
->pos
) {
1352 imlib_blend_image_onto_image_skewed(adesklets
.images
->content
[i
],
1353 atoi(params
->content
[2]),
1354 atoi(params
->content
[3]),
1355 atoi(params
->content
[4]),
1356 atoi(params
->content
[5]),
1357 atoi(params
->content
[6]),
1358 atoi(params
->content
[7]),
1359 atoi(params
->content
[8]),
1360 atoi(params
->content
[9]),
1361 atoi(params
->content
[10]),
1362 atoi(params
->content
[11]),
1363 atoi(params
->content
[12]));
1364 if (image_is_shown())
1365 /* We do not bother: we update everything */
1366 updates
= imlib_update_append_rect(updates
,
1368 imlib_image_get_width(),
1369 imlib_image_get_height());
1371 command_error("image ID %d out of range\n",i
);
1373 command_error("not enough parameters given - need twelve\n");
1375 case CMD_APPLY_FILTER
:
1376 /* WARNING: there is a initialisation bug in imlib2 prior
1377 version 1.2.0 (cvs of 11/20/04) that sets the dynamic filters
1378 never to work if an image loader is not used
1379 at least once before (this has to do with
1380 lt_dlinit() being called at the wrong place...).
1381 We can do nothing about this: upgrade your imlib2 lib!
1383 prototype(const char * script)
1385 if(params
->pos
>=2) {
1386 menu_str
=command_subsplitter(command
.line
,1);
1387 if(!strstr(menu_str
,"[]")) {
1388 imlib_apply_filter(menu_str
);
1389 if (image_is_shown())
1390 updates
=imlib_update_append_rect(updates
,0,0,
1391 imlib_image_get_width(),
1392 imlib_image_get_height());
1395 command_error("variadic filters forbidden\n");
1397 command_error("filter description not given\n");
1400 "tint(x=0,y=0,w=100,h=100,alpha=100,red=155,green=25,blue=25);"
1403 case CMD_GET_TEXT_SIZE
:
1404 /* prototype(const char * text) */
1405 if(imlib_context_get_font()) {
1406 if(params
->pos
>=2) {
1407 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,1));
1408 imlib_get_text_size(menu_str
,
1411 command_ok("text size %d %d\n",i
,j
);
1413 command_error("text string not given or blank\n");
1415 command_error("no font selected.\n");
1417 case CMD_GET_TEXT_ADVANCE
:
1418 /* prototype(const char * text) */
1419 if(imlib_context_get_font()) {
1420 if(params
->pos
>=2) {
1421 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,1));
1422 imlib_get_text_advance(menu_str
,&i
,&j
);
1424 command_ok("text advance %d %d\n",i
,j
);
1426 command_error("text string not given or blank\n");
1428 command_error("no font selected.\n");
1431 if(imlib_context_get_font()) {
1432 if(params
->pos
>=4) {
1433 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,3));
1434 imlib_text_draw(atoi(params
->content
[1]),
1435 atoi(params
->content
[2]),
1437 if (image_is_shown()) {
1438 imlib_get_text_size(menu_str
,&x
,&y
);
1439 updates
= imlib_update_append_rect(updates
,
1440 atoi(params
->content
[1]),
1441 atoi(params
->content
[2]),
1446 command_error("text string not given or blank\n");
1448 command_error("no font selected.\n");
1450 case CMD_MODIFY_COLOR_MODIFIER_GAMMA
:
1451 if(imlib_context_get_color_modifier()) {
1452 if(params
->pos
>=2) {
1453 imlib_modify_color_modifier_gamma(atof(params
->content
[1]));
1455 command_error("gamma value not given\n");
1457 command_error("no context color modifier selected\n");
1459 case CMD_MODIFY_COLOR_MODIFIER_BRIGHTNESS
:
1460 if(imlib_context_get_color_modifier()) {
1461 if(params
->pos
>=2) {
1462 imlib_modify_color_modifier_brightness(atof(params
->content
[1]));
1464 command_error("brightness value not given\n");
1466 command_error("no context color modifier selected\n");
1468 case CMD_MODIFY_COLOR_MODIFIER_CONTRAST
:
1469 if(imlib_context_get_color_modifier()) {
1470 if(params
->pos
>=2) {
1471 imlib_modify_color_modifier_contrast(atof(params
->content
[1]));
1473 command_error("contrast value not given\n");
1475 command_error("no context color modifier selected\n");
1477 case CMD_GET_COLOR_MODIFIER_TABLES
:
1478 /* prototype(void) */
1479 /* Throw all 1024 table entries in RGBA orders */
1480 if(imlib_context_get_color_modifier()) {
1481 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1482 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1483 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1484 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1485 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1486 tables
[2],tables
[3]);
1489 command_printf("%hhu ", tables
[i
][j
]);
1490 command_printf("\n");
1492 command_error("memory allocation problem\n");
1494 if(tables
[i
]) free(tables
[i
]);
1496 command_error("no context color modifier selected\n");
1499 case CMD_SET_COLOR_MODIFIER_TABLES
:
1500 /* prototype(unsigned char * table) */
1501 if(imlib_context_get_color_modifier()) {
1502 if (params
->pos
==1025) {
1503 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1504 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1505 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1506 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1509 tables
[i
][j
]=(DATA8
)atoi(params
->content
[(i
*256)+j
+1]);
1510 imlib_set_color_modifier_tables(tables
[0],tables
[1],
1511 tables
[2],tables
[3]);
1512 command_ok("set_color_modifier_tables\n");
1514 command_error("memory allocation problem");
1516 if(tables
[i
]) free(tables
[i
]);
1518 command_error("Invalid number of entries - need 1024\n");
1520 command_error("no context color modifier selected\n");
1522 case CMD_GET_COLOR_MODIFIER_VALUE
:
1523 /* prototype(enum RGBA_TABLES table, int index) */
1524 /* NOTE: this is not an original imlib2 function.
1525 it was included as a convenience for
1527 if(imlib_context_get_color_modifier()) {
1528 if (params
->pos
>=3) {
1529 for(i
=0;RGBA_TABLES
[i
];++i
)
1530 if(strncmp(RGBA_TABLES
[i
],
1532 strlen(params
->content
[1]))==0)
1534 i
=(RGBA_TABLES
[i
])?i
:atoi(params
->content
[1])%4;
1536 if((j
=atoi(params
->content
[2]))<256 && j
>=0) {
1537 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1538 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1539 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1540 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1541 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1542 tables
[2],tables
[3]);
1543 command_ok("value %s %hhu\n",
1545 (char)tables
[i
][j
]&255);
1548 command_error("memory allocation problem\n");
1550 if(tables
[i
]) free(tables
[i
]);
1552 command_error("index value %d out of range\n",j
);
1554 command_error("parameters not given - need two\n");
1556 command_error("no context color modifier selected\n");
1558 case CMD_SET_COLOR_MODIFIER_VALUE
:
1559 /* prototype(enum RGBA_TABLES table, int index, int value) */
1560 /* NOTE: this is not an original imlib2 function.
1561 it was included as a convenience for
1563 if(imlib_context_get_color_modifier()) {
1564 if (params
->pos
>=4) {
1565 for(i
=0;RGBA_TABLES
[i
];++i
)
1566 if(strncmp(RGBA_TABLES
[i
],
1568 strlen(params
->content
[1]))==0)
1570 i
=(RGBA_TABLES
[i
])?i
:atoi(params
->content
[1])%4;
1572 if((j
=atoi(params
->content
[2]))<256 && j
>=0) {
1573 if ((x
=atoi(params
->content
[3]))<256 && x
>=0) {
1574 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1575 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1576 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1577 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1578 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1579 tables
[2],tables
[3]);
1581 imlib_set_color_modifier_tables(tables
[0],tables
[1],
1582 tables
[2],tables
[3]);
1584 command_error("memory allocation problem\n");
1586 if(tables
[i
]) free(tables
[i
]);
1588 command_error("value %d out of range\n",x
);
1590 command_error("index value %d out of range\n",j
);
1592 command_error("parameters not given - need three\n");
1594 command_error("no context color modifier selected\n");
1596 case CMD_APPLY_COLOR_MODIFIER
:
1597 if(imlib_context_get_color_modifier()) {
1598 imlib_apply_color_modifier();
1599 if(image_is_shown())
1600 updates
=imlib_update_append_rect(updates
,0,0,
1601 imlib_image_get_width(),
1602 imlib_image_get_height());
1604 command_error("no context color modifier selected\n");
1606 case CMD_APPLY_COLOR_MODIFIER_TO_RECTANGLE
:
1607 if(imlib_context_get_color_modifier()) {
1608 if (params
->pos
>=5) {
1609 imlib_apply_color_modifier_to_rectangle(
1610 (x
=atoi(params
->content
[1])),
1611 (y
=atoi(params
->content
[2])),
1612 (i
=atoi(params
->content
[3])),
1613 (j
=atoi(params
->content
[4])));
1614 if (image_is_shown())
1615 updates
=imlib_update_append_rect(updates
,x
,y
,i
,j
);
1617 command_error("rectangles coordinates not given\n");
1619 command_error("no context color modifier selected\n");
1621 case CMD_LOAD_IMAGE_WITHOUT_CACHE
:
1622 if (params
->pos
>=2) {
1623 menu_str
=command_subsplitter(command
.line
,1);
1624 if ((image
=imlib_load_image_without_cache(menu_str
))) {
1625 if (vector_push(adesklets
.images
,image
))
1626 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1628 command_error("memory allocation problem\n");
1630 command_error("could not load image '%s'\n", menu_str
);
1632 command_error("image file name not given\n");
1634 case CMD_LOAD_IMAGE
:
1635 if (params
->pos
>=2) {
1636 menu_str
=command_subsplitter(command
.line
,1);
1637 if ((image
=imlib_load_image_with_error_return(menu_str
,&error
))) {
1638 if (vector_push(adesklets
.images
,image
))
1639 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1641 command_error("memory allocation problem\n");
1643 command_error("could not load image '%s' - %s\n",
1644 menu_str
,LOAD_ERRORS
[(int)error
]);
1646 command_error("image file name not given\n");
1648 case CMD_SAVE_IMAGE
:
1649 if (params
->pos
>=2) {
1650 menu_str
=command_subsplitter(command
.line
,1);
1651 imlib_save_image_with_error_return(menu_str
,&error
);
1652 if(error
!=IMLIB_LOAD_ERROR_NONE
)
1653 command_error("%s\n",LOAD_ERRORS
[(int)error
]);
1655 command_error("image file name not given\n");
1657 case CMD_CREATE_IMAGE
:
1658 if (params
->pos
>=3) {
1659 if((i
=atoi(params
->content
[1]))>0 &&
1660 (j
=atoi(params
->content
[2]))>0) {
1661 if((image
=imlib_create_image(i
,j
))) {
1662 xwindow_context_save(IMLIB_IMAGE
|IMLIB_BLEND
|IMLIB_COLOR
);
1663 imlib_context_set_image(image
);
1664 imlib_image_set_has_alpha(1);
1665 imlib_context_set_blend(0);
1666 imlib_context_set_color(0,0,0,0);
1667 imlib_image_fill_rectangle(0,0,i
,j
);
1668 xwindow_context_restore();
1669 if (vector_push(adesklets
.images
,image
))
1670 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1672 command_error("memory allocation problem\n");
1674 command_error("imlib image allocation error\n");
1676 command_error("image dimensions out of range\n");
1678 command_error("image dimensions were not given\n");
1680 case CMD_CREATE_IMAGE_USING_DATA
:
1681 /* This uses imlib_create_image_using_copied_data(),
1682 so DATA * data can be freed afterward.
1683 As in CMD_IMAGE_GET_DATA, data is expected to be
1685 if (params
->pos
>=3) {
1686 if ((width
=atoi(params
->content
[1]))>0 &&
1687 (height
=atoi(params
->content
[2]))>0) {
1688 if(width
*height
*4==params
->pos
-3) {
1689 if((data
=(DATA32
*)malloc(sizeof(DATA32
)*width
*height
))) {
1690 for(i
=0;i
<width
*height
;++i
)
1692 ((atoi((char*)params
->content
[i
*4+3])&255)<<16)|
1693 ((atoi((char*)params
->content
[i
*4+4])&255)<<8)|
1694 ((atoi((char*)params
->content
[i
*4+5])&255)<<0)|
1695 ((atoi((char*)params
->content
[i
*4+6])&255)<<24);
1696 if ((image
=imlib_create_image_using_copied_data(width
,
1699 xwindow_context_save(IMLIB_IMAGE
);
1700 imlib_context_set_image(image
);
1701 imlib_image_set_has_alpha(1);
1702 xwindow_context_restore();
1703 if(vector_push(adesklets
.images
,image
))
1704 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1706 command_error("memory allocation problem");
1708 command_error("imlib image allocation error\n");
1712 command_error("memory allocation problem\n");
1714 command_error("image dimensions and data lenght mismatch\n");
1716 command_error("image dimensions out of range\n");
1718 command_error("image dimensions were not given\n");
1720 case CMD_CLONE_IMAGE
:
1721 if((image
=imlib_clone_image())) {
1722 if (vector_push(adesklets
.images
,image
))
1723 command_ok("cloned image %d\n",adesklets
.images
->pos
-1);
1725 command_error("memory allocation problem");
1727 command_error("imlib image allocation error\n");
1729 case CMD_FREE_IMAGE
:
1730 /* This does not react as imlib_free_image:
1731 - image ID has to be given
1732 - If current context image is freed, context
1733 is put back on foreground image
1734 - If image corresponding to user_background_image
1735 is freed, user_background_image is reset.
1737 prototype(int image)
1739 if(params
->pos
>=2) {
1740 if((i
=atoi((char*)params
->content
[1]))<adesklets
.images
->pos
&&
1743 j
=(imlib_context_get_image()==adesklets
.images
->content
[i
]);
1744 if (vector_delete(adesklets
.images
,i
)) {
1745 if(i
==adesklets
.user_background_image
) {
1746 adesklets
.user_background_image
=-1;
1747 xwindow_context_save(IMLIB_IMAGE
);
1748 imlib_context_set_image(adesklets
.images
->content
[0]);
1749 updates
=imlib_update_append_rect(updates
,0,0,
1750 imlib_image_get_width(),
1751 imlib_image_get_height());
1752 xwindow_context_restore();
1755 if(i
<adesklets
.user_background_image
)
1756 --adesklets
.user_background_image
;
1758 imlib_context_set_image(adesklets
.images
->content
[0]);
1760 command_error("memory desallocation problem\n");
1762 command_error("it is forbidden to unload image %d\n",i
);
1764 command_error("image ID %d out of range\n",i
);
1766 command_error("image ID not given\n");
1769 if(params
->pos
>=2) {
1770 if (strlen(params
->content
[1])>=3 &&
1771 index(params
->content
[1],'/')) {
1772 if ((font
=imlib_load_font(params
->content
[1]))) {
1773 if(vector_push(adesklets
.fonts
,font
))
1774 command_ok("new font %d\n", adesklets
.fonts
->pos
-1);
1776 command_error("memory allocation problem");
1778 command_error("font '%s' could not be loaded\n",
1779 (char*)params
->content
[1]);
1782 "font description incorrect - should be `name/size'\n");
1784 command_error("font description not given\n");
1787 /* This does not react as imlib_free_font:
1788 - font ID has to be given
1789 - If current font is freed, context
1794 if(params
->pos
>=2) {
1795 if((i
=atoi((char*)params
->content
[1]))
1796 <adesklets
.fonts
->pos
&&
1798 j
=(imlib_context_get_font()==
1799 adesklets
.fonts
->content
[i
]);
1800 if (vector_delete(adesklets
.fonts
,i
)) {
1802 imlib_context_set_font(NULL
);
1804 command_error("memory desallocation problem\n");
1806 command_error("font ID %d out of range\n",i
);
1808 command_error("font ID not given\n");
1810 case CMD_LIST_FONTS
:
1811 /* prototype(void) */
1812 list
=imlib_list_fonts(&j
);
1813 command_printf("%d fonts found\n",j
);
1815 command_printf("%s ",list
[i
]);
1816 command_printf("\n");
1817 imlib_free_font_list(list
,j
);
1819 case CMD_LIST_FONT_PATH
:
1820 /* prototype(void) */
1821 list
=imlib_list_font_path(&j
);
1822 command_printf("%d font_path found\n",j
);
1824 command_printf("%s\n",list
[i
]);
1826 case CMD_ADD_PATH_TO_FONT_PATH
:
1827 if(params
->pos
>=2) {
1828 imlib_add_path_to_font_path(command_subsplitter(command
.line
,1));
1830 command_error("font path not given\n");
1832 case CMD_REMOVE_PATH_FROM_FONT_PATH
:
1833 if(params
->pos
>=2) {
1834 imlib_remove_path_from_font_path(
1835 command_subsplitter(command
.line
,1));
1836 debug("%s\n",command_subsplitter(command
.line
,1));
1838 command_error("font path not given\n");
1840 case CMD_CREATE_COLOR_RANGE
:
1841 if((color_range
=imlib_create_color_range())) {
1842 if(vector_push(adesklets
.color_ranges
,color_range
))
1843 command_ok("new colorrange %d\n",adesklets
.color_ranges
->pos
-1);
1845 command_error("memory allocation problem\n");
1847 command_error("imlib allocation problem\n");
1849 case CMD_FREE_COLOR_RANGE
:
1850 /* This does not react as imlib_free_color_range:
1851 - color_range ID has to be given
1852 - If current color range is freed, context
1855 prototype(int color_range)
1857 if(params
->pos
>=2) {
1858 if((i
=atoi((char*)params
->content
[1]))
1859 <adesklets
.color_ranges
->pos
&&
1861 j
=(imlib_context_get_color_range()==
1862 adesklets
.color_ranges
->content
[i
]);
1863 if (vector_delete(adesklets
.color_ranges
,i
)) {
1865 imlib_context_set_color_range(NULL
);
1867 command_error("memory desallocation problem\n");
1869 command_error("color range ID %d out of range\n",i
);
1871 command_error("color range ID not given\n");
1873 case CMD_CREATE_FILTER
:
1874 /* prototype(void) */
1875 if((filter
=imlib_create_filter(0))) {
1876 if(vector_push(adesklets
.filters
,filter
))
1877 command_ok("new filter %d\n",adesklets
.filters
->pos
-1);
1879 command_error("memory allocation problem\n");
1881 command_error("imlib allocation problem\n");
1883 case CMD_FREE_FILTER
:
1884 /* This does not react as imlib_free_filter:
1885 - filter ID has to be given
1886 - If current filter is freed, context
1889 prototype(int filter)
1891 if(params
->pos
>=2) {
1892 if((i
=atoi((char*)params
->content
[1]))
1893 <adesklets
.filters
->pos
&&
1895 j
=(imlib_context_get_filter()==
1896 adesklets
.filters
->content
[i
]);
1897 if (vector_delete(adesklets
.filters
,i
)) {
1899 imlib_context_set_filter(NULL
);
1901 command_error("memory desallocation problem\n");
1903 command_error("filter ID %d out of range\n",i
);
1905 command_error("filter ID not given\n");
1907 case CMD_CREATE_COLOR_MODIFIER
:
1908 if((color_modifier
=imlib_create_color_modifier())) {
1909 if(vector_push(adesklets
.color_modifiers
,color_modifier
))
1910 command_ok("new colormodifier %d\n",
1911 adesklets
.color_modifiers
->pos
-1);
1913 command_error("memory allocation problem\n");
1915 command_error("imlib allocation problem\n");
1917 case CMD_FREE_COLOR_MODIFIER
:
1918 /* This does not react as imlib_free_color_modifier:
1919 - color_range ID has to be given
1920 - If current color modifier is freed, context
1923 prototype(int color_modifier)
1925 if(params
->pos
>=2) {
1926 if((i
=atoi((char*)params
->content
[1]))
1927 <adesklets
.color_modifiers
->pos
&&
1929 j
=(imlib_context_get_color_modifier()==
1930 adesklets
.color_modifiers
->content
[i
]);
1931 if (vector_delete(adesklets
.color_modifiers
,i
)) {
1933 imlib_context_set_color_modifier(NULL
);
1935 command_error("memory desallocation problem\n");
1937 command_error("color modifier ID %d out of range\n",i
);
1939 command_error("color modifier ID not given\n");
1941 case CMD_POLYGON_NEW
:
1942 if((polygon
=imlib_polygon_new())) {
1943 if(vector_push(adesklets
.polygons
,polygon
))
1944 command_ok("new polygon %d\n",adesklets
.polygons
->pos
-1);
1946 command_error("memory allocation problem\n");
1948 command_error("imlib allocation problem\n");
1950 case CMD_POLYGON_FREE
:
1951 if(params
->pos
>=2) {
1952 if((i
=atoi(params
->content
[1]))>=0 &&
1953 i
<adesklets
.polygons
->pos
) {
1954 if(!vector_delete(adesklets
.polygons
,i
))
1955 command_error("memory desallocation problem\n");
1957 command_error("polygon ID %d out of range\n",i
);
1959 command_error("polygon ID not given\n");
1961 case CMD_POLYGON_ADD_POINT
:
1962 if(params
->pos
>=4) {
1963 if((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
1964 imlib_polygon_add_point(adesklets
.polygons
->content
[i
],
1965 atoi(params
->content
[2]),
1966 atoi(params
->content
[3]));
1968 command_error("polygon ID %d out of range\n",i
);
1970 command_error("not enough parameters given - need 3\n");
1972 case CMD_IMAGES_RESET_ALL
:
1973 /* prototype(void) */
1974 adesklets_images_reset();
1976 case CMD_IMAGES_INFO
:
1977 /* prototype(void) */
1978 xwindow_context_save(IMLIB_IMAGE
);
1979 command_printf("%d images\n",adesklets
.images
->pos
);
1980 for(i
=0;i
<adesklets
.images
->pos
;++i
) {
1981 imlib_context_set_image(adesklets
.images
->content
[i
]);
1982 command_printf("id %d width %d height %d alpha %hhu filename %s\n",
1984 imlib_image_get_width(), imlib_image_get_height(),
1985 imlib_image_has_alpha(), imlib_image_get_filename());
1987 xwindow_context_restore();
1989 case CMD_FONTS_RESET_ALL
:
1990 /* prototype(void) */
1991 adesklets_fonts_reset();
1993 case CMD_FONTS_INFO
:
1994 /* prototype(void) */
1995 command_printf("%d fonts\n",adesklets
.fonts
->pos
);
1997 case CMD_COLOR_RANGES_RESET_ALL
:
1998 /* prototype(void) */
1999 adesklets_color_ranges_reset();
2001 case CMD_COLOR_RANGES_INFO
:
2002 /* prototype(void) */
2003 command_printf("%d color ranges\n",adesklets
.color_ranges
->pos
);
2005 case CMD_COLOR_MODIFIERS_RESET_ALL
:
2006 /* prototype(void) */
2007 adesklets_color_modifiers_reset();
2009 case CMD_COLOR_MODIFIERS_INFO
:
2010 /* prototype(void) */
2011 command_printf("%d color modifiers\n",adesklets
.color_modifiers
->pos
);
2013 case CMD_FILTERS_RESET_ALL
:
2014 /* prototype(void) */
2015 adesklets_filters_reset();
2017 case CMD_FILTERS_INFO
:
2018 /* prototype(void) */
2019 command_printf("%d filters\n",adesklets
.filters
->pos
);
2021 case CMD_POLYGONS_RESET_ALL
:
2022 /* prototype(void) */
2023 adesklets_polygons_reset();
2025 case CMD_POLYGONS_INFO
:
2026 /* prototype(void) */
2027 command_printf("%d polygons\n",adesklets
.polygons
->pos
);
2029 case CMD_IMAGE_HAS_ALPHA
:
2030 command_ok("image alpha %hhu\n",imlib_image_has_alpha());
2032 case CMD_IMAGE_GET_WIDTH
:
2033 command_ok("image width %d\n",imlib_image_get_width());
2035 case CMD_IMAGE_GET_HEIGHT
:
2036 command_ok("image height %d\n",imlib_image_get_height());
2038 case CMD_IMAGE_GET_FILENAME
:
2039 command_ok("image filename %s\n",imlib_image_get_filename());
2041 case CMD_IMAGE_GET_DATA
:
2042 /* This uses imlib_image_get_data_for_reading_only(),
2043 so there is no need to invalidate image. Print final result
2045 if((data
=imlib_image_get_data_for_reading_only())) {
2046 width
=imlib_image_get_width();
2047 height
=imlib_image_get_height();
2048 command_printf("image data - %d %d\n",width
,height
);
2049 for(i
=0;i
<width
*height
;++i
)
2050 command_printf("%hhu %hhu %hhu %hhu ",
2051 ((data
[i
]&(255<<16))>>16),
2052 ((data
[i
]&(255<<8))>>8),
2054 ((data
[i
]&(255<<24))>>24));
2055 command_printf("\n");
2057 command_error("imlib data fetch problem\n");
2059 case CMD_IMAGE_QUERY_PIXEL
:
2060 /* prototype(int x, int y) */
2061 if (params
->pos
>=2) {
2062 imlib_image_query_pixel(atoi(params
->content
[1]),
2063 atoi(params
->content
[2]),
2065 command_ok("pixel value %hhu %hhu %hhu %hhu\n",
2066 (char)color
.red
&255,(char)color
.green
&255,
2067 (char)color
.blue
&255,(char)color
.alpha
&255);
2069 command_error("pixel coordinates not given\n");
2071 case CMD_IMAGE_SET_HAS_ALPHA
:
2072 /* prototype(bool has_alpha) */
2074 imlib_image_set_has_alpha((char)atoi(params
->content
[1]));
2076 command_error("alpha value not given\n");
2078 case CMD_IMAGE_SET_CHANGES_ON_DISK
:
2079 /* prototype(void) */
2080 imlib_image_set_changes_on_disk();
2082 case CMD_IMAGE_SET_FORMAT
:
2084 imlib_image_set_format(params
->content
[1]);
2086 command_error("format string not given\n");
2088 case CMD_IMAGE_FILTER_RECURSE
:
2089 /* prototype(void) */
2090 if(imlib_context_get_filter()) {
2091 for(i
=0,j
=imlib_image_get_width();i
<j
;++i
) {
2092 imlib_image_filter();
2094 if(i
%(j
/10)==(j
/10)-1)
2095 debug("We are %d0 percents through.\n", (i
+1)*10/j
);
2098 if(image_is_shown())
2099 updates
=imlib_update_append_rect(updates
,0,0,
2100 imlib_image_get_width(),
2101 imlib_image_get_height());
2104 command_error("no filter selected\n");
2106 case CMD_IMAGE_DRAW_LINE
:
2107 if(params
->pos
>=5) {
2108 imlib_image_draw_line(atoi(params
->content
[1]),
2109 atoi(params
->content
[2]),
2110 atoi(params
->content
[3]),
2111 atoi(params
->content
[4]),0);
2112 if (image_is_shown())
2113 updates
= imlib_update_append_rect(updates
,
2114 atoi(params
->content
[1]),
2115 atoi(params
->content
[2]),
2116 atoi(params
->content
[3])-
2117 atoi(params
->content
[1]),
2118 atoi(params
->content
[4])-
2119 atoi(params
->content
[2]));
2121 command_error("line coordinates not given\n");
2123 case CMD_IMAGE_DRAW_RECTANGLE
:
2124 if(params
->pos
>=5) {
2125 imlib_image_draw_rectangle(atoi(params
->content
[1]),
2126 atoi(params
->content
[2]),
2127 atoi(params
->content
[3]),
2128 atoi(params
->content
[4]));
2129 if (image_is_shown())
2130 updates
= imlib_update_append_rect(updates
,
2131 atoi(params
->content
[1]),
2132 atoi(params
->content
[2]),
2133 atoi(params
->content
[3]),
2134 atoi(params
->content
[4]));
2136 command_error("rectangle description not given\n");
2138 case CMD_IMAGE_FILL_RECTANGLE
:
2139 if(params
->pos
>=5) {
2140 imlib_image_fill_rectangle(atoi(params
->content
[1]),
2141 atoi(params
->content
[2]),
2142 atoi(params
->content
[3]),
2143 atoi(params
->content
[4]));
2144 if (image_is_shown())
2145 updates
= imlib_update_append_rect(updates
,
2146 atoi(params
->content
[1]),
2147 atoi(params
->content
[2]),
2148 atoi(params
->content
[3]),
2149 atoi(params
->content
[4]));
2151 command_error("rectangle description not given\n");
2153 case CMD_IMAGE_FILL_COLOR_RANGE_RECTANGLE
:
2154 if (imlib_context_get_color_range()) {
2155 if(params
->pos
>=6) {
2156 imlib_image_fill_color_range_rectangle(atoi(params
->content
[1]),
2157 atoi(params
->content
[2]),
2158 atoi(params
->content
[3]),
2159 atoi(params
->content
[4]),
2160 atof(params
->content
[5]));
2161 if (image_is_shown())
2162 updates
= imlib_update_append_rect(updates
,
2163 atoi(params
->content
[1]),
2164 atoi(params
->content
[2]),
2165 atoi(params
->content
[3]),
2166 atoi(params
->content
[4]));
2168 command_error("not enough parameters given - need five\n");
2170 command_error("no color range selected\n");
2172 case CMD_IMAGE_DRAW_ELLIPSE
:
2173 if(params
->pos
>=5) {
2174 imlib_image_draw_ellipse(atoi(params
->content
[1]),
2175 atoi(params
->content
[2]),
2176 atoi(params
->content
[3]),
2177 atoi(params
->content
[4]));
2178 if (image_is_shown())
2179 updates
= imlib_update_append_rect(updates
,
2180 atoi(params
->content
[1])-
2181 atoi(params
->content
[3]),
2182 atoi(params
->content
[2])-
2183 atoi(params
->content
[4]),
2184 2*atoi(params
->content
[3]),
2185 2*atoi(params
->content
[4]));
2187 command_error("ellipse description not given\n");
2189 case CMD_IMAGE_FILL_ELLIPSE
:
2190 if(params
->pos
>=5) {
2191 imlib_image_fill_ellipse(atoi(params
->content
[1]),
2192 atoi(params
->content
[2]),
2193 atoi(params
->content
[3]),
2194 atoi(params
->content
[4]));
2195 if (image_is_shown())
2196 updates
= imlib_update_append_rect(updates
,
2197 atoi(params
->content
[1])-
2198 atoi(params
->content
[3]),
2199 atoi(params
->content
[2])-
2200 atoi(params
->content
[4]),
2201 2*atoi(params
->content
[3]),
2202 2*atoi(params
->content
[4]));
2204 command_error("ellipse description not given\n");
2206 case CMD_IMAGE_COPY_ALPHA_TO_IMAGE
:
2207 if(params
->pos
>=4) {
2208 if((i
=atoi(params
->content
[1]))>=0 &&
2209 i
<adesklets
.images
->pos
) {
2210 imlib_image_copy_alpha_to_image(adesklets
.images
->content
[i
],
2211 atoi(params
->content
[2]),
2212 atoi(params
->content
[3]));
2213 if(image_is_shown()) {
2214 xwindow_context_save(IMLIB_IMAGE
);
2215 imlib_context_set_image(adesklets
.images
->content
[i
]);
2216 updates
= imlib_update_append_rect(updates
,
2217 atoi(params
->content
[2]),
2218 atoi(params
->content
[3]),
2219 imlib_image_get_width(),
2220 imlib_image_get_height());
2221 xwindow_context_restore();
2224 command_error("image ID out of range\n");
2226 command_error("parameters not given\n");
2228 case CMD_IMAGE_COPY_ALPHA_RECTANGLE_TO_IMAGE
:
2229 if(params
->pos
>=8) {
2230 if((i
=atoi(params
->content
[1]))>=0 &&
2231 i
<adesklets
.images
->pos
) {
2232 imlib_image_copy_alpha_rectangle_to_image(
2233 adesklets
.images
->content
[i
],
2234 atoi(params
->content
[2]),
2235 atoi(params
->content
[3]),
2236 atoi(params
->content
[4]),
2237 atoi(params
->content
[5]),
2238 atoi(params
->content
[6]),
2239 atoi(params
->content
[7]));
2241 if(image_is_shown())
2242 updates
= imlib_update_append_rect(updates
,
2243 atoi(params
->content
[6]),
2244 atoi(params
->content
[7]),
2245 atoi(params
->content
[4]),
2246 atoi(params
->content
[5]));
2248 command_error("image ID out of range\n");
2250 command_error("parameters not given - need height\n");
2252 case CMD_IMAGE_DRAW_POLYGON
:
2253 if (params
->pos
>=3) {
2254 if ((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
2255 imlib_image_draw_polygon(adesklets
.polygons
->content
[i
],
2256 ((char*)params
->content
[2])[0]);
2257 if(image_is_shown()) {
2258 imlib_polygon_get_bounds(adesklets
.polygons
->content
[i
],
2260 updates
= imlib_update_append_rect(updates
,x
,y
,i
-x
,j
-y
);
2263 command_error("polygon ID %d out of range\n",i
);
2265 command_error("parameters not given\n");
2267 case CMD_IMAGE_FILL_POLYGON
:
2268 if (params
->pos
>=2) {
2269 if ((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
2270 imlib_image_fill_polygon(adesklets
.polygons
->content
[i
]);
2271 if(image_is_shown()) {
2272 imlib_polygon_get_bounds(adesklets
.polygons
->content
[i
],
2274 updates
= imlib_update_append_rect(updates
,x
,y
,i
-x
,j
-y
);
2277 command_error("polygon ID %d out of range\n",i
);
2279 command_error("polygon ID not given\n");
2281 case CMD_IMAGE_FLIP_HORIZONTAL
:
2282 imlib_image_flip_horizontal();
2283 if (image_is_shown())
2284 updates
=imlib_update_append_rect(updates
,0,0,
2285 imlib_image_get_width(),
2286 imlib_image_get_height());
2288 case CMD_IMAGE_FLIP_VERTICAL
:
2289 imlib_image_flip_vertical();
2290 if (image_is_shown())
2291 updates
=imlib_update_append_rect(updates
,0,0,
2292 imlib_image_get_width(),
2293 imlib_image_get_height());
2295 case CMD_IMAGE_FLIP_DIAGONAL
:
2296 if(((image
=imlib_context_get_image()))!=
2297 adesklets
.images
->content
[0] &&
2298 image
!= adesklets
.images
->content
[1] &&
2299 (adesklets
.user_background_image
==-1 ||
2300 image
!= adesklets
.images
->content
[
2301 adesklets
.user_background_image
]))
2302 imlib_image_flip_diagonal();
2304 command_error("operation forbidden on this image\n");
2306 case CMD_IMAGE_ORIENTATE
:
2307 if (params
->pos
>=2) {
2308 if((i
=atoi(params
->content
[1])%4)%2==0 ||
2309 (((image
=imlib_context_get_image())!=
2310 adesklets
.images
->content
[0] &&
2311 image
!= adesklets
.images
->content
[1])))
2312 imlib_image_orientate(i
);
2314 command_error("operation forbidden on this image\n");
2316 command_error("orientation not given\n");
2318 case CMD_IMAGE_BLUR
:
2319 if (params
->pos
>=2) {
2320 imlib_image_blur(atof(params
->content
[1]));
2321 updates
=imlib_update_append_rect(updates
,0,0,
2322 imlib_image_get_width(),
2323 imlib_image_get_height());
2325 command_error("Blur radius not given\n");
2327 case CMD_IMAGE_SHARPEN
:
2328 if (params
->pos
>=2) {
2329 imlib_image_sharpen(atof(params
->content
[1]));
2330 updates
=imlib_update_append_rect(updates
,0,0,
2331 imlib_image_get_width(),
2332 imlib_image_get_height());
2334 command_error("Sharpen radius not given\n");
2336 #define FILTER_SET(op)\
2337 if(imlib_context_get_filter()) {\
2338 if (params->pos>=7)\
2339 imlib_filter_set ## op(atoi(params->content[1]),\
2340 atoi(params->content[2]),\
2341 atoi(params->content[3]),\
2342 atoi(params->content[4]),\
2343 atoi(params->content[5]),\
2344 atoi(params->content[6]));\
2346 command_error("missing parameters - need six\n");\
2348 command_error("no filter selected\n")
2349 case CMD_FILTER_SET
:
2350 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2353 case CMD_FILTER_SET_RED
:
2354 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2357 case CMD_FILTER_SET_GREEN
:
2358 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2361 case CMD_FILTER_SET_BLUE
:
2362 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2365 case CMD_FILTER_SET_ALPHA
:
2366 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2370 #define FILTER_SET(op)\
2371 if(imlib_context_get_filter()) {\
2372 if (params->pos>=5)\
2373 imlib_filter_ ## op(atoi(params->content[1]),\
2374 atoi(params->content[2]),\
2375 atoi(params->content[3]),\
2376 atoi(params->content[4]));\
2378 command_error("missing parameters - need four\n");\
2380 command_error("no filter selected\n")
2381 case CMD_FILTER_CONSTANTS
:
2382 /* prototype(int a, int r, int g, int b) */
2383 FILTER_SET(constants
);
2385 case CMD_FILTER_DIVISORS
:
2386 /* prototype(int a, int r, int g, int b) */
2387 FILTER_SET(divisors
);
2391 /* prototype(int menu) */
2392 #ifndef X_DISPLAY_MISSING
2393 if (adesklets
.display
&& adesklets
.window
) {
2394 if(params
->pos
>=2) {
2395 i
=atoi((char*)params
->content
[1]);
2396 if (adesklets_menu_fire(i
,(char**)&menu_str
)) {
2397 if (adesklets
.user_event_mask
&MenuFireMask
)
2398 event("menufire %d %s\n",i
,menu_str
);
2400 command_error("menu fire error\n");
2403 command_error("menu ID not given\n");
2406 command_error("X connection or window missing\n");
2408 case CMD_MENU_RESET_ALL
:
2409 /* prototype(void) */
2410 if (!adesklets_menus_reset())
2411 command_error("internal consistency problem with menu\n");
2413 case CMD_MENU_ADD_MENU
:
2414 /* prototype(void) */
2415 if (!vector_push(adesklets
.menus
,xmenu_init()))
2416 command_error("could not add a new menu\n");
2418 command_ok("new menu %d\n",adesklets
.menus
->pos
-1);
2420 case CMD_MENU_ADD_SUBMENU
:
2421 /* prototype(const char * submenu) */
2422 if (params
->pos
>=2) {
2423 if (!xmenu_push_submenu(MENU(adesklets
.menus
->pos
-1),
2425 strlen(COMMANDS
[CMD_MENU_ADD_SUBMENU
].name
)))
2426 command_error("could not create submenu\n");
2428 if ((menu_str=dupstr_utf8(command_subsplitter(command.line,1)))) {
2429 if (!xmenu_push_submenu(MENU(adesklets.menus->pos-1),menu_str))
2430 command_error("could not create submenu\n");
2435 command_error("submenu description not given\n");
2437 case CMD_MENU_ADD_ITEM
:
2438 /* prototype(const char * add_item) */
2439 if(params
->pos
>=2) {
2440 if(!xmenu_push_item(MENU(adesklets
.menus
->pos
-1),
2442 strlen(COMMANDS
[CMD_MENU_ADD_ITEM
].name
)))
2443 command_error("could not create item\n");
2445 command_error("item description not given\n");
2447 case CMD_MENU_ADD_SEPARATOR
:
2448 /* prototype(void) */
2449 if(!xmenu_push_item(MENU(adesklets
.menus
->pos
-1),"-"))
2450 command_error("could not add separator\n");
2452 case CMD_MENU_END_SUBMENU
:
2453 /* prototype(void) */
2454 if(!xmenu_end_submenu(MENU(adesklets
.menus
->pos
-1)))
2455 command_error("could not end submenu\n");
2457 case CMD_EVENT_CATCH
:
2458 /* prototype(voidvoid) */
2459 #ifndef X_DISPLAY_MISSING
2460 if (adesklets
.display
&& adesklets
.window
) {
2461 if(params
->pos
>=2) {
2462 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2463 if(strncmp(X_WINDOW_EVENTS
[i
].name
,params
->content
[1],
2464 strlen(X_WINDOW_EVENTS
[i
].name
))==0)
2466 adesklets
.user_event_mask
|=
2467 X_WINDOW_EVENTS
[(X_WINDOW_EVENTS
[i
].name
)?
2468 i
:atoi(params
->content
[1])%i
].mask
;
2469 adesklets
.event_mask
=(BASE_EVENT_MASK
)|
2470 (adesklets
.user_event_mask
&
2471 ~(BackgroundGrabMask
|MenuFireMask
));
2472 XSelectInput(adesklets
.display
,adesklets
.window
,
2473 adesklets
.event_mask
);
2475 command_error("event to catch not given\n");
2478 command_error("X connection or window missing\n");
2480 case CMD_EVENT_UNCATCH
:
2481 /* prototype(voidvoid) */
2482 #ifndef X_DISPLAY_MISSING
2483 if(adesklets
.display
&& adesklets
.window
) {
2484 if(params
->pos
>=2) {
2485 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2486 if(strncmp(X_WINDOW_EVENTS
[i
].name
,params
->content
[1],
2487 strlen(X_WINDOW_EVENTS
[i
].name
))==0)
2489 mask
=X_WINDOW_EVENTS
[(X_WINDOW_EVENTS
[i
].name
)?
2490 i
:atoi(params
->content
[1])%i
].mask
;
2491 /* If event was already selected, purge all remaining
2492 events of that type if applicable */
2493 if(mask
!=BackgroundGrabMask
&&
2494 mask
!=MenuFireMask
&&
2495 (adesklets
.event_mask
&mask
) &&
2496 !((BASE_EVENT_MASK
)&mask
))
2497 while(XCheckWindowEvent(adesklets
.display
,
2498 adesklets
.window
,mask
,&ev
));
2499 adesklets
.user_event_mask
&=~mask
;
2500 adesklets
.event_mask
=(BASE_EVENT_MASK
)|
2501 (adesklets
.user_event_mask
2502 &~(BackgroundGrabMask
|MenuFireMask
));
2503 XSelectInput(adesklets
.display
,adesklets
.window
,
2504 adesklets
.event_mask
);
2506 command_error("event to uncatch not given\n");
2509 command_error("X connection or window missing\n");
2511 case CMD_EVENTS_RESET_ALL
:
2512 /* prototype(voidvoid) */
2513 #ifndef X_DISPLAY_MISSING
2514 if(adesklets
.display
&& adesklets
.window
) {
2515 XSelectInput(adesklets
.display
,adesklets
.window
,
2517 while(XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
2518 adesklets
.user_event_mask
&
2519 ~(BASE_EVENT_MASK
)&~BackgroundGrabMask
&
2522 adesklets
.user_event_mask
=0;
2523 adesklets
.event_mask
=BASE_EVENT_MASK
;
2526 command_error("X connection or window missing\n");
2528 case CMD_EVENTS_INFO
:
2529 /* prototype(void) */
2530 #ifndef X_DISPLAY_MISSING
2531 if (adesklets
.display
&& adesklets
.window
) {
2532 for(i
=0,j
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2533 if(adesklets
.user_event_mask
&X_WINDOW_EVENTS
[i
].mask
)
2535 command_printf("%d events caught\n",j
);
2536 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2537 if(adesklets
.user_event_mask
&X_WINDOW_EVENTS
[i
].mask
)
2538 command_printf("%d (%s)\n",i
, X_WINDOW_EVENTS
[i
].name
);
2541 command_error("X connection or window missing\n");
2543 case CMD_EVENTS_GET_ECHO
:
2544 /* prototype(void) */
2545 command_ok("events echo %d\n", events_echo
);
2547 case CMD_EVENTS_SET_ECHO
:
2548 /* prototype(voidvoid) */
2549 if(params
->pos
>=2) {
2550 if (events_echo
!=(i
=atoi(params
->content
[1]))) {
2557 command_error("echo value not given\n");
2559 case CMD_EVENTS_GET_SEND_SIGUSR1
:
2560 /* prototype(void) */
2561 command_ok("events send_sigusr1 %d\n",(events_ppid
)?1:0);
2563 case CMD_EVENTS_SET_SEND_SIGUSR1
:
2564 /* prototype(voidvoid) */
2566 events_ppid
=(atoi(params
->content
[1]))?adesklets
.ppid
:0;
2568 command_error("send SIGUSR1 status not given\n");
2570 case CMD_EVENTS_PURGE
:
2571 /* prototype(voidvoid) */
2572 command_printf("%d events to purge\n",(events
)?events
->pos
:0);
2575 case CMD_WINDOW_RESET
:
2576 /* prototype(enum WINDOW_MANAGER manager) */
2577 if(params
->pos
>=2) {
2578 for(i
=0;WINDOW_MANAGER
[i
];++i
)
2579 if(strncmp(WINDOW_MANAGER
[i
],params
->content
[1],
2580 strlen(params
->content
[1]))==0)
2582 if (adesklets_window_reset((WINDOW_MANAGER
[i
])?i
:
2583 atoi(params
->content
[1]))) {
2584 if (adesklets_menus_reset()) {
2585 if (!adesklets_images_reset_background(0))
2586 command_error("could not reset background images\n");
2588 command_error("could not reset menus\n");
2590 command_error("could not reset main window\n");
2592 command_error("Window manager status not given\n");
2594 case CMD_WINDOW_SHOW
:
2595 /* prototype(void) */
2596 #ifndef X_DISPLAY_MISSING
2597 if (adesklets
.display
&& adesklets
.window
) {
2598 if (!XMapWindow(adesklets
.display
,adesklets
.window
))
2599 command_error("could not map the window\n");
2602 command_error("X connection or window missing\n");
2604 case CMD_WINDOW_HIDE
:
2605 /* prototype(void) */
2606 #ifndef X_DISPLAY_MISSING
2607 if (adesklets
.display
&& adesklets
.window
) {
2608 if(!XUnmapWindow(adesklets
.display
,adesklets
.window
))
2609 command_error("could not unmap the window\n");
2612 command_error("X connection or window missing\n");
2614 case CMD_WINDOW_RESIZE
:
2615 /* prototype(int width, int height) */
2616 if (params
->pos
>=3) {
2617 if((i
=atoi(params
->content
[1]))>0 &&
2618 (j
=atoi(params
->content
[2]))>0) {
2619 #ifndef X_DISPLAY_MISSING
2620 if (adesklets
.display
&& adesklets
.window
) {
2621 if (!xwindow_resize_window(adesklets
.display
,adesklets
.window
,
2622 adesklets
.params
,i
,j
,0))
2623 command_error("did not resize window\n");
2626 if (!adesklets_images_reset_background(1,i
,j
))
2627 command_error("no window, and could not resize images\n");
2628 #ifndef X_DISPLAY_MISSING
2631 } else command_error("resize out of range\n");
2632 } else command_error("resize dimensions no given\n");
2634 case CMD_WINDOW_GET_TRANSPARENCY
:
2635 /* prototype(void) */
2636 command_ok("window transparency %d\n",adesklets
.transparency
);
2638 case CMD_WINDOW_GET_BACKGROUND_GRAB
:
2639 /* prototype(void) */
2640 if(X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
)
2641 command_ok("window backgroundgrab %d\n",adesklets
.background_grab
);
2644 "background grab irrelevant - no X window connection or window\n");
2646 case CMD_WINDOW_GET_BACKGROUND_IMAGE
:
2647 /* prototype(void) */
2648 if(X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
)
2649 command_ok("background image %d\n",
2650 (adesklets
.user_background_image
!=-1)?
2651 adesklets
.user_background_image
:1);
2654 "background window irrelevant - no X window connection or window\n");
2656 case CMD_WINDOW_GET_MANAGED_STATUS
:
2657 /* prototype(void) */
2658 #ifndef X_DISPLAY_MISSING
2659 if(adesklets
.display
&& adesklets
.window
) {
2660 command_ok("window managedstatus %d (%s)\n",
2662 WINDOW_MANAGER
[adesklets
.managed
]);
2664 command_error("X connection or window missing\n");
2666 command_error("X connection or window missing\n");
2669 case CMD_WINDOW_SET_TRANSPARENCY
:
2670 /* prototype(bool transparency) */
2671 if (params
->pos
>=2) {
2672 i
=atoi((char*)params
->content
[1]);
2673 if (adesklets
.transparency
!=i
) {
2674 adesklets
.transparency
=i
;
2675 /* If there is a chance, invalidate the entire window */
2676 #ifndef X_DISPLAY_MISSING
2677 xwindow_window_size(adesklets
.display
,adesklets
.window
,
2679 updates
= imlib_update_append_rect(updates
,
2680 0,0,(int)width
,(int)height
);
2683 } else command_error("transparency value not given\n");
2685 case CMD_WINDOW_SET_BACKGROUND_GRAB
:
2686 /* prototype(bool grab) */
2687 if (params
->pos
>=2) {
2688 if (adesklets
.background_grab
!=(i
=atoi(params
->content
[1]))) {
2689 if ((adesklets
.background_grab
=i
))
2690 adesklets_images_reset_background(0);
2692 xwindow_context_save(IMLIB_IMAGE
|IMLIB_BLEND
|IMLIB_COLOR
);
2693 imlib_context_set_image(adesklets
.images
->content
[1]);
2694 imlib_context_set_color(0,0,0,255);
2695 imlib_context_set_blend(0);
2696 imlib_image_fill_rectangle(0,0,
2697 imlib_image_get_width(),
2698 imlib_image_get_height());
2699 xwindow_context_restore();
2702 #ifndef X_DISPLAY_MISSING
2703 xwindow_window_size(adesklets
.display
,adesklets
.window
,
2705 updates
= imlib_update_append_rect(updates
,
2706 0,0,(int)width
,(int)height
);
2710 command_error("background grab value not given\n");
2712 case CMD_WINDOW_SET_BACKGROUND_IMAGE
:
2713 /* prototype(int image) */
2714 if (X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
) {
2715 if(params
->pos
>=2) {
2716 if((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.images
->pos
) {
2718 xwindow_context_save(IMLIB_IMAGE
);
2719 imlib_context_set_image(adesklets
.images
->content
[0]);
2720 j
=imlib_image_get_width();
2721 k
=imlib_image_get_height();
2723 imlib_context_set_image(adesklets
.images
->content
[i
]);
2724 x
=imlib_image_get_width();
2725 y
=imlib_image_get_height();
2727 adesklets
.user_background_image
=i
;
2728 updates
= imlib_update_append_rect(updates
,
2732 command_error("incorrect dimensions image\n");
2734 /* Drop silently reset to actual foreground */
2735 adesklets
.user_background_image
=-1;
2736 updates
= imlib_update_append_rect(updates
,
2739 xwindow_context_restore();
2742 "foreground image cannot be selected as background\n");
2744 command_error("image ID %d out of range\n",i
);
2746 command_error("background image ID not given\n");
2749 "background window irrelevant - no X window connection or window\n");
2751 case CMD_SCREEN_GET_WIDTH
:
2752 /* prototype(void) */
2753 #ifndef X_DISPLAY_MISSING
2754 if (adesklets
.display
) {
2755 command_ok("screen width %d\n",
2756 WidthOfScreen(ScreenOfDisplay(adesklets
.display
,
2757 adesklets
.params
->scr
)));
2759 command_error("X connection missing\n");
2761 command_error("X connection missing\n");
2764 case CMD_SCREEN_GET_HEIGHT
:
2765 /* prototype(void) */
2766 #ifndef X_DISPLAY_MISSING
2767 if(adesklets
.display
) {
2768 command_ok("screen height %d\n",
2769 HeightOfScreen(ScreenOfDisplay(adesklets
.display
,
2770 adesklets
.params
->scr
)));
2772 command_error("X connection missing\n");
2774 command_error("X connection missing\n");
2777 case CMD_SCREEN_GET_DEPTH
:
2778 /* prototype(void) */
2779 if(adesklets
.display
)
2780 command_ok("screen depth %d\n",adesklets
.depth
);
2782 command_error("X connection missing\n");
2784 case CMD_GET_CHARSET
:
2785 /* prototype(void) */
2787 if (command
.from_page
)
2788 command_ok("charset %s\n",command
.from_page
);
2791 command_ok("charset -1 (unset)\n");
2793 case CMD_SET_CHARSET
:
2794 /* prototype(const char * charset) */
2796 if (params
->pos
>=2) {
2797 if ((cd
=iconv_open("UTF8",params
->content
[1]))!=(iconv_t
)(-1)) {
2799 iconv_close(command
.cd
);
2802 if (command
.from_page
) {
2803 free(command
.from_page
);
2804 command
.from_page
=NULL
;
2806 command
.from_page
=dupstr(params
->content
[1]);
2809 command_error("could not establish conversion from '%s' to 'UTF8'\n",
2810 params
->content
[1]);
2813 iconv_close(command
.cd
);
2816 if (command
.from_page
) {
2817 free(command
.from_page
);
2818 command
.from_page
=NULL
;
2820 command_ok("charset -1 (unset)\n");
2823 command_error("charset conversion not compiled in\n");
2826 case CMD_CHARSET_STATUS
:
2827 /* prototype(void) */
2829 command_ok("charset_status 1\n");
2831 command_ok("charset_status 0 (charset conversion not compiled in)\n");
2835 /* prototype(void) */
2836 #ifndef X_DISPLAY_MISSING
2837 command_ok("x_status %d (%s%s')\n",(adesklets
.display
)?1:0,
2838 (adesklets
.display
)?"connected to '":"disconnected from '",
2839 XDisplayName(NULL
));
2841 command_ok("x_status 0 (X Window support not compiled in)\n");
2845 /* prototype(void) */
2846 command_ok("quitting...\n");
2847 adesklets
.quit_flag
=1;
2850 if(blank_line(command
.line
))
2851 command
.message_out
=1;
2853 command_error("syntax error\n");
2854 } /* switch(command_type) */
2855 } /* if command.recording */
2856 if (!command
.message_out
) command_ok("%s\n",command
.line
);
2857 vector_free(params
);
2859 command
.ready
=0; ++command
.rank
;
2860 if (command
.interactive
&& !command
.replay_pos
&&
2861 !adesklets
.quit_flag
&& !adesklets
.restart_flag
)
2862 command_interpreter_reset();
2863 } else {printf("\n"); adesklets
.quit_flag
=1;} /* if (command.line) */
2864 } /* if(command.ready) */
2866 #ifndef X_DISPLAY_MISSING
2867 while(adesklets
.display
&& adesklets
.window
&&
2868 (XCheckWindowEvent(adesklets
.display
,
2869 DefaultRootWindow(adesklets
.display
),
2870 PropertyChangeMask
, &ev
) ||
2871 XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
2872 adesklets
.event_mask
,&ev
) ||
2873 XCheckTypedWindowEvent(adesklets
.display
,adesklets
.window
,
2874 ClientMessage
,&ev
))) {
2877 /* Refresh updates list */
2878 updates
= imlib_update_append_rect(updates
,
2879 ev
.xexpose
.x
,ev
.xexpose
.y
,
2880 ev
.xexpose
.width
,ev
.xexpose
.height
);
2882 case PropertyNotify
:
2883 /* This event is generated from root window only:
2884 we use it to check for dynamic root window background change,
2885 as enlightment has used it for years. Look at
2886 xwindow_updated_background() for details */
2887 if (ev
.xproperty
.atom
!= None
&&
2888 ev
.xproperty
.atom
== XInternAtom (adesklets
.display
,
2889 "_XROOTPMAP_ID", True
) &&
2890 adesklets
.background_grab
&&
2891 xwindow_updated_background(adesklets
.display
,
2892 ev
.xproperty
.window
,
2894 /* Recompute the background images */
2895 adesklets_images_reset_background(0);
2897 /* Because the setting of background_pixmap as ParentRelative
2898 on the main window, there is no need to invalidate
2899 it here: an Expose event will be automatically generated. */
2902 /* Fire default menu on left button click */
2903 if(ev
.xbutton
.button
==3) {
2904 #ifdef CONTROL_ON_CONTEXT_MENU
2905 if (ev
.xbutton
.state
& ControlMask
) {
2907 if ((adesklets_menu_fire(0,&menu_str
)) &&
2908 (adesklets
.user_event_mask
&MenuFireMask
))
2909 event("menufire 0 %s\n",menu_str
);
2910 #ifdef CONTROL_ON_CONTEXT_MENU
2912 ev
.xbutton
.window
= adesklets
.root
;
2913 XSendEvent(adesklets
.display
, ev
.xbutton
.window
,
2914 False
, ButtonPressMask
, &ev
);
2915 debug("menu call redirected to root\n");
2919 if(adesklets
.user_event_mask
&ButtonPressMask
)
2920 event("buttonpress %d %d %d\n",
2921 ev
.xbutton
.x
,ev
.xbutton
.y
,ev
.xbutton
.button
);
2924 if(ev
.xbutton
.button
!=3)
2925 event("buttonrelease %d %d %d\n",
2926 ev
.xbutton
.x
,ev
.xbutton
.y
,ev
.xbutton
.button
);
2929 event("motionnotify %d %d\n",
2930 ev
.xmotion
.x
, ev
.xmotion
.y
);
2933 event("enternotify %d %d\n",
2934 ev
.xcrossing
.x
, ev
.xcrossing
.y
);
2937 event("leavenotify %d %d\n",
2938 ev
.xcrossing
.x
, ev
.xcrossing
.y
);
2940 case ConfigureNotify
:
2941 if (ev
.xconfigure
.window
==adesklets
.window
)
2942 if (xwindow_window_moved_or_resized(ev
.xconfigure
.x
,
2944 ev
.xconfigure
.width
,
2945 ev
.xconfigure
.height
))
2946 adesklets_images_reset_background(0);
2949 /* Check for the "WM_WINDOW_DELETE" protocol */
2950 if (ev
.xclient
.data
.l
[0] == XInternAtom(adesklets
.display
,
2953 debug("Message from window manager: quitting!\n");
2954 adesklets
.user_quit_flag
=adesklets
.quit_flag
=1;
2956 debug("Unknown client message sent.\n");
2959 /* Untreated cases */
2964 /* Now, performs main window updates as needed */
2965 xwindow_update_window(adesklets
.window
, &updates
,
2966 adesklets
.images
->content
[
2967 (adesklets
.user_background_image
!=-1)?
2968 adesklets
.user_background_image
:1],
2969 adesklets
.images
->content
[0],
2970 adesklets
.transparency
);
2972 if(updates
) imlib_updates_free(updates
);
2974 } while(!adesklets
.quit_flag
&& !adesklets
.restart_flag
&&
2975 (command_replayer() || command_interpreter()));
2978 /*----------------------------------------------------------------------------*/
2979 int adesklets_free(void)
2984 debug("---------------------------------------------------------------\n");
2985 /* Ultimate update : take care of potential applet removal
2986 if user asked for it. */
2987 adesklets
.params
->no_update
|=adesklets
.user_quit_flag
;
2988 cfgfile_update(adesklets
.params
);
2990 /* X Windows cleanup */
2991 #ifndef X_DISPLAY_MISSING
2992 if(adesklets
.display
) {
2993 if(adesklets
.window
) {
2994 XUnmapWindow(adesklets
.display
,adesklets
.window
);
2995 XDestroyWindow(adesklets
.display
,adesklets
.window
);
2997 XCloseDisplay(adesklets
.display
);
3001 /* For terminal reset, if it was not cleanly performed
3002 (will happen when quitting from the default left click
3003 menu, for instance) */
3004 rl_callback_handler_remove();
3006 /* Send SIGTERM notification signal to parent process:
3007 in all case but restart, adesklets do not
3008 go further to ensure parent termination. */
3009 kill(adesklets
.ppid
,SIGTERM
);
3011 /* if Lock exist: handle possible restart */
3012 if(adesklets
.lock
) {
3013 if(adesklets
.restart_flag
) {
3014 /* Wait for adesklets parent process to exit
3015 SIGKILL_TIMEOUT seconds, then send a SIGKILL. */
3016 for(i
=0;i
<SIGKILL_TIMEOUT
&& adesklets
.ppid
==getppid();++i
)
3018 if (i
==SIGKILL_TIMEOUT
) kill(adesklets
.ppid
,SIGKILL
);
3019 while(adesklets
.ppid
==getppid()) sleep(1);
3021 /* Redirect stdout and stderr to /dev/null to avoid
3022 output buffer overflow */
3023 if ((fd_null
=open("/dev/null",O_WRONLY
))>=0) {
3028 execl(adesklets
.params
->applet
,
3029 adesklets
.params
->applet
,
3031 /* debug("Restart: could not exec `%s'",adesklets.params->applet); */
3036 /* Release the lock */
3037 lock
.l_type
=F_UNLCK
;
3038 lock
.l_whence
=SEEK_SET
;
3041 fcntl(fileno(adesklets
.lock
),F_SETLK
,&lock
);
3042 fclose(adesklets
.lock
);
3044 /* Try to unlink the lock file:
3045 thanks to POSIX, this will fail gracefully
3046 if a process is still using the file */
3047 unlink(adesklets
.lock_filename
);
3050 /* Free structures */
3051 if(events
) vector_free(events
);
3052 adesklets
.menus
=vector_free(adesklets
.menus
);
3053 adesklets
.images
=vector_free(adesklets
.images
);
3054 adesklets
.fonts
=vector_free(adesklets
.fonts
);
3055 adesklets
.color_ranges
=vector_free(adesklets
.color_ranges
);
3056 adesklets
.color_modifiers
=vector_free(adesklets
.color_modifiers
);
3057 adesklets
.filters
=vector_free(adesklets
.filters
);
3058 adesklets
.polygons
=vector_free(adesklets
.polygons
);
3059 adesklets
.variables
=vector_free(adesklets
.variables
);
3061 return !adesklets
.menus
&&
3062 !adesklets
.images
&&
3064 !adesklets
.color_ranges
&&
3065 !adesklets
.color_modifiers
&&
3066 !adesklets
.filters
&&
3067 !adesklets
.polygons
&&
3068 !adesklets
.variables
;
3071 /*----------------------------------------------------------------------------*/
3072 /* Signal wrapper for adesklets_free()
3075 termination_handler(int signum
)
3077 exit((adesklets_free())?EXIT_SUCCESS
:EXIT_FAILURE
);
3080 /*----------------------------------------------------------------------------*/
3081 /* Since we cannot verify if applet is a script of a binary without trying
3082 to execute it, we require it to have both read and execute permissions for
3083 the current user... Better _portable_ solution is welcomed.
3086 adesklets_valid_desklet(char * applet
, int register_flag
)
3091 if((register_flag
&& applet
[0]=='/') || !register_flag
)
3092 result
=(access(applet
,R_OK
|X_OK
)==0);
3096 /*----------------------------------------------------------------------------*/
3097 /* Our image generator function (have a look at command.c) */
3099 image_generator(const char * text
, int state
)
3101 return generic_index_generator(text
,state
,adesklets
.images
->pos
);
3104 /*----------------------------------------------------------------------------*/
3105 /* Our font name generator function (have a look at command.c) */
3107 base_font_generator(const char * text
, int state
)
3111 static char ** fonts
;
3114 fonts
=imlib_list_fonts(&number
);
3116 if(!(result
=generic_generator(text
,state
,fonts
,number
))) {
3117 imlib_free_font_list(fonts
,number
);
3122 /*----------------------------------------------------------------------------*/
3124 base_font_path_generator(const char * text
, int state
)
3127 static char ** font_path
;
3130 font_path
=imlib_list_font_path(&number
);
3132 return generic_generator(text
,state
,font_path
,number
);
3135 /*----------------------------------------------------------------------------*/
3137 font_generator (const char * text
, int state
)
3139 return generic_index_generator(text
,state
,adesklets
.fonts
->pos
);
3142 /*----------------------------------------------------------------------------*/
3144 font_generator_with_null (const char * text
, int state
)
3146 return generic_index_generator_with_null(text
,state
,adesklets
.fonts
->pos
);
3149 /*----------------------------------------------------------------------------*/
3150 /* Our menu generator function (have a look at command.c) */
3152 menu_generator(const char * text
, int state
)
3154 return generic_index_generator(text
,state
,adesklets
.menus
->pos
);
3157 /*----------------------------------------------------------------------------*/
3158 /* Our color ranges generator function (have a look at command.c) */
3160 color_range_generator(const char * text
, int state
)
3162 return generic_index_generator(text
,state
,adesklets
.color_ranges
->pos
);
3165 /*----------------------------------------------------------------------------*/
3166 /* Our color ranges generator function (have a look at command.c) */
3168 color_range_generator_with_null(const char * text
, int state
)
3170 return generic_index_generator_with_null(text
,state
,
3171 adesklets
.color_ranges
->pos
);
3174 /*----------------------------------------------------------------------------*/
3175 /* Our color modifiers generator function (have a look at command.c) */
3177 color_modifier_generator(const char * text
, int state
)
3179 return generic_index_generator(text
,state
,adesklets
.color_modifiers
->pos
);
3182 /*----------------------------------------------------------------------------*/
3183 /* Our color modifiers generator function (have a look at command.c) */
3185 color_modifier_generator_with_null(const char * text
, int state
)
3187 return generic_index_generator_with_null(text
,state
,
3188 adesklets
.color_modifiers
->pos
);
3191 /*----------------------------------------------------------------------------*/
3192 /* Our filters generator function (have a look at command.c) */
3194 filter_generator(const char * text
, int state
)
3196 return generic_index_generator(text
,state
,adesklets
.filters
->pos
);
3199 /*----------------------------------------------------------------------------*/
3200 /* Our filters generator function (have a look at command.c) */
3202 filter_generator_with_null(const char * text
, int state
)
3204 return generic_index_generator_with_null(text
,state
,
3205 adesklets
.filters
->pos
);
3208 /*----------------------------------------------------------------------------*/
3209 /* Our polygon generator function (have a look at command.c) */
3211 polygon_generator(const char * text
, int state
)
3213 return generic_index_generator(text
,state
,adesklets
.polygons
->pos
);
3216 /*----------------------------------------------------------------------------*/
3217 /* We have to put this generator here because variables vector is part of
3218 the adesklets structure */
3220 variable_generator(const char * text
, int state
)
3222 static int list_index
, len
;
3230 while (list_index
<adesklets
.variables
->pos
) {
3231 name
=((var_item
*)adesklets
.variables
->content
[list_index
])->name
;
3233 if(strncmp(name
,text
,len
)==0)
3234 return dupstr(name
);
3240 /*----------------------------------------------------------------------------*/
3242 /* Generic generator mecanism: used for different wrappers.*/
3244 char * generic_generator(const char * text, int state,
3245 char ** names, int number)
3247 static int list_index, len;
3255 while((number==-1 || list_index<number) &&
3256 (name=names[list_index])) {
3258 if(strncmp(name,text,len)==0)
3259 return(dupstr(name));