51659fa6e309a35971bfd799f2d9b7f3a94f6db4
[profile/ivi/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 i;
379         int *key_list = NULL;
380
381         Atom ret_type;
382         int ret_format;
383         unsigned long nr_item;
384         unsigned long sz_remains_data;
385         Window ex_grabwin;
386
387         if( grab_mode == EXCLUSIVE_GRAB )
388         {
389                 if( _atom_grab_excl_win == None )
390                         _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
391                 ex_grabwin = _atom_grab_excl_win;
392         }
393         else if( grab_mode == OR_EXCLUSIVE_GRAB )
394         {
395                 if( _atom_grab_or_excl_win == None )
396                         _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
397                 ex_grabwin = _atom_grab_or_excl_win;
398         }
399         else
400                 return;
401
402         if (XGetWindowProperty(disp, DefaultRootWindow(disp),
403                 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
404                 &ret_type, &ret_format, &nr_item,
405                 &sz_remains_data, (unsigned char**)&key_list) != Success)
406         {
407                 fprintf(stderr, "[utilX][%s] Fail to get root window property !\n", __FUNCTION__);
408                 goto out;
409         }
410
411 #ifdef __DEBUG__
412         printf("[%s] keycode = %d\n", __FUNCTION__, keycode);
413 #endif
414
415         for( i=0 ; i < nr_item ; i++ )
416         {
417                 if( key_list && (key_list[i] == keycode) )
418                         return;
419         }
420
421         XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
422         nr_item ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
423         XSync(disp, False);
424
425 out:
426         return;
427 }
428
429
430 static void _unset_exclusive_grab_info_to_root (Display *disp, int keycode, int grab_mode)
431 {
432         int i;
433         unsigned long cnt = 0;
434         int *key_list = NULL;
435         int *new_key_list = NULL;
436
437         Atom ret_type;
438         int ret_format;
439         unsigned long nr_item;
440         unsigned long sz_remains_data;
441         Window ex_grabwin;
442
443         if( grab_mode == EXCLUSIVE_GRAB )
444         {
445                 if( _atom_grab_excl_win == None )
446                         _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
447                 ex_grabwin = _atom_grab_excl_win;
448         }
449         else if( grab_mode == OR_EXCLUSIVE_GRAB )
450         {
451                 if( _atom_grab_or_excl_win == None )
452                         _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
453                 ex_grabwin = _atom_grab_or_excl_win;
454         }
455         else
456                 return;
457
458         if (XGetWindowProperty(disp, DefaultRootWindow(disp),
459                 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
460                 &ret_type, &ret_format, &nr_item,
461                 &sz_remains_data, (unsigned char**)&key_list) != Success)
462         {
463                 nr_item = 0;
464         }
465
466         if (nr_item == 0)
467         {
468                 fprintf(stderr, "\e[32m[utilX][%s] keycode = %d\e[0m\n", __FUNCTION__, keycode);
469                 goto out;
470         }
471
472         for( i=0 ; i < nr_item ; i++ )
473         {
474                 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
475                 {
476                         continue;
477                 }
478                 cnt++;
479         }
480
481 #ifdef __DEBUG__
482         fprintf(stderr, "[utilX][%s] cnt = %d, nr_item = %d\n", __FUNCTION__, cnt, nr_item);
483 #endif
484
485         if( 0 < cnt )
486         {
487                 new_key_list = malloc(sizeof(int)*cnt);
488                 cnt = 0;
489         }
490         else
491                 new_key_list = NULL;
492
493         if( !new_key_list )
494         {
495                 //fprintf(stderr, "\e[32m[utilX][%s] Fail to allocation memory for new_key_list ! \e[0m\n", __FUNCTION__);
496                 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
497                 XSync(disp, False);
498                 goto out;
499         }
500
501         for( i=0 ; i < nr_item ; i++ )
502         {
503                 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
504                 {
505                         continue;
506                 }
507                 else
508                         new_key_list[cnt++] = key_list[i];
509         }
510
511         if (new_key_list) {
512                 XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
513                         PropModeReplace, (unsigned char *)new_key_list, cnt);
514         }
515         else {
516                 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
517         }
518         XSync(disp, False);
519
520         if(new_key_list)
521                 free(new_key_list);
522
523 out:
524         return;
525 }
526
527
528 static int _is_grabbed_key_exclusively (Display* disp, int keycode, int grab_mode)
529 {
530         int i, result = 0;
531         int *key_list = NULL;
532
533         Atom ret_type;
534         int ret_format;
535         unsigned long nr_item;
536         unsigned long sz_remains_data;
537         Window ex_grabwin;
538
539         if( grab_mode == EXCLUSIVE_GRAB )
540         {
541                 if( _atom_grab_excl_win == None )
542                         _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
543                 ex_grabwin = _atom_grab_excl_win;
544         }
545         else if( grab_mode == OR_EXCLUSIVE_GRAB )
546         {
547                 if( _atom_grab_or_excl_win == None )
548                         _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
549                 ex_grabwin = _atom_grab_or_excl_win;
550         }
551         else
552                 return result;
553
554         if (XGetWindowProperty(disp, DefaultRootWindow(disp),
555                 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
556                 &ret_type, &ret_format, &nr_item,
557                 &sz_remains_data, (unsigned char**)&key_list) != Success)
558         {
559                 fprintf(stderr, "[%s] Fail to get root window property !\n", __FUNCTION__);
560                 goto out;
561         }
562
563         for( i=0 ; i < nr_item ; i++ )
564         {
565                 if( key_list[i] == keycode )
566                         return EXCLUSIVE_GRABBED_ALREADY;
567         }
568
569 out:
570         return result;
571 }
572
573 API int utilx_grab_key (Display* disp, Window win, const char* key, int grab_mode)
574 {
575         unsigned long cnt;
576         int *key_list = NULL;
577         int i, result = 0;
578         int keycode = 0;
579         KeySym keysym;
580         errno = EINVAL;
581
582         if( NULL == disp )
583         {
584                 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
585                 return -1;
586         }
587
588         if (_atom_grab_key == None) {
589                 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
590         }
591
592         if (!strncmp(key, "Keycode-", 8)) {
593                 keycode = atoi(key + 8);
594         } else {
595                 keysym = XStringToKeysym(key);
596                 if (keysym == NoSymbol) goto out;
597                 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
598         }
599         if (keycode == 0) goto out;
600
601         if( grab_mode == EXCLUSIVE_GRAB )
602         {
603                 //Window grabWin;
604                 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
605
606 #ifdef __DEBUG__
607                 printf("[%s] _is_grabbed_key_exclusively returns result = %d\n", __FUNCTION__, result);
608 #endif
609
610                 if( result )
611                 {
612                         fprintf(stderr, "[%s] keycode(%d) was already grabbed exclusively (grab_mode=0x%X) !\n", __FUNCTION__, keycode, grab_mode);
613                         goto out;
614                 }
615         }
616         else if( grab_mode == OR_EXCLUSIVE_GRAB )
617         {
618                 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
619
620                 if( result )
621                 {
622                         fprintf(stderr, "[%s] Keycode(%d) was already grabbed with overridable exclusive mode (grab_mode=0x%x)\n", __FUNCTION__, keycode, grab_mode);
623                         fprintf(stderr, "[%s] Now it will be overridden by a new window(0x%x) !\n", __FUNCTION__, win);
624                         utilx_ungrab_key(disp, win, key);
625                 }
626         }
627
628         keycode |= grab_mode;
629
630         cnt = _get_list_of_grabbed_key(disp, win, &key_list);
631         if (cnt > 0) {
632                 i = _search_grabbed_key(key_list, keycode, cnt);
633                 _free_list_of_grabbed_key(key_list);
634                 if ( i != -1 ) {
635                         if( grab_mode == OR_EXCLUSIVE_GRAB )
636                         {
637                                 utilx_ungrab_key(disp, win, key);
638                         }
639                         else
640                         {
641                         fprintf(stderr, "Key is already grabbed\n");
642                         goto out;
643                         }
644                 }
645         }
646
647         XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
648                         cnt ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
649         XSync(disp, False);
650         keycode = keycode & (~GRAB_MODE_MASK);
651 #ifdef __DEBUG__
652         printf("[%s] keycode = %d\n", __FUNCTION__, keycode);
653 #endif
654
655         if( EXCLUSIVE_GRAB == grab_mode || OR_EXCLUSIVE_GRAB == grab_mode )
656                 _set_exclusive_grab_info_to_root(disp, keycode, win, grab_mode);
657
658         errno = 0;
659
660 out:
661
662         return result;
663 }
664
665
666 API int utilx_ungrab_key (Display* disp, Window win, const char* key)
667 {
668         int i;
669         unsigned long cnt;
670         int *key_list = NULL;
671         int *new_key_list = NULL;
672         long keycode = 0;
673         KeySym keysym;
674         int ret = -1;
675         errno = EINVAL;
676
677         if( NULL == disp )
678         {
679                 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
680                 return -1;
681         }
682
683         if (_atom_grab_key == None) {
684                 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
685         }
686
687         if (!strncmp(key, "Keycode-", 8)) {
688                 keycode = atoi(key + 8);
689         } else {
690                 keysym = XStringToKeysym(key);
691                 if (keysym == NoSymbol) goto out;
692                 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
693         }
694         if (keycode == 0) goto out;
695
696         cnt = _get_list_of_grabbed_key(disp, win, &key_list);
697         if (cnt == 0) goto out;
698
699         //EXCLUSIVE mode
700         i = _search_grabbed_key(key_list, keycode | EXCLUSIVE_GRAB, cnt);
701
702         if ( i == -1)
703         {
704                 //OR_EXCLUSIVE mode
705                 i = _search_grabbed_key(key_list, keycode | OR_EXCLUSIVE_GRAB, cnt);
706
707                 if ( i == -1)
708                 {
709                         //TOP_POSITION mode
710                         i = _search_grabbed_key(key_list, keycode | TOP_POSITION_GRAB, cnt);
711
712                         if (i == -1)
713                         {
714                                 //SHARED mode
715                                 i = _search_grabbed_key(key_list, keycode | SHARED_GRAB, cnt);
716
717                                 if (i == -1)
718                                 {
719                                         _free_list_of_grabbed_key(key_list);
720                                         goto out;
721                                 }
722                         }
723                 }
724                 else
725                 {
726                         _unset_exclusive_grab_info_to_root(disp, keycode, OR_EXCLUSIVE_GRAB);
727                 }
728         }
729         else
730         {
731                 _unset_exclusive_grab_info_to_root(disp, keycode, EXCLUSIVE_GRAB);
732         }
733
734         new_key_list = _del_grabbed_key(key_list, i, &cnt);
735         _free_list_of_grabbed_key(key_list);
736
737         if (new_key_list) {
738                 XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
739                         PropModeReplace, (unsigned char *)new_key_list, cnt);
740         }
741         else {
742                 XDeleteProperty(disp, win, _atom_grab_key);
743         }
744         XSync(disp, False);
745
746         _free_new_list_of_grabbed_key(new_key_list);
747         ret = 0;
748         errno = 0;
749
750 out:
751
752         return ret;
753 }
754
755 API Utilx_Key_Status utilx_get_key_status(Display* dpy, char *key_name)
756 {
757         unsigned char keymap[32];
758         static unsigned int masktable[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
759         Utilx_Key_Status status = UTILX_KEY_STATUS_UNKNOWN;
760
761         if( !strncmp(key_name, KEY_VOLUMEDOWN, LEN_KEY_VOLUMEDOWN) ||
762                 !strncmp(key_name, KEY_VOLUMEUP, LEN_KEY_VOLUMEUP) ||
763                 !strncmp(key_name, KEY_PAUSE, LEN_KEY_PAUSE) ||
764                 !strncmp(key_name, KEY_SEND, LEN_KEY_SEND) ||
765                 !strncmp(key_name, KEY_SELECT, LEN_KEY_VOLUMEDOWN) ||
766                 !strncmp(key_name, KEY_END, LEN_KEY_END) ||
767                 !strncmp(key_name, KEY_POWER, LEN_KEY_POWER) ||
768                 !strncmp(key_name, KEY_CAMERA, LEN_KEY_CAMERA) ||
769                 !strncmp(key_name, KEY_CONFIG, LEN_KEY_CONFIG) ||
770                 !strncmp(key_name, KEY_PLAYCD, LEN_KEY_PLAYCD) ||
771                 !strncmp(key_name, KEY_STOPCD, LEN_KEY_STOPCD) ||
772                 !strncmp(key_name, KEY_PAUSECD, LEN_KEY_PAUSECD) ||
773                 !strncmp(key_name, KEY_NEXTSONG, LEN_KEY_NEXTSONG) ||
774                 !strncmp(key_name, KEY_PREVIOUSSONG, LEN_KEY_PREVIOUSSONG) ||
775                 !strncmp(key_name, KEY_REWIND, LEN_KEY_REWIND) ||
776                 !strncmp(key_name, KEY_FASTFORWARD, LEN_KEY_FASTFORWARD) ||
777                 !strncmp(key_name, KEY_MEDIA, LEN_KEY_MEDIA) )
778         {
779                 KeySym ks = XStringToKeysym(key_name);
780                 KeyCode kc = XKeysymToKeycode(dpy, ks);
781
782                 if( kc )
783                 {
784                         XQueryKeymap(dpy, (char *)keymap);
785                         if( keymap[kc >> 3] & masktable[kc & 7] )
786                                 status = UTILX_KEY_STATUS_PRESSED;
787                         else
788                                 status = UTILX_KEY_STATUS_RELEASED;
789                 }
790         }
791
792         return status;
793 }
794
795 API void utilx_set_window_effect_state(Display* dpy, Window win, int state)
796 {
797         if ( dpy == NULL )
798         {
799                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
800                 return;
801         }
802         if( !_atom_comp_effect_state)
803                 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
804
805         _utilx_set_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
806
807         XSync(dpy, 0 );
808 }
809
810 API int utilx_get_window_effect_state(Display* dpy, Window win)
811 {
812         int state = 0;
813         if( !_atom_comp_effect_state)
814                 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
815         _utilx_get_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
816         return state;
817 }
818
819 static void
820 _utilx_string_set_window_property( Display *dpy, Window win, Atom atom, char *val, unsigned int num)
821 {
822         XChangeProperty( dpy, win, atom, XA_STRING, 8, PropModeReplace, (unsigned char*)val, val ? strlen(val):0 );
823 }
824
825 API void utilx_set_fake_launch_img(Display* dpy, Window win, char *file_name)
826 {
827         //UTILX_TRACE ("[UTILX] utilx_set_effect_state... win = %x, show_state = %d\n", win, enable);
828
829         if ( dpy == NULL )
830         {
831                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
832                 return;
833         }
834         if( !_atom_comp_fake_launch_image)
835                 _atom_comp_fake_launch_image = XInternAtom(dpy, "_E_COMP_FAKE_LAUNCH_IMAGE",False);
836
837         _utilx_string_set_window_property(dpy, win, _atom_comp_fake_launch_image, file_name, 1);
838 }
839
840 API void utilx_show_fake_effect( Display *dpy, Window win, char *fake_image_file )
841 {
842         XEvent xev;
843
844         _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
845
846         if(  !_atom_comp_fake_launch )
847         {
848                 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
849                 return;
850         }
851
852         utilx_set_fake_launch_img(dpy, win, fake_image_file);
853
854         XSync(dpy, 0 );
855
856         // send fake client message
857         xev.xclient.type = ClientMessage;
858         xev.xclient.display = dpy;
859         xev.xclient.window = win;
860         xev.xclient.message_type =  _atom_comp_fake_launch;
861         xev.xclient.format = 32;
862         xev.xclient.data.l[0] = 1;  // 1 : start effect , 0 : end effect
863         xev.xclient.data.l[1] = 0;
864         xev.xclient.data.l[2] = 0;
865         xev.xclient.data.l[3] = 0;
866         xev.xclient.data.l[4] = 0;
867
868         XSendEvent( dpy, win, False,
869                                 SubstructureRedirectMask | SubstructureNotifyMask,
870                                 &xev );
871         XSync(dpy, 0 );
872
873 }
874
875
876 API void utilx_hide_fake_effect( Display *dpy, Window win)
877 {
878         XEvent xev;
879
880         _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
881         if(  !_atom_comp_fake_launch )
882         {
883                 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
884                 return;
885         }
886
887         // send fake client message
888         xev.xclient.type = ClientMessage;
889         xev.xclient.display = dpy;
890         xev.xclient.window = win;
891         xev.xclient.message_type =  _atom_comp_fake_launch;
892         xev.xclient.format = 32;
893         xev.xclient.data.l[0] = 0;  // 1 : start effect , 0 : end effect
894         xev.xclient.data.l[1] = 0;
895         xev.xclient.data.l[2] = 0;
896         xev.xclient.data.l[3] = 0;
897         xev.xclient.data.l[4] = 0;
898
899         XSendEvent( dpy, win, False,
900                                 SubstructureRedirectMask | SubstructureNotifyMask,
901                                 &xev );
902         XSync(dpy, 0 );
903 }
904
905 static void _utilx_effect_atom_check( Display* dpy )
906 {
907         if ( dpy == NULL )
908         {
909                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
910                 return;
911         }
912
913         if( !_atom_comp_window_effect_type)
914                 _atom_comp_window_effect_type =  XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_TYPE",False);
915         if( !_atom_comp_effect_default )
916                 _atom_comp_effect_default = XInternAtom(dpy, "_NET_CM_EFFECT_DEFAULT",False);
917         if( !_atom_comp_effect_none )
918                 _atom_comp_effect_none = XInternAtom(dpy, "_NET_CM_EFFECT_NONE",False);
919         if( !_atom_comp_effect_custom0 )
920                 _atom_comp_effect_custom0 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM0",False);
921         if( !_atom_comp_effect_custom1 )
922                 _atom_comp_effect_custom1 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM1",False);
923         if( !_atom_comp_effect_custom2 )
924                 _atom_comp_effect_custom2 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM2",False);
925         if( !_atom_comp_effect_custom3 )
926                 _atom_comp_effect_custom3 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM3",False);
927         if( !_atom_comp_effect_custom4 )
928                 _atom_comp_effect_custom4 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM4",False);
929         if( !_atom_comp_effect_custom5 )
930                 _atom_comp_effect_custom5 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM5",False);
931         if( !_atom_comp_effect_custom6 )
932                 _atom_comp_effect_custom6 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM6",False);
933         if( !_atom_comp_effect_custom7 )
934                 _atom_comp_effect_custom7 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM7",False);
935         if( !_atom_comp_effect_custom8 )
936                 _atom_comp_effect_custom8 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM8",False);
937         if( !_atom_comp_effect_custom9 )
938                 _atom_comp_effect_custom9 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM9",False);
939 }
940
941 static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style )
942 {
943         if ( dpy == NULL )
944         {
945                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
946                 return _atom_comp_effect_none;
947         }
948         _utilx_effect_atom_check(dpy);
949
950         if ( style == UTILX_EFFECT_STYLE_DEFAULT )       return _atom_comp_effect_default;
951         else if ( style == UTILX_EFFECT_STYLE_NONE )     return _atom_comp_effect_none;
952         else if ( style == UTILX_EFFECT_STYLE_CUSTOM0 )  return _atom_comp_effect_custom0;
953         else if ( style == UTILX_EFFECT_STYLE_CUSTOM1 )  return _atom_comp_effect_custom1;
954         else if ( style == UTILX_EFFECT_STYLE_CUSTOM2 )  return _atom_comp_effect_custom2;
955         else if ( style == UTILX_EFFECT_STYLE_CUSTOM3 )  return _atom_comp_effect_custom3;
956         else if ( style == UTILX_EFFECT_STYLE_CUSTOM4 )  return _atom_comp_effect_custom4;
957         else if ( style == UTILX_EFFECT_STYLE_CUSTOM5 )  return _atom_comp_effect_custom5;
958         else if ( style == UTILX_EFFECT_STYLE_CUSTOM6 )  return _atom_comp_effect_custom6;
959         else if ( style == UTILX_EFFECT_STYLE_CUSTOM7 )  return _atom_comp_effect_custom7;
960         else if ( style == UTILX_EFFECT_STYLE_CUSTOM8 )  return _atom_comp_effect_custom8;
961         else if ( style == UTILX_EFFECT_STYLE_CUSTOM9 )  return _atom_comp_effect_custom9;
962         else                                             return _atom_comp_effect_none;
963
964 }
965
966 static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style )
967 {
968         if ( dpy == NULL )
969         {
970                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
971                 return UTILX_EFFECT_STYLE_NONE;
972         }
973         _utilx_effect_atom_check(dpy);
974
975         if ( style == _atom_comp_effect_default )       return UTILX_EFFECT_STYLE_DEFAULT;
976         else if ( style == _atom_comp_effect_none )     return UTILX_EFFECT_STYLE_NONE;
977         else if ( style == _atom_comp_effect_custom0 )  return UTILX_EFFECT_STYLE_CUSTOM0;
978         else if ( style == _atom_comp_effect_custom1 )  return UTILX_EFFECT_STYLE_CUSTOM1;
979         else if ( style == _atom_comp_effect_custom2 )  return UTILX_EFFECT_STYLE_CUSTOM2;
980         else if ( style == _atom_comp_effect_custom3 )  return UTILX_EFFECT_STYLE_CUSTOM3;
981         else if ( style == _atom_comp_effect_custom4 )  return UTILX_EFFECT_STYLE_CUSTOM4;
982         else if ( style == _atom_comp_effect_custom5 )  return UTILX_EFFECT_STYLE_CUSTOM5;
983         else if ( style == _atom_comp_effect_custom6 )  return UTILX_EFFECT_STYLE_CUSTOM6;
984         else if ( style == _atom_comp_effect_custom7 )  return UTILX_EFFECT_STYLE_CUSTOM7;
985         else if ( style == _atom_comp_effect_custom8 )  return UTILX_EFFECT_STYLE_CUSTOM8;
986         else if ( style == _atom_comp_effect_custom9 )  return UTILX_EFFECT_STYLE_CUSTOM9;
987         else                                            return UTILX_EFFECT_STYLE_DEFAULT;
988 }
989
990 API void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style)
991 {
992         Atom *window_effect_type_list = NULL;
993         if ( dpy == NULL )
994         {
995                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
996                 return;
997         }
998         _utilx_effect_atom_check(dpy);
999
1000         window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1001
1002         if ( !window_effect_type_list )
1003         {
1004                 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1005                 return;
1006         }
1007
1008         window_effect_type_list[0] = _atom_comp_effect_default;
1009         window_effect_type_list[1] = _atom_comp_effect_default;
1010         window_effect_type_list[2] = _atom_comp_effect_default;
1011         window_effect_type_list[3] = _atom_comp_effect_default;
1012         window_effect_type_list[4] = _atom_comp_effect_default;
1013         window_effect_type_list[5] = _atom_comp_effect_default;
1014
1015         _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1016
1017         if ( type == UTILX_EFFECT_TYPE_MAP )             window_effect_type_list[0] = _utilx_convert_style_to_atom(dpy, style);
1018         else if ( type == UTILX_EFFECT_TYPE_UNMAP )      window_effect_type_list[1] = _utilx_convert_style_to_atom(dpy, style);
1019         else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) window_effect_type_list[2] = _utilx_convert_style_to_atom(dpy, style);
1020         else if ( type == UTILX_EFFECT_TYPE_ROTATION )   window_effect_type_list[3] = _utilx_convert_style_to_atom(dpy, style);
1021         else if ( type == UTILX_EFFECT_TYPE_FOCUSIN )    window_effect_type_list[4] = _utilx_convert_style_to_atom(dpy, style);
1022         else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT )   window_effect_type_list[5] = _utilx_convert_style_to_atom(dpy, style);
1023
1024         _utilx_set_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1025
1026         XSync(dpy, 0 );
1027         free(window_effect_type_list);
1028 }
1029
1030 API Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type)
1031 {
1032         Atom *window_effect_type_list = NULL;
1033         Utilx_Effect_Style style = UTILX_EFFECT_STYLE_DEFAULT;
1034
1035         if ( dpy == NULL )
1036         {
1037                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1038                 return UTILX_EFFECT_STYLE_NONE;
1039         }
1040         _utilx_effect_atom_check(dpy);
1041
1042         window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1043
1044         if ( !window_effect_type_list )
1045         {
1046                 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1047                 return UTILX_EFFECT_STYLE_NONE;
1048         }
1049
1050         if ( _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6) != 6 )
1051         {
1052                 fprintf (stderr, "[UTILX] Error.. get property failed!.. %s (%d)\n", __func__, __LINE__);
1053                 free(window_effect_type_list);
1054                 return UTILX_EFFECT_STYLE_NONE;
1055         }
1056
1057         if ( type == UTILX_EFFECT_TYPE_MAP )             style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[0]);
1058         else if ( type == UTILX_EFFECT_TYPE_UNMAP )      style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[1]);
1059         else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[2]);
1060         else if ( type == UTILX_EFFECT_TYPE_ROTATION )   style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[3]);
1061         else if ( type == UTILX_EFFECT_TYPE_FOCUSIN )    style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[4]);
1062         else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT )   style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[5]);
1063
1064         XSync(dpy, 0 );
1065         free(window_effect_type_list);
1066         return style;
1067 }
1068
1069 API int utilx_set_window_opaque_state (Display* dpy, Window win, Utilx_Opaque_State state)
1070 {
1071         UTILX_TRACE ("[UTILX] utilx_set_window_opaque_state... win = %x, show_state = %d\n", win, state);
1072
1073         unsigned int is_opaque;
1074
1075         if (dpy == NULL)
1076         {
1077                 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1078                 return 0;
1079         }
1080
1081         switch (state)
1082         {
1083                 case UTILX_OPAQUE_STATE_OFF:
1084                         is_opaque = 0;
1085                         break;
1086
1087                 case UTILX_OPAQUE_STATE_ON:
1088                         is_opaque = 1;
1089                         break;
1090
1091                 default:
1092                         fprintf (stderr, "[UTILX] Error.. Invald State.. %s (%d)\n", __func__, __LINE__);
1093                         return 0;
1094         }
1095
1096         if (!_atom_window_opaque)
1097         {
1098                 _atom_window_opaque = XInternAtom (dpy, "_E_ILLUME_WINDOW_REGION_OPAQUE", False);
1099                 if (!_atom_window_opaque)
1100                 {
1101                         fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_WINDOW_REGION_OPAQUE atom.. %s (%d)\n", __func__, __LINE__);
1102                         return 0;
1103                 }
1104         }
1105
1106         _utilx_set_window_property (dpy, win, _atom_window_opaque, XA_CARDINAL,
1107                         (unsigned int *)&is_opaque, 1);
1108
1109         return 1;
1110 }
1111
1112 static void
1113 _utilx_screen_capture_atom_ensure (Display* dpy)
1114 {
1115         if (_atom_screen_capture_disable)
1116                 return;
1117
1118         _atom_screen_capture_disable = XInternAtom (dpy, "_CB_SCREEN_CAPTURE_DISABLE", False);
1119         if (_atom_screen_capture_disable)
1120                 return;
1121
1122         fprintf (stderr, "[UTILX] Error.. Cannot create _CB_SCREEN_CAPTURE_DISABLE atom.. %s (%d)\n", __func__, __LINE__);
1123 }
1124
1125 API int
1126 utilx_set_screen_capture(Display* dpy, int enable)
1127 {
1128         Window root;
1129         int disable;
1130
1131         if (!dpy)
1132         {
1133                 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1134                 return 0;
1135         }
1136
1137         root = RootWindow (dpy, DefaultScreen(dpy));
1138         disable = (enable) ? 0 : 1;
1139
1140         _utilx_screen_capture_atom_ensure (dpy);
1141
1142         _utilx_set_window_property (dpy, root, _atom_screen_capture_disable, XA_CARDINAL, (unsigned int *)&disable, 1);
1143
1144         return 1;
1145 }
1146
1147 API int
1148 utilx_get_screen_capture(Display* dpy)
1149 {
1150         Window root;
1151         int disable = 0;
1152
1153         if (!dpy)
1154         {
1155                 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1156                 return 0;
1157         }
1158
1159         root = RootWindow (dpy, DefaultScreen(dpy));
1160
1161         _utilx_screen_capture_atom_ensure (dpy);
1162
1163         _utilx_get_window_property(dpy, root, _atom_screen_capture_disable, XA_CARDINAL,
1164                                     (unsigned int *)&disable, 1);
1165
1166         return (disable) ? 0 : 1;
1167 }
1168
1169 API void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value)
1170 {
1171         _utilx_set_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1172 }
1173
1174 API int utilx_get_window_cardinal_property (Display* dpy, Window win, Atom atom, unsigned int *value)
1175 {
1176         return _utilx_get_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1177 }
1178
1179 API void utilx_show_capture_effect( Display *dpy, Window win)
1180 {
1181     XEvent xev;
1182
1183     _atom_comp_capture_effect = XInternAtom( dpy, "_E_COMP_CAPTURE_EFFECT", False );
1184     if(  !_atom_comp_capture_effect )
1185     {
1186         fprintf( stderr, "XInternAtom(_E_COMP_CAPTURE_EFFECT) failed.\n" );
1187         return;
1188     }
1189
1190     // send capture effect client message
1191     xev.xclient.type = ClientMessage;
1192     xev.xclient.display = dpy;
1193     xev.xclient.window = win;
1194     xev.xclient.message_type =  _atom_comp_capture_effect;
1195     xev.xclient.format = 32;
1196     xev.xclient.data.l[0] = 0;
1197     xev.xclient.data.l[1] = 0;
1198     xev.xclient.data.l[2] = 0;
1199     xev.xclient.data.l[3] = 0;
1200     xev.xclient.data.l[4] = 0;
1201
1202     XSendEvent( dpy, win, False,
1203                 SubstructureRedirectMask | SubstructureNotifyMask,
1204                 &xev );
1205     XSync(dpy, 0 );
1206 }