efl/legacy/ecore/src/e_x.c

2307 lines
48 KiB
C

#include "e_x.h"
#include "e_mem.h"
#include "e_str.h"
#include <Imlib2.h>
#include <stdio.h>
#include <unistd.h>
typedef struct _window_list Window_List;
struct _window_list
{
Window win;
Window_List *next;
};
static Display *disp;
static Visual *default_vis;
static Colormap default_cm;
static int default_depth;
static Window default_win;
static Window default_root;
static XContext xid_context = 0;
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 x_grabs = 0;
static Window_List *ignore_wins = NULL;
static Window grab_pointer_win = 0;
static int dnd_copy = 0;
static int dnd_link = 0;
static int dnd_move = 1;
static void e_handle_x_error(Display * d, XErrorEvent * ev);
static void e_handle_x_io_error(Display * d);
static Window e_window_at_xy_0(Window base, int bx, int by, int x, int y);
static void
e_handle_x_error(Display * d, XErrorEvent * ev)
{
/* ignroe all X errors */
return;
d = NULL;
ev = NULL;
}
static void
e_handle_x_io_error(Display * d)
{
/* FIXME: call clean exit handler */
exit(1);
d = NULL;
}
void
e_del_child(Window win, Window child)
{
E_XID *xid = NULL;
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
e_add_child(Window win, Window child)
{
E_XID *xid = NULL;
if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
return;
if (xid)
{
xid->children_num++;
if (!xid->children)
xid->children = NEW(Window, xid->children_num);
else
REALLOC(xid->children, Window, xid->children_num);
xid->children[xid->children_num - 1] = child;
}
}
void
e_raise_child(Window win, Window child)
{
E_XID *xid = NULL;
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
e_lower_child(Window win, Window child)
{
E_XID *xid = NULL;
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;
}
}
}
}
E_XID *
e_add_xid(Window win, int x, int y, int w, int h, int depth, Window parent)
{
E_XID *xid = NULL;
e_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | XEV_VISIBILITY);
xid = NEW(E_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 = e_window_get_root(parent);
xid->children_num = 0;
xid->children = NULL;
XSaveContext(disp, xid->win, xid_context, (XPointer) xid);
return xid;
}
E_XID *
e_validate_xid(Window win)
{
E_XID *xid = 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;
e_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE |
XEV_VISIBILITY | XEV_CHILD_CHANGE);
xid = NEW(E_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)
e_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;
XSaveContext(disp, xid->win, xid_context, (XPointer) xid);
}
return xid;
}
void
e_unvalidate_xid(Window win)
{
E_XID *xid = NULL;
if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT)
return;
if (xid)
{
int i;
for (i = 0; i < xid->children_num; i++)
e_unvalidate_xid(xid->children[i]);
IF_FREE(xid->children);
FREE(xid);
XDeleteContext(disp, win, xid_context);
}
}
void
e_sync(void)
{
XSync(disp, False);
}
void
e_flush(void)
{
XFlush(disp);
}
Window
e_window_new(Window parent, int x, int y, int w, int h)
{
Window win;
XSetWindowAttributes attr;
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);
e_add_xid(win, x, y, w, h, default_depth, parent);
return win;
}
Window
e_window_override_new(Window parent, int x, int y, int w, int h)
{
Window win;
XSetWindowAttributes attr;
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);
e_add_xid(win, x, y, w, h, default_depth, parent);
return win;
}
Window
e_window_input_new(Window parent, int x, int y, int w, int h)
{
Window win;
XSetWindowAttributes attr;
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);
e_add_xid(win, x, y, w, h, 0, parent);
return win;
}
void
e_window_show(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
if (xid->mapped)
xid->mapped = 1;
XMapWindow(disp, win);
}
}
void
e_window_hide(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
if (!xid->mapped)
return;
xid->mapped = 0;
XUnmapWindow(disp, win);
}
}
Pixmap
e_pixmap_new(Window win, int w, int h, int dep)
{
if (!win)
win = default_win;
if (dep == 0)
dep = default_depth;
return XCreatePixmap(disp, win, w, h, dep);
}
void
e_pixmap_free(Pixmap pmap)
{
if (!pmap)
return;
XFreePixmap(disp, pmap);
}
void
e_window_set_background_pixmap(Window win, Pixmap pmap)
{
XSetWindowBackgroundPixmap(disp, win, pmap);
}
void
e_window_set_shape_mask(Window win, Pixmap mask)
{
XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
}
void
e_window_clear(Window win)
{
XClearWindow(disp, win);
}
void
e_window_clear_area(Window win, int x, int y, int w, int h)
{
XClearArea(disp, win, x, y, w, h, False);
}
void
e_pointer_xy(Window win, int *x, int *y)
{
Window dw;
unsigned int dm;
int wx, wy;
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
e_pointer_xy_set(int x, int y)
{
mouse_x = x;
mouse_y = y;
}
void
e_pointer_xy_get(int *x, int *y)
{
if (x)
*x = mouse_x;
if (y)
*y = mouse_y;
}
void
e_window_set_events(Window win, long mask)
{
if (win == 0)
win = default_root;
XSelectInput(disp, win, mask);
}
void
e_window_remove_events(Window win, long mask)
{
XWindowAttributes att;
if (win == 0)
win = default_root;
if (XGetWindowAttributes(disp, win, &att) == True)
{
mask = att.your_event_mask & (~mask);
e_window_set_events(win, mask);
}
}
void
e_window_add_events(Window win, long mask)
{
XWindowAttributes att;
if (win == 0)
win = default_root;
if (XGetWindowAttributes(disp, win, &att) == True)
{
mask = att.your_event_mask | mask;
e_window_set_events(win, mask);
}
}
void
e_window_move(Window win, int x, int y)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
if ((xid->x == x) && (xid->y == y))
return;
xid->x = x;
xid->y = y;
XMoveWindow(disp, win, x, y);
}
}
void
e_window_resize(Window win, int w, int h)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
if ((xid->w == w) && (xid->h == h))
return;
xid->w = w;
xid->h = h;
XResizeWindow(disp, win, w, h);
}
}
void
e_window_move_resize(Window win, int x, int y, int w, int h)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
if ((xid->x == x) && (xid->y == y) && (xid->w == w) && (xid->h == h))
return;
xid->x = x;
xid->y = y;
xid->w = w;
xid->h = h;
XMoveResizeWindow(disp, win, x, y, w, h);
}
}
int
e_x_get_fd(void)
{
return ConnectionNumber(disp);
}
void
e_display_init(char *display)
{
int revert;
xid_context = XUniqueContext();
disp = XOpenDisplay(display);
if (!disp)
{
char *d;
d = getenv("DISPLAY");
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 efm\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 efm\n");
exit(1);
}
XSetErrorHandler((XErrorHandler) e_handle_x_error);
XSetIOErrorHandler((XIOErrorHandler) e_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 = e_mod_mask_shift_get();
mod_ctrl = e_mod_mask_ctrl_get();
mod_alt = e_mod_mask_alt_get();
mod_win = e_mod_mask_win_get();
XGetInputFocus(disp, &focused_win, &revert);
e_window_set_events(default_root, XEV_KEY | XEV_IN_OUT | XEV_MOUSE_MOVE |
XEV_CONFIGURE | XEV_CHILD_CHANGE | XEV_PROPERTY |
XEV_COLORMAP | XEV_VISIBILITY);
e_pointer_xy(0, NULL, NULL);
imlib_context_set_display(disp);
imlib_context_set_visual(default_vis);
imlib_context_set_colormap(default_cm);
imlib_context_set_drawable(default_root);
imlib_context_set_dither(0);
imlib_context_set_blend(1);
}
int
e_events_pending(void)
{
if (!disp) return 0;
return XPending(disp);
}
void
e_get_next_event(XEvent * event)
{
XNextEvent(disp, event);
}
int
e_event_shape_get_id(void)
{
int base = -1, err_base;
XShapeQueryExtension(disp, &base, &err_base);
base += ShapeNotify;
return base;
}
KeySym
e_key_get_keysym_from_keycode(KeyCode keycode)
{
return XKeycodeToKeysym(disp, keycode, 0);
}
char *
e_key_get_string_from_keycode(KeyCode keycode)
{
return e_string_dup(XKeysymToString(e_key_get_keysym_from_keycode(keycode)));
}
void
e_event_allow(int mode, Time t)
{
XAllowEvents(disp, mode, t);
}
int
e_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 (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
e_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 (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
e_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 (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
e_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 (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
e_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 (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
e_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 (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
e_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 (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 == e_mod_mask_alt_get())
mask = 0;
if (mask == e_mod_mask_ctrl_get())
mask = 0;
have_mask = 1;
return mask;
}
}
}
if (mod)
{
if (mod->modifiermap)
XFree(mod->modifiermap);
XFree(mod);
}
return 0;
}
int
e_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 (!mask)
mask = e_lock_mask_scroll_get() | e_lock_mask_num_get() |
e_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
e_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;
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
e_get_key_grab_win(void)
{
return grabkey_win;
}
void
e_key_grab(char *key, Ev_Key_Modifiers mods, int anymod, int sync)
{
KeyCode keycode;
int i, mod, mask_scroll, mask_num, mask_caps, masks[8], mode;
keycode = e_key_get_keycode(key);
mod = 0;
mode = GrabModeAsync;
if (sync)
mode = GrabModeSync;
if (!grabkey_win)
grabkey_win = default_root;
if (mods & EV_KEY_MODIFIER_SHIFT)
mod |= mod_shift;
if (mods & EV_KEY_MODIFIER_CTRL)
mod |= mod_ctrl;
if (mods & EV_KEY_MODIFIER_ALT)
mod |= mod_alt;
if (mods & EV_KEY_MODIFIER_WIN)
mod |= mod_win;
mask_scroll = e_lock_mask_scroll_get();
mask_num = e_lock_mask_num_get();
mask_caps = e_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
e_key_ungrab(char *key, Ev_Key_Modifiers mods, int anymod)
{
KeyCode keycode;
keycode = e_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 & EV_KEY_MODIFIER_SHIFT)
mod |= mod_shift;
if (mods & EV_KEY_MODIFIER_CTRL)
mod |= mod_ctrl;
if (mods & EV_KEY_MODIFIER_ALT)
mod |= mod_alt;
if (mods & EV_KEY_MODIFIER_WIN)
mod |= mod_win;
mask_scroll = e_lock_mask_scroll_get();
mask_num = e_lock_mask_num_get();
mask_caps = e_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
e_key_get_keycode(char *key)
{
return XKeysymToKeycode(disp, XStringToKeysym(key));
}
void
e_window_destroy(Window win)
{
e_unvalidate_xid(win);
XDestroyWindow(disp, win);
}
void
e_window_reparent(Window win, Window parent, int x, int y)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
if (parent == 0)
parent = default_root;
XReparentWindow(disp, win, parent, x, y);
e_del_child(xid->parent, win);
e_add_child(parent, win);
xid->parent = parent;
xid->x = x;
xid->y = y;
}
}
void
e_window_raise(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
XRaiseWindow(disp, win);
e_raise_child(xid->parent, win);
}
}
void
e_window_lower(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
{
XLowerWindow(disp, win);
e_lower_child(xid->parent, win);
}
}
void
e_window_get_geometry(Window win, int *x, int *y, int *w, int *h)
{
E_XID *xid = NULL;
if (win == 0)
win = default_root;
xid = e_validate_xid(win);
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
e_window_get_depth(Window win)
{
E_XID *xid = NULL;
if (win == 0)
win = default_root;
xid = e_validate_xid(win);
if (xid)
return xid->depth;
return -1;
}
int
e_window_exists(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
return 1;
return 0;
}
Window
e_window_get_parent(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
return xid->parent;
return 0;
}
Window *
e_window_get_children(Window win, int *num)
{
E_XID *xid = NULL;
if (win == 0)
win = default_root;
xid = e_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
e_window_mouse_in(Window win)
{
E_XID *xid = NULL;
if (win == 0)
win = default_root;
xid = e_validate_xid(win);
if (xid)
return xid->mouse_in;
return 0;
}
void
e_window_mouse_set_in(Window win, int in)
{
E_XID *xid = NULL;
if (win == 0)
win = default_root;
xid = e_validate_xid(win);
if (xid)
xid->mouse_in = in;
}
Display *
e_display_get(void)
{
return disp;
}
Window
e_window_get_root(Window win)
{
E_XID *xid = NULL;
xid = e_validate_xid(win);
if (xid)
return xid->root;
return 0;
}
void
e_lock_scroll_set(int onoff)
{
lock_scroll = onoff;
}
int
e_lock_scroll_get(void)
{
return lock_scroll;
}
void
e_lock_num_set(int onoff)
{
lock_num = onoff;
}
int
e_lock_num_get(void)
{
return lock_num;
}
void
e_lock_caps_set(int onoff)
{
lock_caps = onoff;
}
int
e_lock_caps_get(void)
{
return lock_caps;
}
void
e_mod_shift_set(int onoff)
{
mod_shift = onoff;
}
int
e_mod_shift_get(void)
{
return mod_shift;
}
void
e_mod_ctrl_set(int onoff)
{
mod_ctrl = onoff;
}
int
e_mod_ctrl_get(void)
{
return mod_ctrl;
}
void
e_mod_alt_set(int onoff)
{
mod_alt = onoff;
}
int
e_mod_alt_get(void)
{
return mod_alt;
}
void
e_mod_win_set(int onoff)
{
mod_win = onoff;
}
int
e_mod_win_get(void)
{
return mod_win;
}
void
e_focus_window_set(Window win)
{
focused_win = win;
}
Window
e_focus_window_get(void)
{
return focused_win;
}
void
e_focus_to_window(Window win)
{
if (win == 0)
win = default_root;
XSetInputFocus(disp, win, RevertToPointerRoot, CurrentTime);
}
Atom
e_atom_get(char *name)
{
return XInternAtom(disp, name, False);
}
void
e_window_set_delete_inform(Window win)
{
static Atom protocols[1] = { 0 };
E_ATOM(protocols[0], "WM_DELETE_WINDOW");
XSetWMProtocols(disp, win, protocols, 1);
}
void
e_window_property_set(Window win, Atom type, Atom format, int size, void *data,
int number)
{
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 *
e_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;
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
e_window_dnd_advertise(Window win)
{
static Atom atom_xdndaware = 0;
int dnd_version = 3;
E_ATOM(atom_xdndaware, "XdndAware");
e_window_property_set(win, atom_xdndaware, XA_ATOM, 32, &dnd_version, 1);
}
void
e_grab(void)
{
x_grabs++;
if (x_grabs == 1)
XGrabServer(disp);
}
void
e_ungrab(void)
{
x_grabs--;
if (x_grabs == 0)
{
XUngrabServer(disp);
e_sync();
}
}
void
e_window_ignore(Window win)
{
Window_List *w;
if (win == 0)
win = default_root;
w = NEW(Window_List, 1);
w->win = win;
w->next = ignore_wins;
ignore_wins = w;
}
void
e_window_no_ignore(Window win)
{
Window_List *w, *pw;
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
e_window_is_ignored(Window win)
{
Window_List *w;
if (win == 0)
win = default_root;
for (w = ignore_wins; w; w = w->next)
{
if (w->win == win)
return 1;
}
return 0;
}
static Window
e_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 ((!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 (!e_window_is_ignored(list[i]))
{
if ((child = e_window_at_xy_0(list[i], wx, wy, x, y)) != 0)
{
XFree(list);
return child;
}
}
if (!i)
break;
}
XFree(list);
}
return base;
}
Window
e_window_get_at_xy(int x, int y)
{
Window child;
e_grab();
child = e_window_at_xy_0(default_root, 0, 0, x, y);
if (child)
{
e_ungrab();
return child;
}
e_ungrab();
return default_root;
}
int
e_window_dnd_capable(Window win)
{
static Atom atom_xdndaware = 0;
int dnd_version = 3;
int *atom_ret;
int size = 0;
E_ATOM(atom_xdndaware, "XdndAware");
atom_ret = e_window_property_get(win, atom_xdndaware, XA_ATOM, &size);
if ((atom_ret) && (size >= sizeof(int)))
{
if (atom_ret[0] == dnd_version)
{
FREE(atom_ret);
return 1;
}
FREE(atom_ret);
}
return 0;
}
void
e_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;
Window win;
XEvent xevent;
win = e_window_get_at_xy(x, y);
while ((win) && (!e_window_dnd_capable(win)))
win = e_window_get_parent(win);
E_ATOM(atom_xdndenter, "XdndEnter");
E_ATOM(atom_xdndleave, "XdndLeave");
E_ATOM(atom_xdnddrop, "XdndDrop");
E_ATOM(atom_xdndposition, "XdndPosition");
E_ATOM(atom_xdndactioncopy, "XdndActionCopy");
E_ATOM(atom_xdndactionmove, "XdndActionMove");
E_ATOM(atom_xdndactionlink, "XdndActionLink");
E_ATOM(atom_xdndactionask, "XdndActionAsk");
E_ATOM(atom_text_uri_list, "text/uri-list");
E_ATOM(atom_text_plain, "text/plain");
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] = 0;
XSendEvent(disp, win, False, 0, &xevent);
}
/* 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);
}
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;
}
int
e_dnd_selection_convert(Window win, Window req, Atom type)
{
static Atom atom_xdndselection = 0;
static Atom atom_jxselectionwindowproperty = 0;
E_ATOM(atom_xdndselection, "XdndSelection");
E_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty");
if (win == XGetSelectionOwner(disp, atom_xdndselection))
{
XConvertSelection(disp, atom_xdndselection, type,
atom_jxselectionwindowproperty, req, CurrentTime);
return 1;
}
return 0;
}
void *
e_dnd_selection_get(Window win, Window req, Atom type, int *size)
{
unsigned char *data = NULL;
long bytes_read;
unsigned long remaining = 1;
*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
e_dnd_set_data(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;
static Atom atom_xdndselection = 0;
E_ATOM(atom_xdndactioncopy, "XdndActionCopy");
E_ATOM(atom_xdndactionmove, "XdndActionMove");
E_ATOM(atom_xdndactionlink, "XdndActionLink");
E_ATOM(atom_xdndactionask, "XdndActionAsk");
E_ATOM(atom_xdndactionlist, "XdndActionList");
E_ATOM(atom_xdndselection, "XdndSelection");
if (dnd_copy)
e_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
&atom_xdndactioncopy, 1);
else if (dnd_link)
e_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
&atom_xdndactionlink, 1);
else if (dnd_move)
e_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
&atom_xdndactionmove, 1);
else
e_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32,
&atom_xdndactionask, 1);
XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime);
}
void
e_dnd_send_data(Window win, Window source_win, void *data, int size,
Atom dest_atom, int plain_text)
{
XEvent xevent;
static Atom atom_text_plain = 0;
static Atom atom_text_uri_list = 0;
static Atom atom_xdndselection = 0;
Atom target;
E_ATOM(atom_xdndselection, "XdndSelection");
E_ATOM(atom_text_uri_list, "text/uri-list");
E_ATOM(atom_text_plain, "text/plain");
target = atom_text_uri_list;
if (plain_text)
target = atom_text_plain;
e_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
e_dnd_set_mode_copy(void)
{
dnd_copy = 1;
dnd_link = 0;
dnd_move = 0;
}
void
e_dnd_set_mode_link(void)
{
dnd_copy = 0;
dnd_link = 1;
dnd_move = 0;
}
void
e_dnd_set_mode_move(void)
{
dnd_copy = 0;
dnd_link = 0;
dnd_move = 1;
}
void
e_dnd_set_mode_ask(void)
{
dnd_copy = 0;
dnd_link = 0;
dnd_move = 0;
}
void
e_dnd_own_selection(Window win)
{
static Atom atom_xdndselection = 0;
static Atom atom_jxselectionwindowproperty = 0;
E_ATOM(atom_xdndselection, "XdndSelection");
E_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty");
if (!XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime))
return;
}
void
e_dnd_send_drop(Window win, Window source_win)
{
static Atom atom_xdnddrop = 0;
XEvent xevent;
E_ATOM(atom_xdnddrop, "XdndDrop");
e_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
e_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;
E_ATOM(atom_xdndstatus, "XdndStatus");
E_ATOM(atom_xdndactioncopy, "XdndActionCopy");
E_ATOM(atom_xdndactionmove, "XdndActionMove");
E_ATOM(atom_xdndactionlink, "XdndActionLink");
E_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
e_window_dnd_send_finished(Window source_win, Window win)
{
static Atom atom_xdndfinished = 0;
XEvent xevent;
E_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
e_window_dnd_ok(int ok)
{
current_dnd_target_ok = ok;
}
void
e_window_dnd_finished(void)
{
current_dnd_win = 0;
}
void
e_window_set_title(Window win, char *title)
{
XStoreName(disp, win, title);
}
void
e_window_set_name_class(Window win, char *name, char *class)
{
XClassHint hint;
hint.res_name = name;
hint.res_class = class;
XSetClassHint(disp, win, &hint);
}
void
e_window_set_min_size(Window win, int w, int h)
{
XSizeHints hints;
long ret;
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
e_window_set_max_size(Window win, int w, int h)
{
XSizeHints hints;
long ret;
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
e_window_set_xy_hints(Window win, int x, int y)
{
XSizeHints hints;
long ret;
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
e_window_get_frame_size(Window win, int *l, int *r, int *t, int *b)
{
static Atom atom_e_frame_size = 0;
int *data, size;
E_ATOM(atom_e_frame_size, "_E_FRAME_SIZE");
data = e_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
e_window_save_under(Window win)
{
XSetWindowAttributes att;
XWindowAttributes gatt;
att.save_under = True;
XChangeWindowAttributes(disp, win, CWSaveUnder, &att);
XGetWindowAttributes(disp, win, &gatt);
if (gatt.save_under == True)
return 1;
return 0;
}
GC
e_gc_new(Drawable d)
{
XGCValues gcv;
if (d == 0)
d = default_root;
return XCreateGC(disp, d, 0, &gcv);
}
void
e_gc_free(GC gc)
{
XFreeGC(disp, gc);
}
void
e_gc_set_fg(GC gc, int val)
{
XSetForeground(disp, gc, val);
}
void
e_fill_rectangle(Drawable d, GC gc, int x, int y, int w, int h)
{
XFillRectangle(disp, d, gc, x, y, w, h);
}
void
e_draw_rectangle(Drawable d, GC gc, int x, int y, int w, int h)
{
XDrawRectangle(disp, d, gc, x, y, w - 1, h - 1);
}
void
e_draw_line(Drawable d, GC gc, int x1, int y1, int x2, int y2)
{
XDrawLine(disp, d, gc, x1, y1, x2, y2);
}
void
e_window_hint_set_layer(Window win, int layer)
{
static Atom atom_win_layer = 0;
E_ATOM(atom_win_layer, "_WIN_LAYER");
e_window_property_set(win, atom_win_layer, XA_CARDINAL, 32, &layer, 1);
}
void
e_window_hint_set_sticky(Window win, int sticky)
{
static Atom atom_win_state = 0;
static Atom atom_win_hints = 0;
int data;
E_ATOM(atom_win_state, "_WIN_STATE");
E_ATOM(atom_win_hints, "_WIN_HINTS");
if (sticky)
{
data = ((1 << 0) | (1 << 8) | (1 << 9));
e_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1);
data = ((1 << 0) | (1 << 1) | (1 << 2));
e_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1);
}
else
{
data = 0;
e_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1);
e_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1);
}
}
void
e_window_hint_set_borderless(Window win)
{
static Atom atom_motif_wm_hints = 0;
int data[5];
E_ATOM(atom_motif_wm_hints, "_MOTIF_WM_HINTS");
data[0] = 0x3;
data[1] = 0x0;
data[2] = 0x0;
data[3] = 0x2ada27b0;
data[4] = 0x2aabd6b0;
e_window_property_set(win, atom_motif_wm_hints, atom_motif_wm_hints, 32,
data, 5);
}
void
e_grab_mouse(Window win, int confine, Cursor cursor)
{
int ret;
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
e_ungrab_mouse(void)
{
XUngrabPointer(disp, CurrentTime);
grab_pointer_win = 0;
}
Window
e_grab_window_get(void)
{
return grab_pointer_win;
}
void
e_window_gravity_reset(Window win)
{
XSetWindowAttributes att;
att.win_gravity = NorthWestGravity;
XChangeWindowAttributes(disp, win, CWWinGravity, &att);
}
void
e_pointer_warp_by(int dx, int dy)
{
XWarpPointer(disp, None, None, 0, 0, 0, 0, dx, dy);
}
void
e_pointer_warp_to(int x, int y)
{
XWarpPointer(disp, None, default_root, 0, 0, 0, 0, x, y);
}
void
e_gc_set_include_inferiors(GC gc)
{
XGCValues gcv;
gcv.subwindow_mode = IncludeInferiors;
XChangeGC(disp, gc, GCSubwindowMode, &gcv);
}
void
e_area_copy(Drawable src, Drawable dest, GC gc,
int sx, int sy, int sw, int sh, int dx, int dy)
{
if (src == 0)
src = default_root;
if (dest == 0)
dest = default_root;
XCopyArea(disp, src, dest, gc, sx, sy, sw, sh, dx, dy);
}
Window e_window_root(void)
{
return default_root;
}
void
e_window_get_virtual_area(Window win, int *area_x, int *area_y)
{
static Atom atom_win_area = 0;
int *data, size;
E_ATOM(atom_win_area, "_WIN_AREA");
data = e_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
e_get_virtual_area(int *area_x, int *area_y)
{
static Atom atom_win_area = 0;
int *data, size;
E_ATOM(atom_win_area, "_WIN_AREA");
data =
e_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);
}
}