]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkdevice-wintab.c
x11: Use boolean instead of enum for errors in xsettings code
[~andy/gtk] / gdk / win32 / gdkdevice-wintab.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include <gdk/gdkwindow.h>
21
22 #include <windowsx.h>
23 #include <objbase.h>
24
25 #include "gdkwin32.h"
26 #include "gdkdevice-wintab.h"
27
28 static gboolean gdk_device_wintab_get_history (GdkDevice      *device,
29                                                GdkWindow      *window,
30                                                guint32         start,
31                                                guint32         stop,
32                                                GdkTimeCoord ***events,
33                                                gint           *n_events);
34 static void gdk_device_wintab_get_state (GdkDevice       *device,
35                                          GdkWindow       *window,
36                                          gdouble         *axes,
37                                          GdkModifierType *mask);
38 static void gdk_device_wintab_set_window_cursor (GdkDevice *device,
39                                                  GdkWindow *window,
40                                                  GdkCursor *cursor);
41 static void gdk_device_wintab_warp (GdkDevice *device,
42                                     GdkScreen *screen,
43                                     gint       x,
44                                     gint       y);
45 static void gdk_device_wintab_query_state (GdkDevice        *device,
46                                            GdkWindow        *window,
47                                            GdkWindow       **root_window,
48                                            GdkWindow       **child_window,
49                                            gint             *root_x,
50                                            gint             *root_y,
51                                            gint             *win_x,
52                                            gint             *win_y,
53                                            GdkModifierType  *mask);
54 static GdkGrabStatus gdk_device_wintab_grab   (GdkDevice     *device,
55                                                GdkWindow     *window,
56                                                gboolean       owner_events,
57                                                GdkEventMask   event_mask,
58                                                GdkWindow     *confine_to,
59                                                GdkCursor     *cursor,
60                                                guint32        time_);
61 static void          gdk_device_wintab_ungrab (GdkDevice     *device,
62                                                guint32        time_);
63 static GdkWindow * gdk_device_wintab_window_at_position (GdkDevice       *device,
64                                                          gint            *win_x,
65                                                          gint            *win_y,
66                                                          GdkModifierType *mask,
67                                                          gboolean         get_toplevel);
68 static void      gdk_device_wintab_select_window_events (GdkDevice       *device,
69                                                          GdkWindow       *window,
70                                                          GdkEventMask     event_mask);
71
72
73 G_DEFINE_TYPE (GdkDeviceWintab, gdk_device_wintab, GDK_TYPE_DEVICE)
74
75 static void
76 gdk_device_wintab_class_init (GdkDeviceWintabClass *klass)
77 {
78   GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
79
80   device_class->get_history = gdk_device_wintab_get_history;
81   device_class->get_state = gdk_device_wintab_get_state;
82   device_class->set_window_cursor = gdk_device_wintab_set_window_cursor;
83   device_class->warp = gdk_device_wintab_warp;
84   device_class->query_state = gdk_device_wintab_query_state;
85   device_class->grab = gdk_device_wintab_grab;
86   device_class->ungrab = gdk_device_wintab_ungrab;
87   device_class->window_at_position = gdk_device_wintab_window_at_position;
88   device_class->select_window_events = gdk_device_wintab_select_window_events;
89 }
90
91 static void
92 gdk_device_wintab_init (GdkDeviceWintab *device_wintab)
93 {
94   GdkDevice *device;
95
96   device = GDK_DEVICE (device_wintab);
97 }
98
99 static gboolean
100 gdk_device_wintab_get_history (GdkDevice      *device,
101                                GdkWindow      *window,
102                                guint32         start,
103                                guint32         stop,
104                                GdkTimeCoord ***events,
105                                gint           *n_events)
106 {
107   return FALSE;
108 }
109
110 static GdkModifierType
111 get_current_mask (void)
112 {
113   GdkModifierType mask;
114   BYTE kbd[256];
115
116   GetKeyboardState (kbd);
117   mask = 0;
118   if (kbd[VK_SHIFT] & 0x80)
119     mask |= GDK_SHIFT_MASK;
120   if (kbd[VK_CAPITAL] & 0x80)
121     mask |= GDK_LOCK_MASK;
122   if (kbd[VK_CONTROL] & 0x80)
123     mask |= GDK_CONTROL_MASK;
124   if (kbd[VK_MENU] & 0x80)
125     mask |= GDK_MOD1_MASK;
126   if (kbd[VK_LBUTTON] & 0x80)
127     mask |= GDK_BUTTON1_MASK;
128   if (kbd[VK_MBUTTON] & 0x80)
129     mask |= GDK_BUTTON2_MASK;
130   if (kbd[VK_RBUTTON] & 0x80)
131     mask |= GDK_BUTTON3_MASK;
132
133   return mask;
134 }
135
136 static void
137 gdk_device_wintab_get_state (GdkDevice       *device,
138                              GdkWindow       *window,
139                              gdouble         *axes,
140                              GdkModifierType *mask)
141 {
142   GdkDeviceWintab *device_wintab;
143
144   device_wintab = GDK_DEVICE_WINTAB (device);
145
146   /* For now just use the last known button and axis state of the device.
147    * Since graphical tablets send an insane amount of motion events each
148    * second, the info should be fairly up to date */
149   if (mask)
150     {
151       *mask = get_current_mask ();
152       *mask &= 0xFF; /* Mask away core pointer buttons */
153       *mask |= ((device_wintab->button_state << 8)
154                 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
155                    | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
156                    | GDK_BUTTON5_MASK));
157     }
158
159   if (axes && device_wintab->last_axis_data)
160     _gdk_device_wintab_translate_axes (device_wintab, window, axes, NULL, NULL);
161 }
162
163 static void
164 gdk_device_wintab_set_window_cursor (GdkDevice *device,
165                                      GdkWindow *window,
166                                      GdkCursor *cursor)
167 {
168 }
169
170 static void
171 gdk_device_wintab_warp (GdkDevice *device,
172                         GdkScreen *screen,
173                         gint       x,
174                         gint       y)
175 {
176 }
177
178 static void
179 gdk_device_wintab_query_state (GdkDevice        *device,
180                                GdkWindow        *window,
181                                GdkWindow       **root_window,
182                                GdkWindow       **child_window,
183                                gint             *root_x,
184                                gint             *root_y,
185                                gint             *win_x,
186                                gint             *win_y,
187                                GdkModifierType  *mask)
188 {
189   GdkDeviceWintab *device_wintab;
190   POINT point;
191   HWND hwnd, hwndc;
192
193   device_wintab = GDK_DEVICE_WINTAB (device);
194
195   hwnd = GDK_WINDOW_HWND (window);
196   GetCursorPos (&point);
197
198   if (root_x)
199     *root_x = point.x;
200
201   if (root_y)
202     *root_y = point.y;
203
204   ScreenToClient (hwnd, &point);
205
206   if (win_x)
207     *win_x = point.x;
208
209   if (win_y)
210     *win_y = point.y;
211
212   if (window == _gdk_root)
213     {
214       if (win_x)
215         *win_x += _gdk_offset_x;
216
217       if (win_y)
218         *win_y += _gdk_offset_y;
219     }
220
221   if (child_window)
222     {
223       hwndc = ChildWindowFromPoint (hwnd, point);
224
225       if (hwndc && hwndc != hwnd)
226         *child_window = gdk_win32_handle_table_lookup (hwndc);
227       else
228         *child_window = NULL; /* Direct child unknown to gdk */
229     }
230
231   if (root_window)
232     {
233       GdkScreen *screen;
234
235       screen = gdk_window_get_screen (window);
236       *root_window = gdk_screen_get_root_window (screen);
237     }
238
239   if (mask)
240     {
241       *mask = get_current_mask ();
242       *mask &= 0xFF; /* Mask away core pointer buttons */
243       *mask |= ((device_wintab->button_state << 8)
244                 & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
245                    | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
246                    | GDK_BUTTON5_MASK));
247
248     }
249 }
250
251 static GdkGrabStatus
252 gdk_device_wintab_grab (GdkDevice    *device,
253                         GdkWindow    *window,
254                         gboolean      owner_events,
255                         GdkEventMask  event_mask,
256                         GdkWindow    *confine_to,
257                         GdkCursor    *cursor,
258                         guint32       time_)
259 {
260   return GDK_GRAB_SUCCESS;
261 }
262
263 static void
264 gdk_device_wintab_ungrab (GdkDevice *device,
265                           guint32    time_)
266 {
267 }
268
269 static GdkWindow *
270 gdk_device_wintab_window_at_position (GdkDevice       *device,
271                                       gint            *win_x,
272                                       gint            *win_y,
273                                       GdkModifierType *mask,
274                                       gboolean         get_toplevel)
275 {
276   return NULL;
277 }
278
279 static void
280 gdk_device_wintab_select_window_events (GdkDevice    *device,
281                                         GdkWindow    *window,
282                                         GdkEventMask  event_mask)
283 {
284 }
285
286 void
287 _gdk_device_wintab_translate_axes (GdkDeviceWintab *device_wintab,
288                                    GdkWindow       *window,
289                                    gdouble         *axes,
290                                    gdouble         *x,
291                                    gdouble         *y)
292 {
293   GdkDevice *device;
294   GdkWindow *impl_window;
295   gint root_x, root_y;
296   gdouble temp_x, temp_y;
297   gint i;
298
299   device = GDK_DEVICE (device_wintab);
300   impl_window = _gdk_window_get_impl_window (window);
301   temp_x = temp_y = 0;
302
303   gdk_window_get_origin (impl_window, &root_x, &root_y);
304
305   for (i = 0; i < gdk_device_get_n_axes (device); i++)
306     {
307       GdkAxisUse use;
308
309       use = gdk_device_get_axis_use (device, i);
310
311       switch (use)
312         {
313         case GDK_AXIS_X:
314         case GDK_AXIS_Y:
315           if (gdk_device_get_mode (device) == GDK_MODE_WINDOW)
316             _gdk_device_translate_window_coord (device, window, i,
317                                                 device_wintab->last_axis_data[i],
318                                                 &axes[i]);
319           else
320             _gdk_device_translate_screen_coord (device, window,
321                                                 root_x, root_y, i,
322                                                 device_wintab->last_axis_data[i],
323                                                 &axes[i]);
324           if (use == GDK_AXIS_X)
325             temp_x = axes[i];
326           else if (use == GDK_AXIS_Y)
327             temp_y = axes[i];
328
329           break;
330         default:
331           _gdk_device_translate_axis (device, i,
332                                       device_wintab->last_axis_data[i],
333                                       &axes[i]);
334           break;
335         }
336     }
337
338   if (x)
339     *x = temp_x;
340
341   if (y)
342     *y = temp_y;
343 }