1 /*--- adesklets.c --------------------------------------------------------------
2 Copyright (C) 2004, 2005 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
);
308 XCreateWindow(adesklets
.display
,
310 adesklets
.params
->x
, adesklets
.params
->y
,
312 DefaultDepth(adesklets
.display
,
313 adesklets
.params
->scr
),
316 (managed
)?valuemask
:(valuemask
|CWOverrideRedirect
),
317 &XDefaultWindowAttributes
);
319 if (xwindow_error_check()) {
320 /* Set this window size */
321 xwindow_resize_window(adesklets
.display
,adesklets
.window
,
322 adesklets
.params
,width
,height
,1);
323 /* Set this window event mask */
324 XSelectInput(adesklets
.display
,adesklets
.window
,adesklets
.event_mask
);
326 /* Set this window as imlib2's default drawable */
327 imlib_context_set_drawable(adesklets
.window
);
329 /* Set window stacking order, and various properties if applicable */
331 XRaiseWindow(adesklets
.display
,adesklets
.window
);
333 if (XmbTextListToTextProperty(adesklets
.display
,
336 &text_prop_name
)==Success
)
337 XSetWMName(adesklets
.display
, adesklets
.window
, &text_prop_name
);
339 /* Window delete protocol registration */
340 if ((atom
=XInternAtom(adesklets
.display
,
341 "WM_DELETE_WINDOW",False
))!=None
)
342 XSetWMProtocols(adesklets
.display
,
343 adesklets
.window
, &atom
, 1);
346 XLowerWindow(adesklets
.display
,adesklets
.window
);
348 /* Map the window if needed */
349 if (mapped
) XMapWindow(adesklets
.display
,adesklets
.window
);
351 /* Eventually add capture of PropertyNotify on root window:
352 used for dynamic background reinitialisation */
353 XSelectInput(adesklets
.display
,
355 ((adesklets
.background_grab
)?PropertyChangeMask
:0));
357 /* Store new value */
358 adesklets
.managed
= managed
;
362 adesklets
.window
=(Window
)0;
364 adesklets
.window
=(Window
)0;
369 /*----------------------------------------------------------------------------*/
370 /* Reste to nothing the vector of fonts, color_ranges and color_modifiers.
371 Returns 1 if successful, 0 otherwise.
373 #define ADESKLETS_RESET_FUNCTION(name)\
375 adesklets_ ## name ## s_reset(void)\
378 if(adesklets.name ## s)\
379 adesklets.name ## s=vector_free(adesklets.name ## s);\
380 if(!adesklets.name ## s) {\
381 if((adesklets.name ## s=vector_init())) {\
382 adesklets.name## s->vector_free_item=\
383 name ## _vector_free_item;\
384 imlib_context_set_ ## name(NULL);\
391 ADESKLETS_RESET_FUNCTION(font
)
392 ADESKLETS_RESET_FUNCTION(color_range
)
393 ADESKLETS_RESET_FUNCTION(color_modifier
)
394 ADESKLETS_RESET_FUNCTION(filter
)
395 #undef ADESKLETS_RESET_FUNCTION
397 /*----------------------------------------------------------------------------*/
398 /* Reset to nothing a generic vector of something; you need
399 to provide a reference to the vector and another to a
400 vector_free_item_func function
403 adesklets_generic_reset(vector
** vec
, vector_free_item_func func
)
407 *vec
=vector_free(*vec
);
409 if((*vec
=vector_init())) {
410 (*vec
)->vector_free_item
=func
;
417 /*----------------------------------------------------------------------------*/
418 /* Generate placeholder function using preceeding generic function
420 #define ADESKLETS_RESET_FUNCTION(name) \
422 adesklets_ ## name ## s_reset(void) \
424 return adesklets_generic_reset(&adesklets.name ## s,\
425 name ## _vector_free_item);\
428 ADESKLETS_RESET_FUNCTION(polygon
)
429 ADESKLETS_RESET_FUNCTION(variable
)
430 #undef ADESKLETS_RESET_FUNCTION
432 /*----------------------------------------------------------------------------*/
433 /* Wrapper for xmenu_fire() that intercepts non-maskable events
434 from default menu ("Move", "Restart" and "Quit" events)
437 adesklets_menu_fire(int index
, char ** return_str
)
439 #ifndef X_DISPLAY_MISSING
441 if(index
>=0 && index
<adesklets
.menus
->pos
) {
442 *return_str
=xmenu_fire(adesklets
.display
,adesklets
.params
->scr
,
444 adesklets
.images
->content
[
445 (adesklets
.user_background_image
==-1)?
446 1:adesklets
.user_background_image
],
447 adesklets
.images
->content
[0],
448 adesklets
.transparency
,
450 /* Intercept default actions move and quit on the way back */
451 if(index
==0 && *return_str
) {
452 /* For move: verify the main window is not managed,
453 to avoid false move due to user-added "Move" */
455 #ifndef X_DISPLAY_MISSING
456 !adesklets
.managed
&&
458 strcmp(*return_str
,"Move")==0) {
459 if(xwindow_move_window(adesklets
.display
,
460 adesklets
.root
, adesklets
.window
,
462 XMapWindow(adesklets
.display
,adesklets
.window
);
463 if(!adesklets
.params
->no_update
)
464 cfgfile_update(adesklets
.params
);
468 /* For restart: verify there is a lock file open,
469 to avoid false restart due to user-added "Restart"
470 item in default menu */
471 if(adesklets
.lock
&& strcmp(*return_str
,"Restart")==0) {
473 adesklets
.restart_flag
=1;
476 if(strcmp(*return_str
,"Quit")==0) {
477 adesklets
.user_quit_flag
=adesklets
.quit_flag
=1;
492 /*----------------------------------------------------------------------------*/
493 /* Return 1 if current image is potentially shown on screen, 0 otherwise.
494 Mainly used to determine needs for screen updates */
499 image
= imlib_context_get_image();
501 return (image
==adesklets
.images
->content
[0]) ||
502 (adesklets
.transparency
&&
503 ((adesklets
.user_background_image
!=-1 &&
504 image
==adesklets
.images
->content
[adesklets
.user_background_image
]) ||
505 (image
==adesklets
.images
->content
[1])));
508 /*----------------------------------------------------------------------------*/
509 void usage(const char * name
)
511 printf("Usage: %s [OPTIONS] [script_id]\n", name
);
512 printf("adesklets interpreter and desklets launcher\n\
515 -h, --help Display this help message\n\
516 -v, --version Get package version\n\
517 -f, --file In interpreter mode, use file as\n\
518 input stream instead of stdin\n\n");
521 /*----------------------------------------------------------------------------*/
523 adesklets_init(int argc
, char ** argv
)
527 char str
[CFGFILE_NAME_SIZE
];
530 struct sigaction new_action
, old_action
;
532 const char * OPTIONS
[] = {"-h", "--help", "-f", "--file", "-v", "--version" };
534 /* Seek --help string: otherwise, it is either a script name of junk */
536 if(strncmp(argv
[1],OPTIONS
[0],strlen(OPTIONS
[0]))==0 ||
537 strncmp(argv
[1],OPTIONS
[1],strlen(OPTIONS
[1]))==0) {
541 if (strncmp(argv
[1],OPTIONS
[4],strlen(OPTIONS
[4]))==0 ||
542 strncmp(argv
[1],OPTIONS
[5],strlen(OPTIONS
[5]))==0) {
543 printf("%s %s\n",PACKAGE
,VERSION
);
546 if (strncmp(argv
[1],OPTIONS
[2],strlen(OPTIONS
[2]))==0 ||
547 strncmp(argv
[1],OPTIONS
[3],strlen(OPTIONS
[3]))==0) {
549 if (!((file
=fopen(argv
[2],"r"))&&
550 dup2(fileno(file
),fileno(stdin
))>=0)) {
552 fprintf(stderr
,"Could not open file '%s' for reading\n",
566 /* Get original parent process id */
567 adesklets
.ppid
=getppid();
569 /* Get desklet ID from environment */
570 adesklets_id
= getenv("ADESKLETS_ID");
572 /* Set stdout and stderr to be unbuffered: this is needed
573 for proper pipe operation. stderr is always
575 if (setvbuf(stdout
,NULL
,_IONBF
,0)!=0) {
576 fprintf(stderr
,"Could not remove stdout buffer\n");
579 if (setvbuf(stderr
,NULL
,_IONBF
,0)!=0) {
580 fprintf(stderr
,"Could not remove stderr buffer\n");
584 /* Determine if interactive use */
585 command
.interactive
=isatty(fileno(stdin
));
587 /* Retrieve all parameters from config file */
588 adesklets
.params
= cfgfile_getinfo((!command
.interactive
)?argv
[pos
]:NULL
,
589 ((uint
)(adesklets_id
)?
590 atoi(adesklets_id
):-1));
592 /* Make sure ADESKLETS_ID is set in current environment */
594 if (sprintf(str
,"%u",adesklets
.params
->id
)>0)
595 setenv("ADESKLETS_ID",str
,1);
597 /* If interactive use, print welcome message */
598 if(command
.interactive
) {
600 printf("Press TAB for hints.\n");
601 /* But if not, build and acquire lock file name */
602 } else if (adesklets_valid_desklet(argv
[pos
],0)) {
603 strncpy(str
,argv
[1],CFGFILE_NAME_SIZE
-1);
604 str
[CFGFILE_NAME_SIZE
-1]=0;
605 if (snprintf(adesklets
.lock_filename
,CFGFILE_NAME_SIZE
-1,
606 "%s/%s_uid%u_%s_%u.lock",
610 (char*)basename(str
),
611 adesklets
.params
->id
)<CFGFILE_NAME_SIZE
)
612 adesklets
.lock_filename
[CFGFILE_NAME_SIZE
-1]=0;
613 /* Now, lock the file: this will wait forever */
614 if ((adesklets
.lock
=fdopen(open(adesklets
.lock_filename
,
615 O_CREAT
|O_TRUNC
|O_WRONLY
,
619 lock
.l_whence
=SEEK_SET
;
622 debug("Lock file: acquiring %s\n",adesklets
.lock_filename
);
624 TRY(fcntl(fileno(adesklets
.lock
),F_SETLKW
,&lock
));
626 /* Write PPID and PID to lock file */
627 fprintf(adesklets
.lock
,"%d %d\n",adesklets
.ppid
,getpid());
628 fflush(adesklets
.lock
);
630 debug("Lock file: could not get lock\n");
631 fclose(adesklets
.lock
);
637 /* Force config file entry removal (or, at least, no registration)
638 at next update if invalid */
639 adesklets
.params
->no_update
=!
640 adesklets_valid_desklet(adesklets
.params
->applet
,1);
642 #ifndef X_DISPLAY_MISSING
643 /* Perform X Windows initialisation */
644 if ((adesklets
.display
=XOpenDisplay(NULL
))) {
645 /* Correct screen determination */
646 adesklets
.params
->scr
=(adesklets
.params
->scr
>=0 &&
647 adesklets
.params
->scr
<
648 ScreenCount(adesklets
.display
))?
649 adesklets
.params
->scr
:
650 DefaultScreen(adesklets
.display
);
652 /* X related imlib2 settings */
653 adesklets
.visual
=imlib_get_best_visual(adesklets
.display
,
654 adesklets
.params
->scr
,
656 imlib_context_set_display(adesklets
.display
);
657 imlib_context_set_visual(adesklets
.visual
);
658 imlib_context_set_colormap(DefaultColormap(adesklets
.display
,
659 adesklets
.params
->scr
));
661 /* Create main desklet window: managed if interactive,
663 adesklets_window_reset(command
.interactive
);
664 /* Install custom error handler */
665 XSetErrorHandler(xwindow_non_fatal_error_handler
);
669 debug("Could not connect to X server '%s'\n",XDisplayName(NULL
));
673 /* Locate true type fonts system-wide */
674 xwindow_locate_truetype_fonts();
676 /* Various Others imlib2 settings */
677 imlib_set_cache_size(2048*1024);
678 imlib_set_font_cache_size(512*1024);
679 imlib_set_color_usage(128);
680 imlib_context_set_dither(1);
681 imlib_context_set_blend(1);
682 imlib_context_set_color(255,255,255,255);
684 /* Set events in proper echo mode: no echo if interactive, echo otherwise. */
685 events_echo
=!command
.interactive
;
687 /* Initial settings */
688 if (adesklets_menus_reset()) {
689 if (adesklets_images_reset()) {
690 if (adesklets_fonts_reset()) {
691 if (adesklets_color_ranges_reset()) {
692 if (adesklets_color_modifiers_reset()) {
693 if (adesklets_filters_reset()) {
694 if (adesklets_polygons_reset()) {
695 if (adesklets_variables_reset()) {
696 /* Setup command interpreter */
697 if(command_interpreter_reset()) {
698 #ifdef FORCE_EXTENDED_CHARACTERS_INPUT
699 rl_variable_bind("input-meta", "on");
700 rl_variable_bind("convert-meta", "off");
701 rl_variable_bind("output-meta", "on");
703 /* Finally, set up event handler. This code snipset
704 was copied verbatim from the GNU C Library
705 Reference Manual (sigaction Function
707 new_action
.sa_handler
= termination_handler
;
708 sigemptyset (&new_action
.sa_mask
);
709 new_action
.sa_flags
= 0;
710 sigaction (SIGINT
, NULL
, &old_action
);
711 if (old_action
.sa_handler
!= SIG_IGN
)
712 sigaction (SIGINT
, &new_action
, NULL
);
713 sigaction (SIGHUP
, NULL
, &old_action
);
714 if (old_action
.sa_handler
!= SIG_IGN
)
715 sigaction (SIGHUP
, &new_action
, NULL
);
716 sigaction (SIGTERM
, NULL
, &old_action
);
717 if (old_action
.sa_handler
!= SIG_IGN
)
718 sigaction (SIGTERM
, &new_action
, NULL
);
719 /* If applicable, make an initial setup of
720 config file, just in case */
721 if (X_DISPLAY_SUPPORT
&&
722 adesklets
.display
&& adesklets
.window
)
723 cfgfile_update(adesklets
.params
);
727 fprintf(stderr
, "Cannot initialize command interpreter\n");
729 fprintf(stderr
, "Cannot initialize variables\n");
731 fprintf(stderr
, "Cannot initialize imlib polygons\n");
733 fprintf(stderr
, "Cannot initialize imlib filters\n");
735 fprintf(stderr
, "Cannot initialize imlib color modifiers\n");
737 fprintf(stderr
, "Cannot initialize imlib color ranges\n");
739 fprintf(stderr
, "Cannot initialize imlib fonts\n");
741 fprintf(stderr
, "Cannot initialize imlib images\n");
743 fprintf(stderr
, "Cannot initialize menus\n");
748 /*----------------------------------------------------------------------------*/
750 adesklets_events_loop(void)
757 #ifndef X_DISPLAY_MISSING
761 struct timespec sleep_time
;
762 command_enum command_type
;
764 #ifndef X_DISPLAY_MISSING
767 #ifdef HAVE_READLINE_HISTORY_H
768 HIST_ENTRY
** history
;
774 Imlib_Updates updates
;
778 Imlib_Color_Range color_range
;
779 Imlib_Color_Modifier color_modifier
;
781 ImlibPolygon polygon
;
782 Imlib_Load_Error error
;
786 debug("---------------------------------------------------------------\n");
788 updates
= imlib_updates_init();
791 command
.message_out
=0;
792 variable_expansion(adesklets
.variables
,&command
.line
);
793 params
=command_splitter(command
.line
,&command_type
);
795 if (!command
.recording
||
796 command_type
==CMD_PLAY
||
797 command_type
==CMD_START_RECORDING
||
798 command_type
==CMD_STOP_RECORDING
) {
799 switch(command_type
) {
801 /* NOTE : for semi-automated generation of an adesklets'
802 API for scripting languages, you should include
803 a prototype declaration similar to this one
804 in a comment (multi-lines comments allowed)
805 directly below case declaration. Look at protoize.sh
806 for further details. Commands that are also
807 Imlib2 primitives do not need to have prototypes
810 prototype(double gate) */
811 if (command
.replay_pos
) {
812 if (params
->pos
>=2) {
813 angle
=atof(params
->content
[1]);
814 #ifndef X_DISPLAY_MISSING
815 if (command
.replay_abort_on_events
) {
816 sleep_time
.tv_sec
=0; sleep_time
.tv_nsec
=X_POLLING_PERIOD
/10;
817 while (angle
>command_gate_chronometer())
818 if (adesklets
.display
&& adesklets
.window
&&
819 (XCheckWindowEvent(adesklets
.display
,
821 PropertyChangeMask
, &ev
) ||
822 XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
823 adesklets
.event_mask
,&ev
) ||
824 XCheckTypedWindowEvent(adesklets
.display
,adesklets
.window
,
825 ClientMessage
,&ev
))) {
826 XPutBackEvent(adesklets
.display
,&ev
);
829 nanosleep(&sleep_time
,NULL
);
832 if ((angle
-=command_gate_chronometer())>0) {
833 sleep_time
.tv_sec
=(time_t)angle
;
834 sleep_time
.tv_nsec
=(long)((angle
-floor(angle
))*1E9
);
836 debug("Sleep time: %f, or %d %d\n",
837 angle,sleep_time.tv_sec,sleep_time.tv_nsec);
839 nanosleep(&sleep_time
,NULL
);
841 #ifndef X_DISPLAY_MISSING
845 command_error("time gate not given\n");
847 command_error("ignoring timer gate, interpreter not replaying\n");
850 /* prototype([const char * command]) */
854 strcmp(params
->content
[1],COMMANDS
[i
].name
);
856 if (COMMANDS
[i
].name
)
857 command_ok("%s - %s\n",COMMANDS
[i
].name
, COMMANDS
[i
].doc
);
859 command_error("no help on '%s'\n", (char*)params
->content
[1]);
861 for(i
=0;COMMANDS
[i
].name
;++i
)
862 command_printf("%-25s -\t%s\n",COMMANDS
[i
].name
, COMMANDS
[i
].doc
);
866 /* prototype(void) */
867 command_ok("pong!\n");
870 /* prototype([int delay]) */
872 (((i
=atoi(params
->content
[1]))>0)?i
:5):5;
873 debug("Pausing for %d seconds.\n",i
);
877 /* prototype(void) */
878 command_ok("%s %s\n",PACKAGE
,VERSION
);
881 /* prototype(void) */
882 command_ok("adesklets id %u\n", adesklets
.params
->id
);
885 /* prototype([const char * filename]) */
886 #ifdef HAVE_READLINE_HISTORY_H
887 if ((history
=history_list())) {
888 for(i
=0;history
[i
];++i
);
889 command_printf("%d commands in history\n",i
);
890 if((file
=(params
->pos
>=2)?
891 fopen(command_subsplitter(command
.line
,1),"w"):stdout
)) {
892 for(i
=0;history
[i
];++i
)
893 if (params
->pos
>=2 || !command
.interactive
)
894 fprintf(file
,"%s\n",history
[i
]->line
);
896 fprintf(file
,"%d\t%s\n",i
,history
[i
]->line
);
897 if(file
!=stdout
) fclose(file
);
899 command_error("could not open output file for writing\n");
901 command_error("could not retrieve history list\n");
903 command_error("history support not compiled in\n");
907 /* prototype([const * char name, const * char value]) */
908 if ((i
=params
->pos
)>1) {
909 /* Verify variable name does not include a dollar character */
911 ((char*)params
->content
[1])[j
] &&
912 ((char*)params
->content
[1])[j
]!='$';
914 if (j
==strlen((char*)params
->content
[1])) {
915 /* First, search for existing variable */
917 vector_find(adesklets
.variables
,(uint
*)&j
,
918 variable_search_func
,(void*)params
->content
[1]);
920 /* Then, if it exists, just delete it */
922 vector_delete(adesklets
.variables
,(uint
)j
);
925 command_error("variable '%s' does not exist\n",
929 /* Then, set it back if there is a new content */
930 vector_push(adesklets
.variables
,
931 (void*)variable_create(
932 (char*)params
->content
[1],
933 (char*)command_subsplitter(command
.line
,2)));
936 command_error("variable name contains '$'\n");
938 /* Print out all variables */
939 command_printf("%d variable(s)\n", adesklets
.variables
->pos
);
940 for (i
=0;i
<adesklets
.variables
->pos
;++i
)
941 command_printf("%s=%s\n",
942 ((var_item
*)adesklets
.variables
->content
[i
])->name
,
943 ((var_item
*)adesklets
.variables
->content
[i
])->value
);
947 /* prototype(void) */
948 adesklets_variables_reset();
951 /* prototype(const char * string) */
953 case CMD_START_RECORDING
:
954 /* prototype(void) */
955 #ifdef HAVE_READLINE_HISTORY_H
956 /* This is a special case: you have to make sure to abort
957 current macro recording if called recursively from direct mode.
959 But this is not enough: you also need to ckeck we are not inside
960 a replay loop (indirect mode) because it would still be possible
961 to insert hidden calls to 'start_recording' inside a macro using
962 textual expansion (text variables) */
963 if (!command
.recording
&& !command
.replay_pos
)
964 command
.recording
=history_size()+1;
966 /* In non interactive mode, purge newly created history
968 if (command
.recording
&& !command
.interactive
)
969 for(i
=history_size()-1;i
>=command
.recording
-1;--i
)
970 free_history_entry(remove_history(i
));
971 command
.recording
=command
.replay_pos
=0;
972 command_error("cannot call this while already recording or \
973 replaying, aborded\n");
976 command_error("compiled without GNU history support\n");
979 case CMD_STOP_RECORDING
:
980 /* prototype(void) */
981 #ifdef HAVE_READLINE_HISTORY_H
982 if (!command
.replay_pos
) {
983 if (command
.recording
) {
986 if(!command
.interactive
)
987 /* In case of non interactive use, remove
988 the reference to the 'stop_record' command */
989 free_history_entry(remove_history(j
));
990 if (command
.recording
!=j
)
991 command_ok("recorded_commands %d %d\n",
995 command_error("no command recorded\n");
997 command_error("no recording taking place right now\n");
999 command_error("cannot call stop while replaying, replay aborded\n");
1000 command
.recording
=0;
1002 command_error("compiled without GNU history support\n");
1005 case CMD_PLAY_GET_ABORT_ON_EVENTS
:
1006 /* prototype(void) */
1007 command_ok("abort_on_event %d\n",command
.replay_abort_on_events
);
1009 case CMD_PLAY_SET_ABORT_ON_EVENTS
:
1010 /* prototype(bool abort) */
1011 if (!command
.replay_pos
) {
1013 command
.replay_abort_on_events
=atoi((char*)params
->content
[1]);
1015 command_error("abort on event value not given\n");
1017 command_error("cannot be called inside a replay\n");
1020 /* prototype(int beginning, int end) */
1021 #ifdef HAVE_READLINE_HISTORY_H
1022 if (!command
.recording
&& !command
.replay_pos
) {
1023 if (params
->pos
>=3) {
1024 if (((i
=atoi(params
->content
[1]))<(j
=history_size())) &&
1025 ((k
=atoi(params
->content
[2]))<j
)) {
1026 if (i
>=0 && k
>=0 && (i
<=k
)) {
1027 gettimeofday(&command
.replay_time
,NULL
);
1028 command
.replay_pos
=i
+1;
1029 command
.replay_stop
=k
;
1032 command_error("invalid limits\n");
1034 command_error("limits out of range\n");
1036 command_error("missing start and stop limits\n");
1038 command
.recording
=command
.replay_pos
=0;
1039 command_error("cannot call this now, aborded\n");
1042 command_error("compiled without GNU history support\n");
1045 case CMD_CONTEXT_GET_DITHER
:
1046 command_ok("context dither %hhu\n",imlib_context_get_dither());
1048 case CMD_CONTEXT_GET_ANTI_ALIAS
:
1049 command_ok("context antialias %hhu\n",imlib_context_get_anti_alias());
1051 case CMD_CONTEXT_GET_BLEND
:
1052 command_ok("context blend %hhu\n",imlib_context_get_blend());
1054 case CMD_CONTEXT_GET_OPERATION
:
1055 i
=imlib_context_get_operation();
1056 command_ok("context operation %d (%s)\n",
1059 case CMD_CONTEXT_GET_CLIPRECT
:
1060 /* prototype(void) */
1061 imlib_context_get_cliprect(&x
,&y
,&i
,&j
);
1062 command_ok("context cliprect %d %d %d %d\n",x
,y
,i
,j
);
1064 case CMD_CONTEXT_GET_IMAGE
:
1065 image
=imlib_context_get_image();
1066 for(i
=0;i
<adesklets
.images
->pos
;++i
)
1067 if(adesklets
.images
->content
[i
]==image
)
1068 command_ok("context image %d\n",i
);
1070 case CMD_CONTEXT_GET_FONT
:
1071 if ((font
=imlib_context_get_font())) {
1072 for(i
=0;i
<adesklets
.fonts
->pos
;++i
)
1073 if(adesklets
.fonts
->content
[i
]==font
)
1074 command_ok("context font %d\n",i
);
1076 command_ok("context font -1 (unset)\n");
1078 case CMD_CONTEXT_GET_COLOR_RANGE
:
1079 if ((color_range
=imlib_context_get_color_range())) {
1080 for(i
=0;i
<adesklets
.color_ranges
->pos
;++i
)
1081 if(adesklets
.color_ranges
->content
[i
]==color_range
)
1082 command_ok("context colorrange %d\n",i
);
1084 command_ok("context colorrange -1 (unset)\n");
1086 case CMD_CONTEXT_GET_COLOR_MODIFIER
:
1087 if ((color_modifier
=imlib_context_get_color_modifier())) {
1088 for(i
=0;i
<adesklets
.color_modifiers
->pos
;++i
)
1089 if(adesklets
.color_modifiers
->content
[i
]==color_modifier
)
1090 command_ok("context colormodifier %d\n",i
);
1092 command_ok("context colormodifier -1 (unset)\n");
1094 case CMD_CONTEXT_GET_FILTER
:
1095 if ((filter
=imlib_context_get_filter())) {
1096 for(i
=0;i
<adesklets
.filters
->pos
;++i
)
1097 if(adesklets
.filters
->content
[i
]==filter
)
1098 command_ok("context filter %d\n",i
);
1100 command_ok("context filter -1 (unset)\n");
1102 case CMD_CONTEXT_GET_COLOR
:
1103 /* prototype(void) */
1104 imlib_context_get_color(&x
,&y
,&i
,&j
);
1105 command_ok("context color %hhu %hhu %hhu %hhu\n",
1106 x
&255,y
&255,i
&255,j
&255);
1108 case CMD_CONTEXT_GET_ANGLE
:
1109 angle
=imlib_context_get_angle();
1110 command_ok("context angle %4.2f\n",angle
);
1112 case CMD_CONTEXT_GET_DIRECTION
:
1113 i
=imlib_context_get_direction();
1114 command_ok("context direction %d (%s)\n",
1117 case CMD_CONTEXT_SET_DITHER
:
1118 /* prototype(bool dither) */
1120 imlib_context_set_dither((char)atoi(params
->content
[1]));
1122 command_error("dither value not given\n");
1124 case CMD_CONTEXT_SET_ANTI_ALIAS
:
1125 /* prototype(bool anti_alias) */
1127 imlib_context_set_anti_alias((char)atoi(params
->content
[1]));
1129 command_error("anti alias value not given\n");
1131 case CMD_CONTEXT_SET_BLEND
:
1132 /* prototype(bool blend) */
1134 imlib_context_set_blend((char)atoi(params
->content
[1]));
1136 command_error("blend value not given\n");
1138 case CMD_CONTEXT_SET_OPERATION
:
1139 /* prototype(enum OPERATIONS operation) */
1140 if(params
->pos
>=2) {
1141 for(i
=0;OPERATIONS
[i
];++i
)
1142 if(strncmp(OPERATIONS
[i
],params
->content
[1],
1143 strlen(params
->content
[1]))==0)
1145 imlib_context_set_operation((OPERATIONS
[i
])?
1146 i
:((j
=atoi(params
->content
[1])))<4?j
:0);
1148 command_error("operation not given\n");
1150 case CMD_CONTEXT_SET_CLIPRECT
:
1151 if (params
->pos
>=5) {
1152 if ((x
=atoi((char*)params
->content
[1]))>=0 &&
1153 (y
=atoi((char*)params
->content
[2]))>=0 &&
1154 (i
=atoi((char*)params
->content
[3]))>=0 &&
1155 (j
=atoi((char*)params
->content
[4]))>=0) {
1156 imlib_context_set_cliprect(x
,y
,i
,j
);
1158 command_error("clipping rectangle coordinates out of range\n");
1160 command_error("clipping rectangle description not given\n");
1162 case CMD_CONTEXT_SET_IMAGE
:
1163 if (params
->pos
>=2) {
1164 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1165 i
<adesklets
.images
->pos
) {
1166 imlib_context_set_image(adesklets
.images
->content
[i
]);
1168 command_error("image ID %d out of range\n",i
);
1170 command_error("image ID not given\n");
1172 case CMD_CONTEXT_SET_FONT
:
1173 /* prototype([int font]) */
1175 if (params
->pos
>=2) {
1176 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1177 i
<adesklets
.fonts
->pos
) {
1178 imlib_context_set_font(adesklets
.fonts
->content
[i
]);
1182 imlib_context_set_font(NULL
);
1184 command_error("font ID %d out of range\n",i
);
1188 imlib_context_set_font(NULL
);
1190 if(j
) command_ok("context font unset\n");
1192 case CMD_CONTEXT_SET_COLOR_RANGE
:
1193 /* prototype([int color_range]) */
1195 if (params
->pos
>=2) {
1196 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1197 i
<adesklets
.color_ranges
->pos
) {
1198 imlib_context_set_color_range(adesklets
.color_ranges
->content
[i
]);
1202 imlib_context_set_color_range(NULL
);
1204 command_error("color range ID %d out of range\n",i
);
1208 imlib_context_set_color_range(NULL
);
1210 if(j
) command_ok("context color range unset\n");
1212 case CMD_CONTEXT_SET_COLOR_MODIFIER
:
1213 /* prototype([int color_modifier]) */
1215 if (params
->pos
>=2) {
1216 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1217 i
<adesklets
.color_modifiers
->pos
) {
1218 imlib_context_set_color_modifier(
1219 adesklets
.color_modifiers
->content
[i
]);
1223 imlib_context_set_color_modifier(NULL
);
1225 command_error("color modifier ID %d out of range\n",i
);
1229 imlib_context_set_color_modifier(NULL
);
1231 if(j
) command_ok("context color modifier unset\n");
1233 case CMD_CONTEXT_SET_FILTER
:
1234 /* prototype([int filter]) */
1236 if (params
->pos
>=2) {
1237 if ((i
=atoi((char*)params
->content
[1]))>=0 &&
1238 i
<adesklets
.filters
->pos
) {
1239 imlib_context_set_filter(adesklets
.filters
->content
[i
]);
1243 imlib_context_set_filter(NULL
);
1245 command_error("filter ID %d out of range\n",i
);
1249 imlib_context_set_filter(NULL
);
1251 if(j
) command_ok("context filter unset\n");
1253 case CMD_CONTEXT_SET_COLOR
:
1255 imlib_context_set_color(atoi(params
->content
[1]),
1256 atoi(params
->content
[2]),
1257 atoi(params
->content
[3]),
1258 atoi(params
->content
[4]));
1260 command_error("color RGBA description not given\n");
1262 case CMD_CONTEXT_SET_ANGLE
:
1263 if (params
->pos
>=2) {
1264 imlib_context_set_angle(atof(params
->content
[1]));
1266 command_error("angle not given\n");
1268 case CMD_CONTEXT_SET_DIRECTION
:
1269 /* prototype(enum DIRECTIONS direction) */
1270 if(params
->pos
>=2) {
1271 for(i
=0;DIRECTIONS
[i
];++i
)
1272 if(strncmp(DIRECTIONS
[i
],params
->content
[1],
1273 strlen(params
->content
[1]))==0)
1275 imlib_context_set_direction((DIRECTIONS
[i
])?
1276 i
:((j
=atoi(params
->content
[1])))<5?j
:0);
1278 command_error("direction not given\n");
1280 case CMD_ADD_COLOR_TO_COLOR_RANGE
:
1281 if(imlib_context_get_color_range()) {
1282 i
=(params
->pos
>=2)?atoi(params
->content
[1]):0;
1283 imlib_add_color_to_color_range(i
);
1285 command_error("no color range selected\n");
1287 case CMD_BLEND_IMAGE_ONTO_IMAGE
:
1288 if (params
->pos
>=11) {
1289 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1290 i
<adesklets
.images
->pos
) {
1291 imlib_blend_image_onto_image(adesklets
.images
->content
[i
],
1292 atoi(params
->content
[2]),
1293 atoi(params
->content
[3]),
1294 atoi(params
->content
[4]),
1295 atoi(params
->content
[5]),
1296 atoi(params
->content
[6]),
1297 atoi(params
->content
[7]),
1298 atoi(params
->content
[8]),
1299 atoi(params
->content
[9]),
1300 atoi(params
->content
[10]));
1301 if (image_is_shown())
1302 updates
= imlib_update_append_rect(updates
,
1303 atoi(params
->content
[7]),
1304 atoi(params
->content
[8]),
1305 atoi(params
->content
[9]),
1306 atoi(params
->content
[10]));
1308 command_error("image ID %d out of range\n",i
);
1310 command_error("not enough parameters given - need ten\n");
1312 case CMD_BLEND_IMAGE_ONTO_IMAGE_AT_ANGLE
:
1313 if (params
->pos
>=11) {
1314 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1315 i
<adesklets
.images
->pos
) {
1316 imlib_blend_image_onto_image_at_angle(
1317 adesklets
.images
->content
[i
],
1318 atoi(params
->content
[2]),
1319 atoi(params
->content
[3]),
1320 atoi(params
->content
[4]),
1321 atoi(params
->content
[5]),
1322 atoi(params
->content
[6]),
1323 atoi(params
->content
[7]),
1324 atoi(params
->content
[8]),
1325 atoi(params
->content
[9]),
1326 atoi(params
->content
[10]));
1327 if (image_is_shown())
1328 /* We do not bother: we update everything */
1329 updates
= imlib_update_append_rect(updates
,
1331 imlib_image_get_width(),
1332 imlib_image_get_height());
1334 command_error("image ID %d out of range\n",i
);
1336 command_error("not enough parameters given - need ten\n");
1338 case CMD_BLEND_IMAGE_ONTO_IMAGE_SKEWED
:
1339 if (params
->pos
>=12) {
1340 if((i
=atoi((char*)params
->content
[1]))>=0 &&
1341 i
<adesklets
.images
->pos
) {
1342 imlib_blend_image_onto_image_skewed(adesklets
.images
->content
[i
],
1343 atoi(params
->content
[2]),
1344 atoi(params
->content
[3]),
1345 atoi(params
->content
[4]),
1346 atoi(params
->content
[5]),
1347 atoi(params
->content
[6]),
1348 atoi(params
->content
[7]),
1349 atoi(params
->content
[8]),
1350 atoi(params
->content
[9]),
1351 atoi(params
->content
[10]),
1352 atoi(params
->content
[11]),
1353 atoi(params
->content
[12]));
1354 if (image_is_shown())
1355 /* We do not bother: we update everything */
1356 updates
= imlib_update_append_rect(updates
,
1358 imlib_image_get_width(),
1359 imlib_image_get_height());
1361 command_error("image ID %d out of range\n",i
);
1363 command_error("not enough parameters given - need twelve\n");
1365 case CMD_APPLY_FILTER
:
1366 /* WARNING: there is a initialisation bug in imlib2 prior
1367 version 1.2.0 (cvs of 11/20/04) that sets the dynamic filters
1368 never to work if an image loader is not used
1369 at least once before (this has to do with
1370 lt_dlinit() being called at the wrong place...).
1371 We can do nothing about this: upgrade your imlib2 lib!
1373 prototype(const char * script)
1375 if(params
->pos
>=2) {
1376 menu_str
=command_subsplitter(command
.line
,1);
1377 if(!strstr(menu_str
,"[]")) {
1378 imlib_apply_filter(menu_str
);
1379 if (image_is_shown())
1380 updates
=imlib_update_append_rect(updates
,0,0,
1381 imlib_image_get_width(),
1382 imlib_image_get_height());
1385 command_error("variadic filters forbidden\n");
1387 command_error("filter description not given\n");
1390 "tint(x=0,y=0,w=100,h=100,alpha=100,red=155,green=25,blue=25);"
1393 case CMD_GET_TEXT_SIZE
:
1394 /* prototype(const char * text) */
1395 if(imlib_context_get_font()) {
1396 if(params
->pos
>=2) {
1397 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,1));
1398 imlib_get_text_size(menu_str
,
1401 command_ok("text size %d %d\n",i
,j
);
1403 command_error("text string not given or blank\n");
1405 command_error("no font selected.\n");
1407 case CMD_GET_TEXT_ADVANCE
:
1408 /* prototype(const char * text) */
1409 if(imlib_context_get_font()) {
1410 if(params
->pos
>=2) {
1411 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,1));
1412 imlib_get_text_advance(menu_str
,&i
,&j
);
1414 command_ok("text advance %d %d\n",i
,j
);
1416 command_error("text string not given or blank\n");
1418 command_error("no font selected.\n");
1421 if(imlib_context_get_font()) {
1422 if(params
->pos
>=4) {
1423 menu_str
=dupstr_utf8(command_subsplitter(command
.line
,3));
1424 imlib_text_draw(atoi(params
->content
[1]),
1425 atoi(params
->content
[2]),
1427 if (image_is_shown()) {
1428 imlib_get_text_size(menu_str
,&x
,&y
);
1429 updates
= imlib_update_append_rect(updates
,
1430 atoi(params
->content
[1]),
1431 atoi(params
->content
[2]),
1436 command_error("text string not given or blank\n");
1438 command_error("no font selected.\n");
1440 case CMD_MODIFY_COLOR_MODIFIER_GAMMA
:
1441 if(imlib_context_get_color_modifier()) {
1442 if(params
->pos
>=2) {
1443 imlib_modify_color_modifier_gamma(atof(params
->content
[1]));
1445 command_error("gamma value not given\n");
1447 command_error("no context color modifier selected\n");
1449 case CMD_MODIFY_COLOR_MODIFIER_BRIGHTNESS
:
1450 if(imlib_context_get_color_modifier()) {
1451 if(params
->pos
>=2) {
1452 imlib_modify_color_modifier_brightness(atof(params
->content
[1]));
1454 command_error("brightness value not given\n");
1456 command_error("no context color modifier selected\n");
1458 case CMD_MODIFY_COLOR_MODIFIER_CONTRAST
:
1459 if(imlib_context_get_color_modifier()) {
1460 if(params
->pos
>=2) {
1461 imlib_modify_color_modifier_contrast(atof(params
->content
[1]));
1463 command_error("contrast value not given\n");
1465 command_error("no context color modifier selected\n");
1467 case CMD_GET_COLOR_MODIFIER_TABLES
:
1468 /* prototype(void) */
1469 /* Throw all 1024 table entries in RGBA orders */
1470 if(imlib_context_get_color_modifier()) {
1471 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1472 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1473 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1474 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1475 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1476 tables
[2],tables
[3]);
1479 command_printf("%hhu ", tables
[i
][j
]);
1480 command_printf("\n");
1482 command_error("memory allocation problem\n");
1484 if(tables
[i
]) free(tables
[i
]);
1486 command_error("no context color modifier selected\n");
1489 case CMD_SET_COLOR_MODIFIER_TABLES
:
1490 /* prototype(unsigned char * table) */
1491 if(imlib_context_get_color_modifier()) {
1492 if (params
->pos
==1025) {
1493 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1494 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1495 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1496 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1499 tables
[i
][j
]=(DATA8
)atoi(params
->content
[(i
*256)+j
+1]);
1500 imlib_set_color_modifier_tables(tables
[0],tables
[1],
1501 tables
[2],tables
[3]);
1502 command_ok("set_color_modifier_tables\n");
1504 command_error("memory allocation problem");
1506 if(tables
[i
]) free(tables
[i
]);
1508 command_error("Invalid number of entries - need 1024\n");
1510 command_error("no context color modifier selected\n");
1512 case CMD_GET_COLOR_MODIFIER_VALUE
:
1513 /* prototype(enum RGBA_TABLES table, int index) */
1514 /* NOTE: this is not an original imlib2 function.
1515 it was included as a convenience for
1517 if(imlib_context_get_color_modifier()) {
1518 if (params
->pos
>=3) {
1519 for(i
=0;RGBA_TABLES
[i
];++i
)
1520 if(strncmp(RGBA_TABLES
[i
],
1522 strlen(params
->content
[1]))==0)
1524 i
=(RGBA_TABLES
[i
])?i
:atoi(params
->content
[1])%4;
1526 if((j
=atoi(params
->content
[2]))<256 && j
>=0) {
1527 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1528 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1529 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1530 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1531 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1532 tables
[2],tables
[3]);
1533 command_ok("value %s %hhu\n",
1535 (char)tables
[i
][j
]&255);
1538 command_error("memory allocation problem\n");
1540 if(tables
[i
]) free(tables
[i
]);
1542 command_error("index value %d out of range\n",j
);
1544 command_error("parameters not given - need two\n");
1546 command_error("no context color modifier selected\n");
1548 case CMD_SET_COLOR_MODIFIER_VALUE
:
1549 /* prototype(enum RGBA_TABLES table, int index, int value) */
1550 /* NOTE: this is not an original imlib2 function.
1551 it was included as a convenience for
1553 if(imlib_context_get_color_modifier()) {
1554 if (params
->pos
>=4) {
1555 for(i
=0;RGBA_TABLES
[i
];++i
)
1556 if(strncmp(RGBA_TABLES
[i
],
1558 strlen(params
->content
[1]))==0)
1560 i
=(RGBA_TABLES
[i
])?i
:atoi(params
->content
[1])%4;
1562 if((j
=atoi(params
->content
[2]))<256 && j
>=0) {
1563 if ((x
=atoi(params
->content
[3]))<256 && x
>=0) {
1564 if((tables
[0]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1565 (tables
[1]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1566 (tables
[2]=(DATA8
*)malloc(sizeof(DATA8
)*256))&&
1567 (tables
[3]=(DATA8
*)malloc(sizeof(DATA8
)*256))) {
1568 imlib_get_color_modifier_tables(tables
[0],tables
[1],
1569 tables
[2],tables
[3]);
1571 imlib_set_color_modifier_tables(tables
[0],tables
[1],
1572 tables
[2],tables
[3]);
1574 command_error("memory allocation problem\n");
1576 if(tables
[i
]) free(tables
[i
]);
1578 command_error("value %d out of range\n",x
);
1580 command_error("index value %d out of range\n",j
);
1582 command_error("parameters not given - need three\n");
1584 command_error("no context color modifier selected\n");
1586 case CMD_APPLY_COLOR_MODIFIER
:
1587 if(imlib_context_get_color_modifier()) {
1588 imlib_apply_color_modifier();
1589 if(image_is_shown())
1590 updates
=imlib_update_append_rect(updates
,0,0,
1591 imlib_image_get_width(),
1592 imlib_image_get_height());
1594 command_error("no context color modifier selected\n");
1596 case CMD_APPLY_COLOR_MODIFIER_TO_RECTANGLE
:
1597 if(imlib_context_get_color_modifier()) {
1598 if (params
->pos
>=5) {
1599 imlib_apply_color_modifier_to_rectangle(
1600 (x
=atoi(params
->content
[1])),
1601 (y
=atoi(params
->content
[2])),
1602 (i
=atoi(params
->content
[3])),
1603 (j
=atoi(params
->content
[4])));
1604 if (image_is_shown())
1605 updates
=imlib_update_append_rect(updates
,x
,y
,i
,j
);
1607 command_error("rectangles coordinates not given\n");
1609 command_error("no context color modifier selected\n");
1611 case CMD_LOAD_IMAGE_WITHOUT_CACHE
:
1612 if (params
->pos
>=2) {
1613 menu_str
=command_subsplitter(command
.line
,1);
1614 if ((image
=imlib_load_image_without_cache(menu_str
))) {
1615 if (vector_push(adesklets
.images
,image
))
1616 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1618 command_error("memory allocation problem\n");
1620 command_error("could not load image '%s'\n", menu_str
);
1622 command_error("image file name not given\n");
1624 case CMD_LOAD_IMAGE
:
1625 if (params
->pos
>=2) {
1626 menu_str
=command_subsplitter(command
.line
,1);
1627 if ((image
=imlib_load_image_with_error_return(menu_str
,&error
))) {
1628 if (vector_push(adesklets
.images
,image
))
1629 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1631 command_error("memory allocation problem\n");
1633 command_error("could not load image '%s' - %s\n",
1634 menu_str
,LOAD_ERRORS
[(int)error
]);
1636 command_error("image file name not given\n");
1638 case CMD_SAVE_IMAGE
:
1639 if (params
->pos
>=2) {
1640 menu_str
=command_subsplitter(command
.line
,1);
1641 imlib_save_image_with_error_return(menu_str
,&error
);
1642 if(error
!=IMLIB_LOAD_ERROR_NONE
)
1643 command_error("%s\n",LOAD_ERRORS
[(int)error
]);
1645 command_error("image file name not given\n");
1647 case CMD_CREATE_IMAGE
:
1648 if (params
->pos
>=3) {
1649 if((i
=atoi(params
->content
[1]))>0 &&
1650 (j
=atoi(params
->content
[2]))>0) {
1651 if((image
=imlib_create_image(i
,j
))) {
1652 xwindow_context_save(IMLIB_IMAGE
|IMLIB_BLEND
|IMLIB_COLOR
);
1653 imlib_context_set_image(image
);
1654 imlib_image_set_has_alpha(1);
1655 imlib_context_set_blend(0);
1656 imlib_context_set_color(0,0,0,0);
1657 imlib_image_fill_rectangle(0,0,i
,j
);
1658 xwindow_context_restore();
1659 if (vector_push(adesklets
.images
,image
))
1660 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1662 command_error("memory allocation problem\n");
1664 command_error("imlib image allocation error\n");
1666 command_error("image dimensions out of range\n");
1668 command_error("image dimensions were not given\n");
1670 case CMD_CREATE_IMAGE_USING_DATA
:
1671 /* This uses imlib_create_image_using_copied_data(),
1672 so DATA * data can be freed afterward.
1673 As in CMD_IMAGE_GET_DATA, data is expected to be
1675 if (params
->pos
>=3) {
1676 if ((width
=atoi(params
->content
[1]))>0 &&
1677 (height
=atoi(params
->content
[2]))>0) {
1678 if(width
*height
*4==params
->pos
-3) {
1679 if((data
=(DATA32
*)malloc(sizeof(DATA32
)*width
*height
))) {
1680 for(i
=0;i
<width
*height
;++i
)
1682 ((atoi((char*)params
->content
[i
*4+3])&255)<<16)|
1683 ((atoi((char*)params
->content
[i
*4+4])&255)<<8)|
1684 ((atoi((char*)params
->content
[i
*4+5])&255)<<0)|
1685 ((atoi((char*)params
->content
[i
*4+6])&255)<<24);
1686 if ((image
=imlib_create_image_using_copied_data(width
,
1689 xwindow_context_save(IMLIB_IMAGE
);
1690 imlib_context_set_image(image
);
1691 imlib_image_set_has_alpha(1);
1692 xwindow_context_restore();
1693 if(vector_push(adesklets
.images
,image
))
1694 command_ok("new image %d\n",adesklets
.images
->pos
-1);
1696 command_error("memory allocation problem");
1698 command_error("imlib image allocation error\n");
1702 command_error("memory allocation problem\n");
1704 command_error("image dimensions and data lenght mismatch\n");
1706 command_error("image dimensions out of range\n");
1708 command_error("image dimensions were not given\n");
1710 case CMD_CLONE_IMAGE
:
1711 if((image
=imlib_clone_image())) {
1712 if (vector_push(adesklets
.images
,image
))
1713 command_ok("cloned image %d\n",adesklets
.images
->pos
-1);
1715 command_error("memory allocation problem");
1717 command_error("imlib image allocation error\n");
1719 case CMD_FREE_IMAGE
:
1720 /* This does not react as imlib_free_image:
1721 - image ID has to be given
1722 - If current context image is freed, context
1723 is put back on foreground image
1724 - If image corresponding to user_background_image
1725 is freed, user_background_image is reset.
1727 prototype(int image)
1729 if(params
->pos
>=2) {
1730 if((i
=atoi((char*)params
->content
[1]))<adesklets
.images
->pos
&&
1733 j
=(imlib_context_get_image()==adesklets
.images
->content
[i
]);
1734 if (vector_delete(adesklets
.images
,i
)) {
1735 if(i
==adesklets
.user_background_image
) {
1736 adesklets
.user_background_image
=-1;
1737 xwindow_context_save(IMLIB_IMAGE
);
1738 imlib_context_set_image(adesklets
.images
->content
[0]);
1739 updates
=imlib_update_append_rect(updates
,0,0,
1740 imlib_image_get_width(),
1741 imlib_image_get_height());
1742 xwindow_context_restore();
1745 if(i
<adesklets
.user_background_image
)
1746 --adesklets
.user_background_image
;
1748 imlib_context_set_image(adesklets
.images
->content
[0]);
1750 command_error("memory desallocation problem\n");
1752 command_error("it is forbidden to unload image %d\n",i
);
1754 command_error("image ID %d out of range\n",i
);
1756 command_error("image ID not given\n");
1759 if(params
->pos
>=2) {
1760 if (strlen(params
->content
[1])>=3 &&
1761 index(params
->content
[1],'/')) {
1762 if ((font
=imlib_load_font(params
->content
[1]))) {
1763 if(vector_push(adesklets
.fonts
,font
))
1764 command_ok("new font %d\n", adesklets
.fonts
->pos
-1);
1766 command_error("memory allocation problem");
1768 command_error("font '%s' could not be loaded\n",
1769 (char*)params
->content
[1]);
1772 "font description incorrect - should be `name/size'\n");
1774 command_error("font description not given\n");
1777 /* This does not react as imlib_free_font:
1778 - font ID has to be given
1779 - If current font is freed, context
1784 if(params
->pos
>=2) {
1785 if((i
=atoi((char*)params
->content
[1]))
1786 <adesklets
.fonts
->pos
&&
1788 j
=(imlib_context_get_font()==
1789 adesklets
.fonts
->content
[i
]);
1790 if (vector_delete(adesklets
.fonts
,i
)) {
1792 imlib_context_set_font(NULL
);
1794 command_error("memory desallocation problem\n");
1796 command_error("font ID %d out of range\n",i
);
1798 command_error("font ID not given\n");
1800 case CMD_LIST_FONTS
:
1801 /* prototype(void) */
1802 list
=imlib_list_fonts(&j
);
1803 command_printf("%d fonts found\n",j
);
1805 command_printf("%s ",list
[i
]);
1806 command_printf("\n");
1807 imlib_free_font_list(list
,j
);
1809 case CMD_LIST_FONT_PATH
:
1810 /* prototype(void) */
1811 list
=imlib_list_font_path(&j
);
1812 command_printf("%d font_path found\n",j
);
1814 command_printf("%s\n",list
[i
]);
1816 case CMD_ADD_PATH_TO_FONT_PATH
:
1817 if(params
->pos
>=2) {
1818 imlib_add_path_to_font_path(command_subsplitter(command
.line
,1));
1820 command_error("font path not given\n");
1822 case CMD_REMOVE_PATH_FROM_FONT_PATH
:
1823 if(params
->pos
>=2) {
1824 imlib_remove_path_from_font_path(
1825 command_subsplitter(command
.line
,1));
1826 debug("%s\n",command_subsplitter(command
.line
,1));
1828 command_error("font path not given\n");
1830 case CMD_CREATE_COLOR_RANGE
:
1831 if((color_range
=imlib_create_color_range())) {
1832 if(vector_push(adesklets
.color_ranges
,color_range
))
1833 command_ok("new colorrange %d\n",adesklets
.color_ranges
->pos
-1);
1835 command_error("memory allocation problem\n");
1837 command_error("imlib allocation problem\n");
1839 case CMD_FREE_COLOR_RANGE
:
1840 /* This does not react as imlib_free_color_range:
1841 - color_range ID has to be given
1842 - If current color range is freed, context
1845 prototype(int color_range)
1847 if(params
->pos
>=2) {
1848 if((i
=atoi((char*)params
->content
[1]))
1849 <adesklets
.color_ranges
->pos
&&
1851 j
=(imlib_context_get_color_range()==
1852 adesklets
.color_ranges
->content
[i
]);
1853 if (vector_delete(adesklets
.color_ranges
,i
)) {
1855 imlib_context_set_color_range(NULL
);
1857 command_error("memory desallocation problem\n");
1859 command_error("color range ID %d out of range\n",i
);
1861 command_error("color range ID not given\n");
1863 case CMD_CREATE_FILTER
:
1864 /* prototype(void) */
1865 if((filter
=imlib_create_filter(0))) {
1866 if(vector_push(adesklets
.filters
,filter
))
1867 command_ok("new filter %d\n",adesklets
.filters
->pos
-1);
1869 command_error("memory allocation problem\n");
1871 command_error("imlib allocation problem\n");
1873 case CMD_FREE_FILTER
:
1874 /* This does not react as imlib_free_filter:
1875 - filter ID has to be given
1876 - If current filter is freed, context
1879 prototype(int filter)
1881 if(params
->pos
>=2) {
1882 if((i
=atoi((char*)params
->content
[1]))
1883 <adesklets
.filters
->pos
&&
1885 j
=(imlib_context_get_filter()==
1886 adesklets
.filters
->content
[i
]);
1887 if (vector_delete(adesklets
.filters
,i
)) {
1889 imlib_context_set_filter(NULL
);
1891 command_error("memory desallocation problem\n");
1893 command_error("filter ID %d out of range\n",i
);
1895 command_error("filter ID not given\n");
1897 case CMD_CREATE_COLOR_MODIFIER
:
1898 if((color_modifier
=imlib_create_color_modifier())) {
1899 if(vector_push(adesklets
.color_modifiers
,color_modifier
))
1900 command_ok("new colormodifier %d\n",
1901 adesklets
.color_modifiers
->pos
-1);
1903 command_error("memory allocation problem\n");
1905 command_error("imlib allocation problem\n");
1907 case CMD_FREE_COLOR_MODIFIER
:
1908 /* This does not react as imlib_free_color_modifier:
1909 - color_range ID has to be given
1910 - If current color modifier is freed, context
1913 prototype(int color_modifier)
1915 if(params
->pos
>=2) {
1916 if((i
=atoi((char*)params
->content
[1]))
1917 <adesklets
.color_modifiers
->pos
&&
1919 j
=(imlib_context_get_color_modifier()==
1920 adesklets
.color_modifiers
->content
[i
]);
1921 if (vector_delete(adesklets
.color_modifiers
,i
)) {
1923 imlib_context_set_color_modifier(NULL
);
1925 command_error("memory desallocation problem\n");
1927 command_error("color modifier ID %d out of range\n",i
);
1929 command_error("color modifier ID not given\n");
1931 case CMD_POLYGON_NEW
:
1932 if((polygon
=imlib_polygon_new())) {
1933 if(vector_push(adesklets
.polygons
,polygon
))
1934 command_ok("new polygon %d\n",adesklets
.polygons
->pos
-1);
1936 command_error("memory allocation problem\n");
1938 command_error("imlib allocation problem\n");
1940 case CMD_POLYGON_FREE
:
1941 if(params
->pos
>=2) {
1942 if((i
=atoi(params
->content
[1]))>=0 &&
1943 i
<adesklets
.polygons
->pos
) {
1944 if(!vector_delete(adesklets
.polygons
,i
))
1945 command_error("memory desallocation problem\n");
1947 command_error("polygon ID %d out of range\n",i
);
1949 command_error("polygon ID not given\n");
1951 case CMD_POLYGON_ADD_POINT
:
1952 if(params
->pos
>=4) {
1953 if((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
1954 imlib_polygon_add_point(adesklets
.polygons
->content
[i
],
1955 atoi(params
->content
[2]),
1956 atoi(params
->content
[3]));
1958 command_error("polygon ID %d out of range\n",i
);
1960 command_error("not enough parameters given - need 3\n");
1962 case CMD_IMAGES_RESET_ALL
:
1963 /* prototype(void) */
1964 adesklets_images_reset();
1966 case CMD_IMAGES_INFO
:
1967 /* prototype(void) */
1968 xwindow_context_save(IMLIB_IMAGE
);
1969 command_printf("%d images\n",adesklets
.images
->pos
);
1970 for(i
=0;i
<adesklets
.images
->pos
;++i
) {
1971 imlib_context_set_image(adesklets
.images
->content
[i
]);
1972 command_printf("id %d width %d height %d alpha %hhu filename %s\n",
1974 imlib_image_get_width(), imlib_image_get_height(),
1975 imlib_image_has_alpha(), imlib_image_get_filename());
1977 xwindow_context_restore();
1979 case CMD_FONTS_RESET_ALL
:
1980 /* prototype(void) */
1981 adesklets_fonts_reset();
1983 case CMD_FONTS_INFO
:
1984 /* prototype(void) */
1985 command_printf("%d fonts\n",adesklets
.fonts
->pos
);
1987 case CMD_COLOR_RANGES_RESET_ALL
:
1988 /* prototype(void) */
1989 adesklets_color_ranges_reset();
1991 case CMD_COLOR_RANGES_INFO
:
1992 /* prototype(void) */
1993 command_printf("%d color ranges\n",adesklets
.color_ranges
->pos
);
1995 case CMD_COLOR_MODIFIERS_RESET_ALL
:
1996 /* prototype(void) */
1997 adesklets_color_modifiers_reset();
1999 case CMD_COLOR_MODIFIERS_INFO
:
2000 /* prototype(void) */
2001 command_printf("%d color modifiers\n",adesklets
.color_modifiers
->pos
);
2003 case CMD_FILTERS_RESET_ALL
:
2004 /* prototype(void) */
2005 adesklets_filters_reset();
2007 case CMD_FILTERS_INFO
:
2008 /* prototype(void) */
2009 command_printf("%d filters\n",adesklets
.filters
->pos
);
2011 case CMD_POLYGONS_RESET_ALL
:
2012 /* prototype(void) */
2013 adesklets_polygons_reset();
2015 case CMD_POLYGONS_INFO
:
2016 /* prototype(void) */
2017 command_printf("%d polygons\n",adesklets
.polygons
->pos
);
2019 case CMD_IMAGE_HAS_ALPHA
:
2020 command_ok("image alpha %hhu\n",imlib_image_has_alpha());
2022 case CMD_IMAGE_GET_WIDTH
:
2023 command_ok("image width %d\n",imlib_image_get_width());
2025 case CMD_IMAGE_GET_HEIGHT
:
2026 command_ok("image height %d\n",imlib_image_get_height());
2028 case CMD_IMAGE_GET_FILENAME
:
2029 command_ok("image filename %s\n",imlib_image_get_filename());
2031 case CMD_IMAGE_GET_DATA
:
2032 /* This uses imlib_image_get_data_for_reading_only(),
2033 so there is no need to invalidate image. Print final result
2035 if((data
=imlib_image_get_data_for_reading_only())) {
2036 width
=imlib_image_get_width();
2037 height
=imlib_image_get_height();
2038 command_printf("image data - %d %d\n",width
,height
);
2039 for(i
=0;i
<width
*height
;++i
)
2040 command_printf("%hhu %hhu %hhu %hhu ",
2041 ((data
[i
]&(255<<16))>>16),
2042 ((data
[i
]&(255<<8))>>8),
2044 ((data
[i
]&(255<<24))>>24));
2045 command_printf("\n");
2047 command_error("imlib data fetch problem\n");
2049 case CMD_IMAGE_QUERY_PIXEL
:
2050 /* prototype(int x, int y) */
2051 if (params
->pos
>=2) {
2052 imlib_image_query_pixel(atoi(params
->content
[1]),
2053 atoi(params
->content
[2]),
2055 command_ok("pixel value %hhu %hhu %hhu %hhu\n",
2056 (char)color
.red
&255,(char)color
.green
&255,
2057 (char)color
.blue
&255,(char)color
.alpha
&255);
2059 command_error("pixel coordinates not given\n");
2061 case CMD_IMAGE_SET_HAS_ALPHA
:
2062 /* prototype(bool has_alpha) */
2064 imlib_image_set_has_alpha((char)atoi(params
->content
[1]));
2066 command_error("alpha value not given\n");
2068 case CMD_IMAGE_SET_CHANGES_ON_DISK
:
2069 /* prototype(void) */
2070 imlib_image_set_changes_on_disk();
2072 case CMD_IMAGE_SET_FORMAT
:
2074 imlib_image_set_format(params
->content
[1]);
2076 command_error("format string not given\n");
2078 case CMD_IMAGE_FILTER_RECURSE
:
2079 /* prototype(void) */
2080 if(imlib_context_get_filter()) {
2081 for(i
=0,j
=imlib_image_get_width();i
<j
;++i
) {
2082 imlib_image_filter();
2084 if(i
%(j
/10)==(j
/10)-1)
2085 debug("We are %d0 percents through.\n", (i
+1)*10/j
);
2088 if(image_is_shown())
2089 updates
=imlib_update_append_rect(updates
,0,0,
2090 imlib_image_get_width(),
2091 imlib_image_get_height());
2094 command_error("no filter selected\n");
2096 case CMD_IMAGE_DRAW_LINE
:
2097 if(params
->pos
>=5) {
2098 imlib_image_draw_line(atoi(params
->content
[1]),
2099 atoi(params
->content
[2]),
2100 atoi(params
->content
[3]),
2101 atoi(params
->content
[4]),0);
2102 if (image_is_shown())
2103 updates
= imlib_update_append_rect(updates
,
2104 atoi(params
->content
[1]),
2105 atoi(params
->content
[2]),
2106 atoi(params
->content
[3])-
2107 atoi(params
->content
[1]),
2108 atoi(params
->content
[4])-
2109 atoi(params
->content
[2]));
2111 command_error("line coordinates not given\n");
2113 case CMD_IMAGE_DRAW_RECTANGLE
:
2114 if(params
->pos
>=5) {
2115 imlib_image_draw_rectangle(atoi(params
->content
[1]),
2116 atoi(params
->content
[2]),
2117 atoi(params
->content
[3]),
2118 atoi(params
->content
[4]));
2119 if (image_is_shown())
2120 updates
= imlib_update_append_rect(updates
,
2121 atoi(params
->content
[1]),
2122 atoi(params
->content
[2]),
2123 atoi(params
->content
[3]),
2124 atoi(params
->content
[4]));
2126 command_error("rectangle description not given\n");
2128 case CMD_IMAGE_FILL_RECTANGLE
:
2129 if(params
->pos
>=5) {
2130 imlib_image_fill_rectangle(atoi(params
->content
[1]),
2131 atoi(params
->content
[2]),
2132 atoi(params
->content
[3]),
2133 atoi(params
->content
[4]));
2134 if (image_is_shown())
2135 updates
= imlib_update_append_rect(updates
,
2136 atoi(params
->content
[1]),
2137 atoi(params
->content
[2]),
2138 atoi(params
->content
[3]),
2139 atoi(params
->content
[4]));
2141 command_error("rectangle description not given\n");
2143 case CMD_IMAGE_FILL_COLOR_RANGE_RECTANGLE
:
2144 if (imlib_context_get_color_range()) {
2145 if(params
->pos
>=6) {
2146 imlib_image_fill_color_range_rectangle(atoi(params
->content
[1]),
2147 atoi(params
->content
[2]),
2148 atoi(params
->content
[3]),
2149 atoi(params
->content
[4]),
2150 atof(params
->content
[5]));
2151 if (image_is_shown())
2152 updates
= imlib_update_append_rect(updates
,
2153 atoi(params
->content
[1]),
2154 atoi(params
->content
[2]),
2155 atoi(params
->content
[3]),
2156 atoi(params
->content
[4]));
2158 command_error("not enough parameters given - need five\n");
2160 command_error("no color range selected\n");
2162 case CMD_IMAGE_DRAW_ELLIPSE
:
2163 if(params
->pos
>=5) {
2164 imlib_image_draw_ellipse(atoi(params
->content
[1]),
2165 atoi(params
->content
[2]),
2166 atoi(params
->content
[3]),
2167 atoi(params
->content
[4]));
2168 if (image_is_shown())
2169 updates
= imlib_update_append_rect(updates
,
2170 atoi(params
->content
[1])-
2171 atoi(params
->content
[3]),
2172 atoi(params
->content
[2])-
2173 atoi(params
->content
[4]),
2174 2*atoi(params
->content
[3]),
2175 2*atoi(params
->content
[4]));
2177 command_error("ellipse description not given\n");
2179 case CMD_IMAGE_FILL_ELLIPSE
:
2180 if(params
->pos
>=5) {
2181 imlib_image_fill_ellipse(atoi(params
->content
[1]),
2182 atoi(params
->content
[2]),
2183 atoi(params
->content
[3]),
2184 atoi(params
->content
[4]));
2185 if (image_is_shown())
2186 updates
= imlib_update_append_rect(updates
,
2187 atoi(params
->content
[1])-
2188 atoi(params
->content
[3]),
2189 atoi(params
->content
[2])-
2190 atoi(params
->content
[4]),
2191 2*atoi(params
->content
[3]),
2192 2*atoi(params
->content
[4]));
2194 command_error("ellipse description not given\n");
2196 case CMD_IMAGE_COPY_ALPHA_TO_IMAGE
:
2197 if(params
->pos
>=4) {
2198 if((i
=atoi(params
->content
[1]))>=0 &&
2199 i
<adesklets
.images
->pos
) {
2200 imlib_image_copy_alpha_to_image(adesklets
.images
->content
[i
],
2201 atoi(params
->content
[2]),
2202 atoi(params
->content
[3]));
2203 if(image_is_shown()) {
2204 xwindow_context_save(IMLIB_IMAGE
);
2205 imlib_context_set_image(adesklets
.images
->content
[i
]);
2206 updates
= imlib_update_append_rect(updates
,
2207 atoi(params
->content
[2]),
2208 atoi(params
->content
[3]),
2209 imlib_image_get_width(),
2210 imlib_image_get_height());
2211 xwindow_context_restore();
2214 command_error("image ID out of range\n");
2216 command_error("parameters not given\n");
2218 case CMD_IMAGE_COPY_ALPHA_RECTANGLE_TO_IMAGE
:
2219 if(params
->pos
>=8) {
2220 if((i
=atoi(params
->content
[1]))>=0 &&
2221 i
<adesklets
.images
->pos
) {
2222 imlib_image_copy_alpha_rectangle_to_image(
2223 adesklets
.images
->content
[i
],
2224 atoi(params
->content
[2]),
2225 atoi(params
->content
[3]),
2226 atoi(params
->content
[4]),
2227 atoi(params
->content
[5]),
2228 atoi(params
->content
[6]),
2229 atoi(params
->content
[7]));
2231 if(image_is_shown())
2232 updates
= imlib_update_append_rect(updates
,
2233 atoi(params
->content
[6]),
2234 atoi(params
->content
[7]),
2235 atoi(params
->content
[4]),
2236 atoi(params
->content
[5]));
2238 command_error("image ID out of range\n");
2240 command_error("parameters not given - need height\n");
2242 case CMD_IMAGE_DRAW_POLYGON
:
2243 if (params
->pos
>=3) {
2244 if ((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
2245 imlib_image_draw_polygon(adesklets
.polygons
->content
[i
],
2246 ((char*)params
->content
[2])[0]);
2247 if(image_is_shown()) {
2248 imlib_polygon_get_bounds(adesklets
.polygons
->content
[i
],
2250 updates
= imlib_update_append_rect(updates
,x
,y
,i
-x
,j
-y
);
2253 command_error("polygon ID %d out of range\n",i
);
2255 command_error("parameters not given\n");
2257 case CMD_IMAGE_FILL_POLYGON
:
2258 if (params
->pos
>=2) {
2259 if ((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.polygons
->pos
) {
2260 imlib_image_fill_polygon(adesklets
.polygons
->content
[i
]);
2261 if(image_is_shown()) {
2262 imlib_polygon_get_bounds(adesklets
.polygons
->content
[i
],
2264 updates
= imlib_update_append_rect(updates
,x
,y
,i
-x
,j
-y
);
2267 command_error("polygon ID %d out of range\n",i
);
2269 command_error("polygon ID not given\n");
2271 case CMD_IMAGE_FLIP_HORIZONTAL
:
2272 imlib_image_flip_horizontal();
2273 if (image_is_shown())
2274 updates
=imlib_update_append_rect(updates
,0,0,
2275 imlib_image_get_width(),
2276 imlib_image_get_height());
2278 case CMD_IMAGE_FLIP_VERTICAL
:
2279 imlib_image_flip_vertical();
2280 if (image_is_shown())
2281 updates
=imlib_update_append_rect(updates
,0,0,
2282 imlib_image_get_width(),
2283 imlib_image_get_height());
2285 case CMD_IMAGE_FLIP_DIAGONAL
:
2286 if(((image
=imlib_context_get_image()))!=
2287 adesklets
.images
->content
[0] &&
2288 image
!= adesklets
.images
->content
[1] &&
2289 (adesklets
.user_background_image
==-1 ||
2290 image
!= adesklets
.images
->content
[
2291 adesklets
.user_background_image
]))
2292 imlib_image_flip_diagonal();
2294 command_error("operation forbidden on this image\n");
2296 case CMD_IMAGE_ORIENTATE
:
2297 if (params
->pos
>=2) {
2298 if((i
=atoi(params
->content
[1])%4)%2==0 ||
2299 (((image
=imlib_context_get_image())!=
2300 adesklets
.images
->content
[0] &&
2301 image
!= adesklets
.images
->content
[1])))
2302 imlib_image_orientate(i
);
2304 command_error("operation forbidden on this image\n");
2306 command_error("orientation not given\n");
2308 case CMD_IMAGE_BLUR
:
2309 if (params
->pos
>=2) {
2310 imlib_image_blur(atof(params
->content
[1]));
2311 updates
=imlib_update_append_rect(updates
,0,0,
2312 imlib_image_get_width(),
2313 imlib_image_get_height());
2315 command_error("Blur radius not given\n");
2317 case CMD_IMAGE_SHARPEN
:
2318 if (params
->pos
>=2) {
2319 imlib_image_sharpen(atof(params
->content
[1]));
2320 updates
=imlib_update_append_rect(updates
,0,0,
2321 imlib_image_get_width(),
2322 imlib_image_get_height());
2324 command_error("Sharpen radius not given\n");
2326 #define FILTER_SET(op)\
2327 if(imlib_context_get_filter()) {\
2328 if (params->pos>=7)\
2329 imlib_filter_set ## op(atoi(params->content[1]),\
2330 atoi(params->content[2]),\
2331 atoi(params->content[3]),\
2332 atoi(params->content[4]),\
2333 atoi(params->content[5]),\
2334 atoi(params->content[6]));\
2336 command_error("missing parameters - need six\n");\
2338 command_error("no filter selected\n")
2339 case CMD_FILTER_SET
:
2340 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2343 case CMD_FILTER_SET_RED
:
2344 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2347 case CMD_FILTER_SET_GREEN
:
2348 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2351 case CMD_FILTER_SET_BLUE
:
2352 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2355 case CMD_FILTER_SET_ALPHA
:
2356 /* prototype(int xoff, int yoff, int a, int r, int g, int b) */
2360 #define FILTER_SET(op)\
2361 if(imlib_context_get_filter()) {\
2362 if (params->pos>=5)\
2363 imlib_filter_ ## op(atoi(params->content[1]),\
2364 atoi(params->content[2]),\
2365 atoi(params->content[3]),\
2366 atoi(params->content[4]));\
2368 command_error("missing parameters - need four\n");\
2370 command_error("no filter selected\n")
2371 case CMD_FILTER_CONSTANTS
:
2372 /* prototype(int a, int r, int g, int b) */
2373 FILTER_SET(constants
);
2375 case CMD_FILTER_DIVISORS
:
2376 /* prototype(int a, int r, int g, int b) */
2377 FILTER_SET(divisors
);
2381 /* prototype(int menu) */
2382 #ifndef X_DISPLAY_MISSING
2383 if (adesklets
.display
&& adesklets
.window
) {
2384 if(params
->pos
>=2) {
2385 i
=atoi((char*)params
->content
[1]);
2386 if (adesklets_menu_fire(i
,(char**)&menu_str
)) {
2387 if (adesklets
.user_event_mask
&MenuFireMask
)
2388 event("menufire %d %s\n",i
,menu_str
);
2390 command_error("menu fire error\n");
2393 command_error("menu ID not given\n");
2396 command_error("X connection or window missing\n");
2398 case CMD_MENU_RESET_ALL
:
2399 /* prototype(void) */
2400 if (!adesklets_menus_reset())
2401 command_error("internal consistency problem with menu\n");
2403 case CMD_MENU_ADD_MENU
:
2404 /* prototype(void) */
2405 if (!vector_push(adesklets
.menus
,xmenu_init()))
2406 command_error("could not add a new menu\n");
2408 command_ok("new menu %d\n",adesklets
.menus
->pos
-1);
2410 case CMD_MENU_ADD_SUBMENU
:
2411 /* prototype(const char * submenu) */
2412 if (params
->pos
>=2) {
2413 if (!xmenu_push_submenu(MENU(adesklets
.menus
->pos
-1),
2415 strlen(COMMANDS
[CMD_MENU_ADD_SUBMENU
].name
)))
2416 command_error("could not create submenu\n");
2418 if ((menu_str=dupstr_utf8(command_subsplitter(command.line,1)))) {
2419 if (!xmenu_push_submenu(MENU(adesklets.menus->pos-1),menu_str))
2420 command_error("could not create submenu\n");
2425 command_error("submenu description not given\n");
2427 case CMD_MENU_ADD_ITEM
:
2428 /* prototype(const char * add_item) */
2429 if(params
->pos
>=2) {
2430 if(!xmenu_push_item(MENU(adesklets
.menus
->pos
-1),
2432 strlen(COMMANDS
[CMD_MENU_ADD_ITEM
].name
)))
2433 command_error("could not create item\n");
2435 command_error("item description not given\n");
2437 case CMD_MENU_ADD_SEPARATOR
:
2438 /* prototype(void) */
2439 if(!xmenu_push_item(MENU(adesklets
.menus
->pos
-1),"-"))
2440 command_error("could not add separator\n");
2442 case CMD_MENU_END_SUBMENU
:
2443 /* prototype(void) */
2444 if(!xmenu_end_submenu(MENU(adesklets
.menus
->pos
-1)))
2445 command_error("could not end submenu\n");
2447 case CMD_EVENT_CATCH
:
2448 /* prototype(voidvoid) */
2449 #ifndef X_DISPLAY_MISSING
2450 if (adesklets
.display
&& adesklets
.window
) {
2451 if(params
->pos
>=2) {
2452 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2453 if(strncmp(X_WINDOW_EVENTS
[i
].name
,params
->content
[1],
2454 strlen(X_WINDOW_EVENTS
[i
].name
))==0)
2456 adesklets
.user_event_mask
|=
2457 X_WINDOW_EVENTS
[(X_WINDOW_EVENTS
[i
].name
)?
2458 i
:atoi(params
->content
[1])%i
].mask
;
2459 adesklets
.event_mask
=(BASE_EVENT_MASK
)|
2460 (adesklets
.user_event_mask
&
2461 ~(BackgroundGrabMask
|MenuFireMask
));
2462 XSelectInput(adesklets
.display
,adesklets
.window
,
2463 adesklets
.event_mask
);
2465 command_error("event to catch not given\n");
2468 command_error("X connection or window missing\n");
2470 case CMD_EVENT_UNCATCH
:
2471 /* prototype(voidvoid) */
2472 #ifndef X_DISPLAY_MISSING
2473 if(adesklets
.display
&& adesklets
.window
) {
2474 if(params
->pos
>=2) {
2475 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2476 if(strncmp(X_WINDOW_EVENTS
[i
].name
,params
->content
[1],
2477 strlen(X_WINDOW_EVENTS
[i
].name
))==0)
2479 mask
=X_WINDOW_EVENTS
[(X_WINDOW_EVENTS
[i
].name
)?
2480 i
:atoi(params
->content
[1])%i
].mask
;
2481 /* If event was already selected, purge all remaining
2482 events of that type if applicable */
2483 if(mask
!=BackgroundGrabMask
&&
2484 mask
!=MenuFireMask
&&
2485 (adesklets
.event_mask
&mask
) &&
2486 !((BASE_EVENT_MASK
)&mask
))
2487 while(XCheckWindowEvent(adesklets
.display
,
2488 adesklets
.window
,mask
,&ev
));
2489 adesklets
.user_event_mask
&=~mask
;
2490 adesklets
.event_mask
=(BASE_EVENT_MASK
)|
2491 (adesklets
.user_event_mask
2492 &~(BackgroundGrabMask
|MenuFireMask
));
2493 XSelectInput(adesklets
.display
,adesklets
.window
,
2494 adesklets
.event_mask
);
2496 command_error("event to uncatch not given\n");
2499 command_error("X connection or window missing\n");
2501 case CMD_EVENTS_RESET_ALL
:
2502 /* prototype(voidvoid) */
2503 #ifndef X_DISPLAY_MISSING
2504 if(adesklets
.display
&& adesklets
.window
) {
2505 XSelectInput(adesklets
.display
,adesklets
.window
,
2507 while(XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
2508 adesklets
.user_event_mask
&
2509 ~(BASE_EVENT_MASK
)&~BackgroundGrabMask
&
2512 adesklets
.user_event_mask
=0;
2513 adesklets
.event_mask
=BASE_EVENT_MASK
;
2516 command_error("X connection or window missing\n");
2518 case CMD_EVENTS_INFO
:
2519 /* prototype(void) */
2520 #ifndef X_DISPLAY_MISSING
2521 if (adesklets
.display
&& adesklets
.window
) {
2522 for(i
=0,j
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2523 if(adesklets
.user_event_mask
&X_WINDOW_EVENTS
[i
].mask
)
2525 command_printf("%d events caught\n",j
);
2526 for(i
=0;X_WINDOW_EVENTS
[i
].name
;++i
)
2527 if(adesklets
.user_event_mask
&X_WINDOW_EVENTS
[i
].mask
)
2528 command_printf("%d (%s)\n",i
, X_WINDOW_EVENTS
[i
].name
);
2531 command_error("X connection or window missing\n");
2533 case CMD_EVENTS_GET_ECHO
:
2534 /* prototype(void) */
2535 command_ok("events echo %d\n", events_echo
);
2537 case CMD_EVENTS_SET_ECHO
:
2538 /* prototype(voidvoid) */
2539 if(params
->pos
>=2) {
2540 if (events_echo
!=(i
=atoi(params
->content
[1]))) {
2547 command_error("echo value not given\n");
2549 case CMD_EVENTS_GET_SEND_SIGUSR1
:
2550 /* prototype(void) */
2551 command_ok("events send_sigusr1 %d\n",(events_ppid
)?1:0);
2553 case CMD_EVENTS_SET_SEND_SIGUSR1
:
2554 /* prototype(voidvoid) */
2556 events_ppid
=(atoi(params
->content
[1]))?adesklets
.ppid
:0;
2558 command_error("send SIGUSR1 status not given\n");
2560 case CMD_EVENTS_PURGE
:
2561 /* prototype(voidvoid) */
2562 command_printf("%d events to purge\n",(events
)?events
->pos
:0);
2565 case CMD_WINDOW_RESET
:
2566 /* prototype(enum WINDOW_MANAGER manager) */
2567 if(params
->pos
>=2) {
2568 for(i
=0;WINDOW_MANAGER
[i
];++i
)
2569 if(strncmp(WINDOW_MANAGER
[i
],params
->content
[1],
2570 strlen(params
->content
[1]))==0)
2572 if (adesklets_window_reset((WINDOW_MANAGER
[i
])?i
:
2573 atoi(params
->content
[1]))) {
2574 if (adesklets_menus_reset()) {
2575 if (!adesklets_images_reset_background(0))
2576 command_error("could not reset background images\n");
2578 command_error("could not reset menus\n");
2580 command_error("could not reset main window\n");
2582 command_error("Window manager status not given\n");
2584 case CMD_WINDOW_SHOW
:
2585 /* prototype(void) */
2586 #ifndef X_DISPLAY_MISSING
2587 if (adesklets
.display
&& adesklets
.window
) {
2588 if (!XMapWindow(adesklets
.display
,adesklets
.window
))
2589 command_error("could not map the window\n");
2592 command_error("X connection or window missing\n");
2594 case CMD_WINDOW_HIDE
:
2595 /* prototype(void) */
2596 #ifndef X_DISPLAY_MISSING
2597 if (adesklets
.display
&& adesklets
.window
) {
2598 if(!XUnmapWindow(adesklets
.display
,adesklets
.window
))
2599 command_error("could not unmap the window\n");
2602 command_error("X connection or window missing\n");
2604 case CMD_WINDOW_RESIZE
:
2605 /* prototype(int width, int height) */
2606 if (params
->pos
>=3) {
2607 if((i
=atoi(params
->content
[1]))>0 &&
2608 (j
=atoi(params
->content
[2]))>0) {
2609 #ifndef X_DISPLAY_MISSING
2610 if (adesklets
.display
&& adesklets
.window
) {
2611 if (!xwindow_resize_window(adesklets
.display
,adesklets
.window
,
2612 adesklets
.params
,i
,j
,0))
2613 command_error("did not resize window\n");
2616 if (!adesklets_images_reset_background(1,i
,j
))
2617 command_error("no window, and could not resize images\n");
2618 #ifndef X_DISPLAY_MISSING
2621 } else command_error("resize out of range\n");
2622 } else command_error("resize dimensions no given\n");
2624 case CMD_WINDOW_GET_TRANSPARENCY
:
2625 /* prototype(void) */
2626 command_ok("window transparency %d\n",adesklets
.transparency
);
2628 case CMD_WINDOW_GET_BACKGROUND_GRAB
:
2629 /* prototype(void) */
2630 if(X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
)
2631 command_ok("window backgroundgrab %d\n",adesklets
.background_grab
);
2634 "background grab irrelevant - no X window connection or window\n");
2636 case CMD_WINDOW_GET_BACKGROUND_IMAGE
:
2637 /* prototype(void) */
2638 if(X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
)
2639 command_ok("background image %d\n",
2640 (adesklets
.user_background_image
!=-1)?
2641 adesklets
.user_background_image
:1);
2644 "background window irrelevant - no X window connection or window\n");
2646 case CMD_WINDOW_GET_MANAGED_STATUS
:
2647 /* prototype(void) */
2648 #ifndef X_DISPLAY_MISSING
2649 if(adesklets
.display
&& adesklets
.window
) {
2650 command_ok("window managedstatus %d (%s)\n",
2652 WINDOW_MANAGER
[adesklets
.managed
]);
2654 command_error("X connection or window missing\n");
2656 command_error("X connection or window missing\n");
2659 case CMD_WINDOW_SET_TRANSPARENCY
:
2660 /* prototype(bool transparency) */
2661 if (params
->pos
>=2) {
2662 i
=atoi((char*)params
->content
[1]);
2663 if (adesklets
.transparency
!=i
) {
2664 adesklets
.transparency
=i
;
2665 /* If there is a chance, invalidate the entire window */
2666 #ifndef X_DISPLAY_MISSING
2667 xwindow_window_size(adesklets
.display
,adesklets
.window
,
2669 updates
= imlib_update_append_rect(updates
,
2670 0,0,(int)width
,(int)height
);
2673 } else command_error("transparency value not given\n");
2675 case CMD_WINDOW_SET_BACKGROUND_GRAB
:
2676 /* prototype(bool grab) */
2677 if (params
->pos
>=2) {
2678 if (adesklets
.background_grab
!=(i
=atoi(params
->content
[1]))) {
2679 if ((adesklets
.background_grab
=i
))
2680 adesklets_images_reset_background(0);
2682 xwindow_context_save(IMLIB_IMAGE
|IMLIB_BLEND
|IMLIB_COLOR
);
2683 imlib_context_set_image(adesklets
.images
->content
[1]);
2684 imlib_context_set_color(0,0,0,255);
2685 imlib_context_set_blend(0);
2686 imlib_image_fill_rectangle(0,0,
2687 imlib_image_get_width(),
2688 imlib_image_get_height());
2689 xwindow_context_restore();
2692 #ifndef X_DISPLAY_MISSING
2693 xwindow_window_size(adesklets
.display
,adesklets
.window
,
2695 updates
= imlib_update_append_rect(updates
,
2696 0,0,(int)width
,(int)height
);
2700 command_error("background grab value not given\n");
2702 case CMD_WINDOW_SET_BACKGROUND_IMAGE
:
2703 /* prototype(int image) */
2704 if (X_DISPLAY_SUPPORT
&& adesklets
.display
&& adesklets
.window
) {
2705 if(params
->pos
>=2) {
2706 if((i
=atoi(params
->content
[1]))>=0 && i
<adesklets
.images
->pos
) {
2708 xwindow_context_save(IMLIB_IMAGE
);
2709 imlib_context_set_image(adesklets
.images
->content
[0]);
2710 j
=imlib_image_get_width();
2711 k
=imlib_image_get_height();
2713 imlib_context_set_image(adesklets
.images
->content
[i
]);
2714 x
=imlib_image_get_width();
2715 y
=imlib_image_get_height();
2717 adesklets
.user_background_image
=i
;
2718 updates
= imlib_update_append_rect(updates
,
2722 command_error("incorrect dimensions image\n");
2724 /* Drop silently reset to actual foreground */
2725 adesklets
.user_background_image
=-1;
2726 updates
= imlib_update_append_rect(updates
,
2729 xwindow_context_restore();
2732 "foreground image cannot be selected as background\n");
2734 command_error("image ID %d out of range\n",i
);
2736 command_error("background image ID not given\n");
2739 "background window irrelevant - no X window connection or window\n");
2741 case CMD_SCREEN_GET_WIDTH
:
2742 /* prototype(void) */
2743 #ifndef X_DISPLAY_MISSING
2744 if (adesklets
.display
) {
2745 command_ok("screen width %d\n",
2746 WidthOfScreen(ScreenOfDisplay(adesklets
.display
,
2747 adesklets
.params
->scr
)));
2749 command_error("X connection missing\n");
2751 command_error("X connection missing\n");
2754 case CMD_SCREEN_GET_HEIGHT
:
2755 /* prototype(void) */
2756 #ifndef X_DISPLAY_MISSING
2757 if(adesklets
.display
) {
2758 command_ok("screen height %d\n",
2759 HeightOfScreen(ScreenOfDisplay(adesklets
.display
,
2760 adesklets
.params
->scr
)));
2762 command_error("X connection missing\n");
2764 command_error("X connection missing\n");
2767 case CMD_SCREEN_GET_DEPTH
:
2768 /* prototype(void) */
2769 if(adesklets
.display
)
2770 command_ok("screen depth %d\n",adesklets
.depth
);
2772 command_error("X connection missing\n");
2774 case CMD_GET_CHARSET
:
2775 /* prototype(void) */
2777 if (command
.from_page
)
2778 command_ok("charset %s\n",command
.from_page
);
2781 command_ok("charset -1 (unset)\n");
2783 case CMD_SET_CHARSET
:
2784 /* prototype(const char * charset) */
2786 if (params
->pos
>=2) {
2787 if ((cd
=iconv_open("UTF8",params
->content
[1]))!=(iconv_t
)(-1)) {
2789 iconv_close(command
.cd
);
2792 if (command
.from_page
) {
2793 free(command
.from_page
);
2794 command
.from_page
=NULL
;
2796 command
.from_page
=dupstr(params
->content
[1]);
2799 command_error("could not establish conversion from '%s' to 'UTF8'\n",
2800 params
->content
[1]);
2803 iconv_close(command
.cd
);
2806 if (command
.from_page
) {
2807 free(command
.from_page
);
2808 command
.from_page
=NULL
;
2810 command_ok("charset -1 (unset)\n");
2813 command_error("charset conversion not compiled in\n");
2816 case CMD_CHARSET_STATUS
:
2817 /* prototype(void) */
2819 command_ok("charset_status 1\n");
2821 command_ok("charset_status 0 (charset conversion not compiled in)\n");
2825 /* prototype(void) */
2826 #ifndef X_DISPLAY_MISSING
2827 command_ok("x_status %d (%s%s')\n",(adesklets
.display
)?1:0,
2828 (adesklets
.display
)?"connected to '":"disconnected from '",
2829 XDisplayName(NULL
));
2831 command_ok("x_status 0 (X Window support not compiled in)\n");
2835 /* prototype(void) */
2836 command_ok("quitting...\n");
2837 adesklets
.quit_flag
=1;
2840 if(blank_line(command
.line
))
2841 command
.message_out
=1;
2843 command_error("syntax error\n");
2844 } /* switch(command_type) */
2845 } /* if command.recording */
2846 if (!command
.message_out
) command_ok("%s\n",command
.line
);
2847 vector_free(params
);
2849 command
.ready
=0; ++command
.rank
;
2850 if (command
.interactive
&& !command
.replay_pos
&&
2851 !adesklets
.quit_flag
&& !adesklets
.restart_flag
)
2852 command_interpreter_reset();
2853 } else {printf("\n"); adesklets
.quit_flag
=1;} /* if (command.line) */
2854 } /* if(command.ready) */
2856 #ifndef X_DISPLAY_MISSING
2857 while(adesklets
.display
&& adesklets
.window
&&
2858 (XCheckWindowEvent(adesklets
.display
,
2860 PropertyChangeMask
, &ev
) ||
2861 XCheckWindowEvent(adesklets
.display
,adesklets
.window
,
2862 adesklets
.event_mask
,&ev
) ||
2863 XCheckTypedWindowEvent(adesklets
.display
,adesklets
.window
,
2864 ClientMessage
,&ev
))) {
2867 /* Refresh updates list */
2868 updates
= imlib_update_append_rect(updates
,
2869 ev
.xexpose
.x
,ev
.xexpose
.y
,
2870 ev
.xexpose
.width
,ev
.xexpose
.height
);
2872 case PropertyNotify
:
2873 /* This event is generated from root window only:
2874 we use it to check for dynamic root window background change,
2875 as enlightment has used it for years. Look at
2876 xwindow_updated_background() for details */
2877 if (ev
.xproperty
.atom
!= None
&&
2878 ev
.xproperty
.atom
== XInternAtom (adesklets
.display
,
2879 "_XROOTPMAP_ID", True
) &&
2880 adesklets
.background_grab
&&
2881 xwindow_updated_background(adesklets
.display
,
2882 ev
.xproperty
.window
,
2884 /* Recompute the background images */
2885 adesklets_images_reset_background(0);
2887 /* Because the setting of background_pixmap as ParentRelative
2888 on the main window, there is no need to invalidate
2889 it here: an Expose event will be automatically generated. */
2892 /* Fire default menu on left button click */
2893 if(ev
.xbutton
.button
==3) {
2895 #ifdef CONTROL_ON_CONTEXT_MENU
2896 (ev
.xbutton
.state
& ControlMask
) &&
2898 (adesklets_menu_fire(0,&menu_str
)) &&
2899 (adesklets
.user_event_mask
&MenuFireMask
))
2900 event("menufire 0 %s\n",menu_str
);
2902 if(adesklets
.user_event_mask
&ButtonPressMask
)
2903 event("buttonpress %d %d %d\n",
2904 ev
.xbutton
.x
,ev
.xbutton
.y
,ev
.xbutton
.button
);
2908 if(ev
.xbutton
.button
!=3)
2909 event("buttonrelease %d %d %d\n",
2910 ev
.xbutton
.x
,ev
.xbutton
.y
,ev
.xbutton
.button
);
2913 event("motionnotify %d %d\n",
2914 ev
.xmotion
.x
, ev
.xmotion
.y
);
2917 event("enternotify %d %d\n",
2918 ev
.xcrossing
.x
, ev
.xcrossing
.y
);
2921 event("leavenotify %d %d\n",
2922 ev
.xcrossing
.x
, ev
.xcrossing
.y
);
2924 case ConfigureNotify
:
2925 if (ev
.xconfigure
.window
==adesklets
.window
)
2926 if (xwindow_window_moved_or_resized(ev
.xconfigure
.x
,
2928 ev
.xconfigure
.width
,
2929 ev
.xconfigure
.height
))
2930 adesklets_images_reset_background(0);
2933 /* Check for the "WM_WINDOW_DELETE" protocol */
2934 if (ev
.xclient
.data
.l
[0] == XInternAtom(adesklets
.display
,
2937 debug("Message from window manager: quitting!\n");
2938 adesklets
.user_quit_flag
=adesklets
.quit_flag
=1;
2940 debug("Unknown client message sent.");
2943 /* Untreated cases */
2948 /* Now, performs main window updates as needed */
2949 xwindow_update_window(adesklets
.window
, &updates
,
2950 adesklets
.images
->content
[
2951 (adesklets
.user_background_image
!=-1)?
2952 adesklets
.user_background_image
:1],
2953 adesklets
.images
->content
[0],
2954 adesklets
.transparency
);
2956 if(updates
) imlib_updates_free(updates
);
2958 } while(!adesklets
.quit_flag
&& !adesklets
.restart_flag
&&
2959 (command_replayer() || command_interpreter()));
2962 /*----------------------------------------------------------------------------*/
2963 int adesklets_free(void)
2968 debug("---------------------------------------------------------------\n");
2969 /* Ultimate update : take care of potential applet removal
2970 if user asked for it. */
2971 adesklets
.params
->no_update
|=adesklets
.user_quit_flag
;
2972 cfgfile_update(adesklets
.params
);
2974 /* X Windows cleanup */
2975 #ifndef X_DISPLAY_MISSING
2976 if(adesklets
.display
) {
2977 if(adesklets
.window
) {
2978 XUnmapWindow(adesklets
.display
,adesklets
.window
);
2979 XDestroyWindow(adesklets
.display
,adesklets
.window
);
2981 XCloseDisplay(adesklets
.display
);
2985 /* For terminal reset, if it was not cleanly performed
2986 (will happen when quitting from the default left click
2987 menu, for instance) */
2988 rl_callback_handler_remove();
2990 /* Send SIGTERM notification signal to parent process:
2991 in all case but restart, adesklets do not
2992 go further to ensure parent termination. */
2993 kill(adesklets
.ppid
,SIGTERM
);
2995 /* if Lock exist: handle possible restart */
2996 if(adesklets
.lock
) {
2997 if(adesklets
.restart_flag
) {
2998 /* Wait for adesklets parent process to exit
2999 SIGKILL_TIMEOUT seconds, then send a SIGKILL. */
3000 for(i
=0;i
<SIGKILL_TIMEOUT
&& adesklets
.ppid
==getppid();++i
)
3002 if (i
==SIGKILL_TIMEOUT
) kill(adesklets
.ppid
,SIGKILL
);
3003 while(adesklets
.ppid
==getppid()) sleep(1);
3005 /* Redirect stdout and stderr to /dev/null to avoid
3006 output buffer overflow */
3007 if ((fd_null
=open("/dev/null",O_WRONLY
))>=0) {
3012 execl(adesklets
.params
->applet
,
3013 adesklets
.params
->applet
,
3015 /* debug("Restart: could not exec `%s'",adesklets.params->applet); */
3020 /* Release the lock */
3021 lock
.l_type
=F_UNLCK
;
3022 lock
.l_whence
=SEEK_SET
;
3025 fcntl(fileno(adesklets
.lock
),F_SETLK
,&lock
);
3026 fclose(adesklets
.lock
);
3028 /* Try to unlink the lock file:
3029 thanks to POSIX, this will fail gracefully
3030 if a process is still using the file */
3031 unlink(adesklets
.lock_filename
);
3034 /* Free structures */
3035 if(events
) vector_free(events
);
3036 adesklets
.menus
=vector_free(adesklets
.menus
);
3037 adesklets
.images
=vector_free(adesklets
.images
);
3038 adesklets
.fonts
=vector_free(adesklets
.fonts
);
3039 adesklets
.color_ranges
=vector_free(adesklets
.color_ranges
);
3040 adesklets
.color_modifiers
=vector_free(adesklets
.color_modifiers
);
3041 adesklets
.filters
=vector_free(adesklets
.filters
);
3042 adesklets
.polygons
=vector_free(adesklets
.polygons
);
3043 adesklets
.variables
=vector_free(adesklets
.variables
);
3045 return !adesklets
.menus
&&
3046 !adesklets
.images
&&
3048 !adesklets
.color_ranges
&&
3049 !adesklets
.color_modifiers
&&
3050 !adesklets
.filters
&&
3051 !adesklets
.polygons
&&
3052 !adesklets
.variables
;
3055 /*----------------------------------------------------------------------------*/
3056 /* Signal wrapper for adesklets_free()
3059 termination_handler(int signum
)
3061 exit((adesklets_free())?EXIT_SUCCESS
:EXIT_FAILURE
);
3064 /*----------------------------------------------------------------------------*/
3065 /* Since we cannot verify if applet is a script of a binary without trying
3066 to execute it, we require it to have both read and execute permissions for
3067 the current user... Better _portable_ solution is welcomed.
3070 adesklets_valid_desklet(char * applet
, int register_flag
)
3075 if((register_flag
&& applet
[0]=='/') || !register_flag
)
3076 result
=(access(applet
,R_OK
|X_OK
)==0);
3080 /*----------------------------------------------------------------------------*/
3081 /* Our image generator function (have a look at command.c) */
3083 image_generator(const char * text
, int state
)
3085 return generic_index_generator(text
,state
,adesklets
.images
->pos
);
3088 /*----------------------------------------------------------------------------*/
3089 /* Our font name generator function (have a look at command.c) */
3091 base_font_generator(const char * text
, int state
)
3095 static char ** fonts
;
3098 fonts
=imlib_list_fonts(&number
);
3100 if(!(result
=generic_generator(text
,state
,fonts
,number
))) {
3101 imlib_free_font_list(fonts
,number
);
3106 /*----------------------------------------------------------------------------*/
3108 base_font_path_generator(const char * text
, int state
)
3111 static char ** font_path
;
3114 font_path
=imlib_list_font_path(&number
);
3116 return generic_generator(text
,state
,font_path
,number
);
3119 /*----------------------------------------------------------------------------*/
3121 font_generator (const char * text
, int state
)
3123 return generic_index_generator(text
,state
,adesklets
.fonts
->pos
);
3126 /*----------------------------------------------------------------------------*/
3128 font_generator_with_null (const char * text
, int state
)
3130 return generic_index_generator_with_null(text
,state
,adesklets
.fonts
->pos
);
3133 /*----------------------------------------------------------------------------*/
3134 /* Our menu generator function (have a look at command.c) */
3136 menu_generator(const char * text
, int state
)
3138 return generic_index_generator(text
,state
,adesklets
.menus
->pos
);
3141 /*----------------------------------------------------------------------------*/
3142 /* Our color ranges generator function (have a look at command.c) */
3144 color_range_generator(const char * text
, int state
)
3146 return generic_index_generator(text
,state
,adesklets
.color_ranges
->pos
);
3149 /*----------------------------------------------------------------------------*/
3150 /* Our color ranges generator function (have a look at command.c) */
3152 color_range_generator_with_null(const char * text
, int state
)
3154 return generic_index_generator_with_null(text
,state
,
3155 adesklets
.color_ranges
->pos
);
3158 /*----------------------------------------------------------------------------*/
3159 /* Our color modifiers generator function (have a look at command.c) */
3161 color_modifier_generator(const char * text
, int state
)
3163 return generic_index_generator(text
,state
,adesklets
.color_modifiers
->pos
);
3166 /*----------------------------------------------------------------------------*/
3167 /* Our color modifiers generator function (have a look at command.c) */
3169 color_modifier_generator_with_null(const char * text
, int state
)
3171 return generic_index_generator_with_null(text
,state
,
3172 adesklets
.color_modifiers
->pos
);
3175 /*----------------------------------------------------------------------------*/
3176 /* Our filters generator function (have a look at command.c) */
3178 filter_generator(const char * text
, int state
)
3180 return generic_index_generator(text
,state
,adesklets
.filters
->pos
);
3183 /*----------------------------------------------------------------------------*/
3184 /* Our filters generator function (have a look at command.c) */
3186 filter_generator_with_null(const char * text
, int state
)
3188 return generic_index_generator_with_null(text
,state
,
3189 adesklets
.filters
->pos
);
3192 /*----------------------------------------------------------------------------*/
3193 /* Our polygon generator function (have a look at command.c) */
3195 polygon_generator(const char * text
, int state
)
3197 return generic_index_generator(text
,state
,adesklets
.polygons
->pos
);
3200 /*----------------------------------------------------------------------------*/
3201 /* We have to put this generator here because variables vector is part of
3202 the adesklets structure */
3204 variable_generator(const char * text
, int state
)
3206 static int list_index
, len
;
3214 while (list_index
<adesklets
.variables
->pos
) {
3215 name
=((var_item
*)adesklets
.variables
->content
[list_index
])->name
;
3217 if(strncmp(name
,text
,len
)==0)
3218 return dupstr(name
);
3224 /*----------------------------------------------------------------------------*/
3226 /* Generic generator mecanism: used for different wrappers.*/
3228 char * generic_generator(const char * text, int state,
3229 char ** names, int number)
3231 static int list_index, len;
3239 while((number==-1 || list_index<number) &&
3240 (name=names[list_index])) {
3242 if(strncmp(name,text,len)==0)
3243 return(dupstr(name));