📄 gdkevents-win32.c
字号:
(msg->message == WM_XBUTTONUP && HIWORD (msg->wParam) == XBUTTON2)) state |= GDK_BUTTON5_MASK; if (msg->wParam & MK_SHIFT) state |= GDK_SHIFT_MASK; if (GetKeyState (VK_MENU) < 0) state |= GDK_MOD1_MASK; if (GetKeyState (VK_CAPITAL) & 0x1) state |= GDK_LOCK_MASK; return state;}static voidbuild_wm_ime_composition_event (GdkEvent *event, MSG *msg, wchar_t wc, BYTE *key_state){ event->key.time = _gdk_win32_get_next_tick (msg->time); build_key_event_state (event, key_state); event->key.hardware_keycode = 0; /* FIXME: What should it be? */ event->key.string = NULL; event->key.length = 0; event->key.keyval = gdk_unicode_to_keyval (wc);}#ifdef G_ENABLE_DEBUGstatic voidprint_event_state (guint state){#define CASE(bit) if (state & GDK_ ## bit ## _MASK) g_print (#bit " "); CASE (SHIFT); CASE (LOCK); CASE (CONTROL); CASE (MOD1); CASE (MOD2); CASE (MOD3); CASE (MOD4); CASE (MOD5); CASE (BUTTON1); CASE (BUTTON2); CASE (BUTTON3); CASE (BUTTON4); CASE (BUTTON5);#undef CASE}static voidprint_event (GdkEvent *event){ gchar *escaped, *kvname; g_print ("%s%*s===> ", (debug_indent > 0 ? "\n" : ""), debug_indent, ""); switch (event->any.type) {#define CASE(x) case x: g_print (#x); break; CASE (GDK_NOTHING); CASE (GDK_DELETE); CASE (GDK_DESTROY); CASE (GDK_EXPOSE); CASE (GDK_MOTION_NOTIFY); CASE (GDK_BUTTON_PRESS); CASE (GDK_2BUTTON_PRESS); CASE (GDK_3BUTTON_PRESS); CASE (GDK_BUTTON_RELEASE); CASE (GDK_KEY_PRESS); CASE (GDK_KEY_RELEASE); CASE (GDK_ENTER_NOTIFY); CASE (GDK_LEAVE_NOTIFY); CASE (GDK_FOCUS_CHANGE); CASE (GDK_CONFIGURE); CASE (GDK_MAP); CASE (GDK_UNMAP); CASE (GDK_PROPERTY_NOTIFY); CASE (GDK_SELECTION_CLEAR); CASE (GDK_SELECTION_REQUEST); CASE (GDK_SELECTION_NOTIFY); CASE (GDK_PROXIMITY_IN); CASE (GDK_PROXIMITY_OUT); CASE (GDK_DRAG_ENTER); CASE (GDK_DRAG_LEAVE); CASE (GDK_DRAG_MOTION); CASE (GDK_DRAG_STATUS); CASE (GDK_DROP_START); CASE (GDK_DROP_FINISHED); CASE (GDK_CLIENT_EVENT); CASE (GDK_VISIBILITY_NOTIFY); CASE (GDK_NO_EXPOSE); CASE (GDK_SCROLL); CASE (GDK_WINDOW_STATE); CASE (GDK_SETTING);#undef CASE default: g_assert_not_reached (); } g_print (" %p ", GDK_WINDOW_HWND (event->any.window)); switch (event->any.type) { case GDK_EXPOSE: g_print ("%s %d", _gdk_win32_gdkrectangle_to_string (&event->expose.area), event->expose.count); break; case GDK_MOTION_NOTIFY: g_print ("(%.4g,%.4g) (%.4g,%.4g) %s", event->motion.x, event->motion.y, event->motion.x_root, event->motion.y_root, event->motion.is_hint ? "HINT " : ""); print_event_state (event->motion.state); break; case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: g_print ("%d (%.4g,%.4g) (%.4g,%.4g) ", event->button.button, event->button.x, event->button.y, event->button.x_root, event->button.y_root); print_event_state (event->button.state); break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: if (event->key.length == 0) escaped = g_strdup (""); else escaped = g_strescape (event->key.string, NULL); kvname = gdk_keyval_name (event->key.keyval); g_print ("%#.02x group:%d %s %d:\"%s\" ", event->key.hardware_keycode, event->key.group, (kvname ? kvname : "??"), event->key.length, escaped); g_free (escaped); print_event_state (event->key.state); break; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: g_print ("%p (%.4g,%.4g) (%.4g,%.4g) %s %s%s", event->crossing.subwindow == NULL ? NULL : GDK_WINDOW_HWND (event->crossing.subwindow), event->crossing.x, event->crossing.y, event->crossing.x_root, event->crossing.y_root, (event->crossing.mode == GDK_CROSSING_NORMAL ? "NORMAL" : (event->crossing.mode == GDK_CROSSING_GRAB ? "GRAB" : (event->crossing.mode == GDK_CROSSING_UNGRAB ? "UNGRAB" : "???"))), (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" : (event->crossing.detail == GDK_NOTIFY_VIRTUAL ? "VIRTUAL" : (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" : (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" : (event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL ? "NONLINEAR_VIRTUAL" : (event->crossing.detail == GDK_NOTIFY_UNKNOWN ? "UNKNOWN" : "???")))))), event->crossing.focus ? " FOCUS" : ""); print_event_state (event->crossing.state); break; case GDK_FOCUS_CHANGE: g_print ("%s", (event->focus_change.in ? "IN" : "OUT")); break; case GDK_CONFIGURE: g_print ("x:%d y:%d w:%d h:%d", event->configure.x, event->configure.y, event->configure.width, event->configure.height); break; case GDK_SCROLL: g_print ("(%.4g,%.4g) (%.4g,%.4g) %s", event->scroll.x, event->scroll.y, event->scroll.x_root, event->scroll.y_root, (event->scroll.direction == GDK_SCROLL_UP ? "UP" : (event->scroll.direction == GDK_SCROLL_DOWN ? "DOWN" : (event->scroll.direction == GDK_SCROLL_LEFT ? "LEFT" : (event->scroll.direction == GDK_SCROLL_RIGHT ? "RIGHT" : "???"))))); print_event_state (event->scroll.state); break; case GDK_WINDOW_STATE: g_print ("%s: %s", _gdk_win32_window_state_to_string (event->window_state.changed_mask), _gdk_win32_window_state_to_string (event->window_state.new_window_state)); default: /* Nothing */ break; } g_print ("%s", (debug_indent == 0 ? "\n" : "")); }static char *decode_key_lparam (LPARAM lParam){ static char buf[100]; char *p = buf; if (HIWORD (lParam) & KF_UP) p += g_sprintf (p, "KF_UP "); if (HIWORD (lParam) & KF_REPEAT) p += g_sprintf (p, "KF_REPEAT "); if (HIWORD (lParam) & KF_ALTDOWN) p += g_sprintf (p, "KF_ALTDOWN "); if (HIWORD (lParam) & KF_EXTENDED) p += g_sprintf (p, "KF_EXTENDED "); p += g_sprintf (p, "sc:%d rep:%d", LOBYTE (HIWORD (lParam)), LOWORD (lParam)); return buf;}#endifstatic voidfixup_event (GdkEvent *event){ if (event->any.window) g_object_ref (event->any.window); if (((event->any.type == GDK_ENTER_NOTIFY) || (event->any.type == GDK_LEAVE_NOTIFY)) && (event->crossing.subwindow != NULL)) g_object_ref (event->crossing.subwindow); event->any.send_event = InSendMessage (); }static voidappend_event (GdkDisplay *display, GdkEvent *event){ fixup_event (event); _gdk_event_queue_append (display, event); GDK_NOTE (EVENTS, print_event (event));}static voidfill_key_event_string (GdkEvent *event){ gunichar c; gchar buf[256]; /* Fill in event->string crudely, since various programs * depend on it. */ c = 0; if (event->key.keyval != GDK_VoidSymbol) c = gdk_keyval_to_unicode (event->key.keyval); if (c) { gsize bytes_written; gint len; /* Apply the control key - Taken from Xlib */ if (event->key.state & GDK_CONTROL_MASK) { if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; else if (c == '2') { event->key.string = g_memdup ("\0\0", 2); event->key.length = 1; return; } else if (c >= '3' && c <= '7') c -= ('3' - '\033'); else if (c == '8') c = '\177'; else if (c == '/') c = '_' & 0x1F; } len = g_unichar_to_utf8 (c, buf); buf[len] = '\0'; event->key.string = g_locale_from_utf8 (buf, len, NULL, &bytes_written, NULL); if (event->key.string) event->key.length = bytes_written; } else if (event->key.keyval == GDK_Escape) { event->key.length = 1; event->key.string = g_strdup ("\033"); } else if (event->key.keyval == GDK_Return || event->key.keyval == GDK_KP_Enter) { event->key.length = 1; event->key.string = g_strdup ("\r"); } if (!event->key.string) { event->key.length = 0; event->key.string = g_strdup (""); }}static GdkFilterReturnapply_filters (GdkDisplay *display, GdkWindow *window, MSG *msg, GList *filters){ GdkFilterReturn result; GdkEvent *event = gdk_event_new (GDK_NOTHING); GList *node; if (window != NULL) { event->any.window = window; g_object_ref (window); } ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; /* I think GdkFilterFunc semantics require the passed-in event * to already be in the queue. The filter func can generate * more events and append them after it if it likes. */ node = _gdk_event_queue_append (display, event); result = gdk_event_apply_filters (msg, event, filters); if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE) { _gdk_event_queue_remove_link (display, node); g_list_free_1 (node); gdk_event_free (event); } else /* GDK_FILTER_TRANSLATE */ { ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; fixup_event (event); GDK_NOTE (EVENTS, print_event (event)); } return result;}static gbooleangdk_window_is_ancestor (GdkWindow *ancestor, GdkWindow *window){ if (ancestor == NULL || window == NULL) return FALSE; return (gdk_window_get_parent (window) == ancestor || gdk_window_is_ancestor (ancestor, gdk_window_get_parent (window)));}static voidsynthesize_enter_or_leave_event (GdkWindow *window, MSG *msg, GdkEventType type, GdkCrossingMode mode, GdkNotifyType detail, gint x, gint y){ GdkEvent *event; gint xoffset, yoffset; event = gdk_event_new (type); event->crossing.window = window; event->crossing.subwindow = NULL; event->crossing.time = _gdk_win32_get_next_tick (msg->time); _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); event->crossing.x = x + xoffset; event->crossing.y = y + yoffset; event->crossing.x_root = msg->pt.x + _gdk_offset_x; event->crossing.y_root = msg->pt.y + _gdk_offset_y; event->crossing.mode = mode; event->crossing.detail = detail; event->crossing.focus = TRUE; /* FIXME: Set correctly */ event->crossing.state = 0; /* FIXME: Set correctly */ append_event (gdk_drawable_get_display (window), event); if (type == GDK_ENTER_NOTIFY && ((GdkWindowObject *) window)->extension_events != 0) _gdk_input_enter_event (window);}static voidsynthesize_leave_event (GdkWindow *window, MSG *msg, GdkCrossingMode mode, GdkNotifyType detail){ POINT pt; if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_LEAVE_NOTIFY_MASK)) return; if (!(((GdkWindowObject *) window)->event_mask & GDK_LEAVE_NOTIFY_MASK)) return; /* Leave events are at (current_x,current_y) in current_window */ if (current_window != window) { pt.x = current_x; pt.y = current_y; ClientToScreen (GDK_WINDOW_HWND (current_window), &pt); ScreenToClient (GDK_WINDOW_HWND (window), &pt); synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, pt.x, pt.y); } else synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, current_x, current_y); /* This would only make sense if the WM_MOUSEMOVE messages would come * before the respective WM_MOUSELEAVE message, which apparently they * do not. track_mouse_event (TME_CANCEL, msg->hwnd); */} static voidsynthesize_enter_event (GdkWindow *window, MSG *msg, GdkCrossingMode mode, GdkNotifyType detail){ POINT pt; if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_ENTER_NOTIFY_MASK)) return; if (!(((GdkWindowObject *) window)->event_mask & GDK_ENTER_NOTIFY_MASK)) return; /* Enter events are at GET_X_LPARAM (msg->lParam), GET_Y_LPARAM * (msg->lParam) in msg->hwnd */ pt.x = GET_X_LPARAM (msg->lParam); pt.y = GET_Y_LPARAM (msg->lParam); if (msg->hwnd != GDK_WINDOW_HWND (window)) { ClientToScreen (msg->hwnd, &pt); ScreenToClient (GDK_WINDOW_HWND (window), &pt); } synthesize_enter_or_leave_event (window, msg, GDK_ENTER_NOTIFY, mode, detail, pt.x, pt.y); track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (window));} static voidsynthesize_enter_events (GdkWindow *from, GdkWindow *to, MSG *msg, GdkCrossingMode mode, GdkNotifyType detail){ GdkWindow *prev = gdk_window_get_parent (to); if (prev != from) synthesize_enter_events (from, prev, msg, mode, detail); synthesize_enter_event (to, msg, mode, detail);} static voidsynthesize_leave_events (GdkWindow *from, GdkWindow *to, MSG *msg, GdkCrossingMode mode, GdkNotifyType detail){ GdkWindow *next = gdk_window_get_parent (from); synthesize_leave_event (from, msg, mode, detail); if (next != to) synthesize_leave_events (next, to, msg, mode, detail);} static voidsynthesize_crossing_events (GdkWindow *window, GdkCrossingMode mode, MSG *msg){ GdkWindow *intermediate, *tem, *common_ancestor; if (gdk_window_is_ancestor (current_window, window)) { /* Pointer has moved to an inferior window. */ synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_INFERIOR); /* If there are intermediate windows, generate ENTER_NOTIFY * events for them
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -