Ticket #4021: touch-display.c

File touch-display.c, 4.9 KB (added by erikos, 12 years ago)

Example program from Carlos that listens for raw events (touch begin/update/end), uses XFixesHideCursor to hide the cursor on startup

Line 
1/* gcc -o touch-display `pkg-config --cflags --libs gtk+-3.0 gtk+-x11-3.0 xi` touch-display.c */
2#include <stdio.h>
3#include <gtk/gtk.h>
4#include <gdk/gdkx.h>
5#include <X11/extensions/XInput2.h>
6
7static GHashTable *coords = NULL;
8
9static gboolean
10window_draw_cb (GtkWidget *widget,
11                cairo_t   *cr,
12                gpointer   user_data)
13{
14  GHashTableIter iter;
15  GdkPoint *point;
16  gpointer data;
17
18  if (g_hash_table_size (coords) == 0)
19    {
20      cairo_move_to (cr, 0, 0);
21      cairo_rel_line_to (cr, 1, 0);
22      cairo_stroke (cr);
23      return TRUE;
24    }
25
26  g_hash_table_iter_init (&iter, coords);
27
28  cairo_save (cr);
29  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
30  cairo_paint (cr);
31  cairo_restore (cr);
32
33  while (g_hash_table_iter_next (&iter, NULL, &data))
34    {
35      point = data;
36
37      printf("===> draw points %d %d \n", point->x, point->y);
38      cairo_arc (cr, point->x, point->y,
39                 30, 0, 2 * G_PI);
40      cairo_set_source_rgba (cr, 1, 0, 0, 0.5);
41      cairo_fill (cr);
42    }
43
44  return TRUE;
45}
46
47static void
48raw_event_get_coords (XIRawEvent *raw,
49                      GdkScreen  *screen,
50                      GdkPoint   *point)
51{
52  if (raw->raw_values[0] != 0){
53    point->x = (raw->raw_values[0] / 1200) *
54      gdk_screen_get_width (screen);
55    printf("===> point-x %d %f \n", point->x, raw->raw_values[0]);
56  }
57  if (raw->raw_values[1] != 0){
58    point->y = (raw->raw_values[1] / 900) *
59      gdk_screen_get_height (screen);
60    printf("===> point-y %d %f \n", point->y, raw->raw_values[1]);
61  }
62}
63
64static GdkFilterReturn
65raw_event_filter (GdkXEvent *xevent,
66                  GdkEvent  *event,
67                  gpointer   user_data)
68{
69  GtkWidget *window = user_data;
70  XEvent *ev = xevent;
71  XIRawEvent *raw;
72  XIEvent *xiev;
73  GdkPoint *point = NULL;
74
75  if (ev->type != GenericEvent)
76    return GDK_FILTER_CONTINUE;
77
78  xiev = ev->xcookie.data;
79
80  switch (xiev->evtype)
81    {
82    case XI_RawTouchBegin:
83      raw = (XIRawEvent *) xiev;
84      point = g_new0 (GdkPoint, 1);
85      g_hash_table_insert (coords,
86                           GUINT_TO_POINTER (raw->detail),
87                           point);
88      printf("===> touch-begin %d %d \n", point->x, point->y);
89
90      /* Fall through */
91    case XI_RawTouchUpdate:
92      raw = (XIRawEvent *) xiev;
93
94      if (!point){
95        point = g_hash_table_lookup (coords,
96                                     GUINT_TO_POINTER (raw->detail));
97      }
98      if (!point)
99        return GDK_FILTER_REMOVE;
100
101      printf("===> touch-update %d %d \n", point->x, point->y);
102      raw_event_get_coords (raw,
103                            gtk_widget_get_screen (window),
104                            point);
105      gtk_widget_queue_draw (window);
106
107      return GDK_FILTER_REMOVE;
108    case XI_RawTouchEnd:
109
110      printf("===> touch-end \n");
111
112      raw = (XIRawEvent *) xiev;
113      g_hash_table_remove (coords, GUINT_TO_POINTER (raw->detail));
114      gtk_widget_queue_draw (window);
115
116      return GDK_FILTER_REMOVE;
117    default:
118      break;
119    }
120
121  return GDK_FILTER_CONTINUE;
122}
123
124int
125main (int argc, char *argv[])
126{
127  GdkRGBA transparent = { 0 };
128  XIEventMask mask;
129  guchar *evmask;
130  GtkWidget *window;
131  GdkScreen *screen;
132  cairo_region_t *region;
133  GdkCursor *cursor;
134  Display *xdisplay;
135  GdkDisplay *display;
136
137  gtk_init (NULL, NULL);
138
139  coords = g_hash_table_new_full (NULL, NULL, NULL,
140                                  (GDestroyNotify) g_free);
141
142  window = gtk_window_new (GTK_WINDOW_POPUP);
143  g_signal_connect (window, "draw",
144                    G_CALLBACK (window_draw_cb), NULL);
145
146  screen = gtk_widget_get_screen (window);
147  gtk_widget_set_visual (window,
148                         gdk_screen_get_rgba_visual (screen));
149
150  gtk_widget_realize (window);
151
152  evmask = g_new0 (guchar, XIMaskLen (XI_LASTEVENT));
153  XISetMask (evmask, XI_RawTouchBegin);
154  XISetMask (evmask, XI_RawTouchEnd);
155  XISetMask (evmask, XI_RawTouchUpdate);
156
157  mask.deviceid = XIAllMasterDevices;
158  mask.mask_len = sizeof (evmask);
159  mask.mask = evmask;
160
161  XISelectEvents (GDK_SCREEN_XDISPLAY (screen),
162                  GDK_WINDOW_XID (gdk_screen_get_root_window (screen)),
163                  &mask, 1);
164
165  gdk_window_add_filter (NULL, raw_event_filter, window);
166
167  region = cairo_region_create ();
168  gdk_window_input_shape_combine_region (gtk_widget_get_window (window),
169                                         region, 0, 0);
170  cairo_region_destroy (region);
171
172  gdk_window_set_background_rgba (gtk_widget_get_window (window),
173                                  &transparent);
174
175  gtk_window_move (GTK_WINDOW (window), 1, 1);
176  gtk_widget_set_size_request (window,
177                               gdk_screen_get_width (screen) / 2,
178                               gdk_screen_get_height (screen) / 2);
179
180  gtk_widget_show (window);
181
182  display = gdk_display_get_default ();
183  xdisplay = GDK_DISPLAY_XDISPLAY (display);
184  XFixesHideCursor (xdisplay, GDK_WINDOW_XID (gdk_screen_get_root_window (screen)));
185
186  gtk_main ();
187}