59
59
static GdkWindow *wintab_window = NULL;
61
static GdkWindow *x_grab_window = NULL; /* Window that currently holds
62
* the extended inputs grab
64
static GdkEventMask x_grab_mask;
65
static gboolean x_grab_owner_events;
61
static GdkDevicePrivate *_gdk_device_in_proximity;
67
63
typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
68
64
typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
69
65
typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
70
66
typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
67
typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
68
typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
71
69
typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
72
70
typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
73
71
typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
665
670
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
666
GdkInputWindow *input_window,
668
673
gdouble *axis_out,
677
GdkWindowObject *priv, *impl_window;
672
678
GdkWindowImplWin32 *root_impl;
673
GdkWindowObject *window_object;
679
double device_width, device_height;
684
double device_width, device_height, x_min, y_min;
680
685
double x_offset, y_offset, x_scale, y_scale;
682
window_object = GDK_WINDOW_OBJECT (input_window);
687
priv = (GdkWindowObject *) window;
688
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
684
690
for (i=0; i<gdkdev->info.num_axes; i++)
686
692
switch (gdkdev->info.axes[i].use)
699
705
device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
706
x_min = gdkdev->axes[x_axis].min_value;
700
707
device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
708
y_min = gdkdev->axes[y_axis].min_value;
702
710
if (gdkdev->info.mode == GDK_MODE_SCREEN)
705
713
x_scale = GDK_WINDOW_OBJECT (_gdk_root)->width / device_width;
706
714
y_scale = GDK_WINDOW_OBJECT (_gdk_root)->height / device_height;
708
x_offset = - input_window->root_x;
709
y_offset = - input_window->root_y;
716
x_offset = - impl_window->input_window->root_x - priv->abs_x;
717
y_offset = - impl_window->input_window->root_y - priv->abs_y;
711
719
else /* GDK_MODE_WINDOW */
713
double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
714
(device_width*gdkdev->axes[x_axis].resolution);
716
if (device_aspect * window_object->width >= window_object->height)
718
/* device taller than window */
719
x_scale = window_object->width / device_width;
720
y_scale = (x_scale * gdkdev->axes[x_axis].resolution) / gdkdev->axes[y_axis].resolution;
723
y_offset = -(device_height * y_scale - window_object->height) / 2;
721
double x_resolution = gdkdev->axes[x_axis].resolution;
722
double y_resolution = gdkdev->axes[y_axis].resolution;
723
double device_aspect = (device_height*y_resolution) / (device_width * x_resolution);
725
if (device_aspect * priv->width >= priv->height)
727
/* device taller than window */
728
x_scale = priv->width / device_width;
729
y_scale = (x_scale * x_resolution) / y_resolution;
732
y_offset = -(device_height * y_scale - priv->height) / 2;
727
/* window taller than device */
728
y_scale = window_object->height / device_height;
729
x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
730
/ gdkdev->axes[x_axis].resolution;
736
/* window taller than device */
737
y_scale = priv->height / device_height;
738
x_scale = (y_scale * y_resolution) / x_resolution;
733
x_offset = - (device_width * x_scale - window_object->width) / 2;
741
x_offset = - (device_width * x_scale - priv->width) / 2;
737
745
for (i = 0; i < gdkdev->info.num_axes; i++)
739
747
switch (gdkdev->info.axes[i].use)
742
axis_out[i] = x_offset + x_scale * axis_data[x_axis];
744
*x_out = axis_out[i];
747
axis_out[i] = y_offset + y_scale * axis_data[y_axis];
749
*y_out = axis_out[i];
753
(gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
754
gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
755
(gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
750
axis_out[i] = x_offset + x_scale * axis_data[x_axis];
752
*x_out = axis_out[i];
755
axis_out[i] = y_offset + y_scale * axis_data[y_axis];
757
*y_out = axis_out[i];
761
(gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
762
gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
763
(gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
768
GetWindowRect (w, &rect);
778
ClientToScreen (w, &pt);
771
*x_ret = rect.left + _gdk_offset_x;
781
*x_ret = pt.x + _gdk_offset_x;
773
*y_ret = rect.top + _gdk_offset_y;
783
*y_ret = pt.y + _gdk_offset_y;
777
787
_gdk_input_configure_event (GdkWindow *window)
779
789
GdkInputWindow *input_window;
790
GdkWindowObject *impl_window;
780
791
int root_x, root_y;
782
input_window = _gdk_input_window_find (window);
783
793
g_return_if_fail (window != NULL);
795
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
796
input_window = impl_window->input_window;
785
798
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
786
799
&root_x, &root_y);
867
866
ignore_core_timefunc, NULL);
872
_gdk_input_update_for_device_mode (GdkDevicePrivate *gdkdev)
876
if (gdkdev != _gdk_device_in_proximity)
879
if (p_WTGetA (gdkdev->hctx, &lc))
881
if (gdkdev->info.mode == GDK_MODE_SCREEN &&
882
(lc.lcOptions & CXO_SYSTEM) == 0)
884
lc.lcOptions |= CXO_SYSTEM;
885
p_WTSetA (gdkdev->hctx, &lc);
887
else if (gdkdev->info.mode == GDK_MODE_WINDOW &&
888
(lc.lcOptions & CXO_SYSTEM) != 0)
890
lc.lcOptions &= ~CXO_SYSTEM;
891
p_WTSetA (gdkdev->hctx, &lc);
897
find_window_for_input_event (MSG* msg, int *x, int *y)
907
hwnd = WindowFromPoint (pt);
910
POINT client_pt = pt;
912
ScreenToClient (hwnd, &client_pt);
913
GetClientRect (hwnd, &rect);
914
if (PtInRect (&rect, client_pt))
915
window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
918
/* need to also adjust the coordinates to the new window */
920
ScreenToClient (GDK_WINDOW_HWND (window), &pt);
871
932
_gdk_input_other_event (GdkEvent *event,
873
934
GdkWindow *window)
876
GdkWindowObject *obj, *grab_obj;
936
GdkWindowObject *obj, *impl_window;
937
GdkWindow *native_window;
877
938
GdkInputWindow *input_window;
878
939
GdkDevicePrivate *gdkdev = NULL;
879
GdkEventMask masktest;
890
949
static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
892
if (event->any.window != wintab_window)
951
if (window != wintab_window)
894
953
g_warning ("_gdk_input_other_event: not wintab_window?");
898
window = gdk_window_at_pointer (&x, &y);
902
g_object_ref (window);
903
display = gdk_drawable_get_display (window);
957
native_window = find_window_for_input_event (msg, &x, &y);
905
959
GDK_NOTE (EVENTS_OR_INPUT,
906
g_print ("_gdk_input_other_event: window=%p %+d%+d\n",
907
GDK_WINDOW_HWND (window), x, y));
909
if (msg->message == WT_PACKET)
960
g_print ("_gdk_input_other_event: native_window=%p %+d%+d\n",
961
GDK_WINDOW_HWND (native_window), x, y));
963
if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
911
965
if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
915
obj = GDK_WINDOW_OBJECT (window);
917
969
switch (msg->message)
981
1028
if (!(translated_buttons & button_mask))
983
event->any.type = GDK_BUTTON_RELEASE;
984
masktest = GDK_BUTTON_RELEASE_MASK;
1029
event->any.type = GDK_BUTTON_RELEASE;
988
event->any.type = GDK_BUTTON_PRESS;
989
masktest = GDK_BUTTON_PRESS_MASK;
1031
event->any.type = GDK_BUTTON_PRESS;
991
1032
gdkdev->button_state ^= button_mask;
995
1036
event->any.type = GDK_MOTION_NOTIFY;
996
masktest = GDK_POINTER_MOTION_MASK;
997
if (gdkdev->button_state & (1 << 0))
998
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
999
if (gdkdev->button_state & (1 << 1))
1000
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
1001
if (gdkdev->button_state & (1 << 2))
1002
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
1005
/* See if input is grabbed */
1006
/* FIXME: x_grab_owner_events should probably be handled somehow */
1007
if (x_grab_window != NULL)
1009
grab_obj = GDK_WINDOW_OBJECT (x_grab_window);
1010
if (!GDK_WINDOW_IMPL_WIN32 (grab_obj->impl)->extension_events_selected
1011
|| !(grab_obj->extension_events & masktest)
1012
|| !(x_grab_mask && masktest))
1014
GDK_NOTE (EVENTS_OR_INPUT,
1015
g_print ("... grabber doesn't want it\n"));
1018
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... to grabber\n"));
1020
g_object_ref(x_grab_window);
1021
g_object_unref(window);
1022
window = x_grab_window;
1025
/* Now we can check if the window wants the event, and
1026
* propagate if necessary.
1029
if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
1030
|| !(obj->extension_events & masktest))
1032
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
1034
if (obj->parent == GDK_WINDOW_OBJECT (_gdk_root))
1037
/* It is not good to propagate the extended events up to the parent
1038
* if this window wants normal (not extended) motion/button events */
1039
if (obj->event_mask & masktest)
1041
GDK_NOTE (EVENTS_OR_INPUT,
1042
g_print ("... wants ordinary event, ignoring this\n"));
1048
ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1049
g_object_unref (window);
1050
window = (GdkWindow *) obj->parent;
1051
obj = GDK_WINDOW_OBJECT (window);
1052
g_object_ref (window);
1053
ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1056
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
1057
GDK_WINDOW_HWND (window), x, y));
1061
input_window = _gdk_input_window_find (window);
1039
if (native_window == _gdk_root)
1042
window = _gdk_window_get_input_window_for_event (native_window,
1044
gdkdev->button_state << 8,
1047
obj = GDK_WINDOW_OBJECT (window);
1049
if (window == NULL ||
1050
obj->extension_events == 0)
1053
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
1054
input_window = impl_window->input_window;
1063
1056
g_assert (input_window != NULL);
1065
if (gdkdev->info.mode == GDK_MODE_WINDOW
1066
&& input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
1058
if (gdkdev->info.mode == GDK_MODE_WINDOW &&
1059
(obj->extension_events & GDK_ALL_DEVICES_MASK) == 0)
1069
1062
event->any.window = window;
1070
1063
key_state = get_modifier_key_state ();
1071
if (event->any.type == GDK_BUTTON_PRESS
1072
|| event->any.type == GDK_BUTTON_RELEASE)
1064
if (event->any.type == GDK_BUTTON_PRESS ||
1065
event->any.type == GDK_BUTTON_RELEASE)
1074
1067
event->button.time = _gdk_win32_get_next_tick (msg->time);
1075
1068
event->button.device = &gdkdev->info;
1077
1070
event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
1079
gdk_input_translate_coordinates (gdkdev, input_window,
1072
gdk_input_translate_coordinates (gdkdev, window,
1080
1073
gdkdev->last_axis_data,
1081
1074
event->button.axes,
1082
1075
&event->button.x,
1127
if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
1128
packet.pkCursor)) == NULL)
1131
_gdk_device_in_proximity = gdkdev;
1133
_gdk_input_update_for_device_mode (gdkdev);
1136
if (native_window != _gdk_root)
1137
window = _gdk_window_get_input_window_for_event (native_window,
1143
event->proximity.type = GDK_PROXIMITY_IN;
1144
event->proximity.window = window;
1145
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1146
event->proximity.device = &_gdk_device_in_proximity->info;
1149
GDK_NOTE (EVENTS_OR_INPUT,
1150
g_print ("WINTAB proximity in\n"));
1133
1154
case WT_PROXIMITY:
1155
/* TODO: Set ignore_core if in input_window */
1134
1156
if (LOWORD (msg->lParam) == 0)
1136
event->proximity.type = GDK_PROXIMITY_OUT;
1137
set_ignore_core (FALSE);
1158
_gdk_input_in_proximity = FALSE;
1161
if (native_window != _gdk_root)
1162
window = _gdk_window_get_input_window_for_event (native_window,
1168
event->proximity.type = GDK_PROXIMITY_OUT;
1169
event->proximity.window = window;
1170
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1171
event->proximity.device = &_gdk_device_in_proximity->info;
1174
GDK_NOTE (EVENTS_OR_INPUT,
1175
g_print ("WINTAB proximity out\n"));
1141
event->proximity.type = GDK_PROXIMITY_IN;
1142
set_ignore_core (TRUE);
1144
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1145
event->proximity.device = &gdkdev->info;
1147
GDK_NOTE (EVENTS_OR_INPUT,
1148
g_print ("WINTAB proximity %s\n",
1149
(event->proximity.type == GDK_PROXIMITY_IN ?
1180
_gdk_input_in_proximity = TRUE;
1182
_gdk_input_check_proximity ();
1157
_gdk_input_enable_window (GdkWindow *window,
1158
GdkDevicePrivate *gdkdev)
1160
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1162
impl->extension_events_selected = TRUE;
1168
_gdk_input_disable_window (GdkWindow *window,
1169
GdkDevicePrivate *gdkdev)
1171
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1173
impl->extension_events_selected = FALSE;
1190
_gdk_input_select_events (GdkWindow *impl_window)
1195
GList *l, *dev_list;
1198
iw = ((GdkWindowObject *)impl_window)->input_window;
1201
for (dev_list = _gdk_input_devices; dev_list; dev_list = dev_list->next)
1203
GdkDevicePrivate *gdkdev = dev_list->data;
1205
if (!GDK_IS_CORE (gdkdev) &&
1206
gdkdev->info.mode != GDK_MODE_DISABLED &&
1209
for (l = iw->windows; l != NULL; l = l->next)
1212
if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
1213
event_mask |= w->extension_events;
1218
event_mask &= ~GDK_ALL_DEVICES_MASK;
1221
GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
1223
GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *)impl_window)->impl)->extension_events_mask = event_mask;
1182
1230
GdkWindow *confine_to,
1185
GdkInputWindow *input_window, *new_window;
1186
gboolean need_ungrab;
1187
GdkDevicePrivate *gdkdev;
1190
tmp_list = _gdk_input_windows;
1192
need_ungrab = FALSE;
1194
1233
GDK_NOTE (INPUT, g_print ("_gdk_input_grab_pointer: %p %d %p\n",
1195
1234
GDK_WINDOW_HWND (window),
1197
1236
(confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
1201
input_window = (GdkInputWindow *)tmp_list->data;
1203
if (input_window->window == window)
1204
new_window = input_window;
1205
else if (input_window->grabbed)
1207
input_window->grabbed = FALSE;
1211
tmp_list = tmp_list->next;
1216
new_window->grabbed = TRUE;
1217
x_grab_window = window;
1218
x_grab_mask = event_mask;
1219
x_grab_owner_events = owner_events;
1221
/* FIXME: Do we need to handle confine_to and time? */
1223
tmp_list = _gdk_input_devices;
1226
gdkdev = (GdkDevicePrivate *)tmp_list->data;
1227
if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx)
1231
gdk_input_common_find_events (window, gdkdev,
1233
event_classes, &num_classes);
1235
result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
1236
GDK_WINDOW_XWINDOW (window),
1237
owner_events, num_classes, event_classes,
1238
GrabModeAsync, GrabModeAsync, time);
1240
/* FIXME: if failure occurs on something other than the first
1241
device, things will be badly inconsistent */
1242
if (result != Success)
1246
tmp_list = tmp_list->next;
1251
x_grab_window = NULL;
1253
tmp_list = _gdk_input_devices;
1256
gdkdev = (GdkDevicePrivate *)tmp_list->data;
1257
if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx &&
1258
((gdkdev->button_state != 0) || need_ungrab))
1262
XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1264
gdkdev->button_state = 0;
1267
tmp_list = tmp_list->next;
1272
1238
return GDK_GRAB_SUCCESS;
1276
1242
_gdk_input_ungrab_pointer (guint32 time)
1278
GdkInputWindow *input_window;
1279
GdkDevicePrivate *gdkdev;
1282
1245
GDK_NOTE (INPUT, g_print ("_gdk_input_ungrab_pointer\n"));
1284
tmp_list = _gdk_input_windows;
1287
input_window = (GdkInputWindow *)tmp_list->data;
1288
if (input_window->grabbed)
1290
tmp_list = tmp_list->next;
1293
if (tmp_list) /* we found a grabbed window */
1295
input_window->grabbed = FALSE;
1297
tmp_list = _gdk_input_devices;
1300
gdkdev = (GdkDevicePrivate *)tmp_list->data;
1303
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
1304
XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1306
tmp_list = tmp_list->next;
1309
x_grab_window = NULL;