From 9249365837c33e18f8504dcbf12b8c3d217f0d43 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 29 Dec 2021 09:53:42 +0800 Subject: [PATCH] Add support for xwidgets to the PGTK port * src/emacsgtkfixed.c (EMACS_FIXED_GET_CLASS): New function. (struct GtkFixedPrivateL): New struct. (emacs_fixed_gtk_widget_size_allocate): (emacs_fixed_class_init): New functions. * src/keyboard.h: Declare lispy_function_keys also when HAVE_PGTK. * src/pgtkterm.c (x_free_frame_resources): Destroy all xwidget views. (pgtk_scroll_run): Move xwidget views that overlap with the scrolled area. (pgtk_emacs_to_gtk_modifiers): Expose function. * src/pgtkterm.h: Wrap in include guard. (pgtk_emacs_to_gtk_modifiers): New prototype. * src/xwidget.c (xw_forward_event_translate): (xw_forward_event_from_view): New functions. (Fmake_xwidget): Remove obsolete PGTK specific code. (Fxwidget_perform_lispy_event): Convert modifiers correctly on PGTK. (define_cursors): Use GDK functions to define cursors on PGTK. (xwidget_view_from_window): Disable on non-PGTK builds. (xwidget_show_view): (xwidget_hide_view): Implement on PGTK. (xv_do_draw): Disable on non-PGTK builds. (offscreen_damage_event): Queue xwidget views for draw. (xwidget_expose): Disable on non-PGTK builds. (xwidget_init_view): (x_draw_xwidget_glyph_string): (Fdelete_xwidget_view): Implement for PGTK. (syms_of_xwidget): Don't initialize XID to widget table on PGTK. (lower_frame_xwidget_views): Disable on PGTK. * src/xwidget.h (struct xwidget_view): New fields for PGTK builds. (kill_frame_xwidget_views): Enable on PGTK. --- src/emacsgtkfixed.c | 89 ++++++++++++++++ src/keyboard.h | 2 +- src/pgtkterm.c | 90 +++++++++++++++- src/pgtkterm.h | 4 + src/xwidget.c | 251 +++++++++++++++++++++++++++++++++++++++++--- src/xwidget.h | 11 ++ 6 files changed, 431 insertions(+), 16 deletions(-) diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c index 78c952f8054..7130e3535a7 100644 --- a/src/emacsgtkfixed.c +++ b/src/emacsgtkfixed.c @@ -63,6 +63,92 @@ EMACS_FIXED (GtkWidget *widget) EmacsFixed); } +#if defined HAVE_XWIDGETS && defined HAVE_PGTK + +static EmacsFixedClass * +EMACS_FIXED_GET_CLASS (GtkWidget *widget) +{ + return G_TYPE_INSTANCE_GET_CLASS (widget, emacs_fixed_get_type (), + EmacsFixedClass); +} + +struct GtkFixedPrivateL +{ + GList *children; +}; + +static void +emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + /* For xwidgets. + + This basically re-implements the base class method and adds an + additional case for an xwidget view. + + It would be nicer if the bse class method could be called first, + and the xview modification only would remain here. It wasn't + possible to solve it that way yet. */ + EmacsFixedClass *klass; + GtkWidgetClass *parent_class; + struct GtkFixedPrivateL *priv; + + klass = EMACS_FIXED_GET_CLASS (widget); + parent_class = g_type_class_peek_parent (klass); + parent_class->size_allocate (widget, allocation); + + priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, GTK_TYPE_FIXED, + struct GtkFixedPrivateL); + + gtk_widget_set_allocation (widget, allocation); + + if (gtk_widget_get_has_window (widget)) + { + if (gtk_widget_get_realized (widget)) + gdk_window_move_resize (gtk_widget_get_window (widget), + allocation->x, + allocation->y, + allocation->width, + allocation->height); + } + + for (GList *children = priv->children; children; children = children->next) + { + GtkFixedChild *child = children->data; + + if (!gtk_widget_get_visible (child->widget)) + continue; + + GtkRequisition child_requisition; + gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL); + + GtkAllocation child_allocation; + child_allocation.x = child->x; + child_allocation.y = child->y; + + if (!gtk_widget_get_has_window (widget)) + { + child_allocation.x += allocation->x; + child_allocation.y += allocation->y; + } + + child_allocation.width = child_requisition.width; + child_allocation.height = child_requisition.height; + + struct xwidget_view *xv + = g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW); + if (xv) + { + child_allocation.width = xv->clip_right; + child_allocation.height = xv->clip_bottom - xv->clip_top; + } + + gtk_widget_size_allocate (child->widget, &child_allocation); + } +} + +#endif /* HAVE_XWIDGETS && HAVE_PGTK */ + static void emacs_fixed_class_init (EmacsFixedClass *klass) { @@ -72,6 +158,9 @@ emacs_fixed_class_init (EmacsFixedClass *klass) widget_class->get_preferred_width = emacs_fixed_get_preferred_width; widget_class->get_preferred_height = emacs_fixed_get_preferred_height; +#if defined HAVE_XWIDGETS && defined HAVE_PGTK + widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate; +#endif g_type_class_add_private (klass, sizeof (EmacsFixedPrivate)); } diff --git a/src/keyboard.h b/src/keyboard.h index 21c51ec3862..26b910ba7e0 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -491,7 +491,7 @@ extern void process_pending_signals (void); extern struct timespec timer_check (void); extern void mark_kboards (void); -#if defined HAVE_NTGUI || defined HAVE_X_WINDOWS +#if defined HAVE_NTGUI || defined HAVE_X_WINDOWS || defined HAVE_PGTK extern const char *const lispy_function_keys[]; #endif diff --git a/src/pgtkterm.c b/src/pgtkterm.c index c75dab5130a..0814fb0df88 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -245,6 +245,9 @@ x_free_frame_resources (struct frame *f) block_input (); +#ifdef HAVE_XWIDGETS + kill_frame_xwidget_views (f); +#endif free_frame_faces (f); if (FRAME_X_OUTPUT (f)->scale_factor_atimer != NULL) @@ -2999,6 +3002,91 @@ pgtk_scroll_run (struct window *w, struct run *run) block_input (); +#ifdef HAVE_XWIDGETS + /* "Copy" xwidget views in the area that will be scrolled. */ + GtkWidget *tem, *parent = FRAME_GTK_WIDGET (f); + GList *children = gtk_container_get_children (GTK_CONTAINER (parent)); + GList *iter; + struct xwidget_view *view; + + for (iter = children; iter; iter = iter->next) + { + tem = iter->data; + view = g_object_get_data (G_OBJECT (tem), XG_XWIDGET_VIEW); + + if (view && !view->hidden) + { + int window_y = view->y + view->clip_top; + int window_height = view->clip_bottom - view->clip_top; + + Emacs_Rectangle r1, r2, result; + r1.x = w->pixel_left; + r1.y = from_y; + r1.width = w->pixel_width; + r1.height = height; + r2 = r1; + r2.y = window_y; + r2.height = window_height; + + /* The window is offscreen, just unmap it. */ + if (window_height == 0) + { + view->hidden = true; + gtk_widget_hide (tem); + continue; + } + + bool intersects_p = + gui_intersect_rectangles (&r1, &r2, &result); + + if (XWINDOW (view->w) == w && intersects_p) + { + int y = view->y + (to_y - from_y); + int text_area_x, text_area_y, text_area_width, text_area_height; + int clip_top, clip_bottom; + + window_box (w, view->area, &text_area_x, &text_area_y, + &text_area_width, &text_area_height); + + view->y = y; + + clip_top = 0; + clip_bottom = XXWIDGET (view->model)->height; + + if (y < text_area_y) + clip_top = text_area_y - y; + + if ((y + clip_bottom) > (text_area_y + text_area_height)) + { + clip_bottom -= (y + clip_bottom) - (text_area_y + text_area_height); + } + + view->clip_top = clip_top; + view->clip_bottom = clip_bottom; + + /* This means the view has moved offscreen. Unmap + it and hide it here. */ + if ((view->clip_bottom - view->clip_top) <= 0) + { + view->hidden = true; + gtk_widget_hide (tem); + } + else + { + gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (f)), + tem, view->x + view->clip_left, + view->y + view->clip_top); + gtk_widget_set_size_request (tem, view->clip_right - view->clip_left, + view->clip_bottom - view->clip_top); + gtk_widget_queue_allocate (tem); + } + } + } + } + + g_list_free (children); +#endif + /* Cursor off. Will be switched on again in x_update_window_end. */ gui_clear_cursor (w); @@ -5099,7 +5187,7 @@ pgtk_gtk_to_emacs_modifiers (struct pgtk_display_info *dpyinfo, int state) return mod; } -static int +int pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *dpyinfo, int state) { int mod_ctrl; diff --git a/src/pgtkterm.h b/src/pgtkterm.h index e76411cf021..034e4f3c835 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -17,6 +17,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ +#ifndef _PGTKTERM_H_ +#define _PGTKTERM_H_ #include "dispextern.h" #include "frame.h" @@ -660,5 +662,7 @@ extern bool xg_set_icon_from_xpm_data (struct frame *f, const char **data); extern bool pgtk_text_icon (struct frame *f, const char *icon_name); extern double pgtk_frame_scale_factor (struct frame *); +extern int pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *, int); #endif /* HAVE_PGTK */ +#endif /* _PGTKTERM_H_ */ diff --git a/src/xwidget.c b/src/xwidget.c index 63ac0555dbb..ffd61ebfa82 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -39,7 +39,11 @@ along with GNU Emacs. If not, see . */ #include #include #include +#ifndef HAVE_PGTK #include +#else +#include +#endif #ifdef HAVE_XINPUT2 #include #endif @@ -55,7 +59,9 @@ static Lisp_Object internal_xwidget_list; static uint32_t xwidget_counter = 0; #ifdef USE_GTK +#ifdef HAVE_X_WINDOWS static Lisp_Object x_window_to_xwv_map; +#endif static gboolean offscreen_damage_event (GtkWidget *, GdkEvent *, gpointer); static void synthesize_focus_in_event (GtkWidget *); static GdkDevice *find_suitable_keyboard (struct frame *); @@ -119,6 +125,102 @@ static void mouse_target_changed (WebKitWebView *, WebKitHitTestResult *, guint, gpointer); #endif +#ifdef HAVE_PGTK +static int +xw_forward_event_translate (GdkEvent *event, struct xwidget_view *xv, + struct xwidget *xw) +{ + GtkWidget *widget; + int new_x, new_y; + + switch (event->type) + { + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + widget = find_widget_at_pos (xw->widgetwindow_osr, + lrint (event->button.x - xv->clip_left), + lrint (event->button.y - xv->clip_top), + &new_x, &new_y); + if (widget) + { + event->any.window = gtk_widget_get_window (widget); + event->button.x = new_x; + event->button.y = new_y; + return 1; + } + return 0; + case GDK_SCROLL: + widget = find_widget_at_pos (xw->widgetwindow_osr, + lrint (event->scroll.x - xv->clip_left), + lrint (event->scroll.y - xv->clip_top), + &new_x, &new_y); + if (widget) + { + event->any.window = gtk_widget_get_window (widget); + event->scroll.x = new_x; + event->scroll.y = new_y; + return 1; + } + return 0; + case GDK_MOTION_NOTIFY: + widget = find_widget_at_pos (xw->widgetwindow_osr, + lrint (event->motion.x - xv->clip_left), + lrint (event->motion.y - xv->clip_top), + &new_x, &new_y); + if (widget) + { + event->any.window = gtk_widget_get_window (widget); + event->motion.x = new_x; + event->motion.y = new_y; + return 1; + } + return 0; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + widget = find_widget_at_pos (xw->widgetwindow_osr, + lrint (event->crossing.x - xv->clip_left), + lrint (event->crossing.y - xv->clip_top), + &new_x, &new_y); + if (widget) + { + event->any.window = gtk_widget_get_window (widget); + event->crossing.x = new_x; + event->crossing.y = new_y; + return 1; + } + return 0; + default: + return 0; + } +} + +static gboolean +xw_forward_event_from_view (GtkWidget *widget, GdkEvent *event, + gpointer user_data) +{ + struct xwidget_view *xv = user_data; + struct xwidget *xw = XXWIDGET (xv->model); + GdkEvent *eventcopy; + bool translated_p; + + if (NILP (xw->buffer)) + return TRUE; + + eventcopy = gdk_event_copy (event); + translated_p = xw_forward_event_translate (eventcopy, xv, xw); + record_osr_embedder (xv); + + g_object_ref (eventcopy->any.window); + if (translated_p) + gtk_main_do_event (eventcopy); + gdk_event_free (eventcopy); + + /* Don't propagate this event further. */ + return TRUE; +} +#endif DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, @@ -185,12 +287,9 @@ fails. */) # endif xw->widgetwindow_osr = gtk_offscreen_window_new (); -#ifndef HAVE_PGTK gtk_window_resize (GTK_WINDOW (xw->widgetwindow_osr), xw->width, xw->height); -#else gtk_container_check_resize (GTK_CONTAINER (xw->widgetwindow_osr)); -#endif if (EQ (xw->type, Qwebkit)) { @@ -389,10 +488,17 @@ selected frame is not an X-Windows frame. */) if (character < 32) character += '_'; +#ifndef HAVE_PGTK if (f) modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), modifiers); else modifiers = 0; +#else + if (f) + modifiers = pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f), modifiers); + else + modifiers = 0; +#endif } else if (SYMBOLP (event)) { @@ -414,11 +520,19 @@ selected frame is not an X-Windows frame. */) ++off; } +#ifndef HAVE_PGTK if (f) modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), XFIXNUM (XCAR (XCDR (decoded)))); else modifiers = 0; +#else + if (f) + modifiers = pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f), + XFIXNUM (XCAR (XCDR (decoded)))); + else + modifiers = 0; +#endif if (found) keycode = off + 0xff00; @@ -816,6 +930,9 @@ static void define_cursors (struct xwidget *xw, WebKitHitTestResult *res) { struct xwidget_view *xvw; +#ifdef HAVE_PGTK + GdkWindow *wdesc; +#endif xw->hit_result = webkit_hit_test_result_get_context (res); @@ -829,8 +946,16 @@ define_cursors (struct xwidget *xw, WebKitHitTestResult *res) if (XXWIDGET (xvw->model) == xw) { xvw->cursor = cursor_for_hit (xw->hit_result, xvw->frame); +#ifdef HAVE_X_WINDOWS if (xvw->wdesc != None) XDefineCursor (xvw->dpy, xvw->wdesc, xvw->cursor); +#else + if (gtk_widget_get_realized (xvw->widget)) + { + wdesc = gtk_widget_get_window (xvw->widget); + gdk_window_set_cursor (wdesc, xvw->cursor); + } +#endif } } } @@ -904,6 +1029,7 @@ run_file_chooser_cb (WebKitWebView *webview, return TRUE; } +#ifdef HAVE_X_WINDOWS static void xwidget_button_1 (struct xwidget_view *view, @@ -1173,6 +1299,8 @@ xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event) gdk_event_free (xg_event); } +#endif /* HAVE_X_WINDOWS */ + static void synthesize_focus_in_event (GtkWidget *offscreen_window) { @@ -1198,6 +1326,7 @@ synthesize_focus_in_event (GtkWidget *offscreen_window) gdk_event_free (focus_event); } +#ifdef HAVE_X_WINDOWS struct xwidget_view * xwidget_view_from_window (Window wdesc) { @@ -1209,16 +1338,24 @@ xwidget_view_from_window (Window wdesc) return XXWIDGET_VIEW (xwv); } +#endif static void xwidget_show_view (struct xwidget_view *xv) { xv->hidden = false; +#ifdef HAVE_X_WINDOWS XMoveWindow (xv->dpy, xv->wdesc, xv->x + xv->clip_left, xv->y + xv->clip_top); XMapWindow (xv->dpy, xv->wdesc); XFlush (xv->dpy); +#else + gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (xv->frame)), + xv->widget, xv->x + xv->clip_left, + xv->y + xv->clip_top); + gtk_widget_show_all (xv->widget); +#endif } /* Hide an xwidget view. */ @@ -1226,10 +1363,15 @@ static void xwidget_hide_view (struct xwidget_view *xv) { xv->hidden = true; +#ifdef HAVE_X_WINDOWS XUnmapWindow (xv->dpy, xv->wdesc); XFlush (xv->dpy); +#else + gtk_widget_hide (xv->widget); +#endif } +#ifndef HAVE_PGTK static void xv_do_draw (struct xwidget_view *xw, struct xwidget *w) { @@ -1261,6 +1403,37 @@ xv_do_draw (struct xwidget_view *xw, struct xwidget *w) unblock_input (); } +#else +static void +xwidget_view_draw_cb (GtkWidget *widget, cairo_t *cr, + gpointer data) +{ + struct xwidget_view *view = data; + struct xwidget *w = XXWIDGET (view->model); + GtkOffscreenWindow *wnd; + cairo_surface_t *surface; + + if (NILP (w->buffer)) + return; + + block_input (); + wnd = GTK_OFFSCREEN_WINDOW (w->widgetwindow_osr); + surface = gtk_offscreen_window_get_surface (wnd); + + cairo_save (cr); + if (surface) + { + cairo_translate (cr, -view->clip_left, + -view->clip_top); + cairo_set_source_surface (cr, surface, 0, 0); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + } + cairo_restore (cr); + + unblock_input (); +} +#endif /* When the off-screen webkit master view changes this signal is called. It copies the bitmap from the off-screen instance. */ @@ -1276,9 +1449,12 @@ offscreen_damage_event (GtkWidget *widget, GdkEvent *event, if (XWIDGET_VIEW_P (XCAR (tail))) { struct xwidget_view *view = XXWIDGET_VIEW (XCAR (tail)); - +#ifdef HAVE_X_WINDOWS if (view->wdesc && XXWIDGET (view->model) == xwidget) xv_do_draw (view, XXWIDGET (view->model)); +#else + gtk_widget_queue_draw (view->widget); +#endif } } @@ -1287,6 +1463,7 @@ offscreen_damage_event (GtkWidget *widget, GdkEvent *event, return FALSE; } +#ifdef HAVE_X_WINDOWS void xwidget_expose (struct xwidget_view *xv) { @@ -1294,6 +1471,7 @@ xwidget_expose (struct xwidget_view *xv) xv_do_draw (xv, xw); } +#endif #endif /* USE_GTK */ void @@ -1754,7 +1932,7 @@ xwidget_init_view (struct xwidget *xww, XSETWINDOW (xv->w, s->w); XSETXWIDGET (xv->model, xww); -#ifdef USE_GTK +#ifdef HAVE_X_WINDOWS xv->dpy = FRAME_X_DISPLAY (s->f); xv->x = x; @@ -1766,6 +1944,32 @@ xwidget_init_view (struct xwidget *xww, xv->clip_bottom = xww->height; xv->wdesc = None; + xv->frame = s->f; + xv->cursor = cursor_for_hit (xww->hit_result, s->f); + xv->just_resized = false; +#elif defined HAVE_PGTK + xv->dpyinfo = FRAME_DISPLAY_INFO (s->f); + xv->widget = gtk_drawing_area_new (); + gtk_widget_set_app_paintable (xv->widget, TRUE); + gtk_widget_add_events (xv->widget, GDK_ALL_EVENTS_MASK); + gtk_container_add (GTK_CONTAINER (FRAME_GTK_WIDGET (s->f)), + xv->widget); + + g_signal_connect (xv->widget, "draw", + G_CALLBACK (xwidget_view_draw_cb), xv); + g_signal_connect (xv->widget, "event", + G_CALLBACK (xw_forward_event_from_view), xv); + + g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, xv); + + xv->x = x; + xv->y = y; + + xv->clip_left = 0; + xv->clip_right = xww->width; + xv->clip_top = 0; + xv->clip_bottom = xww->height; + xv->frame = s->f; xv->cursor = cursor_for_hit (xww->hit_result, s->f); xv->just_resized = false; @@ -1847,13 +2051,13 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) bool moved = (xv->x + xv->clip_left != x + clip_left || xv->y + xv->clip_top != y + clip_top); -#ifdef USE_GTK +#ifdef HAVE_X_WINDOWS bool wdesc_was_none = xv->wdesc == None; #endif xv->x = x; xv->y = y; -#ifdef USE_GTK +#ifdef HAVE_X_WINDOWS block_input (); if (xv->wdesc == None) { @@ -1905,16 +2109,25 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) moved = false; } #endif +#ifdef HAVE_PGTK + block_input (); +#endif /* Has it moved? */ if (moved) { -#ifdef USE_GTK +#ifdef HAVE_X_WINDOWS XMoveResizeWindow (xv->dpy, xv->wdesc, x + clip_left, y + clip_top, clip_right - clip_left, clip_bottom - clip_top); XFlush (xv->dpy); cairo_xlib_surface_set_size (xv->cr_surface, clip_right - clip_left, clip_bottom - clip_top); +#elif defined HAVE_PGTK + gtk_widget_set_size_request (xv->widget, clip_right - clip_left, + clip_bottom - clip_top); + gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (xv->frame)), + xv->widget, x + clip_left, y + clip_top); + gtk_widget_queue_allocate (xv->widget); #elif defined NS_IMPL_COCOA nsxwidget_move_view (xv, x + clip_left, y + clip_top); #endif @@ -1930,6 +2143,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) || xv->clip_top != clip_top || xv->clip_left != clip_left) { #ifdef USE_GTK +#ifdef HAVE_X_WINDOWS if (!wdesc_was_none && !moved) { if (clip_right - clip_left <= 0 @@ -1947,6 +2161,12 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) cairo_xlib_surface_set_size (xv->cr_surface, clip_right - clip_left, clip_bottom - clip_top); } +#else + gtk_widget_set_size_request (xv->widget, clip_right - clip_left, + clip_bottom - clip_top); + gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (xv->frame)), + xv->widget, x + clip_left, y + clip_top); +#endif #elif defined NS_IMPL_COCOA nsxwidget_resize_view (xv, clip_right - clip_left, clip_bottom - clip_top); @@ -1975,7 +2195,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) #endif } } -#ifdef USE_GTK +#ifdef HAVE_X_WINDOWS else { XSetWindowBackground (xv->dpy, xv->wdesc, @@ -2324,7 +2544,7 @@ DEFUN ("delete-xwidget-view", #ifdef USE_GTK struct xwidget *xw = XXWIDGET (xv->model); GdkWindow *w; - +#ifdef HAVE_X_WINDOWS if (xv->wdesc != None) { block_input (); @@ -2334,6 +2554,9 @@ DEFUN ("delete-xwidget-view", Fremhash (make_fixnum (xv->wdesc), x_window_to_xwv_map); unblock_input (); } +#else + gtk_widget_destroy (xv->widget); +#endif if (xw->embedder_view == xv && !NILP (xw->buffer)) { @@ -2925,8 +3148,8 @@ syms_of_xwidget (void) internal_xwidget_view_list = Qnil; staticpro (&internal_xwidget_view_list); -#ifdef USE_GTK - x_window_to_xwv_map = CALLN (Fmake_hash_table, QCtest, Qeq); +#ifdef HAVE_X_WINDOWS + x_window_to_xwv_map = CALLN (Fmake_hash_table, QCtest,); Qeq staticpro (&x_window_to_xwv_map); #endif @@ -3115,7 +3338,7 @@ xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix) } } -#ifdef USE_GTK +#ifdef HAVE_X_WINDOWS void lower_frame_xwidget_views (struct frame *f) { @@ -3129,6 +3352,7 @@ lower_frame_xwidget_views (struct frame *f) XLowerWindow (xv->dpy, xv->wdesc); } } +#endif void kill_frame_xwidget_views (struct frame *f) @@ -3146,7 +3370,6 @@ kill_frame_xwidget_views (struct frame *f) for (; CONSP (rem); rem = XCDR (rem)) Fdelete_xwidget_view (XCAR (rem)); } -#endif static void kill_xwidget (struct xwidget *xw) diff --git a/src/xwidget.h b/src/xwidget.h index a03006fde9a..ef56dfa7c5a 100644 --- a/src/xwidget.h +++ b/src/xwidget.h @@ -32,8 +32,12 @@ struct window; #if defined (USE_GTK) #include +#ifndef HAVE_PGTK #include #include "xterm.h" +#else +#include "pgtkterm.h" +#endif #elif defined (NS_IMPL_COCOA) && defined (__OBJC__) #import #import "nsxwidget.h" @@ -107,8 +111,13 @@ struct xwidget_view enum glyph_row_area area; #if defined (USE_GTK) +#ifndef HAVE_PGTK Display *dpy; Window wdesc; +#else + struct pgtk_display_info *dpyinfo; + GtkWidget *widget; +#endif Emacs_Cursor cursor; struct frame *frame; @@ -190,7 +199,9 @@ extern struct xwidget *xwidget_from_id (uint32_t id); struct xwidget_view *xwidget_view_from_window (Window wdesc); void xwidget_expose (struct xwidget_view *xv); extern void lower_frame_xwidget_views (struct frame *f); +#endif extern void kill_frame_xwidget_views (struct frame *f); +#ifdef HAVE_X_WINDOWS extern void xwidget_button (struct xwidget_view *, bool, int, int, int, int, Time); extern void xwidget_motion_or_crossing (struct xwidget_view *, -- 2.39.2