📄 gdkevents-win32.c
字号:
} y += pixmap_impl->height; } } x += pixmap_impl->width; } SelectObject (bgdc, oldbitmap); DeleteDC (bgdc); } }}static GdkRegion *_gdk_win32_hrgn_to_region (HRGN hrgn){ RGNDATA *rgndata; RECT *rects; GdkRegion *result; gint nbytes; guint i; if ((nbytes = GetRegionData (hrgn, 0, NULL)) == 0) { WIN32_GDI_FAILED ("GetRegionData"); return NULL; } rgndata = (RGNDATA *) g_malloc (nbytes); if (GetRegionData (hrgn, nbytes, rgndata) == 0) { WIN32_GDI_FAILED ("GetRegionData"); g_free (rgndata); return NULL; } result = gdk_region_new (); rects = (RECT *) rgndata->Buffer; for (i = 0; i < rgndata->rdh.nCount; i++) { GdkRectangle r; r.x = rects[i].left; r.y = rects[i].top; r.width = rects[i].right - r.x; r.height = rects[i].bottom - r.y; gdk_region_union_with_rect (result, &r); } g_free (rgndata); return result;}static voidadjust_drag (LONG *drag, LONG curr, gint inc){ if (*drag > curr) *drag = curr + ((*drag + inc/2 - curr) / inc) * inc; else *drag = curr - ((curr - *drag + inc/2) / inc) * inc;}static voidhandle_wm_paint (MSG *msg, GdkWindow *window, gboolean return_exposes, GdkEvent **event){ HRGN hrgn = CreateRectRgn (0, 0, 0, 0); HDC hdc; PAINTSTRUCT paintstruct; GdkRegion *update_region; gint xoffset, yoffset; if (GetUpdateRgn (msg->hwnd, hrgn, FALSE) == ERROR) { WIN32_GDI_FAILED ("GetUpdateRgn"); return; } hdc = BeginPaint (msg->hwnd, &paintstruct); GDK_NOTE (EVENTS, g_print (" %s %s dc %p%s", _gdk_win32_rect_to_string (&paintstruct.rcPaint), (paintstruct.fErase ? "erase" : ""), hdc, (return_exposes ? " return_exposes" : ""))); EndPaint (msg->hwnd, &paintstruct); /* HB: don't generate GDK_EXPOSE events for InputOnly * windows -> backing store now works! */ if (((GdkWindowObject *) window)->input_only) { DeleteObject (hrgn); return; } if (!(((GdkWindowObject *) window)->event_mask & GDK_EXPOSURE_MASK)) { GDK_NOTE (EVENTS, g_print (" (ignored)")); DeleteObject (hrgn); return; }#if 0 /* we need to process exposes even with GDK_NO_BG * Otherwise The GIMP canvas update is broken .... */ if (((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG) break;#endif if ((paintstruct.rcPaint.right == paintstruct.rcPaint.left) || (paintstruct.rcPaint.bottom == paintstruct.rcPaint.top)) { GDK_NOTE (EVENTS, g_print (" (empty paintstruct, ignored)")); DeleteObject (hrgn); return; } if (return_exposes) { if (!GDK_WINDOW_DESTROYED (window)) { GList *list = gdk_drawable_get_display (window)->queued_events; *event = gdk_event_new (GDK_EXPOSE); (*event)->expose.window = window; (*event)->expose.area.x = paintstruct.rcPaint.left; (*event)->expose.area.y = paintstruct.rcPaint.top; (*event)->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left; (*event)->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top; (*event)->expose.region = _gdk_win32_hrgn_to_region (hrgn); (*event)->expose.count = 0; while (list != NULL) { GdkEventPrivate *evp = list->data; if (evp->event.any.type == GDK_EXPOSE && evp->event.any.window == window && !(evp->flags & GDK_EVENT_PENDING)) evp->event.expose.count++; list = list->next; } } return; } update_region = _gdk_win32_hrgn_to_region (hrgn); _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); gdk_region_offset (update_region, xoffset, yoffset); _gdk_window_process_expose (window, update_region); gdk_region_destroy (update_region); DeleteObject (hrgn);}static voidhandle_stuff_while_moving_or_resizing (void){ int arbitrary_limit = 1; while (g_main_pending () && arbitrary_limit--) g_main_iteration (FALSE);}static VOID CALLBACKresize_timer_proc (HWND hwnd, UINT msg, UINT id, DWORD time){ if (_sizemove_in_progress) handle_stuff_while_moving_or_resizing ();}static voidhandle_display_change (void){ _gdk_monitor_init (); _gdk_root_window_size_init (); g_signal_emit_by_name (_gdk_screen, "size_changed");}static gbooleangdk_event_translate (GdkDisplay *display, MSG *msg, gint *ret_valp){ RECT rect, *drag, orig_drag; POINT point; MINMAXINFO *mmi; HWND hwnd; HCURSOR hcursor; BYTE key_state[256]; HIMC himc; GdkEvent *event; wchar_t wbuf[100]; gint ccount; GdkWindow *window = NULL; GdkWindowImplWin32 *impl; GdkWindow *orig_window, *new_window; gint xoffset, yoffset; static gint update_colors_counter = 0; gint button; GdkAtom target; gchar buf[256]; gboolean return_val = FALSE; int i; if (_gdk_default_filters) { /* Apply global filters */ GdkFilterReturn result = apply_filters (display, NULL, msg, _gdk_default_filters); /* If result is GDK_FILTER_CONTINUE, we continue as if nothing * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE, * we return TRUE, and DefWindowProc() will not be called. */ if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE) return TRUE; } window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd); orig_window = window; if (window == NULL) { /* XXX Handle WM_QUIT here ? */ if (msg->message == WM_QUIT) { GDK_NOTE (EVENTS, g_print (" %d", msg->wParam)); exit (msg->wParam); } else if (msg->message == WM_MOVE || msg->message == WM_SIZE) { /* It's quite normal to get these messages before we have * had time to register the window in our lookup table, or * when the window is being destroyed and we already have * removed it. Repost the same message to our queue so that * we will get it later when we are prepared. */ GDK_NOTE (EVENTS, g_print (" (posted)")); PostMessage (msg->hwnd, msg->message, msg->wParam, msg->lParam); } else if (msg->message == WM_CREATE) { window = (UNALIGNED GdkWindow*) (((LPCREATESTRUCT) msg->lParam)->lpCreateParams); GDK_WINDOW_HWND (window) = msg->hwnd; } else { GDK_NOTE (EVENTS, g_print (" (no GdkWindow)")); } return FALSE; } g_object_ref (window); /* window's refcount has now been increased, so code below should * not just return from this function, but instead goto done (or * break out of the big switch). To protect against forgetting this, * #define return to a syntax error... */#define return GOTO_DONE_INSTEAD if (!GDK_WINDOW_DESTROYED (window) && ((GdkWindowObject *) window)->filters) { /* Apply per-window filters */ GdkFilterReturn result = apply_filters (display, window, msg, ((GdkWindowObject *) window)->filters); if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE) { return_val = TRUE; goto done; } } if (msg->message == msh_mousewheel) { GDK_NOTE (EVENTS, g_print (" (MSH_MOUSEWHEEL)")); /* MSG_MOUSEWHEEL is delivered to the foreground window. Work * around that. Also, the position is in screen coordinates, not * client coordinates as with the button messages. */ point.x = GET_X_LPARAM (msg->lParam); point.y = GET_Y_LPARAM (msg->lParam); if ((hwnd = WindowFromPoint (point)) == NULL) goto done; msg->hwnd = hwnd; if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL) goto done; assign_object (&window, new_window); if (!propagate (&window, msg, p_grab_window, p_grab_owner_events, p_grab_mask, doesnt_want_scroll, TRUE)) goto done; if (GDK_WINDOW_DESTROYED (window)) goto done; ScreenToClient (msg->hwnd, &point); event = gdk_event_new (GDK_SCROLL); event->scroll.window = window; event->scroll.direction = ((int) msg->wParam > 0) ? GDK_SCROLL_UP : GDK_SCROLL_DOWN; event->scroll.time = _gdk_win32_get_next_tick (msg->time); _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); event->scroll.x = (gint16) point.x + xoffset; event->scroll.y = (gint16) point.y + yoffset; event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x; event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y; event->scroll.state = 0; /* No state information with MSH_MOUSEWHEEL */ event->scroll.device = display->core_pointer; append_event (display, event); return_val = TRUE; goto done; } else if (msg->message == client_message) { GList *tmp_list; GdkFilterReturn result = GDK_FILTER_CONTINUE; GDK_NOTE (EVENTS, g_print (" client_message")); tmp_list = client_filters; while (tmp_list) { GdkClientFilter *filter = tmp_list->data; tmp_list = tmp_list->next; if (filter->type == GDK_POINTER_TO_ATOM (msg->wParam)) { GList *filter_list = g_list_append (NULL, filter); GDK_NOTE (EVENTS, g_print (" (match)")); result = apply_filters (display, window, msg, filter_list); g_list_free (filter_list); if (result != GDK_FILTER_CONTINUE) break; } } if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE) { return_val = TRUE; goto done; } else { /* Send unknown client messages on to Gtk for it to use */ event = gdk_event_new (GDK_CLIENT_EVENT); event->client.window = window; event->client.message_type = GDK_POINTER_TO_ATOM (msg->wParam); event->client.data_format = 32; event->client.data.l[0] = msg->lParam; for (i = 1; i < 5; i++) event->client.data.l[i] = 0; append_event (display, event); return_val = TRUE; goto done; } } switch (msg->message) { case WM_INPUTLANGCHANGE: _gdk_input_locale = (HKL) msg->lParam; _gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale); GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, buf, sizeof (buf)); _gdk_input_codepage = atoi (buf); _gdk_keymap_serial++; GDK_NOTE (EVENTS, g_print (" cs:%lu hkl:%lx%s cp:%d", (gulong) msg->wParam, msg->lParam, _gdk_input_locale_is_ime ? " (IME)" : "", _gdk_input_codepage)); break; case WM_SYSKEYUP: case WM_SYSKEYDOWN: GDK_NOTE (EVENTS, g_print (" %s ch:%.02x %s", _gdk_win32_key_to_string (msg->lParam), msg->wParam, decode_key_lparam (msg->lParam))); /* If posted without us having keyboard focus, ignore */ if ((msg->wParam != VK_F10 && msg->wParam != VK_MENU) && !(HIWORD (msg->lParam) & KF_ALTDOWN)) break; /* Let the system handle Alt-Tab, Alt-Space, Alt-Enter and * Alt-F4 unless the keyboard is grabbed. */ if (k_grab_window == NULL && (msg->wParam == VK_TAB || msg->wParam == VK_SPACE || msg->wParam == VK_RETURN || msg->wParam == VK_F4)) break; /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */ goto keyup_or_down; case WM_KEYUP: case WM_KEYDOWN: GDK_NOTE (EVENTS, g_print (" %s ch:%.02x %s", _gdk_win32_key_to_string (msg->lParam), msg->wParam, decode_key_lparam (msg->lParam))); keyup_or_down: /* Ignore key messages intended for the IME */ if (msg->wParam == VK_PROCESSKEY || in_ime_composition) break; if (!propagate (&window, msg, k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK, doesnt_want_key, FALSE)) break; if (GDK_WINDOW_DESTROYED (window)) break; event = gdk_event_new ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) ? GDK_KEY_PRESS : GDK_KEY_RELEASE); event->key.window = window; event->key.time = _gdk_win32_get_next_tick (msg->time); event->key.keyval = GDK_VoidSymbol; event->key.string = NULL; event->key.length = 0; event->key.hardware_keycode = msg->wParam; if (HIWORD (msg->lParam) & KF_EXTENDED) { switch (msg->wParam) { case VK_CONTROL: event->key.hardware_keycode = VK_RCONTROL; break; case VK_SHIFT: /* Actually, KF_EXTENDED is not set * for the right shift ke
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -