void gdk_property_change (GdkWindow *window, GdkAtom property, GdkAtom type, gint format, GdkPropMode mode, const guchar *data, gint nelements) { GdkDisplay *display; Window xwindow; Atom xproperty; Atom xtype; g_return_if_fail (!window || GDK_IS_WINDOW (window)); if (!window) { GdkScreen *screen; screen = gdk_screen_get_default (); window = gdk_screen_get_root_window (screen); GDK_NOTE (MULTIHEAD, g_message ("gdk_property_change(): window is NULL\n")); } if (GDK_WINDOW_DESTROYED (window)) return; display = gdk_drawable_get_display (window); xproperty = gdk_x11_atom_to_xatom_for_display (display, property); xtype = gdk_x11_atom_to_xatom_for_display (display, type); xwindow = GDK_WINDOW_XID (window); if (xtype == XA_ATOM || xtype == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { /* * data is an array of GdkAtom, we need to convert it * to an array of X Atoms */ gint i; GdkAtom *atoms = (GdkAtom*) data; Atom *xatoms; xatoms = g_new (Atom, nelements); for (i = 0; i < nelements; i++) xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]); XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, xtype, format, mode, (guchar *)xatoms, nelements); g_free (xatoms); } else XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, xtype, format, mode, (guchar *)data, nelements); }
gboolean gdk_device_get_history (GdkDevice *device, GdkWindow *window, guint32 start, guint32 stop, GdkTimeCoord ***events, gint *n_events) { g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); g_return_val_if_fail (events != NULL, FALSE); g_return_val_if_fail (n_events != NULL, FALSE); if (n_events) *n_events = 0; if (events) *events = NULL; if (GDK_WINDOW_DESTROYED (window)) return FALSE; if (GDK_IS_CORE (device)) return FALSE; else return _gdk_device_get_history (device, window, start, stop, events, n_events); }
void gdk_property_delete (GdkWindow *window, GdkAtom property) { g_return_if_fail (!window || GDK_IS_WINDOW (window)); if (!window) { GdkScreen *screen = gdk_screen_get_default (); window = gdk_screen_get_root_window (screen); GDK_NOTE (MULTIHEAD, g_message ("gdk_property_delete(): window is NULL\n")); } if (GDK_WINDOW_DESTROYED (window)) return; gi_atom_id_t aid; GdkDisplay *display = GDK_DISPLAY_OBJECT(_gdk_display); aid = gdk_x11_atom_to_xatom_for_display (display, property); gi_delete_property ( GDK_DRAWABLE_GIX_ID (window), aid); }
GdkGrabStatus gdk_keyboard_grab (GdkWindow * window, gboolean owner_events, guint32 time) { gint return_val; unsigned long serial; GdkDisplay *display; GdkDisplayX11 *display_x11; GdkWindow *native; g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); native = gdk_window_get_toplevel (window); /* TODO: What do we do for offscreens and children? We need to proxy the grab somehow */ if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl)) return GDK_GRAB_SUCCESS; display = GDK_WINDOW_DISPLAY (native); display_x11 = GDK_DISPLAY_X11 (display); serial = NextRequest (GDK_WINDOW_XDISPLAY (native)); if (!GDK_WINDOW_DESTROYED (native)) { #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) return_val = GrabSuccess; else #endif return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (native), GDK_WINDOW_XID (native), owner_events, GrabModeAsync, GrabModeAsync, time); if (G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed)) /* we can't grab the keyboard, but we can do a GTK-local grab */ return_val = GrabSuccess; } else return_val = AlreadyGrabbed; if (return_val == GrabSuccess) _gdk_display_set_has_keyboard_grab (display, window, native, owner_events, serial, time); return gdk_x11_convert_grab_status (return_val); }
static cairo_surface_t * gdk_quartz_ref_cairo_surface (GdkDrawable *drawable) { GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable); if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) && GDK_WINDOW_DESTROYED (impl->wrapper)) return NULL; if (!impl->cairo_surface) { int width, height; gdk_drawable_get_size (drawable, &width, &height); impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, width, height); } else cairo_surface_reference (impl->cairo_surface); return impl->cairo_surface; }
void gdk_property_delete (GdkWindow *window, GdkAtom property) { g_return_if_fail (!window || GDK_IS_WINDOW (window)); if (!window) { GdkScreen *screen = gdk_screen_get_default (); window = gdk_screen_get_root_window (screen); GDK_NOTE (MULTIHEAD, g_message ("gdk_property_delete(): window is NULL\n")); } if (GDK_WINDOW_DESTROYED (window)) return; XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XWINDOW (window), gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window), property)); }
void gdk_input_set_extension_events (GdkWindow *window, gint mask, GdkExtensionMode mode) { GdkDeviceManager *device_manager; GList *devices, *d; g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; if (mode == GDK_EXTENSION_EVENTS_NONE) mask = 0; window->extension_events = mask; device_manager = gdk_display_get_device_manager (_gdk_display); devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING); for (d = devices; d; d = d->next) { GdkDevice *dev; gint dev_mask; dev = d->data; dev_mask = mask; if (gdk_device_get_mode (dev) == GDK_MODE_DISABLED || (!gdk_device_get_has_cursor (dev) && mode == GDK_EXTENSION_EVENTS_CURSOR)) dev_mask = 0; gdk_window_set_device_events (window, dev, mask); } g_list_free (devices); }
GdkGrabStatus _gdk_windowing_pointer_grab (GdkWindow *window, GdkWindow *native, gboolean owner_events, GdkEventMask event_mask, GdkWindow *confine_to, GdkCursor *cursor, guint32 time) { gint return_val; GdkCursorPrivate *cursor_private; GdkDisplayX11 *display_x11; guint xevent_mask; Window xwindow; Window xconfine_to; Cursor xcursor; int i; if (confine_to) confine_to = _gdk_window_get_impl_window (confine_to); display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native)); cursor_private = (GdkCursorPrivate*) cursor; xwindow = GDK_WINDOW_XID (native); if (!confine_to || GDK_WINDOW_DESTROYED (confine_to)) xconfine_to = None; else xconfine_to = GDK_WINDOW_XID (confine_to); if (!cursor) xcursor = None; else { _gdk_x11_cursor_update_theme (cursor); xcursor = cursor_private->xcursor; } xevent_mask = 0; for (i = 0; i < _gdk_nenvent_masks; i++) { if (event_mask & (1 << (i + 1))) xevent_mask |= _gdk_event_mask_table[i]; } /* We don't want to set a native motion hint mask, as we're emulating motion * hints. If we set a native one we just wouldn't get any events. */ xevent_mask &= ~PointerMotionHintMask; return_val = _gdk_input_grab_pointer (window, native, owner_events, event_mask, confine_to, time); if (return_val == GrabSuccess || G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed)) { if (!GDK_WINDOW_DESTROYED (native)) { #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) return_val = GrabSuccess; else #endif return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (native), xwindow, owner_events, xevent_mask, GrabModeAsync, GrabModeAsync, xconfine_to, xcursor, time); } else return_val = AlreadyGrabbed; } if (return_val == GrabSuccess) _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11), has_pointer_grab_callback, NULL); return gdk_x11_convert_grab_status (return_val); }
GdkPixmap* gdk_pixmap_new (GdkDrawable *drawable, gint width, gint height, gint depth) { GIXSurfacePixelFormat format; GdkPixmap *pixmap; GdkDrawableImplGix *draw_impl; g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (drawable != NULL || depth != -1, NULL); g_return_val_if_fail (width > 0 && height > 0, NULL); if (!drawable) drawable = _gdk_parent_root; if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable)) return NULL; GDK_NOTE (MISC, g_print ("gdk_pixmap_new: %dx%dx%d\n", width, height, depth)); if (depth == -1) { draw_impl = GDK_DRAWABLE_IMPL_GIX (GDK_WINDOW_OBJECT (drawable)->impl); g_return_val_if_fail (draw_impl != NULL, NULL); format = gi_screen_format(); depth = GI_RENDER_FORMAT_BPP (format); } else { switch (depth) { case 1: format = GI_RENDER_a8; break; case 8: format = GI_RENDER_r3g3b2; break; case 15: format = GI_RENDER_x1r5g5b5; break; case 16: format = GI_RENDER_r5g6b5; break; case 24: format = GI_RENDER_r8g8b8; break; case 32: format = GI_RENDER_x8r8g8b8; break; default: g_message ("unimplemented %s for depth %d", __FUNCTION__, depth); return NULL; } } pixmap = g_object_new (gdk_pixmap_get_type (), NULL); draw_impl = GDK_DRAWABLE_IMPL_GIX (GDK_PIXMAP_OBJECT (pixmap)->impl); draw_impl->window_id = gi_create_pixmap_window( GDK_DRAWABLE_IMPL_GIX (drawable)->window_id,width,height,format); //surface->Clear (surface, 0x0, 0x0, 0x0, 0x0); //surface->GetSize (surface, &draw_impl->width, &draw_impl->height); //surface->GetPixelFormat (surface, &draw_impl->format); draw_impl->width = width; draw_impl->height = height; draw_impl->format = format; draw_impl->abs_x = draw_impl->abs_y = 0; GDK_PIXMAP_OBJECT (pixmap)->depth = depth; return pixmap; }
gboolean gdk_property_get (GdkWindow *window, GdkAtom property, GdkAtom type, gulong offset, gulong length, gint pdelete, GdkAtom *actual_property_type, gint *actual_format_type, gint *actual_length, guchar **data) { GdkDisplay *display; Atom ret_prop_type; gint ret_format; gulong ret_nitems; gulong ret_bytes_after; gulong get_length; gulong ret_length; guchar *ret_data; Atom xproperty; Atom xtype; int res; g_return_val_if_fail (!window || GDK_WINDOW_IS_X11 (window), FALSE); if (!window) { GdkScreen *screen = gdk_screen_get_default (); window = gdk_screen_get_root_window (screen); GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n")); } else if (!GDK_WINDOW_IS_X11 (window)) return FALSE; if (GDK_WINDOW_DESTROYED (window)) return FALSE; display = gdk_drawable_get_display (window); xproperty = gdk_x11_atom_to_xatom_for_display (display, property); if (type == GDK_NONE) xtype = AnyPropertyType; else xtype = gdk_x11_atom_to_xatom_for_display (display, type); ret_data = NULL; /* * Round up length to next 4 byte value. Some code is in the (bad?) * habit of passing G_MAXLONG as the length argument, causing an * overflow to negative on the add. In this case, we clamp the * value to G_MAXLONG. */ get_length = length + 3; if (get_length > G_MAXLONG) get_length = G_MAXLONG; /* To fail, either the user passed 0 or G_MAXULONG */ get_length = get_length / 4; if (get_length == 0) { g_warning ("gdk_propery-get(): invalid length 0"); return FALSE; } res = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XWINDOW (window), xproperty, offset, get_length, pdelete, xtype, &ret_prop_type, &ret_format, &ret_nitems, &ret_bytes_after, &ret_data); if (res != Success || (ret_prop_type == None && ret_format == 0)) { return FALSE; } if (actual_property_type) *actual_property_type = gdk_x11_xatom_to_atom_for_display (display, ret_prop_type); if (actual_format_type) *actual_format_type = ret_format; if ((xtype != AnyPropertyType) && (ret_prop_type != xtype)) { XFree (ret_data); g_warning ("Couldn't match property type %s to %s\n", gdk_x11_get_xatom_name_for_display (display, ret_prop_type), gdk_x11_get_xatom_name_for_display (display, xtype)); return FALSE; } /* FIXME: ignoring bytes_after could have very bad effects */ if (data) { if (ret_prop_type == XA_ATOM || ret_prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { /* * data is an array of X atom, we need to convert it * to an array of GDK Atoms */ gint i; GdkAtom *ret_atoms = g_new (GdkAtom, ret_nitems); Atom *xatoms = (Atom *)ret_data; *data = (guchar *)ret_atoms; for (i = 0; i < ret_nitems; i++) ret_atoms[i] = gdk_x11_xatom_to_atom_for_display (display, xatoms[i]); if (actual_length) *actual_length = ret_nitems * sizeof (GdkAtom); } else { switch (ret_format) { case 8: ret_length = ret_nitems; break; case 16: ret_length = sizeof(short) * ret_nitems; break; case 32: ret_length = sizeof(long) * ret_nitems; break; default: g_warning ("unknown property return format: %d", ret_format); XFree (ret_data); return FALSE; } *data = g_new (guchar, ret_length); memcpy (*data, ret_data, ret_length); if (actual_length) *actual_length = ret_length; } } XFree (ret_data); return TRUE; }
void gdk_window_move_region (GdkWindow *window, GdkRegion *region, gint dx, gint dy) { GdkRegion *invalidate_region; GdkWindowImplWin32 *impl; GdkWindowObject *obj; GdkRectangle src_rect, dest_rect; HRGN hrgn; RECT clipRect, destRect; g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; obj = GDK_WINDOW_OBJECT (window); impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); if (dx == 0 && dy == 0) return; /* Move the current invalid region */ if (obj->update_area) gdk_region_offset (obj->update_area, dx, dy); /* impl->position_info.clip_rect isn't meaningful for toplevels */ if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) src_rect = impl->position_info.clip_rect; else { src_rect.x = 0; src_rect.y = 0; src_rect.width = impl->width; src_rect.height = impl->height; } invalidate_region = gdk_region_rectangle (&src_rect); dest_rect = src_rect; dest_rect.x += dx; dest_rect.y += dy; gdk_rectangle_intersect (&dest_rect, &src_rect, &dest_rect); if (dest_rect.width > 0 && dest_rect.height > 0) { GdkRegion *tmp_region; tmp_region = gdk_region_rectangle (&dest_rect); gdk_region_subtract (invalidate_region, tmp_region); gdk_region_destroy (tmp_region); } /* no guffaw scroll on win32 */ hrgn = _gdk_win32_gdkregion_to_hrgn(invalidate_region, 0, 0); gdk_region_destroy (invalidate_region); destRect.left = dest_rect.y; destRect.top = dest_rect.x; destRect.right = dest_rect.x + dest_rect.width; destRect.bottom = dest_rect.y + dest_rect.height; clipRect.left = src_rect.y; clipRect.top = src_rect.x; clipRect.right = src_rect.x + src_rect.width; clipRect.bottom = src_rect.y + src_rect.height; g_print ("ScrollWindowEx(%d, %d, ...) - if you see this work, remove trace;)\n", dx, dy); API_CALL(ScrollWindowEx, (GDK_WINDOW_HWND (window), dx, dy, /* in: scroll offsets */ NULL, /* in: scroll rect, NULL == entire client area */ &clipRect, /* in: restrict to */ hrgn, /* in: update region */ NULL, /* out: update rect */ SW_INVALIDATE)); API_CALL(DeleteObject, (hrgn)); }
void gdk_window_scroll (GdkWindow *window, gint dx, gint dy) { GdkRegion *invalidate_region; GdkWindowImplWin32 *impl; GdkWindowObject *obj; GList *tmp_list; GdkWindowParentPos parent_pos; HRGN native_invalidate_region; g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; GDK_NOTE (EVENTS, g_print ("gdk_window_scroll: %p %d,%d\n", GDK_WINDOW_HWND (window), dx, dy)); obj = GDK_WINDOW_OBJECT (window); impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); if (dx == 0 && dy == 0) return; /* Move the current invalid region */ if (obj->update_area) gdk_region_offset (obj->update_area, dx, dy); gdk_window_compute_parent_pos (impl, &parent_pos); parent_pos.x += obj->x; parent_pos.y += obj->y; parent_pos.win32_x += impl->position_info.x; parent_pos.win32_y += impl->position_info.y; parent_pos.clip_rect = impl->position_info.clip_rect; gdk_window_tmp_unset_bg (window); native_invalidate_region = CreateRectRgn (0, 0, 0, 0); if (native_invalidate_region == NULL) WIN32_API_FAILED ("CreateRectRgn"); API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window), dx, dy, NULL, NULL, native_invalidate_region, NULL, SW_SCROLLCHILDREN)); if (impl->position_info.no_bg) gdk_window_tmp_reset_bg (window); tmp_list = obj->children; while (tmp_list) { GDK_WINDOW_OBJECT(tmp_list->data)->x += dx; GDK_WINDOW_OBJECT(tmp_list->data)->y += dy; gdk_window_postmove (tmp_list->data, &parent_pos, FALSE); tmp_list = tmp_list->next; } if (native_invalidate_region != NULL) { invalidate_region = _gdk_win32_hrgn_to_region (native_invalidate_region); gdk_region_offset (invalidate_region, impl->position_info.x_offset, impl->position_info.y_offset); gdk_window_invalidate_region (window, invalidate_region, TRUE); gdk_region_destroy (invalidate_region); GDI_CALL (DeleteObject, (native_invalidate_region)); } }
static gboolean gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, GdkDisplay *display, GdkEvent *event, XEvent *xevent) { GdkX11DeviceManagerCore *device_manager; GdkWindow *window; gboolean return_val; GdkToplevelX11 *toplevel = NULL; GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator); return_val = FALSE; window = get_event_window (translator, xevent); if (window) { if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window)) return FALSE; toplevel = _gdk_x11_window_get_toplevel (window); g_object_ref (window); } event->any.window = window; event->any.send_event = xevent->xany.send_event ? TRUE : FALSE; if (window && GDK_WINDOW_DESTROYED (window)) { if (xevent->type != DestroyNotify) { return_val = FALSE; goto done; } } if (window && (xevent->type == MotionNotify || xevent->type == ButtonRelease)) { if (_gdk_x11_moveresize_handle_event (xevent)) { return_val = FALSE; goto done; } } /* We do a "manual" conversion of the XEvent to a * GdkEvent. The structures are mostly the same so * the conversion is fairly straightforward. We also * optionally print debugging info regarding events * received. */ return_val = TRUE; switch (xevent->type) { case KeyPress: if (window == NULL) { return_val = FALSE; break; } translate_key_event (display, device_manager, event, xevent); set_user_time (window, event); break; case KeyRelease: if (window == NULL) { return_val = FALSE; break; } /* Emulate detectable auto-repeat by checking to see * if the next event is a key press with the same * keycode and timestamp, and if so, ignoring the event. */ if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display)) { XEvent next_event; XPeekEvent (xevent->xkey.display, &next_event); if (next_event.type == KeyPress && next_event.xkey.keycode == xevent->xkey.keycode && next_event.xkey.time == xevent->xkey.time) { return_val = FALSE; break; } } translate_key_event (display, device_manager, event, xevent); break; case ButtonPress: GDK_NOTE (EVENTS, g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); if (window == NULL) { return_val = FALSE; break; } /* If we get a ButtonPress event where the button is 4 or 5, it's a Scroll event */ switch (xevent->xbutton.button) { case 4: /* up */ case 5: /* down */ case 6: /* left */ case 7: /* right */ event->scroll.type = GDK_SCROLL; if (xevent->xbutton.button == 4) event->scroll.direction = GDK_SCROLL_UP; else if (xevent->xbutton.button == 5) event->scroll.direction = GDK_SCROLL_DOWN; else if (xevent->xbutton.button == 6) event->scroll.direction = GDK_SCROLL_LEFT; else event->scroll.direction = GDK_SCROLL_RIGHT; event->scroll.window = window; event->scroll.time = xevent->xbutton.time; event->scroll.x = (gdouble) xevent->xbutton.x; event->scroll.y = (gdouble) xevent->xbutton.y; event->scroll.x_root = (gdouble) xevent->xbutton.x_root; event->scroll.y_root = (gdouble) xevent->xbutton.y_root; event->scroll.state = (GdkModifierType) xevent->xbutton.state; event->scroll.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } break; default: event->button.type = GDK_BUTTON_PRESS; event->button.window = window; event->button.time = xevent->xbutton.time; event->button.x = (gdouble) xevent->xbutton.x; event->button.y = (gdouble) xevent->xbutton.y; event->button.x_root = (gdouble) xevent->xbutton.x_root; event->button.y_root = (gdouble) xevent->xbutton.y_root; event->button.axes = NULL; event->button.state = (GdkModifierType) xevent->xbutton.state; event->button.button = xevent->xbutton.button; event->button.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) return_val = FALSE; break; } set_user_time (window, event); break; case ButtonRelease: GDK_NOTE (EVENTS, g_message ("button release:\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); if (window == NULL) { return_val = FALSE; break; } /* We treat button presses as scroll wheel events, so ignore the release */ if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 || xevent->xbutton.button == 6 || xevent->xbutton.button == 7) { return_val = FALSE; break; } event->button.type = GDK_BUTTON_RELEASE; event->button.window = window; event->button.time = xevent->xbutton.time; event->button.x = (gdouble) xevent->xbutton.x; event->button.y = (gdouble) xevent->xbutton.y; event->button.x_root = (gdouble) xevent->xbutton.x_root; event->button.y_root = (gdouble) xevent->xbutton.y_root; event->button.axes = NULL; event->button.state = (GdkModifierType) xevent->xbutton.state; event->button.button = xevent->xbutton.button; event->button.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) return_val = FALSE; break; case MotionNotify: GDK_NOTE (EVENTS, g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s", xevent->xmotion.window, xevent->xmotion.x, xevent->xmotion.y, (xevent->xmotion.is_hint) ? "true" : "false")); if (window == NULL) { return_val = FALSE; break; } event->motion.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = xevent->xmotion.time; event->motion.x = (gdouble) xevent->xmotion.x; event->motion.y = (gdouble) xevent->xmotion.y; event->motion.x_root = (gdouble) xevent->xmotion.x_root; event->motion.y_root = (gdouble) xevent->xmotion.y_root; event->motion.axes = NULL; event->motion.state = (GdkModifierType) xevent->xmotion.state; event->motion.is_hint = xevent->xmotion.is_hint; event->motion.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } break; case EnterNotify: GDK_NOTE (EVENTS, g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); if (window == NULL) { return_val = FALSE; break; } if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } event->crossing.type = GDK_ENTER_NOTIFY; event->crossing.window = window; gdk_event_set_device (event, device_manager->core_pointer); /* If the subwindow field of the XEvent is non-NULL, then * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; event->crossing.x = (gdouble) xevent->xcrossing.x; event->crossing.y = (gdouble) xevent->xcrossing.y; event->crossing.x_root = (gdouble) xevent->xcrossing.x_root; event->crossing.y_root = (gdouble) xevent->xcrossing.y_root; event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); event->crossing.focus = xevent->xcrossing.focus; event->crossing.state = xevent->xcrossing.state; break; case LeaveNotify: GDK_NOTE (EVENTS, g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); if (window == NULL) { return_val = FALSE; break; } if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } event->crossing.type = GDK_LEAVE_NOTIFY; event->crossing.window = window; gdk_event_set_device (event, device_manager->core_pointer); /* If the subwindow field of the XEvent is non-NULL, then * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; event->crossing.x = (gdouble) xevent->xcrossing.x; event->crossing.y = (gdouble) xevent->xcrossing.y; event->crossing.x_root = (gdouble) xevent->xcrossing.x_root; event->crossing.y_root = (gdouble) xevent->xcrossing.y_root; event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); event->crossing.focus = xevent->xcrossing.focus; event->crossing.state = xevent->xcrossing.state; break; /* We only care about focus events that indicate that _this_ * window (not a ancestor or child) got or lost the focus */ case FocusIn: GDK_NOTE (EVENTS, g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s", xevent->xfocus.window, notify_details[xevent->xfocus.detail], notify_modes[xevent->xfocus.mode])); if (toplevel) { gboolean had_focus = HAS_FOCUS (toplevel); switch (xevent->xfocus.detail) { case NotifyAncestor: case NotifyVirtual: /* When the focus moves from an ancestor of the window to * the window or a descendent of the window, *and* the * pointer is inside the window, then we were previously * receiving keystroke events in the has_pointer_focus * case and are now receiving them in the * has_focus_window case. */ if (toplevel->has_pointer && xevent->xfocus.mode != NotifyGrab && xevent->xfocus.mode != NotifyUngrab) toplevel->has_pointer_focus = FALSE; /* fall through */ case NotifyNonlinear: case NotifyNonlinearVirtual: if (xevent->xfocus.mode != NotifyGrab && xevent->xfocus.mode != NotifyUngrab) toplevel->has_focus_window = TRUE; /* We pretend that the focus moves to the grab * window, so we pay attention to NotifyGrab * NotifyUngrab, and ignore NotifyWhileGrabbed */ if (xevent->xfocus.mode != NotifyWhileGrabbed) toplevel->has_focus = TRUE; break; case NotifyPointer: /* The X server sends NotifyPointer/NotifyGrab, * but the pointer focus is ignored while a * grab is in effect */ if (xevent->xfocus.mode != NotifyGrab && xevent->xfocus.mode != NotifyUngrab) toplevel->has_pointer_focus = TRUE; break; case NotifyInferior: case NotifyPointerRoot: case NotifyDetailNone: break; } if (HAS_FOCUS (toplevel) != had_focus) generate_focus_event (device_manager, window, TRUE); } break; case FocusOut: GDK_NOTE (EVENTS, g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s", xevent->xfocus.window, notify_details[xevent->xfocus.detail], notify_modes[xevent->xfocus.mode])); if (toplevel) { gboolean had_focus = HAS_FOCUS (toplevel); switch (xevent->xfocus.detail) { case NotifyAncestor: case NotifyVirtual: /* When the focus moves from the window or a descendent * of the window to an ancestor of the window, *and* the * pointer is inside the window, then we were previously * receiving keystroke events in the has_focus_window * case and are now receiving them in the * has_pointer_focus case. */ if (toplevel->has_pointer && xevent->xfocus.mode != NotifyGrab && xevent->xfocus.mode != NotifyUngrab) toplevel->has_pointer_focus = TRUE; /* fall through */ case NotifyNonlinear: case NotifyNonlinearVirtual: if (xevent->xfocus.mode != NotifyGrab && xevent->xfocus.mode != NotifyUngrab) toplevel->has_focus_window = FALSE; if (xevent->xfocus.mode != NotifyWhileGrabbed) toplevel->has_focus = FALSE; break; case NotifyPointer: if (xevent->xfocus.mode != NotifyGrab && xevent->xfocus.mode != NotifyUngrab) toplevel->has_pointer_focus = FALSE; break; case NotifyInferior: case NotifyPointerRoot: case NotifyDetailNone: break; } if (HAS_FOCUS (toplevel) != had_focus) generate_focus_event (device_manager, window, FALSE); } break; default: return_val = FALSE; } 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 gboolean gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, GdkDisplay *display, GdkEvent *event, XEvent *xevent) { GdkWindowImplX11 *impl; GdkX11DeviceManagerCore *device_manager; GdkWindow *window; gboolean return_val; int scale; GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator); window = get_event_window (translator, xevent); scale = 1; if (window) { if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window)) return FALSE; g_object_ref (window); impl = GDK_WINDOW_IMPL_X11 (window->impl); scale = impl->window_scale; } event->any.window = window; event->any.send_event = xevent->xany.send_event ? TRUE : FALSE; if (window && GDK_WINDOW_DESTROYED (window)) { if (xevent->type != DestroyNotify) { return_val = FALSE; goto done; } } if (window && (xevent->type == MotionNotify || xevent->type == ButtonRelease)) { if (_gdk_x11_moveresize_handle_event (xevent)) { return_val = FALSE; goto done; } } /* We do a "manual" conversion of the XEvent to a * GdkEvent. The structures are mostly the same so * the conversion is fairly straightforward. We also * optionally print debugging info regarding events * received. */ return_val = TRUE; switch (xevent->type) { case KeyPress: if (window == NULL) { return_val = FALSE; break; } translate_key_event (display, device_manager, event, xevent); set_user_time (window, event); break; case KeyRelease: if (window == NULL) { return_val = FALSE; break; } /* Emulate detectable auto-repeat by checking to see * if the next event is a key press with the same * keycode and timestamp, and if so, ignoring the event. */ if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display)) { XEvent next_event; XPeekEvent (xevent->xkey.display, &next_event); if (next_event.type == KeyPress && next_event.xkey.keycode == xevent->xkey.keycode && next_event.xkey.time == xevent->xkey.time) { return_val = FALSE; break; } } translate_key_event (display, device_manager, event, xevent); break; case ButtonPress: GDK_NOTE (EVENTS, g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); if (window == NULL) { return_val = FALSE; break; } /* If we get a ButtonPress event where the button is 4 or 5, it's a Scroll event */ switch (xevent->xbutton.button) { case 4: /* up */ case 5: /* down */ case 6: /* left */ case 7: /* right */ event->scroll.type = GDK_SCROLL; if (xevent->xbutton.button == 4) event->scroll.direction = GDK_SCROLL_UP; else if (xevent->xbutton.button == 5) event->scroll.direction = GDK_SCROLL_DOWN; else if (xevent->xbutton.button == 6) event->scroll.direction = GDK_SCROLL_LEFT; else event->scroll.direction = GDK_SCROLL_RIGHT; event->scroll.window = window; event->scroll.time = xevent->xbutton.time; event->scroll.x = (gdouble) xevent->xbutton.x / scale; event->scroll.y = (gdouble) xevent->xbutton.y / scale; event->scroll.x_root = (gdouble) xevent->xbutton.x_root / scale; event->scroll.y_root = (gdouble) xevent->xbutton.y_root / scale; event->scroll.state = (GdkModifierType) xevent->xbutton.state; event->scroll.device = device_manager->core_pointer; event->scroll.delta_x = 0; event->scroll.delta_y = 0; if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } break; default: event->button.type = GDK_BUTTON_PRESS; event->button.window = window; event->button.time = xevent->xbutton.time; event->button.x = (gdouble) xevent->xbutton.x / scale; event->button.y = (gdouble) xevent->xbutton.y / scale; event->button.x_root = (gdouble) xevent->xbutton.x_root / scale; event->button.y_root = (gdouble) xevent->xbutton.y_root / scale; event->button.axes = NULL; event->button.state = (GdkModifierType) xevent->xbutton.state; event->button.button = xevent->xbutton.button; event->button.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) return_val = FALSE; break; } set_user_time (window, event); break; case ButtonRelease: GDK_NOTE (EVENTS, g_message ("button release:\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); if (window == NULL) { return_val = FALSE; break; } /* We treat button presses as scroll wheel events, so ignore the release */ if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 || xevent->xbutton.button == 6 || xevent->xbutton.button == 7) { return_val = FALSE; break; } event->button.type = GDK_BUTTON_RELEASE; event->button.window = window; event->button.time = xevent->xbutton.time; event->button.x = (gdouble) xevent->xbutton.x / scale; event->button.y = (gdouble) xevent->xbutton.y / scale; event->button.x_root = (gdouble) xevent->xbutton.x_root / scale; event->button.y_root = (gdouble) xevent->xbutton.y_root / scale; event->button.axes = NULL; event->button.state = (GdkModifierType) xevent->xbutton.state; event->button.button = xevent->xbutton.button; event->button.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) return_val = FALSE; break; case MotionNotify: GDK_NOTE (EVENTS, g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s", xevent->xmotion.window, xevent->xmotion.x, xevent->xmotion.y, (xevent->xmotion.is_hint) ? "true" : "false")); if (window == NULL) { return_val = FALSE; break; } event->motion.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = xevent->xmotion.time; event->motion.x = (gdouble) xevent->xmotion.x / scale; event->motion.y = (gdouble) xevent->xmotion.y / scale; event->motion.x_root = (gdouble) xevent->xmotion.x_root / scale; event->motion.y_root = (gdouble) xevent->xmotion.y_root / scale; event->motion.axes = NULL; event->motion.state = (GdkModifierType) xevent->xmotion.state; event->motion.is_hint = xevent->xmotion.is_hint; event->motion.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } break; case EnterNotify: GDK_NOTE (EVENTS, g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); if (window == NULL) { return_val = FALSE; break; } if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } event->crossing.type = GDK_ENTER_NOTIFY; event->crossing.window = window; gdk_event_set_device (event, device_manager->core_pointer); /* If the subwindow field of the XEvent is non-NULL, then * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; event->crossing.x = (gdouble) xevent->xcrossing.x / scale; event->crossing.y = (gdouble) xevent->xcrossing.y / scale; event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale; event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale; event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); event->crossing.focus = xevent->xcrossing.focus; event->crossing.state = xevent->xcrossing.state; break; case LeaveNotify: GDK_NOTE (EVENTS, g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); if (window == NULL) { return_val = FALSE; break; } if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } event->crossing.type = GDK_LEAVE_NOTIFY; event->crossing.window = window; gdk_event_set_device (event, device_manager->core_pointer); /* If the subwindow field of the XEvent is non-NULL, then * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; event->crossing.x = (gdouble) xevent->xcrossing.x / scale; event->crossing.y = (gdouble) xevent->xcrossing.y / scale; event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale; event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale; event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); event->crossing.focus = xevent->xcrossing.focus; event->crossing.state = xevent->xcrossing.state; break; case FocusIn: case FocusOut: if (window) _gdk_device_manager_core_handle_focus (window, xevent->xfocus.window, device_manager->core_keyboard, NULL, xevent->type == FocusIn, xevent->xfocus.detail, xevent->xfocus.mode); return_val = FALSE; break; default: return_val = FALSE; } 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; }