emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9249365837: Add support for xwidgets to the PGTK port


From: Po Lu
Subject: master 9249365837: Add support for xwidgets to the PGTK port
Date: Tue, 28 Dec 2021 21:00:02 -0500 (EST)

branch: master
commit 9249365837c33e18f8504dcbf12b8c3d217f0d43
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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 78c952f805..7130e3535a 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 21c51ec386..26b910ba7e 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 c75dab5130..0814fb0df8 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 e76411cf02..034e4f3c83 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 <https://www.gnu.org/licenses/>.  */
 
+#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 63ac0555db..ffd61ebfa8 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -39,7 +39,11 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <webkit2/webkit2.h>
 #include <JavaScriptCore/JavaScript.h>
 #include <cairo.h>
+#ifndef HAVE_PGTK
 #include <X11/Xlib.h>
+#else
+#include <gtk/gtk.h>
+#endif
 #ifdef HAVE_XINPUT2
 #include <X11/extensions/XInput2.h>
 #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 a03006fde9..ef56dfa7c5 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -32,8 +32,12 @@ struct window;
 
 #if defined (USE_GTK)
 #include <gtk/gtk.h>
+#ifndef HAVE_PGTK
 #include <X11/Xlib.h>
 #include "xterm.h"
+#else
+#include "pgtkterm.h"
+#endif
 #elif defined (NS_IMPL_COCOA) && defined (__OBJC__)
 #import <AppKit/NSView.h>
 #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 *,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]