gtk2/gdk/nanox/gdkevents-nanox.c

442 lines
12 KiB
C
Raw Normal View History

#include "gdk.h"
#include "gdkinternals.h"
#include "gdkprivate-nanox.h"
typedef struct _GdkEventPrivate GdkEventPrivate;
#define DOUBLE_CLICK_TIME 250
#define TRIPLE_CLICK_TIME 500
#define DOUBLE_CLICK_DIST 5
#define TRIPLE_CLICK_DIST 5
#define GR_BUTTON_TO_GDK(b) b&LBUTTON? 1: (b&MBUTTON? 2: (b&RBUTTON? 3: 0))
static guint gr_mod_to_gdk(guint mods, guint buttons) {
guint res=0;
if (mods & GR_MODIFIER_SHIFT)
res |= GDK_SHIFT_MASK;
if (mods & GR_MODIFIER_CTRL)
res |= GDK_CONTROL_MASK;
if (mods & GR_MODIFIER_META)
res |= GDK_MOD1_MASK;
if (buttons & LBUTTON)
res |= GDK_BUTTON1_MASK;
if (buttons & MBUTTON)
res |= GDK_BUTTON2_MASK;
if (buttons & RBUTTON)
res |= GDK_BUTTON3_MASK;
return res;
}
static gboolean gdk_event_prepare (gpointer source_data,
GTimeVal *current_time,
gint *timeout,
gpointer user_data);
static gboolean gdk_event_check (gpointer source_data,
GTimeVal *current_time,
gpointer user_data);
static gboolean gdk_event_dispatch (gpointer source_data,
GTimeVal *current_time,
gpointer user_data);
typedef enum
{
/* Following flag is set for events on the event queue during
* translation and cleared afterwards.
*/
GDK_EVENT_PENDING = 1 << 0
} GdkEventFlags;
struct _GdkEventPrivate
{
GdkEvent event;
guint flags;
};
static GSourceFuncs event_funcs = {
gdk_event_prepare,
gdk_event_check,
gdk_event_dispatch,
(GDestroyNotify)g_free
};
GPollFD event_poll_fd;
extern int sock;
static guint serial_value = 1;
static int
events_idle () {
gdk_events_queue();
return TRUE;
}
void
gdk_events_init (void)
{
g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
event_poll_fd.fd = sock;
event_poll_fd.events = G_IO_IN;
g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS);
g_idle_add(events_idle, NULL);
}
static gboolean
gdk_event_prepare (gpointer source_data,
GTimeVal *current_time,
gint *timeout,
gpointer user_data)
{
gboolean retval;
GDK_THREADS_ENTER ();
*timeout = -1;
retval = (gdk_event_queue_find_first () != NULL);
GDK_THREADS_LEAVE ();
return retval;
}
static gboolean
gdk_event_check (gpointer source_data,
GTimeVal *current_time,
gpointer user_data)
{
gboolean retval;
GDK_THREADS_ENTER ();
if (event_poll_fd.revents & G_IO_IN)
//retval = (gdk_event_queue_find_first () != NULL);
retval = 1;
else
retval = FALSE;
GDK_THREADS_LEAVE ();
return retval;
}
static gboolean
gdk_event_dispatch (gpointer source_data,
GTimeVal *current_time,
gpointer user_data)
{
GdkEvent *event;
GDK_THREADS_ENTER ();
gdk_events_queue();
event = gdk_event_unqueue();
if (event)
{
if (gdk_event_func)
(*gdk_event_func) (event, gdk_event_data);
gdk_event_free (event);
}
GDK_THREADS_LEAVE ();
return TRUE;
}
gboolean
gdk_events_pending (void)
{
return gdk_event_queue_find_first();
}
GdkEvent*
gdk_event_get_graphics_expose (GdkWindow *window)
{
return NULL;
}
static gint gdk_event_translate (GdkEvent *event, GR_EVENT *xevent) {
GdkWindow *window=NULL;
GdkWindowPrivate *window_private=NULL;
gint return_val = FALSE;
static int lastx=0, lasty=0, lastrootx=0, lastrooty=0;
if (xevent->type == GR_EVENT_TYPE_FDINPUT)
return 0;
window = gdk_window_lookup (xevent->general.wid);
/* FIXME: window might be a GdkPixmap!!! */
window_private = (GdkWindowPrivate *) window;
if (window != NULL)
gdk_window_ref (window);
event->any.window = window;
event->any.send_event = FALSE;
if (window_private && GDK_DRAWABLE_DESTROYED (window))
{
return FALSE;
}
else
{
/* Check for filters for this window
*/
GdkFilterReturn result = GDK_FILTER_CONTINUE;
/*result = gdk_event_apply_filters (xevent, event,
window_private
?window_private->filters
:gdk_default_filters);
*/
if (result != GDK_FILTER_CONTINUE)
{
return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
}
}
return_val = TRUE;
//g_message("got event (%p) %d", window, xevent->type);
switch (xevent->type)
{
case GR_EVENT_TYPE_KEY_DOWN:
event->key.keyval = xevent->keystroke.ch;
event->key.type = GDK_KEY_PRESS;
event->key.window = window;
event->key.time = serial_value++;
event->key.state = gr_mod_to_gdk(xevent->keystroke.modifiers, xevent->keystroke.buttons);
event->key.string = g_strdup_printf ("%c", xevent->keystroke.ch);
event->key.length = 1;
break;
case GR_EVENT_TYPE_KEY_UP:
event->key.keyval = xevent->keystroke.ch;
event->key.type = GDK_KEY_RELEASE;
event->key.window = window;
event->key.time = serial_value++;
event->key.state = gr_mod_to_gdk(xevent->keystroke.modifiers, xevent->keystroke.buttons)|GDK_RELEASE_MASK;
event->key.string = NULL;
event->key.length = 0;
break;
case GR_EVENT_TYPE_BUTTON_DOWN:
event->button.type = GDK_BUTTON_PRESS;
event->button.window = window;
event->button.time = serial_value++;
event->button.x = xevent->button.x;
event->button.y = xevent->button.y;
event->button.x_root = (gfloat)xevent->button.rootx;
event->button.y_root = (gfloat)xevent->button.rooty;
event->button.pressure = 0.5;
event->button.xtilt = 0;
event->button.ytilt = 0;
event->button.state = gr_mod_to_gdk(xevent->button.modifiers, xevent->button.buttons);
event->button.button = GR_BUTTON_TO_GDK(xevent->button.changebuttons);
event->button.source = GDK_SOURCE_MOUSE;
event->button.deviceid = GDK_CORE_POINTER;
g_message("button down: %d", event->button.button);
gdk_event_button_generate (event);
break;
case GR_EVENT_TYPE_BUTTON_UP:
event->button.type = GDK_BUTTON_RELEASE;
event->button.window = window;
event->button.time = serial_value++;
event->button.x = xevent->button.x;
event->button.y = xevent->button.y;
event->button.x_root = (gfloat)xevent->button.rootx;
event->button.y_root = (gfloat)xevent->button.rooty;
event->button.pressure = 0.5;
event->button.xtilt = 0;
event->button.ytilt = 0;
event->button.state = gr_mod_to_gdk(xevent->button.modifiers, xevent->button.buttons)|GDK_RELEASE_MASK;
event->button.button = GR_BUTTON_TO_GDK(xevent->button.changebuttons);
event->button.source = GDK_SOURCE_MOUSE;
event->button.deviceid = GDK_CORE_POINTER;
g_message("button up: %d", event->button.button);
gdk_event_button_generate (event);
break;
case GR_EVENT_TYPE_MOUSE_MOTION:
event->motion.type = GDK_MOTION_NOTIFY;
event->motion.window = window;
event->motion.time = serial_value++;
event->motion.x = xevent->mouse.x;
event->motion.y = xevent->mouse.y;
event->motion.x_root = (gfloat)xevent->mouse.rootx;
event->motion.y_root = (gfloat)xevent->mouse.rooty;
event->motion.pressure = 0.5;
event->motion.xtilt = 0;
event->motion.ytilt = 0;
event->motion.state = gr_mod_to_gdk(xevent->mouse.modifiers, xevent->mouse.buttons);
event->motion.is_hint = 0;
event->motion.source = GDK_SOURCE_MOUSE;
event->motion.deviceid = GDK_CORE_POINTER;
break;
case GR_EVENT_TYPE_MOUSE_POSITION:
return_val = FALSE;
break;
case GR_EVENT_TYPE_MOUSE_ENTER:
event->crossing.type = GDK_ENTER_NOTIFY;
event->crossing.window = window;
event->crossing.subwindow = NULL;
event->crossing.time = serial_value++;
event->crossing.detail = GDK_NOTIFY_UNKNOWN;
//g_message("subwindow 1: %p", event->crossing.subwindow);
/* other stuff here , x, y, x_root, y_root */
break;
case GR_EVENT_TYPE_MOUSE_EXIT:
event->crossing.type = GDK_LEAVE_NOTIFY;
event->crossing.window = window;
event->crossing.subwindow = NULL;
event->crossing.time = serial_value++;
event->crossing.mode = GDK_CROSSING_NORMAL;
event->crossing.detail = GDK_NOTIFY_UNKNOWN;
//g_message("subwindow 2: %p", event->crossing.subwindow);
/* other stuff here , x, y, x_root, y_root */
break;
case GR_EVENT_TYPE_FOCUS_IN:
case GR_EVENT_TYPE_FOCUS_OUT:
event->focus_change.type = GDK_FOCUS_CHANGE;
event->focus_change.window = window;
event->focus_change.in = (xevent->general.type == GR_EVENT_TYPE_FOCUS_IN);
break;
case GR_EVENT_TYPE_UPDATE:
case GR_EVENT_TYPE_CHLD_UPDATE:
if (xevent->update.utype == GR_UPDATE_MAP) {
event->any.type = GDK_MAP;
event->any.window = window;
} else if (xevent->update.utype == GR_UPDATE_UNMAP) {
event->any.type = GDK_UNMAP;
event->any.window = window;
if (gdk_xgrab_window == window_private)
gdk_xgrab_window = NULL;
} else {
if (!window || GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_CHILD)
return_val = FALSE;
else
{
event->configure.type = GDK_CONFIGURE;
event->configure.window = window;
event->configure.width = xevent->update.width;
event->configure.height = xevent->update.height;
event->configure.x = xevent->update.x;
event->configure.y = xevent->update.y;
window_private->x = event->configure.x;
window_private->y = event->configure.y;
window_private->drawable.width = event->configure.width;
window_private->drawable.height = event->configure.height;
if (window_private->resize_count > 1)
window_private->resize_count -= 1;
}
}
break;
case GR_EVENT_TYPE_EXPOSURE:
event->expose.type = GDK_EXPOSE;
event->expose.window = window;
event->expose.area.x = xevent->exposure.x;
event->expose.area.y = xevent->exposure.y;
event->expose.area.width = xevent->exposure.width;
event->expose.area.height = xevent->exposure.height;
event->expose.count = 0;
break;
case GR_EVENT_TYPE_FDINPUT:
case GR_EVENT_TYPE_NONE:
return_val = FALSE;
break;
default:
return_val = FALSE;
g_message("event %d not handled\n", xevent->type);
}
if (return_val)
{
if (event->any.window)
gdk_window_ref (event->any.window);
if (((event->any.type == GDK_ENTER_NOTIFY) ||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
gdk_window_ref (event->crossing.subwindow);
}
else
{
/* Mark this event as having no resources to be freed */
event->any.window = NULL;
event->any.type = GDK_NOTHING;
}
if (window)
gdk_window_unref (window);
return return_val;
}
void
gdk_events_queue (void)
{
GList *node;
GdkEvent *event;
GR_EVENT xevent;
while (!gdk_event_queue_find_first())
{
GrCheckNextEvent (&xevent);
if (!xevent.type)
return;
event = gdk_event_new ();
event->any.type = GDK_NOTHING;
event->any.window = NULL;
event->any.send_event = FALSE;
((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
gdk_event_queue_append (event);
node = gdk_queued_tail;
if (gdk_event_translate (event, &xevent))
{
((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
//g_message("got event: %d", event->type);
}
else
{
gdk_event_queue_remove_link (node);
g_list_free_1 (node);
gdk_event_free (event);
}
}
}
gboolean
gdk_event_send_client_message (GdkEvent *event, guint32 xid)
{
g_message("unimplemented %s", __FUNCTION__);
return 0;
}
void
gdk_event_send_clientmessage_toall (GdkEvent *event)
{
g_message("unimplemented %s", __FUNCTION__);
}
void
gdk_flush (void)
{
GrFlush();
}