From: Po Lu <luangruo@yahoo.com>
Date: Tue, 30 Nov 2021 00:16:50 +0000 (+0800)
Subject: Merge remote-tracking branch 'origin/master' into feature/pgtk
X-Git-Tag: emacs-29.0.90~3649
X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=8f5d2a3181d22f858ede3fb6a1452f99272901fe;p=emacs.git

Merge remote-tracking branch 'origin/master' into feature/pgtk
---

8f5d2a3181d22f858ede3fb6a1452f99272901fe
diff --cc configure.ac
index d68cf42145a,c36dffde84c..fffac4c2e61
--- a/configure.ac
+++ b/configure.ac
@@@ -2246,11 -2303,9 +2310,14 @@@ dnl use the toolkit if we have gtk, or 
    w32 )
      term_header=w32term.h
    ;;
 +  pgtk )
 +    term_header=pgtkterm.h
 +    with_gtk3=yes
 +    USE_X_TOOLKIT=none
 +  ;;
+   haiku )
+     term_header=haikuterm.h
+   ;;
  esac
  
  if test "$window_system" = none && test "X$with_x" != "Xno"; then
@@@ -2582,7 -2637,8 +2649,9 @@@ f
  
  ### Use -lrsvg-2 if available, unless '--with-rsvg=no' is specified.
  HAVE_RSVG=no
- if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${window_system}" = "pgtk" || test "${opsys}" = "mingw32"; then
+ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" \
 -   || test "${opsys}" = "mingw32" || test "${HAVE_BE_APP}" = "yes"; then
++   || test "${opsys}" = "mingw32" || test "${HAVE_BE_APP}" = "yes" \
++   || test "${window_system}" = "pgtk"; then
    if test "${with_rsvg}" != "no"; then
      RSVG_REQUIRED=2.14.0
      RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED"
@@@ -2625,7 -2682,8 +2695,8 @@@ if test "${with_webp}" != "no"; the
  fi
  
  HAVE_IMAGEMAGICK=no
- if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${window_system}" = "pgtk" || test "${HAVE_W32}" = "yes"; then
+ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes" || \
 -   test "${HAVE_BE_APP}" = "yes"; then
++   test "${HAVE_BE_APP}" = "yes" || test "${window_system}" = "pgtk"; then
    if test "${with_imagemagick}" != "no"; then
      if test -n "$BREW"; then
        # Homebrew doesn't link ImageMagick 6 by default, so make sure
