void _gdk_wayland_display_convert_selection (GdkDisplay *display, GdkWindow *requestor, GdkAtom selection, GdkAtom target, guint32 time) { GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); SelectionBuffer *buffer_data; if (!wayland_selection->offer) { GdkEvent *event; event = gdk_event_new (GDK_SELECTION_NOTIFY); event->selection.window = g_object_ref (requestor); event->selection.send_event = FALSE; event->selection.selection = selection; event->selection.target = target; event->selection.property = GDK_NONE; event->selection.time = GDK_CURRENT_TIME; event->selection.requestor = g_object_ref (requestor); gdk_event_put (event); gdk_event_free (event); return; } if (target != gdk_atom_intern_static_string ("TARGETS")) wl_data_offer_accept (wayland_selection->offer, _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)), gdk_atom_name (target)); buffer_data = g_hash_table_lookup (wayland_selection->selection_buffers, target); if (buffer_data) selection_buffer_add_requestor (buffer_data, requestor); else { GInputStream *stream = NULL; int pipe_fd[2], natoms = 0; GdkAtom *targets = NULL; if (target == gdk_atom_intern_static_string ("TARGETS")) { gint i = 0; GList *l; natoms = g_list_length (wayland_selection->targets); targets = g_new0 (GdkAtom, natoms); for (l = wayland_selection->targets; l; l = l->next) targets[i++] = l->data; } else { g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL); wl_data_offer_receive (wayland_selection->offer, gdk_atom_name (target), pipe_fd[1]); stream = g_unix_input_stream_new (pipe_fd[0], TRUE); close (pipe_fd[1]); } buffer_data = selection_buffer_new (stream, selection, target); selection_buffer_add_requestor (buffer_data, requestor); if (stream) g_object_unref (stream); if (targets) { /* Store directly the local atoms */ selection_buffer_append_data (buffer_data, targets, natoms * sizeof (GdkAtom)); g_free (targets); } g_hash_table_insert (wayland_selection->selection_buffers, GDK_ATOM_TO_POINTER (target), buffer_data); } if (!buffer_data->stream) selection_buffer_notify (buffer_data); }
/* We only care about focus events that indicate that _this_ * window (not a ancestor or child) got or lost the focus */ void _gdk_device_manager_core_handle_focus (GdkWindow *window, Window original, GdkDevice *device, GdkDevice *source_device, gboolean focus_in, int detail, int mode) { GdkToplevelX11 *toplevel; GdkX11Screen *x11_screen; gboolean had_focus; g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_DEVICE (device)); g_return_if_fail (source_device == NULL || GDK_IS_DEVICE (source_device)); GDK_NOTE (EVENTS, g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s", GDK_WINDOW_XID (window), notify_details[detail], notify_modes[mode])); toplevel = _gdk_x11_window_get_toplevel (window); if (!toplevel) return; if (toplevel->focus_window == original) return; had_focus = HAS_FOCUS (toplevel); x11_screen = GDK_X11_SCREEN (gdk_window_get_screen (window)); switch (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 && !x11_screen->wmspec_check_window && mode != NotifyGrab && #ifdef XINPUT_2 mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab && #endif /* XINPUT_2 */ mode != NotifyUngrab) toplevel->has_pointer_focus = (focus_in) ? FALSE : TRUE; /* fall through */ case NotifyNonlinear: case NotifyNonlinearVirtual: if (mode != NotifyGrab && #ifdef XINPUT_2 mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab && #endif /* XINPUT_2 */ mode != NotifyUngrab) toplevel->has_focus_window = (focus_in) ? TRUE : FALSE; /* We pretend that the focus moves to the grab * window, so we pay attention to NotifyGrab * NotifyUngrab, and ignore NotifyWhileGrabbed */ if (mode != NotifyWhileGrabbed) toplevel->has_focus = (focus_in) ? TRUE : FALSE; break; case NotifyPointer: /* The X server sends NotifyPointer/NotifyGrab, * but the pointer focus is ignored while a * grab is in effect */ if (!x11_screen->wmspec_check_window && mode != NotifyGrab && #ifdef XINPUT_2 mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab && #endif /* XINPUT_2 */ mode != NotifyUngrab) toplevel->has_pointer_focus = (focus_in) ? TRUE : FALSE; break; case NotifyInferior: case NotifyPointerRoot: case NotifyDetailNone: default: break; } if (HAS_FOCUS (toplevel) != had_focus) { GdkEvent *event; event = gdk_event_new (GDK_FOCUS_CHANGE); event->focus_change.window = g_object_ref (window); event->focus_change.send_event = FALSE; event->focus_change.in = focus_in; gdk_event_set_device (event, device); if (source_device) gdk_event_set_source_device (event, source_device); gdk_event_put (event); gdk_event_free (event); } }
/* dir is either ZOOM_IN, ZOOM_OUT or ZOOM_FULL which are defined in globals.h */ void a_zoom(GschemToplevel *w_current, GschemPageView *page_view, int dir, int selected_from) { g_return_if_fail (page_view != NULL); GschemPageGeometry *geometry = gschem_page_view_get_page_geometry (page_view); g_return_if_fail (geometry != NULL); double world_pan_center_x,world_pan_center_y,relativ_zoom_factor = - 1; int start_x, start_y; double top, bottom, right, left; /* NB: w_current->zoom_gain is a percentage increase */ switch(dir) { case(ZOOM_IN): relativ_zoom_factor = (100.0 + w_current->zoom_gain) / 100.0; break; case(ZOOM_OUT): relativ_zoom_factor = 100.0 / (100.0 + w_current->zoom_gain); break; case(ZOOM_FULL): /* indicate the zoom full with a negative zoomfactor */ relativ_zoom_factor = -1; break; } /* calc center: either "mouse_to_world" or center=center or a virtual center if warp_cursor is disabled */ if (w_current->zoom_with_pan == TRUE && selected_from == HOTKEY) { if (!x_event_get_pointer_position(w_current, FALSE, &start_x, &start_y)) return; if ( w_current->warp_cursor ) { world_pan_center_x = start_x; world_pan_center_y = start_y; } else { left = ((geometry->viewport_left - start_x) * (1/relativ_zoom_factor) + start_x); right = ((geometry->viewport_right - start_x) * (1/relativ_zoom_factor) + start_x); top = ((geometry->viewport_top - start_y) * (1/relativ_zoom_factor) + start_y); bottom = ((geometry->viewport_bottom - start_y) * (1/relativ_zoom_factor) + start_y); world_pan_center_x = (right + left) / 2; world_pan_center_y = (top + bottom) / 2; } } else { world_pan_center_x = (double) (geometry->viewport_left + geometry->viewport_right) / 2; world_pan_center_y = (double) (geometry->viewport_top + geometry->viewport_bottom) / 2; } #if DEBUG printf("relative zoomfactor: %E\n", relativ_zoom_factor); printf("new center: x: %E, y: %E \n", world_pan_center_x, world_pan_center_y); #endif /* calculate new window and draw it */ gschem_page_view_pan_general (page_view, world_pan_center_x, world_pan_center_y, relativ_zoom_factor); /* Before warping the cursor, filter out any consecutive scroll events * from the event queue. If the program receives more than one scroll * event before it can process the first one, then the globals mouse_x * and mouse_y won't contain the proper mouse position, * because the handler for the mouse moved event needs to * run first to set these values. */ GdkEvent *topEvent = gdk_event_get(); while( topEvent != NULL ) { if( topEvent->type != GDK_SCROLL ) { gdk_event_put( topEvent ); gdk_event_free( topEvent ); break; } gdk_event_free( topEvent ); topEvent = gdk_event_get(); } /* warp the cursor to the right position */ if (w_current->warp_cursor) { gschem_page_view_WORLDtoSCREEN (page_view, world_pan_center_x, world_pan_center_y, &start_x, &start_y); x_basic_warp_cursor (GTK_WIDGET (page_view), start_x, start_y); } }