Git init
[framework/uifw/xorg/libslp-utilx.git] / x11.c
1 /*
2  * libslp-utilx
3  *
4    Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24
25 #include <X11/Xlib.h>
26 #include <X11/Xatom.h>
27
28 #include "utilX.h"
29 #include "util_x11.h"
30
31
32 #define UTILX_DEBUG 0
33 #if UTILX_DEBUG
34 #define UTILX_TRACE  printf
35 #else
36 #define UTILX_TRACE(...)
37 #endif
38
39 static Atom _atom_grab_key = None;
40 static Atom _atom_grab_excl_win = None;
41 static Atom _atom_grab_or_excl_win = None;
42
43 static Atom _atom_notification_level = None;
44 static Atom _atom_indicator_visible_state = None;
45
46 static Atom _atom_comp_effect_state = None;
47 static Atom _atom_comp_fake_launch = None;
48 static Atom _atom_comp_fake_launch_image = None;
49
50 static Atom _atom_comp_window_effect_type = None;
51 static Atom _atom_comp_effect_default = None;
52 static Atom _atom_comp_effect_none = None;
53 static Atom _atom_comp_effect_custom0 = None;
54 static Atom _atom_comp_effect_custom1 = None;
55 static Atom _atom_comp_effect_custom2 = None;
56 static Atom _atom_comp_effect_custom3 = None;
57 static Atom _atom_comp_effect_custom4 = None;
58 static Atom _atom_comp_effect_custom5 = None;
59 static Atom _atom_comp_effect_custom6 = None;
60 static Atom _atom_comp_effect_custom7 = None;
61 static Atom _atom_comp_effect_custom8 = None;
62 static Atom _atom_comp_effect_custom9 = None;
63
64 static Atom _atom_window_opaque = None;
65
66 static Atom _atom_screen_capture_disable = None;
67
68 static Atom _atom_comp_capture_effect = None;
69
70 const unsigned long maxlen = 1024l;
71
72 static void _utilx_set_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int num);
73 static int _utilx_get_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len);
74
75 static void _utilx_effect_atom_check( Display* dpy );
76 static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style );
77 static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style );
78
79 API void utilx_set_system_notification_level (Display* dpy, Window win, Utilx_Notification_Level level)
80 {
81         UTILX_TRACE ("[UTILX] utilx_set_system_notification_level... win = %x, level = %d\n", win, level);
82
83         int noti_level;
84
85         if (dpy == NULL)
86         {
87                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
88                 return;
89         }
90
91         switch (level)
92         {
93                 case UTILX_NOTIFICATION_LEVEL_LOW:
94                         noti_level = 50;
95                         break;
96
97                 case UTILX_NOTIFICATION_LEVEL_NORMAL:
98                         noti_level = 100;
99                         break;
100
101                 case UTILX_NOTIFICATION_LEVEL_HIGH:
102                         noti_level = 150;
103                         break;
104
105                 default:
106                         noti_level = 50;
107                         break;
108         }
109
110         if (!_atom_notification_level)
111         {
112                 _atom_notification_level = XInternAtom (dpy, "_E_ILLUME_NOTIFICATION_LEVEL", False);
113                 if (!_atom_notification_level)
114                 {
115                         fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_NOTIFICATION_LEVEL atom.. %s (%d)\n", __func__, __LINE__);
116                         return;
117                 }
118         }
119
120         _utilx_set_window_property (dpy, win, _atom_notification_level, XA_CARDINAL,
121                         (unsigned int *)&noti_level, 1);
122 }
123
124
125 API Utilx_Notification_Level utilx_get_system_notification_level (Display* dpy, Window win)
126 {
127         UTILX_TRACE ("[UTILX] utilx_get_system_notification_level... win = %x\n", win);
128
129         Utilx_Notification_Level noti_level;
130         unsigned int level;
131         int ret;
132
133         noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
134
135         if (dpy == NULL)
136         {
137                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
138                 goto error;
139         }
140
141         if (!_atom_notification_level)
142         {
143                 _atom_notification_level = XInternAtom (dpy, "_E_ILLUME_NOTIFICATION_LEVEL", False);
144                 if (!_atom_notification_level)
145                 {
146                         fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_NOTIFICATION_LEVEL atom.. %s (%d)\n", __func__, __LINE__);
147                         goto error;
148                 }
149         }
150
151         ret = _utilx_get_window_property (dpy, win, _atom_notification_level, XA_CARDINAL,
152                         (unsigned int *)&level, 1);
153
154         if (ret > 0)
155         {
156                 switch (level)
157                 {
158                         case 50:
159                                 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
160                                 break;
161
162                         case 100:
163                                 noti_level = UTILX_NOTIFICATION_LEVEL_NORMAL;
164                                 break;
165
166                         case 150:
167                                 noti_level = UTILX_NOTIFICATION_LEVEL_HIGH;
168                                 break;
169
170                         default:
171                                 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
172                                 break;
173                 }
174         }
175         else
176         {
177                 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
178         }
179
180 error:
181         return noti_level;
182 }
183
184
185 API void utilx_enable_indicator (Display* dpy, Window win, int enable)
186 {
187         UTILX_TRACE ("[UTILX] utilx_indicator_set_visible_state... win = %x, show_state = %d\n", win, enable);
188
189         if (dpy == NULL)
190         {
191                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
192                 return;
193         }
194
195         if (!_atom_indicator_visible_state)
196         {
197                 _atom_indicator_visible_state = XInternAtom (dpy, "_E_ILLUME_INDICATOR_STATE", False);
198                 if (!_atom_indicator_visible_state)
199                 {
200                         fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_STATE atom.. %s (%d)\n", __func__, __LINE__);
201                         return;
202                 }
203         }
204
205         _utilx_set_window_property (dpy, win, _atom_indicator_visible_state, XA_CARDINAL,
206                         (unsigned int *)&enable, 1);
207 }
208
209
210 API int utilx_get_indicator_state (Display* dpy, Window win)
211 {
212         UTILX_TRACE ("[UTILX] utilx_indicator_set_visible_state... win = %x, show_state = %d\n", win, enable);
213
214         int ret;
215         int state;
216
217         if (dpy == NULL)
218         {
219                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
220                 return -1;
221         }
222
223         if (!_atom_indicator_visible_state)
224         {
225                 _atom_indicator_visible_state = XInternAtom (dpy, "_E_ILLUME_INDICATOR_STATE", False);
226                 if (!_atom_indicator_visible_state)
227                 {
228                         fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_STATE atom.. %s (%d)\n", __func__, __LINE__);
229                         return -1;
230                 }
231         }
232
233         ret = _utilx_get_window_property (dpy, win, _atom_indicator_visible_state, XA_CARDINAL,
234                         (unsigned int *)&state, 1);
235
236         if (ret > 0)
237                 return state;
238         else
239                 return -1;
240 }
241
242 static void
243 _utilx_set_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int num)
244 {
245         XChangeProperty (dpy, win, atom, type, 32, PropModeReplace, (unsigned char *)val, num);
246         XSync(dpy, 0 );
247 }
248
249
250 static int
251 _utilx_get_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len)
252 {
253         unsigned char* prop_ret;
254         Atom type_ret;
255         unsigned long bytes_after, num_ret;
256         int format_ret;
257         unsigned int i;
258         int num;
259
260         prop_ret = NULL;
261         if (XGetWindowProperty(dpy, win, atom, 0, 0x7fffffff, False,
262                                 type, &type_ret, &format_ret, &num_ret,
263                                 &bytes_after, &prop_ret) != Success)
264         {
265                 return -1;
266         }
267
268         if (type_ret != type || format_ret != 32)
269         {
270                 num = -1;
271         }
272         else if (num_ret == 0 || !prop_ret)
273         {
274                 num = 0;
275         }
276         else
277         {
278                 if (num_ret < len)
279                 len = num_ret;
280                 for (i = 0; i < len; i++)
281                 {
282                         val[i] = ((unsigned long *)prop_ret)[i];
283                 }
284                 num = len;
285         }
286
287         if (prop_ret)
288                 XFree(prop_ret);
289
290         return num;
291
292 }
293
294
295 static unsigned long _get_list_of_grabbed_key (Display *disp, Window win, int **key_list)
296 {
297         Atom ret_type;
298         int ret_format;
299         unsigned long nr_item;
300         unsigned long sz_remains_data;
301
302         if (XGetWindowProperty(disp, win,
303                 _atom_grab_key, 0, 0x7fffffff, False, XA_CARDINAL,
304                 &ret_type, &ret_format, &nr_item,
305                 &sz_remains_data, (unsigned char**)key_list) != Success)
306         {
307                 nr_item = 0;
308         }
309
310 //      fprintf(stderr, "\e[31m%d - %lu\e[0m\n", ret_format, nr_item);
311
312         return nr_item;
313 }
314
315
316 static void _free_list_of_grabbed_key (int *key_list)
317 {
318         if (key_list) {
319                 XFree(key_list);
320         }
321 }
322
323
324 static void _free_new_list_of_grabbed_key (int *new_key_list)
325 {
326         if (new_key_list) {
327                 free(new_key_list);
328         }
329 }
330
331
332 static int _search_grabbed_key (int *key_list, int key, unsigned long cnt)
333 {
334         register int i;
335
336         for (i = cnt - 1; i >= 0; i --) {
337                 if (key_list[i] == key) break;
338         }
339
340         return i;
341 }
342
343
344 static int *_del_grabbed_key (int *key_list, int i, unsigned long *cnt)
345 {
346         int *new_key_list = NULL;
347
348         // Only one element is exists in the list of grabbed key
349         (*cnt) --;
350
351         if (*cnt == 0) return NULL;
352
353         // Shrink the buffer
354         new_key_list = malloc((*cnt) * sizeof(int));
355         if (new_key_list == NULL) {
356                 perror(__func__);
357                 return NULL;
358         }
359
360         // copy head
361         if (i > 0) {
362                 memcpy(new_key_list, key_list, sizeof(int) * i);
363         }
364
365         // copy tail
366         if ((*cnt) - i > 0) {
367                 memcpy(new_key_list + i,
368                         key_list + i + 1,
369                         sizeof(int) * ((*cnt) - i)
370                 );
371         }
372         return new_key_list;
373 }
374
375
376 static void _set_exclusive_grab_info_to_root (Display *disp, int keycode, Window win, int grab_mode)
377 {
378         int *key_list = NULL;
379
380         Atom ret_type;
381         int ret_format;
382         unsigned long nr_item;
383         unsigned long sz_remains_data;
384         Window ex_grabwin;
385
386         if( grab_mode == EXCLUSIVE_GRAB )
387         {
388                 if( _atom_grab_excl_win == None )
389                         _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
390                 ex_grabwin = _atom_grab_excl_win;
391         }
392         else if( grab_mode == OR_EXCLUSIVE_GRAB )
393         {
394                 if( _atom_grab_or_excl_win == None )
395                         _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
396                 ex_grabwin = _atom_grab_or_excl_win;
397         }
398         else
399                 return;
400
401         if (XGetWindowProperty(disp, DefaultRootWindow(disp),
402                 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
403                 &ret_type, &ret_format, &nr_item,
404                 &sz_remains_data, (unsigned char**)&key_list) != Success)
405         {
406                 fprintf(stderr, "[utilX][%s] Fail to get root window property !\n", __FUNCTION__);
407                 goto out;
408         }
409
410 #if 1//def __DEBUG__
411         printf("[%s] keycode = %d\n", __FUNCTION__, keycode);
412 #endif
413
414         XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
415         nr_item ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
416         XSync(disp, False);
417
418 out:
419         return;
420 }
421
422
423 static void _unset_exclusive_grab_info_to_root (Display *disp, int keycode, int grab_mode)
424 {
425         int i;
426         unsigned long cnt = 0;
427         int *key_list = NULL;
428         int *new_key_list = NULL;
429
430         Atom ret_type;
431         int ret_format;
432         unsigned long nr_item;
433         unsigned long sz_remains_data;
434         Window ex_grabwin;
435
436         if( grab_mode == EXCLUSIVE_GRAB )
437         {
438                 if( _atom_grab_excl_win == None )
439                         _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
440                 ex_grabwin = _atom_grab_excl_win;
441         }
442         else if( grab_mode == OR_EXCLUSIVE_GRAB )
443         {
444                 if( _atom_grab_or_excl_win == None )
445                         _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
446                 ex_grabwin = _atom_grab_or_excl_win;
447         }
448         else
449                 return;
450
451         if (XGetWindowProperty(disp, DefaultRootWindow(disp),
452                 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
453                 &ret_type, &ret_format, &nr_item,
454                 &sz_remains_data, (unsigned char**)&key_list) != Success)
455         {
456                 nr_item = 0;
457         }
458
459         if (nr_item == 0)
460         {
461                 fprintf(stderr, "\e[32m[utilX][%s] keycode = %d\e[0m\n", __FUNCTION__, keycode);
462                 goto out;
463         }
464
465         for( i=0 ; i < nr_item ; i++ )
466         {
467                 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
468                 {
469                         continue;
470                 }
471                 cnt++;
472         }
473
474 #ifdef __DEBUG__
475         fprintf(stderr, "[utilX][%s] cnt = %d, nr_item = %d\n", __FUNCTION__, cnt, nr_item);
476 #endif
477
478         if( 0 < cnt )
479         {
480                 new_key_list = malloc(sizeof(int)*cnt);
481                 cnt = 0;
482         }
483         else
484                 new_key_list = NULL;
485
486         if( !new_key_list )
487         {
488                 //fprintf(stderr, "\e[32m[utilX][%s] Fail to allocation memory for new_key_list ! \e[0m\n", __FUNCTION__);
489                 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
490                 XSync(disp, False);
491                 goto out;
492         }
493
494         for( i=0 ; i < nr_item ; i++ )
495         {
496                 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
497                 {
498                         continue;
499                 }
500                 else
501                         new_key_list[cnt++] = key_list[i];
502         }
503
504         if (new_key_list) {
505                 XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
506                         PropModeReplace, (unsigned char *)new_key_list, cnt);
507         }
508         else {
509                 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
510         }
511         XSync(disp, False);
512
513         if(new_key_list)
514                 free(new_key_list);
515
516 out:
517         return;
518 }
519
520
521 static int _is_grabbed_key_exclusively (Display* disp, int keycode, int grab_mode)
522 {
523         int i, result = 0;
524         int *key_list = NULL;
525
526         Atom ret_type;
527         int ret_format;
528         unsigned long nr_item;
529         unsigned long sz_remains_data;
530         Window ex_grabwin;
531
532         if( grab_mode == EXCLUSIVE_GRAB )
533         {
534                 if( _atom_grab_excl_win == None )
535                         _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
536                 ex_grabwin = _atom_grab_excl_win;
537         }
538         else if( grab_mode == OR_EXCLUSIVE_GRAB )
539         {
540                 if( _atom_grab_or_excl_win == None )
541                         _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
542                 ex_grabwin = _atom_grab_or_excl_win;
543         }
544         else
545                 return result;
546
547         if (XGetWindowProperty(disp, DefaultRootWindow(disp),
548                 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
549                 &ret_type, &ret_format, &nr_item,
550                 &sz_remains_data, (unsigned char**)&key_list) != Success)
551         {
552                 fprintf(stderr, "[%s] Fail to get root window property !\n", __FUNCTION__);
553                 goto out;
554         }
555
556         for( i=0 ; i < nr_item ; i++ )
557         {
558                 if( key_list[i] == keycode )
559                         return EXCLUSIVE_GRABBED_ALREADY;
560         }
561
562 out:
563         return result;
564 }
565
566 API int utilx_grab_key (Display* disp, Window win, const char* key, int grab_mode)
567 {
568         unsigned long cnt;
569         int *key_list = NULL;
570         int i, result = 0;
571         int keycode = 0;
572         KeySym keysym;
573         errno = EINVAL;
574
575         if( NULL == disp )
576         {
577                 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
578                 return -1;
579         }
580
581         if (_atom_grab_key == None) {
582                 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
583         }
584
585         if (!strncmp(key, "Keycode-", 8)) {
586                 keycode = atoi(key + 8);
587         } else {
588                 keysym = XStringToKeysym(key);
589                 if (keysym == NoSymbol) goto out;
590                 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
591         }
592         if (keycode == 0) goto out;
593
594         if( grab_mode == EXCLUSIVE_GRAB )
595         {
596                 //Window grabWin;
597                 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
598
599 #ifdef __DEBUG__
600                 printf("[%s] _is_grabbed_key_exclusively returns result = %d\n", __FUNCTION__, result);
601 #endif
602
603                 if( result )
604                 {
605                         fprintf(stderr, "[%s] keycode(%d) was already grabbed exclusively (grab_mode=0x%X) !\n", __FUNCTION__, keycode, grab_mode);
606                         goto out;
607                 }
608         }
609         else if( grab_mode == OR_EXCLUSIVE_GRAB )
610         {
611                 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
612
613                 if( result )
614                 {
615                         fprintf(stderr, "[%s] Keycode(%d) was already grabbed with overridable exclusive mode (grab_mode=0x%x)\n", __FUNCTION__, keycode, grab_mode);
616                         fprintf(stderr, "[%s] Now it will be overridden by a new window(0x%x) !\n", __FUNCTION__, win);
617                         utilx_ungrab_key(disp, win, key);
618                 }
619         }
620
621         keycode |= grab_mode;
622
623         cnt = _get_list_of_grabbed_key(disp, win, &key_list);
624         if (cnt > 0) {
625                 i = _search_grabbed_key(key_list, keycode, cnt);
626                 _free_list_of_grabbed_key(key_list);
627                 if ( i != -1 ) {
628                         fprintf(stderr, "Key is already grabbed\n");
629                         goto out;
630                 }
631         }
632
633         XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
634                         cnt ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
635         XSync(disp, False);
636         keycode = keycode & (~GRAB_MODE_MASK);
637 #ifdef __DEBUG__
638         printf("[%s] keycode = %d\n", __FUNCTION__, keycode);
639 #endif
640
641         if( EXCLUSIVE_GRAB == grab_mode || OR_EXCLUSIVE_GRAB == grab_mode )
642                 _set_exclusive_grab_info_to_root(disp, keycode, win, grab_mode);
643
644         errno = 0;
645
646 out:
647
648         return result;
649 }
650
651
652 API int utilx_ungrab_key (Display* disp, Window win, const char* key)
653 {
654         int i;
655         unsigned long cnt;
656         int *key_list = NULL;
657         int *new_key_list = NULL;
658         long keycode = 0;
659         KeySym keysym;
660         int ret = -1;
661         errno = EINVAL;
662
663         if( NULL == disp )
664         {
665                 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
666                 return -1;
667         }
668
669         if (_atom_grab_key == None) {
670                 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
671         }
672
673         if (!strncmp(key, "Keycode-", 8)) {
674                 keycode = atoi(key + 8);
675         } else {
676                 keysym = XStringToKeysym(key);
677                 if (keysym == NoSymbol) goto out;
678                 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
679         }
680         if (keycode == 0) goto out;
681
682         cnt = _get_list_of_grabbed_key(disp, win, &key_list);
683         if (cnt == 0) goto out;
684
685         //EXCLUSIVE mode
686         i = _search_grabbed_key(key_list, keycode | EXCLUSIVE_GRAB, cnt);
687
688         if ( i == -1)
689         {
690                 //OR_EXCLUSIVE mode
691                 i = _search_grabbed_key(key_list, keycode | OR_EXCLUSIVE_GRAB, cnt);
692
693                 if ( i == -1)
694                 {
695                         //TOP_POSITION mode
696                         i = _search_grabbed_key(key_list, keycode | TOP_POSITION_GRAB, cnt);
697
698                         if (i == -1)
699                         {
700                                 //SHARED mode
701                                 i = _search_grabbed_key(key_list, keycode | SHARED_GRAB, cnt);
702
703                                 if (i == -1)
704                                 {
705                                         _free_list_of_grabbed_key(key_list);
706                                         goto out;
707                                 }
708                         }
709                 }
710                 else
711                 {
712                         _unset_exclusive_grab_info_to_root(disp, keycode, OR_EXCLUSIVE_GRAB);
713                 }
714         }
715         else
716         {
717                 _unset_exclusive_grab_info_to_root(disp, keycode, EXCLUSIVE_GRAB);
718         }
719
720         new_key_list = _del_grabbed_key(key_list, i, &cnt);
721         _free_list_of_grabbed_key(key_list);
722
723         if (new_key_list) {
724                 XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
725                         PropModeReplace, (unsigned char *)new_key_list, cnt);
726         }
727         else {
728                 XDeleteProperty(disp, win, _atom_grab_key);
729         }
730         XSync(disp, False);
731
732         _free_new_list_of_grabbed_key(new_key_list);
733         ret = 0;
734         errno = 0;
735
736 out:
737
738         return ret;
739 }
740
741 API Utilx_Key_Status utilx_get_key_status(Display* dpy, char *key_name)
742 {
743         unsigned char keymap[32];
744         static unsigned int masktable[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
745         Utilx_Key_Status status = UTILX_KEY_STATUS_UNKNOWN;
746
747         if( !strncmp(key_name, KEY_VOLUMEDOWN, LEN_KEY_VOLUMEDOWN) ||
748                 !strncmp(key_name, KEY_VOLUMEUP, LEN_KEY_VOLUMEUP) ||
749                 !strncmp(key_name, KEY_PAUSE, LEN_KEY_PAUSE) ||
750                 !strncmp(key_name, KEY_SEND, LEN_KEY_SEND) ||
751                 !strncmp(key_name, KEY_SELECT, LEN_KEY_VOLUMEDOWN) ||
752                 !strncmp(key_name, KEY_END, LEN_KEY_END) ||
753                 !strncmp(key_name, KEY_POWER, LEN_KEY_POWER) ||
754                 !strncmp(key_name, KEY_CAMERA, LEN_KEY_CAMERA) ||
755                 !strncmp(key_name, KEY_CONFIG, LEN_KEY_CONFIG) ||
756                 !strncmp(key_name, KEY_PLAYCD, LEN_KEY_PLAYCD) ||
757                 !strncmp(key_name, KEY_STOPCD, LEN_KEY_STOPCD) ||
758                 !strncmp(key_name, KEY_PAUSECD, LEN_KEY_PAUSECD) ||
759                 !strncmp(key_name, KEY_NEXTSONG, LEN_KEY_NEXTSONG) ||
760                 !strncmp(key_name, KEY_PREVIOUSSONG, LEN_KEY_PREVIOUSSONG) ||
761                 !strncmp(key_name, KEY_REWIND, LEN_KEY_REWIND) ||
762                 !strncmp(key_name, KEY_FASTFORWARD, LEN_KEY_FASTFORWARD) )
763         {
764                 KeySym ks = XStringToKeysym(key_name);
765                 KeyCode kc = XKeysymToKeycode(dpy, ks);
766
767                 if( kc )
768                 {
769                         XQueryKeymap(dpy, (char *)keymap);
770                         if( keymap[kc >> 3] & masktable[kc & 7] )
771                                 status = UTILX_KEY_STATUS_PRESSED;
772                         else
773                                 status = UTILX_KEY_STATUS_RELEASED;
774                 }
775         }
776
777         return status;
778 }
779
780 API void utilx_set_window_effect_state(Display* dpy, Window win, int state)
781 {
782         if ( dpy == NULL )
783         {
784                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
785                 return;
786         }
787         if( !_atom_comp_effect_state)
788                 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
789
790         _utilx_set_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
791
792         XSync(dpy, 0 );
793 }
794
795 API int utilx_get_window_effect_state(Display* dpy, Window win)
796 {
797         int state = 0;
798         if( !_atom_comp_effect_state)
799                 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
800         _utilx_get_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
801         return state;
802 }
803
804 static void
805 _utilx_string_set_window_property( Display *dpy, Window win, Atom atom, char *val, unsigned int num)
806 {
807         XChangeProperty( dpy, win, atom, XA_STRING, 8, PropModeReplace, (unsigned char*)val, val ? strlen(val):0 );
808 }
809
810 API void utilx_set_fake_launch_img(Display* dpy, Window win, char *file_name)
811 {
812         //UTILX_TRACE ("[UTILX] utilx_set_effect_state... win = %x, show_state = %d\n", win, enable);
813
814         if ( dpy == NULL )
815         {
816                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
817                 return;
818         }
819         if( !_atom_comp_fake_launch_image)
820                 _atom_comp_fake_launch_image = XInternAtom(dpy, "_E_COMP_FAKE_LAUNCH_IMAGE",False);
821
822         _utilx_string_set_window_property(dpy, win, _atom_comp_fake_launch_image, file_name, 1);
823 }
824
825 API void utilx_show_fake_effect( Display *dpy, Window win, char *fake_image_file )
826 {
827         XEvent xev;
828
829         _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
830
831         if(  !_atom_comp_fake_launch )
832         {
833                 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
834                 return;
835         }
836
837         utilx_set_fake_launch_img(dpy, win, fake_image_file);
838
839         XSync(dpy, 0 );
840
841         // send fake client message
842         xev.xclient.type = ClientMessage;
843         xev.xclient.display = dpy;
844         xev.xclient.window = win;
845         xev.xclient.message_type =  _atom_comp_fake_launch;
846         xev.xclient.format = 32;
847         xev.xclient.data.l[0] = 1;  // 1 : start effect , 0 : end effect
848         xev.xclient.data.l[1] = 0;
849         xev.xclient.data.l[2] = 0;
850         xev.xclient.data.l[3] = 0;
851         xev.xclient.data.l[4] = 0;
852
853         XSendEvent( dpy, win, False,
854                                 SubstructureRedirectMask | SubstructureNotifyMask,
855                                 &xev );
856         XSync(dpy, 0 );
857
858 }
859
860
861 API void utilx_hide_fake_effect( Display *dpy, Window win)
862 {
863         XEvent xev;
864
865         _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
866         if(  !_atom_comp_fake_launch )
867         {
868                 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
869                 return;
870         }
871
872         // send fake client message
873         xev.xclient.type = ClientMessage;
874         xev.xclient.display = dpy;
875         xev.xclient.window = win;
876         xev.xclient.message_type =  _atom_comp_fake_launch;
877         xev.xclient.format = 32;
878         xev.xclient.data.l[0] = 0;  // 1 : start effect , 0 : end effect
879         xev.xclient.data.l[1] = 0;
880         xev.xclient.data.l[2] = 0;
881         xev.xclient.data.l[3] = 0;
882         xev.xclient.data.l[4] = 0;
883
884         XSendEvent( dpy, win, False,
885                                 SubstructureRedirectMask | SubstructureNotifyMask,
886                                 &xev );
887         XSync(dpy, 0 );
888 }
889
890 static void _utilx_effect_atom_check( Display* dpy )
891 {
892         if ( dpy == NULL )
893         {
894                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
895                 return;
896         }
897
898         if( !_atom_comp_window_effect_type)
899                 _atom_comp_window_effect_type =  XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_TYPE",False);
900         if( !_atom_comp_effect_default )
901                 _atom_comp_effect_default = XInternAtom(dpy, "_NET_CM_EFFECT_DEFAULT",False);
902         if( !_atom_comp_effect_none )
903                 _atom_comp_effect_none = XInternAtom(dpy, "_NET_CM_EFFECT_NONE",False);
904         if( !_atom_comp_effect_custom0 )
905                 _atom_comp_effect_custom0 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM0",False);
906         if( !_atom_comp_effect_custom1 )
907                 _atom_comp_effect_custom1 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM1",False);
908         if( !_atom_comp_effect_custom2 )
909                 _atom_comp_effect_custom2 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM2",False);
910         if( !_atom_comp_effect_custom3 )
911                 _atom_comp_effect_custom3 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM3",False);
912         if( !_atom_comp_effect_custom4 )
913                 _atom_comp_effect_custom4 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM4",False);
914         if( !_atom_comp_effect_custom5 )
915                 _atom_comp_effect_custom5 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM5",False);
916         if( !_atom_comp_effect_custom6 )
917                 _atom_comp_effect_custom6 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM6",False);
918         if( !_atom_comp_effect_custom7 )
919                 _atom_comp_effect_custom7 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM7",False);
920         if( !_atom_comp_effect_custom8 )
921                 _atom_comp_effect_custom8 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM8",False);
922         if( !_atom_comp_effect_custom9 )
923                 _atom_comp_effect_custom9 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM9",False);
924 }
925
926 static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style )
927 {
928         if ( dpy == NULL )
929         {
930                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
931                 return _atom_comp_effect_none;
932         }
933         _utilx_effect_atom_check(dpy);
934
935         if ( style == UTILX_EFFECT_STYLE_DEFAULT )       return _atom_comp_effect_default;
936         else if ( style == UTILX_EFFECT_STYLE_NONE )     return _atom_comp_effect_none;
937         else if ( style == UTILX_EFFECT_STYLE_CUSTOM0 )  return _atom_comp_effect_custom0;
938         else if ( style == UTILX_EFFECT_STYLE_CUSTOM1 )  return _atom_comp_effect_custom1;
939         else if ( style == UTILX_EFFECT_STYLE_CUSTOM2 )  return _atom_comp_effect_custom2;
940         else if ( style == UTILX_EFFECT_STYLE_CUSTOM3 )  return _atom_comp_effect_custom3;
941         else if ( style == UTILX_EFFECT_STYLE_CUSTOM4 )  return _atom_comp_effect_custom4;
942         else if ( style == UTILX_EFFECT_STYLE_CUSTOM5 )  return _atom_comp_effect_custom5;
943         else if ( style == UTILX_EFFECT_STYLE_CUSTOM6 )  return _atom_comp_effect_custom6;
944         else if ( style == UTILX_EFFECT_STYLE_CUSTOM7 )  return _atom_comp_effect_custom7;
945         else if ( style == UTILX_EFFECT_STYLE_CUSTOM8 )  return _atom_comp_effect_custom8;
946         else if ( style == UTILX_EFFECT_STYLE_CUSTOM9 )  return _atom_comp_effect_custom9;
947         else                                             return _atom_comp_effect_none;
948
949 }
950
951 static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style )
952 {
953         if ( dpy == NULL )
954         {
955                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
956                 return UTILX_EFFECT_STYLE_NONE;
957         }
958         _utilx_effect_atom_check(dpy);
959
960         if ( style == _atom_comp_effect_default )       return UTILX_EFFECT_STYLE_DEFAULT;
961         else if ( style == _atom_comp_effect_none )     return UTILX_EFFECT_STYLE_NONE;
962         else if ( style == _atom_comp_effect_custom0 )  return UTILX_EFFECT_STYLE_CUSTOM0;
963         else if ( style == _atom_comp_effect_custom1 )  return UTILX_EFFECT_STYLE_CUSTOM1;
964         else if ( style == _atom_comp_effect_custom2 )  return UTILX_EFFECT_STYLE_CUSTOM2;
965         else if ( style == _atom_comp_effect_custom3 )  return UTILX_EFFECT_STYLE_CUSTOM3;
966         else if ( style == _atom_comp_effect_custom4 )  return UTILX_EFFECT_STYLE_CUSTOM4;
967         else if ( style == _atom_comp_effect_custom5 )  return UTILX_EFFECT_STYLE_CUSTOM5;
968         else if ( style == _atom_comp_effect_custom6 )  return UTILX_EFFECT_STYLE_CUSTOM6;
969         else if ( style == _atom_comp_effect_custom7 )  return UTILX_EFFECT_STYLE_CUSTOM7;
970         else if ( style == _atom_comp_effect_custom8 )  return UTILX_EFFECT_STYLE_CUSTOM8;
971         else if ( style == _atom_comp_effect_custom9 )  return UTILX_EFFECT_STYLE_CUSTOM9;
972         else                                            return UTILX_EFFECT_STYLE_DEFAULT;
973 }
974
975 API void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style)
976 {
977         Atom *window_effect_type_list = NULL;
978         if ( dpy == NULL )
979         {
980                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
981                 return;
982         }
983         _utilx_effect_atom_check(dpy);
984
985         window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
986
987         if ( !window_effect_type_list )
988         {
989                 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
990                 return;
991         }
992
993         window_effect_type_list[0] = _atom_comp_effect_default;
994         window_effect_type_list[1] = _atom_comp_effect_default;
995         window_effect_type_list[2] = _atom_comp_effect_default;
996         window_effect_type_list[3] = _atom_comp_effect_default;
997         window_effect_type_list[4] = _atom_comp_effect_default;
998         window_effect_type_list[5] = _atom_comp_effect_default;
999
1000         _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1001
1002         if ( type == UTILX_EFFECT_TYPE_MAP )             window_effect_type_list[0] = _utilx_convert_style_to_atom(dpy, style);
1003         else if ( type == UTILX_EFFECT_TYPE_UNMAP )      window_effect_type_list[1] = _utilx_convert_style_to_atom(dpy, style);
1004         else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) window_effect_type_list[2] = _utilx_convert_style_to_atom(dpy, style);
1005         else if ( type == UTILX_EFFECT_TYPE_ROTATION )   window_effect_type_list[3] = _utilx_convert_style_to_atom(dpy, style);
1006         else if ( type == UTILX_EFFECT_TYPE_FOCUSIN )    window_effect_type_list[4] = _utilx_convert_style_to_atom(dpy, style);
1007         else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT )   window_effect_type_list[5] = _utilx_convert_style_to_atom(dpy, style);
1008
1009         _utilx_set_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1010
1011         XSync(dpy, 0 );
1012         free(window_effect_type_list);
1013 }
1014
1015 API Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type)
1016 {
1017         Atom *window_effect_type_list = NULL;
1018         Utilx_Effect_Style style = UTILX_EFFECT_STYLE_DEFAULT;
1019
1020         if ( dpy == NULL )
1021         {
1022                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1023                 return UTILX_EFFECT_STYLE_NONE;
1024         }
1025         _utilx_effect_atom_check(dpy);
1026
1027         window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1028
1029         if ( !window_effect_type_list )
1030         {
1031                 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1032                 return UTILX_EFFECT_STYLE_NONE;
1033         }
1034
1035         if ( _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6) != 6 )
1036         {
1037                 fprintf (stderr, "[UTILX] Error.. get property failed!.. %s (%d)\n", __func__, __LINE__);
1038                 free(window_effect_type_list);
1039                 return UTILX_EFFECT_STYLE_NONE;
1040         }
1041
1042         if ( type == UTILX_EFFECT_TYPE_MAP )             style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[0]);
1043         else if ( type == UTILX_EFFECT_TYPE_UNMAP )      style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[1]);
1044         else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[2]);
1045         else if ( type == UTILX_EFFECT_TYPE_ROTATION )   style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[3]);
1046         else if ( type == UTILX_EFFECT_TYPE_FOCUSIN )    style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[4]);
1047         else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT )   style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[5]);
1048
1049         XSync(dpy, 0 );
1050         free(window_effect_type_list);
1051         return style;
1052 }
1053
1054 API int utilx_set_window_opaque_state (Display* dpy, Window win, Utilx_Opaque_State state)
1055 {
1056         UTILX_TRACE ("[UTILX] utilx_set_window_opaque_state... win = %x, show_state = %d\n", win, state);
1057
1058         unsigned int is_opaque;
1059
1060         if (dpy == NULL)
1061         {
1062                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1063                 return 0;
1064         }
1065
1066         switch (state)
1067         {
1068                 case UTILX_OPAQUE_STATE_OFF:
1069                         is_opaque = 0;
1070                         break;
1071
1072                 case UTILX_OPAQUE_STATE_ON:
1073                         is_opaque = 1;
1074                         break;
1075
1076                 default:
1077                         fprintf (stderr, "[UTILX] Error.. Invald State.. %s (%d)\n", __func__, __LINE__);
1078                         return 0;
1079         }
1080
1081         if (!_atom_window_opaque)
1082         {
1083                 _atom_window_opaque = XInternAtom (dpy, "_E_ILLUME_WINDOW_REGION_OPAQUE", False);
1084                 if (!_atom_window_opaque)
1085                 {
1086                         fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_WINDOW_REGION_OPAQUE atom.. %s (%d)\n", __func__, __LINE__);
1087                         return 0;
1088                 }
1089         }
1090
1091         _utilx_set_window_property (dpy, win, _atom_window_opaque, XA_CARDINAL,
1092                         (unsigned int *)&is_opaque, 1);
1093
1094         return 1;
1095 }
1096
1097 static void
1098 _utilx_screen_capture_atom_ensure (Display* dpy)
1099 {
1100         if (_atom_screen_capture_disable)
1101                 return;
1102
1103         _atom_screen_capture_disable = XInternAtom (dpy, "_CB_SCREEN_CAPTURE_DISABLE", False);
1104         if (_atom_screen_capture_disable)
1105                 return;
1106
1107         fprintf (stderr, "[UTILX] Error.. Cannot create _CB_SCREEN_CAPTURE_DISABLE atom.. %s (%d)\n", __func__, __LINE__);
1108 }
1109
1110 API int
1111 utilx_set_screen_capture(Display* dpy, int enable)
1112 {
1113         Window root;
1114         int disable;
1115
1116         if (!dpy)
1117         {
1118                 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1119                 return 0;
1120         }
1121
1122         root = RootWindow (dpy, DefaultScreen(dpy));
1123         disable = (enable) ? 0 : 1;
1124
1125         _utilx_screen_capture_atom_ensure (dpy);
1126
1127         _utilx_set_window_property (dpy, root, _atom_screen_capture_disable, XA_CARDINAL, (unsigned int *)&disable, 1);
1128
1129         return 1;
1130 }
1131
1132 API int
1133 utilx_get_screen_capture(Display* dpy)
1134 {
1135         Window root;
1136         int disable = 0;
1137
1138         if (!dpy)
1139         {
1140                 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1141                 return 0;
1142         }
1143
1144         root = RootWindow (dpy, DefaultScreen(dpy));
1145
1146         _utilx_screen_capture_atom_ensure (dpy);
1147
1148         _utilx_get_window_property(dpy, root, _atom_screen_capture_disable, XA_CARDINAL,
1149                                     (unsigned int *)&disable, 1);
1150
1151         return (disable) ? 0 : 1;
1152 }
1153
1154 API void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value)
1155 {
1156         _utilx_set_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1157 }
1158
1159 API int utilx_get_window_cardinal_property (Display* dpy, Window win, Atom atom, unsigned int *value)
1160 {
1161         return _utilx_get_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1162 }
1163
1164 API void utilx_show_capture_effect( Display *dpy, Window win)
1165 {
1166     XEvent xev;
1167
1168     _atom_comp_capture_effect = XInternAtom( dpy, "_E_COMP_CAPTURE_EFFECT", False );
1169     if(  !_atom_comp_capture_effect )
1170     {
1171         fprintf( stderr, "XInternAtom(_E_COMP_CAPTURE_EFFECT) failed.\n" );
1172         return;
1173     }
1174
1175     // send capture effect client message
1176     xev.xclient.type = ClientMessage;
1177     xev.xclient.display = dpy;
1178     xev.xclient.window = win;
1179     xev.xclient.message_type =  _atom_comp_capture_effect;
1180     xev.xclient.format = 32;
1181     xev.xclient.data.l[0] = 0;
1182     xev.xclient.data.l[1] = 0;
1183     xev.xclient.data.l[2] = 0;
1184     xev.xclient.data.l[3] = 0;
1185     xev.xclient.data.l[4] = 0;
1186
1187     XSendEvent( dpy, win, False,
1188                 SubstructureRedirectMask | SubstructureNotifyMask,
1189                 &xev );
1190     XSync(dpy, 0 );
1191 }