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__);
469 for( i=0 ; i < nr_item ; i++ )
471 if( key_list && (key_list[i] == keycode) )
475 XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
476 nr_item ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
484 static void _unset_exclusive_grab_info_to_root (Display *disp, int keycode, int grab_mode)
487 unsigned long cnt = 0;
488 int *key_list = NULL;
489 int *new_key_list = NULL;
493 unsigned long nr_item;
494 unsigned long sz_remains_data;
497 if( grab_mode == EXCLUSIVE_GRAB )
499 if( _atom_grab_excl_win == None )
500 _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
501 ex_grabwin = _atom_grab_excl_win;
503 else if( grab_mode == OR_EXCLUSIVE_GRAB )
505 if( _atom_grab_or_excl_win == None )
506 _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
507 ex_grabwin = _atom_grab_or_excl_win;
512 if (XGetWindowProperty(disp, DefaultRootWindow(disp),
513 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
514 &ret_type, &ret_format, &nr_item,
515 &sz_remains_data, (unsigned char**)&key_list) != Success)
525 for( i=0 ; i < nr_item ; i++ )
527 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
536 new_key_list = malloc(sizeof(int)*cnt);
544 //fprintf(stderr, "
\e[32m[utilX][%s] Fail to allocation memory for new_key_list !
\e[0m\n", __FUNCTION__);
545 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
550 for( i=0 ; i < nr_item ; i++ )
552 if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB )
557 new_key_list[cnt++] = key_list[i];
561 XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32,
562 PropModeReplace, (unsigned char *)new_key_list, cnt);
565 XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin);
577 static int _is_grabbed_key_exclusively (Display* disp, int keycode, int grab_mode)
580 int *key_list = NULL;
584 unsigned long nr_item;
585 unsigned long sz_remains_data;
588 if( grab_mode == EXCLUSIVE_GRAB )
590 if( _atom_grab_excl_win == None )
591 _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False);
592 ex_grabwin = _atom_grab_excl_win;
594 else if( grab_mode == OR_EXCLUSIVE_GRAB )
596 if( _atom_grab_or_excl_win == None )
597 _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False);
598 ex_grabwin = _atom_grab_or_excl_win;
603 if (XGetWindowProperty(disp, DefaultRootWindow(disp),
604 ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL,
605 &ret_type, &ret_format, &nr_item,
606 &sz_remains_data, (unsigned char**)&key_list) != Success)
608 fprintf(stderr, "[%s] Fail to get root window property !\n", __FUNCTION__);
612 for( i=0 ; i < nr_item ; i++ )
614 if( key_list[i] == keycode )
615 return EXCLUSIVE_GRABBED_ALREADY;
622 API int utilx_grab_key (Display* disp, Window win, const char* key, int grab_mode)
625 int *key_list = NULL;
633 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
637 if (_atom_grab_key == None) {
638 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
641 if (!strncmp(key, "Keycode-", 8)) {
642 keycode = atoi(key + 8);
644 keysym = XStringToKeysym(key);
645 if (keysym == NoSymbol) goto out;
646 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
648 if (keycode == 0) goto out;
650 if( grab_mode == EXCLUSIVE_GRAB )
653 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
660 else if( grab_mode == OR_EXCLUSIVE_GRAB )
662 result = _is_grabbed_key_exclusively(disp, keycode, grab_mode);
666 utilx_ungrab_key(disp, win, key);
670 keycode |= grab_mode;
672 cnt = _get_list_of_grabbed_key(disp, win, &key_list);
674 i = _search_grabbed_key(key_list, keycode, cnt);
675 _free_list_of_grabbed_key(key_list);
677 if( grab_mode == OR_EXCLUSIVE_GRAB )
679 utilx_ungrab_key(disp, win, key);
683 fprintf(stderr, "Key is already grabbed\n");
689 XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
690 cnt ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1);
692 keycode = keycode & (~GRAB_MODE_MASK);
694 if( EXCLUSIVE_GRAB == grab_mode || OR_EXCLUSIVE_GRAB == grab_mode )
695 _set_exclusive_grab_info_to_root(disp, keycode, win, grab_mode);
705 API int utilx_ungrab_key (Display* disp, Window win, const char* key)
709 int *key_list = NULL;
710 int *new_key_list = NULL;
718 fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__);
722 if (_atom_grab_key == None) {
723 _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False);
726 if (!strncmp(key, "Keycode-", 8)) {
727 keycode = atoi(key + 8);
729 keysym = XStringToKeysym(key);
730 if (keysym == NoSymbol) goto out;
731 keycode = XKeysymToKeycode(disp, XStringToKeysym(key));
733 if (keycode == 0) goto out;
735 cnt = _get_list_of_grabbed_key(disp, win, &key_list);
736 if (cnt == 0) goto out;
739 i = _search_grabbed_key(key_list, keycode | EXCLUSIVE_GRAB, cnt);
744 i = _search_grabbed_key(key_list, keycode | OR_EXCLUSIVE_GRAB, cnt);
749 i = _search_grabbed_key(key_list, keycode | TOP_POSITION_GRAB, cnt);
754 i = _search_grabbed_key(key_list, keycode | SHARED_GRAB, cnt);
758 _free_list_of_grabbed_key(key_list);
765 _unset_exclusive_grab_info_to_root(disp, keycode, OR_EXCLUSIVE_GRAB);
770 _unset_exclusive_grab_info_to_root(disp, keycode, EXCLUSIVE_GRAB);
773 new_key_list = _del_grabbed_key(key_list, i, &cnt);
774 _free_list_of_grabbed_key(key_list);
777 XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32,
778 PropModeReplace, (unsigned char *)new_key_list, cnt);
781 XDeleteProperty(disp, win, _atom_grab_key);
785 _free_new_list_of_grabbed_key(new_key_list);
794 API Utilx_Key_Status utilx_get_key_status(Display* dpy, char *key_name)
796 unsigned char keymap[32];
797 static unsigned int masktable[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
798 Utilx_Key_Status status = UTILX_KEY_STATUS_UNKNOWN;
800 if( !strncmp(key_name, KEY_VOLUMEDOWN, LEN_KEY_VOLUMEDOWN) ||
801 !strncmp(key_name, KEY_VOLUMEUP, LEN_KEY_VOLUMEUP) ||
802 !strncmp(key_name, KEY_PAUSE, LEN_KEY_PAUSE) ||
803 !strncmp(key_name, KEY_SEND, LEN_KEY_SEND) ||
804 !strncmp(key_name, KEY_SELECT, LEN_KEY_VOLUMEDOWN) ||
805 !strncmp(key_name, KEY_END, LEN_KEY_END) ||
806 !strncmp(key_name, KEY_POWER, LEN_KEY_POWER) ||
807 !strncmp(key_name, KEY_CAMERA, LEN_KEY_CAMERA) ||
808 !strncmp(key_name, KEY_CONFIG, LEN_KEY_CONFIG) ||
809 !strncmp(key_name, KEY_PLAYCD, LEN_KEY_PLAYCD) ||
810 !strncmp(key_name, KEY_STOPCD, LEN_KEY_STOPCD) ||
811 !strncmp(key_name, KEY_PAUSECD, LEN_KEY_PAUSECD) ||
812 !strncmp(key_name, KEY_NEXTSONG, LEN_KEY_NEXTSONG) ||
813 !strncmp(key_name, KEY_PREVIOUSSONG, LEN_KEY_PREVIOUSSONG) ||
814 !strncmp(key_name, KEY_REWIND, LEN_KEY_REWIND) ||
815 !strncmp(key_name, KEY_FASTFORWARD, LEN_KEY_FASTFORWARD) ||
816 !strncmp(key_name, KEY_MEDIA, LEN_KEY_MEDIA) )
818 KeySym ks = XStringToKeysym(key_name);
819 KeyCode kc = XKeysymToKeycode(dpy, ks);
823 XQueryKeymap(dpy, (char *)keymap);
824 if( keymap[kc >> 3] & masktable[kc & 7] )
825 status = UTILX_KEY_STATUS_PRESSED;
827 status = UTILX_KEY_STATUS_RELEASED;
834 API void utilx_set_window_effect_state(Display* dpy, Window win, int state)
838 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
841 if( !_atom_comp_effect_state)
842 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
844 _utilx_set_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
849 API int utilx_get_window_effect_state(Display* dpy, Window win)
852 if( !_atom_comp_effect_state)
853 _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False);
854 _utilx_get_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1);
859 _utilx_string_set_window_property( Display *dpy, Window win, Atom atom, char *val, unsigned int num)
861 XChangeProperty( dpy, win, atom, XA_STRING, 8, PropModeReplace, (unsigned char*)val, val ? strlen(val):0 );
864 API void utilx_set_fake_launch_img(Display* dpy, Window win, char *file_name)
866 //UTILX_TRACE ("[UTILX] utilx_set_effect_state... win = %x, show_state = %d\n", win, enable);
870 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
873 if( !_atom_comp_fake_launch_image)
874 _atom_comp_fake_launch_image = XInternAtom(dpy, "_E_COMP_FAKE_LAUNCH_IMAGE",False);
876 _utilx_string_set_window_property(dpy, win, _atom_comp_fake_launch_image, file_name, 1);
879 API void utilx_show_fake_effect( Display *dpy, Window win, char *fake_image_file )
883 _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
885 if( !_atom_comp_fake_launch )
887 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
891 utilx_set_fake_launch_img(dpy, win, fake_image_file);
895 // send fake client message
896 xev.xclient.type = ClientMessage;
897 xev.xclient.display = dpy;
898 xev.xclient.window = win;
899 xev.xclient.message_type = _atom_comp_fake_launch;
900 xev.xclient.format = 32;
901 xev.xclient.data.l[0] = 1; // 1 : start effect , 0 : end effect
902 xev.xclient.data.l[1] = 0;
903 xev.xclient.data.l[2] = 0;
904 xev.xclient.data.l[3] = 0;
905 xev.xclient.data.l[4] = 0;
907 XSendEvent( dpy, win, False,
908 SubstructureRedirectMask | SubstructureNotifyMask,
915 API void utilx_hide_fake_effect( Display *dpy, Window win)
919 _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False );
920 if( !_atom_comp_fake_launch )
922 fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" );
926 // send fake client message
927 xev.xclient.type = ClientMessage;
928 xev.xclient.display = dpy;
929 xev.xclient.window = win;
930 xev.xclient.message_type = _atom_comp_fake_launch;
931 xev.xclient.format = 32;
932 xev.xclient.data.l[0] = 0; // 1 : start effect , 0 : end effect
933 xev.xclient.data.l[1] = 0;
934 xev.xclient.data.l[2] = 0;
935 xev.xclient.data.l[3] = 0;
936 xev.xclient.data.l[4] = 0;
938 XSendEvent( dpy, win, False,
939 SubstructureRedirectMask | SubstructureNotifyMask,
944 static void _utilx_effect_atom_check( Display* dpy )
948 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
952 if( !_atom_comp_window_effect_type)
953 _atom_comp_window_effect_type = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_TYPE",False);
954 if( !_atom_comp_effect_default )
955 _atom_comp_effect_default = XInternAtom(dpy, "_NET_CM_EFFECT_DEFAULT",False);
956 if( !_atom_comp_effect_none )
957 _atom_comp_effect_none = XInternAtom(dpy, "_NET_CM_EFFECT_NONE",False);
958 if( !_atom_comp_effect_custom0 )
959 _atom_comp_effect_custom0 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM0",False);
960 if( !_atom_comp_effect_custom1 )
961 _atom_comp_effect_custom1 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM1",False);
962 if( !_atom_comp_effect_custom2 )
963 _atom_comp_effect_custom2 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM2",False);
964 if( !_atom_comp_effect_custom3 )
965 _atom_comp_effect_custom3 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM3",False);
966 if( !_atom_comp_effect_custom4 )
967 _atom_comp_effect_custom4 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM4",False);
968 if( !_atom_comp_effect_custom5 )
969 _atom_comp_effect_custom5 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM5",False);
970 if( !_atom_comp_effect_custom6 )
971 _atom_comp_effect_custom6 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM6",False);
972 if( !_atom_comp_effect_custom7 )
973 _atom_comp_effect_custom7 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM7",False);
974 if( !_atom_comp_effect_custom8 )
975 _atom_comp_effect_custom8 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM8",False);
976 if( !_atom_comp_effect_custom9 )
977 _atom_comp_effect_custom9 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM9",False);
980 static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style )
984 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
985 return _atom_comp_effect_none;
987 _utilx_effect_atom_check(dpy);
989 if ( style == UTILX_EFFECT_STYLE_DEFAULT ) return _atom_comp_effect_default;
990 else if ( style == UTILX_EFFECT_STYLE_NONE ) return _atom_comp_effect_none;
991 else if ( style == UTILX_EFFECT_STYLE_CUSTOM0 ) return _atom_comp_effect_custom0;
992 else if ( style == UTILX_EFFECT_STYLE_CUSTOM1 ) return _atom_comp_effect_custom1;
993 else if ( style == UTILX_EFFECT_STYLE_CUSTOM2 ) return _atom_comp_effect_custom2;
994 else if ( style == UTILX_EFFECT_STYLE_CUSTOM3 ) return _atom_comp_effect_custom3;
995 else if ( style == UTILX_EFFECT_STYLE_CUSTOM4 ) return _atom_comp_effect_custom4;
996 else if ( style == UTILX_EFFECT_STYLE_CUSTOM5 ) return _atom_comp_effect_custom5;
997 else if ( style == UTILX_EFFECT_STYLE_CUSTOM6 ) return _atom_comp_effect_custom6;
998 else if ( style == UTILX_EFFECT_STYLE_CUSTOM7 ) return _atom_comp_effect_custom7;
999 else if ( style == UTILX_EFFECT_STYLE_CUSTOM8 ) return _atom_comp_effect_custom8;
1000 else if ( style == UTILX_EFFECT_STYLE_CUSTOM9 ) return _atom_comp_effect_custom9;
1001 else return _atom_comp_effect_none;
1005 static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style )
1009 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1010 return UTILX_EFFECT_STYLE_NONE;
1012 _utilx_effect_atom_check(dpy);
1014 if ( style == _atom_comp_effect_default ) return UTILX_EFFECT_STYLE_DEFAULT;
1015 else if ( style == _atom_comp_effect_none ) return UTILX_EFFECT_STYLE_NONE;
1016 else if ( style == _atom_comp_effect_custom0 ) return UTILX_EFFECT_STYLE_CUSTOM0;
1017 else if ( style == _atom_comp_effect_custom1 ) return UTILX_EFFECT_STYLE_CUSTOM1;
1018 else if ( style == _atom_comp_effect_custom2 ) return UTILX_EFFECT_STYLE_CUSTOM2;
1019 else if ( style == _atom_comp_effect_custom3 ) return UTILX_EFFECT_STYLE_CUSTOM3;
1020 else if ( style == _atom_comp_effect_custom4 ) return UTILX_EFFECT_STYLE_CUSTOM4;
1021 else if ( style == _atom_comp_effect_custom5 ) return UTILX_EFFECT_STYLE_CUSTOM5;
1022 else if ( style == _atom_comp_effect_custom6 ) return UTILX_EFFECT_STYLE_CUSTOM6;
1023 else if ( style == _atom_comp_effect_custom7 ) return UTILX_EFFECT_STYLE_CUSTOM7;
1024 else if ( style == _atom_comp_effect_custom8 ) return UTILX_EFFECT_STYLE_CUSTOM8;
1025 else if ( style == _atom_comp_effect_custom9 ) return UTILX_EFFECT_STYLE_CUSTOM9;
1026 else return UTILX_EFFECT_STYLE_DEFAULT;
1029 API void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style)
1031 Atom *window_effect_type_list = NULL;
1034 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1037 _utilx_effect_atom_check(dpy);
1039 window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1041 if ( !window_effect_type_list )
1043 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1047 window_effect_type_list[0] = _atom_comp_effect_default;
1048 window_effect_type_list[1] = _atom_comp_effect_default;
1049 window_effect_type_list[2] = _atom_comp_effect_default;
1050 window_effect_type_list[3] = _atom_comp_effect_default;
1051 window_effect_type_list[4] = _atom_comp_effect_default;
1052 window_effect_type_list[5] = _atom_comp_effect_default;
1054 _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1056 if ( type == UTILX_EFFECT_TYPE_MAP ) window_effect_type_list[0] = _utilx_convert_style_to_atom(dpy, style);
1057 else if ( type == UTILX_EFFECT_TYPE_UNMAP ) window_effect_type_list[1] = _utilx_convert_style_to_atom(dpy, style);
1058 else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) window_effect_type_list[2] = _utilx_convert_style_to_atom(dpy, style);
1059 else if ( type == UTILX_EFFECT_TYPE_ROTATION ) window_effect_type_list[3] = _utilx_convert_style_to_atom(dpy, style);
1060 else if ( type == UTILX_EFFECT_TYPE_FOCUSIN ) window_effect_type_list[4] = _utilx_convert_style_to_atom(dpy, style);
1061 else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT ) window_effect_type_list[5] = _utilx_convert_style_to_atom(dpy, style);
1063 _utilx_set_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6);
1066 free(window_effect_type_list);
1069 API Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type)
1071 Atom *window_effect_type_list = NULL;
1072 Utilx_Effect_Style style = UTILX_EFFECT_STYLE_DEFAULT;
1076 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1077 return UTILX_EFFECT_STYLE_NONE;
1079 _utilx_effect_atom_check(dpy);
1081 window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6);
1083 if ( !window_effect_type_list )
1085 fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__);
1086 return UTILX_EFFECT_STYLE_NONE;
1089 if ( _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6) != 6 )
1091 fprintf (stderr, "[UTILX] Error.. get property failed!.. %s (%d)\n", __func__, __LINE__);
1092 free(window_effect_type_list);
1093 return UTILX_EFFECT_STYLE_NONE;
1096 if ( type == UTILX_EFFECT_TYPE_MAP ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[0]);
1097 else if ( type == UTILX_EFFECT_TYPE_UNMAP ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[1]);
1098 else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[2]);
1099 else if ( type == UTILX_EFFECT_TYPE_ROTATION ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[3]);
1100 else if ( type == UTILX_EFFECT_TYPE_FOCUSIN ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[4]);
1101 else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[5]);
1104 free(window_effect_type_list);
1108 API int utilx_set_window_opaque_state (Display* dpy, Window win, Utilx_Opaque_State state)
1110 UTILX_TRACE ("[UTILX] utilx_set_window_opaque_state... win = %x, show_state = %d\n", win, state);
1112 unsigned int is_opaque;
1116 fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__);
1122 case UTILX_OPAQUE_STATE_OFF:
1126 case UTILX_OPAQUE_STATE_ON:
1131 fprintf (stderr, "[UTILX] Error.. Invald State.. %s (%d)\n", __func__, __LINE__);
1135 if (!_atom_window_opaque)
1137 _atom_window_opaque = XInternAtom (dpy, "_E_ILLUME_WINDOW_REGION_OPAQUE", False);
1138 if (!_atom_window_opaque)
1140 fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_WINDOW_REGION_OPAQUE atom.. %s (%d)\n", __func__, __LINE__);
1145 _utilx_set_window_property (dpy, win, _atom_window_opaque, XA_CARDINAL,
1146 (unsigned int *)&is_opaque, 1);
1152 _utilx_screen_capture_atom_ensure (Display* dpy)
1154 if (_atom_screen_capture_disable)
1157 _atom_screen_capture_disable = XInternAtom (dpy, "_CB_SCREEN_CAPTURE_DISABLE", False);
1158 if (_atom_screen_capture_disable)
1161 fprintf (stderr, "[UTILX] Error.. Cannot create _CB_SCREEN_CAPTURE_DISABLE atom.. %s (%d)\n", __func__, __LINE__);
1165 utilx_set_screen_capture(Display* dpy, int enable)
1172 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1176 root = RootWindow (dpy, DefaultScreen(dpy));
1177 disable = (enable) ? 0 : 1;
1179 _utilx_screen_capture_atom_ensure (dpy);
1181 _utilx_set_window_property (dpy, root, _atom_screen_capture_disable, XA_CARDINAL, (unsigned int *)&disable, 1);
1187 utilx_get_screen_capture(Display* dpy)
1194 fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__);
1198 root = RootWindow (dpy, DefaultScreen(dpy));
1200 _utilx_screen_capture_atom_ensure (dpy);
1202 _utilx_get_window_property(dpy, root, _atom_screen_capture_disable, XA_CARDINAL,
1203 (unsigned int *)&disable, 1);
1205 return (disable) ? 0 : 1;
1208 API void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value)
1210 _utilx_set_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1213 API int utilx_get_window_cardinal_property (Display* dpy, Window win, Atom atom, unsigned int *value)
1215 return _utilx_get_window_property(dpy, win, atom, XA_CARDINAL, value, 1);
1218 API void utilx_show_capture_effect( Display *dpy, Window win)
1222 _atom_comp_capture_effect = XInternAtom( dpy, "_E_COMP_CAPTURE_EFFECT", False );
1223 if( !_atom_comp_capture_effect )
1225 fprintf( stderr, "XInternAtom(_E_COMP_CAPTURE_EFFECT) failed.\n" );
1229 // send capture effect client message
1230 xev.xclient.type = ClientMessage;
1231 xev.xclient.display = dpy;
1232 xev.xclient.window = win;
1233 xev.xclient.message_type = _atom_comp_capture_effect;
1234 xev.xclient.format = 32;
1235 xev.xclient.data.l[0] = 0;
1236 xev.xclient.data.l[1] = 0;
1237 xev.xclient.data.l[2] = 0;
1238 xev.xclient.data.l[3] = 0;
1239 xev.xclient.data.l[4] = 0;
1241 XSendEvent( dpy, win, False,
1242 SubstructureRedirectMask | SubstructureNotifyMask,
1247 API UtilxScrnConf *utilx_scrnconf_allocate (void)
1249 UtilxScrnConf *scrnconf = calloc (1, sizeof(UtilxScrnConf));
1252 fprintf (stderr, "fail to allocate UtilxScrnConf\n");
1259 API void utilx_scrnconf_free (UtilxScrnConf *scrnconf)
1264 if (scrnconf->str_output)
1265 free (scrnconf->str_output);
1267 if (scrnconf->str_resolution)
1268 free (scrnconf->str_resolution);
1274 API int utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf)
1276 Window win = DefaultRootWindow(dpy);
1277 Atom scrnconf_atom = None;
1286 scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_INFO", False);
1289 if (XGetTextProperty (dpy, win, &xtp, scrnconf_atom))
1291 s = XmbTextPropertyToTextList (dpy, &xtp, &list, &items);
1292 if ((s == XLocaleNotSupported) ||
1293 (s == XNoMemory) || (s == XConverterNotFound))
1294 str = strdup((char *)xtp.value);
1295 else if ((s >= Success) && (items > 0))
1296 str = strdup(list[0]);
1299 XFreeStringList (list);
1304 ptr = strtok (str, ",");
1309 scrnconf->str_output = calloc (1, strlen(ptr));
1310 if (!scrnconf->str_output)
1313 strcpy (scrnconf->str_output, ptr);
1317 if (!strcmp(ptr, "CONNECT"))
1318 scrnconf->status = UTILX_SCRNCONF_STATUS_CONNECT;
1319 else if (!strcmp(ptr, "ACTIVE"))
1320 scrnconf->status = UTILX_SCRNCONF_STATUS_ACTIVE;
1322 scrnconf->status = UTILX_SCRNCONF_STATUS_NULL;
1326 scrnconf->str_resolution = calloc (1, strlen(ptr));
1327 if (!scrnconf->str_resolution)
1330 strcpy (scrnconf->str_resolution, ptr);
1334 if (!strcmp(ptr, "CLONE"))
1335 scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_CLONE;
1336 else if (!strcmp(ptr, "EXTENDED"))
1337 scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED;
1339 scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_NULL;
1344 ptr = strtok (NULL, ",");
1358 API int utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode)
1360 Window win = DefaultRootWindow(dpy);
1362 Atom scrnconf_atom = None;
1363 UtilxScrnConf *scrnconf = NULL;
1365 scrnconf = utilx_scrnconf_allocate ();
1369 if (!utilx_scrnconf_get_info (dpy, scrnconf))
1371 utilx_scrnconf_free (scrnconf);
1375 if (scrnconf->status == UTILX_SCRNCONF_STATUS_NULL)
1377 fprintf (stderr, "[utilx_scrnconf]: the status of screen configuration is null\n");
1378 utilx_scrnconf_free (scrnconf);
1382 if (scrnconf->dispmode == dispmode)
1384 fprintf (stderr, "[utilx_scrnconf]: dispmode (%d) already set\n", dispmode);
1385 utilx_scrnconf_free (scrnconf);
1389 utilx_scrnconf_free (scrnconf);
1391 scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_DISPMODE_SET", False);
1393 xev.xclient.window = win;
1394 xev.xclient.type = ClientMessage;
1395 xev.xclient.message_type = scrnconf_atom;
1396 xev.xclient.format = 32;
1397 xev.xclient.data.s[0] = dispmode;
1399 XSendEvent(dpy, win, False, StructureNotifyMask, &xev);
1405 typedef struct _ShotInfo
1412 unsigned int height;
1424 DRI2Buffer* dri2_buffers;
1430 XShmSegmentInfo shminfo;
1433 #define FOURCC(a,b,c,d) (((unsigned)d&0xff)<<24 | ((unsigned)c&0xff)<<16 | ((unsigned)b&0xff)<<8 | ((unsigned)a&0xff))
1435 #define FOURCC_RGB32 FOURCC('R','G','B','4')
1436 #define TIMEOUT_CAPTURE 3
1438 /* x error handling */
1439 static Bool x_error_caught;
1441 static ShotInfo *shot_info;
1444 _get_port (Display *dpy, unsigned int id)
1446 unsigned int ver, rev, req_base, evt_base, err_base;
1447 unsigned int adaptors;
1448 XvAdaptorInfo *ai = NULL;
1449 XvImageFormatValues *fo = NULL;
1453 if (XvQueryExtension (dpy, &ver, &rev, &req_base, &evt_base, &err_base) != Success)
1455 fprintf (stderr, "[UTILX] no XV extension. \n");
1459 if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &adaptors, &ai) != Success)
1461 fprintf (stderr, "[UTILX] fail : query adaptors. \n");
1467 fprintf (stderr, "[UTILX] fail : get adaptor info. \n");
1471 for (i = 0; i < adaptors; i++)
1473 int support_format = False;
1475 if (!(ai[i].type & XvInputMask) ||
1476 !(ai[i].type & XvStillMask))
1481 fo = XvListImageFormats (dpy, p, &formats);
1482 for (j = 0; j < formats; j++)
1483 if (fo[j].id == (int)id)
1484 support_format = True;
1489 if (!support_format)
1492 if (XvGrabPort (dpy, p, 0) == Success)
1494 XvFreeAdaptorInfo (ai);
1498 fprintf (stderr, "[UTILX] fail : grab port. \n");
1501 XvFreeAdaptorInfo (ai);
1507 _deinit_screen_shot (ShotInfo *info)
1509 static Atom atom_stream_off = None;
1514 if (atom_stream_off == None)
1515 atom_stream_off = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False);
1517 XvSetPortAttribute (info->dpy, info->port, atom_stream_off, 1);
1520 XDestroyImage (info->image);
1521 if (info->shminfo.shmid != -1)
1523 XShmDetach (info->dpy, &info->shminfo);
1524 shmdt (info->shminfo.shmaddr);
1525 shmctl (info->shminfo.shmid, IPC_RMID, 0);
1529 tbm_bo_unref(info->bo);
1530 if (info->dri2_buffers)
1531 free(info->dri2_buffers);
1533 tbm_bufmgr_deinit (info->bufmgr);
1534 if (info->drm_fd >= 0)
1535 close (info->drm_fd);
1538 XDamageDestroy (info->dpy, info->damage);
1541 XFreeGC (info->dpy, info->gc);
1542 if (info->pixmap > 0)
1543 XFreePixmap (info->dpy, info->pixmap);
1545 XvUngrabPort (info->dpy, info->port, 0);
1547 XSync (info->dpy, False);
1554 _screen_shot_x_error_handle (Display *dpy, XErrorEvent *ev)
1556 if (!shot_info || (dpy != shot_info->dpy))
1559 x_error_caught = True;
1565 _init_screen_shot_damage (ShotInfo *info)
1567 int damage_err_base = 0;
1569 if (!XDamageQueryExtension(info->dpy, &info->damage_base, &damage_err_base))
1571 fprintf (stderr, "[UTILX] no X Damage extension. \n");
1575 info->damage = XDamageCreate (info->dpy, info->pixmap, XDamageReportNonEmpty);
1576 if (info->damage <= 0)
1578 fprintf (stderr, "[UTILX] fail : create damage \n");
1586 _init_screen_shot_dri2 (ShotInfo *info)
1590 int dri2_err_base = 0;
1591 int dri2Major, dri2Minor;
1592 char *driverName = NULL, *deviceName = NULL;
1593 unsigned int attachments[1];
1594 int dri2_count, dri2_out_count;
1595 int dri2_width, dri2_height, dri2_stride;
1597 tbm_bo_handle bo_handle;
1599 screen = DefaultScreen(info->dpy);
1600 if (!DRI2QueryExtension (info->dpy, &dri2_base, &dri2_err_base))
1602 fprintf (stderr, "[UTILX] no DRI2 extension. !!\n");
1603 goto fail_init_dri2;
1606 if (!DRI2QueryVersion (info->dpy, &dri2Major, &dri2Minor))
1608 fprintf (stderr, "[UTILX] fail : DRI2QueryVersion !!\n");
1609 goto fail_init_dri2;
1612 if (!DRI2Connect (info->dpy, RootWindow(info->dpy, screen), &driverName, &deviceName))
1614 fprintf (stderr, "[UTILX] fail : DRI2Connect !!\n");
1615 goto fail_init_dri2;
1618 if (!driverName || !deviceName)
1620 fprintf (stderr, "[UTILX] fail : Get DRI info !!\n");
1621 goto fail_init_dri2;
1625 info->drm_fd = open (deviceName, O_RDWR);
1626 if (info->drm_fd < 0)
1628 fprintf (stderr, "[UTILX] fail : open drm device (%s)\n", deviceName);
1629 goto fail_init_dri2;
1632 /* get the drm magic */
1633 drmGetMagic(info->drm_fd, &magic);
1634 if (!DRI2Authenticate(info->dpy, RootWindow(info->dpy, screen), magic))
1636 fprintf (stderr, "[UTILX] fail : DRI2Authenticate (%d)\n", magic);
1637 goto fail_init_dri2;
1641 info->bufmgr = tbm_bufmgr_init (info->drm_fd);
1644 fprintf (stderr, "[UTILX] fail : init buffer manager \n");
1645 goto fail_init_dri2;
1648 DRI2CreateDrawable (info->dpy, info->pixmap);
1650 attachments[0] = DRI2BufferFrontLeft;
1652 info->dri2_buffers = DRI2GetBuffers (info->dpy, info->pixmap, &dri2_width, &dri2_height,
1653 attachments, dri2_count, &dri2_out_count);
1655 if (!info->dri2_buffers)
1657 fprintf (stderr, "[UTILX] fail : get buffers\n");
1658 goto fail_init_dri2;
1661 if (!info->dri2_buffers[0].name)
1663 fprintf (stderr, "[UTILX] fail : a handle of the dri2 buffer is null \n ");
1664 goto fail_init_dri2;
1667 info->bo = tbm_bo_import (info->bufmgr, info->dri2_buffers[0].name);
1670 fprintf (stderr, "[UTILX] fail : import bo (key:%d)\n", info->dri2_buffers[0].name);
1671 goto fail_init_dri2;
1674 dri2_stride = info->dri2_buffers[0].pitch;
1677 bo_handle = tbm_bo_get_handle (info->bo, TBM_DEVICE_CPU);
1678 info->virtual = (void *)bo_handle.ptr;
1681 fprintf (stderr, "[UTILX] fail : map \n");
1682 goto fail_init_dri2;
1685 info->enable_xshm = False;
1695 tbm_bo_unref(info->bo);
1696 if (info->dri2_buffers)
1697 free(info->dri2_buffers);
1699 tbm_bufmgr_deinit (info->bufmgr);
1700 if (info->drm_fd >= 0)
1701 close (info->drm_fd);
1712 _init_screen_shot_shm (ShotInfo *info)
1714 if (!XShmQueryExtension (info->dpy))
1716 fprintf (stderr, "[UTILX] no XShm extension. !!\n");
1720 info->image = XShmCreateImage (info->dpy,
1721 DefaultVisual (info->dpy, DefaultScreen (info->dpy)),
1722 DefaultDepth (info->dpy, DefaultScreen (info->dpy)),
1730 fprintf (stderr, "[UTILX] fail : XShmCreateImage \n");
1734 info->shminfo.shmid = shmget (IPC_PRIVATE, info->image->bytes_per_line * info->height, IPC_CREAT | 0777);
1735 if (info->shminfo.shmid == -1)
1737 XDestroyImage (info->image);
1738 fprintf (stderr, "[UTILX] fail : shmget\n");
1742 info->shminfo.shmaddr = shmat (info->shminfo.shmid, 0, 0);
1743 if (info->shminfo.shmaddr == (void *) -1)
1745 XDestroyImage (info->image);
1746 shmctl (info->shminfo.shmid, IPC_RMID, 0);
1747 info->shminfo.shmid = -1;
1748 fprintf (stderr, "[UTILX] fail : shmat\n");
1752 info->shminfo.readOnly = False;
1754 if (!XShmAttach (info->dpy, &info->shminfo))
1756 XDestroyImage (info->image);
1757 shmdt (info->shminfo.shmaddr);
1758 shmctl (info->shminfo.shmid, IPC_RMID, 0);
1759 info->shminfo.shmid = -1;
1760 fprintf (stderr, "[UTILX] fail : XShmAttach\n");
1764 info->image->data = info->shminfo.shmaddr;
1765 info->virtual = info->shminfo.shmaddr;
1767 info->enable_xshm = True;
1773 _init_screen_shot (Display* dpy, unsigned int width, unsigned int height)
1775 ShotInfo *info = NULL;
1776 static Atom atom_capture = None;
1777 static Atom atom_fps = None;
1778 XErrorHandler old_handler = NULL;
1782 if (shot_info->width == width && shot_info->height == height)
1785 _deinit_screen_shot (shot_info);
1788 info = calloc (1, sizeof (ShotInfo));
1796 info->shminfo.shmid = -1;
1797 info->shminfo.shmaddr = (void*)-1;
1801 info->port = _get_port (info->dpy, FOURCC_RGB32);
1802 if (info->port <= 0)
1806 if (atom_capture == None)
1807 atom_capture = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False);
1808 if (atom_fps == None)
1809 atom_fps = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_FPS", False);
1811 XSync (info->dpy, 0);
1812 x_error_caught = False;
1813 old_handler = XSetErrorHandler (_screen_shot_x_error_handle);
1815 XvSetPortAttribute (info->dpy, info->port, atom_capture, 1);
1816 XvSetPortAttribute (info->dpy, info->port, atom_fps, 60);
1818 XSync (info->dpy, 0);
1820 x_error_caught = False;
1821 XSetErrorHandler (old_handler);
1823 XvQueryBestSize (info->dpy, info->port, 0, 0, 0, width, height, &width, &height);
1824 if (width <= 0 || height <= 0)
1826 info->width = width;
1827 info->height = height;
1830 info->pixmap = XCreatePixmap (info->dpy,
1831 DefaultRootWindow (info->dpy),
1833 DefaultDepth (info->dpy, DefaultScreen (info->dpy)));
1834 if (info->pixmap <= 0)
1836 fprintf (stderr, "[UTILX] fail : create pixmap. \n");
1841 info->gc = XCreateGC (info->dpy, info->pixmap, 0, 0);
1842 if (info->gc == NULL)
1844 fprintf (stderr, "[UTILX] fail : create gc. \n");
1848 XSetForeground (info->dpy, info->gc, 0xFF000000);
1849 XFillRectangle (info->dpy, info->pixmap, info->gc, 0, 0, width, height);
1851 if (!_init_screen_shot_damage (info))
1854 if (!_init_screen_shot_dri2 (info))
1856 if (!_init_screen_shot_shm (info))
1859 fprintf (stderr, "[UTILX] XShm success. !!\n");
1864 fprintf (stderr, "[UTILX] fail : get virtual \n");
1873 _deinit_screen_shot (info);
1878 utilx_create_screen_shot (Display* dpy, int width, int height)
1882 XErrorHandler old_handler = NULL;
1886 fprintf (stderr, "[UTILX] invalid display(%p) \n", dpy);
1890 if (width <= 0 || height <= 0)
1892 fprintf (stderr, "[UTILX] invalid size(%dx%d) \n", width, height);
1898 info = _init_screen_shot (dpy, width, height);
1902 fprintf (stderr, "[UTILX] fail : initialize screenshot. \n");
1908 x_error_caught = False;
1909 old_handler = XSetErrorHandler (_screen_shot_x_error_handle);
1911 XvPutStill (info->dpy, info->port, info->pixmap, info->gc,
1912 0, 0, info->width, info->height,
1913 0, 0, info->width, info->height);
1919 x_error_caught = False;
1920 XSetErrorHandler (old_handler);
1924 x_error_caught = False;
1925 XSetErrorHandler (old_handler);
1927 if (XPending (info->dpy))
1928 XNextEvent (info->dpy, &ev);
1931 int fd = ConnectionNumber (info->dpy);
1940 tv.tv_sec = TIMEOUT_CAPTURE;
1942 ret = select (fd + 1, &mask, 0, 0, &tv);
1944 fprintf (stderr, "[UTILX] fail: select.\n");
1946 fprintf (stderr, "[UTILX] timeout(%d sec)!\n", TIMEOUT_CAPTURE);
1947 else if (XPending (info->dpy))
1948 XNextEvent (info->dpy, &ev);
1950 fprintf (stderr, "[UTILX] fail: not passed a event!\n");
1953 if (ev.type == (info->damage_base + XDamageNotify))
1955 XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev;
1956 if (damage_ev->drawable == info->pixmap)
1958 if (info->enable_xshm)
1959 XShmGetImage (info->dpy, info->pixmap, info->image, 0, 0, AllPlanes);
1961 XDamageSubtract (info->dpy, info->damage, None, None );
1962 return info->virtual;
1965 XDamageSubtract (info->dpy, info->damage, None, None );
1968 utilx_release_screen_shot ();
1974 utilx_release_screen_shot (void)
1976 _deinit_screen_shot (shot_info);
1979 #define XRR_PROPERTY_FB_VISIBLE "XRR_PROPERTY_FB_VISIBLE"
1980 #define XRR_PROPERTY_VIDEO_OFFSET "XRR_PROPERTY_VIDEO_OFFSET"
1983 _utilx_xrr_set_property (Display* dpy, Atom atom, unsigned char *buf, int buf_len, unsigned char **get)
1986 XRRScreenResources *res = NULL;
1987 RROutput rr_output = None;
1990 root = XRootWindow (dpy, 0);
1993 fprintf (stderr, "[UTILX] Warning : Root window is None.. %s (%d)\n", __func__, __LINE__);
1997 res = XRRGetScreenResources (dpy, root);
1998 if (res == NULL || res->noutput == 0)
2000 fprintf (stderr, "[UTILX] Warning : ScreenResources is None.. %s (%d)\n", __func__, __LINE__);
2004 for (i = 0; i < res->noutput; i++)
2006 XRROutputInfo *output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
2009 if (!strcmp (output_info->name, "LVDS1"))
2011 rr_output = res->outputs[i];
2012 XRRFreeOutputInfo(output_info);
2015 XRRFreeOutputInfo(output_info);
2019 if (rr_output == None)
2021 fprintf (stderr, "[UTILX] Warning : output is None.. %s (%d)\n", __func__, __LINE__);
2022 XRRFreeScreenResources (res);
2026 XRRChangeOutputProperty (dpy, rr_output, atom,
2027 XA_CARDINAL, 8, PropModeReplace, buf, buf_len);
2033 unsigned long nitems, bytes_after;
2035 XRRGetOutputProperty (dpy, rr_output, atom,
2037 True, False, XA_CARDINAL,
2038 &actual_type, &actual_format,
2039 &nitems, &bytes_after,
2045 XRRFreeScreenResources (res);
2051 utilx_set_fb_visible (Display* dpy, Utilx_Fb_Type fb, Bool visible)
2053 static Atom property = None;
2054 char buf[8192] = {0,};
2060 fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__);
2064 if (fb <= UTILX_FB_TYPE_NONE || fb > UTILX_FB_TYPE_OVERLAY)
2066 fprintf (stderr, "[UTILX] Error.. Invald fb(%d).. %s (%d)\n", fb, __func__, __LINE__);
2070 p += sprintf (p, "%d:", 0);
2071 p += sprintf (p, "%d", fb + 2);
2072 p += sprintf (p, ":%d", (visible > 0)? 1 : 0);
2079 if (property == None)
2080 property = XInternAtom (dpy, XRR_PROPERTY_FB_VISIBLE, False);
2082 if (property == None)
2084 fprintf (stderr, "[UTILX] Warning : FB_VISIBLE property is None.. %s (%d)\n", __func__, __LINE__);
2088 if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, NULL))
2090 fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__);
2096 utilx_get_fb_visible (Display* dpy, Utilx_Fb_Type fb)
2098 static Atom property = None;
2099 char buf[32] = {0,};
2102 unsigned char *prop = NULL;
2103 Bool visible = False;
2107 fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__);
2111 if (fb <= UTILX_FB_TYPE_NONE || fb > UTILX_FB_TYPE_OVERLAY)
2113 fprintf (stderr, "[UTILX] Error.. Invald fb(%d).. %s (%d)\n", fb, __func__, __LINE__);
2117 p += sprintf (p, "%d:", 0);
2118 p += sprintf (p, "%d", fb + 2);
2125 if (property == None)
2126 property = XInternAtom (dpy, XRR_PROPERTY_FB_VISIBLE, False);
2128 if (property == None)
2130 fprintf (stderr, "[UTILX] Warning : FB_VISIBLE property is None.. %s (%d)\n", __func__, __LINE__);
2134 if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, &prop))
2136 fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__);
2141 visible = atoi((char*)prop);
2147 utilx_set_video_offset (Display* dpy, int x, int y)
2149 static Atom property = None;
2150 char buf[32] = {0,};
2156 fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__);
2160 p += sprintf (p, "%d,%d", x, y);
2167 if (property == None)
2168 property = XInternAtom (dpy, XRR_PROPERTY_VIDEO_OFFSET, False);
2170 if (property == None)
2172 fprintf (stderr, "[UTILX] Warning : VIDEO_OFFSET property is None.. %s (%d)\n", __func__, __LINE__);
2176 if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, NULL))
2178 fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__);