4 Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
10 http://www.apache.org/licenses/LICENSE-2.0
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.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <X11/extensions/Xrandr.h>
36 #include <X11/extensions/Xvlib.h>
37 #include <X11/extensions/Xvproto.h>
38 #include <X11/extensions/Xdamage.h>
39 #include <X11/extensions/XShm.h>
41 #include <tbm_bufmgr.h>
47 #define UTILX_TRACE printf
49 #define UTILX_TRACE(...)
52 static Atom _atom_grab_key = None;
53 static Atom _atom_grab_excl_win = None;
54 static Atom _atom_grab_or_excl_win = None;
56 static Atom _atom_notification_level = None;
57 static Atom _atom_indicator_visible_state = None;
58 static Atom _atom_indicator_visible_state_on = None;
59 static Atom _atom_indicator_visible_state_off = None;
61 static Atom _atom_comp_effect_state = None;
62 static Atom _atom_comp_fake_launch = None;
63 static Atom _atom_comp_fake_launch_image = None;
65 static Atom _atom_comp_window_effect_type = None;
66 static Atom _atom_comp_effect_default = None;
67 static Atom _atom_comp_effect_none = None;
68 static Atom _atom_comp_effect_custom0 = None;
69 static Atom _atom_comp_effect_custom1 = None;
70 static Atom _atom_comp_effect_custom2 = None;
71 static Atom _atom_comp_effect_custom3 = None;
72 static Atom _atom_comp_effect_custom4 = None;
73 static Atom _atom_comp_effect_custom5 = None;
74 static Atom _atom_comp_effect_custom6 = None;
75 static Atom _atom_comp_effect_custom7 = None;
76 static Atom _atom_comp_effect_custom8 = None;
77 static Atom _atom_comp_effect_custom9 = None;
79 static Atom _atom_window_opaque = None;
81 static Atom _atom_screen_capture_disable = None;
83 static Atom _atom_comp_capture_effect = None;
85 const unsigned long maxlen = 1024l;
87 static void _utilx_set_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int num);
88 static int _utilx_get_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len);
90 static void _utilx_effect_atom_check( Display* dpy );
91 static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style );
92 static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style );
94 static int _utilx_get_indicator_atoms(Display *dpy);
96 API void utilx_set_system_notification_level (Display* dpy, Window win, Utilx_Notification_Level level)
98 UTILX_TRACE ("[UTILX] utilx_set_system_notification_level... win = %x, level = %d\n", win, level);
104 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
110 case UTILX_NOTIFICATION_LEVEL_LOW:
114 case UTILX_NOTIFICATION_LEVEL_NORMAL:
118 case UTILX_NOTIFICATION_LEVEL_HIGH:
127 if (!_atom_notification_level)
129 _atom_notification_level = XInternAtom (dpy, "_E_ILLUME_NOTIFICATION_LEVEL", False);
130 if (!_atom_notification_level)
132 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_NOTIFICATION_LEVEL atom.. %s (%d)\n", __func__, __LINE__);
137 _utilx_set_window_property (dpy, win, _atom_notification_level, XA_CARDINAL,
138 (unsigned int *)¬i_level, 1);
142 API Utilx_Notification_Level utilx_get_system_notification_level (Display* dpy, Window win)
144 UTILX_TRACE ("[UTILX] utilx_get_system_notification_level... win = %x\n", win);
146 Utilx_Notification_Level noti_level;
150 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
154 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
158 if (!_atom_notification_level)
160 _atom_notification_level = XInternAtom (dpy, "_E_ILLUME_NOTIFICATION_LEVEL", False);
161 if (!_atom_notification_level)
163 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_NOTIFICATION_LEVEL atom.. %s (%d)\n", __func__, __LINE__);
168 ret = _utilx_get_window_property (dpy, win, _atom_notification_level, XA_CARDINAL,
169 (unsigned int *)&level, 1);
176 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
180 noti_level = UTILX_NOTIFICATION_LEVEL_NORMAL;
184 noti_level = UTILX_NOTIFICATION_LEVEL_HIGH;
188 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
194 noti_level = UTILX_NOTIFICATION_LEVEL_LOW;
201 static int _utilx_get_indicator_atoms(Display *dpy)
203 if (!_atom_indicator_visible_state)
205 _atom_indicator_visible_state = XInternAtom (dpy, "_E_ILLUME_INDICATOR_STATE", False);
206 if (!_atom_indicator_visible_state)
208 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_STATE atom.. %s (%d)\n", __func__, __LINE__);
213 if (!_atom_indicator_visible_state_on)
215 _atom_indicator_visible_state_on = XInternAtom (dpy, "_E_ILLUME_INDICATOR_ON", False);
216 if (!_atom_indicator_visible_state_on)
218 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_ON atom.. %s (%d)\n", __func__, __LINE__);
223 if (!_atom_indicator_visible_state_off)
225 _atom_indicator_visible_state_off = XInternAtom (dpy, "_E_ILLUME_INDICATOR_OFF", False);
226 if (!_atom_indicator_visible_state_off)
228 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_OFF atom.. %s (%d)\n", __func__, __LINE__);
236 API void utilx_enable_indicator (Display* dpy, Window win, int enable)
238 UTILX_TRACE ("[UTILX] utilx_indicator_set_visible_state... win = %x, show_state = %d\n", win, enable);
242 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
246 if (!_utilx_get_indicator_atoms(dpy))
248 fprintf (stderr, "[UTILX] Error.. Cannot create atoms.. %s (%d)\n", __func__, __LINE__);
254 _utilx_set_window_property (dpy, win, _atom_indicator_visible_state, XA_ATOM,
255 (unsigned int *)&_atom_indicator_visible_state_on, 1);
259 _utilx_set_window_property (dpy, win, _atom_indicator_visible_state, XA_ATOM,
260 (unsigned int *)&_atom_indicator_visible_state_off, 1);
265 API int utilx_get_indicator_state (Display* dpy, Window win)
267 UTILX_TRACE ("[UTILX] utilx_indicator_set_visible_state... win = %x, show_state = %d\n", win, enable);
274 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
278 if (!_utilx_get_indicator_atoms(dpy))
280 fprintf (stderr, "[UTILX] Error.. Cannot create atoms.. %s (%d)\n", __func__, __LINE__);
284 ret = _utilx_get_window_property (dpy, win, _atom_indicator_visible_state, XA_ATOM,
285 (unsigned int *)&state, 1);
289 if (state == _atom_indicator_visible_state_on)
291 else if (state == _atom_indicator_visible_state_off)
301 _utilx_set_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int num)
303 XChangeProperty (dpy, win, atom, type, 32, PropModeReplace, (unsigned char *)val, num);
309 _utilx_get_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len)
311 unsigned char* prop_ret;
313 unsigned long bytes_after, num_ret;
319 if (XGetWindowProperty(dpy, win, atom, 0, 0x7fffffff, False,
320 type, &type_ret, &format_ret, &num_ret,
321 &bytes_after, &prop_ret) != Success)
326 if (type_ret != type || format_ret != 32)
330 else if (num_ret == 0 || !prop_ret)
338 for (i = 0; i < len; i++)
340 val[i] = ((unsigned long *)prop_ret)[i];
353 static unsigned long _get_list_of_grabbed_key (Display *disp, Window win, int **key_list)
357 unsigned long nr_item;
358 unsigned long sz_remains_data;
360 if (XGetWindowProperty(disp, win,
361 _atom_grab_key, 0, 0x7fffffff, False, XA_CARDINAL,
362 &ret_type, &ret_format, &nr_item,
363 &sz_remains_data, (unsigned char**)key_list) != Success)
368 // fprintf(stderr, "
\e[31m%d - %lu
\e[0m\n", ret_format, nr_item);
374 static void _free_list_of_grabbed_key (int *key_list)
382 static void _free_new_list_of_grabbed_key (int *new_key_list)
390 static int _search_grabbed_key (int *key_list, int key, unsigned long cnt)
394 for (i = cnt - 1; i >= 0; i --) {
395 if (key_list[i] == key) break;
402 static int *_del_grabbed_key (int *key_list, int i, unsigned long *cnt)
404 int *new_key_list = NULL;
406 // Only one element is exists in the list of grabbed key
409 if (*cnt == 0) return NULL;
412 new_key_list = malloc((*cnt) * sizeof(int));
413 if (new_key_list == NULL) {
420 memcpy(new_key_list, key_list, sizeof(int) * i);
424 if ((*cnt) - i > 0) {
425 memcpy(new_key_list + i,
427 sizeof(int) * ((*cnt) - i)
434 static void _set_exclusive_grab_info_to_root (Display *disp, int keycode, Window win, int grab_mode)
437 int *key_list = NULL;
441 unsigned long nr_item;
442 unsigned long sz_remains_data;
445 if( grab_mode == EXCLUSIVE_GRAB )
447 if( _atom_grab_excl_win == None )
448 _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
449 ex_grabwin = _atom_grab_excl_win;
451 else if( grab_mode == OR_EXCLUSIVE_GRAB )
453 if( _atom_grab_or_excl_win == None )
454 _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
455 ex_grabwin = _atom_grab_or_excl_win;
460 if (XGetWindowProperty(disp, DefaultRootWindow(disp),
461 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
462 &ret_type, &ret_format, &nr_item,
463 &sz_remains_data, (unsigned char**)&key_list) != Success)
465 fprintf(stderr, "[utilX][%s] Fail to get root window property !\n", __FUNCTION__);
470 printf("[%s] keycode = %d\n", __FUNCTION__, keycode);
473 for( i=0 ; i < nr_item ; i++ )
475 if( key_list && (key_list[i] == keycode) )
479 XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
480 nr_item ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
488 static void _unset_exclusive_grab_info_to_root (Display *disp, int keycode, int grab_mode)
491 unsigned long cnt = 0;
492 int *key_list = NULL;
493 int *new_key_list = NULL;
497 unsigned long nr_item;
498 unsigned long sz_remains_data;
501 if( grab_mode == EXCLUSIVE_GRAB )
503 if( _atom_grab_excl_win == None )
504 _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
505 ex_grabwin = _atom_grab_excl_win;
507 else if( grab_mode == OR_EXCLUSIVE_GRAB )
509 if( _atom_grab_or_excl_win == None )
510 _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
511 ex_grabwin = _atom_grab_or_excl_win;
516 if (XGetWindowProperty(disp, DefaultRootWindow(disp),
517 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
518 &ret_type, &ret_format, &nr_item,
519 &sz_remains_data, (unsigned char**)&key_list) != Success)
526 fprintf(stderr, "
\e[32m[utilX][%s] keycode = %d
\e[0m\n", __FUNCTION__, keycode);
530 for( i=0 ; i < nr_item ; i++ )
532 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
540 fprintf(stderr, "[utilX][%s] cnt = %d, nr_item = %d\n", __FUNCTION__, cnt, nr_item);
545 new_key_list = malloc(sizeof(int)*cnt);
553 //fprintf(stderr, "
\e[32m[utilX][%s] Fail to allocation memory for new_key_list !
\e[0m\n", __FUNCTION__);
554 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
559 for( i=0 ; i < nr_item ; i++ )
561 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
566 new_key_list[cnt++] = key_list[i];
570 XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
571 PropModeReplace, (unsigned char *)new_key_list, cnt);
574 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
586 static int _is_grabbed_key_exclusively (Display* disp, int keycode, int grab_mode)
589 int *key_list = NULL;
593 unsigned long nr_item;
594 unsigned long sz_remains_data;
597 if( grab_mode == EXCLUSIVE_GRAB )
599 if( _atom_grab_excl_win == None )
600 _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
601 ex_grabwin = _atom_grab_excl_win;
603 else if( grab_mode == OR_EXCLUSIVE_GRAB )
605 if( _atom_grab_or_excl_win == None )
606 _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
607 ex_grabwin = _atom_grab_or_excl_win;
612 if (XGetWindowProperty(disp, DefaultRootWindow(disp),
613 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
614 &ret_type, &ret_format, &nr_item,
615 &sz_remains_data, (unsigned char**)&key_list) != Success)
617 fprintf(stderr, "[%s] Fail to get root window property !\n", __FUNCTION__);
621 for( i=0 ; i < nr_item ; i++ )
623 if( key_list[i] == keycode )
624 return EXCLUSIVE_GRABBED_ALREADY;
631 API int utilx_grab_key (Display* disp, Window win, const char* key, int grab_mode)
634 int *key_list = NULL;
642 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
646 if (_atom_grab_key == None) {
647 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
650 if (!strncmp(key, "Keycode-", 8)) {
651 keycode = atoi(key + 8);
653 keysym = XStringToKeysym(key);
654 if (keysym == NoSymbol) goto out;
655 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
657 if (keycode == 0) goto out;
659 if( grab_mode == EXCLUSIVE_GRAB )
662 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
665 printf("[%s] _is_grabbed_key_exclusively returns result = %d\n", __FUNCTION__, result);
670 fprintf(stderr, "[%s] keycode(%d) was already grabbed exclusively (grab_mode=0x%X) !\n", __FUNCTION__, keycode, grab_mode);
674 else if( grab_mode == OR_EXCLUSIVE_GRAB )
676 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
680 fprintf(stderr, "[%s] Keycode(%d) was already grabbed with overridable exclusive mode (grab_mode=0x%x)\n", __FUNCTION__, keycode, grab_mode);
681 fprintf(stderr, "[%s] Now it will be overridden by a new window(0x%x) !\n", __FUNCTION__, win);
682 utilx_ungrab_key(disp, win, key);
686 keycode |= grab_mode;
688 cnt = _get_list_of_grabbed_key(disp, win, &key_list);
690 i = _search_grabbed_key(key_list, keycode, cnt);
691 _free_list_of_grabbed_key(key_list);
693 if( grab_mode == OR_EXCLUSIVE_GRAB )
695 utilx_ungrab_key(disp, win, key);
699 fprintf(stderr, "Key is already grabbed\n");
705 XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
706 cnt ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
708 keycode = keycode & (~GRAB_MODE_MASK);
710 printf("[%s] keycode = %d\n", __FUNCTION__, keycode);
713 if( EXCLUSIVE_GRAB == grab_mode || OR_EXCLUSIVE_GRAB == grab_mode )
714 _set_exclusive_grab_info_to_root(disp, keycode, win, grab_mode);
724 API int utilx_ungrab_key (Display* disp, Window win, const char* key)
728 int *key_list = NULL;
729 int *new_key_list = NULL;
737 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
741 if (_atom_grab_key == None) {
742 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
745 if (!strncmp(key, "Keycode-", 8)) {
746 keycode = atoi(key + 8);
748 keysym = XStringToKeysym(key);
749 if (keysym == NoSymbol) goto out;
750 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
752 if (keycode == 0) goto out;
754 cnt = _get_list_of_grabbed_key(disp, win, &key_list);
755 if (cnt == 0) goto out;
758 i = _search_grabbed_key(key_list, keycode | EXCLUSIVE_GRAB, cnt);
763 i = _search_grabbed_key(key_list, keycode | OR_EXCLUSIVE_GRAB, cnt);
768 i = _search_grabbed_key(key_list, keycode | TOP_POSITION_GRAB, cnt);
773 i = _search_grabbed_key(key_list, keycode | SHARED_GRAB, cnt);
777 _free_list_of_grabbed_key(key_list);
784 _unset_exclusive_grab_info_to_root(disp, keycode, OR_EXCLUSIVE_GRAB);
789 _unset_exclusive_grab_info_to_root(disp, keycode, EXCLUSIVE_GRAB);
792 new_key_list = _del_grabbed_key(key_list, i, &cnt);
793 _free_list_of_grabbed_key(key_list);
796 XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
797 PropModeReplace, (unsigned char *)new_key_list, cnt);
800 XDeleteProperty(disp, win, _atom_grab_key);
804 _free_new_list_of_grabbed_key(new_key_list);
813 API Utilx_Key_Status utilx_get_key_status(Display* dpy, char *key_name)
815 unsigned char keymap[32];
816 static unsigned int masktable[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
817 Utilx_Key_Status status = UTILX_KEY_STATUS_UNKNOWN;
819 if( !strncmp(key_name, KEY_VOLUMEDOWN, LEN_KEY_VOLUMEDOWN) ||
820 !strncmp(key_name, KEY_VOLUMEUP, LEN_KEY_VOLUMEUP) ||
821 !strncmp(key_name, KEY_PAUSE, LEN_KEY_PAUSE) ||
822 !strncmp(key_name, KEY_SEND, LEN_KEY_SEND) ||
823 !strncmp(key_name, KEY_SELECT, LEN_KEY_VOLUMEDOWN) ||
824 !strncmp(key_name, KEY_END, LEN_KEY_END) ||
825 !strncmp(key_name, KEY_POWER, LEN_KEY_POWER) ||
826 !strncmp(key_name, KEY_CAMERA, LEN_KEY_CAMERA) ||
827 !strncmp(key_name, KEY_CONFIG, LEN_KEY_CONFIG) ||
828 !strncmp(key_name, KEY_PLAYCD, LEN_KEY_PLAYCD) ||
829 !strncmp(key_name, KEY_STOPCD, LEN_KEY_STOPCD) ||
830 !strncmp(key_name, KEY_PAUSECD, LEN_KEY_PAUSECD) ||
831 !strncmp(key_name, KEY_NEXTSONG, LEN_KEY_NEXTSONG) ||
832 !strncmp(key_name, KEY_PREVIOUSSONG, LEN_KEY_PREVIOUSSONG) ||
833 !strncmp(key_name, KEY_REWIND, LEN_KEY_REWIND) ||
834 !strncmp(key_name, KEY_FASTFORWARD, LEN_KEY_FASTFORWARD) ||
835 !strncmp(key_name, KEY_MEDIA, LEN_KEY_MEDIA) )
837 KeySym ks = XStringToKeysym(key_name);
838 KeyCode kc = XKeysymToKeycode(dpy, ks);
842 XQueryKeymap(dpy, (char *)keymap);
843 if( keymap[kc >> 3] & masktable[kc & 7] )
844 status = UTILX_KEY_STATUS_PRESSED;
846 status = UTILX_KEY_STATUS_RELEASED;
853 API void utilx_set_window_effect_state(Display* dpy, Window win, int state)
857 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
860 if( !_atom_comp_effect_state)
861 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
863 _utilx_set_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
868 API int utilx_get_window_effect_state(Display* dpy, Window win)
871 if( !_atom_comp_effect_state)
872 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
873 _utilx_get_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
878 _utilx_string_set_window_property( Display *dpy, Window win, Atom atom, char *val, unsigned int num)
880 XChangeProperty( dpy, win, atom, XA_STRING, 8, PropModeReplace, (unsigned char*)val, val ? strlen(val):0 );
883 API void utilx_set_fake_launch_img(Display* dpy, Window win, char *file_name)
885 //UTILX_TRACE ("[UTILX] utilx_set_effect_state... win = %x, show_state = %d\n", win, enable);
889 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
892 if( !_atom_comp_fake_launch_image)
893 _atom_comp_fake_launch_image = XInternAtom(dpy, "_E_COMP_FAKE_LAUNCH_IMAGE",False);
895 _utilx_string_set_window_property(dpy, win, _atom_comp_fake_launch_image, file_name, 1);
898 API void utilx_show_fake_effect( Display *dpy, Window win, char *fake_image_file )
902 _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
904 if( !_atom_comp_fake_launch )
906 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
910 utilx_set_fake_launch_img(dpy, win, fake_image_file);
914 // send fake client message
915 xev.xclient.type = ClientMessage;
916 xev.xclient.display = dpy;
917 xev.xclient.window = win;
918 xev.xclient.message_type = _atom_comp_fake_launch;
919 xev.xclient.format = 32;
920 xev.xclient.data.l[0] = 1; // 1 : start effect , 0 : end effect
921 xev.xclient.data.l[1] = 0;
922 xev.xclient.data.l[2] = 0;
923 xev.xclient.data.l[3] = 0;
924 xev.xclient.data.l[4] = 0;
926 XSendEvent( dpy, win, False,
927 SubstructureRedirectMask | SubstructureNotifyMask,
934 API void utilx_hide_fake_effect( Display *dpy, Window win)
938 _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
939 if( !_atom_comp_fake_launch )
941 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
945 // send fake client message
946 xev.xclient.type = ClientMessage;
947 xev.xclient.display = dpy;
948 xev.xclient.window = win;
949 xev.xclient.message_type = _atom_comp_fake_launch;
950 xev.xclient.format = 32;
951 xev.xclient.data.l[0] = 0; // 1 : start effect , 0 : end effect
952 xev.xclient.data.l[1] = 0;
953 xev.xclient.data.l[2] = 0;
954 xev.xclient.data.l[3] = 0;
955 xev.xclient.data.l[4] = 0;
957 XSendEvent( dpy, win, False,
958 SubstructureRedirectMask | SubstructureNotifyMask,
963 static void _utilx_effect_atom_check( Display* dpy )
967 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
971 if( !_atom_comp_window_effect_type)
972 _atom_comp_window_effect_type = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_TYPE",False);
973 if( !_atom_comp_effect_default )
974 _atom_comp_effect_default = XInternAtom(dpy, "_NET_CM_EFFECT_DEFAULT",False);
975 if( !_atom_comp_effect_none )
976 _atom_comp_effect_none = XInternAtom(dpy, "_NET_CM_EFFECT_NONE",False);
977 if( !_atom_comp_effect_custom0 )
978 _atom_comp_effect_custom0 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM0",False);
979 if( !_atom_comp_effect_custom1 )
980 _atom_comp_effect_custom1 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM1",False);
981 if( !_atom_comp_effect_custom2 )
982 _atom_comp_effect_custom2 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM2",False);
983 if( !_atom_comp_effect_custom3 )
984 _atom_comp_effect_custom3 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM3",False);
985 if( !_atom_comp_effect_custom4 )
986 _atom_comp_effect_custom4 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM4",False);
987 if( !_atom_comp_effect_custom5 )
988 _atom_comp_effect_custom5 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM5",False);
989 if( !_atom_comp_effect_custom6 )
990 _atom_comp_effect_custom6 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM6",False);
991 if( !_atom_comp_effect_custom7 )
992 _atom_comp_effect_custom7 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM7",False);
993 if( !_atom_comp_effect_custom8 )
994 _atom_comp_effect_custom8 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM8",False);
995 if( !_atom_comp_effect_custom9 )
996 _atom_comp_effect_custom9 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM9",False);
999 static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style )
1003 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1004 return _atom_comp_effect_none;
1006 _utilx_effect_atom_check(dpy);
1008 if ( style == UTILX_EFFECT_STYLE_DEFAULT ) return _atom_comp_effect_default;
1009 else if ( style == UTILX_EFFECT_STYLE_NONE ) return _atom_comp_effect_none;
1010 else if ( style == UTILX_EFFECT_STYLE_CUSTOM0 ) return _atom_comp_effect_custom0;
1011 else if ( style == UTILX_EFFECT_STYLE_CUSTOM1 ) return _atom_comp_effect_custom1;
1012 else if ( style == UTILX_EFFECT_STYLE_CUSTOM2 ) return _atom_comp_effect_custom2;
1013 else if ( style == UTILX_EFFECT_STYLE_CUSTOM3 ) return _atom_comp_effect_custom3;
1014 else if ( style == UTILX_EFFECT_STYLE_CUSTOM4 ) return _atom_comp_effect_custom4;
1015 else if ( style == UTILX_EFFECT_STYLE_CUSTOM5 ) return _atom_comp_effect_custom5;
1016 else if ( style == UTILX_EFFECT_STYLE_CUSTOM6 ) return _atom_comp_effect_custom6;
1017 else if ( style == UTILX_EFFECT_STYLE_CUSTOM7 ) return _atom_comp_effect_custom7;
1018 else if ( style == UTILX_EFFECT_STYLE_CUSTOM8 ) return _atom_comp_effect_custom8;
1019 else if ( style == UTILX_EFFECT_STYLE_CUSTOM9 ) return _atom_comp_effect_custom9;
1020 else return _atom_comp_effect_none;
1024 static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style )
1028 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1029 return UTILX_EFFECT_STYLE_NONE;
1031 _utilx_effect_atom_check(dpy);
1033 if ( style == _atom_comp_effect_default ) return UTILX_EFFECT_STYLE_DEFAULT;
1034 else if ( style == _atom_comp_effect_none ) return UTILX_EFFECT_STYLE_NONE;
1035 else if ( style == _atom_comp_effect_custom0 ) return UTILX_EFFECT_STYLE_CUSTOM0;
1036 else if ( style == _atom_comp_effect_custom1 ) return UTILX_EFFECT_STYLE_CUSTOM1;
1037 else if ( style == _atom_comp_effect_custom2 ) return UTILX_EFFECT_STYLE_CUSTOM2;
1038 else if ( style == _atom_comp_effect_custom3 ) return UTILX_EFFECT_STYLE_CUSTOM3;
1039 else if ( style == _atom_comp_effect_custom4 ) return UTILX_EFFECT_STYLE_CUSTOM4;
1040 else if ( style == _atom_comp_effect_custom5 ) return UTILX_EFFECT_STYLE_CUSTOM5;
1041 else if ( style == _atom_comp_effect_custom6 ) return UTILX_EFFECT_STYLE_CUSTOM6;
1042 else if ( style == _atom_comp_effect_custom7 ) return UTILX_EFFECT_STYLE_CUSTOM7;
1043 else if ( style == _atom_comp_effect_custom8 ) return UTILX_EFFECT_STYLE_CUSTOM8;
1044 else if ( style == _atom_comp_effect_custom9 ) return UTILX_EFFECT_STYLE_CUSTOM9;
1045 else return UTILX_EFFECT_STYLE_DEFAULT;
1048 API void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style)
1050 Atom *window_effect_type_list = NULL;
1053 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1056 _utilx_effect_atom_check(dpy);
1058 window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1060 if ( !window_effect_type_list )
1062 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1066 window_effect_type_list[0] = _atom_comp_effect_default;
1067 window_effect_type_list[1] = _atom_comp_effect_default;
1068 window_effect_type_list[2] = _atom_comp_effect_default;
1069 window_effect_type_list[3] = _atom_comp_effect_default;
1070 window_effect_type_list[4] = _atom_comp_effect_default;
1071 window_effect_type_list[5] = _atom_comp_effect_default;
1073 _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1075 if ( type == UTILX_EFFECT_TYPE_MAP ) window_effect_type_list[0] = _utilx_convert_style_to_atom(dpy, style);
1076 else if ( type == UTILX_EFFECT_TYPE_UNMAP ) window_effect_type_list[1] = _utilx_convert_style_to_atom(dpy, style);
1077 else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) window_effect_type_list[2] = _utilx_convert_style_to_atom(dpy, style);
1078 else if ( type == UTILX_EFFECT_TYPE_ROTATION ) window_effect_type_list[3] = _utilx_convert_style_to_atom(dpy, style);
1079 else if ( type == UTILX_EFFECT_TYPE_FOCUSIN ) window_effect_type_list[4] = _utilx_convert_style_to_atom(dpy, style);
1080 else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT ) window_effect_type_list[5] = _utilx_convert_style_to_atom(dpy, style);
1082 _utilx_set_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1085 free(window_effect_type_list);
1088 API Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type)
1090 Atom *window_effect_type_list = NULL;
1091 Utilx_Effect_Style style = UTILX_EFFECT_STYLE_DEFAULT;
1095 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1096 return UTILX_EFFECT_STYLE_NONE;
1098 _utilx_effect_atom_check(dpy);
1100 window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1102 if ( !window_effect_type_list )
1104 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1105 return UTILX_EFFECT_STYLE_NONE;
1108 if ( _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6) != 6 )
1110 fprintf (stderr, "[UTILX] Error.. get property failed!.. %s (%d)\n", __func__, __LINE__);
1111 free(window_effect_type_list);
1112 return UTILX_EFFECT_STYLE_NONE;
1115 if ( type == UTILX_EFFECT_TYPE_MAP ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[0]);
1116 else if ( type == UTILX_EFFECT_TYPE_UNMAP ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[1]);
1117 else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[2]);
1118 else if ( type == UTILX_EFFECT_TYPE_ROTATION ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[3]);
1119 else if ( type == UTILX_EFFECT_TYPE_FOCUSIN ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[4]);
1120 else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[5]);
1123 free(window_effect_type_list);
1127 API int utilx_set_window_opaque_state (Display* dpy, Window win, Utilx_Opaque_State state)
1129 UTILX_TRACE ("[UTILX] utilx_set_window_opaque_state... win = %x, show_state = %d\n", win, state);
1131 unsigned int is_opaque;
1135 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1141 case UTILX_OPAQUE_STATE_OFF:
1145 case UTILX_OPAQUE_STATE_ON:
1150 fprintf (stderr, "[UTILX] Error.. Invald State.. %s (%d)\n", __func__, __LINE__);
1154 if (!_atom_window_opaque)
1156 _atom_window_opaque = XInternAtom (dpy, "_E_ILLUME_WINDOW_REGION_OPAQUE", False);
1157 if (!_atom_window_opaque)
1159 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_WINDOW_REGION_OPAQUE atom.. %s (%d)\n", __func__, __LINE__);
1164 _utilx_set_window_property (dpy, win, _atom_window_opaque, XA_CARDINAL,
1165 (unsigned int *)&is_opaque, 1);
1171 _utilx_screen_capture_atom_ensure (Display* dpy)
1173 if (_atom_screen_capture_disable)
1176 _atom_screen_capture_disable = XInternAtom (dpy, "_CB_SCREEN_CAPTURE_DISABLE", False);
1177 if (_atom_screen_capture_disable)
1180 fprintf (stderr, "[UTILX] Error.. Cannot create _CB_SCREEN_CAPTURE_DISABLE atom.. %s (%d)\n", __func__, __LINE__);
1184 utilx_set_screen_capture(Display* dpy, int enable)
1191 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1195 root = RootWindow (dpy, DefaultScreen(dpy));
1196 disable = (enable) ? 0 : 1;
1198 _utilx_screen_capture_atom_ensure (dpy);
1200 _utilx_set_window_property (dpy, root, _atom_screen_capture_disable, XA_CARDINAL, (unsigned int *)&disable, 1);
1206 utilx_get_screen_capture(Display* dpy)
1213 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1217 root = RootWindow (dpy, DefaultScreen(dpy));
1219 _utilx_screen_capture_atom_ensure (dpy);
1221 _utilx_get_window_property(dpy, root, _atom_screen_capture_disable, XA_CARDINAL,
1222 (unsigned int *)&disable, 1);
1224 return (disable) ? 0 : 1;
1227 API void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value)
1229 _utilx_set_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1232 API int utilx_get_window_cardinal_property (Display* dpy, Window win, Atom atom, unsigned int *value)
1234 return _utilx_get_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1237 API void utilx_show_capture_effect( Display *dpy, Window win)
1241 _atom_comp_capture_effect = XInternAtom( dpy, "_E_COMP_CAPTURE_EFFECT", False );
1242 if( !_atom_comp_capture_effect )
1244 fprintf( stderr, "XInternAtom(_E_COMP_CAPTURE_EFFECT) failed.\n" );
1248 // send capture effect client message
1249 xev.xclient.type = ClientMessage;
1250 xev.xclient.display = dpy;
1251 xev.xclient.window = win;
1252 xev.xclient.message_type = _atom_comp_capture_effect;
1253 xev.xclient.format = 32;
1254 xev.xclient.data.l[0] = 0;
1255 xev.xclient.data.l[1] = 0;
1256 xev.xclient.data.l[2] = 0;
1257 xev.xclient.data.l[3] = 0;
1258 xev.xclient.data.l[4] = 0;
1260 XSendEvent( dpy, win, False,
1261 SubstructureRedirectMask | SubstructureNotifyMask,
1266 API UtilxScrnConf *utilx_scrnconf_allocate (void)
1268 UtilxScrnConf *scrnconf = calloc (1, sizeof(UtilxScrnConf));
1271 fprintf (stderr, "fail to allocate UtilxScrnConf\n");
1278 API void utilx_scrnconf_free (UtilxScrnConf *scrnconf)
1283 if (scrnconf->str_output)
1284 free (scrnconf->str_output);
1286 if (scrnconf->str_resolution)
1287 free (scrnconf->str_resolution);
1293 API int utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf)
1295 Window win = DefaultRootWindow(dpy);
1296 Atom scrnconf_atom = None;
1305 scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_INFO", False);
1308 if (XGetTextProperty (dpy, win, &xtp, scrnconf_atom))
1310 s = XmbTextPropertyToTextList (dpy, &xtp, &list, &items);
1311 if ((s == XLocaleNotSupported) ||
1312 (s == XNoMemory) || (s == XConverterNotFound))
1313 str = strdup((char *)xtp.value);
1314 else if ((s >= Success) && (items > 0))
1315 str = strdup(list[0]);
1318 XFreeStringList (list);
1323 ptr = strtok (str, ",");
1328 scrnconf->str_output = calloc (1, strlen(ptr));
1329 if (!scrnconf->str_output)
1332 strcpy (scrnconf->str_output, ptr);
1336 if (!strcmp(ptr, "CONNECT"))
1337 scrnconf->status = UTILX_SCRNCONF_STATUS_CONNECT;
1338 else if (!strcmp(ptr, "ACTIVE"))
1339 scrnconf->status = UTILX_SCRNCONF_STATUS_ACTIVE;
1341 scrnconf->status = UTILX_SCRNCONF_STATUS_NULL;
1345 scrnconf->str_resolution = calloc (1, strlen(ptr));
1346 if (!scrnconf->str_resolution)
1349 strcpy (scrnconf->str_resolution, ptr);
1353 if (!strcmp(ptr, "CLONE"))
1354 scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_CLONE;
1355 else if (!strcmp(ptr, "EXTENDED"))
1356 scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED;
1358 scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_NULL;
1363 ptr = strtok (NULL, ",");
1377 API int utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode)
1379 Window win = DefaultRootWindow(dpy);
1381 Atom scrnconf_atom = None;
1382 UtilxScrnConf *scrnconf = NULL;
1384 scrnconf = utilx_scrnconf_allocate ();
1388 if (!utilx_scrnconf_get_info (dpy, scrnconf))
1390 utilx_scrnconf_free (scrnconf);
1394 if (scrnconf->status == UTILX_SCRNCONF_STATUS_NULL)
1396 fprintf (stderr, "[utilx_scrnconf]: the status of screen configuration is null\n");
1397 utilx_scrnconf_free (scrnconf);
1401 if (scrnconf->dispmode == dispmode)
1403 fprintf (stderr, "[utilx_scrnconf]: dispmode (%d) already set\n", dispmode);
1404 utilx_scrnconf_free (scrnconf);
1408 utilx_scrnconf_free (scrnconf);
1410 scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_DISPMODE_SET", False);
1412 xev.xclient.window = win;
1413 xev.xclient.type = ClientMessage;
1414 xev.xclient.message_type = scrnconf_atom;
1415 xev.xclient.format = 32;
1416 xev.xclient.data.s[0] = dispmode;
1418 XSendEvent(dpy, win, False, StructureNotifyMask, &xev);
1424 typedef struct _ShotInfo
1431 unsigned int height;
1443 DRI2Buffer* dri2_buffers;
1449 XShmSegmentInfo shminfo;
1452 #define FOURCC(a,b,c,d) (((unsigned)d&0xff)<<24 | ((unsigned)c&0xff)<<16 | ((unsigned)b&0xff)<<8 | ((unsigned)a&0xff))
1454 #define FOURCC_RGB32 FOURCC('R','G','B','4')
1455 #define TIMEOUT_CAPTURE 3
1457 /* x error handling */
1458 static Bool x_error_caught;
1460 static ShotInfo *shot_info;
1463 _get_port (Display *dpy, unsigned int id)
1465 unsigned int ver, rev, req_base, evt_base, err_base;
1466 unsigned int adaptors;
1467 XvAdaptorInfo *ai = NULL;
1468 XvImageFormatValues *fo = NULL;
1472 if (XvQueryExtension (dpy, &ver, &rev, &req_base, &evt_base, &err_base) != Success)
1474 fprintf (stderr, "[UTILX] no XV extension. \n");
1478 if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &adaptors, &ai) != Success)
1480 fprintf (stderr, "[UTILX] fail : query adaptors. \n");
1486 fprintf (stderr, "[UTILX] fail : get adaptor info. \n");
1490 for (i = 0; i < adaptors; i++)
1492 int support_format = False;
1494 if (!(ai[i].type & XvInputMask) ||
1495 !(ai[i].type & XvStillMask))
1500 fo = XvListImageFormats (dpy, p, &formats);
1501 for (j = 0; j < formats; j++)
1502 if (fo[j].id == (int)id)
1503 support_format = True;
1508 if (!support_format)
1511 if (XvGrabPort (dpy, p, 0) == Success)
1513 XvFreeAdaptorInfo (ai);
1517 fprintf (stderr, "[UTILX] fail : grab port. \n");
1520 XvFreeAdaptorInfo (ai);
1526 _deinit_screen_shot (ShotInfo *info)
1528 static Atom atom_stream_off = None;
1533 if (atom_stream_off == None)
1534 atom_stream_off = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False);
1536 XvSetPortAttribute (info->dpy, info->port, atom_stream_off, 1);
1539 XDestroyImage (info->image);
1540 if (info->shminfo.shmid != -1)
1542 XShmDetach (info->dpy, &info->shminfo);
1543 shmdt (info->shminfo.shmaddr);
1544 shmctl (info->shminfo.shmid, IPC_RMID, 0);
1548 tbm_bo_unref(info->bo);
1549 if (info->dri2_buffers)
1550 free(info->dri2_buffers);
1552 tbm_bufmgr_deinit (info->bufmgr);
1553 if (info->drm_fd >= 0)
1554 close (info->drm_fd);
1557 XDamageDestroy (info->dpy, info->damage);
1560 XFreeGC (info->dpy, info->gc);
1561 if (info->pixmap > 0)
1562 XFreePixmap (info->dpy, info->pixmap);
1564 XvUngrabPort (info->dpy, info->port, 0);
1566 XSync (info->dpy, False);
1573 _screen_shot_x_error_handle (Display *dpy, XErrorEvent *ev)
1575 if (!shot_info || (dpy != shot_info->dpy))
1578 x_error_caught = True;
1584 _init_screen_shot_damage (ShotInfo *info)
1586 int damage_err_base = 0;
1588 if (!XDamageQueryExtension(info->dpy, &info->damage_base, &damage_err_base))
1590 fprintf (stderr, "[UTILX] no X Damage extension. \n");
1594 info->damage = XDamageCreate (info->dpy, info->pixmap, XDamageReportNonEmpty);
1595 if (info->damage <= 0)
1597 fprintf (stderr, "[UTILX] fail : create damage \n");
1605 _init_screen_shot_dri2 (ShotInfo *info)
1609 int dri2_err_base = 0;
1610 int dri2Major, dri2Minor;
1611 char *driverName = NULL, *deviceName = NULL;
1612 unsigned int attachments[1];
1613 int dri2_count, dri2_out_count;
1614 int dri2_width, dri2_height, dri2_stride;
1616 tbm_bo_handle bo_handle;
1618 screen = DefaultScreen(info->dpy);
1619 if (!DRI2QueryExtension (info->dpy, &dri2_base, &dri2_err_base))
1621 fprintf (stderr, "[UTILX] no DRI2 extension. !!\n");
1622 goto fail_init_dri2;
1625 if (!DRI2QueryVersion (info->dpy, &dri2Major, &dri2Minor))
1627 fprintf (stderr, "[UTILX] fail : DRI2QueryVersion !!\n");
1628 goto fail_init_dri2;
1631 if (!DRI2Connect (info->dpy, RootWindow(info->dpy, screen), &driverName, &deviceName))
1633 fprintf (stderr, "[UTILX] fail : DRI2Connect !!\n");
1634 goto fail_init_dri2;
1638 info->drm_fd = open (deviceName, O_RDWR);
1639 if (info->drm_fd < 0)
1641 fprintf (stderr, "[UTILX] fail : open drm device (%s)\n", deviceName);
1642 goto fail_init_dri2;
1645 /* get the drm magic */
1646 drmGetMagic(info->drm_fd, &magic);
1647 if (!DRI2Authenticate(info->dpy, RootWindow(info->dpy, screen), magic))
1649 fprintf (stderr, "[UTILX] fail : DRI2Authenticate (%d)\n", magic);
1650 goto fail_init_dri2;
1654 info->bufmgr = tbm_bufmgr_init (info->drm_fd);
1657 fprintf (stderr, "[UTILX] fail : init buffer manager \n");
1658 goto fail_init_dri2;
1661 DRI2CreateDrawable (info->dpy, info->pixmap);
1663 attachments[0] = DRI2BufferFrontLeft;
1665 info->dri2_buffers = DRI2GetBuffers (info->dpy, info->pixmap, &dri2_width, &dri2_height,
1666 attachments, dri2_count, &dri2_out_count);
1668 if (!info->dri2_buffers)
1670 fprintf (stderr, "[UTILX] fail : get buffers\n");
1671 goto fail_init_dri2;
1674 if (!info->dri2_buffers[0].name)
1676 fprintf (stderr, "[UTILX] fail : a handle of the dri2 buffer is null \n ");
1677 goto fail_init_dri2;
1680 info->bo = tbm_bo_import (info->bufmgr, info->dri2_buffers[0].name);
1683 fprintf (stderr, "[UTILX] fail : import bo (key:%d)\n", info->dri2_buffers[0].name);
1684 goto fail_init_dri2;
1687 dri2_stride = info->dri2_buffers[0].pitch;
1690 bo_handle = tbm_bo_get_handle (info->bo, TBM_DEVICE_CPU);
1691 info->virtual = (void *)bo_handle.ptr;
1694 fprintf (stderr, "[UTILX] fail : map \n");
1695 goto fail_init_dri2;
1698 info->enable_xshm = False;
1705 tbm_bo_unref(info->bo);
1706 if (info->dri2_buffers)
1707 free(info->dri2_buffers);
1709 tbm_bufmgr_deinit (info->bufmgr);
1710 if (info->drm_fd >= 0)
1711 close (info->drm_fd);
1717 _init_screen_shot_shm (ShotInfo *info)
1719 if (!XShmQueryExtension (info->dpy))
1721 fprintf (stderr, "[UTILX] no XShm extension. !!\n");
1725 info->image = XShmCreateImage (info->dpy,
1726 DefaultVisual (info->dpy, DefaultScreen (info->dpy)),
1727 DefaultDepth (info->dpy, DefaultScreen (info->dpy)),
1735 fprintf (stderr, "[UTILX] fail : XShmCreateImage \n");
1739 info->shminfo.shmid = shmget (IPC_PRIVATE, info->image->bytes_per_line * info->height, IPC_CREAT | 0777);
1740 if (info->shminfo.shmid == -1)
1742 XDestroyImage (info->image);
1743 fprintf (stderr, "[UTILX] fail : shmget\n");
1747 info->shminfo.shmaddr = shmat (info->shminfo.shmid, 0, 0);
1748 if (info->shminfo.shmaddr == (void *) -1)
1750 XDestroyImage (info->image);
1751 shmctl (info->shminfo.shmid, IPC_RMID, 0);
1752 info->shminfo.shmid = -1;
1753 fprintf (stderr, "[UTILX] fail : shmat\n");
1757 info->shminfo.readOnly = False;
1759 if (!XShmAttach (info->dpy, &info->shminfo))
1761 XDestroyImage (info->image);
1762 shmdt (info->shminfo.shmaddr);
1763 shmctl (info->shminfo.shmid, IPC_RMID, 0);
1764 info->shminfo.shmid = -1;
1765 fprintf (stderr, "[UTILX] fail : XShmAttach\n");
1769 info->image->data = info->shminfo.shmaddr;
1770 info->virtual = info->shminfo.shmaddr;
1772 info->enable_xshm = True;
1778 _init_screen_shot (Display* dpy, unsigned int width, unsigned int height)
1780 ShotInfo *info = NULL;
1781 static Atom atom_capture = None;
1782 static Atom atom_fps = None;
1783 XErrorHandler old_handler = NULL;
1787 if (shot_info->width == width && shot_info->height == height)
1790 _deinit_screen_shot (shot_info);
1793 info = calloc (1, sizeof (ShotInfo));
1801 info->shminfo.shmid = -1;
1802 info->shminfo.shmaddr = (void*)-1;
1806 info->port = _get_port (info->dpy, FOURCC_RGB32);
1807 if (info->port <= 0)
1811 if (atom_capture == None)
1812 atom_capture = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False);
1813 if (atom_fps == None)
1814 atom_fps = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_FPS", False);
1816 XSync (info->dpy, 0);
1817 x_error_caught = False;
1818 old_handler = XSetErrorHandler (_screen_shot_x_error_handle);
1820 XvSetPortAttribute (info->dpy, info->port, atom_capture, 1);
1821 XvSetPortAttribute (info->dpy, info->port, atom_fps, 60);
1823 XSync (info->dpy, 0);
1825 x_error_caught = False;
1826 XSetErrorHandler (old_handler);
1828 XvQueryBestSize (info->dpy, info->port, 0, 0, 0, width, height, &width, &height);
1829 if (width <= 0 || height <= 0)
1831 info->width = width;
1832 info->height = height;
1835 info->pixmap = XCreatePixmap (info->dpy,
1836 DefaultRootWindow (info->dpy),
1838 DefaultDepth (info->dpy, DefaultScreen (info->dpy)));
1839 if (info->pixmap <= 0)
1841 fprintf (stderr, "[UTILX] fail : create pixmap. \n");
1846 info->gc = XCreateGC (info->dpy, info->pixmap, 0, 0);
1847 if (info->gc == NULL)
1849 fprintf (stderr, "[UTILX] fail : create gc. \n");
1853 XSetForeground (info->dpy, info->gc, 0xFF000000);
1854 XFillRectangle (info->dpy, info->pixmap, info->gc, 0, 0, width, height);
1856 if (!_init_screen_shot_damage (info))
1859 if (!_init_screen_shot_dri2 (info))
1861 if (!_init_screen_shot_shm (info))
1864 fprintf (stderr, "[UTILX] XShm success. !!\n");
1869 fprintf (stderr, "[UTILX] fail : get virtual \n");
1878 _deinit_screen_shot (info);
1883 utilx_create_screen_shot (Display* dpy, int width, int height)
1887 XErrorHandler old_handler = NULL;
1891 fprintf (stderr, "[UTILX] invalid display(%p) \n", dpy);
1895 if (width <= 0 || height <= 0)
1897 fprintf (stderr, "[UTILX] invalid size(%dx%d) \n", width, height);
1903 info = _init_screen_shot (dpy, width, height);
1907 fprintf (stderr, "[UTILX] fail : initialize screenshot. \n");
1913 x_error_caught = False;
1914 old_handler = XSetErrorHandler (_screen_shot_x_error_handle);
1916 XvPutStill (info->dpy, info->port, info->pixmap, info->gc,
1917 0, 0, info->width, info->height,
1918 0, 0, info->width, info->height);
1924 x_error_caught = False;
1925 XSetErrorHandler (old_handler);
1929 x_error_caught = False;
1930 XSetErrorHandler (old_handler);
1932 if (XPending (info->dpy))
1933 XNextEvent (info->dpy, &ev);
1936 int fd = ConnectionNumber (info->dpy);
1945 tv.tv_sec = TIMEOUT_CAPTURE;
1947 ret = select (fd + 1, &mask, 0, 0, &tv);
1949 fprintf (stderr, "[UTILX] fail: select.\n");
1951 fprintf (stderr, "[UTILX] timeout(%d sec)!\n", TIMEOUT_CAPTURE);
1952 else if (XPending (info->dpy))
1953 XNextEvent (info->dpy, &ev);
1955 fprintf (stderr, "[UTILX] fail: not passed a event!\n");
1958 if (ev.type == (info->damage_base + XDamageNotify))
1960 XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev;
1961 if (damage_ev->drawable == info->pixmap)
1963 if (info->enable_xshm)
1964 XShmGetImage (info->dpy, info->pixmap, info->image, 0, 0, AllPlanes);
1966 XDamageSubtract (info->dpy, info->damage, None, None );
1967 return info->virtual;
1970 XDamageSubtract (info->dpy, info->damage, None, None );
1973 utilx_release_screen_shot ();
1979 utilx_release_screen_shot (void)
1981 _deinit_screen_shot (shot_info);
1984 #define XRR_PROPERTY_FB_VISIBLE "XRR_PROPERTY_FB_VISIBLE"
1985 #define XRR_PROPERTY_VIDEO_OFFSET "XRR_PROPERTY_VIDEO_OFFSET"
1988 _utilx_xrr_set_property (Display* dpy, Atom atom, unsigned char *buf, int buf_len, unsigned char **get)
1991 XRRScreenResources *res = NULL;
1992 RROutput rr_output = None;
1995 root = XRootWindow (dpy, 0);
1998 fprintf (stderr, "[UTILX] Warning : Root window is None.. %s (%d)\n", __func__, __LINE__);
2002 res = XRRGetScreenResources (dpy, root);
2003 if (res == NULL || res->noutput == 0)
2005 fprintf (stderr, "[UTILX] Warning : ScreenResources is None.. %s (%d)\n", __func__, __LINE__);
2009 for (i = 0; i < res->noutput; i++)
2011 XRROutputInfo *output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
2014 if (!strcmp (output_info->name, "LVDS1"))
2016 rr_output = res->outputs[i];
2017 XRRFreeOutputInfo(output_info);
2020 XRRFreeOutputInfo(output_info);
2024 if (rr_output == None)
2026 fprintf (stderr, "[UTILX] Warning : output is None.. %s (%d)\n", __func__, __LINE__);
2027 XRRFreeScreenResources (res);
2031 XRRChangeOutputProperty (dpy, rr_output, atom,
2032 XA_CARDINAL, 8, PropModeReplace, buf, buf_len);
2038 unsigned long nitems, bytes_after;
2040 XRRGetOutputProperty (dpy, rr_output, atom,
2042 True, False, XA_CARDINAL,
2043 &actual_type, &actual_format,
2044 &nitems, &bytes_after,
2050 XRRFreeScreenResources (res);
2056 utilx_set_fb_visible (Display* dpy, Utilx_Fb_Type fb, Bool visible)
2058 static Atom property = None;
2059 char buf[8192] = {0,};
2065 fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__);
2069 if (fb <= UTILX_FB_TYPE_NONE || fb > UTILX_FB_TYPE_OVERLAY)
2071 fprintf (stderr, "[UTILX] Error.. Invald fb(%d).. %s (%d)\n", fb, __func__, __LINE__);
2075 p += sprintf (p, "%d:", 0);
2076 p += sprintf (p, "%d", fb + 2);
2077 p += sprintf (p, ":%d", (visible > 0)? 1 : 0);
2084 if (property == None)
2085 property = XInternAtom (dpy, XRR_PROPERTY_FB_VISIBLE, False);
2087 if (property == None)
2089 fprintf (stderr, "[UTILX] Warning : FB_VISIBLE property is None.. %s (%d)\n", __func__, __LINE__);
2093 if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, NULL))
2095 fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__);
2101 utilx_get_fb_visible (Display* dpy, Utilx_Fb_Type fb)
2103 static Atom property = None;
2104 char buf[32] = {0,};
2107 unsigned char *prop = NULL;
2108 Bool visible = False;
2112 fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__);
2116 if (fb <= UTILX_FB_TYPE_NONE || fb > UTILX_FB_TYPE_OVERLAY)
2118 fprintf (stderr, "[UTILX] Error.. Invald fb(%d).. %s (%d)\n", fb, __func__, __LINE__);
2122 p += sprintf (p, "%d:", 0);
2123 p += sprintf (p, "%d", fb + 2);
2130 if (property == None)
2131 property = XInternAtom (dpy, XRR_PROPERTY_FB_VISIBLE, False);
2133 if (property == None)
2135 fprintf (stderr, "[UTILX] Warning : FB_VISIBLE property is None.. %s (%d)\n", __func__, __LINE__);
2139 if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, &prop))
2141 fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__);
2146 visible = atoi((char*)prop);
2152 utilx_set_video_offset (Display* dpy, int x, int y)
2154 static Atom property = None;
2155 char buf[32] = {0,};
2161 fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__);
2165 p += sprintf (p, "%d,%d", x, y);
2172 if (property == None)
2173 property = XInternAtom (dpy, XRR_PROPERTY_VIDEO_OFFSET, False);
2175 if (property == None)
2177 fprintf (stderr, "[UTILX] Warning : VIDEO_OFFSET property is None.. %s (%d)\n", __func__, __LINE__);
2181 if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, NULL))
2183 fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__);