@@@ -3691,8 -3762,8 +3833,9 @@@ AC_SUBST(LIBXPM
  ### Use -ljpeg if available, unless '--with-jpeg=no'.
  HAVE_JPEG=no
  LIBJPEG=
- if test "${HAVE_X11}" = "yes" || test "$window_system" = "pgtk" || test "${HAVE_W32}" = "yes" \
-    || test "${HAVE_NS}" = "yes"; then
+ if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
 -   || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes"; then
++   || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
++   || test "$window_system" = "pgtk"; then
    if test "${with_jpeg}" != "no"; then
      AC_CACHE_CHECK([for jpeglib 6b or later],
        [emacs_cv_jpeglib],
@@@ -4009,8 -4080,8 +4152,9 @@@ if test "${with_png}" != no; the
    # mingw32 loads the library dynamically.
    if test "$opsys" = mingw32; then
      AC_CHECK_HEADER([png.h], [HAVE_PNG=yes])
-   elif test "${HAVE_X11}" = "yes" || test "$window_system" = "pgtk" || test "${HAVE_W32}" = "yes" \
-        || test "${HAVE_NS}" = "yes"; then
+   elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
 -       || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes"; then
++       || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
++       || test "$window_system" = "pgtk"; then
      EMACS_CHECK_MODULES([PNG], [libpng >= 1.0.0])
      if test $HAVE_PNG = yes; then
        LIBPNG=$PNG_LIBS
@@@ -4084,8 -4155,8 +4228,9 @@@ if test "${opsys}" = "mingw32"; the
    if test "${HAVE_TIFF}" = "yes"; then
      AC_DEFINE(HAVE_TIFF, 1, [Define to 1 if you have the tiff library (-ltiff).])
    fi
- elif test "${HAVE_X11}" = "yes" || test "${window_system}" = "pgtk" || test "${HAVE_W32}" = "yes" \
-      || test "${HAVE_NS}" = "yes"; then
+ elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
 -     || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes"; then
++     || test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes" \
++     || test "$window_system" = "pgtk"; then
    if test "${with_tiff}" != "no"; then
      AC_CHECK_HEADER(tiffio.h,
        [tifflibs="-lz -lm"
@@@ -4113,8 -4184,9 +4258,9 @@@ if test "${opsys}" = "mingw32"; the
    if test "${HAVE_GIF}" = "yes"; then
      AC_DEFINE(HAVE_GIF, 1, [Define to 1 if you have a gif (or ungif) library.])
    fi
- elif test "${HAVE_X11}" = "yes" -o "${window_system}" = "pgtk"  && test "${with_gif}" != "no" \
-         || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then
+ elif test "${HAVE_X11}" = "yes" && test "${with_gif}" != "no" \
+         || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes" \
 -	|| test "${HAVE_BE_APP}" = "yes"; then
++	|| test "${HAVE_BE_APP}" = "yes" || test "$window_system" = "pgtk"; then
    AC_CHECK_HEADER(gif_lib.h,
  # EGifPutExtensionLast only exists from version libungif-4.1.0b1.
  # Earlier versions can crash Emacs, but version 5.0 removes EGifPutExtensionLast.
@@@ -5613,9 -5752,17 +5827,20 @@@ if test "${HAVE_X_WINDOWS}" = "yes" ; t
      FONT_OBJ="$FONT_OBJ ftfont.o"
    fi
  fi
 +if test "${window_system}" = "pgtk"; then
 +   FONT_OBJ="ftfont.o ftcrfont.o"
 +fi
+ 
+ if test "${HAVE_BE_APP}" = "yes" ; then
+   if test "${HAVE_FREETYPE}" = "yes" || \
+      test "${HAVE_CAIRO}" = "yes"; then
+      FONT_OBJ="$FONT_OBJ ftfont.o"
+   fi
+   if test "${HAVE_CAIRO}" = "yes"; then
+     FONT_OBJ="$FONT_OBJ ftcrfont.o"
+   fi
+ fi
+ 
  if test "${HAVE_HARFBUZZ}" = "yes" ; then
    FONT_OBJ="$FONT_OBJ hbfont.o"
  fi
@@@ -6004,11 -6151,11 +6229,11 @@@ Configured for '${canonical}'
  #### Please respect alphabetical ordering when making additions.
  optsep=
  emacs_config_features=
- for opt in ACL CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
+ for opt in ACL BE_APP CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
   HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \
 - M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PNG RSVG SECCOMP \
 + M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PGTK PNG RSVG SECCOMP \
   SOUND THREADS TIFF TOOLKIT_SCROLL_BARS \
-  UNEXEC WEBP X11 XAW3D XDBE XFT XIM XPM XWIDGETS X_TOOLKIT \
+  UNEXEC WEBP X11 XAW3D XDBE XFT XIM XINPUT2 XPM XWIDGETS X_TOOLKIT \
   ZLIB; do
  
      case $opt in
diff --cc lib-src/emacsclient.c
index 1f3e72f81db,c55b29830df..bdf228aeaa9
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@@ -603,14 -603,11 +603,16 @@@ decode_options (int argc, char **argv
        alt_display = "ns";
  #elif defined (HAVE_NTGUI)
        alt_display = "w32";
+ #elif defined (HAVE_HAIKU)
+       alt_display = "be";
  #endif
  
 +#ifdef HAVE_PGTK
 +      display = egetenv ("WAYLAND_DISPLAY");
 +      alt_display = egetenv ("DISPLAY");
 +#else
        display = egetenv ("DISPLAY");
 +#endif
      }
  
    if (!display)
diff --cc lisp/cus-edit.el
index f91a7e228ed,b7c53a4dfed..ae71140e262
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@@ -2176,7 -2176,7 +2176,7 @@@ and `face'.
  ;;; The `custom' Widget.
  
  (defface custom-button
-   '((((type x w32 ns pgtk) (class color))	; Like default mode line
 -  '((((type x w32 ns haiku) (class color))	; Like default mode line
++  '((((type x w32 ns haiku pgtk) (class color))	; Like default mode line
       :box (:line-width 2 :style released-button)
       :background "lightgrey" :foreground "black"))
    "Face for custom buffer buttons if `custom-raised-buttons' is non-nil."
@@@ -2184,7 -2184,7 +2184,7 @@@
    :group 'custom-faces)
  
  (defface custom-button-mouse
-   '((((type x w32 ns pgtk) (class color))
 -  '((((type x w32 ns haiku) (class color))
++  '((((type x w32 ns haiku pgtk) (class color))
       :box (:line-width 2 :style released-button)
       :background "grey90" :foreground "black")
      (t
@@@ -2209,7 -2209,7 +2209,7 @@@
        (if custom-raised-buttons 'custom-button-mouse 'highlight))
  
  (defface custom-button-pressed
-   '((((type x w32 ns pgtk) (class color))
 -  '((((type x w32 ns haiku) (class color))
++  '((((type x w32 ns haiku pgtk) (class color))
       :box (:line-width 2 :style pressed-button)
       :background "lightgrey" :foreground "black")
      (t :inverse-video t))
diff --cc lisp/faces.el
index 5804f56378f,5ed6bd1766e..535fa44246e
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@@ -1172,9 -1172,8 +1172,8 @@@ an integer value.
             (:height
              'integerp)
             (:stipple
-             (and (memq (window-system frame) '(x ns pgtk)) ; No stipple on w32
-                  (mapcar (lambda (f)
-                            (cons (file-name-base f) f))
 -            (and (memq (window-system frame) '(x ns)) ; No stipple on w32 or haiku
++            (and (memq (window-system frame) '(x ns pgtk)) ; No stipple on w32 or haiku
+                  (mapcar #'list
                           (apply #'nconc
                                  (mapcar (lambda (dir)
                                            (and (file-readable-p dir)
@@@ -2823,7 -2831,7 +2831,7 @@@ Note: Other faces cannot inherit from t
    '((default
       :box (:line-width 1 :style released-button)
       :foreground "black")
-     (((type x w32 ns pgtk) (class color))
 -    (((type x w32 ns haiku) (class color))
++    (((type x w32 ns haiku pgtk) (class color))
       :background "grey75")
      (((type x) (class mono))
       :background "grey"))
diff --cc lisp/frame.el
index 5e54d8d9af7,1319759e74d..c9306ec46df
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@@ -1633,7 -1633,7 +1633,8 @@@ live frame and defaults to the selecte
  (declare-function x-frame-geometry "xfns.c" (&optional frame))
  (declare-function w32-frame-geometry "w32fns.c" (&optional frame))
  (declare-function ns-frame-geometry "nsfns.m" (&optional frame))
 +(declare-function pgtk-frame-geometry "pgtkfns.c" (&optional frame))
+ (declare-function haiku-frame-geometry "haikufns.c" (&optional frame))
  
  (defun frame-geometry (&optional frame)
    "Return geometric attributes of FRAME.
@@@ -1683,8 -1683,8 +1684,10 @@@ and width values are in pixels
        (w32-frame-geometry frame))
       ((eq frame-type 'ns)
        (ns-frame-geometry frame))
 +     ((eq frame-type 'pgtk)
 +      (pgtk-frame-geometry frame))
+      ((eq frame-type 'haiku)
+       (haiku-frame-geometry frame))
       (t
        (list
         '(outer-position 0 . 0)
@@@ -1809,7 -1809,7 +1812,8 @@@ of frames like calls to map a frame or 
  (declare-function x-frame-edges "xfns.c" (&optional frame type))
  (declare-function w32-frame-edges "w32fns.c" (&optional frame type))
  (declare-function ns-frame-edges "nsfns.m" (&optional frame type))
 +(declare-function pgtk-frame-edges "pgtkfns.c" (&optional frame type))
+ (declare-function haiku-frame-edges "haikufns.c" (&optional frame type))
  
  (defun frame-edges (&optional frame type)
    "Return coordinates of FRAME's edges.
@@@ -1833,15 -1833,15 +1837,18 @@@ FRAME.
        (w32-frame-edges frame type))
       ((eq frame-type 'ns)
        (ns-frame-edges frame type))
 +     ((eq frame-type 'pgtk)
 +      (pgtk-frame-edges frame type))
+      ((eq frame-type 'haiku)
+       (haiku-frame-edges frame type))
       (t
        (list 0 0 (frame-width frame) (frame-height frame))))))
  
  (declare-function w32-mouse-absolute-pixel-position "w32fns.c")
  (declare-function x-mouse-absolute-pixel-position "xfns.c")
  (declare-function ns-mouse-absolute-pixel-position "nsfns.m")
 +(declare-function pgtk-mouse-absolute-pixel-position "pgtkfns.c")
+ (declare-function haiku-mouse-absolute-pixel-position "haikufns.c")
  
  (defun mouse-absolute-pixel-position ()
    "Return absolute position of mouse cursor in pixels.
@@@ -1856,8 -1856,8 +1863,10 @@@ position (0, 0) of the selected frame'
        (w32-mouse-absolute-pixel-position))
       ((eq frame-type 'ns)
        (ns-mouse-absolute-pixel-position))
 +     ((eq frame-type 'pgtk)
 +      (pgtk-mouse-absolute-pixel-position))
+      ((eq frame-type 'haiku)
+       (haiku-mouse-absolute-pixel-position))
       (t
        (cons 0 0)))))
  
@@@ -1972,7 -1972,7 +1984,8 @@@ workarea attribute.
  (declare-function x-frame-list-z-order "xfns.c" (&optional display))
  (declare-function w32-frame-list-z-order "w32fns.c" (&optional display))
  (declare-function ns-frame-list-z-order "nsfns.m" (&optional display))
 +(declare-function pgtk-frame-list-z-order "pgtkfns.c" (&optional display))
+ (declare-function haiku-frame-list-z-order "haikufns.c" (&optional display))
  
  (defun frame-list-z-order (&optional display)
    "Return list of Emacs' frames, in Z (stacking) order.
@@@ -1993,8 -1993,8 +2006,10 @@@ Return nil if DISPLAY contains no Emac
        (w32-frame-list-z-order display))
       ((eq frame-type 'ns)
        (ns-frame-list-z-order display))
 +     ((eq frame-type 'pgtk)
-       (pgtk-frame-list-z-order display)))))
++      (pgtk-frame-list-z-order display))
+      ((eq frame-type 'haiku)
+       (haiku-frame-list-z-order display)))))
  
  (declare-function x-frame-restack "xfns.c" (frame1 frame2 &optional above))
  (declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above))
@@@ -2078,8 -2075,8 +2093,8 @@@ frame's display).
       ((eq frame-type 'w32)
        (with-no-warnings
         (> w32-num-mouse-buttons 0)))
-      ((memq frame-type '(x ns pgtk))
-       t)    ;; We assume X and NeXTstep *always* have a pointing device
 -     ((memq frame-type '(x ns haiku))
 -      t)    ;; We assume X, NeXTstep and Haiku *always* have a pointing device
++     ((memq frame-type '(x ns haiku pgtk))
++      t)    ;; We assume X, NeXTstep, GTK, and Haiku *always* have a pointing device
       (t
        (or (and (featurep 'xt-mouse)
  	       xterm-mouse-mode)
@@@ -2104,7 -2101,7 +2119,7 @@@ frames and several different fonts at o
  that use a window system such as X, and false for text-only terminals.
  DISPLAY can be a display name, a frame, or nil (meaning the selected
  frame's display)."
-   (not (null (memq (framep-on-display display) '(x w32 ns pgtk)))))
 -  (not (null (memq (framep-on-display display) '(x w32 ns haiku)))))
++  (not (null (memq (framep-on-display display) '(x w32 ns haiku haiku)))))
  
  (defun display-images-p (&optional display)
    "Return non-nil if DISPLAY can display images.
@@@ -2155,7 -2152,7 +2170,7 @@@ DISPLAY should be either a frame or a d
  If DISPLAY is omitted or nil, it defaults to the selected frame's display."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-screens display))
       (t
        1))))
@@@ -2175,7 -2172,7 +2190,7 @@@ with DISPLAY.  To get information for e
  `display-monitor-attributes-list'."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-pixel-height display))
       (t
        (frame-height (if (framep display) display (selected-frame)))))))
@@@ -2195,7 -2192,7 +2210,7 @@@ with DISPLAY.  To get information for e
  `display-monitor-attributes-list'."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-pixel-width display))
       (t
        (frame-width (if (framep display) display (selected-frame)))))))
@@@ -2233,7 -2230,7 +2248,7 @@@ For graphical terminals, note that on \
  refers to the height in millimeters for all physical monitors
  associated with DISPLAY.  To get information for each physical
  monitor, use `display-monitor-attributes-list'."
-   (and (memq (framep-on-display display) '(x w32 ns pgtk))
 -  (and (memq (framep-on-display display) '(x w32 ns haiku))
++  (and (memq (framep-on-display display) '(x w32 ns haiku pgtk))
         (or (cddr (assoc (or display (frame-parameter nil 'display))
  			display-mm-dimensions-alist))
  	   (cddr (assoc t display-mm-dimensions-alist))
@@@ -2254,7 -2251,7 +2269,7 @@@ For graphical terminals, note that on \
  refers to the width in millimeters for all physical monitors
  associated with DISPLAY.  To get information for each physical
  monitor, use `display-monitor-attributes-list'."
-   (and (memq (framep-on-display display) '(x w32 ns pgtk))
 -  (and (memq (framep-on-display display) '(x w32 ns haiku))
++  (and (memq (framep-on-display display) '(x w32 ns haiku pgtk))
         (or (cadr (assoc (or display (frame-parameter nil 'display))
  			display-mm-dimensions-alist))
  	   (cadr (assoc t display-mm-dimensions-alist))
@@@ -2272,7 -2269,7 +2287,7 @@@ DISPLAY can be a display name or a fram
  If DISPLAY is omitted or nil, it defaults to the selected frame's display."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-backing-store display))
       (t
        'not-useful))))
@@@ -2285,7 -2282,7 +2300,7 @@@ DISPLAY can be a display name or a fram
  If DISPLAY is omitted or nil, it defaults to the selected frame's display."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-save-under display))
       (t
        'not-useful))))
@@@ -2298,7 -2295,7 +2313,7 @@@ DISPLAY can be a display name or a fram
  If DISPLAY is omitted or nil, it defaults to the selected frame's display."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-planes display))
       ((eq frame-type 'pc)
        4)
@@@ -2313,7 -2310,7 +2328,7 @@@ DISPLAY can be a display name or a fram
  If DISPLAY is omitted or nil, it defaults to the selected frame's display."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-color-cells display))
       ((eq frame-type 'pc)
        16)
@@@ -2330,7 -2327,7 +2345,7 @@@ DISPLAY can be a display name or a fram
  If DISPLAY is omitted or nil, it defaults to the selected frame's display."
    (let ((frame-type (framep-on-display display)))
      (cond
-      ((memq frame-type '(x w32 ns pgtk))
 -     ((memq frame-type '(x w32 ns haiku))
++     ((memq frame-type '(x w32 ns haiku pgtk))
        (x-display-visual-class display))
       ((and (memq frame-type '(pc t))
  	   (tty-display-color-p display))
diff --cc lisp/international/mule-cmds.el
index 2b94a2845f7,b922f192a94..a4cbf22511c
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@@ -88,7 -88,7 +88,7 @@@
      (bindings--define-key map [separator-3] menu-bar-separator)
      (bindings--define-key map [set-terminal-coding-system]
        '(menu-item "For Terminal" set-terminal-coding-system
-         :enable (null (memq initial-window-system '(x w32 ns pgtk)))
 -        :enable (null (memq initial-window-system '(x w32 ns haiku)))
++        :enable (null (memq initial-window-system '(x w32 ns haiku pgtk)))
          :help "How to encode terminal output"))
      (bindings--define-key map [set-keyboard-coding-system]
        '(menu-item "For Keyboard" set-keyboard-coding-system
diff --cc lisp/menu-bar.el
index b9ca57f5c49,8c04e35a51f..bd110226618
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@@ -2540,7 -2539,7 +2539,8 @@@ See `menu-bar-mode' for more informatio
  
  (declare-function x-menu-bar-open "term/x-win" (&optional frame))
  (declare-function w32-menu-bar-open "term/w32-win" (&optional frame))
 +(declare-function pgtk-menu-bar-open "term/pgtk-win" (&optional frame))
+ (declare-function haiku-menu-bar-open "haikumenu.c" (&optional frame))
  
  (defun lookup-key-ignore-too-long (map key)
    "Call `lookup-key' and convert numeric values to nil."
@@@ -2677,6 -2677,7 +2678,8 @@@ If FRAME is nil or not given, use the s
      (cond
       ((eq type 'x) (x-menu-bar-open frame))
       ((eq type 'w32) (w32-menu-bar-open frame))
+      ((eq type 'haiku) (haiku-menu-bar-open frame))
++     ((eq type 'pgtk) (pgtk-menu-bar-open frame))
       ((and (null tty-menu-open-use-tmm)
  	   (not (zerop (or (frame-parameter nil 'menu-bar-lines) 0))))
        ;; Make sure the menu bar is up to date.  One situation where
diff --cc lisp/mwheel.el
index 4627142757b,6a853a35216..d04139d1489
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@@ -55,29 -55,41 +55,47 @@@
      (mouse-wheel-mode 1)))
  
  (defcustom mouse-wheel-down-event
-   (cond ((or (featurep 'w32-win) (featurep 'ns-win))
-          'wheel-up)
-         ((featurep 'pgtk-win)
-          '(mouse-4 wheel-up))
-         (t
-          'mouse-4))
+   (if (or (featurep 'w32-win) (featurep 'ns-win)
 -          (featurep 'haiku-win))
++          (featurep 'haiku-win) (featurep 'pgtk-win))
+       'wheel-up
+     'mouse-4)
    "Event used for scrolling down."
    :group 'mouse
    :type 'symbol
    :set 'mouse-wheel-change-button)
  
+ (defcustom mouse-wheel-down-alternate-event
 -  (when (featurep 'xinput2) 'wheel-up)
++  (if (featurep 'xinput2)
++      'wheel-up
++    (unless (featurep 'x)
++      'mouse-4))
+   "Alternative wheel down event to consider."
+   :group 'mouse
+   :type 'symbol
+   :version "29.1"
+   :set 'mouse-wheel-change-button)
+ 
  (defcustom mouse-wheel-up-event
-   (cond ((or (featurep 'w32-win) (featurep 'ns-win))
-          'wheel-down)
-         ((featurep 'pgtk-win)
-          '(mouse-5 wheel-down))
-         (t
-          'mouse-5))
+   (if (or (featurep 'w32-win) (featurep 'ns-win)
 -          (featurep 'haiku-win))
++          (featurep 'haiku-win) (feautrep 'pgtk-win))
+       'wheel-down
+     'mouse-5)
    "Event used for scrolling up."
    :group 'mouse
    :type 'symbol
    :set 'mouse-wheel-change-button)
  
+ (defcustom mouse-wheel-up-alternate-event
 -  (when (featurep 'xinput2) 'wheel-down)
++  (if (featurep 'xinput2)
++      'wheel-down
++    (unless (featurep 'x)
++      'mouse-5))
+   "Alternative wheel up event to consider."
+   :group 'mouse
+   :type 'symbol
+   :version "29.1"
+   :set 'mouse-wheel-change-button)
+ 
  (defcustom mouse-wheel-click-event 'mouse-2
    "Event that should be temporarily inhibited after mouse scrolling.
  The mouse wheel is typically on the mouse-2 button, so it may easily
@@@ -227,23 -239,27 +245,33 @@@ Also see `mouse-wheel-tilt-scroll'.
    "Function that does the job of scrolling right.")
  
  (defvar mouse-wheel-left-event
-   (cond ((or (featurep 'w32-win) (featurep 'ns-win))
-          'wheel-left)
-         ((featurep 'pgtk-win)
-          '(mouse-6 wheel-left))
-         (t
-          'mouse-6))
+   (if (or (featurep 'w32-win) (featurep 'ns-win)
 -          (featurep 'haiku-win))
++          (featurep 'haiku-win) (featurep 'pgtk-win))
+       'wheel-left
+     'mouse-6)
    "Event used for scrolling left.")
  
+ (defvar mouse-wheel-left-alternate-event
 -  (when (featurep 'xinput2) 'wheel-left)
++  (if (featurep 'xinput2)
++      'wheel-left
++    (unless (featurep 'x)
++      'mouse-8))
+   "Alternative wheel left event to consider.")
+ 
  (defvar mouse-wheel-right-event
-   (cond ((or (featurep 'w32-win) (featurep 'ns-win))
-          'wheel-right)
-         ((featurep 'pgtk-win)
-          '(mouse-7 wheel-right))
-         (t
-          'mouse-7))
+   (if (or (featurep 'w32-win) (featurep 'ns-win)
 -          (featurep 'haiku-win))
++          (featurep 'haiku-win) (featurep 'pgtk-win))
+       'wheel-right
+     'mouse-7)
    "Event used for scrolling right.")
  
+ (defvar mouse-wheel-right-alternate-event
 -  (when (featurep 'xinput2) 'wheel-right)
++  (if (featurep 'xinput2)
++      'wheel-right
++    (unless (featurep 'x)
++      'mouse-7))
+   "Alternative wheel right event to consider.")
+ 
  (defun mouse-wheel--get-scroll-window (event)
    "Return window for mouse wheel event EVENT.
  If `mouse-wheel-follow-mouse' is non-nil, return the window that
diff --cc lisp/net/eww.el
index 46e211171e6,e86d21f889c..0c66cf3a0d7
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@@ -239,7 -239,7 +239,7 @@@ parameter, and should return the (possi
    :version "29.1")
  
  (defface eww-form-submit
-   '((((type x w32 ns pgtk) (class color))	; Like default mode line
 -  '((((type x w32 ns haiku) (class color))	; Like default mode line
++  '((((type x w32 ns haiku pgtk) (class color))	; Like default mode line
       :box (:line-width 2 :style released-button)
       :background "#808080" :foreground "black"))
    "Face for eww buffer buttons."
@@@ -247,7 -247,7 +247,7 @@@
    :group 'eww)
  
  (defface eww-form-file
-   '((((type x w32 ns pgtk) (class color))	; Like default mode line
 -  '((((type x w32 ns haiku) (class color))	; Like default mode line
++  '((((type x w32 ns haiku pgtk) (class color))	; Like default mode line
       :box (:line-width 2 :style released-button)
       :background "#808080" :foreground "black"))
    "Face for eww buffer buttons."
@@@ -255,7 -255,7 +255,7 @@@
    :group 'eww)
  
  (defface eww-form-checkbox
-   '((((type x w32 ns pgtk) (class color))	; Like default mode line
 -  '((((type x w32 ns haiku) (class color))	; Like default mode line
++  '((((type x w32 ns haiku pgtk) (class color))	; Like default mode line
       :box (:line-width 2 :style released-button)
       :background "lightgrey" :foreground "black"))
    "Face for eww buffer buttons."
@@@ -263,7 -263,7 +263,7 @@@
    :group 'eww)
  
  (defface eww-form-select
-   '((((type x w32 ns pgtk) (class color))	; Like default mode line
 -  '((((type x w32 ns haiku) (class color))	; Like default mode line
++  '((((type x w32 ns haiku pgtk) (class color))	; Like default mode line
       :box (:line-width 2 :style released-button)
       :background "lightgrey" :foreground "black"))
    "Face for eww buffer buttons."
diff --cc src/Makefile.in
index d646001ccea,d276df22475..1a67d399497
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@@ -413,9 -428,11 +431,11 @@@ base_obj = dispnew.o frame.o scroll.o x
  	profiler.o decompress.o \
  	thread.o systhread.o \
  	$(if $(HYBRID_MALLOC),sheap.o) \
- 	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(PGTK_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
- 	$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ)
- obj = $(base_obj) $(NS_OBJC_OBJ)
+ 	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
+ 	$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
 -	$(HAIKU_OBJ)
++	$(HAIKU_OBJ) $(PGTK_OBJ)
+ doc_obj = $(base_obj) $(NS_OBJC_OBJ)
+ obj = $(doc_obj) $(HAIKU_CXX_OBJ)
  
  ## Object files used on some machine or other.
  ## These go in the DOC file on all machines in case they are needed.
diff --cc src/dispextern.h
index ef4d7d915f6,ff4e7293d85..0f316a2eaf9
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@@ -134,12 -134,11 +134,19 @@@ typedef Emacs_Pixmap Emacs_Pix_Context
  #define FACE_COLOR_TO_PIXEL(face_color, frame) face_color
  #endif
  
 +#ifdef HAVE_PGTK
 +#include "pgtkgui.h"
 +/* Following typedef needed to accommodate the MSDOS port, believe it or not.  */
 +typedef struct pgtk_display_info Display_Info;
 +typedef Emacs_Pixmap XImagePtr;
 +typedef XImagePtr XImagePtr_or_DC;
++#endif /* HAVE_PGTK */
++
+ #ifdef HAVE_HAIKU
+ #include "haikugui.h"
+ typedef struct haiku_display_info Display_Info;
+ typedef Emacs_Pixmap Emacs_Pix_Container;
+ typedef Emacs_Pixmap Emacs_Pix_Context;
  #endif
  
  #ifdef HAVE_WINDOW_SYSTEM
diff --cc src/dispnew.c
index 92d9eb1f700,a976bf94c5e..4faa7a7777b
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@@ -6453,14 -6453,10 +6453,19 @@@ init_display_interactive (void
      }
  #endif
  
 +#ifdef HAVE_PGTK
-   if (!inhibit_window_system
- #ifndef CANNOT_DUMP
-      && initialized
- #endif
-       )
++  if (!inhibit_window_system && !will_dump_p ())
 +    {
 +      Vinitial_window_system = Qpgtk;
++      Vwindow_system_version = make_fixnum (3);
++      return;
++    }
++#endif
++
+ #ifdef HAVE_HAIKU
+   if (!inhibit_window_system && !will_dump_p ())
+     {
+       Vinitial_window_system = Qhaiku;
        Vwindow_system_version = make_fixnum (1);
        return;
      }
diff --cc src/emacs.c
index adac8fc38ab,4734faf33c2..28b55d74f5a
--- a/src/emacs.c
+++ b/src/emacs.c
@@@ -2210,15 -2244,17 +2247,26 @@@ Using an Emacs configured with --with-x
        syms_of_fontset ();
  #endif /* HAVE_NS */
  
 +#ifdef HAVE_PGTK
 +      syms_of_pgtkterm ();
 +      syms_of_pgtkfns ();
 +      syms_of_pgtkselect ();
 +      syms_of_pgtkmenu ();
 +      syms_of_pgtkim ();
 +      syms_of_fontset ();
 +      syms_of_xsettings ();
++#endif /* HAVE_PGTK */
+ #ifdef HAVE_HAIKU
+       syms_of_haikuterm ();
+       syms_of_haikufns ();
+       syms_of_haikumenu ();
+       syms_of_haikufont ();
+       syms_of_haikuselect ();
+ #ifdef HAVE_NATIVE_IMAGE_API
+       syms_of_haikuimage ();
  #endif
+       syms_of_fontset ();
+ #endif /* HAVE_HAIKU */
  
        syms_of_gnutls ();
  
diff --cc src/frame.c
index 585be79bf23,33e9606e41d..98f1b80e423
--- a/src/frame.c
+++ b/src/frame.c
@@@ -225,8 -225,8 +225,9 @@@ Value is
   `x' for an Emacs frame that is really an X window,
   `w32' for an Emacs frame that is a window on MS-Windows display,
   `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
 - `pc' for a direct-write MS-DOS frame.
 + `pc' for a direct-write MS-DOS frame,
 + `pgtk' for an Emacs frame running on pure GTK.
+  `haiku' for an Emacs frame running in Haiku.
  See also `frame-live-p'.  */)
    (Lisp_Object object)
  {
@@@ -245,8 -245,8 +246,10 @@@
        return Qpc;
      case output_ns:
        return Qns;
 +    case output_pgtk:
 +      return Qpgtk;
+     case output_haiku:
+       return Qhaiku;
      default:
        emacs_abort ();
      }
@@@ -6035,7 -6023,7 +6038,8 @@@ syms_of_frame (void
    DEFSYM (Qw32, "w32");
    DEFSYM (Qpc, "pc");
    DEFSYM (Qns, "ns");
 +  DEFSYM (Qpgtk, "pgtk");
+   DEFSYM (Qhaiku, "haiku");
    DEFSYM (Qvisible, "visible");
    DEFSYM (Qbuffer_predicate, "buffer-predicate");
    DEFSYM (Qbuffer_list, "buffer-list");
diff --cc src/frame.h
index fa6cc4a5617,cb2bad71c5d..4060ee65c42
--- a/src/frame.h
+++ b/src/frame.h
@@@ -585,7 -585,7 +585,8 @@@ struct fram
      struct x_output *x;         /* From xterm.h.  */
      struct w32_output *w32;     /* From w32term.h.  */
      struct ns_output *ns;       /* From nsterm.h.  */
 +    struct pgtk_output *pgtk; /* From pgtkterm.h. */
+     struct haiku_output *haiku; /* From haikuterm.h. */
    }
    output_data;
  
@@@ -853,11 -853,11 +854,16 @@@ default_pixels_per_inch_y (void
  #else
  #define FRAME_NS_P(f) ((f)->output_method == output_ns)
  #endif
 +#ifndef HAVE_PGTK
 +#define FRAME_PGTK_P(f) false
 +#else
 +#define FRAME_PGTK_P(f) ((f)->output_method == output_pgtk)
 +#endif
+ #ifndef HAVE_HAIKU
+ #define FRAME_HAIKU_P(f) false
+ #else
+ #define FRAME_HAIKU_P(f) ((f)->output_method == output_haiku)
+ #endif
  
  /* FRAME_WINDOW_P tests whether the frame is a graphical window system
     frame.  */
@@@ -870,9 -870,9 +876,12 @@@
  #ifdef HAVE_NS
  #define FRAME_WINDOW_P(f) FRAME_NS_P(f)
  #endif
 +#ifdef HAVE_PGTK
 +#define FRAME_WINDOW_P(f) FRAME_PGTK_P(f)
 +#endif
+ #ifdef HAVE_HAIKU
+ #define FRAME_WINDOW_P(f) FRAME_HAIKU_P (f)
+ #endif
  #ifndef FRAME_WINDOW_P
  #define FRAME_WINDOW_P(f) ((void) (f), false)
  #endif
diff --cc src/ftcrfont.c
index 6a0411ff6d4,820b3c0bd0c..49b179b0efc
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@@ -22,10 -22,12 +22,14 @@@ along with GNU Emacs.  If not, see <htt
  #include <cairo-ft.h>
  
  #include "lisp.h"
- #ifndef HAVE_PGTK
+ #ifdef HAVE_X_WINDOWS
  #include "xterm.h"
 -#else /* Otherwise, Haiku */
++#elif HAVE_HAIKU
+ #include "haikuterm.h"
+ #include "haiku_support.h"
+ #include "termchar.h"
 +#else
 +#include "pgtkterm.h"
  #endif
  #include "blockinput.h"
  #include "charset.h"
@@@ -517,19 -525,44 +527,52 @@@ ftcrfont_draw (struct glyph_string *s
  
    block_input ();
  
- #ifndef HAVE_PGTK
+ #ifndef USE_BE_CAIRO
++#ifdef HAVE_X_WINDOWS
    cr = x_begin_cr_clip (f, s->gc);
 +#else
 +  cr = pgtk_begin_cr_clip (f);
 +#endif
+ #else
+   BView_draw_lock (FRAME_HAIKU_VIEW (f));
+   EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+   cr = haiku_begin_cr_clip (f, s);
+   if (!cr)
+     {
+       BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+       EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+       unblock_input ();
+       return 0;
+     }
+   BView_cr_dump_clipping (FRAME_HAIKU_VIEW (f), cr);
+ 
+   if (s->left_overhang && s->clip_head && !s->for_overlaps)
+     {
+       cairo_rectangle (cr, s->clip_head->x, 0,
+ 		       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+       cairo_clip (cr);
+     }
+ #endif
  
    if (with_background)
      {
- #ifndef HAVE_PGTK
+ #ifndef USE_BE_CAIRO
++#ifdef HAVE_X_WINDOWS
        x_set_cr_source_with_gc_background (f, s->gc);
 +#else
 +      pgtk_set_cr_source_with_color (f, s->xgcv.background);
 +#endif
+ #else
+       struct face *face = s->face;
+ 
+       uint32_t col = s->hl == DRAW_CURSOR ?
+ 	FRAME_CURSOR_COLOR (s->f).pixel : face->background;
+ 
+       cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
+ 			    GREEN_FROM_ULONG (col) / 255.0,
+ 			    BLUE_FROM_ULONG (col) / 255.0);
+ #endif
+       s->background_filled_p = 1;
        cairo_rectangle (cr, x, y - FONT_BASE (face->font),
  		       s->width, FONT_HEIGHT (face->font));
        cairo_fill (cr);
@@@ -545,21 -578,25 +588,33 @@@
                                                         glyphs[i].index,
                                                         NULL));
      }
- 
- #ifndef HAVE_PGTK
+ #ifndef USE_BE_CAIRO
++#ifdef HAVE_X_WINDOWS
    x_set_cr_source_with_gc_foreground (f, s->gc);
 +#else
 +  pgtk_set_cr_source_with_color (f, s->xgcv.foreground);
++#endif
+ #else
+   uint32_t col = s->hl == DRAW_CURSOR ?
+     FRAME_OUTPUT_DATA (s->f)->cursor_fg : face->foreground;
+ 
+   cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
+ 			GREEN_FROM_ULONG (col) / 255.0,
+ 			BLUE_FROM_ULONG (col) / 255.0);
  #endif
    cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
    cairo_show_glyphs (cr, glyphs, len);
- 
- #ifndef HAVE_PGTK
+ #ifndef USE_BE_CAIRO
++#ifdef HAVE_X_WINDOWS
    x_end_cr_clip (f);
 +#else
 +  pgtk_end_cr_clip (f);
 +#endif
- 
+ #else
+   haiku_end_cr_clip (cr);
+   EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
+   BView_draw_unlock (FRAME_HAIKU_VIEW (f));
+ #endif
    unblock_input ();
  
    return len;
diff --cc src/gtkutil.c
index d4823f813bc,8f8db4ed372..1cb90b85cf5
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@@ -4682,20 -4286,23 +4724,33 @@@ xg_event_is_for_scrollbar (struct fram
  {
    bool retval = 0;
  
+ #ifdef HAVE_XINPUT2
+   XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data;
+   if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
+ 	     && event->type == GenericEvent
+ 	     && (event->xgeneric.extension
+ 		 == FRAME_DISPLAY_INFO (f)->xi2_opcode)
+ 	     && ((event->xgeneric.evtype == XI_ButtonPress
+ 		  && xev->detail < 4)
+ 		 || (event->xgeneric.evtype == XI_Motion)))
+ 	    || (event->type == ButtonPress
+ 		&& event->xbutton.button < 4)))
+ #else
 -  if (f && event->type == ButtonPress && event->xbutton.button < 4)
 +  if (f
 +#ifndef HAVE_PGTK
 +      && event->type == ButtonPress && event->xbutton.button < 4
 +#else
 +      && event->type == GDK_BUTTON_PRESS && event->button.button < 4
 +#endif
 +      )
+ #endif /* HAVE_XINPUT2 */
      {
        /* Check if press occurred outside the edit widget.  */
 +#ifndef HAVE_PGTK
        GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
 +#else
 +      GdkDisplay *gdpy = FRAME_X_DISPLAY (f);
 +#endif
        GdkWindow *gwin;
  #ifdef HAVE_GTK3
  #if GTK_CHECK_VERSION (3, 20, 0)
@@@ -4709,17 -4316,30 +4764,37 @@@
  #else
        gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL);
  #endif
 -      retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget);
 +      retval = gwin != gtk_widget_get_window (f->output_data.xp->edit_widget);
+ #ifdef HAVE_XINPUT2
+       GtkWidget *grab = gtk_grab_get_current ();
+       if (event->type == GenericEvent
+ 	  && event->xgeneric.evtype == XI_Motion)
+ 	retval = retval || (grab && GTK_IS_SCROLLBAR (grab));
+ #endif
      }
+ #ifdef HAVE_XINPUT2
+   else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
+ 		  && event->type == GenericEvent
+ 		  && (event->xgeneric.extension
+ 		      == FRAME_DISPLAY_INFO (f)->xi2_opcode)
+ 		  && ((event->xgeneric.evtype == XI_ButtonRelease
+ 		       && xev->detail < 4)
+ 		      || (event->xgeneric.evtype == XI_Motion)))
+ 		 || ((event->type == ButtonRelease
+ 		      && event->xbutton.button < 4)
+ 		     || event->type == MotionNotify)))
+ #else
    else if (f
 +#ifndef HAVE_PGTK
             && ((event->type == ButtonRelease && event->xbutton.button < 4)
 +               || event->type == MotionNotify)
 +#else
 +           && ((event->type == GDK_BUTTON_RELEASE && event->button.button < 4)
 +               || event->type == GDK_MOTION_NOTIFY)
 +#endif
 +	   )
+                || event->type == MotionNotify))
+ #endif /* HAVE_XINPUT2 */
      {
        /* If we are releasing or moving the scroll bar, it has the grab.  */
        GtkWidget *w = gtk_grab_get_current ();
diff --cc src/image.c
index a41a2a16a64,f2597f529d1..da23b66cb5e
--- a/src/image.c
+++ b/src/image.c
@@@ -473,47 -452,9 +495,52 @@@ image_create_bitmap_from_data (struct f
        return -1;
  #endif
  
 +#ifdef HAVE_PGTK
 +  GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
 +				      FALSE,
 +				      8,
 +				      width,
 +				      height);
 +  {
 +    char *sp = bits;
 +    int mask = 0x01;
 +    unsigned char *buf = gdk_pixbuf_get_pixels (pixbuf);
 +    int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 +    for (int y = 0; y < height; y++)
 +      {
 +	unsigned char *dp = buf + rowstride * y;
 +	for (int x = 0; x < width; x++)
 +	  {
 +	    if (*sp & mask)
 +	      {
 +		*dp++ = 0xff;
 +		*dp++ = 0xff;
 +		*dp++ = 0xff;
 +	      }
 +	    else
 +	      {
 +		*dp++ = 0x00;
 +		*dp++ = 0x00;
 +		*dp++ = 0x00;
 +	      }
 +	    if ((mask <<= 1) >= 0x100)
 +	      {
 +		mask = 0x01;
 +		sp++;
 +	      }
 +	  }
 +	if (mask != 0x01)
 +	  {
 +	    mask = 0x01;
 +	    sp++;
 +	  }
 +      }
 +  }
++#endif /* HAVE_PGTK */
++
+ #ifdef HAVE_HAIKU
+   void *bitmap = BBitmap_new (width, height, 1);
+   BBitmap_import_mono_bits (bitmap, bits, width, height);
  #endif
  
    id = image_allocate_bitmap_record (f);
@@@ -523,13 -464,11 +550,18 @@@
    dpyinfo->bitmaps[id - 1].depth = 1;
  #endif
  
 +#ifdef HAVE_PGTK
 +  dpyinfo->bitmaps[id - 1].img = pixbuf;
 +  dpyinfo->bitmaps[id - 1].depth = 1;
 +  dpyinfo->bitmaps[id - 1].pattern =
 +    image_create_pattern_from_pixbuf (f, pixbuf);
 +#endif
 +
+ #ifdef HAVE_HAIKU
+   dpyinfo->bitmaps[id - 1].img = bitmap;
+   dpyinfo->bitmaps[id - 1].depth = 1;
+ #endif
+ 
    dpyinfo->bitmaps[id - 1].file = NULL;
    dpyinfo->bitmaps[id - 1].height = height;
    dpyinfo->bitmaps[id - 1].width = width;
@@@ -678,11 -593,10 +710,15 @@@ free_bitmap_record (Display_Info *dpyin
    ns_release_object (bm->img);
  #endif
  
 +#ifdef HAVE_PGTK
 +  if (bm->pattern != NULL)
 +    cairo_pattern_destroy (bm->pattern);
 +#endif
 +
+ #ifdef HAVE_HAIKU
+   BBitmap_free (bm->img);
+ #endif
+ 
    if (bm->file)
      {
        xfree (bm->file);
@@@ -4186,7 -4152,7 +4282,7 @@@ enum xpm_keyword_inde
    XPM_LAST
  };
  
- #if defined HAVE_XPM || defined HAVE_NS || defined HAVE_PGTK
 -#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU
++#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
  /* Vector of image_keyword structures describing the format
     of valid XPM image specifications.  */
  
@@@ -4204,7 -4170,7 +4300,7 @@@ static const struct image_keyword xpm_f
    {":color-symbols",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
- #endif	/* HAVE_XPM || HAVE_NS */
 -#endif	/* HAVE_XPM || HAVE_NS || HAVE_HAIKU */
++#endif	/* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */
  
  #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
  
@@@ -4428,7 -4394,7 +4524,7 @@@ init_xpm_functions (void
  
  #endif /* WINDOWSNT */
  
- #if defined HAVE_XPM || defined HAVE_NS || defined HAVE_PGTK
 -#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU
++#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
  /* Value is true if COLOR_SYMBOLS is a valid color symbols list
     for XPM images.  Such a list must consist of conses whose car and
     cdr are strings.  */
@@@ -4464,9 -4430,9 +4560,9 @@@ xpm_image_p (Lisp_Object object
  	  && (! fmt[XPM_COLOR_SYMBOLS].count
  	      || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
  }
- #endif	/* HAVE_XPM || HAVE_NS */
 -#endif	/* HAVE_XPM || HAVE_NS || HAVE_HAIKU */
++#endif	/* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */
  
- #endif /* HAVE_XPM || USE_CAIRO || HAVE_NS */
+ #endif /* HAVE_XPM || USE_CAIRO || HAVE_NS || HAVE_HAIKU */
  
  #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
  ptrdiff_t
@@@ -4835,9 -4801,10 +4931,11 @@@ xpm_load (struct frame *f, struct imag
  #endif /* HAVE_XPM && !USE_CAIRO */
  
  #if (defined USE_CAIRO && defined HAVE_XPM)	\
-   || ((defined HAVE_NS || defined HAVE_PGTK) && !defined HAVE_XPM)
+   || (defined HAVE_NS && !defined HAVE_XPM)	\
 -  || (defined HAVE_HAIKU && !defined HAVE_XPM)
++  || (defined HAVE_HAIKU && !defined HAVE_XPM)  \
++  || (defined HAVE_PGTK && !defined HAVE_XPM)
  
- /* XPM support functions for NS where libxpm is not available, and for
+ /* XPM support functions for NS and Haiku where libxpm is not available, and for
     Cairo.  Only XPM version 3 (without any extensions) is supported.  */
  
  static void xpm_put_color_table_v (Lisp_Object, const char *,
@@@ -11155,7 -11121,7 +11262,7 @@@ static struct image_type const image_ty
   { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image,
     IMAGE_TYPE_INIT (init_jpeg_functions) },
  #endif
- #if defined HAVE_XPM || defined HAVE_NS || defined USE_CAIRO
 -#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU
++#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
   { SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
     IMAGE_TYPE_INIT (init_xpm_functions) },
  #endif
@@@ -11303,7 -11269,7 +11410,8 @@@ non-numeric, there is no explicit limi
    DEFSYM (Qxbm, "xbm");
    add_image_type (Qxbm);
  
- #if defined (HAVE_XPM) || defined (HAVE_NS) || defined (USE_CAIRO)
 -#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_HAIKU)
++#if defined (HAVE_XPM) || defined (HAVE_NS) \
++  || defined (HAVE_HAIKU) || defined (HAVE_PGTK)
    DEFSYM (Qxpm, "xpm");
    add_image_type (Qxpm);
  #endif
diff --cc src/menu.c
index 780b71eba6b,96d1c5208a9..b9da85ef3d5
--- a/src/menu.c
+++ b/src/menu.c
@@@ -422,7 -423,8 +423,8 @@@ single_menu_item (Lisp_Object key, Lisp
  		  AREF (item_properties, ITEM_PROPERTY_SELECTED),
  		  AREF (item_properties, ITEM_PROPERTY_HELP));
  
- #ifdef HAVE_EXT_MENU_BAR
+ #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
 -  || defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
++  || defined (HAVE_NTGUI) || defined (HAVE_HAIKU) || defined (HAVE_PGTK)
    /* Display a submenu using the toolkit.  */
    if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame))
        && ! (NILP (map) || NILP (enabled)))
diff --cc src/process.c
index 42743f6531a,241ffe9a8dd..eb27ddef45f
--- a/src/process.c
+++ b/src/process.c
@@@ -5588,12 -5588,17 +5588,19 @@@ wait_reading_process_output (intmax_t t
  	    timeout = make_timespec (0, 0);
  #endif
  
 -#if !defined USABLE_SIGIO && !defined WINDOWSNT
 +#if defined HAVE_PGTK
 +	  nfds = pgtk_select (max_desc + 1,
 +			      &Available, (check_write ? &Writeok : 0),
 +			      NULL, &timeout, NULL);
++#elif !defined USABLE_SIGIO && !defined WINDOWSNT
+ 	  /* If we're polling for input, don't get stuck in select for
+ 	     more than 25 msec. */
+ 	  struct timespec short_timeout = make_timespec (0, 25000000);
+ 	  if ((read_kbd || !NILP (wait_for_cell))
+ 	      && timespec_cmp (short_timeout, timeout) < 0)
+ 	    timeout = short_timeout;
 -#endif
 -
 +#elif defined HAVE_GLIB && !defined HAVE_NS
  	  /* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c.  */
 -#if defined HAVE_GLIB && !defined HAVE_NS
  	  nfds = xg_select (max_desc + 1,
  			    &Available, (check_write ? &Writeok : 0),
  			    NULL, &timeout, NULL);
diff --cc src/termhooks.h
index 7e8318c07af,1cf9863f3a1..f0c3ffd57b1
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@@ -61,7 -61,7 +61,8 @@@ enum output_metho
    output_msdos_raw,
    output_w32,
    output_ns,
 +  output_pgtk
+   output_haiku
  };
  
  /* Input queue declarations and hooks.  */
@@@ -449,7 -447,7 +453,8 @@@ struct termina
      struct x_display_info *x;         /* xterm.h */
      struct w32_display_info *w32;     /* w32term.h */
      struct ns_display_info *ns;       /* nsterm.h */
 +    struct pgtk_display_info *pgtk; /* pgtkterm.h */
+     struct haiku_display_info *haiku; /* haikuterm.h */
    } display_info;
  
  
@@@ -838,9 -836,9 +843,12 @@@ extern struct terminal *terminal_list
  #elif defined (HAVE_NS)
  #define TERMINAL_FONT_CACHE(t)						\
    (t->type == output_ns ? t->display_info.ns->name_list_element : Qnil)
 +#elif defined (HAVE_PGTK)
 +#define TERMINAL_FONT_CACHE(t)						\
 +  (t->type == output_pgtk ? t->display_info.pgtk->name_list_element : Qnil)
+ #elif defined (HAVE_HAIKU)
+ #define TERMINAL_FONT_CACHE(t)						\
+   (t->type == output_haiku ? t->display_info.haiku->name_list_element : Qnil)
  #endif
  
  extern struct terminal *decode_live_terminal (Lisp_Object);
diff --cc src/terminal.c
index dd2a8aa7188,b5f244ee318..a9ecb63d85d
--- a/src/terminal.c
+++ b/src/terminal.c
@@@ -445,8 -445,8 +445,10 @@@ possible return values.  */
        return Qpc;
      case output_ns:
        return Qns;
 +    case output_pgtk:
 +      return Qpgtk;
+     case output_haiku:
+       return Qhaiku;
      default:
        emacs_abort ();
      }
diff --cc src/xfaces.c
index 86ee18cd44a,813d89e5a3e..6f52637e916
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@@ -247,9 -247,9 +247,13 @@@ along with GNU Emacs.  If not, see <htt
  #define GCGraphicsExposures 0
  #endif /* HAVE_NS */
  
 +#ifdef HAVE_PGTK
 +#define GCGraphicsExposures 0
- #endif /* HAVE_NS */
++#endif /* HAVE_PGTK */
++
+ #ifdef HAVE_HAIKU
+ #define GCGraphicsExposures 0
+ #endif /* HAVE_HAIKU */
  #endif /* HAVE_WINDOW_SYSTEM */
  
  #include "buffer.h"