📄 gdkevents-x11.c
字号:
else return_val = FALSE; break; case SelectionClear: GDK_NOTE (EVENTS, g_message ("selection clear:\twindow: %ld", xevent->xproperty.window)); if (_gdk_selection_filter_clear_event (&xevent->xselectionclear)) { event->selection.type = GDK_SELECTION_CLEAR; event->selection.window = window; event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection); event->selection.time = xevent->xselectionclear.time; } else return_val = FALSE; break; case SelectionRequest: GDK_NOTE (EVENTS, g_message ("selection request:\twindow: %ld", xevent->xproperty.window)); event->selection.type = GDK_SELECTION_REQUEST; event->selection.window = window; event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection); event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target); event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property); event->selection.requestor = xevent->xselectionrequest.requestor; event->selection.time = xevent->xselectionrequest.time; break; case SelectionNotify: GDK_NOTE (EVENTS, g_message ("selection notify:\twindow: %ld", xevent->xproperty.window)); event->selection.type = GDK_SELECTION_NOTIFY; event->selection.window = window; event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection); event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target); event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property); event->selection.time = xevent->xselection.time; break; case ColormapNotify: GDK_NOTE (EVENTS, g_message ("colormap notify:\twindow: %ld", xevent->xcolormap.window)); /* Not currently handled */ return_val = FALSE; break; case ClientMessage: { GList *tmp_list; GdkFilterReturn result = GDK_FILTER_CONTINUE; GdkAtom message_type = gdk_x11_xatom_to_atom_for_display (display, xevent->xclient.message_type); GDK_NOTE (EVENTS, g_message ("client message:\twindow: %ld", xevent->xclient.window)); tmp_list = display_x11->client_filters; while (tmp_list) { GdkClientFilter *filter = tmp_list->data; tmp_list = tmp_list->next; if (filter->type == message_type) { result = (*filter->function) (xevent, event, filter->data); if (result != GDK_FILTER_CONTINUE) break; } } switch (result) { case GDK_FILTER_REMOVE: return_val = FALSE; break; case GDK_FILTER_TRANSLATE: return_val = TRUE; break; case GDK_FILTER_CONTINUE: /* Send unknown ClientMessage's on to Gtk for it to use */ if (window_private == NULL) { return_val = FALSE; } else { event->client.type = GDK_CLIENT_EVENT; event->client.window = window; event->client.message_type = message_type; event->client.data_format = xevent->xclient.format; memcpy(&event->client.data, &xevent->xclient.data, sizeof(event->client.data)); } break; } } break; case MappingNotify: GDK_NOTE (EVENTS, g_message ("mapping notify")); /* Let XLib know that there is a new keyboard mapping. */ XRefreshKeyboardMapping (&xevent->xmapping); _gdk_keymap_keys_changed (display); return_val = FALSE; break; default:#ifdef HAVE_XKB if (xevent->type == display_x11->xkb_event_type) { XkbEvent *xkb_event = (XkbEvent *)xevent; switch (xkb_event->any.xkb_type) { case XkbNewKeyboardNotify: case XkbMapNotify: _gdk_keymap_keys_changed (display); return_val = FALSE; break; case XkbStateNotify: _gdk_keymap_state_changed (display); break; } } else#endif#ifdef HAVE_XFIXES if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify) { XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent; event->owner_change.type = GDK_OWNER_CHANGE; event->owner_change.window = window; event->owner_change.owner = selection_notify->owner; event->owner_change.reason = selection_notify->subtype; event->owner_change.selection = gdk_x11_xatom_to_atom_for_display (display, selection_notify->selection); event->owner_change.time = selection_notify->timestamp; event->owner_change.selection_time = selection_notify->selection_timestamp; return_val = TRUE; } else#endif { /* something else - (e.g., a Xinput event) */ if (window_private && !GDK_WINDOW_DESTROYED (window_private) && (window_private->extension_events != 0)) return_val = _gdk_input_other_event(event, xevent, window); else return_val = FALSE; break; } } done: if (return_val) { 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); } else { /* Mark this event as having no resources to be freed */ event->any.window = NULL; event->any.type = GDK_NOTHING; } if (window) g_object_unref (window); return return_val;}static GdkFilterReturngdk_wm_protocols_filter (GdkXEvent *xev, GdkEvent *event, gpointer data){ XEvent *xevent = (XEvent *)xev; GdkWindow *win = event->any.window; GdkDisplay *display; Atom atom; if (!win) return GDK_FILTER_REMOVE; display = GDK_WINDOW_DISPLAY (win); atom = (Atom)xevent->xclient.data.l[0]; if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW")) { /* The delete window request specifies a window * to delete. We don't actually destroy the * window because "it is only a request". (The * window might contain vital data that the * program does not want destroyed). Instead * the event is passed along to the program, * which should then destroy the window. */ GDK_NOTE (EVENTS, g_message ("delete window:\t\twindow: %ld", xevent->xclient.window)); event->any.type = GDK_DELETE; gdk_x11_window_set_user_time (win, xevent->xclient.data.l[1]); return GDK_FILTER_TRANSLATE; } else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS")) { GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window); GdkWindowObject *private = (GdkWindowObject *)win; /* There is no way of knowing reliably whether we are viewable; * _gdk_x11_set_input_focus_safe() traps errors asynchronously. */ if (toplevel && private->accept_focus) _gdk_x11_set_input_focus_safe (display, toplevel->focus_window, RevertToParent, xevent->xclient.data.l[1]); return GDK_FILTER_REMOVE; } else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") && !_gdk_x11_display_is_root_window (display, xevent->xclient.window)) { XEvent xev = *xevent; xev.xclient.window = GDK_WINDOW_XROOTWIN (win); XSendEvent (GDK_WINDOW_XDISPLAY (win), xev.xclient.window, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); return GDK_FILTER_REMOVE; } else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") && GDK_DISPLAY_X11 (display)->use_sync) { GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window); if (toplevel) {#ifdef HAVE_XSYNC XSyncIntsToValue (&toplevel->pending_counter_value, xevent->xclient.data.l[2], xevent->xclient.data.l[3]);#endif } return GDK_FILTER_REMOVE; } return GDK_FILTER_CONTINUE;}void_gdk_events_queue (GdkDisplay *display){ GList *node; GdkEvent *event; XEvent xevent; Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); while (!_gdk_event_queue_find_first(display) && XPending (xdisplay)) { XNextEvent (xdisplay, &xevent); switch (xevent.type) { case KeyPress: case KeyRelease: break; default: if (XFilterEvent (&xevent, None)) continue; } event = gdk_event_new (GDK_NOTHING); event->any.window = NULL; event->any.send_event = xevent.xany.send_event ? TRUE : FALSE; ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; node = _gdk_event_queue_append (display, event); if (gdk_event_translate (display, event, &xevent, FALSE)) { ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; } else { _gdk_event_queue_remove_link (display, node); g_list_free_1 (node); gdk_event_free (event); } }}static gboolean gdk_event_prepare (GSource *source, gint *timeout){ GdkDisplay *display = ((GdkDisplaySource*)source)->display; gboolean retval; GDK_THREADS_ENTER (); *timeout = -1; retval = (_gdk_event_queue_find_first (display) != NULL || gdk_check_xpending (display)); GDK_THREADS_LEAVE (); return retval;}static gboolean gdk_event_check (GSource *source) { GdkDisplaySource *display_source = (GdkDisplaySource*)source; gboolean retval; GDK_THREADS_ENTER (); if (display_source->event_poll_fd.revents & G_IO_IN) retval = (_gdk_event_queue_find_first (display_source->display) != NULL || gdk_check_xpending (display_source->display)); else retval = FALSE; GDK_THREADS_LEAVE (); return retval;}static gboolean gdk_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data){ GdkDisplay *display = ((GdkDisplaySource*)source)->display; GdkEvent *event; GDK_THREADS_ENTER (); _gdk_events_queue (display); event = _gdk_event_unqueue (display); if (event) { if (_gdk_event_func) (*_gdk_event_func) (event, _gdk_event_data); gdk_event_free (event); } GDK_THREADS_LEAVE (); return TRUE;}/** * gdk_event_send_client_message_for_display: * @display: the #GdkDisplay for the window where the message is to be sent. * @event: the #GdkEvent to send, which should be a #GdkEventClient. * @winid: the window to send the client message to. * * On X11, sends an X ClientMessage event to a given window. On * Windows, sends a message registered with the name * GDK_WIN32_CLIENT_MESSAGE. * * This could be used for communicating between different * applications, though the amount of data is limited to 20 bytes on * X11, and to just four bytes on Windows. * * Returns: non-zero on success. * * Since: 2.2 */gbooleangdk_event_send_client_message_for_display (GdkDisplay *display, GdkEvent *event, GdkNativeWindow winid){ XEvent sev; g_return_val_if_fail(event != NULL, FALSE); /* Set up our event to send, with the exception of its target window */ sev.xclient.type = ClientMessage; sev.xclient.display = GDK_DISPLAY_XDISPLAY (display); sev.xclient.format = event->client.data_format; sev.xclient.window = winid; memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data)); sev.xclient.message_type = gdk_x11_atom_to_xatom_for_display (display, event->client.message_type); return _gdk_send_xevent (display, winid, False, NoEventMask, &sev);}/* Sends a ClientMessage to all toplevel client windows */static gbooleangdk_event_send_client_message_to_all_recurse (GdkDisplay *display, XEvent *xev, guint32 xid, guint level){ Atom type = None; int format; unsigned long nitems, after; unsigned char *data; Window *ret_children, ret_root, ret_parent; unsigned int ret_nchildren; gboolean send = FALSE; gboolean found = FALSE; gboolean result = FALSE; int i; gdk_error_trap_push (); if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid, gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"), 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &data) != Success) goto out; if (type) { send = TRUE; XFree (data); } else { /* OK, we're all set, now let's
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -