efl/legacy/ecore/src/e_ev_x.c

1030 lines
30 KiB
C

#include "e_events.h"
#include "e_ev_x.h"
#include "e_str.h"
#include "e_mem.h"
#include "e_util.h"
/* private funtion prototypes */
static void e_ev_x_handle_events(int fd);
static void e_ev_x_translate_events(XEvent * events, int num_events);
static void e_ev_key_down_free(void *event);
static void e_ev_key_up_free(void *event);
static void e_ev_generic_free(void *event);
static void e_ev_dnd_drop_request_free(void *event);
static void e_ev_x_handle_key_press(XEvent * xevent);
static void e_ev_x_handle_key_release(XEvent * xevent);
static void e_ev_x_handle_button_press(XEvent * xevent);
static void e_ev_x_handle_button_release(XEvent * xevent);
static void e_ev_x_handle_motion_notify(XEvent * xevent);
static void e_ev_x_handle_enter_notify(XEvent * xevent);
static void e_ev_x_handle_leave_notify(XEvent * xevent);
static void e_ev_x_handle_focus_in(XEvent * xevent);
static void e_ev_x_handle_focus_out(XEvent * xevent);
static void e_ev_x_handle_expose(XEvent * xevent);
static void e_ev_x_handle_visibility_notify(XEvent * xevent);
static void e_ev_x_handle_create_notify(XEvent * xevent);
static void e_ev_x_handle_destroy_notify(XEvent * xevent);
static void e_ev_x_handle_unmap_notify(XEvent * xevent);
static void e_ev_x_handle_map_notify(XEvent * xevent);
static void e_ev_x_handle_map_request(XEvent * xevent);
static void e_ev_x_handle_reparent_notify(XEvent * xevent);
static void e_ev_x_handle_configure_notify(XEvent * xevent);
static void e_ev_x_handle_configure_request(XEvent * xevent);
static void e_ev_x_handle_circulate_notify(XEvent * xevent);
static void e_ev_x_handle_circulate_request(XEvent * xevent);
static void e_ev_x_handle_property_notify(XEvent * xevent);
static void e_ev_x_handle_colormap_notify(XEvent * xevent);
static void e_ev_x_handle_selection_notify(XEvent * xevent);
static void e_ev_x_handle_selection_request(XEvent * xevent);
static void e_ev_x_handle_client_message(XEvent * xevent);
static void e_ev_x_handle_shape_change(XEvent * xevent);
static int max_event_id = 0;
static void (**event_translator) (XEvent * event) = NULL;
static int lock_mask_scroll = 0, lock_mask_num = 0, lock_mask_caps = 0;
static int mod_mask_shift = 0, mod_mask_ctrl = 0, mod_mask_alt =
0, mod_mask_win = 0;
/* convenience macros */
#define GETSET_MODS(state, mods) \
(mods) = EV_KEY_MODIFIER_NONE;\
if ((state) & mod_mask_shift) { e_mod_shift_set(1); (mods) |= EV_KEY_MODIFIER_SHIFT; }\
else e_mod_shift_set(0);\
if ((state) & mod_mask_ctrl) { e_mod_ctrl_set(1); (mods) |= EV_KEY_MODIFIER_CTRL; }\
else e_mod_ctrl_set(0);\
if ((state) & mod_mask_alt) { e_mod_alt_set(1); (mods) |= EV_KEY_MODIFIER_ALT; }\
else e_mod_alt_set(0);\
if ((state) & mod_mask_win) { e_mod_win_set(1); (mods) |= EV_KEY_MODIFIER_WIN; }\
else e_mod_win_set(0);
/* public functions */
/* initialise event handling for the fd X is on */
void
e_ev_x_init(void)
{
int i, shape_event_id, current_lock;
shape_event_id = max_event_id = e_event_shape_get_id();
event_translator = NEW_PTR(max_event_id + 1);
for (i = 0; i < max_event_id + 1; i++)
event_translator[i] = NULL;
event_translator[KeyPress] = e_ev_x_handle_key_press;
event_translator[KeyRelease] = e_ev_x_handle_key_release;
event_translator[ButtonPress] = e_ev_x_handle_button_press;
event_translator[ButtonRelease] = e_ev_x_handle_button_release;
event_translator[MotionNotify] = e_ev_x_handle_motion_notify;
event_translator[EnterNotify] = e_ev_x_handle_enter_notify;
event_translator[LeaveNotify] = e_ev_x_handle_leave_notify;
event_translator[FocusIn] = e_ev_x_handle_focus_in;
event_translator[FocusOut] = e_ev_x_handle_focus_out;
event_translator[Expose] = e_ev_x_handle_expose;
event_translator[VisibilityNotify] = e_ev_x_handle_visibility_notify;
event_translator[CreateNotify] = e_ev_x_handle_create_notify;
event_translator[DestroyNotify] = e_ev_x_handle_destroy_notify;
event_translator[UnmapNotify] = e_ev_x_handle_unmap_notify;
event_translator[MapNotify] = e_ev_x_handle_map_notify;
event_translator[MapRequest] = e_ev_x_handle_map_request;
event_translator[ReparentNotify] = e_ev_x_handle_reparent_notify;
event_translator[ConfigureNotify] = e_ev_x_handle_configure_notify;
event_translator[ConfigureRequest] = e_ev_x_handle_configure_request;
event_translator[CirculateNotify] = e_ev_x_handle_circulate_notify;
event_translator[CirculateRequest] = e_ev_x_handle_circulate_request;
event_translator[PropertyNotify] = e_ev_x_handle_property_notify;
event_translator[ColormapNotify] = e_ev_x_handle_colormap_notify;
event_translator[ClientMessage] = e_ev_x_handle_client_message;
event_translator[SelectionNotify] = e_ev_x_handle_selection_notify;
event_translator[SelectionRequest] = e_ev_x_handle_selection_request;
event_translator[shape_event_id] = e_ev_x_handle_shape_change;
lock_mask_scroll = e_lock_mask_num_get();
lock_mask_num = e_lock_mask_num_get();
lock_mask_caps = e_lock_mask_scroll_get();
mod_mask_shift = e_mod_mask_shift_get();
mod_mask_ctrl = e_mod_mask_ctrl_get();
mod_mask_alt = e_mod_mask_alt_get();
mod_mask_win = e_mod_mask_win_get();
e_key_grab("Num_Lock", EV_KEY_MODIFIER_NONE, 1, 1);
e_key_grab("Scroll_Lock", EV_KEY_MODIFIER_NONE, 1, 1);
e_key_grab("Caps_Lock", EV_KEY_MODIFIER_NONE, 1, 1);
current_lock = e_modifier_mask_get();
if (current_lock & lock_mask_scroll)
e_lock_scroll_set(1);
if (current_lock & lock_mask_num)
e_lock_num_set(1);
if (current_lock & lock_mask_caps)
e_lock_caps_set(1);
if (current_lock & mod_mask_shift)
e_mod_shift_set(1);
if (current_lock & mod_mask_ctrl)
e_mod_ctrl_set(1);
if (current_lock & mod_mask_alt)
e_mod_alt_set(1);
if (current_lock & mod_mask_win)
e_mod_win_set(1);
e_add_event_fd(e_x_get_fd(), e_ev_x_handle_events);
}
/* private functions */
/* get all events onthe event queue and translate them */
static void
e_ev_x_handle_events(int fd)
{
int num_events = 0, size_events = 0;
XEvent *events = NULL;
/* while there are events in the queue */
while (e_events_pending())
{
/* incriment our event count */
num_events++;
/* if the numebr fo events is > than our buffer size then */
if (num_events > size_events)
{
/* increase the buffer size by 64 events */
size_events += 64;
if (events)
{
REALLOC(events, XEvent, size_events)}
else
events = NEW(XEvent, size_events);
}
/* get the next event into the event buffer */
e_get_next_event(&(events[num_events - 1]));
}
/* call the XEvent -> Eevent translator */
if (events)
{
e_ev_x_translate_events(events, num_events);
/* if theres an event buffer - free it */
FREE(events);
}
return;
fd = 0;
}
/* take an array of events and translate them into E events */
static void
e_ev_x_translate_events(XEvent * events, int num_events)
{
int i;
for (i = 0; i < num_events; i++)
{
if ((events[i].type < max_event_id) &&
(event_translator[events[i].type]))
(*(event_translator[events[i].type])) (&(events[i]));
}
}
static void
e_ev_key_down_free(void *event)
{
Ev_Key_Down *e;
e = (Ev_Key_Down *) event;
IF_FREE(e->key);
IF_FREE(e->compose);
FREE(e);
}
static void
e_ev_key_up_free(void *event)
{
Ev_Key_Up *e;
e = (Ev_Key_Up *) event;
IF_FREE(e->key);
IF_FREE(e->compose);
FREE(e);
}
static void
e_ev_generic_free(void *event)
{
FREE(event);
}
static void
e_ev_dnd_drop_request_free(void *event)
{
Ev_Dnd_Drop_Request *e;
e = (Ev_Dnd_Drop_Request *) event;
if (e->files)
e_string_free_list(e->files, e->num_files);
FREE(event);
}
static void
e_ev_x_handle_key_press(XEvent * xevent)
{
Ev_Key_Down *e;
static KeyCode previous_code = 0;
static Time previous_time = 0;
/* avoid doubling events up from passive grabs */
if ((xevent->xkey.keycode == previous_code) &&
xevent->xkey.time == previous_time)
return;
previous_code = xevent->xkey.keycode;
previous_time = xevent->xkey.time;
if (e_key_get_keysym_from_keycode(xevent->xkey.keycode) == XK_Scroll_Lock)
{
if (e_lock_scroll_get())
e_lock_scroll_set(0);
else
e_lock_scroll_set(1);
e_event_allow(ReplayKeyboard, xevent->xkey.time);
e_flush();
}
else if (e_key_get_keysym_from_keycode(xevent->xkey.keycode) == XK_Num_Lock)
{
if (e_lock_num_get())
e_lock_num_set(0);
else
e_lock_num_set(1);
e_event_allow(ReplayKeyboard, xevent->xkey.time);
e_flush();
}
else if (e_key_get_keysym_from_keycode(xevent->xkey.keycode) == XK_Caps_Lock)
{
if (e_lock_caps_get())
e_lock_caps_set(0);
else
e_lock_caps_set(1);
e_event_allow(ReplayKeyboard, xevent->xkey.time);
e_flush();
}
e = NEW(Ev_Key_Down, 1);
e->win = xevent->xkey.window;
e->root = xevent->xkey.root;
GETSET_MODS(xevent->xkey.state, e->mods);
e->time = xevent->xkey.time;
e->key = e_key_get_string_from_keycode(xevent->xkey.keycode);
{
int val;
char buf[256];
KeySym sym;
XComposeStatus stat;
val = XLookupString((XKeyEvent *) xevent, buf, sizeof(buf), &sym, &stat);
if (val > 0)
{
buf[val] = 0;
e->compose = e_string_dup(buf);
}
else
e->compose = NULL;
}
e_add_event(EV_KEY_DOWN, e, e_ev_key_down_free);
}
static void
e_ev_x_handle_key_release(XEvent * xevent)
{
Ev_Key_Up *e;
static KeyCode previous_code = 0;
static Time previous_time = 0;
/* avoid doubling events up from passive grabs */
if ((xevent->xkey.keycode == previous_code) &&
xevent->xkey.time == previous_time)
return;
previous_code = xevent->xkey.keycode;
previous_time = xevent->xkey.time;
e = NEW(Ev_Key_Up, 1);
e->win = xevent->xkey.window;
e->root = xevent->xkey.root;
GETSET_MODS(xevent->xkey.state, e->mods);
e->time = xevent->xkey.time;
e->key = e_key_get_string_from_keycode(xevent->xkey.keycode);
{
int val;
char buf[256];
KeySym sym;
XComposeStatus stat;
val = XLookupString((XKeyEvent *) xevent, buf, sizeof(buf), &sym, &stat);
if (val > 0)
{
buf[val] = 0;
e->compose = e_string_dup(buf);
}
else
e->compose = NULL;
}
e_add_event(EV_KEY_UP, e, e_ev_key_up_free);
}
static void
e_ev_x_handle_button_press(XEvent * xevent)
{
static Time last_time = 0, last_last_time = 0;
static int last_button = 0, last_last_button = 0;
static Window last_window = 0, last_last_window = 0;
e_pointer_xy_set(xevent->xbutton.x_root, xevent->xbutton.y_root);
if ((xevent->xbutton.button == 4) || (xevent->xbutton.button == 5))
{
Ev_Wheel *e;
e = NEW(Ev_Wheel, 1);
e->win = xevent->xbutton.window;
e->root = xevent->xbutton.root;
e->x = xevent->xbutton.x;
e->y = xevent->xbutton.y;
e->rx = xevent->xbutton.x_root;
e->ry = xevent->xbutton.y_root;
e->time = xevent->xbutton.time;
if (xevent->xbutton.button == 5)
e->z = 1;
else
e->z = -1;
if (xevent->xbutton.time - last_time < 15)
e->z *= 16;
else if (xevent->xbutton.time - last_time < 30)
e->z *= 4;
GETSET_MODS(xevent->xbutton.state, e->mods);
e_add_event(EV_MOUSE_WHEEL, e, e_ev_generic_free);
}
else
{
Ev_Mouse_Down *e;
e = NEW(Ev_Mouse_Down, 1);
e->win = xevent->xbutton.window;
e->root = xevent->xbutton.root;
e->button = xevent->xbutton.button;
e->x = xevent->xbutton.x;
e->y = xevent->xbutton.y;
e->rx = xevent->xbutton.x_root;
e->ry = xevent->xbutton.y_root;
e->time = xevent->xbutton.time;
e->double_click = 0;
e->triple_click = 0;
GETSET_MODS(xevent->xbutton.state, e->mods);
if (xevent->xbutton.time - last_last_time < 500)
{
if ((xevent->xbutton.window == (unsigned int)last_window) &&
(last_window == last_last_window) &&
(xevent->xbutton.button == (unsigned int)last_button) &&
(last_button == last_button))
e->triple_click = 1;
}
else if (xevent->xbutton.time - last_time < 250)
{
if ((xevent->xbutton.window == (unsigned int)last_window) &&
(xevent->xbutton.button == (unsigned int)last_button))
e->double_click = 1;
}
e_add_event(EV_MOUSE_DOWN, e, e_ev_generic_free);
}
last_last_window = last_window;
last_window = xevent->xbutton.window;
last_last_button = last_button;
last_button = xevent->xbutton.button;
last_last_time = last_time;
last_time = xevent->xbutton.time;
}
static void
e_ev_x_handle_button_release(XEvent * xevent)
{
Ev_Mouse_Up *e;
if (xevent->xbutton.button > 3)
return;
e = NEW(Ev_Mouse_Up, 1);
e->win = xevent->xbutton.window;
e->root = xevent->xbutton.root;
e->button = xevent->xbutton.button;
e->x = xevent->xbutton.x;
e->y = xevent->xbutton.y;
e->rx = xevent->xbutton.x_root;
e->ry = xevent->xbutton.y_root;
e->time = xevent->xbutton.time;
GETSET_MODS(xevent->xbutton.state, e->mods);
e_add_event(EV_MOUSE_UP, e, e_ev_generic_free);
}
static void
e_ev_x_handle_motion_notify(XEvent * xevent)
{
Ev_Mouse_Move *e;
e_pointer_xy_set(xevent->xmotion.x_root, xevent->xmotion.y_root);
e = NEW(Ev_Mouse_Move, 1);
e->win = xevent->xmotion.window;
e->root = xevent->xmotion.root;
e->x = xevent->xmotion.x;
e->y = xevent->xmotion.y;
e->rx = xevent->xmotion.x_root;
e->ry = xevent->xmotion.y_root;
e->time = xevent->xmotion.time;
GETSET_MODS(xevent->xmotion.state, e->mods);
e_add_event(EV_MOUSE_MOVE, e, e_ev_generic_free);
}
static void
e_ev_x_handle_enter_notify(XEvent * xevent)
{
Ev_Window_Enter *e;
e_pointer_xy_set(xevent->xcrossing.x_root, xevent->xcrossing.y_root);
e = NEW(Ev_Window_Enter, 1);
e->win = xevent->xcrossing.window;
e->root = xevent->xcrossing.root;
e->x = xevent->xcrossing.x;
e->y = xevent->xcrossing.y;
e->rx = xevent->xcrossing.x_root;
e->ry = xevent->xcrossing.y_root;
e->time = xevent->xcrossing.time;
GETSET_MODS(xevent->xcrossing.state, e->mods);
e_add_event(EV_MOUSE_IN, e, e_ev_generic_free);
e_window_mouse_set_in(e->win, 1);
}
static void
e_ev_x_handle_leave_notify(XEvent * xevent)
{
Ev_Window_Leave *e;
e_pointer_xy_set(xevent->xcrossing.x_root, xevent->xcrossing.y_root);
e = NEW(Ev_Window_Leave, 1);
e->win = xevent->xcrossing.window;
e->root = xevent->xcrossing.root;
e->x = xevent->xcrossing.x;
e->y = xevent->xcrossing.y;
e->rx = xevent->xcrossing.x_root;
e->ry = xevent->xcrossing.y_root;
e->time = xevent->xcrossing.time;
GETSET_MODS(xevent->xcrossing.state, e->mods);
e_add_event(EV_MOUSE_OUT, e, e_ev_generic_free);
e_window_mouse_set_in(e->win, 0);
}
static void
e_ev_x_handle_focus_in(XEvent * xevent)
{
Ev_Window_Focus_In *e;
e = NEW(Ev_Window_Focus_In, 1);
e->win = xevent->xfocus.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_FOCUS_IN, e, e_ev_generic_free);
e_focus_window_set(e->win);
}
static void
e_ev_x_handle_focus_out(XEvent * xevent)
{
Ev_Window_Focus_Out *e;
e = NEW(Ev_Window_Focus_Out, 1);
e->win = xevent->xfocus.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_FOCUS_OUT, e, e_ev_generic_free);
e_focus_window_set(0);
}
static void
e_ev_x_handle_expose(XEvent * xevent)
{
Ev_Window_Expose *e;
e = NEW(Ev_Window_Expose, 1);
e->win = xevent->xexpose.window;
e->root = e_window_get_root(e->win);
e->x = xevent->xexpose.x;
e->y = xevent->xexpose.y;
e->w = xevent->xexpose.width;
e->h = xevent->xexpose.height;
e_add_event(EV_WINDOW_EXPOSE, e, e_ev_generic_free);
}
static void
e_ev_x_handle_visibility_notify(XEvent * xevent)
{
if (xevent->xvisibility.state != VisibilityPartiallyObscured)
{
Ev_Window_Visibility *e;
e = NEW(Ev_Window_Visibility, 1);
e->win = xevent->xvisibility.window;
e->root = e_window_get_root(e->win);
if (xevent->xvisibility.state == VisibilityFullyObscured)
e->fully_obscured = 1;
else
e->fully_obscured = 0;
e_add_event(EV_WINDOW_VISIBILITY, e, e_ev_generic_free);
}
}
static void
e_ev_x_handle_create_notify(XEvent * xevent)
{
Ev_Window_Create *e;
e = NEW(Ev_Window_Create, 1);
e->win = xevent->xcreatewindow.window;
e_validate_xid(e->win);
e->root = e_window_get_root(e->win);
if (xevent->xcreatewindow.override_redirect)
e->override = 1;
else
e->override = 0;
e_add_event(EV_WINDOW_CREATE, e, e_ev_generic_free);
}
static void
e_ev_x_handle_destroy_notify(XEvent * xevent)
{
Ev_Window_Destroy *e;
e = NEW(Ev_Window_Destroy, 1);
e->win = xevent->xdestroywindow.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_DESTROY, e, e_ev_generic_free);
e_unvalidate_xid(e->win);
}
static void
e_ev_x_handle_unmap_notify(XEvent * xevent)
{
Ev_Window_Unmap *e;
E_XID *xid = NULL;
e = NEW(Ev_Window_Unmap, 1);
e->win = xevent->xunmap.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_UNMAP, e, e_ev_generic_free);
xid = e_validate_xid(e->win);
if (xid)
xid->mapped = 0;
}
static void
e_ev_x_handle_map_notify(XEvent * xevent)
{
Ev_Window_Map *e;
E_XID *xid = NULL;
e = NEW(Ev_Window_Map, 1);
e->win = xevent->xmap.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_MAP, e, e_ev_generic_free);
xid = e_validate_xid(e->win);
if (xid)
xid->mapped = 1;
}
static void
e_ev_x_handle_map_request(XEvent * xevent)
{
Ev_Window_Map_Request *e;
e = NEW(Ev_Window_Map_Request, 1);
e->win = xevent->xmaprequest.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_MAP_REQUEST, e, e_ev_generic_free);
e_validate_xid(e->win);
}
static void
e_ev_x_handle_reparent_notify(XEvent * xevent)
{
Ev_Window_Reparent *e;
Window parent;
E_XID *xid = NULL;
e = NEW(Ev_Window_Reparent, 1);
e->win = xevent->xreparent.window;
xid = e_validate_xid(e->win);
e->root = e_window_get_root(e->win);
parent = e_window_get_parent(e->win);
e->parent_from = parent;
e->parent = xevent->xreparent.parent;
e_validate_xid(e->parent);
e_del_child(parent, e->win);
e_add_child(xevent->xreparent.parent, xevent->xreparent.window);
if (xid)
xid->parent = e->parent;
e_add_event(EV_WINDOW_REPARENT, e, e_ev_generic_free);
}
static void
e_ev_x_handle_configure_notify(XEvent * xevent)
{
Ev_Window_Configure *e;
E_XID *xid;
e = NEW(Ev_Window_Configure, 1);
e->win = xevent->xconfigure.window;
e->root = e_window_get_root(e->win);
e->x = xevent->xconfigure.x;
e->y = xevent->xconfigure.y;
e->w = xevent->xconfigure.width;
e->h = xevent->xconfigure.height;
if (!xevent->xconfigure.send_event)
{
xid = e_validate_xid(e->win);
if (xid)
{
xid->x = e->x;
xid->y = e->y;
xid->w = e->w;
xid->h = e->h;
}
e->wm_generated = 0;
/* FIXME: dont handle redioing stack for xevent->xconfigure.above */
/* member (the window is stacked immediately in stack above this) */
}
else
e->wm_generated = 1;
e_add_event(EV_WINDOW_CONFIGURE, e, e_ev_generic_free);
}
static void
e_ev_x_handle_configure_request(XEvent * xevent)
{
Ev_Window_Configure_Request *e;
e = NEW(Ev_Window_Configure_Request, 1);
e->win = xevent->xconfigurerequest.window;
e->root = e_window_get_root(e->win);
e->x = xevent->xconfigurerequest.x;
e->y = xevent->xconfigurerequest.y;
e->w = xevent->xconfigurerequest.width;
e->h = xevent->xconfigurerequest.height;
e->stack_win = xevent->xconfigurerequest.above;
e->detail = xevent->xconfigurerequest.detail;
e->mask = xevent->xconfigurerequest.value_mask;
e_add_event(EV_WINDOW_CONFIGURE_REQUEST, e, e_ev_generic_free);
}
static void
e_ev_x_handle_circulate_notify(XEvent * xevent)
{
Ev_Window_Circulate *e;
e = NEW(Ev_Window_Circulate, 1);
e->win = xevent->xcirculate.window;
e->root = e_window_get_root(e->win);
if (xevent->xcirculate.place == PlaceOnBottom)
e->lower = 1;
else
e->lower = 0;
e_add_event(EV_WINDOW_CIRCULATE, e, e_ev_generic_free);
}
static void
e_ev_x_handle_circulate_request(XEvent * xevent)
{
Ev_Window_Circulate_Request *e;
e = NEW(Ev_Window_Circulate_Request, 1);
e->win = xevent->xcirculaterequest.window;
e->root = e_window_get_root(e->win);
if (xevent->xcirculaterequest.place == PlaceOnBottom)
e->lower = 1;
else
e->lower = 0;
e_add_event(EV_WINDOW_CIRCULATE_REQUEST, e, e_ev_generic_free);
}
static void
e_ev_x_handle_property_notify(XEvent * xevent)
{
Ev_Window_Property *e;
e = NEW(Ev_Window_Property, 1);
e->win = xevent->xproperty.window;
e->root = e_window_get_root(e->win);
e->atom = xevent->xproperty.atom;
e->time = xevent->xproperty.time;
e_add_event(EV_WINDOW_PROPERTY, e, e_ev_generic_free);
}
static void
e_ev_x_handle_colormap_notify(XEvent * xevent)
{
Ev_Colormap *e;
e = NEW(Ev_Colormap, 1);
e->win = xevent->xcolormap.window;
e->root = e_window_get_root(e->win);
e->cmap = xevent->xcolormap.colormap;
if (xevent->xcolormap.state == ColormapInstalled)
e->installed = 1;
else
e->installed = 0;
e_add_event(EV_COLORMAP, e, e_ev_generic_free);
}
Ev_Dnd_Drop_Request *ev_drop_request_pending = NULL;
static void
e_ev_x_handle_selection_notify(XEvent * xevent)
{
Ev_Dnd_Drop_Request *e;
char *data;
int size;
static Atom atom_xdndactioncopy = 0;
static Atom atom_xdndactionmove = 0;
static Atom atom_xdndactionlink = 0;
static Atom atom_xdndactionask = 0;
static Atom atom_xdndactionlist = 0;
e = ev_drop_request_pending;
if (!e)
return;
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");
data = e_dnd_selection_get(xevent->xany.window, e->source_win,
xevent->xselection.property, &size);
if (data)
{
char *s, *buf;
int i, is;
Atom *method = NULL;
method = e_window_property_get(e->source_win,
atom_xdndactionlist, XA_ATOM, &is);
if (method)
{
e->copy = 0;
e->link = 0;
e->move = 0;
if (*method == atom_xdndactioncopy)
e->copy = 1;
else if (*method == atom_xdndactionmove)
e->move = 1;
else if (*method == atom_xdndactionlink)
e->link = 1;
FREE(method);
}
else
{
e->copy = 0;
e->link = 0;
e->move = 0;
}
s = data;
buf = NEW(char, size);
i = 0;
is = 0;
e->files = NULL;
while ((s[is]) && (is < size))
{
if ((i == 0) && (s[is] == '#'))
{
for (; ((s[is] != 0) && (s[is] != '\n')); is++);
}
else
{
if (s[is] != '\r')
{
buf[i++] = s[is];
}
else
{
buf[i] = 0;
e->num_files++;
if (e->files)
{
REALLOC_PTR(e->files, e->num_files);
}
else
e->files = NEW_PTR(e->num_files);
e->files[e->num_files - 1] = e_string_dup(buf);
buf[0] = 0;
i = 0;
is++;
}
is++;
}
}
FREE(buf);
FREE(data);
}
e_add_event(EV_DND_DROP_REQUEST, e, e_ev_dnd_drop_request_free);
ev_drop_request_pending = NULL;
}
static void
e_ev_x_handle_selection_request(XEvent * xevent)
{
static Atom atom_xdndselection = 0;
static Atom atom_text_plain = 0;
Ev_Dnd_Data_Request *e;
E_ATOM(atom_xdndselection, "XdndSelection");
E_ATOM(atom_text_plain, "text/plain");
if (xevent->xselectionrequest.selection == atom_xdndselection)
{
e = NEW(Ev_Dnd_Data_Request, 1);
e->win = xevent->xselectionrequest.owner;
e->root = e_window_get_root(e->win);
e->source_win = xevent->xselectionrequest.requestor;
if (xevent->xselectionrequest.target == atom_text_plain)
e->plain_text = 1;
else
e->plain_text = 0;
e->destination_atom = xevent->xselectionrequest.property;
e_add_event(EV_DND_DATA_REQUEST, e, e_ev_generic_free);
}
}
static void
e_ev_x_handle_client_message(XEvent * xevent)
{
static Atom atom_wm_delete_window = 0;
static Atom atom_wm_protocols = 0;
static Atom atom_xdndstatus = 0;
static Atom atom_xdndenter = 0;
static Atom atom_xdndleave = 0;
static Atom atom_xdndfinished = 0;
static Atom atom_xdndposition = 0;
static Atom atom_xdnddrop = 0;
static Atom atom_text_uri_list = 0;
static Atom atom_xdndactioncopy = 0;
static Atom atom_xdndactionlink = 0;
static Atom atom_xdndactionmove = 0;
/* setup some known atoms to translate this message into a sensible event */
E_ATOM(atom_wm_delete_window, "WM_DELETE_WINDOW");
E_ATOM(atom_wm_protocols, "WM_PROTOCOLS");
E_ATOM(atom_xdndstatus, "XdndStatus");
E_ATOM(atom_xdndfinished, "XdndFinished");
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_xdndactionlink, "XdndActionLink");
E_ATOM(atom_xdndactionmove, "XdndActionMove");
E_ATOM(atom_text_uri_list, "text/uri-list");
/* forst type = delete event sent to client */
if ((xevent->xclient.message_type == atom_wm_protocols) &&
(xevent->xclient.format == 32) &&
(xevent->xclient.data.l[0] == (long)atom_wm_delete_window))
{
Ev_Window_Delete *e;
e = NEW(Ev_Window_Delete, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e_add_event(EV_WINDOW_DELETE, e, e_ev_generic_free);
}
else if ((xevent->xclient.message_type == atom_xdndenter) &&
(xevent->xclient.format == 32))
{
if (xevent->xclient.data.l[2] == (long)atom_text_uri_list)
{
Ev_Dnd_Drop_Request *e;
if (ev_drop_request_pending)
{
e_ev_dnd_drop_request_free(ev_drop_request_pending);
ev_drop_request_pending = NULL;
}
e = NEW(Ev_Dnd_Drop_Request, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e->source_win = (Window) xevent->xclient.data.l[0];
if (!e_dnd_selection_convert
(e->source_win, e->win, atom_text_uri_list))
{
FREE(e);
return;
}
e->files = NULL;
e->num_files = 0;
ev_drop_request_pending = e;
}
}
else if ((xevent->xclient.message_type == atom_xdndleave) &&
(xevent->xclient.format == 32))
{
Ev_Dnd_Drop_End *e;
e = NEW(Ev_Dnd_Drop_End, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e->source_win = (Window) xevent->xclient.data.l[0];
e_add_event(EV_DND_DROP_END, e, e_ev_generic_free);
}
else if ((xevent->xclient.message_type == atom_xdndposition) &&
(xevent->xclient.format == 32))
{
Ev_Dnd_Drop_Position *e;
e = NEW(Ev_Dnd_Drop_Position, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e->source_win = (Window) xevent->xclient.data.l[0];
e->x = (xevent->xclient.data.l[2] >> 16) & 0xffff;
e->y = xevent->xclient.data.l[2] & 0xffff;
e_add_event(EV_DND_DROP_POSITION, e, e_ev_generic_free);
}
else if ((xevent->xclient.message_type == atom_xdndstatus) &&
(xevent->xclient.format == 32))
{
Ev_Dnd_Drop_Status *e;
e = NEW(Ev_Dnd_Drop_Status, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e->source_win = (Window) xevent->xclient.data.l[0];
e->x = (xevent->xclient.data.l[2] >> 16) & 0xffff;
e->y = xevent->xclient.data.l[2] & 0xffff;
e->w = (xevent->xclient.data.l[3] >> 16) & 0xffff;
e->h = xevent->xclient.data.l[3] & 0xffff;
if (xevent->xclient.data.l[1] & 0x1)
e->ok = 1;
else
e->ok = 0;
e_add_event(EV_DND_DROP_STATUS, e, e_ev_generic_free);
}
else if ((xevent->xclient.message_type == atom_xdndfinished) &&
(xevent->xclient.format == 32))
{
Ev_Dnd_Drop_End *e;
e = NEW(Ev_Dnd_Drop_End, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e->source_win = (Window) xevent->xclient.data.l[0];
e_add_event(EV_DND_DROP_END, e, e_ev_generic_free);
}
else if ((xevent->xclient.message_type == atom_xdnddrop) &&
(xevent->xclient.format == 32))
{
Ev_Dnd_Drop *e;
e = NEW(Ev_Dnd_Drop, 1);
e->win = xevent->xclient.window;
e->root = e_window_get_root(e->win);
e->source_win = (Window) xevent->xclient.data.l[0];
e_add_event(EV_DND_DROP, e, e_ev_generic_free);
}
else
{
Ev_Message *e;
e = NEW(Ev_Message, 1);
e->win = xevent->xclient.window;
e->format = xevent->xclient.format;
e->atom = xevent->xclient.message_type;
MEMCPY(xevent->xclient.data.b, e->data.b, char, 20);
e_add_event(EV_MESSAGE, e, e_ev_generic_free);
}
}
static void
e_ev_x_handle_shape_change(XEvent * xevent)
{
Ev_Window_Shape *e;
XShapeEvent *shape_event;
shape_event = (XShapeEvent *) xevent;
e = NEW(Ev_Window_Shape, 1);
e->win = shape_event->window;
e->root = e_window_get_root(e->win);
e->time = shape_event->time;
e_add_event(EV_WINDOW_SHAPE, e, e_ev_generic_free);
}
char *
e_key_press_translate_into_typeable(Ev_Key_Down * e)
{
/* exceptions */
if ((e_string_cmp(e->key, "Delete")) ||
(e_string_cmp(e->key, "BackSpace")) ||
(e_string_cmp(e->key, "Tab")) ||
(e_string_cmp(e->key, "Escape")) ||
(e_string_cmp(e->key, "Return")) ||
(e_string_cmp(e->key, "KP_Enter")) ||
(e_string_cmp(e->key, "Enter")) ||
(e_string_cmp(e->key, "KP_Divide")) ||
(e_string_cmp(e->key, "KP_Multiply")) ||
(e_string_cmp(e->key, "KP_Subtract")) ||
(e_string_cmp(e->key, "KP_Add")) || (e_string_cmp(e->key, "Enter")))
return NULL;
return e->compose;
}