#include "Ecore.h" #include #include #include #include #ifdef XA_CLIPBOARD #define X_CLIPBOARD_SELECTION XA_CLIPBOARD(disp) #define X_CLIPBOARD_PROP XA_CLIPBOARD(disp) #else #define X_CLIPBOARD_SELECTION XA_PRIMARY #define X_CLIPBOARD_PROP XA_CUT_BUFFER0 #endif typedef struct _window_list Window_List; struct _window_list { Window win; Window_List *next; }; XContext xid_context = 0; static Display *disp; static Visual *default_vis; static Colormap default_cm; static int default_depth; static Window default_win; static Window default_root; static int lock_scroll = 0; static int lock_num = 0; static int lock_caps = 0; static Window focused_win = 0; static int mod_shift = 0; static int mod_ctrl = 0; static int mod_alt = 0; static int mod_win = 0; static Window grabkey_win = 0; static int mouse_x = 0, mouse_y = 0; static Window current_dnd_win = 0; static int current_dnd_target_ok = 0; static int dnd_await_target_status = 0; static int x_grabs = 0; static Window_List *ignore_wins = NULL; static Window grab_pointer_win = 0; static Window keyboard_grab_win = 0; static int dnd_copy = 0; static int dnd_link = 0; static int dnd_move = 1; static void ecore_handle_x_error(Display * d, XErrorEvent * ev); static void ecore_handle_x_io_error(Display * d); static Window ecore_window_at_xy_0(Window base, int bx, int by, int x, int y); static void ecore_handle_x_error(Display * d, XErrorEvent * ev) { /* char err[16384]; XGetErrorText(d, ev->error_code, err, 16000); printf("X Error:\n" "Error: %s\nrequest: %i\nminor: %i\n", err, ev->request_code, ev->minor_code); */ /* ignore all X errors */ return; d = NULL; ev = NULL; } static void ecore_handle_x_io_error(Display * d) { /* FIXME: call clean exit handler */ exit(1); d = NULL; } void ecore_del_child(Window win, Window child) { Ecore_XID *xid = NULL; if (!disp) return; if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) return; if (xid) { int i; for (i = 0; i < xid->children_num; i++) { if (xid->children[i] == child) { int j; for (j = i; j < xid->children_num - 1; j++) xid->children[j] = xid->children[j + 1]; xid->children_num--; REALLOC(xid->children, Window, xid->children_num); return; } } } } void ecore_add_child(Window win, Window child) { Ecore_XID *xid = NULL; if (!disp) return; if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) return; if (xid) { int i; for (i = 0; i < xid->children_num; i++) { if (xid->children[i] == child) return; } xid->children_num++; REALLOC(xid->children, Window, xid->children_num); xid->children[xid->children_num - 1] = child; } xid = ecore_validate_xid(child); } void ecore_raise_child(Window win, Window child) { Ecore_XID *xid = NULL; if (!disp) return; if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) return; if (xid) { int i; for (i = 0; i < xid->children_num; i++) { if (xid->children[i] == child) { int j; for (j = i; j < xid->children_num - 1; j++) xid->children[j] = xid->children[j + 1]; xid->children[xid->children_num - 1] = child; return; } } } } void ecore_lower_child(Window win, Window child) { Ecore_XID *xid = NULL; if (!disp) return; if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) return; if (xid) { int i; for (i = 0; i < xid->children_num; i++) { if (xid->children[i] == child) { int j; for (j = i; j > 0; j--) xid->children[j] = xid->children[j - 1]; xid->children[0] = child; return; } } } } Ecore_XID * ecore_add_xid(Window win, int x, int y, int w, int h, int depth, Window parent) { Ecore_XID *xid = NULL; ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | XEV_VISIBILITY); xid = NEW(Ecore_XID, 1); xid->win = win; xid->x = x; xid->y = y; xid->w = w; xid->h = h; xid->mapped = 0; xid->depth = depth; xid->mouse_in = 0; xid->parent = parent; xid->root = ecore_window_get_root(parent); xid->children_num = 0; xid->children = NULL; xid->gravity = ecore_window_get_gravity(win); xid->coords_invalid = 0; xid->bw = 0; xid->grab_button_auto_replay = NULL; XSaveContext(disp, xid->win, xid_context, (XPointer) xid); ecore_add_child(parent, win); return xid; } Ecore_XID * ecore_validate_xid(Window win) { Ecore_XID *xid = NULL; if (!disp) return NULL; if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) { XWindowAttributes att; Window root_ret = 0, parent_ret = 0, *children_ret = NULL; unsigned int children_ret_num = 0; ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | XEV_VISIBILITY | XEV_CHILD_CHANGE); xid = NEW(Ecore_XID, 1); xid->win = win; if (!XGetWindowAttributes(disp, win, &att)) { FREE(xid); return NULL; } if (!XQueryTree(disp, win, &root_ret, &parent_ret, &children_ret, &children_ret_num)) { FREE(xid); return NULL; } xid->parent = parent_ret; if (xid->parent) ecore_validate_xid(xid->parent); if (children_ret) { xid->children_num = children_ret_num; xid->children = NEW(Window, children_ret_num); MEMCPY(children_ret, xid->children, Window, children_ret_num); XFree(children_ret); } else { xid->children_num = 0; xid->children = NULL; } xid->root = root_ret; xid->x = att.x; xid->y = att.y; xid->w = att.width; xid->h = att.height; if (att.map_state == IsUnmapped) xid->mapped = 0; else xid->mapped = 1; xid->depth = att.depth; xid->mouse_in = 0; xid->gravity = att.win_gravity; xid->bw = att.border_width; xid->coords_invalid = 0; xid->grab_button_auto_replay = NULL; XSaveContext(disp, xid->win, xid_context, (XPointer) xid); ecore_add_child(xid->parent, win); } return xid; } void ecore_unvalidate_xid(Window win) { Ecore_XID *xid = NULL; if (!disp) return; if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) return; if (xid) { int i; for (i = 0; i < xid->children_num; i++) ecore_unvalidate_xid(xid->children[i]); ecore_del_child(xid->parent, win); IF_FREE(xid->children); FREE(xid); XDeleteContext(disp, win, xid_context); } } void ecore_sync(void) { if (!disp) return; XSync(disp, False); } void ecore_flush(void) { if (!disp) return; XFlush(disp); } Window ecore_window_new(Window parent, int x, int y, int w, int h) { Window win; XSetWindowAttributes attr; if (!disp) return 0; if (!parent) parent = default_root; attr.backing_store = NotUseful; attr.override_redirect = False; attr.colormap = default_cm; attr.border_pixel = 0; attr.background_pixmap = None; attr.save_under = False; attr.do_not_propagate_mask = True; win = XCreateWindow(disp, parent, x, y, w, h, 0, default_depth, InputOutput, default_vis, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap | CWBackPixmap | CWBorderPixel | CWDontPropagate, &attr); ecore_add_xid(win, x, y, w, h, default_depth, parent); ecore_add_child(parent, win); ecore_validate_xid(parent); return win; } Window ecore_window_override_new(Window parent, int x, int y, int w, int h) { Window win; XSetWindowAttributes attr; if (!disp) return 0; if (!parent) parent = default_root; attr.backing_store = NotUseful; attr.override_redirect = True; attr.colormap = default_cm; attr.border_pixel = 0; attr.background_pixmap = None; attr.save_under = False; attr.do_not_propagate_mask = True; win = XCreateWindow(disp, parent, x, y, w, h, 0, default_depth, InputOutput, default_vis, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap | CWBackPixmap | CWBorderPixel | CWDontPropagate, &attr); ecore_add_xid(win, x, y, w, h, default_depth, parent); ecore_add_child(parent, win); ecore_validate_xid(parent); return win; } Window ecore_window_input_new(Window parent, int x, int y, int w, int h) { Window win; XSetWindowAttributes attr; if (!disp) return 0; if (!parent) parent = default_root; attr.override_redirect = True; attr.do_not_propagate_mask = True; win = XCreateWindow(disp, parent, x, y, w, h, 0, 0, InputOnly, default_vis, CWOverrideRedirect | CWDontPropagate, &attr); ecore_add_xid(win, x, y, w, h, 0, parent); ecore_add_child(parent, win); ecore_validate_xid(parent); return win; } void ecore_window_set_events_propagate(Window win, int propagate) { XSetWindowAttributes attr; if (!disp) return; if (!win) win = default_root; if (!propagate) attr.do_not_propagate_mask = True; else attr.do_not_propagate_mask = False; XChangeWindowAttributes(disp, win, CWDontPropagate, &attr); } void ecore_window_show(Window win) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { if (xid->mapped) return; xid->mapped = 1; XMapWindow(disp, win); } } void ecore_window_hide(Window win) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { if (!xid->mapped) return; xid->mapped = 0; XUnmapWindow(disp, win); } } Pixmap ecore_pixmap_new(Window win, int w, int h, int dep) { if (!disp) return 0; if (!win) win = default_win; if (dep == 0) dep = default_depth; return XCreatePixmap(disp, win, w, h, dep); } void ecore_pixmap_free(Pixmap pmap) { if (!disp) return; if (!pmap) return; XFreePixmap(disp, pmap); } void ecore_window_set_background_pixmap(Window win, Pixmap pmap) { if (!disp) return; if (win == 0) win = default_root; XSetWindowBackgroundPixmap(disp, win, pmap); } void ecore_window_set_shape_mask(Window win, Pixmap mask) { if (!disp) return; XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeSet); } void ecore_window_add_shape_mask(Window win, Pixmap mask) { if (!disp) return; XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeUnion); } void ecore_window_set_shape_window(Window win, Window src, int x, int y) { if (!disp) return; XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding, ShapeSet); } void ecore_window_add_shape_window(Window win, Window src, int x, int y) { if (!disp) return; XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding, ShapeUnion); } void ecore_window_set_shape_rectangle(Window win, int x, int y, int w, int h) { XRectangle rect; if (!disp) return; rect.x = x; rect.y = y; rect.width = w; rect.height = h; XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet, Unsorted); } void ecore_window_add_shape_rectangle(Window win, int x, int y, int w, int h) { XRectangle rect; if (!disp) return; rect.x = x; rect.y = y; rect.width = w; rect.height = h; XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, Unsorted); } void ecore_window_set_shape_rectangles(Window win, XRectangle * rect, int num) { if (!disp) return; XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet, Unsorted); } void ecore_window_add_shape_rectangles(Window win, XRectangle * rect, int num) { if (!disp) return; XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion, Unsorted); } void ecore_window_clip_shape_by_rectangle(Window win, int x, int y, int w, int h) { XRectangle rect; if (!disp) return; rect.x = x; rect.y = y; rect.width = w; rect.height = h; XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, Unsorted); } XRectangle * ecore_window_get_shape_rectangles(Window win, int *num) { int ord; if (!disp) return NULL; return XShapeGetRectangles(disp, win, ShapeBounding, num, &ord); } void ecore_window_select_shape_events(Window win) { if (!disp) return; XShapeSelectInput(disp, win, ShapeNotifyMask); } void ecore_window_unselect_shape_events(Window win) { if (!disp) return; XShapeSelectInput(disp, win, 0); } void ecore_window_clear(Window win) { if (!disp) return; if (win == 0) win = default_root; XClearWindow(disp, win); } void ecore_window_clear_area(Window win, int x, int y, int w, int h) { if (!disp) return; if (win == 0) win = default_root; XClearArea(disp, win, x, y, w, h, False); } void ecore_pointer_xy(Window win, int *x, int *y) { Window dw; unsigned int dm; int wx, wy; if (!disp) return; if (win == 0) win = default_root; XQueryPointer(disp, win, &dw, &dw, &mouse_x, &mouse_y, &wx, &wy, &dm); if (x) *x = wx; if (y) *y = wy; } void ecore_pointer_xy_set(int x, int y) { if (!disp) return; mouse_x = x; mouse_y = y; } void ecore_pointer_xy_get(int *x, int *y) { if (!disp) return; if (x) *x = mouse_x; if (y) *y = mouse_y; } void ecore_window_set_events(Window win, long mask) { if (!disp) return; if (win == 0) win = default_root; XSelectInput(disp, win, mask); } void ecore_window_remove_events(Window win, long mask) { XWindowAttributes att; if (!disp) return; if (win == 0) win = default_root; if (XGetWindowAttributes(disp, win, &att) == True) { mask = att.your_event_mask & (~mask); ecore_window_set_events(win, mask); } } void ecore_window_add_events(Window win, long mask) { XWindowAttributes att; if (!disp) return; if (win == 0) win = default_root; if (XGetWindowAttributes(disp, win, &att) == True) { mask = att.your_event_mask | mask; ecore_window_set_events(win, mask); } } void ecore_window_move(Window win, int x, int y) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { if (!xid->coords_invalid) { if ((xid->x == x) && (xid->y == y)) return; } xid->x = x; xid->y = y; xid->coords_invalid = 0; XMoveWindow(disp, win, x, y); } } #define REGRAVITATE \ if (xid->children) \ { \ int j; \ \ for (j = 0; j < xid->children_num; j++) \ { \ Ecore_XID *xid2; \ \ xid2 = ecore_validate_xid(xid->children[j]); \ if (xid2) \ { \ xid2->coords_invalid = 1; \ } \ } \ } #if 0 switch (xid2->gravity) { case UnmapGravity: xid2->mapped = 0; break; case NorthWestGravity: break; case NorthGravity: xid2->x += (w - xid->w) / 2; break; case NorthEastGravity: xid2->x += (w - xid->w); break; case WestGravity: xid2->h += (h - xid->h) / 2; break; case CenterGravity: xid2->x += (w - xid->w) / 2; xid2->h += (h - xid->h) / 2; break; case EastGravity: xid2->x += (w - xid->w); break; case SouthWestGravity: xid2->y += (h - xid->h); break; case SouthGravity: xid2->x += (w - xid->w) / 2; xid2->y += (h - xid->h); break; case SouthEastGravity: xid2->x += (w - xid->w); xid2->y += (h - xid->h); break; case StaticGravity: xid2->coords_invalid = 1; break; default: break; } } } } #endif void ecore_window_resize(Window win, int w, int h) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { if (!xid->coords_invalid) { if ((xid->w == w) && (xid->h == h)) return; } REGRAVITATE; xid->w = w; xid->h = h; xid->coords_invalid = 0; XResizeWindow(disp, win, w, h); } } void ecore_window_move_resize(Window win, int x, int y, int w, int h) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { if (!xid->coords_invalid) { if ((xid->x == x) && (xid->y == y) && (xid->w == w) && (xid->h == h)) return; } REGRAVITATE; xid->x = x; xid->y = y; xid->w = w; xid->h = h; xid->coords_invalid = 0; XMoveResizeWindow(disp, win, x, y, w, h); } } int ecore_x_get_fd(void) { if (!disp) return 0; return ConnectionNumber(disp); } void ecore_set_error_handler(Ecore_Error_Function func) { if (!disp) return; XSetErrorHandler((XErrorHandler) func); } void ecore_reset_error_handler(void) { if (!disp) return; XSetErrorHandler((XErrorHandler) ecore_handle_x_error); } int ecore_display_init(char *display) { int revert; xid_context = XUniqueContext(); disp = XOpenDisplay(display); if (!disp) { char *d; d = getenv("DISPLAY"); /* no need for this anymore if (d) fprintf(stderr, "Fatal Error:\n" "Cannot connect to the display nominated by your DISPLAY variable:\n" "%s\n" "Try changing your DISPLAY variable like:\n" "DISPLAY=host:0 application_name\n", d); else fprintf(stderr, "Fatal Error:\n" "No DISPLAY variable set so cannot determine display to connect to.\n" "Try setting your DISPLAY variable like:\n" "DISPLAY=host:0 appication_name\n"); */ return 0; } XSetErrorHandler((XErrorHandler) ecore_handle_x_error); XSetIOErrorHandler((XIOErrorHandler) ecore_handle_x_io_error); default_vis = DefaultVisual(disp, DefaultScreen(disp)); default_depth = DefaultDepth(disp, DefaultScreen(disp)); default_cm = DefaultColormap(disp, DefaultScreen(disp)); default_win = DefaultRootWindow(disp); default_root = DefaultRootWindow(disp); mod_shift = ecore_mod_mask_shift_get(); mod_ctrl = ecore_mod_mask_ctrl_get(); mod_alt = ecore_mod_mask_alt_get(); mod_win = ecore_mod_mask_win_get(); XGetInputFocus(disp, &focused_win, &revert); ecore_window_set_events(default_root, XEV_KEY | XEV_IN_OUT | XEV_MOUSE_MOVE | XEV_CONFIGURE | XEV_CHILD_CHANGE | XEV_PROPERTY | XEV_COLORMAP | XEV_VISIBILITY); ecore_pointer_xy(0, NULL, NULL); return 1; } int ecore_events_pending(void) { if (!disp) return 0; return XPending(disp); } void ecore_get_next_event(XEvent * event) { if (!disp) return; XNextEvent(disp, event); } int ecore_event_shape_get_id(void) { int base = -1, err_base; if (!disp) return 0; XShapeQueryExtension(disp, &base, &err_base); base += ShapeNotify; return base; } KeySym ecore_key_get_keysym_from_keycode(KeyCode keycode) { if (!disp) return 0; return XKeycodeToKeysym(disp, keycode, 0); } char * ecore_key_get_string_from_keycode(KeyCode keycode) { char *str; if (!disp) return strdup(""); str = XKeysymToString(ecore_key_get_keysym_from_keycode(keycode)); if (!str) return strdup(""); return strdup(str); } void ecore_event_allow(int mode, Time t) { if (!disp) return; XAllowEvents(disp, mode, t); } int ecore_lock_mask_scroll_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Scroll_Lock); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_lock_mask_num_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Num_Lock); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_lock_mask_caps_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Caps_Lock); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_mod_mask_shift_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Shift_L); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_mod_mask_ctrl_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Control_L); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_mod_mask_alt_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Alt_L); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_mod_mask_win_get(void) { static int have_mask = 0; static int mask = 0; XModifierKeymap *mod; KeyCode nl; int i; int masks[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; if (!disp) return 0; if (have_mask) return mask; mod = XGetModifierMapping(disp); nl = XKeysymToKeycode(disp, XK_Meta_L); if ((mod) && (mod->max_keypermod > 0)) { for (i = 0; i < (8 * mod->max_keypermod); i++) { if ((nl) && (mod->modifiermap[i] == nl)) { mask = masks[i / mod->max_keypermod]; if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); if (mask == ecore_mod_mask_alt_get()) mask = 0; if (mask == ecore_mod_mask_ctrl_get()) mask = 0; have_mask = 1; return mask; } } } if (mod) { if (mod->modifiermap) XFree(mod->modifiermap); XFree(mod); } return 0; } int ecore_lock_mask_get(void) { static int mask = 0; Window root_ret, child_ret; int root_x_ret, root_y_ret, win_x_ret, win_y_ret; unsigned int mask_ret; if (!disp) return 0; if (!mask) mask = ecore_lock_mask_scroll_get() | ecore_lock_mask_num_get() | ecore_lock_mask_caps_get(); XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret, &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret); return (mask_ret & mask); } int ecore_modifier_mask_get(void) { Window root_ret, child_ret; int root_x_ret, root_y_ret, win_x_ret, win_y_ret; unsigned int mask_ret; if (!disp) return 0; XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret, &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret); return (mask_ret); } Window ecore_get_key_grab_win(void) { if (!disp) return 0; return grabkey_win; } void ecore_key_grab(char *key, Ecore_Event_Key_Modifiers mods, int anymod, int sync) { KeyCode keycode; int i, mod, mask_scroll, mask_num, mask_caps, masks[8], mode; if (!disp) return; keycode = ecore_key_get_keycode(key); mod = 0; mode = GrabModeAsync; if (sync) mode = GrabModeSync; if (!grabkey_win) grabkey_win = default_root; if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT) mod |= ecore_mod_mask_shift_get(); if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL) mod |= ecore_mod_mask_ctrl_get(); if (mods & ECORE_EVENT_KEY_MODIFIER_ALT) mod |= ecore_mod_mask_alt_get(); if (mods & ECORE_EVENT_KEY_MODIFIER_WIN) mod |= ecore_mod_mask_win_get(); mask_scroll = ecore_lock_mask_scroll_get(); mask_num = ecore_lock_mask_num_get(); mask_caps = ecore_lock_mask_caps_get(); masks[0] = 0; masks[1] = mask_scroll; masks[2] = mask_num; masks[3] = mask_caps; masks[4] = mask_scroll | mask_num; masks[5] = mask_scroll | mask_caps; masks[6] = mask_num | mask_caps; masks[7] = mask_scroll | mask_num | mask_caps; if (anymod) XGrabKey(disp, keycode, AnyModifier, grabkey_win, False, mode, mode); else { for (i = 0; i < 8; i++) XGrabKey(disp, keycode, masks[i] | mod, grabkey_win, False, mode, mode); } } void ecore_key_ungrab(char *key, Ecore_Event_Key_Modifiers mods, int anymod) { KeyCode keycode; if (!disp) return; keycode = ecore_key_get_keycode(key); if (anymod) XUngrabKey(disp, keycode, AnyModifier, default_root); else { int i, mod, mask_scroll, mask_num, mask_caps, masks[8]; mod = 0; if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT) mod |= ecore_mod_mask_shift_get(); if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL) mod |= ecore_mod_mask_ctrl_get(); if (mods & ECORE_EVENT_KEY_MODIFIER_ALT) mod |= ecore_mod_mask_alt_get(); if (mods & ECORE_EVENT_KEY_MODIFIER_WIN) mod |= ecore_mod_mask_win_get(); mask_scroll = ecore_lock_mask_scroll_get(); mask_num = ecore_lock_mask_num_get(); mask_caps = ecore_lock_mask_caps_get(); masks[0] = 0; masks[1] = mask_scroll; masks[2] = mask_num; masks[3] = mask_caps; masks[4] = mask_scroll | mask_num; masks[5] = mask_scroll | mask_caps; masks[6] = mask_num | mask_caps; masks[7] = mask_scroll | mask_num | mask_caps; for (i = 0; i < 8; i++) XUngrabKey(disp, keycode, masks[i] | mod, grabkey_win); } } KeyCode ecore_key_get_keycode(char *key) { if (!disp) return 0; return XKeysymToKeycode(disp, XStringToKeysym(key)); } void ecore_window_destroy(Window win) { if (!disp) return; ecore_unvalidate_xid(win); XDestroyWindow(disp, win); } void ecore_window_reparent(Window win, Window parent, int x, int y) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { if (parent == 0) parent = default_root; XReparentWindow(disp, win, parent, x, y); ecore_del_child(xid->parent, win); ecore_add_child(parent, win); xid->parent = parent; xid->x = x; xid->y = y; } } void ecore_window_raise(Window win) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { XRaiseWindow(disp, win); ecore_raise_child(xid->parent, win); } } void ecore_window_lower(Window win) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { XLowerWindow(disp, win); ecore_lower_child(xid->parent, win); } } void ecore_window_get_geometry(Window win, int *x, int *y, int *w, int *h) { Ecore_XID *xid = NULL; if (!disp) return; if (win == 0) win = default_root; xid = ecore_validate_xid(win); if ((xid) && (xid->coords_invalid)) { Window dw; int rx, ry; unsigned int rw, rh, di; XGetGeometry(disp, win, &dw, &rx, &ry, &rw, &rh, &di, &di); xid->x = rx; xid->y = ry; xid->w = (int)rw; xid->h = (int)rh; xid->coords_invalid = 0; } if (xid) { if (x) *x = xid->x; if (y) *y = xid->y; if (w) *w = xid->w; if (h) *h = xid->h; } else { if (x) *x = 0; if (y) *y = 0; if (w) *w = 0; if (h) *h = 0; } } int ecore_window_get_depth(Window win) { Ecore_XID *xid = NULL; if (!disp) return 0; if (win == 0) win = default_root; xid = ecore_validate_xid(win); if (xid) return xid->depth; return -1; } int ecore_window_exists(Window win) { Ecore_XID *xid = NULL; if (!disp) return 0; xid = ecore_validate_xid(win); if (xid) return 1; return 0; } Window ecore_window_get_parent(Window win) { Ecore_XID *xid = NULL; if (!disp) return 0; xid = ecore_validate_xid(win); if (xid) return xid->parent; return 0; } Window * ecore_window_get_children(Window win, int *num) { Ecore_XID *xid = NULL; if (!disp) return NULL; if (win == 0) win = default_root; xid = ecore_validate_xid(win); if (xid) { Window *wlist = NULL; *num = xid->children_num; if (xid->children) { wlist = NEW(Window, xid->children_num); MEMCPY(xid->children, wlist, Window, xid->children_num); } return wlist; } *num = 0; return NULL; } int ecore_window_mouse_in(Window win) { Ecore_XID *xid = NULL; if (!disp) return 0; if (win == 0) win = default_root; xid = ecore_validate_xid(win); if (xid) return xid->mouse_in; return 0; } void ecore_window_mouse_set_in(Window win, int in) { Ecore_XID *xid = NULL; if (!disp) return; if (win == 0) win = default_root; xid = ecore_validate_xid(win); if (xid) xid->mouse_in = in; } Display * ecore_display_get(void) { return disp; } Window ecore_window_get_root(Window win) { Ecore_XID *xid = NULL; if (!disp) return 0; xid = ecore_validate_xid(win); if (xid) return xid->root; return 0; } void ecore_lock_scroll_set(int onoff) { lock_scroll = onoff; } int ecore_lock_scroll_get(void) { return lock_scroll; } void ecore_lock_num_set(int onoff) { lock_num = onoff; } int ecore_lock_num_get(void) { return lock_num; } void ecore_lock_caps_set(int onoff) { lock_caps = onoff; } int ecore_lock_caps_get(void) { return lock_caps; } void ecore_mod_shift_set(int onoff) { mod_shift = onoff; } int ecore_mod_shift_get(void) { return mod_shift; } void ecore_mod_ctrl_set(int onoff) { mod_ctrl = onoff; } int ecore_mod_ctrl_get(void) { return mod_ctrl; } void ecore_mod_alt_set(int onoff) { mod_alt = onoff; } int ecore_mod_alt_get(void) { return mod_alt; } void ecore_mod_win_set(int onoff) { mod_win = onoff; } int ecore_mod_win_get(void) { return mod_win; } void ecore_focus_window_set(Window win) { focused_win = win; } Window ecore_focus_window_get(void) { return focused_win; } void ecore_focus_to_window(Window win) { if (!disp) return; if (win == 0) win = default_root; XSetInputFocus(disp, win, RevertToNone, CurrentTime); } void ecore_focus_mode_reset(void) { if (!disp) return; XSetInputFocus(disp, default_root, RevertToPointerRoot, CurrentTime); } Atom ecore_atom_get(char *name) { if (!disp) return 0; return XInternAtom(disp, name, False); } void ecore_window_set_delete_inform(Window win) { static Atom protocols[1] = { 0 }; if (!disp) return; ECORE_ATOM(protocols[0], "WM_DELETE_WINDOW"); XSetWMProtocols(disp, win, protocols, 1); } void ecore_window_property_set(Window win, Atom type, Atom format, int size, void *data, int number) { if (!disp) return; if (win == 0) win = default_root; if (size != 32) XChangeProperty(disp, win, type, format, size, PropModeReplace, (unsigned char *)data, number); else { long *dat; int i, *ptr; dat = NEW(long, number); for (ptr = (int *)data, i = 0; i < number; i++) dat[i] = ptr[i]; XChangeProperty(disp, win, type, format, size, PropModeReplace, (unsigned char *)dat, number); FREE(dat); } } void * ecore_window_property_get(Window win, Atom type, Atom format, int *size) { unsigned char *retval; Atom type_ret; unsigned long bytes_after, num_ret; int format_ret; void *data = NULL; if (!disp) return NULL; retval = NULL; if (win == 0) win = default_root; XGetWindowProperty(disp, win, type, 0, 0x7fffffffL, False, format, &type_ret, &format_ret, &num_ret, &bytes_after, &retval); if (retval) { if (format_ret == 32) { int i; *size = num_ret * sizeof(unsigned int); data = NEW(unsigned int, num_ret); for (i = 0; i < (int)num_ret; i++) ((unsigned int *)data)[i] = ((unsigned long *)retval)[i]; } else if (format_ret == 16) { int i; *size = num_ret * sizeof(unsigned short); data = NEW(unsigned short, *size); for (i = 0; i < (int)num_ret; i++) ((unsigned short *)data)[i] = ((unsigned short *)retval)[i]; } else if (format_ret == 8) { /* format_ret == 8 */ *size = num_ret; data = NEW(char, num_ret); if (data) memcpy(data, retval, num_ret); } XFree(retval); return data; } *size = 0; return NULL; } void ecore_window_dnd_advertise(Window win) { static Atom atom_xdndaware = 0; int dnd_version = 3; if (!disp) return; ECORE_ATOM(atom_xdndaware, "XdndAware"); ecore_window_property_set(win, atom_xdndaware, XA_ATOM, 32, &dnd_version, 1); } void ecore_grab(void) { if (!disp) return; x_grabs++; if (x_grabs == 1) XGrabServer(disp); } void ecore_ungrab(void) { if (!disp) return; x_grabs--; if (x_grabs == 0) { XUngrabServer(disp); ecore_sync(); } } void ecore_window_ignore(Window win) { Window_List *w; if (!disp) return; if (win == 0) win = default_root; w = NEW(Window_List, 1); w->win = win; w->next = ignore_wins; ignore_wins = w; } void ecore_window_no_ignore(Window win) { Window_List *w, *pw; if (!disp) return; if (win == 0) win = default_root; for (pw = NULL, w = ignore_wins; w; pw = w, w = w->next) { if (w->win == win) { if (pw) pw->next = w->next; else ignore_wins = w->next; FREE(w); return; } } } int ecore_window_is_ignored(Window win) { Window_List *w; if (!disp) return 0; if (win == 0) win = default_root; for (w = ignore_wins; w; w = w->next) { if (w->win == win) return 1; } return 0; } static Window ecore_window_at_xy_0(Window base, int bx, int by, int x, int y) { Window *list = NULL; XWindowAttributes att; Window child = 0, parent_win = 0, root_win = 0; int i; unsigned int ww, wh, num; int wx, wy; if (!disp) return 0; if ((!XGetWindowAttributes(disp, base, &att)) || (att.map_state != IsViewable)) return 0; wx = att.x; wy = att.y; ww = att.width; wh = att.height; wx += bx; wy += by; if (!((x >= wx) && (y >= wy) && (x < (int)(wx + ww)) && (y < (int)(wy + wh)))) return 0; if (!XQueryTree(disp, base, &root_win, &parent_win, &list, &num)) return base; if (list) { for (i = num - 1;; i--) { if (!ecore_window_is_ignored(list[i])) { if ((child = ecore_window_at_xy_0(list[i], wx, wy, x, y)) != 0) { XFree(list); return child; } } if (!i) break; } XFree(list); } return base; } Window ecore_window_get_at_xy(int x, int y) { Window child; if (!disp) return 0; ecore_grab(); child = ecore_window_at_xy_0(default_root, 0, 0, x, y); if (child) { ecore_ungrab(); return child; } ecore_ungrab(); return default_root; } int ecore_window_dnd_capable(Window win) { static Atom atom_xdndaware = 0; int dnd_version = 3; int *atom_ret; int size = 0; if (!disp) return 0; ECORE_ATOM(atom_xdndaware, "XdndAware"); atom_ret = ecore_window_property_get(win, atom_xdndaware, XA_ATOM, &size); if ((atom_ret) && (size >= (int)sizeof(int))) { if (atom_ret[0] == dnd_version) { FREE(atom_ret); return 1; } FREE(atom_ret); } return 0; } void ecore_window_dnd_handle_motion(Window source_win, int x, int y, int dragging) { static Atom atom_xdndenter = 0; static Atom atom_xdndleave = 0; static Atom atom_xdnddrop = 0; static Atom atom_xdndposition = 0; static Atom atom_xdndactioncopy = 0; static Atom atom_xdndactionmove = 0; static Atom atom_xdndactionlink = 0; static Atom atom_xdndactionask = 0; static Atom atom_text_uri_list = 0; static Atom atom_text_plain = 0; static Atom atom_text_moz_url = 0; static Atom atom_netscape_url = 0; Window win; XEvent xevent; if (!disp) return; win = ecore_window_get_at_xy(x, y); while ((win) && (!ecore_window_dnd_capable(win))) win = ecore_window_get_parent(win); ECORE_ATOM(atom_xdndenter, "XdndEnter"); ECORE_ATOM(atom_xdndleave, "XdndLeave"); ECORE_ATOM(atom_xdnddrop, "XdndDrop"); ECORE_ATOM(atom_xdndposition, "XdndPosition"); ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); ECORE_ATOM(atom_text_uri_list, "text/uri-list"); ECORE_ATOM(atom_text_plain, "text/plain"); ECORE_ATOM(atom_text_moz_url, "text/x-moz-url"); ECORE_ATOM(atom_netscape_url, "_NETSCAPE_URL"); if ((win != current_dnd_win) && (current_dnd_win)) { /* send leave to old dnd win */ xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.format = 32; xevent.xclient.window = current_dnd_win; xevent.xclient.message_type = atom_xdndleave; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = 0; xevent.xclient.data.l[2] = 0; xevent.xclient.data.l[3] = 0; xevent.xclient.data.l[4] = 0; XSendEvent(disp, current_dnd_win, False, 0, &xevent); } if (win) { if (win != current_dnd_win) { /* send enter on new win */ xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdndenter; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = (3 << 24); xevent.xclient.data.l[2] = atom_text_uri_list; xevent.xclient.data.l[3] = atom_text_plain; xevent.xclient.data.l[4] = atom_text_moz_url; XSendEvent(disp, win, False, 0, &xevent); ecore_clear_target_status(); } /* kjb cep */ if(!dnd_await_target_status) { /* send position information */ xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdndposition; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = (3 << 24); xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); xevent.xclient.data.l[3] = CurrentTime; if (dnd_copy) xevent.xclient.data.l[4] = atom_xdndactioncopy; else if (dnd_link) xevent.xclient.data.l[4] = atom_xdndactionlink; else if (dnd_move) xevent.xclient.data.l[4] = atom_xdndactionmove; else xevent.xclient.data.l[4] = atom_xdndactionask; XSendEvent(disp, win, False, 0, &xevent); dnd_await_target_status = 1; } } if (!dragging) { if (win) { if (current_dnd_target_ok) { xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdnddrop; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = 0; xevent.xclient.data.l[2] = CurrentTime; xevent.xclient.data.l[3] = 0; xevent.xclient.data.l[4] = 0; XSendEvent(disp, win, False, 0, &xevent); } else { xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdndleave; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = 0; xevent.xclient.data.l[2] = 0; xevent.xclient.data.l[3] = 0; xevent.xclient.data.l[4] = 0; XSendEvent(disp, win, False, 0, &xevent); } } current_dnd_target_ok = 0; } current_dnd_win = win; } void ecore_clear_target_status(void) { dnd_await_target_status = 0; } int ecore_dnd_selection_convert(Window win, Window req, Atom type) { static Atom atom_xdndselection = 0; static Atom atom_jxselectionwindowproperty = 0; if (!disp) return 0; ECORE_ATOM(atom_xdndselection, "XdndSelection"); ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty"); if (win == XGetSelectionOwner(disp, atom_xdndselection)) { XConvertSelection(disp, atom_xdndselection, type, atom_jxselectionwindowproperty, req, CurrentTime); return 1; } return 0; } void * ecore_dnd_selection_get(Window win, Window req, Atom type, int *size) { unsigned char *data = NULL; long bytes_read; unsigned long remaining = 1; if (!disp) return NULL; *size = 0; bytes_read = 0; while (remaining) { unsigned char *s; Atom actual; int format; unsigned long count; s = NULL; if (XGetWindowProperty(disp, win, type, bytes_read / 4, 0x10000, 1, AnyPropertyType, &actual, &format, &count, &remaining, &s) != Success) { /* error occured */ XFree(s); IF_FREE(data); *size = 0; return NULL; } if (s) { /* got some mroe data - append it */ bytes_read += count; if (!data) data = NEW(char, bytes_read); else REALLOC(data, char, bytes_read); MEMCPY(s, data + (bytes_read - count), char, count); XFree(s); } } *size = bytes_read; return data; req = 0; } void ecore_dnd_set_data(Window win) { static Atom atom_xdndselection = 0; if (!disp) return; ECORE_ATOM(atom_xdndselection, "XdndSelection"); ecore_dnd_set_action(win); XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime); } void ecore_dnd_set_action(Window win) { static int atom_xdndactioncopy = 0; static int atom_xdndactionmove = 0; static int atom_xdndactionlink = 0; static int atom_xdndactionask = 0; static Atom atom_xdndactionlist = 0; if (!disp) return; ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); ECORE_ATOM(atom_xdndactionlist, "XdndActionList"); if (dnd_copy) ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, &atom_xdndactioncopy, 1); else if (dnd_link) ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, &atom_xdndactionlink, 1); else if (dnd_move) ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, &atom_xdndactionmove, 1); else ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, &atom_xdndactionask, 1); } void ecore_dnd_send_data(Window win, Window source_win, void *data, int size, Atom dest_atom, int type) { XEvent xevent; static Atom atom_text_plain = 0; static Atom atom_text_uri_list = 0; static Atom atom_text_moz_url = 0; static Atom atom_netscape_url = 0; static Atom atom_xdndselection = 0; Atom target; if (!disp) return; ECORE_ATOM(atom_xdndselection, "XdndSelection"); ECORE_ATOM(atom_text_uri_list, "text/uri-list"); ECORE_ATOM(atom_text_plain, "text/plain"); ECORE_ATOM(atom_text_moz_url, "text/x-moz-url"); ECORE_ATOM(atom_text_moz_url, "_NETSCAPE_URL"); ECORE_ATOM(atom_text_plain, "text/plain"); if (type == DND_TYPE_URI_LIST) target = atom_text_uri_list; else if (type == DND_TYPE_PLAIN_TEXT) target = atom_text_plain; else if (type == DND_TYPE_MOZ_URL) target = atom_text_moz_url; else if (type == DND_TYPE_NETSCAPE_URL) target = atom_netscape_url; else target = 0; ecore_window_property_set(win, dest_atom, target, 8, data, size); xevent.xselection.type = SelectionNotify; xevent.xselection.property = dest_atom; xevent.xselection.display = disp; xevent.xselection.requestor = win; xevent.xselection.selection = atom_xdndselection; xevent.xselection.target = target; xevent.xselection.time = CurrentTime; XSendEvent(disp, win, False, 0, &xevent); return; source_win = 0; } void ecore_dnd_set_mode_copy(void) { dnd_copy = 1; dnd_link = 0; dnd_move = 0; } void ecore_dnd_set_mode_link(void) { dnd_copy = 0; dnd_link = 1; dnd_move = 0; } void ecore_dnd_set_mode_move(void) { dnd_copy = 0; dnd_link = 0; dnd_move = 1; } void ecore_dnd_set_mode_ask(void) { dnd_copy = 0; dnd_link = 0; dnd_move = 0; } void ecore_dnd_own_selection(Window win) { static Atom atom_xdndselection = 0; static Atom atom_jxselectionwindowproperty = 0; if (!disp) return; ECORE_ATOM(atom_xdndselection, "XdndSelection"); ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty"); if (!XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime)) return; } void ecore_dnd_send_drop(Window win, Window source_win) { static Atom atom_xdnddrop = 0; XEvent xevent; if (!disp) return; ECORE_ATOM(atom_xdnddrop, "XdndDrop"); ecore_dnd_own_selection(source_win); memset(&xevent, 0, sizeof(xevent)); xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdnddrop; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = CurrentTime; xevent.xclient.data.l[2] = 0; xevent.xclient.data.l[3] = 0; xevent.xclient.data.l[4] = 0; XSendEvent(disp, win, False, 0, &xevent); } void ecore_window_dnd_send_status_ok(Window source_win, Window win, int x, int y, int w, int h) { static Atom atom_xdndstatus = 0; static Atom atom_xdndactioncopy = 0; static Atom atom_xdndactionmove = 0; static Atom atom_xdndactionlink = 0; static Atom atom_xdndactionask = 0; XEvent xevent; if (!disp) return; ECORE_ATOM(atom_xdndstatus, "XdndStatus"); ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); memset(&xevent, 0, sizeof(xevent)); xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdndstatus; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = 3; xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); xevent.xclient.data.l[3] = ((h << 16) & 0xffff0000) | (w & 0xffff); if (dnd_copy) xevent.xclient.data.l[4] = atom_xdndactioncopy; else if (dnd_link) xevent.xclient.data.l[4] = atom_xdndactionlink; else if (dnd_move) xevent.xclient.data.l[4] = atom_xdndactionmove; else xevent.xclient.data.l[4] = atom_xdndactionask; XSendEvent(disp, win, False, 0, &xevent); } void ecore_window_dnd_send_finished(Window source_win, Window win) { static Atom atom_xdndfinished = 0; XEvent xevent; if (!disp) return; ECORE_ATOM(atom_xdndfinished, "XdndFinished"); memset(&xevent, 0, sizeof(xevent)); xevent.xany.type = ClientMessage; xevent.xany.display = disp; xevent.xclient.window = win; xevent.xclient.message_type = atom_xdndfinished; xevent.xclient.format = 32; xevent.xclient.data.l[0] = source_win; xevent.xclient.data.l[1] = 0; xevent.xclient.data.l[2] = 0; xevent.xclient.data.l[3] = 0; xevent.xclient.data.l[4] = 0; XSendEvent(disp, win, False, 0, &xevent); } void ecore_window_dnd_ok(int ok) { current_dnd_target_ok = ok; } void ecore_window_dnd_finished(void) { current_dnd_win = 0; } void ecore_window_set_title(Window win, char *title) { if (!disp) return; XStoreName(disp, win, title); } void ecore_window_set_name_class(Window win, char *name, char *class) { XClassHint hint; if (!disp) return; hint.res_name = name; hint.res_class = class; XSetClassHint(disp, win, &hint); } void ecore_window_get_name_class(Window win, char **name, char **class) { XClassHint xch; if (!disp) return; if (name) *name = NULL; if (class) *class = NULL; if (XGetClassHint(disp, win, &xch)) { if (name) { if (xch.res_name) *name = strdup(xch.res_name); } if (class) { if (xch.res_class) *class = strdup(xch.res_class); } XFree(xch.res_name); XFree(xch.res_class); } } void ecore_window_get_hints(Window win, int *accepts_focus, int *initial_state, Pixmap * icon_pixmap, Pixmap * icon_mask, Window * icon_window, Window * window_group) { XWMHints *hints; if (!disp) return; hints = XGetWMHints(disp, win); if (hints) { if ((hints->flags & InputHint) && (accepts_focus)) { if (hints->input) *accepts_focus = 1; else *accepts_focus = 0; } if ((hints->flags & StateHint) && (initial_state)) { *initial_state = hints->initial_state; } if ((hints->flags & IconPixmapHint) && (icon_pixmap)) { *icon_pixmap = hints->icon_pixmap; } if ((hints->flags & IconMaskHint) && (icon_mask)) { *icon_mask = hints->icon_pixmap; } if ((hints->flags & IconWindowHint) && (icon_window)) { *icon_window = hints->icon_window; } if ((hints->flags & WindowGroupHint) && (window_group)) { *window_group = hints->window_group; } XFree(hints); } } char * ecore_window_get_machine(Window win) { XTextProperty xtp; if (!disp) return NULL; if (XGetWMClientMachine(disp, win, &xtp)) { char *s; if (!xtp.value) return NULL; s = strdup(xtp.value); XFree(xtp.value); return s; } return NULL; } char * ecore_window_get_command(Window win) { int cargc; char **cargv; if (!disp) return NULL; if (XGetCommand(disp, win, &cargv, &cargc)) { if (cargc > 0) { char *s; int size, i; size = 0; for (i = 0; i < cargc; i++) size += strlen(cargv[i]); size += cargc - 1; s = NEW(char, size + 1); s[0] = 0; strcpy(s, cargv[0]); for (i = 1; i < cargc; i++) { strcat(s, " "); strcat(s, cargv[i]); } XFreeStringList(cargv); return s; } else return NULL; } return NULL; } char * ecore_window_get_icon_name(Window win) { XTextProperty xtp; if (!disp) return NULL; if (XGetWMIconName(disp, win, &xtp)) { char *s; if (!xtp.value) return NULL; s = strdup(xtp.value); XFree(xtp.value); return s; } return NULL; } void ecore_window_set_min_size(Window win, int w, int h) { XSizeHints hints; long ret; if (!disp) return; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(disp, win, &hints, &ret); hints.flags |= PMinSize | PSize | USSize; hints.min_width = w; hints.min_height = h; XSetWMNormalHints(disp, win, &hints); } void ecore_window_set_max_size(Window win, int w, int h) { XSizeHints hints; long ret; if (!disp) return; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(disp, win, &hints, &ret); hints.flags |= PMaxSize | PSize | USSize; hints.max_width = w; hints.max_height = h; XSetWMNormalHints(disp, win, &hints); } void ecore_window_set_xy_hints(Window win, int x, int y) { XSizeHints hints; long ret; if (!disp) return; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(disp, win, &hints, &ret); hints.flags |= PPosition | USPosition | PSize | USSize; hints.x = x; hints.y = y; XSetWMNormalHints(disp, win, &hints); } void ecore_window_get_frame_size(Window win, int *l, int *r, int *t, int *b) { static Atom atom_e_frame_size = 0; int *data, size; if (!disp) return; ECORE_ATOM(atom_e_frame_size, "_E_FRAME_SIZE"); data = ecore_window_property_get(win, atom_e_frame_size, XA_CARDINAL, &size); if (data) { if (size == (4 * sizeof(int))) { if (l) *l = data[0]; if (r) *r = data[1]; if (t) *t = data[2]; if (b) *b = data[3]; } else { if (l) *l = 0; if (r) *r = 0; if (t) *t = 0; if (b) *b = 0; } FREE(data); } else { if (l) *l = 0; if (r) *r = 0; if (t) *t = 0; if (b) *b = 0; } } int ecore_window_save_under(Window win) { XSetWindowAttributes att; XWindowAttributes gatt; if (!disp) return 0; att.save_under = True; XChangeWindowAttributes(disp, win, CWSaveUnder, &att); XGetWindowAttributes(disp, win, &gatt); return (gatt.save_under == True) ? 1 : 0; } GC ecore_gc_new(Drawable d) { XGCValues gcv; if (!disp) return 0; if (d == 0) d = default_root; return XCreateGC(disp, d, 0, &gcv); } void ecore_gc_free(GC gc) { if (!disp) return; XFreeGC(disp, gc); } void ecore_gc_set_fg(GC gc, int val) { if (!disp) return; XSetForeground(disp, gc, val); } void ecore_fill_rectangle(Drawable d, GC gc, int x, int y, int w, int h) { if (!disp) return; XFillRectangle(disp, d, gc, x, y, w, h); } void ecore_draw_rectangle(Drawable d, GC gc, int x, int y, int w, int h) { if (!disp) return; XDrawRectangle(disp, d, gc, x, y, w - 1, h - 1); } void ecore_draw_line(Drawable d, GC gc, int x1, int y1, int x2, int y2) { if (!disp) return; XDrawLine(disp, d, gc, x1, y1, x2, y2); } void ecore_draw_point(Drawable d, GC gc, int x, int y) { if (!disp) return; XDrawPoint(disp, d, gc, x, y); } void ecore_window_hint_set_layer(Window win, int layer) { static Atom atom_win_layer = 0; if (!disp) return; ECORE_ATOM(atom_win_layer, "_WIN_LAYER"); ecore_window_property_set(win, atom_win_layer, XA_CARDINAL, 32, &layer, 1); } void ecore_window_hint_set_sticky(Window win, int sticky) { static Atom atom_win_state = 0; static Atom atom_win_hints = 0; int data; if (!disp) return; ECORE_ATOM(atom_win_state, "_WIN_STATE"); ECORE_ATOM(atom_win_hints, "_WIN_HINTS"); if (sticky) { data = ((1 << 0) | (1 << 8) | (1 << 9)); ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1); data = ((1 << 0) | (1 << 1) | (1 << 2)); ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1); } else { data = 0; ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1); ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1); } } void ecore_window_hint_set_borderless(Window win) { static Atom atom_motif_wm_hints = 0; int data[5]; if (!disp) return; ECORE_ATOM(atom_motif_wm_hints, "_MOTIF_WM_HINTS"); data[0] = 0x3; data[1] = 0x0; data[2] = 0x0; data[3] = 0x2ada27b0; data[4] = 0x2aabd6b0; ecore_window_property_set(win, atom_motif_wm_hints, atom_motif_wm_hints, 32, data, 5); } void ecore_grab_mouse(Window win, int confine, Cursor cursor) { int ret; if (!disp) return; if (confine) ret = XGrabPointer(disp, win, False, XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT, GrabModeAsync, GrabModeAsync, win, cursor, CurrentTime); else ret = XGrabPointer(disp, win, False, XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT, GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime); if (ret == GrabSuccess) grab_pointer_win = win; } void ecore_ungrab_mouse(void) { if (!disp) return; XUngrabPointer(disp, CurrentTime); grab_pointer_win = 0; } Window ecore_grab_window_get(void) { return grab_pointer_win; } int ecore_window_get_gravity(Window win) { XWindowAttributes att; if (!disp) return 0; XGetWindowAttributes(disp, win, &att); return att.win_gravity; } void ecore_window_gravity_reset(Window win) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { XSetWindowAttributes att; /* if (xid->gravity != NorthWestGravity)*/ { att.win_gravity = NorthWestGravity; XChangeWindowAttributes(disp, win, CWWinGravity, &att); xid->gravity = NorthWestGravity; xid->coords_invalid = 1; } } } void ecore_window_gravity_set(Window win, int gravity) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { /* if (xid->gravity != gravity)*/ { XSetWindowAttributes att; att.win_gravity = gravity; XChangeWindowAttributes(disp, win, CWWinGravity, &att); xid->gravity = gravity; xid->coords_invalid = 1; } } } void ecore_window_bit_gravity_set(Window win, int gravity) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { XSetWindowAttributes att; att.bit_gravity = gravity; XChangeWindowAttributes(disp, win, CWBitGravity, &att); } } void ecore_pointer_warp_by(int dx, int dy) { if (!disp) return; XWarpPointer(disp, None, None, 0, 0, 0, 0, dx, dy); } void ecore_pointer_warp_to(int x, int y) { if (!disp) return; XWarpPointer(disp, None, default_root, 0, 0, 0, 0, x, y); } void ecore_gc_set_include_inferiors(GC gc) { XGCValues gcv; if (!disp) return; gcv.subwindow_mode = IncludeInferiors; XChangeGC(disp, gc, GCSubwindowMode, &gcv); } void ecore_area_copy(Drawable src, Drawable dest, GC gc, int sx, int sy, int sw, int sh, int dx, int dy) { if (!disp) return; if (src == 0) src = default_root; if (dest == 0) dest = default_root; XCopyArea(disp, src, dest, gc, sx, sy, sw, sh, dx, dy); } Window ecore_window_root(void) { return default_root; } void ecore_window_get_virtual_area(Window win, int *area_x, int *area_y) { static Atom atom_win_area = 0; int *data, size; if (!disp) return; ECORE_ATOM(atom_win_area, "_WIN_AREA"); data = ecore_window_property_get(win, atom_win_area, XA_CARDINAL, &size); if (data) { if (size == (sizeof(int) * 2)) { if (area_x) *area_x = data[0]; if (area_y) *area_y = data[1]; } FREE(data); } } void ecore_get_virtual_area(int *area_x, int *area_y) { static Atom atom_win_area = 0; int *data, size; if (!disp) return; ECORE_ATOM(atom_win_area, "_WIN_AREA"); data = ecore_window_property_get(default_root, atom_win_area, XA_CARDINAL, &size); if (data) { if (size == (sizeof(int) * 2)) { if (area_x) *area_x = data[0]; if (area_y) *area_y = data[1]; } FREE(data); } } void ecore_window_get_root_relative_location(Window win, int *x, int *y) { int dx, dy; Window parent; Ecore_XID *xid = NULL; if (!disp) return; if (win == 0) win = default_root; if (win == default_root) { if (x) *x = 0; if (y) *y = 0; return; } xid = ecore_validate_xid(win); if (!xid) { if (x) *x = 0; if (y) *y = 0; return; } dx = 0; dy = 0; do { parent = xid->parent; dx += xid->x; dy += xid->y; if (parent != default_root) { xid = ecore_validate_xid(parent); if (!xid) { if (x) *x = dx; if (y) *y = dy; return; } } } while (parent != default_root); if (x) *x = dx; if (y) *y = dy; } void ecore_window_button_grab_auto_replay_set(Window win, int (*func) (Ecore_Event_Mouse_Down *ev)) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (!xid) return; xid->grab_button_auto_replay = func; } void * ecore_window_button_grab_auto_replay_get(Window win) { Ecore_XID *xid = NULL; if (!disp) return NULL; xid = ecore_validate_xid(win); if (!xid) return NULL; return xid->grab_button_auto_replay; } void ecore_button_grab(Window win, int button, int events, Ecore_Event_Key_Modifiers mod, int any_mod) { unsigned int b; unsigned int m; unsigned int locks[8]; int i; if (!disp) return; b = button; if (b == 0) b = AnyButton; m = 0; if (any_mod) m = AnyModifier; else { if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT) m |= ecore_mod_mask_shift_get(); if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL) m |= ecore_mod_mask_ctrl_get(); if (mod & ECORE_EVENT_KEY_MODIFIER_ALT) m |= ecore_mod_mask_alt_get(); if (mod & ECORE_EVENT_KEY_MODIFIER_WIN) m |= ecore_mod_mask_win_get(); } locks[0] = 0; locks[1] = ecore_lock_mask_caps_get(); locks[2] = ecore_lock_mask_num_get(); locks[3] = ecore_lock_mask_scroll_get(); locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get(); locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get(); locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get(); locks[7] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get(); for (i = 0; i < 8; i++) XGrabButton(disp, b, m | locks[i], win, False, events, GrabModeSync, GrabModeAsync, None, None); } void ecore_button_ungrab(Window win, int button, Ecore_Event_Key_Modifiers mod, int any_mod) { unsigned int b; unsigned int m; unsigned int locks[8]; int i; if (!disp) return; b = button; if (b == 0) b = AnyButton; m = 0; if (any_mod) m = AnyModifier; else { if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT) m |= ecore_mod_mask_shift_get(); if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL) m |= ecore_mod_mask_ctrl_get(); if (mod & ECORE_EVENT_KEY_MODIFIER_ALT) m |= ecore_mod_mask_alt_get(); if (mod & ECORE_EVENT_KEY_MODIFIER_WIN) m |= ecore_mod_mask_win_get(); } locks[0] = 0; locks[1] = ecore_lock_mask_caps_get(); locks[2] = ecore_lock_mask_num_get(); locks[3] = ecore_lock_mask_scroll_get(); locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get(); locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get(); locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get(); locks[7] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get(); for (i = 0; i < 8; i++) XUngrabButton(disp, b, m | locks[i], win); } void ecore_pointer_replay(Time t) { if (!disp) return; XSync(disp, False); XAllowEvents(disp, ReplayPointer, t); XSync(disp, False); } void ecore_pointer_grab(Window win, Time t) { if (!disp) return; XGrabPointer(disp, win, False, XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT, GrabModeAsync, GrabModeAsync, None, None, t); } void ecore_pointer_ungrab(Time t) { if (!disp) return; XUngrabPointer(disp, t); } void ecore_window_send_event_move_resize(Window win, int x, int y, int w, int h) { XEvent ev; if (!disp) return; ev.type = ConfigureNotify; ev.xconfigure.display = disp; ev.xconfigure.event = win; ev.xconfigure.window = win; ev.xconfigure.x = x; ev.xconfigure.y = y; ev.xconfigure.width = w; ev.xconfigure.height = h; ev.xconfigure.border_width = 0; ev.xconfigure.above = win; ev.xconfigure.override_redirect = False; XSendEvent(disp, win, False, StructureNotifyMask, &ev); } void ecore_window_send_client_message(Window win, Atom type, int format, void *data) { XClientMessageEvent ev; int i; if (!disp) return; ev.type = ClientMessage; ev.window = win; ev.message_type = type; ev.format = format; if (format == 32) { for (i = 0; i < 5; i++) ev.data.l[i] = ((unsigned int *)data)[i]; } else if (format == 16) { for (i = 0; i < 10; i++) ev.data.s[i] = ((unsigned short *)data)[i]; } else if (format == 8) { for (i = 0; i < 20; i++) ev.data.b[i] = ((unsigned char *)data)[i]; } XSendEvent(disp, win, False, 0, (XEvent *) & ev); } void ecore_window_add_to_save_set(Window win) { if (!disp) return; XAddToSaveSet(disp, win); } void ecore_window_del_from_save_set(Window win) { if (!disp) return; XRemoveFromSaveSet(disp, win); } void ecore_window_kill_client(Window win) { if (!disp) return; XKillClient(disp, (XID) win); } void ecore_window_set_border_width(Window win, int bw) { Ecore_XID *xid = NULL; if (!disp) return; xid = ecore_validate_xid(win); if (xid) { xid->bw = bw; } XSetWindowBorderWidth(disp, win, bw); } int ecore_window_get_border_width(Window win) { Ecore_XID *xid = NULL; if (!disp) return 0; xid = ecore_validate_xid(win); if (xid) { return xid->bw; } return 0; } int ecore_window_get_wm_size_hints(Window win, XSizeHints * hints, int *mask) { long sup_ret; Status ok; if (!disp) return 0; ok = XGetWMNormalHints(disp, win, hints, &sup_ret); *mask = (int)sup_ret; return ok; } int ecore_window_is_visible(Window win) { XWindowAttributes att; if (!disp) return 0; if (win == 0) win = default_root; if (XGetWindowAttributes(disp, win, &att) == True) { if (att.map_state == IsUnmapped) return 0; return 1; } return 0; } int ecore_window_is_normal(Window win) { XWindowAttributes att; if (!disp) return 0; if (win == 0) win = default_root; if (XGetWindowAttributes(disp, win, &att) == True) { if ((att.override_redirect) || (att.class == InputOnly)) return 0; return 1; } return 0; } int ecore_window_is_manageable(Window win) { XWindowAttributes att; if (!disp) return 0; if (win == 0) win = default_root; if (XGetWindowAttributes(disp, win, &att) == True) { if ((att.map_state == IsUnmapped) || (att.override_redirect) || (att.class == InputOnly)) return 0; return 1; } return 0; } void ecore_windows_restack(Window * wins, int num) { if (!disp) return; XRestackWindows(disp, wins, num); } void ecore_window_stack_above(Window win, Window above) { XWindowChanges xwc; if (!disp) return; if (win == 0) win = default_root; xwc.sibling = above; xwc.stack_mode = Above; XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc); } void ecore_window_stack_below(Window win, Window below) { XWindowChanges xwc; if (!disp) return; if (win == 0) win = default_root; xwc.sibling = below; xwc.stack_mode = Below; XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc); } char * ecore_window_get_title(Window win) { XTextProperty xtp; if (!disp) return 0; if (win == 0) win = default_root; if (XGetWMName(disp, win, &xtp)) { int items; char **list; Status s; char *title = NULL; if (xtp.format == 8) { s = XmbTextPropertyToTextList(disp, &xtp, &list, &items); if ((s == Success) && (items > 0)) { title = strdup(*list); XFreeStringList(list); } else title = strdup((char *)xtp.value); } else title = strdup((char *)xtp.value); XFree(xtp.value); return title; } return NULL; } void ecore_keyboard_grab(Window win) { int status; if (!disp) return; if (keyboard_grab_win) return; if (win == 0) win = default_root; keyboard_grab_win = win; status = XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); if ((status == AlreadyGrabbed) || (status == GrabNotViewable) || (status == GrabFrozen) || (status == GrabInvalidTime)) keyboard_grab_win = 0; } void ecore_keyboard_ungrab(void) { if (!disp) return; if (!keyboard_grab_win) return; keyboard_grab_win = 0; XUngrabKeyboard(disp, CurrentTime); } Window ecore_keyboard_grab_window_get(void) { if (!disp) return 0; return keyboard_grab_win; } Window ecore_selection_set(char *string) { Window target = 0; static Atom dest = 0; Atom selection; if (!disp) return 0; selection = X_CLIPBOARD_SELECTION; ECORE_ATOM(dest, "TEXT_SELECTION"); target = ecore_window_new(0, 0, 0, 77, 7); ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY); XSetSelectionOwner(disp, selection, target, CurrentTime); if (XGetSelectionOwner(disp, XA_PRIMARY) != target) { ecore_window_destroy(target); return 0; } XChangeProperty(disp, target, dest, XA_STRING, 8, PropModeReplace, string, strlen(string)); return target; } Window ecore_selection_request(void) { static Atom dest = 0; Atom selection; Window target = 0; if (!disp) return 0; selection = X_CLIPBOARD_SELECTION; ECORE_ATOM(dest, "TEXT_SELECTION"); target = ecore_window_new(0, 0, 0, 7, 77); ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY); XConvertSelection(disp, XA_PRIMARY, XA_STRING, dest, target, CurrentTime); return target; } char * ecore_selection_get_data(Window win, Atom prop) { char *string = NULL; long nread; unsigned long bytes_after, nitems; unsigned char *data; Atom actual_type; int actual_fmt; if (!disp) return NULL; if (prop == None) return NULL; for (nread = 0, bytes_after = 1; bytes_after > 0;) { if ((XGetWindowProperty(disp, win, prop, nread / 4, 0x10000, True, AnyPropertyType, &actual_type, &actual_fmt, &nitems, &bytes_after, &data) != Success)) { IF_FREE(string); if (data) { XFree(data); } return NULL; } nread += nitems; if (actual_type == XA_STRING) { if (string) string = realloc(string, strlen(string) + nitems + 1); else { string = malloc(nitems + 1); string[0] = 0; } string[strlen(string) + nitems] = 0; strncat(string, data, nitems); } else { int size, i; XTextProperty xtextp; char **cl = NULL; xtextp.value = data; xtextp.encoding = actual_type; xtextp.format = actual_fmt; xtextp.nitems = nitems; XmbTextPropertyToTextList(disp, &xtextp, &cl, &size); if (cl) { for (i = 0; i < size; i++) { if (cl[i]) { if (string) string = realloc(string, strlen(string) + strlen(cl[i]) + 1); else { string = malloc(strlen(cl[i]) + 1); string[0] = 0; } string[strlen(string) + strlen(cl[i])] = 0; strcat(string, cl[i]); } } XFreeStringList(cl); } } if (data) { XFree(data); } } return string; } void ecore_set_blank_pointer(Window w) { Cursor c; XColor cl; Pixmap p, m; GC gc; XGCValues gcv; if (!disp) return; if (w == 0) w = default_root; p = XCreatePixmap(disp, w, 1, 1, 1); m = XCreatePixmap(disp, w, 1, 1, 1); gc = XCreateGC(disp, m, 0, &gcv); XSetForeground(disp, gc, 0); XDrawPoint(disp, m, gc, 0, 0); XFreeGC(disp, gc); c = XCreatePixmapCursor(disp, p, m, &cl, &cl, 0, 0); XDefineCursor(disp, w, c); XFreeCursor(disp, c); XFreePixmap(disp, p); XFreePixmap(disp, m); } Cursor ecore_cursor_new(Pixmap pmap, Pixmap mask, int x, int y, int fr, int fg, int fb, int br, int bg, int bb) { XColor cl1, cl2; if (!disp) return 0; cl1.pixel = 0; cl1.red = fr << 8 | fr; cl1.green = fg << 8 | fg; cl1.blue = fb << 8 | fb; cl1.flags = DoRed | DoGreen | DoBlue; cl2.pixel = 0; cl2.red = br << 8 | br; cl2.green = bg << 8 | bg; cl2.blue = bb << 8 | bb; cl2.flags = DoRed | DoGreen | DoBlue; return XCreatePixmapCursor(disp, pmap, mask, &cl1, &cl2, x, y); } void ecore_cursor_free(Cursor c) { if (!disp) return; XFreeCursor(disp, c); } void ecore_cursor_set(Window win, Cursor c) { if (!disp) return; if (win == 0) win = default_root; XDefineCursor(disp, win, c); }