summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rw-r--r--ChangeLog.pre-2-030
-rw-r--r--ChangeLog.pre-2-1030
-rw-r--r--ChangeLog.pre-2-230
-rw-r--r--ChangeLog.pre-2-430
-rw-r--r--ChangeLog.pre-2-630
-rw-r--r--ChangeLog.pre-2-830
-rw-r--r--gdk/linux-fb/Makefile.am1
-rw-r--r--gdk/linux-fb/gdkcursor-fb.c236
-rw-r--r--gdk/linux-fb/gdkinput-ps2.c1000
-rw-r--r--gdk/linux-fb/gdkmain-fb.c3
-rw-r--r--gdk/linux-fb/gdkmouse-fb.c618
-rw-r--r--gdk/linux-fb/gdkprivate-fb.h13
-rw-r--r--gdk/linux-fb/gdkwindow-fb.c180
14 files changed, 1253 insertions, 1008 deletions
diff --git a/ChangeLog b/ChangeLog
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index ec294fc959..b10aac88b3 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,5 +1,35 @@
2000-12-06 Alexander Larsson <alexl@redhat.com>
+ * gdk/linux-fb/Makefile.am:
+ Add gdkmouse-fb.c
+
+ * gdk/linux-fb/gdkmouse-fb.c:
+ New file. Abstracted the mouse drivers a bit.
+
+ * gdk/linux-fb/gdkcursor-fb.c:
+ The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+ * gdk/linux-fb/gdkinput-ps2.c:
+ Removed old mouse handling code. Moved cursor handling code
+ to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+ gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+ gdk_mouse_get_info.
+
+ * gdk/linux-fb/gdkmain-fb.c:
+ Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+ * gdk/linux-fb/gdkprivate-fb.h:
+ Removed public gdk_fb_find_common_ancestor, added and renamed
+ functions for the new mouse handling code.
+
+ * gdk/linux-fb/gdkwindow-fb.c:
+ Moved gdk_fb_window_send_crossing_events here. added global
+ variable gdk_fb_window_containing_pointer. made
+ gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+ renamed to gdk_mouse_get_info.
+
+2000-12-06 Alexander Larsson <alexl@redhat.com>
+
* gdk/linux-fb/gdkevents-fb.c:
Update to match latest gmain/gsource changes.
diff --git a/gdk/linux-fb/Makefile.am b/gdk/linux-fb/Makefile.am
index 2bc07b88c2..95c4a3079e 100644
--- a/gdk/linux-fb/Makefile.am
+++ b/gdk/linux-fb/Makefile.am
@@ -50,6 +50,7 @@ libgdk_linux_fb_la_SOURCES = \
gdkprivate-fb.h \
gdkinputprivate.h \
gdkinput-ps2.c \
+ gdkmouse-fb.c \
gdkevents-fb.c \
gdkrender-fb.c \
mi.h \
diff --git a/gdk/linux-fb/gdkcursor-fb.c b/gdk/linux-fb/gdkcursor-fb.c
index 80d51332c4..6dab9f8bd6 100644
--- a/gdk/linux-fb/gdkcursor-fb.c
+++ b/gdk/linux-fb/gdkcursor-fb.c
@@ -284,3 +284,239 @@ _gdk_cursor_destroy (GdkCursor *cursor)
g_free (private);
}
+
+/* Global data to keep track of cursor */
+static GdkPixmap *last_contents = NULL;
+static GdkPoint last_location, last_contents_size;
+static GdkCursor *last_cursor = NULL;
+static GdkFBDrawingContext *gdk_fb_cursor_dc = NULL;
+static GdkFBDrawingContext cursor_dc_dat;
+static GdkGC *cursor_gc;
+static gint cursor_visibility_count = 1;
+
+static GdkFBDrawingContext *
+gdk_fb_cursor_dc_reset (void)
+{
+ if (gdk_fb_cursor_dc)
+ gdk_fb_drawing_context_finalize (gdk_fb_cursor_dc);
+
+ gdk_fb_cursor_dc = &cursor_dc_dat;
+ gdk_fb_drawing_context_init (gdk_fb_cursor_dc,
+ GDK_DRAWABLE_IMPL(gdk_parent_root),
+ cursor_gc,
+ TRUE,
+ FALSE);
+
+ return gdk_fb_cursor_dc;
+}
+
+void
+gdk_fb_cursor_hide (void)
+{
+ GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
+
+ cursor_visibility_count--;
+ g_assert (cursor_visibility_count <= 0);
+
+ if (cursor_visibility_count < 0)
+ return;
+
+ if (!mydc)
+ mydc = gdk_fb_cursor_dc_reset ();
+
+ if (last_contents)
+ {
+ gdk_gc_set_clip_mask (cursor_gc, NULL);
+ /* Restore old picture */
+ gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
+ cursor_gc,
+ GDK_DRAWABLE_IMPL(last_contents),
+ mydc,
+ 0, 0,
+ last_location.x,
+ last_location.y,
+ last_contents_size.x,
+ last_contents_size.y);
+ }
+}
+
+void
+gdk_fb_cursor_invalidate (void)
+{
+ if (last_contents)
+ {
+ gdk_pixmap_unref (last_contents);
+ last_contents = NULL;
+ }
+}
+
+void
+gdk_fb_cursor_unhide()
+{
+ GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
+ GdkCursorPrivateFB *last_private;
+ GdkDrawableFBData *pixmap_last;
+
+ last_private = GDK_CURSOR_FB (last_cursor);
+ pixmap_last = GDK_DRAWABLE_IMPL_FBDATA (last_private->cursor);
+ cursor_visibility_count++;
+ g_assert (cursor_visibility_count <= 1);
+ if (cursor_visibility_count < 1)
+ return;
+
+ if (!mydc)
+ mydc = gdk_fb_cursor_dc_reset ();
+
+ if (last_cursor)
+ {
+ if (!last_contents ||
+ pixmap_last->width > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->width ||
+ pixmap_last->height > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->height)
+ {
+ if (last_contents)
+ gdk_pixmap_unref (last_contents);
+
+ last_contents = gdk_pixmap_new (gdk_parent_root,
+ pixmap_last->width,
+ pixmap_last->height,
+ GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->depth);
+ }
+
+ gdk_gc_set_clip_mask (cursor_gc, NULL);
+ gdk_fb_draw_drawable_2 (GDK_DRAWABLE_IMPL (last_contents),
+ cursor_gc,
+ GDK_DRAWABLE_IMPL (gdk_parent_root),
+ last_location.x,
+ last_location.y,
+ 0, 0,
+ pixmap_last->width,
+ pixmap_last->height,
+ TRUE, FALSE);
+ last_contents_size.x = pixmap_last->width;
+ last_contents_size.y = pixmap_last->height;
+
+ gdk_gc_set_clip_mask (cursor_gc, last_private->mask);
+ gdk_gc_set_clip_origin (cursor_gc,
+ last_location.x,
+ last_location.y);
+
+ gdk_fb_cursor_dc_reset ();
+ gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (gdk_parent_root),
+ cursor_gc,
+ GDK_DRAWABLE_IMPL (last_private->cursor),
+ mydc,
+ 0, 0,
+ last_location.x, last_location.y,
+ pixmap_last->width,
+ pixmap_last->height);
+ }
+ else
+ gdk_fb_cursor_invalidate ();
+}
+
+gboolean
+gdk_fb_cursor_region_need_hide (GdkRegion *region)
+{
+ GdkRectangle testme;
+
+ if (!last_cursor)
+ return FALSE;
+
+ testme.x = last_location.x;
+ testme.y = last_location.y;
+ testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
+ testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
+
+ return (gdk_region_rect_in (region, &testme) != GDK_OVERLAP_RECTANGLE_OUT);
+}
+
+gboolean
+gdk_fb_cursor_need_hide (GdkRectangle *rect)
+{
+ GdkRectangle testme;
+
+ if (!last_cursor)
+ return FALSE;
+
+ testme.x = last_location.x;
+ testme.y = last_location.y;
+ testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
+ testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
+
+ return gdk_rectangle_intersect (rect, &testme, &testme);
+}
+
+void
+gdk_fb_get_cursor_rect (GdkRectangle *rect)
+{
+ if (last_cursor)
+ {
+ rect->x = last_location.x;
+ rect->y = last_location.y;
+ rect->width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
+ rect->height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
+ }
+ else
+ {
+ rect->x = rect->y = -1;
+ rect->width = rect->height = 0;
+ }
+}
+
+void
+gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window)
+{
+ GdkCursor *the_cursor;
+
+ if (!cursor_gc)
+ {
+ GdkColor white, black;
+ cursor_gc = gdk_gc_new (gdk_parent_root);
+ gdk_color_black (gdk_colormap_get_system (), &black);
+ gdk_color_white (gdk_colormap_get_system (), &white);
+ gdk_gc_set_foreground (cursor_gc, &black);
+ gdk_gc_set_background (cursor_gc, &white);
+ }
+
+ gdk_fb_cursor_hide ();
+
+ if (_gdk_fb_pointer_grab_window)
+ {
+ if (_gdk_fb_pointer_grab_cursor)
+ the_cursor = _gdk_fb_pointer_grab_cursor;
+ else
+ {
+ GdkWindow *win = _gdk_fb_pointer_grab_window;
+ while (!GDK_WINDOW_IMPL_FBDATA (win)->cursor && GDK_WINDOW_OBJECT (win)->parent)
+ win = (GdkWindow *)GDK_WINDOW_OBJECT (win)->parent;
+ the_cursor = GDK_WINDOW_IMPL_FBDATA (win)->cursor;
+ }
+ }
+ else
+ {
+ while (!GDK_WINDOW_IMPL_FBDATA (in_window)->cursor && GDK_WINDOW_P (in_window)->parent)
+ in_window = (GdkWindow *)GDK_WINDOW_P (in_window)->parent;
+ the_cursor = GDK_WINDOW_IMPL_FBDATA (in_window)->cursor;
+ }
+
+ last_location.x = x - GDK_CURSOR_FB (the_cursor)->hot_x;
+ last_location.y = y - GDK_CURSOR_FB (the_cursor)->hot_y;
+
+ if (the_cursor)
+ gdk_cursor_ref (the_cursor);
+ if (last_cursor)
+ gdk_cursor_unref (last_cursor);
+ last_cursor = the_cursor;
+
+ gdk_fb_cursor_unhide ();
+}
+
+void
+gdk_fb_cursor_reset(void)
+{
+ GdkWindow *win = gdk_window_at_pointer (NULL, NULL);
+ gint x, y;
+
+ gdk_mouse_get_info (&x, &y, NULL);
+ gdk_fb_cursor_move (x, y, win);
+}
diff --git a/gdk/linux-fb/gdkinput-ps2.c b/gdk/linux-fb/gdkinput-ps2.c
index 7c5a46a5bd..2eccb61bd7 100644
--- a/gdk/linux-fb/gdkinput-ps2.c
+++ b/gdk/linux-fb/gdkinput-ps2.c
@@ -50,18 +50,6 @@
*/
typedef struct {
- gint fd, fd_tag;
-
- gdouble x, y;
- GdkWindow *prev_window;
- gboolean button1_pressed, button2_pressed, button3_pressed;
- gboolean click_grab;
-
- guchar mouse_packet[5];
- int packet_nbytes;
-} MouseDevice;
-
-typedef struct {
gint fd, fd_tag, consfd;
int vtnum, prev_vtnum;
@@ -73,7 +61,6 @@ static guint blanking_timer = 0;
static Keyboard * tty_keyboard_open(void);
-static MouseDevice *gdk_fb_mouse = NULL;
static Keyboard *keyboard = NULL;
#ifndef VESA_NO_BLANKING
@@ -107,977 +94,6 @@ input_activity (void)
#endif
}
-static void
-send_button_event (MouseDevice *mouse,
- guint button,
- gboolean press_event,
- guint32 the_time)
-{
- GdkEvent *event;
- gint x, y;
- GdkWindow *window;
- int nbuttons = 0;
-
- if (_gdk_fb_pointer_grab_window_events)
- window = _gdk_fb_pointer_grab_window_events;
- else
- window = gdk_window_at_pointer(NULL, NULL);
-
- event = gdk_event_make (window, press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE, FALSE);
-
- if (event)
- {
- gdk_window_get_origin (window, &x, &y);
- x = mouse->x - x;
- y = mouse->y - y;
-
- event->button.x = x;
- event->button.y = y;
- event->button.button = button;
- event->button.state = (mouse->button1_pressed?GDK_BUTTON1_MASK:0) |
- (mouse->button2_pressed ? GDK_BUTTON2_MASK : 0) |
- (mouse->button3_pressed ? GDK_BUTTON3_MASK : 0) |
- (1 << (button + 8)) /* badhack */ |
- keyboard->modifier_state;
- event->button.device = gdk_core_pointer;
- event->button.x_root = mouse->x;
- event->button.y_root = mouse->y;
-
- event->button.time = the_time;
-
-#if 0
- g_message ("Button #%d %s [%d, %d] in %p",
- button, press_event?"pressed":"released",
- x, y, window);
-
- /* Debugging aid */
- if (window && window != gdk_parent_root)
- {
- GdkGC *tmp_gc;
-
- tmp_gc = gdk_gc_new (window);
- GDK_GC_FBDATA (tmp_gc)->values.foreground.pixel = 0;
- gdk_fb_draw_rectangle (GDK_DRAWABLE_IMPL(window), tmp_gc, TRUE, 0, 0,
- GDK_DRAWABLE_IMPL_FBDATA(window)->width, GDK_DRAWABLE_IMPL_FBDATA(window)->height);
- gdk_gc_unref(tmp_gc);
- }
-#endif
-
- gdk_event_queue_append (event);
-
- /* For double-clicks */
- if (press_event)
- gdk_event_button_generate (event);
-
- }
-
- if (mouse->button1_pressed)
- nbuttons++;
- if (mouse->button2_pressed)
- nbuttons++;
- if (mouse->button3_pressed)
- nbuttons++;
-
- /* Handle implicit button grabs: */
- if (press_event && nbuttons == 1)
- {
- gdk_fb_pointer_grab (window, FALSE,
- gdk_window_get_events (window),
- NULL, NULL,
- GDK_CURRENT_TIME, TRUE);
- mouse->click_grab = TRUE;
- }
- else if (!press_event && nbuttons == 0 && mouse->click_grab)
- {
- gdk_fb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
- mouse->click_grab = FALSE;
- }
-}
-
-static GdkPixmap *last_contents = NULL;
-static GdkPoint last_location, last_contents_size;
-static GdkCursor *last_cursor = NULL;
-static GdkFBDrawingContext *gdk_fb_cursor_dc = NULL;
-static GdkFBDrawingContext cursor_dc_dat;
-static GdkGC *cursor_gc;
-static gint cursor_visibility_count = 1;
-
-static GdkFBDrawingContext *
-gdk_fb_cursor_dc_reset (void)
-{
- if (gdk_fb_cursor_dc)
- gdk_fb_drawing_context_finalize (gdk_fb_cursor_dc);
-
- gdk_fb_cursor_dc = &cursor_dc_dat;
- gdk_fb_drawing_context_init (gdk_fb_cursor_dc,
- GDK_DRAWABLE_IMPL(gdk_parent_root),
- cursor_gc,
- TRUE,
- FALSE);
-
- return gdk_fb_cursor_dc;
-}
-
-void
-gdk_fb_cursor_hide (void)
-{
- GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
-
- cursor_visibility_count--;
- g_assert (cursor_visibility_count <= 0);
-
- if (cursor_visibility_count < 0)
- return;
-
- if (!mydc)
- mydc = gdk_fb_cursor_dc_reset ();
-
- if (last_contents)
- {
- gdk_gc_set_clip_mask (cursor_gc, NULL);
- /* Restore old picture */
- gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
- cursor_gc,
- GDK_DRAWABLE_IMPL(last_contents),
- mydc,
- 0, 0,
- last_location.x,
- last_location.y,
- last_contents_size.x,
- last_contents_size.y);
- }
-}
-
-void
-gdk_fb_cursor_invalidate (void)
-{
- if (last_contents)
- {
- gdk_pixmap_unref (last_contents);
- last_contents = NULL;
- }
-}
-
-void
-gdk_fb_cursor_unhide()
-{
- GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
- GdkCursorPrivateFB *last_private;
- GdkDrawableFBData *pixmap_last;
-
- last_private = GDK_CURSOR_FB (last_cursor);
- pixmap_last = GDK_DRAWABLE_IMPL_FBDATA (last_private->cursor);
- cursor_visibility_count++;
- g_assert (cursor_visibility_count <= 1);
- if (cursor_visibility_count < 1)
- return;
-
- if (!mydc)
- mydc = gdk_fb_cursor_dc_reset ();
-
- if (last_cursor)
- {
- if (!last_contents ||
- pixmap_last->width > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->width ||
- pixmap_last->height > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->height)
- {
- if (last_contents)
- gdk_pixmap_unref (last_contents);
-
- last_contents = gdk_pixmap_new (gdk_parent_root,
- pixmap_last->width,
- pixmap_last->height,
- GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->depth);
- }
-
- gdk_gc_set_clip_mask (cursor_gc, NULL);
- gdk_fb_draw_drawable_2 (GDK_DRAWABLE_IMPL (last_contents),
- cursor_gc,
- GDK_DRAWABLE_IMPL (gdk_parent_root),
- last_location.x,
- last_location.y,
- 0, 0,
- pixmap_last->width,
- pixmap_last->height,
- TRUE, FALSE);
- last_contents_size.x = pixmap_last->width;
- last_contents_size.y = pixmap_last->height;
-
- gdk_gc_set_clip_mask (cursor_gc, last_private->mask);
- gdk_gc_set_clip_origin (cursor_gc,
- last_location.x,
- last_location.y);
-
- gdk_fb_cursor_dc_reset ();
- gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (gdk_parent_root),
- cursor_gc,
- GDK_DRAWABLE_IMPL (last_private->cursor),
- mydc,
- 0, 0,
- last_location.x, last_location.y,
- pixmap_last->width,
- pixmap_last->height);
- }
- else
- gdk_fb_cursor_invalidate ();
-}
-
-gboolean
-gdk_fb_cursor_region_need_hide (GdkRegion *region)
-{
- GdkRectangle testme;
-
- if (!last_cursor)
- return FALSE;
-
- testme.x = last_location.x;
- testme.y = last_location.y;
- testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
- testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
-
- return (gdk_region_rect_in (region, &testme) != GDK_OVERLAP_RECTANGLE_OUT);
-}
-
-gboolean
-gdk_fb_cursor_need_hide (GdkRectangle *rect)
-{
- GdkRectangle testme;
-
- if (!last_cursor)
- return FALSE;
-
- testme.x = last_location.x;
- testme.y = last_location.y;
- testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
- testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
-
- return gdk_rectangle_intersect (rect, &testme, &testme);
-}
-
-void
-gdk_fb_get_cursor_rect (GdkRectangle *rect)
-{
- if (last_cursor)
- {
- rect->x = last_location.x;
- rect->y = last_location.y;
- rect->width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
- rect->height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
- }
- else
- {
- rect->x = rect->y = -1;
- rect->width = rect->height = 0;
- }
-}
-
-static void
-move_pointer (MouseDevice *mouse, GdkWindow *in_window)
-{
- GdkCursor *the_cursor;
-
- if (!cursor_gc)
- {
- GdkColor white, black;
- cursor_gc = gdk_gc_new (gdk_parent_root);
- gdk_color_black (gdk_colormap_get_system (), &black);
- gdk_color_white (gdk_colormap_get_system (), &white);
- gdk_gc_set_foreground (cursor_gc, &black);
- gdk_gc_set_background (cursor_gc, &white);
- }
-
- gdk_fb_cursor_hide ();
-
- if (_gdk_fb_pointer_grab_window)
- {
- if (_gdk_fb_pointer_grab_cursor)
- the_cursor = _gdk_fb_pointer_grab_cursor;
- else
- {
- GdkWindow *win = _gdk_fb_pointer_grab_window;
- while (!GDK_WINDOW_IMPL_FBDATA (win)->cursor && GDK_WINDOW_OBJECT (win)->parent)
- win = (GdkWindow *)GDK_WINDOW_OBJECT (win)->parent;
- the_cursor = GDK_WINDOW_IMPL_FBDATA (win)->cursor;
- }
- }
- else
- {
- while (!GDK_WINDOW_IMPL_FBDATA (in_window)->cursor && GDK_WINDOW_P (in_window)->parent)
- in_window = (GdkWindow *)GDK_WINDOW_P (in_window)->parent;
- the_cursor = GDK_WINDOW_IMPL_FBDATA (in_window)->cursor;
- }
-
- last_location.x = mouse->x - GDK_CURSOR_FB (the_cursor)->hot_x;
- last_location.y = mouse->y - GDK_CURSOR_FB (the_cursor)->hot_y;
-
- if (the_cursor)
- gdk_cursor_ref (the_cursor);
- if (last_cursor)
- gdk_cursor_unref (last_cursor);
- last_cursor = the_cursor;
-
- gdk_fb_cursor_unhide ();
-}
-
-void
-gdk_fb_cursor_reset(void)
-{
- GdkWindow *win = gdk_window_at_pointer (NULL, NULL);
-
- move_pointer (gdk_fb_mouse, win);
-}
-
-void
-gdk_fb_window_send_crossing_events (GdkWindow *dest,
- GdkCrossingMode mode)
-{
- GdkWindow *c;
- GdkWindow *win, *last, *next;
- GdkEvent *event;
- gint x, y, x_int, y_int;
- GdkModifierType my_mask;
- GList *path, *list;
- gboolean non_linear;
- gboolean only_grabbed_window;
- GdkWindow *a;
- GdkWindow *b;
-
- if (gdk_fb_mouse->prev_window == NULL)
- gdk_fb_mouse->prev_window = gdk_window_ref (gdk_parent_root);
-
- if (mode == GDK_CROSSING_UNGRAB)
- a = _gdk_fb_pointer_grab_window;
- else
- a = gdk_fb_mouse->prev_window;
- b = dest;
-
- /* When grab in progress only send normal crossing events about
- * the grabbed window.
- */
- only_grabbed_window = (_gdk_fb_pointer_grab_window_events != NULL) &&
- (mode == GDK_CROSSING_NORMAL);
-
- if (a==b)
- return;
-
- gdk_input_get_mouseinfo (&x, &y, &my_mask);
-
- c = gdk_fb_find_common_ancestor (a, b);
-
- non_linear = (c != a) && (c != b);
-
- if (!only_grabbed_window || (a == _gdk_fb_pointer_grab_window))
- event = gdk_event_make (a, GDK_LEAVE_NOTIFY, TRUE);
- else
- event = NULL;
- if (event)
- {
- event->crossing.subwindow = NULL;
- gdk_window_get_root_origin (a, &x_int, &y_int);
- event->crossing.x = x - x_int;
- event->crossing.y = y - y_int;
- event->crossing.x_root = x;
- event->crossing.y_root = y;
- event->crossing.mode = mode;
- if (non_linear)
- event->crossing.detail = GDK_NOTIFY_NONLINEAR;
- else if (c==a)
- event->crossing.detail = GDK_NOTIFY_INFERIOR;
- else
- event->crossing.detail = GDK_NOTIFY_ANCESTOR;
- event->crossing.focus = FALSE;
- event->crossing.state = my_mask;
- }
-
- /* Traverse up from a to (excluding) c */
- if (c != a)
- {
- last = a;
- win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
- while (win != c)
- {
- if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
- event = gdk_event_make (win, GDK_LEAVE_NOTIFY, TRUE);
- else
- event = NULL;
- if (event)
- {
- event->crossing.subwindow = gdk_window_ref (last);
- gdk_window_get_root_origin (win, &x_int, &y_int);
- event->crossing.x = x - x_int;
- event->crossing.y = y - y_int;
- event->crossing.x_root = x;
- event->crossing.y_root = y;
- event->crossing.mode = mode;
- if (non_linear)
- event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
- else
- event->crossing.detail = GDK_NOTIFY_VIRTUAL;
- event->crossing.focus = FALSE;
- event->crossing.state = my_mask;
- }
- last = win;
- win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
- }
- }
-
- /* Traverse down from c to b */
- if (c != b)
- {
- path = NULL;
- win = GDK_WINDOW( GDK_WINDOW_OBJECT (b)->parent);
- while (win != c)
- {
- path = g_list_prepend (path, win);
- win = GDK_WINDOW( GDK_WINDOW_OBJECT (win)->parent);
- }
-
- list = path;
- while (list)
- {
- win = (GdkWindow *)list->data;
- list = g_list_next (list);
- if (list)
- next = (GdkWindow *)list->data;
- else
- next = b;
-
- if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
- event = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE);
- else
- event = NULL;
- if (event)
- {
- event->crossing.subwindow = gdk_window_ref (next);
- gdk_window_get_root_origin (win, &x_int, &y_int);
- event->crossing.x = x - x_int;
- event->crossing.y = y - y_int;
- event->crossing.x_root = x;
- event->crossing.y_root = y;
- event->crossing.mode = mode;
- if (non_linear)
- event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
- else
- event->crossing.detail = GDK_NOTIFY_VIRTUAL;
- event->crossing.focus = FALSE;
- event->crossing.state = my_mask;
- }
- }
- g_list_free (path);
- }
-
- if (!only_grabbed_window || (b == _gdk_fb_pointer_grab_window))
- event = gdk_event_make (b, GDK_ENTER_NOTIFY, TRUE);
- else
- event = NULL;
- if (event)
- {
- event->crossing.subwindow = NULL;
- gdk_window_get_root_origin (b, &x_int, &y_int);
- event->crossing.x = x - x_int;
- event->crossing.y = y - y_int;
- event->crossing.x_root = x;
- event->crossing.y_root = y;
- event->crossing.mode = mode;
- if (non_linear)
- event->crossing.detail = GDK_NOTIFY_NONLINEAR;
- else if (c==a)
- event->crossing.detail = GDK_NOTIFY_ANCESTOR;
- else
- event->crossing.detail = GDK_NOTIFY_INFERIOR;
- event->crossing.focus = FALSE;
- event->crossing.state = my_mask;
- }
-
- if ((mode != GDK_CROSSING_GRAB) &&
- (b != gdk_fb_mouse->prev_window))
- {
- gdk_window_unref (gdk_fb_mouse->prev_window);
- gdk_fb_mouse->prev_window = gdk_window_ref (b);
- }
-}
-
-static void
-handle_mouse_input(MouseDevice *mouse,
- gboolean got_motion)
-{
- GdkWindow *mousewin;
- GdkEvent *event;
- gint x, y;
- GdkWindow *win, *grabwin;
- guint state;
-
- if (_gdk_fb_pointer_grab_confine)
- mousewin = _gdk_fb_pointer_grab_confine;
- else
- mousewin = gdk_parent_root;
-
- if (mouse->x < GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_x)
- mouse->x = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_x;
- else if (mouse->x > (GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_x - 1))
- mouse->x = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_x - 1;
-
- if (mouse->y < GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_y)
- mouse->y = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_y;
- else if (mouse->y > (GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_y - 1))
- mouse->y = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_y - 1;
-
- if (!got_motion)
- return;
-
- win = gdk_window_at_pointer (NULL, NULL);
- if (_gdk_fb_pointer_grab_window_events)
- grabwin = _gdk_fb_pointer_grab_window_events;
- else
- grabwin = win;
-
- move_pointer (mouse, grabwin);
-
- gdk_window_get_origin (grabwin, &x, &y);
- x = mouse->x - x;
- y = mouse->y - y;
-
-
- state = (mouse->button1_pressed?GDK_BUTTON1_MASK:0) |
- (mouse->button2_pressed?GDK_BUTTON2_MASK:0) |
- (mouse->button3_pressed?GDK_BUTTON3_MASK:0) |
- keyboard->modifier_state;
-
- event = gdk_event_make (grabwin, GDK_MOTION_NOTIFY, TRUE);
- if (event)
- {
- event->motion.x = x;
- event->motion.y = y;
- event->motion.state = state;
- event->motion.is_hint = FALSE;
- event->motion.device = gdk_core_pointer;
- event->motion.x_root = mouse->x;
- event->motion.y_root = mouse->y;
- event->motion.time = gdk_fb_get_time ();
- }
-
- if (win != mouse->prev_window)
- gdk_fb_window_send_crossing_events (win,
- GDK_CROSSING_NORMAL);
-
- input_activity ();
-}
-
-static gboolean
-pull_fidmour_packet (MouseDevice *mouse,
- gboolean *btn_down,
- gdouble *x,
- gdouble *y)
-{
- gboolean keep_reading = TRUE;
-
- while (keep_reading)
- {
- int n;
-
- n = read (mouse->fd, mouse->mouse_packet + mouse->packet_nbytes, 5 - mouse->packet_nbytes);
- if (n < 0)
- return FALSE;
- else if (n == 0)
- {
- g_error ("EOF on mouse device!");
- g_source_remove (mouse->fd_tag);
- return FALSE;
- }
-
- mouse->packet_nbytes += n;
-
- n = 0;
- if (!(mouse->mouse_packet[0] & 0x80))
- {
- int i;
- /* We haven't received any of the packet yet but there is no header at the beginning */
- for (i = 1; i < mouse->packet_nbytes; i++)
- {
- if (mouse->mouse_packet[i] & 0x80)
- {
- n = i;
- break;
- }
- }
- }
- else if (mouse->packet_nbytes > 1 &&
- ((mouse->mouse_packet[0] & 0x90) == 0x90))
- {
- /* eat the 0x90 and following byte, no clue what it's for */
- n = 2;
- }
- else if (mouse->packet_nbytes == 5)
- {
- switch (mouse->mouse_packet[0] & 0xF)
- {
- case 2:
- *btn_down = 0;
- break;
- case 1:
- case 0:
- *btn_down = 1;
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- *x = mouse->mouse_packet[1] + (mouse->mouse_packet[2] << 7);
- if (*x > 8192)
- *x -= 16384;
- *y = mouse->mouse_packet[3] + (mouse->mouse_packet[4] << 7);
- if (*y > 8192)
- *y -= 16384;
- /* Now map touchscreen coords to screen coords */
- *x *= ((double)gdk_display->modeinfo.xres)/4096.0;
- *y *= ((double)gdk_display->modeinfo.yres)/4096.0;
- n = 5;
- keep_reading = FALSE;
- }
-
- if (n)
- {
- memmove (mouse->mouse_packet, mouse->mouse_packet+n, mouse->packet_nbytes-n);
- mouse->packet_nbytes -= n;
- }
- }
-
- return TRUE;
-}
-
-static gboolean
-handle_input_fidmour (GIOChannel *gioc,
- GIOCondition cond,
- gpointer data)
-{
- MouseDevice *mouse = data;
- gdouble x, y, oldx, oldy;
- gboolean got_motion = FALSE;
- gboolean btn_down;
- guint32 the_time;
-
- the_time = gdk_fb_get_time ();
-
- oldx = mouse->x;
- oldy = mouse->y;
- while (pull_fidmour_packet (mouse, &btn_down, &x, &y))
- {
- if (fabs(x - mouse->x) >= 1.0 || fabs(x - mouse->y) >= 1.0)
- {
- got_motion = TRUE;
- mouse->x = x;
- mouse->y = y;
- }
-
- if (btn_down != mouse->button1_pressed)
- {
- if (got_motion)
- {
- handle_mouse_input (mouse, TRUE);
- got_motion = FALSE;
- }
-
- mouse->button1_pressed = btn_down;
- send_button_event (mouse, 1, btn_down, the_time);
- }
- }
-
- if (got_motion)
- handle_mouse_input (mouse, TRUE);
-
- return TRUE;
-}
-
-static gboolean
-handle_input_ps2 (GIOChannel *gioc,
- GIOCondition cond,
- gpointer data)
-{
- MouseDevice *mouse = data;
- int n, dx=0, dy=0;
- gboolean new_button1, new_button2, new_button3;
- guint32 the_time;
- gboolean got_motion = FALSE;
- guchar *buf;
-
- the_time = gdk_fb_get_time ();
-
- while (1) /* Go through as many mouse events as we can */
- {
- n = read (mouse->fd, mouse->mouse_packet + mouse->packet_nbytes, 3 - mouse->packet_nbytes);
- if (n<=0) /* error or nothing to read */
- break;
-
- mouse->packet_nbytes += n;
-
- if (mouse->packet_nbytes < 3) /* Mouse packet not finished */
- break;
-
- mouse->packet_nbytes = 0;
-
- /* Finished reading a packet */
- buf = mouse->mouse_packet;
-
- new_button1 = (buf[0] & 1) && 1;
- new_button3 = (buf[0] & 2) && 1;
- new_button2 = (buf[0] & 4) && 1;
-
- if (got_motion &&
- (new_button1 != mouse->button1_pressed ||
- new_button2 != mouse->button2_pressed ||
- new_button3 != mouse->button3_pressed))
- {
- /* If a mouse button state changes we need to get correct ordering with enter/leave events,
- so push those out via handle_mouse_input */
- got_motion = FALSE;
- handle_mouse_input (mouse, TRUE);
- }
-
- if (new_button1 != mouse->button1_pressed)
- {
- mouse->button1_pressed = new_button1;
- send_button_event (mouse, 1, new_button1, the_time);
- }
-
- if (new_button2 != mouse->button2_pressed)
- {
- mouse->button2_pressed = new_button2;
- send_button_event (mouse, 2, new_button2, the_time);
- }
-
- if (new_button3 != mouse->button3_pressed)
- {
- mouse->button3_pressed = new_button3;
- send_button_event (mouse, 3, new_button3, the_time);
- }
-
- if (buf[1] != 0)
- dx = ((buf[0] & 0x10) ? ((gint)buf[1])-256 : buf[1]);
- else
- dx = 0;
- if (buf[2] != 0)
- dy = -((buf[0] & 0x20) ? ((gint)buf[2])-256 : buf[2]);
- else
- dy = 0;
-
- mouse->x += dx;
- mouse->y += dy;
- if (dx || dy)
- got_motion = TRUE;
- }
-
- if (got_motion)
- handle_mouse_input (mouse, TRUE);
-
- return TRUE;
-}
-
-static gboolean
-handle_input_ms (GIOChannel *gioc,
- GIOCondition cond,
- gpointer data)
-{
- MouseDevice *mouse = data;
- guchar byte1, byte2, byte3;
- int n, dx=0, dy=0;
- gboolean new_button1, new_button2, new_button3;
- guint32 the_time;
-
- the_time = gdk_fb_get_time ();
-
- n = read (mouse->fd, &byte1, 1);
- if ( (n!=1) || (byte1 & 0x40) != 0x40)
- return TRUE;
-
- n = read (mouse->fd, &byte2, 1);
- if ( (n!=1) || (byte2 & 0x40) != 0x00)
- return TRUE;
-
- n = read (mouse->fd, &byte3, 1);
- if (n!=1)
- return TRUE;
-
- new_button1 = (byte1 & 0x20) && 1;
- new_button2 = (byte1 & 0x10) && 1;
- new_button3 = 0;
-
- if (new_button1 != mouse->button1_pressed)
- {
- mouse->button1_pressed = new_button1;
- send_button_event (mouse, 1, new_button1, the_time);
- }
-
- if (new_button2 != mouse->button2_pressed)
- {
- mouse->button2_pressed = new_button2;
- send_button_event (mouse, 2, new_button2, the_time);
- }
-
- if (new_button3 != mouse->button3_pressed)
- {
- mouse->button3_pressed = new_button3;
- send_button_event (mouse, 3, new_button3, the_time);
- }
-
- dx = (signed char)(((byte1 & 0x03) << 6) | (byte2 & 0x3F));
- dy = (signed char)(((byte1 & 0x0C) << 4) | (byte3 & 0x3F));
-
- mouse->x += dx;
- mouse->y += dy;
-
- if (dx || dy)
- handle_mouse_input (mouse, TRUE);
-
- return TRUE;
-}
-
-static MouseDevice *
-mouse_open(void)
-{
- MouseDevice *retval;
- guchar buf[7];
- int i = 0;
- GIOChannel *gioc;
- char *mousedev, *ctmp;
- int mode;
- struct termios tty;
- enum { PS2_MOUSE, FIDMOUR_MOUSE, MS_MOUSE, UNKNOWN_MOUSE } type;
- int flags;
- fd_set fds;
- char c;
- struct timeval tv;
-
- retval = g_new0 (MouseDevice, 1);
- retval->fd = -1;
- mode = O_RDWR;
- ctmp = getenv ("GDK_MOUSETYPE");
- if (ctmp)
- {
- if (!strcmp (ctmp, "fidmour"))
- type = FIDMOUR_MOUSE;
- else if (!strcmp (ctmp, "ps2"))
- type = PS2_MOUSE;
- else if (!strcmp (ctmp, "ms"))
- type = MS_MOUSE;
- else
- {
- g_print ("Unknown mouse type %s\n", ctmp);
- type = UNKNOWN_MOUSE;
- }
- }
- else
- type = PS2_MOUSE;
-
- switch (type)
- {
- case PS2_MOUSE:
- mousedev = "/dev/psaux";
- mode = O_RDWR;
- break;
- case MS_MOUSE:
- mousedev = "/dev/ttyS0";
- mode = O_RDWR;
- break;
- case FIDMOUR_MOUSE:
- mousedev = "/dev/fidmour";
- mode = O_RDONLY;
- break;
- default:
- goto error;
- break;
- }
-
- ctmp = getenv ("GDK_MOUSEDEV");
- if (ctmp)
- mousedev = ctmp;
-
- /* Use nonblocking mode to open, to not hang on device */
- retval->fd = open (mousedev, mode | O_NONBLOCK);
- if (retval->fd < 0)
- goto error;
-
- flags = fcntl (retval->fd, F_GETFL);
- fcntl (retval->fd, F_SETFL, flags & ~O_NONBLOCK);
-
- switch (type)
- {
- case PS2_MOUSE:
- /* From xf86_Mouse.c */
- buf[i++] = 230; /* 1:1 scaling */
- buf[i++] = 244; /* enable mouse */
- buf[i++] = 243; /* Sample rate */
- buf[i++] = 200;
- buf[i++] = 232; /* device resolution */
- buf[i++] = 1;
- write (retval->fd, buf, i);
- fcntl (retval->fd, F_SETFL, O_RDWR|O_NONBLOCK);
-
- usleep (10000); /* sleep 10 ms, then read whatever junk we can get from the mouse, in a vain attempt
- to get synchronized with the event stream */
- while ((i = read (retval->fd, buf, sizeof(buf))) > 0)
- g_print ("Got %d bytes of junk from psaux\n", i);
-
- gioc = g_io_channel_unix_new (retval->fd);
- retval->fd_tag = g_io_add_watch (gioc, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_input_ps2, retval);
- break;
-
- case MS_MOUSE:
- /* Read all data from fd: */
- FD_ZERO (&fds);
- FD_SET (retval->fd, &fds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- while (select (retval->fd+1, &fds, NULL, NULL, &tv) > 0) {
- FD_ZERO (&fds);
- FD_SET (retval->fd, &fds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- read (retval->fd, &c, 1);
- }
-
- tcgetattr (retval->fd, &tty);
- tty.c_iflag = IGNBRK | IGNPAR;
- tty.c_cflag = CREAD|CLOCAL|HUPCL|CS7|B1200;
- tty.c_oflag = 0;
- tty.c_lflag = 0;
- tty.c_line = 0;
- tty.c_cc[VTIME] = 0;
- tty.c_cc[VMIN] = 1;
- tcsetattr (retval->fd, TCSAFLUSH, &tty);
-
- write (retval->fd, "*n", 2);
-
- gioc = g_io_channel_unix_new (retval->fd);
- retval->fd_tag = g_io_add_watch (gioc, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_input_ms, retval);
- break;
-
- case FIDMOUR_MOUSE:
- fcntl (retval->fd, F_SETFL, O_RDONLY|O_NONBLOCK);
- gioc = g_io_channel_unix_new (retval->fd);
- /* We set the priority lower here because otherwise it will flood out all the other stuff */
- retval->fd_tag = g_io_add_watch_full (gioc, G_PRIORITY_DEFAULT, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- handle_input_fidmour, retval, NULL);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- retval->x = gdk_display->modeinfo.xres >> 1;
- retval->y = gdk_display->modeinfo.yres >> 1;
-
- return retval;
-
- error:
- /* No errors allowed once fd_tag is added */
- g_warning ("Failed to open mouse device\n");
- if (retval->fd >= 0)
- close (retval->fd);
- g_free (retval);
- return NULL;
-}
-
void
gdk_input_init (void)
{
@@ -1085,21 +101,7 @@ gdk_input_init (void)
gdk_input_ignore_core = FALSE;
- gdk_fb_mouse = mouse_open ();
-}
-
-void
-gdk_input_get_mouseinfo (gint *x,
- gint *y,
- GdkModifierType *mask)
-{
- *x = gdk_fb_mouse->x;
- *y = gdk_fb_mouse->y;
- *mask =
- (gdk_fb_mouse->button1_pressed?GDK_BUTTON1_MASK:0) |
- (gdk_fb_mouse->button2_pressed?GDK_BUTTON2_MASK:0) |
- (gdk_fb_mouse->button3_pressed?GDK_BUTTON3_MASK:0) |
- keyboard->modifier_state;
+ gdk_fb_mouse_open ();
}
GdkWindow *
diff --git a/gdk/linux-fb/gdkmain-fb.c b/gdk/linux-fb/gdkmain-fb.c
index 8a7d258f79..c8f8d12a9e 100644
--- a/gdk/linux-fb/gdkmain-fb.c
+++ b/gdk/linux-fb/gdkmain-fb.c
@@ -966,10 +966,9 @@ gdk_event_make (GdkWindow *window,
if (evmask & (GDK_BUTTON1_MOTION_MASK|GDK_BUTTON2_MOTION_MASK|GDK_BUTTON3_MOTION_MASK))
{
- gint x, y;
GdkModifierType mask;
- gdk_input_get_mouseinfo (&x, &y, &mask);
+ gdk_mouse_get_info (NULL, NULL, &mask);
if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
diff --git a/gdk/linux-fb/gdkmouse-fb.c b/gdk/linux-fb/gdkmouse-fb.c
new file mode 100644
index 0000000000..3a149a28da
--- /dev/null
+++ b/gdk/linux-fb/gdkmouse-fb.c
@@ -0,0 +1,618 @@
+#include <gdk/gdk.h>
+#include <gdk/gdkinternals.h>
+#include "gdkprivate-fb.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <math.h>
+
+typedef struct _GdkFBMouse GdkFBMouse;
+typedef struct _GdkFBMouseDevice GdkFBMouseDevice;
+
+struct _GdkFBMouse {
+ gint fd; /* Set by open */
+
+ /* These are written to by parse_packet */
+ gdouble x, y;
+ gboolean button_pressed[3];
+
+ guchar mouse_packet[5]; /* read by parse_packet */
+ gint packet_nbytes;
+
+ gboolean click_grab;
+ GIOChannel *io;
+ gint io_tag;
+
+ GdkFBMouseDevice *dev;
+};
+
+static GdkFBMouse *gdk_fb_mouse = NULL;
+
+void
+gdk_mouse_get_info (gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ if (x)
+ *x = gdk_fb_mouse->x;
+ if (y)
+ *y = gdk_fb_mouse->y;
+ if (mask)
+ *mask =
+ (gdk_fb_mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
+ (gdk_fb_mouse->button_pressed[1]?GDK_BUTTON2_MASK:0) |
+ (gdk_fb_mouse->button_pressed[2]?GDK_BUTTON3_MASK:0) |
+ /*keyboard->modifier_state*/0; //TODO
+}
+
+static void
+handle_mouse_movement(GdkFBMouse *mouse)
+{
+ GdkWindow *mousewin;
+ GdkEvent *event;
+ gint x, y;
+ GdkWindow *win, *grabwin;
+ guint state;
+ GdkDrawableFBData *mousewin_private;
+
+ if (_gdk_fb_pointer_grab_confine)
+ mousewin = _gdk_fb_pointer_grab_confine;
+ else
+ mousewin = gdk_parent_root;
+
+ mousewin_private = GDK_DRAWABLE_IMPL_FBDATA (mousewin);
+
+ if (mouse->x < mousewin_private->llim_x)
+ mouse->x = mousewin_private->llim_x;
+ else if (mouse->x > mousewin_private->lim_x - 1)
+ mouse->x = mousewin_private->lim_x - 1;
+
+ if (mouse->y < mousewin_private->llim_y)
+ mouse->y = mousewin_private->llim_y;
+ else if (mouse->y > mousewin_private->lim_y - 1)
+ mouse->y = mousewin_private->lim_y - 1;
+
+ win = gdk_window_at_pointer (NULL, NULL);
+ if (_gdk_fb_pointer_grab_window_events)
+ grabwin = _gdk_fb_pointer_grab_window_events;
+ else
+ grabwin = win;
+
+ gdk_fb_cursor_move (mouse->x, mouse->y, grabwin);
+
+ gdk_window_get_origin (grabwin, &x, &y);
+ x = mouse->x - x;
+ y = mouse->y - y;
+
+ state = (mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
+ (mouse->button_pressed[1]?GDK_BUTTON2_MASK:0) |
+ (mouse->button_pressed[2]?GDK_BUTTON3_MASK:0) |
+ /*keyboard->modifier_state*/0; // TODO
+
+ event = gdk_event_make (grabwin, GDK_MOTION_NOTIFY, TRUE);
+ if (event)
+ {
+ event->motion.x = x;
+ event->motion.y = y;
+ event->motion.state = state;
+ event->motion.is_hint = FALSE;
+ event->motion.device = gdk_core_pointer;
+ event->motion.x_root = mouse->x;
+ event->motion.y_root = mouse->y;
+ }
+
+ gdk_fb_window_send_crossing_events (win, GDK_CROSSING_NORMAL);
+}
+
+static void
+send_button_event (GdkFBMouse *mouse,
+ guint button,
+ gboolean press_event)
+{
+ GdkEvent *event;
+ gint x, y, i;
+ GdkWindow *window;
+ int nbuttons;
+
+ if (_gdk_fb_pointer_grab_window_events)
+ window = _gdk_fb_pointer_grab_window_events;
+ else
+ window = gdk_window_at_pointer(NULL, NULL);
+
+ event = gdk_event_make (window, press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE, FALSE);
+
+ if (event)
+ {
+ gdk_window_get_origin (window, &x, &y);
+ x = mouse->x - x;
+ y = mouse->y - y;
+
+ event->button.x = x;
+ event->button.y = y;
+ event->button.button = button;
+ event->button.state = (mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
+ (mouse->button_pressed[1] ? GDK_BUTTON2_MASK : 0) |
+ (mouse->button_pressed[2] ? GDK_BUTTON3_MASK : 0) |
+ (1 << (button + 8)) /* badhack */ |
+ /*keyboard->modifier_state*/0; // TODO
+ event->button.device = gdk_core_pointer;
+ event->button.x_root = mouse->x;
+ event->button.y_root = mouse->y;
+
+ gdk_event_queue_append (event);
+
+ /* For double-clicks */
+ if (press_event)
+ gdk_event_button_generate (event);
+ }
+
+ nbuttons = 0;
+ for (i=0;i<3;i++)
+ if (mouse->button_pressed[i])
+ nbuttons++;
+
+ /* Handle implicit button grabs: */
+ if (press_event && nbuttons == 1)
+ {
+ gdk_fb_pointer_grab (window, FALSE,
+ gdk_window_get_events (window),
+ NULL, NULL,
+ GDK_CURRENT_TIME, TRUE);
+ mouse->click_grab = TRUE;
+ }
+ else if (!press_event && nbuttons == 0 && mouse->click_grab)
+ {
+ gdk_fb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
+ mouse->click_grab = FALSE;
+ }
+}
+
+/******************************************************
+ ************ Device specific mouse code **************
+ ******************************************************/
+
+struct _GdkFBMouseDevice {
+ char *name;
+ gint packet_size;
+ gboolean (*open)(GdkFBMouse *mouse);
+ void (*close)(GdkFBMouse *mouse);
+ gboolean (*parse_packet)(GdkFBMouse *mouse, gboolean *got_motion);
+};
+
+static gboolean handle_mouse_io (GIOChannel *gioc,
+ GIOCondition cond,
+ gpointer data);
+static gboolean gdk_fb_mouse_ps2_open (GdkFBMouse *mouse);
+static void gdk_fb_mouse_ps2_close (GdkFBMouse *mouse);
+static gboolean gdk_fb_mouse_ps2_packet (GdkFBMouse *mouse,
+ gboolean *got_motion);
+static gboolean gdk_fb_mouse_ms_open (GdkFBMouse *mouse);
+static void gdk_fb_mouse_ms_close (GdkFBMouse *mouse);
+static gboolean gdk_fb_mouse_ms_packet (GdkFBMouse *mouse,
+ gboolean *got_motion);
+static gboolean gdk_fb_mouse_fidmour_open (GdkFBMouse *mouse);
+static void gdk_fb_mouse_fidmour_close (GdkFBMouse *mouse);
+static gboolean gdk_fb_mouse_fidmour_packet (GdkFBMouse *mouse,
+ gboolean *got_motion);
+
+static GdkFBMouseDevice mouse_devs[] =
+{
+ { "ps2",
+ 3,
+ gdk_fb_mouse_ps2_open,
+ gdk_fb_mouse_ps2_close,
+ gdk_fb_mouse_ps2_packet
+ },
+ { "ms",
+ 3,
+ gdk_fb_mouse_ms_open,
+ gdk_fb_mouse_ms_close,
+ gdk_fb_mouse_ms_packet
+ },
+ { "fidmour",
+ 5,
+ gdk_fb_mouse_fidmour_open,
+ gdk_fb_mouse_fidmour_close,
+ gdk_fb_mouse_fidmour_packet
+ }
+};
+
+
+gboolean
+gdk_fb_mouse_open (void)
+{
+ GdkFBMouse *mouse;
+ GdkFBMouseDevice *device;
+ char *mouse_type;
+ int i;
+
+ mouse = g_new0 (GdkFBMouse, 1);
+ mouse->fd = -1;
+ mouse_type = getenv ("GDK_MOUSETYPE");
+ if (!mouse_type)
+ mouse_type = "ps2";
+
+ for (i=0;i<G_N_ELEMENTS(mouse_devs);i++)
+ {
+ if (g_strcasecmp(mouse_type, mouse_devs[i].name)==0)
+ break;
+ }
+
+ if (i == G_N_ELEMENTS(mouse_devs))
+ {
+ g_warning ("No mouse driver of type %s found\n", mouse_type);
+ return FALSE;
+ }
+
+ device = &mouse_devs[i];
+
+ mouse->dev = device;
+
+ mouse->x = gdk_display->modeinfo.xres / 2;
+ mouse->y = gdk_display->modeinfo.yres / 2;
+
+ if (!device->open(mouse))
+ {
+ g_warning ("Mouse driver open failed\n");
+ g_free (mouse);
+ return FALSE;
+ }
+
+ mouse->io = g_io_channel_unix_new (mouse->fd);
+ mouse->io_tag = g_io_add_watch (mouse->io, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_mouse_io, mouse);
+
+ gdk_fb_mouse = mouse;
+ return TRUE;
+}
+
+void
+gdk_fb_mouse_close (void)
+{
+ g_source_remove (gdk_fb_mouse->io_tag);
+ gdk_fb_mouse->dev->close(gdk_fb_mouse);
+ g_io_channel_unref (gdk_fb_mouse->io);
+ g_free (gdk_fb_mouse);
+}
+
+static gboolean
+handle_mouse_io (GIOChannel *gioc,
+ GIOCondition cond,
+ gpointer data)
+{
+ GdkFBMouse *mouse = (GdkFBMouse *)data;
+ GdkFBMouseDevice *dev = mouse->dev;
+ gboolean got_motion;
+ gint n;
+
+ got_motion = FALSE;
+
+ while (1)
+ {
+ n = read (mouse->fd, mouse->mouse_packet + mouse->packet_nbytes, dev->packet_size - mouse->packet_nbytes);
+ if (n<=0) /* error or nothing to read */
+ break;
+
+ mouse->packet_nbytes += n;
+
+ if (mouse->packet_nbytes == dev->packet_size)
+ {
+ if (dev->parse_packet (mouse, &got_motion))
+ mouse->packet_nbytes = 0;
+ }
+ }
+
+ if (got_motion)
+ handle_mouse_movement (mouse);
+
+ return TRUE;
+}
+
+static gint
+gdk_fb_mouse_dev_open (char *devname, gint mode)
+{
+ gint fd;
+
+ /* Use nonblocking mode to open, to not hang on device */
+ fd = open (devname, mode | O_NONBLOCK);
+ return fd;
+}
+
+static gboolean
+gdk_fb_mouse_ps2_open (GdkFBMouse *mouse)
+{
+ gint fd;
+ guchar buf[7];
+ int i = 0;
+
+ fd = gdk_fb_mouse_dev_open ("/dev/psaux", O_RDWR);
+ if (fd < 0)
+ return FALSE;
+
+ /* From xf86_Mouse.c */
+ buf[i++] = 230; /* 1:1 scaling */
+ buf[i++] = 244; /* enable mouse */
+ buf[i++] = 243; /* Sample rate */
+ buf[i++] = 200;
+ buf[i++] = 232; /* device resolution */
+ buf[i++] = 1;
+
+ write (fd, buf, i);
+
+ usleep (10000); /* sleep 10 ms, then read whatever junk we can get from the mouse, in a vain attempt
+ to get synchronized with the event stream */
+
+ while ((i = read (fd, buf, sizeof(buf))) > 0)
+ g_print ("Got %d bytes of junk from psaux\n", i);
+
+ mouse->fd = fd;
+ return TRUE;
+}
+
+static void
+gdk_fb_mouse_ps2_close (GdkFBMouse *mouse)
+{
+ close (mouse->fd);
+}
+
+static gboolean
+gdk_fb_mouse_ps2_packet (GdkFBMouse *mouse, gboolean *got_motion)
+{
+ int dx=0, dy=0;
+ gboolean new_button1, new_button2, new_button3;
+ guchar *buf;
+
+ buf = mouse->mouse_packet;
+
+ new_button1 = (buf[0] & 1) && 1;
+ new_button3 = (buf[0] & 2) && 1;
+ new_button2 = (buf[0] & 4) && 1;
+
+
+ if (*got_motion &&
+ (new_button1 != mouse->button_pressed[0] ||
+ new_button2 != mouse->button_pressed[1] ||
+ new_button3 != mouse->button_pressed[2]))
+ {
+ /* If a mouse button state changes we need to get correct ordering with enter/leave events,
+ so push those out via handle_mouse_input */
+ *got_motion = FALSE;
+ handle_mouse_movement (mouse);
+ }
+
+ if (new_button1 != mouse->button_pressed[0])
+ {
+ mouse->button_pressed[0] = new_button1;
+ send_button_event (mouse, 1, new_button1);
+ }
+
+ if (new_button2 != mouse->button_pressed[1])
+ {
+ mouse->button_pressed[1] = new_button2;
+ send_button_event (mouse, 2, new_button2);
+ }
+
+ if (new_button3 != mouse->button_pressed[2])
+ {
+ mouse->button_pressed[2] = new_button3;
+ send_button_event (mouse, 3, new_button3);
+ }
+
+ if (buf[1] != 0)
+ dx = ((buf[0] & 0x10) ? ((gint)buf[1])-256 : buf[1]);
+ else
+ dx = 0;
+ if (buf[2] != 0)
+ dy = -((buf[0] & 0x20) ? ((gint)buf[2])-256 : buf[2]);
+ else
+ dy = 0;
+
+ mouse->x += dx;
+ mouse->y += dy;
+
+ if (dx || dy)
+ *got_motion = TRUE;
+
+ return TRUE;
+}
+
+
+static gboolean
+gdk_fb_mouse_ms_open (GdkFBMouse *mouse)
+{
+ gint fd;
+ gint i;
+ guchar buf[7];
+ struct termios tty;
+
+ fd = gdk_fb_mouse_dev_open ("/dev/ttyS0", O_RDWR);
+ if (fd < 0)
+ return FALSE;
+
+ while ((i = read (fd, buf, sizeof(buf))) > 0)
+ g_print ("Got %d bytes of junk from psaux\n", i);
+
+ tcgetattr (fd, &tty);
+ tty.c_iflag = IGNBRK | IGNPAR;
+ tty.c_cflag = CREAD|CLOCAL|HUPCL|CS7|B1200;
+ tty.c_oflag = 0;
+ tty.c_lflag = 0;
+ tty.c_line = 0;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+ tcsetattr (fd, TCSAFLUSH, &tty);
+
+ write (fd, "*n", 2);
+
+ mouse->fd = fd;
+ return TRUE;
+}
+
+static void
+gdk_fb_mouse_ms_close (GdkFBMouse *mouse)
+{
+ close (mouse->fd);
+}
+
+static gboolean
+gdk_fb_mouse_ms_packet (GdkFBMouse *mouse,
+ gboolean *got_motion)
+{
+ int dx=0, dy=0;
+ gboolean new_button1, new_button2, new_button3;
+ guchar *buf;
+
+ buf = mouse->mouse_packet;
+
+ new_button1 = (buf[0] & 0x20) && 1;
+ new_button2 = (buf[1] & 0x10) && 1;
+ new_button3 = 0;
+
+ if (*got_motion &&
+ (new_button1 != mouse->button_pressed[0] ||
+ new_button2 != mouse->button_pressed[1] ||
+ new_button3 != mouse->button_pressed[2]))
+ {
+ /* If a mouse button state changes we need to get correct ordering with enter/leave events,
+ so push those out via handle_mouse_input */
+ *got_motion = FALSE;
+ handle_mouse_movement (mouse);
+ }
+
+ if (new_button1 != mouse->button_pressed[0])
+ {
+ mouse->button_pressed[0] = new_button1;
+ send_button_event (mouse, 1, new_button1);
+ }
+
+ if (new_button2 != mouse->button_pressed[1])
+ {
+ mouse->button_pressed[1] = new_button2;
+ send_button_event (mouse, 2, new_button2);
+ }
+
+ if (new_button3 != mouse->button_pressed[2])
+ {
+ mouse->button_pressed[2] = new_button3;
+ send_button_event (mouse, 3, new_button3);
+ }
+
+ dx = (signed char)(((buf[0] & 0x03) << 6) | (buf[1] & 0x3F));
+ dy = (signed char)(((buf[0] & 0x0C) << 4) | (buf[2] & 0x3F));
+
+ mouse->x += dx;
+ mouse->y += dy;
+
+ if (dx || dy)
+ *got_motion = TRUE;
+
+ return TRUE;
+}
+
+static gboolean
+gdk_fb_mouse_fidmour_open (GdkFBMouse *mouse)
+{
+ gint fd;
+
+ fd = gdk_fb_mouse_dev_open ("/dev/fidmour", O_RDONLY);
+ if (fd < 0)
+ return FALSE;
+
+ mouse->fd = fd;
+ return TRUE;
+}
+
+static void
+gdk_fb_mouse_fidmour_close (GdkFBMouse *mouse)
+{
+ close (mouse->fd);
+}
+
+static gboolean
+gdk_fb_mouse_fidmour_packet (GdkFBMouse *mouse,
+ gboolean *got_motion)
+{
+ int n;
+ gboolean btn_down = 0;
+ gdouble x = 0.0, y = 0.0;
+
+ n = 0;
+ if (!(mouse->mouse_packet[0] & 0x80))
+ {
+ int i;
+ /* We haven't received any of the packet yet but there is no header at the beginning */
+ for (i = 1; i < mouse->packet_nbytes; i++)
+ {
+ if (mouse->mouse_packet[i] & 0x80)
+ {
+ n = i;
+ break;
+ }
+ }
+ }
+ else if (mouse->packet_nbytes > 1 &&
+ ((mouse->mouse_packet[0] & 0x90) == 0x90))
+ {
+ /* eat the 0x90 and following byte, no clue what it's for */
+ n = 2;
+ }
+ else
+ {
+ switch (mouse->mouse_packet[0] & 0xF)
+ {
+ case 2:
+ btn_down = 0;
+ break;
+ case 1:
+ case 0:
+ btn_down = 1;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ x = mouse->mouse_packet[1] + (mouse->mouse_packet[2] << 7);
+ if (x > 8192)
+ x -= 16384;
+ y = mouse->mouse_packet[3] + (mouse->mouse_packet[4] << 7);
+ if (y > 8192)
+ y -= 16384;
+ /* Now map touchscreen coords to screen coords */
+ x *= ((double)gdk_display->modeinfo.xres)/4096.0;
+ y *= ((double)gdk_display->modeinfo.yres)/4096.0;
+ }
+
+ if (n)
+ {
+ memmove (mouse->mouse_packet, mouse->mouse_packet+n, mouse->packet_nbytes-n);
+ mouse->packet_nbytes -= n;
+ return FALSE;
+ }
+
+ if (btn_down != mouse->button_pressed[0])
+ {
+ if (*got_motion)
+ {
+ /* If a mouse button state changes we need to get correct
+ ordering with enter/leave events, so push those out
+ via handle_mouse_input */
+ *got_motion = FALSE;
+ handle_mouse_movement (mouse);
+ }
+
+ mouse->button_pressed[0] = btn_down;
+ send_button_event (mouse, 1, btn_down);
+ }
+
+ if (fabs(x - mouse->x) >= 1.0 || fabs(x - mouse->y) >= 1.0)
+ {
+ *got_motion = TRUE;
+ mouse->x = x;
+ mouse->y = y;
+ }
+
+ return TRUE;
+}
diff --git a/gdk/linux-fb/gdkprivate-fb.h b/gdk/linux-fb/gdkprivate-fb.h
index 5f830e7dfe..06d026ca94 100644
--- a/gdk/linux-fb/gdkprivate-fb.h
+++ b/gdk/linux-fb/gdkprivate-fb.h
@@ -264,8 +264,6 @@ void gdk_window_invalidate_region_clear (GdkWindow *window,
GdkRegion *region);
void gdk_window_invalidate_rect_clear (GdkWindow *window,
GdkRectangle *rect);
-GdkWindow *gdk_fb_find_common_ancestor (GdkWindow *win1,
- GdkWindow *win2);
GdkGC * _gdk_fb_gc_new (GdkDrawable *drawable,
GdkGCValues *values,
@@ -386,13 +384,18 @@ void gdk_fb_cursor_unhide(void);
void gdk_fb_cursor_reset(void);
void gdk_fb_cursor_hide(void);
void gdk_fb_redraw_all(void);
+void gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window);
-void gdk_input_get_mouseinfo (gint *x,
- gint *y,
- GdkModifierType *mask);
void gdk_fb_window_send_crossing_events (GdkWindow *dest,
GdkCrossingMode mode);
+gboolean gdk_fb_mouse_open (void);
+void gdk_fb_mouse_close (void);
+void gdk_mouse_get_info (gint *x,
+ gint *y,
+ GdkModifierType *mask);
+
+
#define PANGO_TYPE_FB_FONT (pango_fb_font_get_type ())
#define PANGO_FB_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FB_FONT, PangoFBFont))
diff --git a/gdk/linux-fb/gdkwindow-fb.c b/gdk/linux-fb/gdkwindow-fb.c
index b4b691d039..0d03563a8e 100644
--- a/gdk/linux-fb/gdkwindow-fb.c
+++ b/gdk/linux-fb/gdkwindow-fb.c
@@ -34,6 +34,8 @@
#include <limits.h>
+/* Global variables: */
+static GdkWindow *gdk_fb_window_containing_pointer = NULL;
static gpointer parent_class = NULL;
static void recompute_drawable (GdkDrawable *drawable);
@@ -438,7 +440,7 @@ gdk_fb_redraw_all (void)
gdk_window_process_all_updates ();
}
-GdkWindow *
+static GdkWindow *
gdk_fb_find_common_ancestor (GdkWindow *win1,
GdkWindow *win2)
{
@@ -475,6 +477,180 @@ gdk_fb_find_common_ancestor (GdkWindow *win1,
}
void
+gdk_fb_window_send_crossing_events (GdkWindow *dest,
+ GdkCrossingMode mode)
+{
+ GdkWindow *c;
+ GdkWindow *win, *last, *next;
+ GdkEvent *event;
+ gint x, y, x_int, y_int;
+ GdkModifierType my_mask;
+ GList *path, *list;
+ gboolean non_linear;
+ gboolean only_grabbed_window;
+ GdkWindow *a;
+ GdkWindow *b;
+
+ if ((mode == GDK_CROSSING_NORMAL) &&
+ (dest == gdk_fb_window_containing_pointer))
+ return;
+
+ if (gdk_fb_window_containing_pointer == NULL)
+ gdk_fb_window_containing_pointer = gdk_window_ref (gdk_parent_root);
+
+ if (mode == GDK_CROSSING_UNGRAB)
+ a = _gdk_fb_pointer_grab_window;
+ else
+ a = gdk_fb_window_containing_pointer;
+ b = dest;
+
+ /* When grab in progress only send normal crossing events about
+ * the grabbed window.
+ */
+ only_grabbed_window = (_gdk_fb_pointer_grab_window_events != NULL) &&
+ (mode == GDK_CROSSING_NORMAL);
+
+ if (a==b)
+ return;
+
+ gdk_mouse_get_info (&x, &y, &my_mask);
+
+ c = gdk_fb_find_common_ancestor (a, b);
+
+ non_linear = (c != a) && (c != b);
+
+ if (!only_grabbed_window || (a == _gdk_fb_pointer_grab_window))
+ event = gdk_event_make (a, GDK_LEAVE_NOTIFY, TRUE);
+ else
+ event = NULL;
+ if (event)
+ {
+ event->crossing.subwindow = NULL;
+ gdk_window_get_root_origin (a, &x_int, &y_int);
+ event->crossing.x = x - x_int;
+ event->crossing.y = y - y_int;
+ event->crossing.x_root = x;
+ event->crossing.y_root = y;
+ event->crossing.mode = mode;
+ if (non_linear)
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+ else if (c==a)
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ event->crossing.focus = FALSE;
+ event->crossing.state = my_mask;
+ }
+
+ /* Traverse up from a to (excluding) c */
+ if (c != a)
+ {
+ last = a;
+ win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
+ while (win != c)
+ {
+ if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
+ event = gdk_event_make (win, GDK_LEAVE_NOTIFY, TRUE);
+ else
+ event = NULL;
+ if (event)
+ {
+ event->crossing.subwindow = gdk_window_ref (last);
+ gdk_window_get_root_origin (win, &x_int, &y_int);
+ event->crossing.x = x - x_int;
+ event->crossing.y = y - y_int;
+ event->crossing.x_root = x;
+ event->crossing.y_root = y;
+ event->crossing.mode = mode;
+ if (non_linear)
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+ else
+ event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+ event->crossing.focus = FALSE;
+ event->crossing.state = my_mask;
+ }
+ last = win;
+ win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
+ }
+ }
+
+ /* Traverse down from c to b */
+ if (c != b)
+ {
+ path = NULL;
+ win = GDK_WINDOW( GDK_WINDOW_OBJECT (b)->parent);
+ while (win != c)
+ {
+ path = g_list_prepend (path, win);
+ win = GDK_WINDOW( GDK_WINDOW_OBJECT (win)->parent);
+ }
+
+ list = path;
+ while (list)
+ {
+ win = (GdkWindow *)list->data;
+ list = g_list_next (list);
+ if (list)
+ next = (GdkWindow *)list->data;
+ else
+ next = b;
+
+ if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
+ event = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE);
+ else
+ event = NULL;
+ if (event)
+ {
+ event->crossing.subwindow = gdk_window_ref (next);
+ gdk_window_get_root_origin (win, &x_int, &y_int);
+ event->crossing.x = x - x_int;
+ event->crossing.y = y - y_int;
+ event->crossing.x_root = x;
+ event->crossing.y_root = y;
+ event->crossing.mode = mode;
+ if (non_linear)
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+ else
+ event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+ event->crossing.focus = FALSE;
+ event->crossing.state = my_mask;
+ }
+ }
+ g_list_free (path);
+ }
+
+ if (!only_grabbed_window || (b == _gdk_fb_pointer_grab_window))
+ event = gdk_event_make (b, GDK_ENTER_NOTIFY, TRUE);
+ else
+ event = NULL;
+ if (event)
+ {
+ event->crossing.subwindow = NULL;
+ gdk_window_get_root_origin (b, &x_int, &y_int);
+ event->crossing.x = x - x_int;
+ event->crossing.y = y - y_int;
+ event->crossing.x_root = x;
+ event->crossing.y_root = y;
+ event->crossing.mode = mode;
+ if (non_linear)
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+ else if (c==a)
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ event->crossing.focus = FALSE;
+ event->crossing.state = my_mask;
+ }
+
+ if ((mode != GDK_CROSSING_GRAB) &&
+ (b != gdk_fb_window_containing_pointer))
+ {
+ gdk_window_unref (gdk_fb_window_containing_pointer);
+ gdk_fb_window_containing_pointer = gdk_window_ref (b);
+ }
+}
+
+void
gdk_window_show (GdkWindow *window)
{
GdkWindowObject *private;
@@ -1231,7 +1407,7 @@ gdk_window_get_pointer (GdkWindow *window,
window = gdk_parent_root;
gdk_window_get_root_origin (window, &x_int, &y_int);
- gdk_input_get_mouseinfo (&winx, &winy, &my_mask);
+ gdk_mouse_get_info (&winx, &winy, &my_mask);
winx -= x_int;
winy -= y_int;