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 | |
---|
7 | static GHashTable *coords = NULL; |
---|
8 | |
---|
9 | static gboolean |
---|
10 | window_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 | |
---|
47 | static void |
---|
48 | raw_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 | |
---|
64 | static GdkFilterReturn |
---|
65 | raw_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 | |
---|
124 | int |
---|
125 | main (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 | } |
---|