1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-21 06:55:39 +00:00

Introduce Pure GTK3 port

* src/xsettings.h:

* src/xsettings.c:
(dpyinfo_valid, store_tool_bar_style_changed)
(XSETTINGS_FONT_NAME, get_prop_window, read_settings)
(apply_xft_settings, read_and_apply_settings)
(xft_settings_event, init_xsettings, xsettings_initialize):

* src/xfaces.c:
(x_create_gc, x_free_gc):

* src/xdisp.c (redisplay_tool_bar, redisplay_internal)
(draw_glyphs_debug, draw_glyphs, mouse_face_from_buffer_pos)
(note_mouse_highlight):

* src/terminal.c (Fterminal_live_p):

* src/termhooks.h (enum output_method, GCALIGNED_STRUCT)
(TERMINAL_FONT_CACHE):

* src/process.c (wait_reading_process_output):

* src/pgtkterm.h:

* src/pgtkterm.c:

* src/pgtkselect.h:

* src/pgtkselect.c:

* src/pgtkgui.h:

* src/pgtkfns.c:

* src/image.c:
(XGetPixel, XPutPixel, image_create_bitmap_from_data)
(image_create_bitmap_from_file, free_bitmap_record)
(image_destroy_x_image, gui_put_x_image, image_get_x_image)
(Create_Pixmap_From_Bitmap_Data, xbm_load_image, )
(xpm_load_image, lookup_rgb_color, image_disable_image)
(image_build_heuristic_mask, imagemagick_load_image):

* src/gtkutil.h:

* src/gtkutil.c (PGTK_TRACE, xg_set_screen, xg_display_open)
(xg_display_close, xg_create_default_cursor)
(xg_get_pixbuf_from_pix_and_mask, xg_check_special_colors)
(qttip_cb, hierarchy_ch_cb, xg_prepare_tooltip, )
(xg_show_tooltip, xg_hide_tooltip, xg_frame_resized)
(xg_frame_set_char_size, xg_height_or_width_changed)
(xg_set_widget_bg, style_changed_cb, xg_create_frame_widgets)
(xg_free_frame_widgets, x_wm_set_size_hint, xg_frame_restack)
(xg_mark_data, xg_update_frame_menubar, free_frame_menubar)
(xg_update_submenu, xg_finish_scroll_bar_creation)
(xg_update_scrollbar_pos, xg_update_horizontal_scrollbar_pos)
(xg_set_toolkit_scroll_bar_thumb, xg_event_is_for_scrollbar)
(draw_page, xg_pack_tool_bar, xg_create_tool_bar)
(xg_update_tool_bar_sizes, update_frame_tool_bar)
(free_frame_tool_bar, xg_change_toolbar_position):

* src/ftcrfont.c:
(ftcrfont_draw):

* src/fringe.c:
(init_fringe_bitmap):

* src/frame.h (GCALIGNED_STRUCT, FRAME_WINDOW_P):

* src/frame.c (Fframep):

* src/font.h:

* src/font.c (syms_of_font):

* src/emacsgtkfixed.c:
(emacs_fixed_get_preferred_width)
(emacs_fixed_get_preferred_height, XSetWMSizeHints):

* src/emacs.c (main):

* src/dispnew.c (init_display_interactive):

* src/dispextern.h:

* src/alloc.c:
(garbage_collect):

* src/Makefile.in (PGTK_OBJ, PGTK_LIBS, base_obj, LIBES):

* src/.gdbinit:

* lisp/url/url-privacy.el (url-setup-privacy-info):

* lisp/term/pgtk-win.el (featurep):

* lisp/startup.el (command-line, fancy-splash-frame):

* lisp/net/eww.el (eww-form-submit, eww-form-file)
(eww-form-checkbox, eww-form-select):

* lisp/mwheel.el (mouse-wheel-down-event, mouse-wheel-up-event):

* lisp/loadup.el (featurep):

* lisp/international/mule-cmds.el (set-coding-system-map):

* lisp/frame.el (pgtk-frame-geometry, frame-geometry)
(w32-frame-edges, frame-edges)
(pgtk-mouse-absolute-pixel-position)
(mouse-absolute-pixel-position)
(pgtk-set-mouse-absolute-pixel-position)
(pgtk-frame-list-z-order, frame-list-z-order)
(pgtk-frame-restack, frame-restack, display-mouse-p)
(display-graphic-p, display-symbol-keys-p, )
(display-pixel-height, display-mm-height, display-mm-width)
(display-backing-store, display-save-under, display-color-cells)
(display-planes, display-visual-class)
(pgtk-display-monitor-attributes-list)
(display-monitor-attributes-list):

* lisp/faces.el (face-spec-set-match-display, tool-bar):

* lisp/cus-edit.el (custom-button, custom-button-mouse)
(custom-button-pressed, custom-display):

* configure.ac (AUTO_DEPEND, XARGS_LIMIT, XWIDGETS_OBJ):
This commit is contained in:
Yuuki Harano 2017-10-28 16:16:29 +09:00 committed by Jeff Walsh
parent 2c7687738d
commit f6d8c5939b
42 changed files with 11535 additions and 133 deletions

View File

@ -1833,6 +1833,8 @@ window_system=none
AC_PATH_X
if test "$no_x" != yes; then
window_system=x11
else
window_system=pgtk
fi
LD_SWITCH_X_SITE_RPATH=
@ -2239,6 +2241,11 @@ dnl use the toolkit if we have gtk, or X11R5 or newer.
w32 )
term_header=w32term.h
;;
pgtk )
term_header=pgtkterm.h
with_gtk3=yes
USE_X_TOOLKIT=none
;;
esac
if test "$window_system" = none && test "X$with_x" != "Xno"; then
@ -2567,7 +2574,7 @@ fi
### Use -lrsvg-2 if available, unless '--with-rsvg=no' is specified.
HAVE_RSVG=no
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = "mingw32"; then
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${window_system}" = "pgtk" || test "${opsys}" = "mingw32"; then
if test "${with_rsvg}" != "no"; then
RSVG_REQUIRED=2.14.0
RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED"
@ -2588,7 +2595,7 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" =
fi
HAVE_IMAGEMAGICK=no
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes"; then
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${window_system}" = "pgtk" || test "${HAVE_W32}" = "yes"; then
if test "${with_imagemagick}" != "no"; then
if test -n "$BREW"; then
# Homebrew doesn't link ImageMagick 6 by default, so make sure
@ -2605,6 +2612,11 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}"
EMACS_CHECK_MODULES([IMAGEMAGICK], [Wand >= 6.3.5 Wand != 6.8.2])
fi
if test $HAVE_IMAGEMAGICK != yes; then
IMAGEMAGICK_MODULE="MagickWand-6.Q16HDRI >= 6.3.5 MagickWand-6.Q16HDRI != 6.8.2 MagickWand-6.Q16HDRI < 7 MagickCore-6.Q16HDRI >= 6.9.9 MagickCore-6.Q16HDRI < 7"
EMACS_CHECK_MODULES([IMAGEMAGICK], [$IMAGEMAGICK_MODULE])
fi
if test $HAVE_IMAGEMAGICK = yes; then
OLD_CFLAGS=$CFLAGS
OLD_LIBS=$LIBS
@ -2812,6 +2824,16 @@ AC_SUBST(XWIDGETS_OBJ)
CFLAGS=$OLD_CFLAGS
LIBS=$OLD_LIBS
PGTK_OBJ=
PGTK_LIBS=
if test "$window_system" = "pgtk"; then
PGTK_OBJ="pgtkfns.o pgtkterm.o pgtkselect.o xsettings.o"
PGTK_LIBS="$GTK_LIBS -ldl"
AC_DEFINE([HAVE_PGTK], 1, [Define to 1 if you have pure Gtk+-3.])
fi
AC_SUBST(PGTK_OBJ)
AC_SUBST(PGTK_LIBS)
dnl D-Bus has been tested under GNU/Linux only. Must be adapted for
dnl other platforms.
HAVE_DBUS=no
@ -2841,7 +2863,7 @@ AC_SUBST(DBUS_OBJ)
dnl GSettings has been tested under GNU/Linux only.
HAVE_GSETTINGS=no
if test "${HAVE_X11}" = "yes" && test "${with_gsettings}" = "yes"; then
if test "${HAVE_X11}" = "yes" -o "${window_system}" = "pgtk" && test "${with_gsettings}" = "yes"; then
EMACS_CHECK_MODULES([GSETTINGS], [gio-2.0 >= 2.26])
if test "$HAVE_GSETTINGS" = "yes"; then
old_CFLAGS=$CFLAGS
@ -2875,7 +2897,7 @@ fi
dnl GConf has been tested under GNU/Linux only.
dnl The version is really arbitrary, it is about the same age as Gtk+ 2.6.
HAVE_GCONF=no
if test "${HAVE_X11}" = "yes" && test "${with_gconf}" != "no"; then
if test "${HAVE_X11}" = "yes" -o "${window_system}" = "pgtk" && test "${with_gconf}" != "no"; then
EMACS_CHECK_MODULES([GCONF], [gconf-2.0 >= 2.13])
if test "$HAVE_GCONF" = yes; then
AC_DEFINE(HAVE_GCONF, 1, [Define to 1 if using GConf.])
@ -3437,10 +3459,34 @@ if test "${HAVE_X11}" = "yes"; then
fi
fi
else # "${HAVE_X11}" != "yes"
HAVE_XFT=no
HAVE_FREETYPE=no
HAVE_LIBOTF=no
HAVE_M17N_FLT=no
if test $window_system = pgtk; then
EMACS_CHECK_MODULES([FONTCONFIG], [fontconfig >= 2.2.0])
EMACS_CHECK_MODULES([FREETYPE], [freetype2])
if test "$HAVE_FONTCONFIG" != yes -o "$HAVE_FREETYPE" != yes; then
AC_MSG_ERROR(fontconfig and freetype is required.)
fi
HAVE_LIBOTF=no
AC_DEFINE(HAVE_FREETYPE, 1,
[Define to 1 if using the freetype and fontconfig libraries.])
if test "${with_libotf}" != "no"; then
EMACS_CHECK_MODULES([LIBOTF], [libotf])
if test "$HAVE_LIBOTF" = "yes"; then
AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
AC_CHECK_LIB(otf, OTF_get_variation_glyphs,
HAVE_OTF_GET_VARIATION_GLYPHS=yes,
HAVE_OTF_GET_VARIATION_GLYPHS=no)
if test "${HAVE_OTF_GET_VARIATION_GLYPHS}" = "yes"; then
AC_DEFINE(HAVE_OTF_GET_VARIATION_GLYPHS, 1,
[Define to 1 if libotf has OTF_get_variation_glyphs.])
fi
fi
fi
else
HAVE_XFT=no
HAVE_FREETYPE=no
HAVE_LIBOTF=no
HAVE_M17N_FLT=no
fi
fi # "${HAVE_X11}" != "yes"
HAVE_HARFBUZZ=no
@ -3452,6 +3498,7 @@ else
harfbuzz_required_ver=0.9.42
fi
if test "${HAVE_X11}" = "yes" && test "${HAVE_FREETYPE}" = "yes" \
|| test "$window_system" = "pgtk" \
|| test "${HAVE_W32}" = "yes"; then
if test "${with_harfbuzz}" != "no"; then
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= $harfbuzz_required_ver])
@ -3479,6 +3526,25 @@ AC_SUBST(LIBOTF_LIBS)
AC_SUBST(M17N_FLT_CFLAGS)
AC_SUBST(M17N_FLT_LIBS)
HAVE_CAIRO=no
if test "${HAVE_X11}" = "yes" -o "$window_system" = pgtk; then
if test "${with_cairo}" != "no"; then
CAIRO_REQUIRED=1.12.0
CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
EMACS_CHECK_MODULES(CAIRO, $CAIRO_MODULE)
if test $HAVE_CAIRO = yes; then
AC_DEFINE(USE_CAIRO, 1, [Define to 1 if using cairo.])
else
AC_MSG_ERROR([cairo requested but not found.])
fi
CFLAGS="$CFLAGS $CAIRO_CFLAGS"
LIBS="$LIBS $CAIRO_LIBS"
AC_SUBST(CAIRO_CFLAGS)
AC_SUBST(CAIRO_LIBS)
fi
fi
if test "${HAVE_X11}" = "yes"; then
AC_CHECK_HEADER(X11/Xlib-xcb.h,
AC_CHECK_LIB(xcb, xcb_translate_coordinates, HAVE_XCB=yes))
@ -3740,7 +3806,7 @@ if test "${with_png}" != no; then
# mingw32 loads the library dynamically.
if test "$opsys" = mingw32; then
AC_CHECK_HEADER([png.h], [HAVE_PNG=yes])
elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
elif test "${HAVE_X11}" = "yes" || test "$window_system" = "pgtk" || test "${HAVE_W32}" = "yes" \
|| test "${HAVE_NS}" = "yes"; then
EMACS_CHECK_MODULES([PNG], [libpng >= 1.0.0])
if test $HAVE_PNG = yes; then
@ -3815,7 +3881,7 @@ if test "${opsys}" = "mingw32"; then
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 "${HAVE_W32}" = "yes" \
elif test "${HAVE_X11}" = "yes" || test "${window_system}" = "pgtk" || test "${HAVE_W32}" = "yes" \
|| test "${HAVE_NS}" = "yes"; then
if test "${with_tiff}" != "no"; then
AC_CHECK_HEADER(tiffio.h,
@ -3844,7 +3910,7 @@ if test "${opsys}" = "mingw32"; then
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" && test "${with_gif}" != "no" \
elif test "${HAVE_X11}" = "yes" -o "${window_system}" = "pgtk" && test "${with_gif}" != "no" \
|| test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then
AC_CHECK_HEADER(gif_lib.h,
# EGifPutExtensionLast only exists from version libungif-4.1.0b1.
@ -5290,6 +5356,9 @@ if test "${HAVE_X_WINDOWS}" = "yes" ; then
FONT_OBJ="$FONT_OBJ ftfont.o"
fi
fi
if test "${window_system}" = "pgtk"; then
FONT_OBJ="ftfont.o ftcrfont.o"
fi
if test "${HAVE_HARFBUZZ}" = "yes" ; then
FONT_OBJ="$FONT_OBJ hbfont.o"
fi

View File

@ -2172,7 +2172,7 @@ and `face'."
;;; The `custom' Widget.
(defface custom-button
'((((type x w32 ns) (class color)) ; Like default mode line
'((((type x w32 ns 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."
@ -2180,7 +2180,7 @@ and `face'."
:group 'custom-faces)
(defface custom-button-mouse
'((((type x w32 ns) (class color))
'((((type x w32 ns pgtk) (class color))
:box (:line-width 2 :style released-button)
:background "grey90" :foreground "black")
(t
@ -2205,7 +2205,7 @@ and `face'."
(if custom-raised-buttons 'custom-button-mouse 'highlight))
(defface custom-button-pressed
'((((type x w32 ns) (class color))
'((((type x w32 ns pgtk) (class color))
:box (:line-width 2 :style pressed-button)
:background "lightgrey" :foreground "black")
(t :inverse-video t))
@ -3445,6 +3445,10 @@ MS Windows.")
:sibling-args (:help-echo "\
GNUstep or Macintosh OS Cocoa interface.")
ns)
(const :format "PGTK "
:sibling-args (:help-echo "\
Pure-GTK interface.")
ns)
(const :format "DOS "
:sibling-args (:help-echo "\
Plain MS-DOS.")

View File

@ -1487,7 +1487,7 @@ If FRAME is nil, the current FRAME is used."
match (cond ((eq req 'type)
(or (memq (window-system frame) options)
(and (memq 'graphic options)
(memq (window-system frame) '(x w32 ns)))
(memq (window-system frame) '(x w32 ns pgtk)))
;; FIXME: This should be revisited to use
;; display-graphic-p, provided that the
;; color selection depends on the number
@ -2755,7 +2755,7 @@ Note: Other faces cannot inherit from the cursor face."
'((default
:box (:line-width 1 :style released-button)
:foreground "black")
(((type x w32 ns) (class color))
(((type x w32 ns pgtk) (class color))
:background "grey75")
(((type x) (class mono))
:background "grey"))

View File

@ -1601,6 +1601,7 @@ live frame and defaults to the selected one."
(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))
(defun frame-geometry (&optional frame)
"Return geometric attributes of FRAME.
@ -1650,6 +1651,8 @@ 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))
(t
(list
'(outer-position 0 . 0)
@ -1696,6 +1699,7 @@ selected frame."
(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))
(defun frame-edges (&optional frame type)
"Return coordinates of FRAME's edges.
@ -1719,12 +1723,15 @@ FRAME."
(w32-frame-edges frame type))
((eq frame-type 'ns)
(ns-frame-edges frame type))
((eq frame-type 'pgtk)
(pgtk-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")
(defun mouse-absolute-pixel-position ()
"Return absolute position of mouse cursor in pixels.
@ -1739,9 +1746,12 @@ position (0, 0) of the selected frame's terminal."
(w32-mouse-absolute-pixel-position))
((eq frame-type 'ns)
(ns-mouse-absolute-pixel-position))
((eq frame-type 'pgtk)
(pgtk-mouse-absolute-pixel-position))
(t
(cons 0 0)))))
(declare-function pgtk-set-mouse-absolute-pixel-position "pgtkfns.c" (x y))
(declare-function ns-set-mouse-absolute-pixel-position "nsfns.m" (x y))
(declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y))
(declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y))
@ -1752,6 +1762,8 @@ The coordinates X and Y are interpreted in pixels relative to a
position (0, 0) of the selected frame's terminal."
(let ((frame-type (framep-on-display)))
(cond
((eq frame-type 'pgtk)
(pgtk-set-mouse-absolute-pixel-position x y))
((eq frame-type 'ns)
(ns-set-mouse-absolute-pixel-position x y))
((eq frame-type 'x)
@ -1850,6 +1862,7 @@ 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))
(defun frame-list-z-order (&optional display)
"Return list of Emacs' frames, in Z (stacking) order.
@ -1869,11 +1882,14 @@ Return nil if DISPLAY contains no Emacs frame."
((eq frame-type 'w32)
(w32-frame-list-z-order display))
((eq frame-type 'ns)
(ns-frame-list-z-order display)))))
(ns-frame-list-z-order display))
((eq frame-type 'pgtk)
(pgtk-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))
(declare-function ns-frame-restack "nsfns.m" (frame1 frame2 &optional above))
(declare-function pgtk-frame-restack "pgtkfns.c" (frame1 frame2 &optional above))
(defun frame-restack (frame1 frame2 &optional above)
"Restack FRAME1 below FRAME2.
@ -1903,7 +1919,9 @@ Some window managers may refuse to restack windows."
((eq frame-type 'w32)
(w32-frame-restack frame1 frame2 above))
((eq frame-type 'ns)
(ns-frame-restack frame1 frame2 above))))
(ns-frame-restack frame1 frame2 above))
((eq frame-type 'pgtk)
(pgtk-frame-restack frame1 frame2 above))))
(error "Cannot restack frames")))
(defun frame-size-changed-p (&optional frame)
@ -1950,7 +1968,7 @@ frame's display)."
((eq frame-type 'w32)
(with-no-warnings
(> w32-num-mouse-buttons 0)))
((memq frame-type '(x ns))
((memq frame-type '(x ns pgtk))
t) ;; We assume X and NeXTstep *always* have a pointing device
(t
(or (and (featurep 'xt-mouse)
@ -1976,7 +1994,7 @@ frames and several different fonts at once. This is true for displays
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)))))
(not (null (memq (framep-on-display display) '(x w32 ns pgtk)))))
(defun display-images-p (&optional display)
"Return non-nil if DISPLAY can display images.
@ -2004,7 +2022,7 @@ frame's display)."
;; a Windows DOS Box.
(with-no-warnings
(not (null dos-windows-version))))
((memq frame-type '(x w32 ns))
((memq frame-type '(x w32 ns pgtk))
t)
(t
nil))))
@ -2014,7 +2032,7 @@ frame's display)."
This means that, for example, DISPLAY can differentiate between
the keybinding RET and [return]."
(let ((frame-type (framep-on-display display)))
(or (memq frame-type '(x w32 ns pc))
(or (memq frame-type '(x w32 ns pc pgtk))
;; MS-DOS and MS-Windows terminals have built-in support for
;; function (symbol) keys
(memq system-type '(ms-dos windows-nt)))))
@ -2027,7 +2045,7 @@ DISPLAY should be either a frame or a display name (a string).
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))
((memq frame-type '(x w32 ns pgtk))
(x-display-screens display))
(t
1))))
@ -2047,7 +2065,7 @@ with DISPLAY. To get information for each physical monitor, use
`display-monitor-attributes-list'."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
((memq frame-type '(x w32 ns pgtk))
(x-display-pixel-height display))
(t
(frame-height (if (framep display) display (selected-frame)))))))
@ -2067,7 +2085,7 @@ with DISPLAY. To get information for each physical monitor, use
`display-monitor-attributes-list'."
(let ((frame-type (framep-on-display display)))
(cond
((memq frame-type '(x w32 ns))
((memq frame-type '(x w32 ns pgtk))
(x-display-pixel-width display))
(t
(frame-width (if (framep display) display (selected-frame)))))))
@ -2105,7 +2123,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
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))
(and (memq (framep-on-display display) '(x w32 ns pgtk))
(or (cddr (assoc (or display (frame-parameter nil 'display))
display-mm-dimensions-alist))
(cddr (assoc t display-mm-dimensions-alist))
@ -2126,7 +2144,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
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))
(and (memq (framep-on-display display) '(x w32 ns pgtk))
(or (cadr (assoc (or display (frame-parameter nil 'display))
display-mm-dimensions-alist))
(cadr (assoc t display-mm-dimensions-alist))
@ -2144,7 +2162,7 @@ DISPLAY can be a display name or a frame.
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))
((memq frame-type '(x w32 ns pgtk))
(x-display-backing-store display))
(t
'not-useful))))
@ -2157,7 +2175,7 @@ DISPLAY can be a display name or a frame.
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))
((memq frame-type '(x w32 ns pgtk))
(x-display-save-under display))
(t
'not-useful))))
@ -2170,7 +2188,7 @@ DISPLAY can be a display name or a frame.
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))
((memq frame-type '(x w32 ns pgtk))
(x-display-planes display))
((eq frame-type 'pc)
4)
@ -2185,7 +2203,7 @@ DISPLAY can be a display name or a frame.
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))
((memq frame-type '(x w32 ns pgtk))
(x-display-color-cells display))
((eq frame-type 'pc)
16)
@ -2202,7 +2220,7 @@ DISPLAY can be a display name or a frame.
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))
((memq frame-type '(x w32 ns pgtk))
(x-display-visual-class display))
((and (memq frame-type '(pc t))
(tty-display-color-p display))
@ -2216,6 +2234,8 @@ If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(&optional display))
(declare-function ns-display-monitor-attributes-list "nsfns.m"
(&optional terminal))
(declare-function pgtk-display-monitor-attributes-list "pgtkfns.c"
(&optional terminal))
(defun display-monitor-attributes-list (&optional display)
"Return a list of physical monitor attributes on DISPLAY.
@ -2264,6 +2284,8 @@ monitors."
(w32-display-monitor-attributes-list display))
((eq frame-type 'ns)
(ns-display-monitor-attributes-list display))
((eq frame-type 'pgtk)
(pgtk-display-monitor-attributes-list display))
(t
(let ((geometry (list 0 0 (display-pixel-width display)
(display-pixel-height display))))

View File

@ -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)))
:enable (null (memq initial-window-system '(x w32 ns pgtk)))
:help "How to encode terminal output"))
(bindings--define-key map [set-keyboard-coding-system]
'(menu-item "For Keyboard" set-keyboard-coding-system

View File

@ -336,6 +336,13 @@
(load "international/mule-util")
(load "international/ucs-normalize")
(load "term/ns-win"))))
(if (featurep 'pgtk)
(progn
(load "term/common-win")
;; Don't load ucs-normalize.el unless uni-*.el files were
;; already produced, because it needs uni-*.el files that might
;; not be built early enough during bootstrap.
(load "term/pgtk-win")))
(if (fboundp 'x-create-frame)
;; Do it after loading term/foo-win.el since the value of the
;; mouse-wheel-*-event vars depends on those files being loaded or not.

View File

@ -52,7 +52,7 @@
(when (bound-and-true-p mouse-wheel-mode) (mouse-wheel-mode 1)))
(defcustom mouse-wheel-down-event
(if (or (featurep 'w32-win) (featurep 'ns-win))
(if (or (featurep 'w32-win) (featurep 'ns-win) (featurep 'pgtk))
'wheel-up
'mouse-4)
"Event used for scrolling down."
@ -61,7 +61,7 @@
:set 'mouse-wheel-change-button)
(defcustom mouse-wheel-up-event
(if (or (featurep 'w32-win) (featurep 'ns-win))
(if (or (featurep 'w32-win) (featurep 'ns-win) (featurep 'pgtk))
'wheel-down
'mouse-5)
"Event used for scrolling up."
@ -215,13 +215,13 @@ Also see `mouse-wheel-tilt-scroll'."
"Function that does the job of scrolling right.")
(defvar mouse-wheel-left-event
(if (or (featurep 'w32-win) (featurep 'ns-win))
(if (or (featurep 'w32-win) (featurep 'ns-win) (featurep 'pgtk))
'wheel-left
'mouse-6)
"Event used for scrolling left.")
(defvar mouse-wheel-right-event
(if (or (featurep 'w32-win) (featurep 'ns-win))
(if (or (featurep 'w32-win) (featurep 'ns-win) (featurep 'pgtk))
'wheel-right
'mouse-7)
"Event used for scrolling right.")

View File

@ -189,7 +189,7 @@ See also `eww-form-checkbox-selected-symbol'."
string))
(defface eww-form-submit
'((((type x w32 ns) (class color)) ; Like default mode line
'((((type x w32 ns pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "#808080" :foreground "black"))
"Face for eww buffer buttons."
@ -197,7 +197,7 @@ See also `eww-form-checkbox-selected-symbol'."
:group 'eww)
(defface eww-form-file
'((((type x w32 ns) (class color)) ; Like default mode line
'((((type x w32 ns pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "#808080" :foreground "black"))
"Face for eww buffer buttons."
@ -205,7 +205,7 @@ See also `eww-form-checkbox-selected-symbol'."
:group 'eww)
(defface eww-form-checkbox
'((((type x w32 ns) (class color)) ; Like default mode line
'((((type x w32 ns pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "lightgrey" :foreground "black"))
"Face for eww buffer buttons."
@ -213,7 +213,7 @@ See also `eww-form-checkbox-selected-symbol'."
:group 'eww)
(defface eww-form-select
'((((type x w32 ns) (class color)) ; Like default mode line
'((((type x w32 ns pgtk) (class color)) ; Like default mode line
:box (:line-width 2 :style released-button)
:background "lightgrey" :foreground "black"))
"Face for eww buffer buttons."

View File

@ -1312,7 +1312,7 @@ please check its value")
;; only because all other settings of no-blinking-cursor are here.
(unless (or noninteractive
emacs-basic-display
(and (memq window-system '(x w32 ns))
(and (memq window-system '(x w32 ns pgtk))
(not (member (x-get-resource "cursorBlink" "CursorBlink")
'("no" "off" "false" "0")))))
(setq no-blinking-cursor t))
@ -1962,6 +1962,8 @@ we put it on this frame."
;; frame visible.
(if (eq (window-system) 'w32)
(sit-for 0 t))
(if (eq (window-system) 'pgtk)
(sit-for 0.1 t))
(dolist (frame (append (frame-list) (list (selected-frame))))
(if (and (frame-visible-p frame)
(not (window-minibuffer-p (frame-selected-window frame))))

429
lisp/term/pgtk-win.el Normal file
View File

@ -0,0 +1,429 @@
;;;
;;; Code:
(eval-when-compile (require 'cl-lib))
(or (featurep 'pgtk)
(error "%s: Loading pgtk-win.el but not compiled for pure Gtk+-3."
(invocation-name)))
;; Documentation-purposes only: actually loaded in loadup.el.
(require 'term/common-win)
(require 'frame)
(require 'mouse)
(require 'scroll-bar)
(require 'faces)
(require 'menu-bar)
(require 'fontset)
(require 'dnd)
(defgroup pgtk nil
"Pure-GTK specific features."
:group 'environment)
;;;; Command line argument handling.
(defvar x-invocation-args)
;; Set in term/common-win.el; currently unused by Gtk's x-open-connection.
(defvar x-command-line-resources)
;; pgtkterm.c.
(defvar pgtk-input-file)
(defun pgtk-handle-nxopen (_switch &optional temp)
(setq unread-command-events (append unread-command-events
(if temp '(pgtk-open-temp-file)
'(pgtk-open-file)))
pgtk-input-file (append pgtk-input-file (list (pop x-invocation-args)))))
(defun pgtk-handle-nxopentemp (switch)
(pgtk-handle-nxopen switch t))
(defun pgtk-ignore-1-arg (_switch)
(setq x-invocation-args (cdr x-invocation-args)))
;;;; File handling.
(defun x-file-dialog (prompt dir default_filename mustmatch only_dir_p)
"Read file name, prompting with PROMPT in directory DIR.
Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
selection box, if specified. If MUSTMATCH is non-nil, the returned file
or directory must exist.
This function is only defined on PGTK, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories."
(pgtk-read-file-name prompt dir mustmatch default_filename only_dir_p))
(defun pgtk-open-file-using-panel ()
"Pop up open-file panel, and load the result in a buffer."
(interactive)
;; Prompt dir defaultName isLoad initial.
(setq pgtk-input-file (pgtk-read-file-name "Select File to Load" nil t nil))
(if pgtk-input-file
(and (setq pgtk-input-file (list pgtk-input-file)) (pgtk-find-file))))
(defun pgtk-write-file-using-panel ()
"Pop up save-file panel, and save buffer in resulting name."
(interactive)
(let (pgtk-output-file)
;; Prompt dir defaultName isLoad initial.
(setq pgtk-output-file (pgtk-read-file-name "Save As" nil nil nil))
(message pgtk-output-file)
(if pgtk-output-file (write-file pgtk-output-file))))
(defcustom pgtk-pop-up-frames 'fresh
"Non-nil means open files upon request from the Workspace in a new frame.
If t, always do so. Any other non-nil value means open a new frame
unless the current buffer is a scratch buffer."
:type '(choice (const :tag "Never" nil)
(const :tag "Always" t)
(other :tag "Except for scratch buffer" fresh))
:version "23.1"
:group 'pgtk)
(declare-function pgtk-hide-emacs "pgtkfns.c" (on))
(defun pgtk-find-file ()
"Do a `find-file' with the `pgtk-input-file' as argument."
(interactive)
(let* ((f (file-truename
(expand-file-name (pop pgtk-input-file)
command-line-default-directory)))
(file (find-file-noselect f))
(bufwin1 (get-buffer-window file 'visible))
(bufwin2 (get-buffer-window "*scratch*" 'visible)))
(cond
(bufwin1
(select-frame (window-frame bufwin1))
(raise-frame (window-frame bufwin1))
(select-window bufwin1))
((and (eq pgtk-pop-up-frames 'fresh) bufwin2)
(pgtk-hide-emacs 'activate)
(select-frame (window-frame bufwin2))
(raise-frame (window-frame bufwin2))
(select-window bufwin2)
(find-file f))
(pgtk-pop-up-frames
(pgtk-hide-emacs 'activate)
(let ((pop-up-frames t)) (pop-to-buffer file nil)))
(t
(pgtk-hide-emacs 'activate)
(find-file f)))))
(defun pgtk-drag-n-drop (event &optional new-frame force-text)
"Edit the files listed in the drag-n-drop EVENT.
Switch to a buffer editing the last file dropped."
(interactive "e")
(let* ((window (posn-window (event-start event)))
(arg (car (cdr (cdr event))))
(type (car arg))
(data (car (cdr arg)))
(url-or-string (cond ((eq type 'file)
(concat "file:" data))
(t data))))
(set-frame-selected-window nil window)
(when new-frame
(select-frame (make-frame)))
(raise-frame)
(setq window (selected-window))
(if force-text
(dnd-insert-text window 'private data)
(dnd-handle-one-url window 'private url-or-string))))
(defun pgtk-drag-n-drop-other-frame (event)
"Edit the files listed in the drag-n-drop EVENT, in other frames.
May create new frames, or reuse existing ones. The frame editing
the last file dropped is selected."
(interactive "e")
(pgtk-drag-n-drop event t))
(defun pgtk-drag-n-drop-as-text (event)
"Drop the data in EVENT as text."
(interactive "e")
(pgtk-drag-n-drop event nil t))
(defun pgtk-drag-n-drop-as-text-other-frame (event)
"Drop the data in EVENT as text in a new frame."
(interactive "e")
(pgtk-drag-n-drop event t t))
(global-set-key [drag-n-drop] 'pgtk-drag-n-drop)
(global-set-key [C-drag-n-drop] 'pgtk-drag-n-drop-other-frame)
(global-set-key [M-drag-n-drop] 'pgtk-drag-n-drop-as-text)
(global-set-key [C-M-drag-n-drop] 'pgtk-drag-n-drop-as-text-other-frame)
;;;; Frame-related functions.
;; pgtkterm.c
(defvar pgtk-alternate-modifier)
(defvar pgtk-right-alternate-modifier)
(defvar pgtk-right-command-modifier)
(defvar pgtk-right-control-modifier)
;; You say tomAYto, I say tomAHto..
(defvaralias 'pgtk-option-modifier 'pgtk-alternate-modifier)
(defvaralias 'pgtk-right-option-modifier 'pgtk-right-alternate-modifier)
(defun pgtk-do-hide-emacs ()
(interactive)
(pgtk-hide-emacs t))
(declare-function pgtk-hide-others "pgtkfns.c" ())
(defun pgtk-do-hide-others ()
(interactive)
(pgtk-hide-others))
(declare-function pgtk-emacs-info-panel "pgtkfns.c" ())
(defun pgtk-do-emacs-info-panel ()
(interactive)
(pgtk-emacs-info-panel))
(defun pgtk-next-frame ()
"Switch to next visible frame."
(interactive)
(other-frame 1))
(defun pgtk-prev-frame ()
"Switch to previous visible frame."
(interactive)
(other-frame -1))
;; Frame will be focused anyway, so select it
;; (if this is not done, mode line is dimmed until first interaction)
;; FIXME: Sounds like we're working around a bug in the underlying code.
(add-hook 'after-make-frame-functions 'select-frame)
(defvar tool-bar-mode)
(declare-function tool-bar-mode "tool-bar" (&optional arg))
;; Based on a function by David Reitter <dreitter@inf.ed.ac.uk> ;
;; see https://lists.gnu.org/archive/html/emacs-devel/2005-09/msg00681.html .
(defun pgtk-toggle-toolbar (&optional frame)
"Switches the tool bar on and off in frame FRAME.
If FRAME is nil, the change applies to the selected frame."
(interactive)
(modify-frame-parameters
frame (list (cons 'tool-bar-lines
(if (> (or (frame-parameter frame 'tool-bar-lines) 0) 0)
0 1)) ))
(if (not tool-bar-mode) (tool-bar-mode t)))
;;;; Dialog-related functions.
;; Ask user for confirm before printing. Due to Kevin Rodgers.
(defun pgtk-print-buffer ()
"Interactive front-end to `print-buffer': asks for user confirmation first."
(interactive)
(if (and (called-interactively-p 'interactive)
(or (listp last-nonmenu-event)
(and (char-or-string-p (event-basic-type last-command-event))
(memq 'super (event-modifiers last-command-event)))))
(let ((last-nonmenu-event (if (listp last-nonmenu-event)
last-nonmenu-event
;; Fake it:
`(mouse-1 POSITION 1))))
(if (y-or-n-p (format "Print buffer %s? " (buffer-name)))
(print-buffer)
(error "Canceled")))
(print-buffer)))
;;;; Font support.
;; Needed for font listing functions under both backend and normal
(setq scalable-fonts-allowed t)
;; Set to use font panel instead
(declare-function pgtk-popup-font-panel "pgtkfns.c" (&optional frame))
(defalias 'x-select-font 'pgtk-popup-font-panel "Pop up the font panel.
This function has been overloaded in Nextstep.")
(defalias 'mouse-set-font 'pgtk-popup-font-panel "Pop up the font panel.
This function has been overloaded in Nextstep.")
;; pgtkterm.c
(defvar pgtk-input-font)
(defvar pgtk-input-fontsize)
(defun pgtk-respond-to-change-font ()
"Respond to changeFont: event, expecting `pgtk-input-font' and\n\
`pgtk-input-fontsize' of new font."
(interactive)
(modify-frame-parameters (selected-frame)
(list (cons 'fontsize pgtk-input-fontsize)))
(modify-frame-parameters (selected-frame)
(list (cons 'font pgtk-input-font)))
(set-frame-font pgtk-input-font))
;; Default fontset. This is mainly here to show how a fontset
;; can be set up manually. Ordinarily, fontsets are auto-created whenever
;; a font is chosen by
(defvar pgtk-standard-fontset-spec
;; Only some code supports this so far, so use uglier XLFD version
;; "-pgtk-*-*-*-*-*-10-*-*-*-*-*-fontset-standard,latin:Courier,han:Kai"
(mapconcat 'identity
'("-*-Monospace-*-*-*-*-10-*-*-*-*-*-fontset-standard"
"latin:-*-Courier-*-*-*-*-10-*-*-*-*-*-iso10646-1"
"han:-*-Kai-*-*-*-*-10-*-*-*-*-*-iso10646-1"
"cyrillic:-*-Trebuchet$MS-*-*-*-*-10-*-*-*-*-*-iso10646-1")
",")
"String of fontset spec of the standard fontset.
This defines a fontset consisting of the Courier and other fonts.
See the documentation of `create-fontset-from-fontset-spec' for the format.")
;;;; Pasteboard support.
(define-obsolete-function-alias 'pgtk-store-cut-buffer-internal
'gui-set-selection "24.1")
(defun pgtk-copy-including-secondary ()
(interactive)
(call-interactively 'kill-ring-save)
(gui-set-selection 'SECONDARY (buffer-substring (point) (mark t))))
(defun pgtk-paste-secondary ()
(interactive)
(insert (gui-get-selection 'SECONDARY)))
;;;; Color support.
;; Functions for color panel + drag
(defun pgtk-face-at-pos (pos)
(let* ((frame (car pos))
(frame-pos (cons (cadr pos) (cddr pos)))
(window (window-at (car frame-pos) (cdr frame-pos) frame))
(window-pos (coordinates-in-window-p frame-pos window))
(buffer (window-buffer window))
(edges (window-edges window)))
(cond
((not window-pos)
nil)
((eq window-pos 'mode-line)
'mode-line)
((eq window-pos 'vertical-line)
'default)
((consp window-pos)
(with-current-buffer buffer
(let ((p (car (compute-motion (window-start window)
(cons (nth 0 edges) (nth 1 edges))
(window-end window)
frame-pos
(- (window-width window) 1)
nil
window))))
(cond
((eq p (window-point window))
'cursor)
((and mark-active (< (region-beginning) p) (< p (region-end)))
'region)
(t
(let ((faces (get-char-property p 'face window)))
(if (consp faces) (car faces) faces)))))))
(t
nil))))
(defun pgtk-suspend-error ()
;; Don't allow suspending if any of the frames are PGTK frames.
(if (memq 'pgtk (mapcar 'window-system (frame-list)))
(error "Cannot suspend Emacs while a PGTK GUI frame exists")))
;; Set some options to be as Nextstep-like as possible.
(setq frame-title-format t
icon-title-format t)
(defvar pgtk-initialized nil
"Non-nil if pure-GTK windowing has been initialized.")
(declare-function x-handle-args "common-win" (args))
(declare-function x-open-connection "pgtkfns.c"
(display &optional xrm-string must-succeed))
(declare-function pgtk-set-resource "pgtkfns.c" (owner name value))
;; Do the actual pure-GTK Windows setup here; the above code just
;; defines functions and variables that we use now.
(cl-defmethod window-system-initialization (&context (window-system pgtk)
&optional display)
"Initialize Emacs for pure-GTK windowing."
(cl-assert (not pgtk-initialized))
;; PENDING: not needed?
(setq command-line-args (x-handle-args command-line-args))
;; Make sure we have a valid resource name.
(or (stringp x-resource-name)
(let (i)
(setq x-resource-name (invocation-name))
;; Change any . or * characters in x-resource-name to hyphens,
;; so as not to choke when we use it in X resource queries.
(while (setq i (string-match "[.*]" x-resource-name))
(aset x-resource-name i ?-))))
;; Setup the default fontset.
(create-default-fontset)
;; Create the standard fontset.
(condition-case err
(create-fontset-from-fontset-spec pgtk-standard-fontset-spec t)
(error (display-warning
'initialization
(format "Creation of the standard fontset failed: %s" err)
:error)))
(x-open-connection (or display
x-display-name)
x-command-line-resources
;; Exit Emacs with fatal error if this fails and we
;; are the initial display.
(= (length (frame-list)) 0))
(x-apply-session-resources)
;; Don't let Emacs suspend under PGTK.
(add-hook 'suspend-hook 'pgtk-suspend-error)
(setq pgtk-initialized t))
;; Any display name is OK.
(add-to-list 'display-format-alist '(".*" . pgtk))
(cl-defmethod handle-args-function (args &context (window-system pgtk))
(x-handle-args args))
(cl-defmethod frame-creation-function (params &context (window-system pgtk))
(x-create-frame-with-faces params))
(declare-function pgtk-own-selection-internal "pgtkselect.c" (selection value &optional frame))
(declare-function pgtk-disown-selection-internal "pgtkselect.c" (selection &optional time_object terminal))
(declare-function pgtk-selection-owner-p "pgtkselect.c" (&optional selection terminal))
(declare-function pgtk-selection-exists-p "pgtkselect.c" (&optional selection terminal))
(declare-function pgtk-get-selection-internal "pgtkselect.c" (selection-symbol target-type &optional time_stamp terminal))
(cl-defmethod gui-backend-set-selection (selection value
&context (window-system pgtk))
(if value (pgtk-own-selection-internal selection value)
(pgtk-disown-selection-internal selection)))
(cl-defmethod gui-backend-selection-owner-p (selection
&context (window-system pgtk))
(pgtk-selection-owner-p selection))
(cl-defmethod gui-backend-selection-exists-p (selection
&context (window-system pgtk))
(pgtk-selection-exists-p selection))
(cl-defmethod gui-backend-get-selection (selection-symbol target-type
&context (window-system pgtk))
(pgtk-get-selection-internal selection-symbol target-type))
(provide 'pgtk-win)
(provide 'term/pgtk-win)
;;; pgtk-win.el ends here

View File

@ -46,6 +46,7 @@
(pcase (or window-system 'tty)
('x "X11")
('ns "OpenStep")
('pgtk "PureGTK")
('tty "TTY")
(_ nil)))))

View File

@ -41,6 +41,9 @@ handle SIGUSR2 noprint pass
# debugging.
handle SIGALRM ignore
# On selection send failed.
handle SIGPIPE nostop noprint
# Use $bugfix so that the value isn't a constant.
# Using a constant runs into GDB bugs sometimes.
define xgetptr
@ -1224,6 +1227,7 @@ set print pretty on
set print sevenbit-strings
show environment DISPLAY
show environment WAYLAND_DISPLAY
show environment TERM
# When debugging, it is handy to be able to "return" from

View File

@ -286,6 +286,9 @@ W32_OBJ=@W32_OBJ@
## -lkernel32 if CYGWIN but not HAVE_W32, else empty.
W32_LIBS=@W32_LIBS@
PGTK_OBJ=@PGTK_OBJ@
PGTK_LIBS=@PGTK_LIBS@
## emacs.res if HAVE_W32
EMACSRES = @EMACSRES@
## If HAVE_W32, compiler arguments for including
@ -421,7 +424,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
profiler.o decompress.o \
thread.o systhread.o \
$(if $(HYBRID_MALLOC),sheap.o) \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(PGTK_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) $(GMP_OBJ)
obj = $(base_obj) $(NS_OBJC_OBJ)
@ -519,7 +522,7 @@ shortlisp := loaddefs.el loadup.el $(sort ${shortlisp})
lisp = $(addprefix ${lispsource}/,${shortlisp})
## Construct full set of libraries to be linked.
LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) $(LIBX_BASE) $(LIBIMAGE) \
$(LIBX_OTHER) $(LIBSOUND) \
$(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \
$(WEBKIT_LIBS) \

View File

@ -96,7 +96,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <unistd.h>
#include <fcntl.h>
#ifdef USE_GTK
#if defined(USE_GTK)
# include "gtkutil.h"
#endif
#ifdef WINDOWSNT
@ -6052,8 +6052,11 @@ garbage_collect (void)
mark_terminals ();
mark_kboards ();
mark_threads ();
#ifdef HAVE_PGTK
mark_pgtkterm();
#endif
#ifdef USE_GTK
#if defined(USE_GTK)
xg_mark_data ();
#endif

View File

@ -134,6 +134,14 @@ 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
#ifdef HAVE_WINDOW_SYSTEM
# include <time.h>
# include "fontset.h"
@ -1393,6 +1401,9 @@ struct glyph_string
Emacs_GC *gc;
HDC hdc;
#endif
#if defined (HAVE_PGTK)
XGCValues xgcv;
#endif
/* A pointer to the first glyph in the string. This glyph
corresponds to char2b[0]. Needed to draw rectangles if

View File

@ -6403,6 +6403,19 @@ init_display_interactive (void)
}
#endif
#ifdef HAVE_PGTK
if (!inhibit_window_system
#ifndef CANNOT_DUMP
&& initialized
#endif
)
{
Vinitial_window_system = Qpgtk;
Vwindow_system_version = make_fixnum (1);
return;
}
#endif
/* If no window system has been specified, try to use the terminal. */
if (! isatty (STDIN_FILENO))
fatal ("standard input is not a tty");

View File

@ -1586,6 +1586,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_bignum ();
init_threads ();
init_eval ();
#ifdef HAVE_PGTK
init_pgtkterm (); /* before init_atimer(). */
#endif
init_atimer ();
running_asynch_code = 0;
init_random ();
@ -1914,6 +1917,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_nsselect ();
syms_of_fontset ();
#endif /* HAVE_NS */
#ifdef HAVE_PGTK
syms_of_pgtkterm();
syms_of_pgtkfns();
syms_of_pgtkselect ();
syms_of_fontset ();
syms_of_xsettings ();
syms_of_xwidget ();
#endif
syms_of_gnutls ();
@ -1982,8 +1993,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef HAVE_DBUS
init_dbusbind ();
#endif
#ifdef USE_GTK
#if defined(USE_GTK)
#ifndef HAVE_PGTK
init_xterm ();
#endif
#endif
/* This can create a thread that may call getenv, so it must follow

View File

@ -22,7 +22,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "frame.h"
#ifdef HAVE_PGTK
#include "pgtkterm.h"
#else
#include "xterm.h"
#endif
#include "xwidget.h"
#include "emacsgtkfixed.h"
@ -182,7 +186,11 @@ emacs_fixed_get_preferred_width (GtkWidget *widget,
{
EmacsFixed *fixed = EMACS_FIXED (widget);
EmacsFixedPrivate *priv = fixed->priv;
#ifdef HAVE_PGTK
int w = priv->f->output_data.pgtk->size_hints.min_width;
#else
int w = priv->f->output_data.x->size_hints.min_width;
#endif
if (minimum) *minimum = w;
if (natural) *natural = w;
}
@ -194,12 +202,18 @@ emacs_fixed_get_preferred_height (GtkWidget *widget,
{
EmacsFixed *fixed = EMACS_FIXED (widget);
EmacsFixedPrivate *priv = fixed->priv;
#ifdef HAVE_PGTK
int h = priv->f->output_data.pgtk->size_hints.min_height;
#else
int h = priv->f->output_data.x->size_hints.min_height;
#endif
if (minimum) *minimum = h;
if (natural) *natural = h;
}
#ifndef HAVE_PGTK
/* Override the X function so we can intercept Gtk+ 3 calls.
Use our values for min_width/height so that KDE don't freak out
(Bug#8919), and so users can resize our frames as they wish. */
@ -234,8 +248,13 @@ XSetWMSizeHints (Display *d,
if ((hints->flags & PMinSize) && f)
{
#ifdef HAVE_PGTK
int w = f->output_data.pgtk->size_hints.min_width;
int h = f->output_data.pgtk->size_hints.min_height;
#else
int w = f->output_data.x->size_hints.min_width;
int h = f->output_data.x->size_hints.min_height;
#endif
data[5] = w;
data[6] = h;
}
@ -253,3 +272,5 @@ XSetWMNormalHints (Display *d, Window w, XSizeHints *hints)
{
XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS);
}
#endif

View File

@ -5567,7 +5567,11 @@ match. */);
syms_of_xftfont ();
#endif /* HAVE_XFT */
#endif /* not USE_CAIRO */
#endif /* HAVE_X_WINDOWS */
#else /* not HAVE_X_WINDOWS */
#ifdef USE_CAIRO
syms_of_ftcrfont ();
#endif
#endif /* not HAVE_X_WINDOWS */
#else /* not HAVE_FREETYPE */
#ifdef HAVE_X_WINDOWS
syms_of_xfont ();

View File

@ -822,7 +822,7 @@ extern Lisp_Object merge_font_spec (Lisp_Object, Lisp_Object);
extern Lisp_Object font_make_entity (void);
extern Lisp_Object font_make_object (int, Lisp_Object, int);
#if defined (HAVE_XFT) || defined (HAVE_FREETYPE) || defined (HAVE_NS)
#if defined (HAVE_XFT) || defined (HAVE_FREETYPE) || defined (HAVE_NS) || defined(HAVE_PGTK)
extern Lisp_Object font_build_object (int, Lisp_Object, Lisp_Object, double);
#endif

View File

@ -291,6 +291,8 @@ See also `frame-live-p'. */)
return Qpc;
case output_ns:
return Qns;
case output_pgtk:
return Qpgtk;
default:
emacs_abort ();
}
@ -2149,7 +2151,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
/* Since a similar behavior was observed on the Lucid and Motif
builds (see Bug#5802, Bug#21509, Bug#23499, Bug#27816), we now
don't delete the terminal for these builds either. */
if (terminal->reference_count == 0 && terminal->type == output_x_window)
if (terminal->reference_count == 0 &&
(terminal->type == output_x_window || terminal->type == output_pgtk))
terminal->reference_count = 1;
#endif /* USE_X_TOOLKIT || USE_GTK */
if (terminal->reference_count == 0)
@ -5749,7 +5752,7 @@ selected frame. This is useful when `make-pointer-invisible' is set. */)
#ifdef HAVE_WINDOW_SYSTEM
# if (defined USE_GTK || defined HAVE_NS || defined HAVE_XINERAMA \
# if (defined USE_GTK || defined HAVE_PGTK || defined HAVE_NS || defined HAVE_XINERAMA \
|| defined HAVE_XRANDR)
void
free_monitors (struct MonitorInfo *monitors, int n_monitors)
@ -5876,6 +5879,7 @@ syms_of_frame (void)
DEFSYM (Qw32, "w32");
DEFSYM (Qpc, "pc");
DEFSYM (Qns, "ns");
DEFSYM (Qpgtk, "pgtk");
DEFSYM (Qvisible, "visible");
DEFSYM (Qbuffer_predicate, "buffer-predicate");
DEFSYM (Qbuffer_list, "buffer-list");

View File

@ -574,6 +574,7 @@ struct frame
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. */
}
output_data;
@ -841,6 +842,11 @@ 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
/* FRAME_WINDOW_P tests whether the frame is a graphical window system
frame. */
@ -854,6 +860,9 @@ default_pixels_per_inch_y (void)
#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
#ifndef FRAME_WINDOW_P
#define FRAME_WINDOW_P(f) ((void) (f), false)
#endif
@ -1701,7 +1710,7 @@ extern const char *x_get_resource_string (const char *, const char *);
extern void x_sync (struct frame *);
#endif /* HAVE_X_WINDOWS */
#ifndef HAVE_NS
#if !defined(HAVE_NS) && !defined(HAVE_PGTK)
/* Set F's bitmap icon, if specified among F's parameters. */

View File

@ -30,6 +30,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include "pdumper.h"
#include "pgtkterm.h"
/* Fringe bitmaps are represented in three different ways:
Logical bitmaps are used internally to denote things like
@ -1398,7 +1400,7 @@ If BITMAP overrides a standard fringe bitmap, the original bitmap is restored.
On W32 and MAC (little endian), there's no need to do this.
*/
#if defined (HAVE_X_WINDOWS)
#if defined (HAVE_X_WINDOWS) || defined(HAVE_PGTK)
static const unsigned char swap_nibble[16] = {
0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
@ -1461,6 +1463,25 @@ init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
#endif /* not USE_CAIRO */
#endif /* HAVE_X_WINDOWS */
#if !defined(HAVE_X_WINDOWS) && defined (HAVE_PGTK)
unsigned short *bits = fb->bits;
int j;
for (j = 0; j < fb->height; j++)
{
unsigned short b = *bits;
#ifdef WORDS_BIGENDIAN
*bits++ = (b << (16 - fb->width));
#else
b = (unsigned short)((swap_nibble[b & 0xf] << 12)
| (swap_nibble[(b>>4) & 0xf] << 8)
| (swap_nibble[(b>>8) & 0xf] << 4)
| (swap_nibble[(b>>12) & 0xf]));
*bits++ = (b >> (16 - fb->width));
#endif
}
#endif /* !HAVE_X_WINDOWS && HAVE_PGTK */
#ifdef HAVE_NTGUI
unsigned short *bits = fb->bits;
int j;

View File

@ -22,7 +22,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <cairo-ft.h>
#include "lisp.h"
#ifndef HAVE_PGTK
#include "xterm.h"
#else
#include "pgtkterm.h"
#endif
#include "blockinput.h"
#include "charset.h"
#include "composite.h"
@ -513,11 +517,19 @@ ftcrfont_draw (struct glyph_string *s,
block_input ();
#ifndef HAVE_PGTK
cr = x_begin_cr_clip (f, s->gc);
#else
cr = pgtk_begin_cr_clip (f);
#endif
if (with_background)
{
#ifndef HAVE_PGTK
x_set_cr_source_with_gc_background (f, s->gc);
#else
pgtk_set_cr_source_with_color (f, s->xgcv.background);
#endif
cairo_rectangle (cr, x, y - FONT_BASE (face->font),
s->width, FONT_HEIGHT (face->font));
cairo_fill (cr);
@ -534,11 +546,19 @@ ftcrfont_draw (struct glyph_string *s,
NULL));
}
#ifndef HAVE_PGTK
x_set_cr_source_with_gc_foreground (f, s->gc);
#else
pgtk_set_cr_source_with_color (f, s->xgcv.foreground);
#endif
cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
cairo_show_glyphs (cr, glyphs, len);
#ifndef HAVE_PGTK
x_end_cr_clip (f);
#else
pgtk_end_cr_clip (f);
#endif
unblock_input ();

View File

@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_SIZES_H
#include FT_TRUETYPE_TABLES_H
#ifdef FT_BDF_H
# include FT_BDF_H
#endif

View File

@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
#ifdef USE_GTK
#if defined(USE_GTK)
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
@ -37,13 +37,24 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "dispextern.h"
#include "frame.h"
#include "systime.h"
#ifndef HAVE_PGTK
#include "xterm.h"
#define xp x
typedef struct x_output xp_output;
#else
#define xp pgtk
typedef struct pgtk_output xp_output;
#endif
#include "blockinput.h"
#include "window.h"
#include "gtkutil.h"
#include "termhooks.h"
#include "keyboard.h"
#include "coding.h"
#ifndef PGTK_TRACE
#define PGTK_TRACE(fmt, ...) ((void) 0)
#define PGTK_BACKTRACE() ((void) 0)
#endif
#include <gdk/gdkkeysyms.h>
@ -52,7 +63,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#endif
#ifdef HAVE_GTK3
#ifndef HAVE_PGTK
#include <gtk/gtkx.h>
#endif
#include "emacsgtkfixed.h"
#endif
@ -129,6 +142,7 @@ static GdkDisplay *gdpy_def;
static void
xg_set_screen (GtkWidget *w, struct frame *f)
{
#ifndef HAVE_PGTK
if (FRAME_X_DISPLAY (f) != DEFAULT_GDK_DISPLAY ())
{
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
@ -139,6 +153,17 @@ xg_set_screen (GtkWidget *w, struct frame *f)
else
gtk_window_set_screen (GTK_WINDOW (w), gscreen);
}
#else
if (FRAME_X_DISPLAY(f) != DEFAULT_GDK_DISPLAY ())
{
GdkScreen *gscreen = gdk_display_get_default_screen (FRAME_X_DISPLAY(f));
if (GTK_IS_MENU (w))
gtk_menu_set_screen (GTK_MENU (w), gscreen);
else
gtk_window_set_screen (GTK_WINDOW (w), gscreen);
}
#endif
}
@ -150,12 +175,20 @@ xg_set_screen (GtkWidget *w, struct frame *f)
multiple displays. */
void
#ifndef HAVE_PGTK
xg_display_open (char *display_name, Display **dpy)
#else
xg_display_open (char *display_name, GdkDisplay **dpy)
#endif
{
GdkDisplay *gdpy;
unrequest_sigio (); /* See comment in x_display_ok, xterm.c. */
#ifndef HAVE_PGTK
gdpy = gdk_display_open (display_name);
#else
gdpy = gdk_display_open (strlen(display_name) == 0 ? NULL : display_name);
#endif
request_sigio ();
if (!gdpy_def && gdpy)
{
@ -164,7 +197,11 @@ xg_display_open (char *display_name, Display **dpy)
gdpy);
}
#ifndef HAVE_PGTK
*dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
#else
*dpy = gdpy;
#endif
}
/* Scaling/HiDPI functions. */
@ -196,8 +233,13 @@ xg_get_scale (struct frame *f)
/* Close display DPY. */
void
#ifndef HAVE_PGTK
xg_display_close (Display *dpy)
#else
xg_display_close (GdkDisplay *gdpy)
#endif
{
#ifndef HAVE_PGTK
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
/* If this is the default display, try to change it before closing.
@ -221,6 +263,31 @@ xg_display_close (Display *dpy)
}
gdk_display_close (gdpy);
#else
/* If this is the default display, try to change it before closing.
If there is no other display to use, gdpy_def is set to NULL, and
the next call to xg_display_open resets the default display. */
if (gdk_display_get_default () == gdpy)
{
struct pgtk_display_info *dpyinfo;
GdkDisplay *gdpy_new = NULL;
/* Find another display. */
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
if (dpyinfo->gdpy != gdpy)
{
gdpy_new = dpyinfo->gdpy;
gdk_display_manager_set_default_display (gdk_display_manager_get (),
gdpy_new);
break;
}
gdpy_def = gdpy_new;
}
gdk_display_close (gdpy);
#endif
}
@ -232,12 +299,19 @@ xg_display_close (Display *dpy)
scroll bars on display DPY. */
GdkCursor *
#ifndef HAVE_PGTK
xg_create_default_cursor (Display *dpy)
#else
xg_create_default_cursor (GdkDisplay *gdpy)
#endif
{
#ifndef HAVE_PGTK
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
#endif
return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR);
}
#ifndef HAVE_PGTK
/* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */
static GdkPixbuf *
@ -250,8 +324,10 @@ xg_get_pixbuf_from_pix_and_mask (struct frame *f,
Window wunused;
unsigned int width, height, depth, uunused;
#ifndef HAVE_PGTK
if (FRAME_DISPLAY_INFO (f)->red_bits != 8)
return 0;
#endif
XGetGeometry (FRAME_X_DISPLAY (f), pix, &wunused, &iunused, &iunused,
&width, &height, &uunused, &depth);
if (depth != 24)
@ -286,6 +362,7 @@ xg_get_pixbuf_from_pix_and_mask (struct frame *f,
return icon_buf;
}
#endif
#if defined USE_CAIRO && !defined HAVE_GTK3
static GdkPixbuf *
@ -633,7 +710,11 @@ xg_check_special_colors (struct frame *f,
g = col.green * 65535,
b = col.blue * 65535;
sprintf (buf, "rgb:%04x/%04x/%04x", r, g, b);
#ifndef HAVE_PGTK
success_p = x_parse_color (f, buf, color) != 0;
#else
success_p = pgtk_parse_color (buf, color) != 0;
#endif
#else
GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f));
GdkColor *grgb = get_bg
@ -667,7 +748,7 @@ hierarchy_ch_cb (GtkWidget *widget,
gpointer user_data)
{
struct frame *f = user_data;
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl);
if (! top || ! GTK_IS_WINDOW (top))
@ -689,7 +770,7 @@ qttip_cb (GtkWidget *widget,
gpointer user_data)
{
struct frame *f = user_data;
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
if (x->ttip_widget == NULL)
{
GtkWidget *p;
@ -736,7 +817,7 @@ xg_prepare_tooltip (struct frame *f,
int *width,
int *height)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
GtkWidget *widget;
GdkWindow *gwin;
GdkScreen *screen;
@ -787,13 +868,19 @@ xg_prepare_tooltip (struct frame *f,
void
xg_show_tooltip (struct frame *f, int root_x, int root_y)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
if (x->ttip_window)
{
block_input ();
#ifndef HAVE_PGTK
gtk_window_move (x->ttip_window, root_x / xg_get_scale (f),
root_y / xg_get_scale (f));
gtk_widget_show (GTK_WIDGET (x->ttip_window));
#else
gtk_widget_show (GTK_WIDGET (x->ttip_window));
gtk_window_move (x->ttip_window, root_x / xg_get_scale (f),
root_y / xg_get_scale (f));
#endif
unblock_input ();
}
}
@ -805,10 +892,10 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
bool
xg_hide_tooltip (struct frame *f)
{
if (f->output_data.x->ttip_window)
bool ret = 0;
if (f->output_data.xp->ttip_window)
{
GtkWindow *win = f->output_data.x->ttip_window;
GtkWindow *win = f->output_data.xp->ttip_window;
block_input ();
gtk_widget_hide (GTK_WIDGET (win));
@ -932,10 +1019,16 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth);
height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight);
PGTK_TRACE("xg_frame_resized: pixel: %dx%d, text: %dx%d", pixelwidth, pixelheight, width, height);
frame_size_history_add
(f, Qxg_frame_resized, width, height, Qnil);
PGTK_TRACE("width: %d -> %d.", FRAME_TEXT_WIDTH(f), width);
PGTK_TRACE("height: %d -> %d.", FRAME_TEXT_HEIGHT(f), height);
PGTK_TRACE("pixelwidth: %d -> %d.", FRAME_PIXEL_WIDTH(f), pixelwidth);
PGTK_TRACE("pixelheight: %d -> %d.", FRAME_PIXEL_HEIGHT(f), pixelheight);
if (width != FRAME_TEXT_WIDTH (f)
|| height != FRAME_TEXT_HEIGHT (f)
|| pixelwidth != FRAME_PIXEL_WIDTH (f)
@ -945,6 +1038,9 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
change_frame_size (f, width, height, 0, 1, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
#ifdef HAVE_PGTK
pgtk_cr_destroy_surface (f);
#endif
}
}
@ -1007,7 +1103,11 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f))
{
was_visible = true;
#ifndef HAVE_PGTK
hide_child_frame = EQ (x_gtk_resize_child_frames, Qhide);
#else
hide_child_frame = true;
#endif // !HAVE_PGTK
if (totalwidth != gwidth || totalheight != gheight)
{
@ -1060,7 +1160,9 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
/* Must call this to flush out events */
(void)gtk_events_pending ();
gdk_flush ();
#ifndef HAVE_PGTK
x_wait_for_event (f, ConfigureNotify);
#endif
if (!NILP (fullscreen))
/* Try to restore fullscreen state. */
@ -1071,24 +1173,24 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
}
else
adjust_frame_size (f, width, height, 5, 0, Qxg_frame_set_char_size);
}
#ifndef HAVE_PGTK
/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
The policy is to keep the number of editable lines. */
#if 0
static void
xg_height_or_width_changed (struct frame *f)
{
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
FRAME_TOTAL_PIXEL_WIDTH (f),
FRAME_TOTAL_PIXEL_HEIGHT (f));
f->output_data.x->hint_flags = 0;
f->output_data.xp->hint_flags = 0;
x_wm_set_size_hint (f, 0, 0);
}
#endif
#ifndef HAVE_PGTK
/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
Must be done like this, because GtkWidget:s can have "hidden"
X Window that aren't accessible.
@ -1116,6 +1218,7 @@ xg_win_to_widget (Display *dpy, Window wdesc)
unblock_input ();
return gwdesc;
}
#endif
/* Set the background of widget W to PIXEL. */
@ -1123,9 +1226,18 @@ static void
xg_set_widget_bg (struct frame *f, GtkWidget *w, unsigned long pixel)
{
#ifdef HAVE_GTK3
XColor xbg;
Emacs_Color xbg;
xbg.pixel = pixel;
#ifndef HAVE_PGTK
if (XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &xbg))
#else
xbg.red = (pixel >> 16) & 0xff;
xbg.green = (pixel >> 8) & 0xff;
xbg.blue = (pixel >> 0) & 0xff;
xbg.red |= xbg.red << 8;
xbg.green |= xbg.green << 8;
xbg.blue |= xbg.blue << 8;
#endif
{
const char format[] = "* { background-color: #%02x%02x%02x; }";
/* The format is always longer than the resulting string. */
@ -1160,7 +1272,16 @@ style_changed_cb (GObject *go,
struct input_event event;
GdkDisplay *gdpy = user_data;
const char *display_name = gdk_display_get_name (gdpy);
#ifndef HAVE_PGTK
Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
#else
GdkDisplay *dpy = gdpy;
#endif
#ifndef HAVE_PGTK
if (display_name == NULL)
display_name = "";
#endif
EVENT_INIT (event);
event.kind = CONFIG_CHANGED_EVENT;
@ -1181,7 +1302,11 @@ style_changed_cb (GObject *go,
{
struct frame *f = XFRAME (frame);
if (FRAME_LIVE_P (f)
#ifndef HAVE_PGTK
&& FRAME_X_P (f)
#else
&& FRAME_PGTK_P (f)
#endif
&& FRAME_X_DISPLAY (f) == dpy)
{
FRAME_TERMINAL (f)->set_scroll_bar_default_width_hook (f);
@ -1216,15 +1341,21 @@ xg_create_frame_widgets (struct frame *f)
#endif
char *title = 0;
PGTK_TRACE("xg_create_frame_widgets.");
block_input ();
#ifndef HAVE_PGTK // gtk_plug not found.
if (FRAME_X_EMBEDDED_P (f))
{
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
wtop = gtk_plug_new_for_display (gdpy, f->output_data.x->parent_desc);
wtop = gtk_plug_new_for_display (gdpy, f->output_data.xp->parent_desc);
}
else
#endif
wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
#ifdef HAVE_PGTK
gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK);
#endif
/* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu
has backported it to Gtk+ 2.0 and they add the resize grip for
@ -1281,8 +1412,8 @@ xg_create_frame_widgets (struct frame *f)
FRAME_GTK_OUTER_WIDGET (f) = wtop;
FRAME_GTK_WIDGET (f) = wfixed;
f->output_data.x->vbox_widget = wvbox;
f->output_data.x->hbox_widget = whbox;
f->output_data.xp->vbox_widget = wvbox;
f->output_data.xp->hbox_widget = whbox;
gtk_widget_set_has_window (wfixed, TRUE);
@ -1309,10 +1440,12 @@ xg_create_frame_widgets (struct frame *f)
SSDATA (Vx_resource_class));
#endif
#ifndef HAVE_PGTK
/* Add callback to do nothing on WM_DELETE_WINDOW. The default in
GTK is to destroy the widget. We want Emacs to do that instead. */
g_signal_connect (G_OBJECT (wtop), "delete-event",
G_CALLBACK (delete_cb), f);
#endif
/* Convert our geometry parameters into a geometry string
and specify it.
@ -1323,7 +1456,9 @@ xg_create_frame_widgets (struct frame *f)
gtk_widget_add_events (wfixed,
GDK_POINTER_MOTION_MASK
#ifndef HAVE_PGTK
| GDK_EXPOSURE_MASK
#endif
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_KEY_PRESS_MASK
@ -1331,13 +1466,25 @@ xg_create_frame_widgets (struct frame *f)
| GDK_LEAVE_NOTIFY_MASK
| GDK_FOCUS_CHANGE_MASK
| GDK_STRUCTURE_MASK
#ifdef HAVE_PGTK
| GDK_SCROLL_MASK
| GDK_SMOOTH_SCROLL_MASK
#endif
| GDK_VISIBILITY_NOTIFY_MASK);
/* Must realize the windows so the X window gets created. It is used
by callers of this function. */
#ifndef HAVE_PGTK
gtk_widget_realize (wfixed);
#else
gtk_widget_show_all(wtop);
#endif
#ifndef HAVE_PGTK
FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed);
#endif
#ifndef HAVE_PGTK
initial_set_up_x_back_buffer (f);
#endif
/* Since GTK clears its window by filling with the background color,
we must keep X and GTK background in sync. */
@ -1354,6 +1501,7 @@ xg_create_frame_widgets (struct frame *f)
gtk_widget_modify_style (wfixed, style);
#else
gtk_widget_set_can_focus (wfixed, TRUE);
gtk_widget_grab_focus(wfixed);
gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE);
#endif
@ -1366,9 +1514,9 @@ xg_create_frame_widgets (struct frame *f)
}
/* Steal a tool tip window we can move ourselves. */
f->output_data.x->ttip_widget = 0;
f->output_data.x->ttip_lbl = 0;
f->output_data.x->ttip_window = 0;
f->output_data.xp->ttip_widget = 0;
f->output_data.xp->ttip_lbl = 0;
f->output_data.xp->ttip_window = 0;
gtk_widget_set_tooltip_text (wtop, "Dummy text");
g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f);
@ -1398,7 +1546,7 @@ xg_free_frame_widgets (struct frame *f)
{
if (FRAME_GTK_OUTER_WIDGET (f))
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
struct xg_frame_tb_info *tbinfo
= g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
TB_INFO_KEY);
@ -1406,10 +1554,14 @@ xg_free_frame_widgets (struct frame *f)
xfree (tbinfo);
/* x_free_frame_resources should have taken care of it */
#ifndef HAVE_PGTK
eassert (!FRAME_X_DOUBLE_BUFFERED_P (f));
#endif
gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */
#ifndef HAVE_PGTK
FRAME_X_RAW_DRAWABLE (f) = 0;
#endif
FRAME_GTK_OUTER_WIDGET (f) = 0;
if (x->ttip_widget)
{
@ -1451,6 +1603,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
XSETFRAME (frame, f);
fs_state = Fframe_parameter (frame, Qfullscreen);
#ifndef HAVE_PGTK
if ((EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth)) &&
(x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_wm_state) ||
x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_wm_state_fullscreen)))
@ -1460,18 +1613,19 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
*/
return;
}
#endif
if (flags)
{
memset (&size_hints, 0, sizeof (size_hints));
f->output_data.x->size_hints = size_hints;
f->output_data.x->hint_flags = hint_flags;
f->output_data.xp->size_hints = size_hints;
f->output_data.xp->hint_flags = hint_flags;
}
else
flags = f->size_hint_flags;
size_hints = f->output_data.x->size_hints;
hint_flags = f->output_data.x->hint_flags;
size_hints = f->output_data.xp->size_hints;
hint_flags = f->output_data.xp->hint_flags;
hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE;
size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
@ -1484,6 +1638,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + FRAME_TOOLBAR_WIDTH (f);
base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1)
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
PGTK_TRACE("base: %dx%d\n", base_width, base_height);
size_hints.base_width = base_width;
size_hints.base_height = base_height;
@ -1533,16 +1688,16 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
size_hints.width_inc /= scale;
size_hints.height_inc /= scale;
if (hint_flags != f->output_data.x->hint_flags
if (hint_flags != f->output_data.xp->hint_flags
|| memcmp (&size_hints,
&f->output_data.x->size_hints,
&f->output_data.xp->size_hints,
sizeof (size_hints)) != 0)
{
block_input ();
gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
NULL, &size_hints, hint_flags);
f->output_data.x->size_hints = size_hints;
f->output_data.x->hint_flags = hint_flags;
f->output_data.xp->size_hints = size_hints;
f->output_data.xp->hint_flags = hint_flags;
unblock_input ();
}
}
@ -1608,7 +1763,11 @@ xg_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
XSETFRAME (frame2, f2);
gdk_window_restack (gwin1, gwin2, above_flag);
#ifndef HAVE_PGTK
x_sync (f1);
#else
gdk_flush();
#endif
}
unblock_input ();
}
@ -1672,6 +1831,7 @@ xg_set_override_redirect (struct frame *f, Lisp_Object override_redirect)
unblock_input ();
}
#ifndef HAVE_PGTK
/* Set the frame icon to ICON_PIXMAP/MASK. This must be done with GTK
functions so GTK does not overwrite the icon. */
@ -1684,6 +1844,7 @@ xg_set_frame_icon (struct frame *f, Pixmap icon_pixmap, Pixmap icon_mask)
if (gp)
gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), gp);
}
#endif
@ -2500,7 +2661,7 @@ xg_mark_data (void)
{
struct frame *f = XFRAME (frame);
if (FRAME_X_P (f) && FRAME_GTK_OUTER_WIDGET (f))
if ((FRAME_X_P (f) || FRAME_PGTK_P (f)) && FRAME_GTK_OUTER_WIDGET (f))
{
struct xg_frame_tb_info *tbinfo
= g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
@ -3529,7 +3690,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data)
void
xg_update_frame_menubar (struct frame *f)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
GtkRequisition req;
if (!x->menubar_widget || gtk_widget_get_mapped (x->menubar_widget))
@ -3562,7 +3723,7 @@ xg_update_frame_menubar (struct frame *f)
void
free_frame_menubar (struct frame *f)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
if (x->menubar_widget)
{
@ -3578,10 +3739,11 @@ free_frame_menubar (struct frame *f)
}
}
#ifndef HAVE_PGTK
bool
xg_event_is_for_menubar (struct frame *f, const XEvent *event)
xg_event_is_for_menubar (struct frame *f, const EVENT *event)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
GList *iter;
GdkRectangle rec;
GList *list;
@ -3628,6 +3790,7 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
g_list_free (list);
return iter != 0;
}
#endif
@ -3783,6 +3946,7 @@ xg_get_default_scrollbar_height (struct frame *f)
return scroll_bar_width_for_theme * xg_get_scale (f);
}
#ifndef HAVE_PGTK
/* Return the scrollbar id for X Window WID on display DPY.
Return -1 if WID not in id_to_widget. */
@ -3803,6 +3967,7 @@ xg_get_scroll_id_for_window (Display *dpy, Window wid)
return -1;
}
#endif
/* Callback invoked when scroll bar WIDGET is destroyed.
DATA is the index into id_to_widget for WIDGET.
@ -3852,7 +4017,7 @@ xg_finish_scroll_bar_creation (struct frame *f,
also, which causes flicker. Put an event box between the edit widget
and the scroll bar, so the scroll bar instead draws itself on the
event box window. */
gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1);
gtk_fixed_put (GTK_FIXED (f->output_data.xp->edit_widget), webox, -1, -1);
gtk_container_add (GTK_CONTAINER (webox), wscroll);
xg_set_widget_bg (f, webox, FRAME_BACKGROUND_PIXEL (f));
@ -3862,7 +4027,12 @@ xg_finish_scroll_bar_creation (struct frame *f,
real X window, it and its scroll-bar child try to draw on the
Emacs main window, which we draw over using Xlib. */
gtk_widget_realize (webox);
#ifdef HAVE_PGTK
gtk_widget_show_all(webox);
#endif
#ifndef HAVE_PGTK
GTK_WIDGET_TO_X_WIN (webox);
#endif
/* Set the cursor to an arrow. */
xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor);
@ -3967,7 +4137,7 @@ xg_update_scrollbar_pos (struct frame *f,
GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
if (wscroll)
{
GtkWidget *wfixed = f->output_data.x->edit_widget;
GtkWidget *wfixed = f->output_data.xp->edit_widget;
GtkWidget *wparent = gtk_widget_get_parent (wscroll);
gint msl;
int scale = xg_get_scale (f);
@ -4007,7 +4177,11 @@ xg_update_scrollbar_pos (struct frame *f,
/* Clear under old scroll bar position. */
oldw += (scale - 1) * oldw;
oldx -= (scale - 1) * oldw;
#ifndef HAVE_PGTK
x_clear_area (f, oldx, oldy, oldw, oldh);
#else
pgtk_clear_area (f, oldx, oldy, oldw, oldh);
#endif
}
if (!hidden)
@ -4015,15 +4189,23 @@ xg_update_scrollbar_pos (struct frame *f,
GtkWidget *scrollbar = xg_get_widget_from_map (scrollbar_id);
GtkWidget *webox = gtk_widget_get_parent (scrollbar);
#ifndef HAVE_PGTK
/* Don't obscure any child frames. */
XLowerWindow (FRAME_X_DISPLAY (f), GTK_WIDGET_TO_X_WIN (webox));
#else
gdk_window_lower(gtk_widget_get_window(webox));
#endif
}
/* GTK does not redraw until the main loop is entered again, but
if there are no X events pending we will not enter it. So we sync
here to get some events. */
#ifndef HAVE_PGTK
x_sync (f);
#else
gdk_flush();
#endif
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
@ -4048,7 +4230,7 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
if (wscroll)
{
GtkWidget *wfixed = f->output_data.x->edit_widget;
GtkWidget *wfixed = f->output_data.xp->edit_widget;
GtkWidget *wparent = gtk_widget_get_parent (wscroll);
gint msl;
int scale = xg_get_scale (f);
@ -4084,7 +4266,11 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
}
if (oldx != -1 && oldw > 0 && oldh > 0)
/* Clear under old scroll bar position. */
#ifndef HAVE_PGTK
x_clear_area (f, oldx, oldy, oldw, oldh);
#else
pgtk_clear_area (f, oldx, oldy, oldw, oldh);
#endif
/* GTK does not redraw until the main loop is entered again, but
if there are no X events pending we will not enter it. So we sync
@ -4095,11 +4281,19 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
xg_get_widget_from_map (scrollbar_id);
GtkWidget *webox = gtk_widget_get_parent (scrollbar);
#ifndef HAVE_PGTK
/* Don't obscure any child frames. */
XLowerWindow (FRAME_X_DISPLAY (f), GTK_WIDGET_TO_X_WIN (webox));
#else
gdk_window_lower(gtk_widget_get_window(webox));
#endif
}
#ifndef HAVE_PGTK
x_sync (f);
#else
gdk_flush();
#endif
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
@ -4128,6 +4322,8 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: ----------------------------------");
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: %p, %d, %d, %d.", bar, portion, position, whole);
if (wscroll && bar->dragging == -1)
{
GtkAdjustment *adj;
@ -4159,17 +4355,26 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
top = (gdouble) position / whole;
shown = (gdouble) portion / whole;
}
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: position=%d, portion=%d, whole=%d", position, portion, whole);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: top=%f, shown=%f", top, shown);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: shown*range=%f", shown * XG_SB_RANGE);
size = clip_to_bounds (1, shown * XG_SB_RANGE, XG_SB_RANGE);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: size=%d.", size);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: top*range=%f.", top * XG_SB_RANGE);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: max-size=%d.", XG_SB_MAX - size);
value = clip_to_bounds (XG_SB_MIN, top * XG_SB_RANGE, XG_SB_MAX - size);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: value=%d.", value);
/* Assume all lines are of equal size. */
new_step = size / max (1, FRAME_LINES (f));
old_size = gtk_adjustment_get_page_size (adj);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: old_size=%d, size=%d", old_size, size);
if (old_size != size)
{
int old_step = gtk_adjustment_get_step_increment (adj);
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: old_step=%d, new_step=%d", old_step, new_step);
if (old_step != new_step)
{
gtk_adjustment_set_page_size (adj, size);
@ -4180,6 +4385,8 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
}
}
PGTK_TRACE("xg_set_toolkit_scroll_bar_thumb: changed=%d, old=%d, value=%d.",
changed, int_gtk_range_get_value (GTK_RANGE (wscroll)), value);
if (changed || int_gtk_range_get_value (GTK_RANGE (wscroll)) != value)
{
block_input ();
@ -4243,14 +4450,24 @@ xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
frame. This function does additional checks. */
bool
xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
xg_event_is_for_scrollbar (struct frame *f, const EVENT *event)
{
bool retval = 0;
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
)
{
/* 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)
@ -4264,11 +4481,17 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
#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);
}
else if (f
#ifndef HAVE_PGTK
&& ((event->type == ButtonRelease && event->xbutton.button < 4)
|| event->type == MotionNotify))
|| event->type == MotionNotify)
#else
&& ((event->type == GDK_BUTTON_RELEASE && event->button.button < 4)
|| event->type == GDK_MOTION_NOTIFY)
#endif
)
{
/* If we are releasing or moving the scroll bar, it has the grab. */
GtkWidget *w = gtk_grab_get_current ();
@ -4346,7 +4569,11 @@ draw_page (GtkPrintOperation *operation, GtkPrintContext *context,
struct frame *f = XFRAME (Fnth (make_fixnum (page_nr), frames));
cairo_t *cr = gtk_print_context_get_cairo_context (context);
#ifndef HAVE_PGTK
x_cr_draw_frame (cr, f);
#else
pgtk_cr_draw_frame (cr, f);
#endif
}
void
@ -4447,7 +4674,11 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
/* Convert between the modifier bits GDK uses and the modifier bits
Emacs uses. This assumes GDK and X masks are the same, which they are when
this is written. */
#ifndef HAVE_PGTK
event.modifiers = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), mod);
#else
event.modifiers = pgtk_gtk_to_emacs_modifiers (mod);
#endif
kbd_buffer_store_event (&event);
/* Return focus to the frame after we have clicked on a detached
@ -4517,7 +4748,6 @@ xg_tool_bar_help_callback (GtkWidget *w,
Returns FALSE to tell GTK to keep processing this event. */
#ifndef HAVE_GTK3
static gboolean
xg_tool_bar_item_expose_callback (GtkWidget *w,
GdkEventExpose *event,
@ -4537,14 +4767,13 @@ xg_tool_bar_item_expose_callback (GtkWidget *w,
return FALSE;
}
#endif
/* Attach a tool bar to frame F. */
static void
xg_pack_tool_bar (struct frame *f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
GtkWidget *top_widget = x->toolbar_widget;
@ -4603,7 +4832,7 @@ tb_size_cb (GtkWidget *widget,
static void
xg_create_tool_bar (struct frame *f)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
#ifdef HAVE_GTK3
GtkStyleContext *gsty;
#endif
@ -4842,7 +5071,7 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name,
static bool
xg_update_tool_bar_sizes (struct frame *f)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
GtkRequisition req;
int nl = 0, nr = 0, nt = 0, nb = 0;
GtkWidget *top_widget = x->toolbar_widget;
@ -4928,7 +5157,11 @@ void
update_frame_tool_bar (struct frame *f)
{
int i, j;
struct x_output *x = f->output_data.x;
#ifndef HAVE_PGTK
struct x_output *x = f->output_data.xp;
#else
struct pgtk_output *x = f->output_data.pgtk;
#endif
int hmargin = 0, vmargin = 0;
GtkToolbar *wtoolbar;
GtkToolItem *ti;
@ -5245,7 +5478,7 @@ update_frame_tool_bar (struct frame *f)
void
free_frame_tool_bar (struct frame *f)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
if (x->toolbar_widget)
{
@ -5291,7 +5524,7 @@ free_frame_tool_bar (struct frame *f)
void
xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
xp_output *x = f->output_data.xp;
GtkWidget *top_widget = x->toolbar_widget;
if (! x->toolbar_widget || ! top_widget)

View File

@ -25,7 +25,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <gtk/gtk.h>
#include "../lwlib/lwlib-widget.h"
#ifdef HAVE_PGTK
#include "pgtkterm.h"
#define EVENT GdkEvent
#else
#include "xterm.h"
#define EVENT XEvent
#endif
/* Minimum and maximum values used for GTK scroll bars */
@ -105,7 +111,7 @@ extern void xg_modify_menubar_widgets (GtkWidget *menubar,
extern void xg_update_frame_menubar (struct frame *f);
extern bool xg_event_is_for_menubar (struct frame *, const XEvent *);
extern bool xg_event_is_for_menubar (struct frame *, const EVENT *);
extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
@ -142,7 +148,7 @@ extern void xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
int portion,
int position,
int whole);
extern bool xg_event_is_for_scrollbar (struct frame *, const XEvent *);
extern bool xg_event_is_for_scrollbar (struct frame *, const EVENT *);
extern int xg_get_default_scrollbar_width (struct frame *f);
extern int xg_get_default_scrollbar_height (struct frame *f);
@ -157,9 +163,15 @@ extern void xg_frame_set_char_size (struct frame *f, int width, int height);
extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc);
extern int xg_get_scale (struct frame *f);
#ifndef HAVE_PGTK
extern void xg_display_open (char *display_name, Display **dpy);
extern void xg_display_close (Display *dpy);
extern GdkCursor * xg_create_default_cursor (Display *dpy);
#else
extern void xg_display_open (char *display_name, GdkDisplay **dpy);
extern void xg_display_close (GdkDisplay *gdpy);
extern GdkCursor * xg_create_default_cursor (GdkDisplay *gdpy);
#endif
extern bool xg_create_frame_widgets (struct frame *f);
extern void xg_free_frame_widgets (struct frame *f);

View File

@ -129,6 +129,10 @@ typedef struct ns_bitmap_record Bitmap_Record;
#endif /* HAVE_NS */
#ifdef HAVE_PGTK
typedef struct pgtk_bitmap_record Bitmap_Record;
#endif /* HAVE_PGTK */
#if (defined HAVE_X_WINDOWS \
&& ! (defined HAVE_NTGUI || defined USE_CAIRO || defined HAVE_NS))
/* W32_TODO : Color tables on W32. */
@ -430,6 +434,14 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
return -1;
#endif
#ifdef HAVE_PGTK
Emacs_Pixmap bitmap = image_pix_container_create_from_bitmap_data(f, bits,
width,
height,
0xffffffff,
0xff000000);
#endif
id = image_allocate_bitmap_record (f);
#ifdef HAVE_NS
@ -437,6 +449,11 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
dpyinfo->bitmaps[id - 1].depth = 1;
#endif
#ifdef HAVE_PGTK
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;
@ -489,6 +506,10 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
return id;
#endif
#ifdef HAVE_PGTK
return -1; // fixme:
#endif
#ifdef HAVE_X_WINDOWS
unsigned int width, height;
Pixmap bitmap;
@ -561,6 +582,9 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
ns_release_object (bm->img);
#endif
#ifdef HAVE_PGTK
#endif
if (bm->file)
{
xfree (bm->file);
@ -1320,7 +1344,6 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
return ascent;
}
/* Image background colors. */
@ -1344,6 +1367,7 @@ four_corners_best (Emacs_Pix_Context pimg, int *corners,
corner_pixels[3] = GET_PIXEL (pimg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
}
else
{
/* Get the colors at the corner_pixels of pimg. */
corner_pixels[0] = GET_PIXEL (pimg, 0, 0);
@ -3908,6 +3932,13 @@ xbm_load (struct frame *f, struct image *img)
XPM images
***********************************************************************/
#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_PGTK)
static bool xpm_image_p (Lisp_Object object);
static bool xpm_load (struct frame *f, struct image *img);
#endif /* HAVE_XPM || HAVE_NS */
#ifdef HAVE_XPM
#ifdef HAVE_NTGUI
/* Indicate to xpm.h that we don't have Xlib. */
@ -4795,7 +4826,7 @@ xpm_load_image (struct frame *f,
Lisp_Object (*get_color_table) (Lisp_Object, const char *, int);
Lisp_Object frame, color_symbols, color_table;
int best_key;
#ifndef HAVE_NS
#if !defined(HAVE_NS)
bool have_mask = false;
#endif
Emacs_Pix_Container ximg = NULL, mask_img = NULL;
@ -4849,7 +4880,7 @@ xpm_load_image (struct frame *f,
}
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)
#ifndef HAVE_NS
#if !defined(HAVE_NS)
|| !image_create_x_image_and_pixmap (f, img, width, height, 1,
&mask_img, 1)
#endif
@ -4977,7 +5008,7 @@ xpm_load_image (struct frame *f,
PUT_PIXEL (ximg, x, y,
FIXNUMP (color_val) ? XFIXNUM (color_val) : frame_fg);
#ifndef HAVE_NS
#if !defined(HAVE_NS)
PUT_PIXEL (mask_img, x, y,
(!EQ (color_val, Qt) ? PIX_MASK_DRAW
: (have_mask = true, PIX_MASK_RETAIN)));
@ -4998,7 +5029,7 @@ xpm_load_image (struct frame *f,
IMAGE_BACKGROUND (img, f, ximg);
image_put_x_image (f, img, ximg, 0);
#ifndef HAVE_NS
#if !defined(HAVE_NS)
if (have_mask)
{
/* Fill in the background_transparent field while we have the
@ -5729,7 +5760,7 @@ image_disable_image (struct frame *f, struct image *img)
if (n_planes < 2 || cross_disabled_images)
{
#ifndef HAVE_NTGUI
#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
#if !defined(HAVE_NS) /* TODO: NS support, however this not needed for toolbars */
#ifndef USE_CAIRO
#define CrossForeground(f) BLACK_PIX_DEFAULT (f)
@ -5807,7 +5838,7 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
image_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
#ifndef HAVE_NTGUI
#ifndef HAVE_NS
#if !defined HAVE_NS
/* Create an image and pixmap serving as mask. */
if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1,
&mask_img, 1))
@ -5869,7 +5900,7 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
if (XGetPixel (ximg, x, y) == bg)
ns_set_alpha (ximg, x, y, 0);
#endif /* HAVE_NS */
#ifndef HAVE_NS
#if !defined HAVE_NS
/* Fill in the background_transparent field while we have the mask handy. */
image_background_transparent (img, f, mask_img);
@ -9314,8 +9345,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
color_scale * pixel.red,
color_scale * pixel.green,
color_scale * pixel.blue));
}
}
}
}
DestroyPixelIterator (iterator);
}
@ -10511,7 +10542,7 @@ static struct image_type const image_types[] =
{ 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
#if defined HAVE_XPM || defined HAVE_NS || defined USE_CAIRO
{ SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
IMAGE_TYPE_INIT (init_xpm_functions) },
#endif

View File

@ -3298,7 +3298,7 @@ struct frame;
#endif
/* Define if the windowing system provides a tool-bar. */
#if defined (USE_GTK) || defined (HAVE_NS)
#if (defined (USE_GTK) && !defined(HAVE_PGTK)) || defined (HAVE_NS)
#define HAVE_EXT_TOOL_BAR true
#endif

2778
src/pgtkfns.c Normal file

File diff suppressed because it is too large Load Diff

136
src/pgtkgui.h Normal file
View File

@ -0,0 +1,136 @@
/* Definitions and headers for communication on the pure Gtk+3.
Copyright (C) 1995, 2005, 2008-2017 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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 __PGTKGUI_H__
#define __PGTKGUI_H__
/* Emulate XCharStruct. */
typedef struct _XCharStruct
{
int rbearing;
int lbearing;
int width;
int ascent;
int descent;
} XCharStruct;
/* Fake structure from Xlib.h to represent two-byte characters. */
typedef unsigned short unichar;
typedef unichar XChar2b;
#define STORE_XCHAR2B(chp, b1, b2) \
(*(chp) = ((XChar2b)((((b1) & 0x00ff) << 8) | ((b2) & 0x00ff))))
#define XCHAR2B_BYTE1(chp) \
((*(chp) & 0xff00) >> 8)
#define XCHAR2B_BYTE2(chp) \
(*(chp) & 0x00ff)
/* XXX: xfaces requires these structures, but the question is are we
forced to use them? */
typedef struct _XGCValues
{
unsigned long foreground;
unsigned long background;
void *font;
} XGCValues;
typedef XGCValues * GC;
#define GCForeground 0x01
#define GCBackground 0x02
#define GCFont 0x03
typedef void *Pixmap;
typedef void *Cursor;
#define No_Cursor (0)
typedef void * Color;
typedef int Window;
typedef struct _GdkDisplay Display;
/* Xism */
typedef Lisp_Object XrmDatabase;
/* some sort of attempt to normalize rectangle handling.. seems a bit much
for what is accomplished */
typedef struct {
int x, y;
unsigned width, height;
} XRectangle;
#define NativeRectangle XRectangle
#define CONVERT_TO_EMACS_RECT(xr, nr) \
((xr).x = (nr).origin.x, \
(xr).y = (nr).origin.y, \
(xr).width = (nr).size.width, \
(xr).height = (nr).size.height)
#define CONVERT_FROM_EMACS_RECT(xr, nr) \
((nr).x = (xr).x, \
(nr).y = (xr).y, \
(nr).width = (xr).width, \
(nr).height = (xr).height)
#define STORE_NATIVE_RECT(nr, px, py, pwidth, pheight) \
((nr).x = (px), \
(nr).y = (py), \
(nr).width = (pwidth), \
(nr).height = (pheight))
/* This stuff needed by frame.c. */
#define ForgetGravity 0
#define NorthWestGravity 1
#define NorthGravity 2
#define NorthEastGravity 3
#define WestGravity 4
#define CenterGravity 5
#define EastGravity 6
#define SouthWestGravity 7
#define SouthGravity 8
#define SouthEastGravity 9
#define StaticGravity 10
#define NoValue 0x0000
#define XValue 0x0001
#define YValue 0x0002
#define WidthValue 0x0004
#define HeightValue 0x0008
#define AllValues 0x000F
#define XNegative 0x0010
#define YNegative 0x0020
#define USPosition (1L << 0) /* user specified x, y */
#define USSize (1L << 1) /* user specified width, height */
#define PPosition (1L << 2) /* program specified position */
#define PSize (1L << 3) /* program specified size */
#define PMinSize (1L << 4) /* program specified minimum size */
#define PMaxSize (1L << 5) /* program specified maximum size */
#define PResizeInc (1L << 6) /* program specified resize increments */
#define PAspect (1L << 7) /* program specified min, max aspect ratios */
#define PBaseSize (1L << 8) /* program specified base for incrementing */
#define PWinGravity (1L << 9) /* program specified window gravity */
#endif /* __PGTKGUI_H__ */

466
src/pgtkselect.c Normal file
View File

@ -0,0 +1,466 @@
/* Gtk selection processing for emacs.
Copyright (C) 1993-1994, 2005-2006, 2008-2017 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>. */
/*
Originally by Carl Edman
Updated by Christian Limpach (chris@nice.ch)
OpenStep/Rhapsody port by Scott Bender (sbender@harmony-ds.com)
macOS/Aqua port by Christophe de Dinechin (descubes@earthlink.net)
GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
*/
/* This should be the first include, as it may set up #defines affecting
interpretation of even the system includes. */
#include <config.h>
#include "lisp.h"
#include "pgtkterm.h"
#include "termhooks.h"
#include "keyboard.h"
#include "pgtkselect.h"
#include <gdk/gdk.h>
#if 0
static Lisp_Object Vselection_alist;
#endif
static GQuark quark_primary_data = 0;
static GQuark quark_primary_size = 0;
static GQuark quark_secondary_data = 0;
static GQuark quark_secondary_size = 0;
static GQuark quark_clipboard_data = 0;
static GQuark quark_clipboard_size = 0;
/* ==========================================================================
Internal utility functions
========================================================================== */
/* From a Lisp_Object, return a suitable frame for selection
operations. OBJECT may be a frame, a terminal object, or nil
(which stands for the selected frame--or, if that is not an pgtk
frame, the first pgtk display on the list). If no suitable frame can
be found, return NULL. */
static struct frame *
frame_for_pgtk_selection (Lisp_Object object)
{
Lisp_Object tail, frame;
struct frame *f;
if (NILP (object))
{
f = XFRAME (selected_frame);
if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
return f;
FOR_EACH_FRAME (tail, frame)
{
f = XFRAME (frame);
if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
return f;
}
}
else if (TERMINALP (object))
{
struct terminal *t = decode_live_terminal (object);
if (t->type == output_pgtk)
FOR_EACH_FRAME (tail, frame)
{
f = XFRAME (frame);
if (FRAME_LIVE_P (f) && f->terminal == t)
return f;
}
}
else if (FRAMEP (object))
{
f = XFRAME (object);
if (FRAME_PGTK_P (f) && FRAME_LIVE_P (f))
return f;
}
return NULL;
}
static GtkClipboard *symbol_to_gtk_clipboard(GtkWidget *widget, Lisp_Object symbol)
{
GdkAtom atom;
CHECK_SYMBOL (symbol);
if (NILP(symbol)) {
atom = GDK_SELECTION_PRIMARY;
} else if (EQ(symbol, QCLIPBOARD)) {
atom = GDK_SELECTION_CLIPBOARD;
} else if (EQ(symbol, QPRIMARY)) {
atom = GDK_SELECTION_PRIMARY;
} else if (EQ(symbol, QSECONDARY)) {
atom = GDK_SELECTION_SECONDARY;
} else if (EQ(symbol, Qt)) {
atom = GDK_SELECTION_SECONDARY;
} else {
atom = 0;
error ("Bad selection");
}
return gtk_widget_get_clipboard(widget, atom);
}
static void selection_type_to_quarks(GdkAtom type, GQuark *quark_data, GQuark *quark_size)
{
if (type == GDK_SELECTION_PRIMARY) {
*quark_data = quark_primary_data;
*quark_size = quark_primary_size;
} else if (type == GDK_SELECTION_SECONDARY) {
*quark_data = quark_secondary_data;
*quark_size = quark_secondary_size;
} else if (type == GDK_SELECTION_CLIPBOARD) {
*quark_data = quark_clipboard_data;
*quark_size = quark_clipboard_size;
} else {
/* fixme: Is it safe to use 'error' here? */
error("Unknown selection type.");
}
}
static void
get_func(GtkClipboard *cb, GtkSelectionData *data, guint info, gpointer user_data_or_owner)
{
PGTK_TRACE("get_func:");
GObject *obj = G_OBJECT(user_data_or_owner);
const char *str;
int size;
GQuark quark_data, quark_size;
selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data, &quark_size);
str = g_object_get_qdata(obj, quark_data);
size = GPOINTER_TO_SIZE(g_object_get_qdata(obj, quark_size));
PGTK_TRACE("get_func: str: %s", str);
gtk_selection_data_set_text(data, str, size);
}
static void
clear_func(GtkClipboard *cb, gpointer user_data_or_owner)
{
PGTK_TRACE("clear_func:");
GObject *obj = G_OBJECT(user_data_or_owner);
GQuark quark_data, quark_size;
selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data, &quark_size);
g_object_set_qdata(obj, quark_data, NULL);
g_object_set_qdata(obj, quark_size, 0);
}
/* ==========================================================================
Functions used externally
========================================================================== */
void pgtk_selection_init(void)
{
if (quark_primary_data == 0) {
quark_primary_data = g_quark_from_static_string("pgtk-primary-data");
quark_primary_size = g_quark_from_static_string("pgtk-primary-size");
quark_secondary_data = g_quark_from_static_string("pgtk-secondary-data");
quark_secondary_size = g_quark_from_static_string("pgtk-secondary-size");
quark_clipboard_data = g_quark_from_static_string("pgtk-clipboard-data");
quark_clipboard_size = g_quark_from_static_string("pgtk-clipboard-size");
}
}
void pgtk_selection_lost(GtkWidget *widget, GdkEventSelection *event, gpointer user_data)
{
GQuark quark_data, quark_size;
PGTK_TRACE("pgtk_selection_lost:");
selection_type_to_quarks(event->selection, &quark_data, &quark_size);
g_object_set_qdata(G_OBJECT(widget), quark_data, NULL);
g_object_set_qdata(G_OBJECT(widget), quark_size, 0);
}
/* ==========================================================================
Lisp Defuns
========================================================================== */
DEFUN ("pgtk-own-selection-internal", Fpgtk_own_selection_internal,
Spgtk_own_selection_internal, 2, 3, 0,
doc: /* Assert an X selection of type SELECTION and value VALUE.
SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
\(Those are literal upper-case symbol names, since that's what X expects.)
VALUE is typically a string, or a cons of two markers, but may be
anything that the functions on `selection-converter-alist' know about.
FRAME should be a frame that should own the selection. If omitted or
nil, it defaults to the selected frame.*/)
(Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
{
PGTK_TRACE("pgtk-own-selection-internal.");
Lisp_Object successful_p = Qnil;
Lisp_Object target_symbol, rest;
GtkClipboard *cb;
struct frame *f;
GQuark quark_data, quark_size;
check_window_system (NULL);
if (NILP (frame)) frame = selected_frame;
if (!FRAME_LIVE_P (XFRAME (frame)) || !FRAME_PGTK_P (XFRAME (frame)))
error ("pgtk selection unavailable for this frame");
f = XFRAME(frame);
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection);
selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data, &quark_size);
/* We only support copy of text. */
target_symbol = QTEXT;
if (STRINGP (value))
{
GtkTargetList *list;
GtkTargetEntry *targets;
gint n_targets;
GtkWidget *widget;
list = gtk_target_list_new (NULL, 0);
gtk_target_list_add_text_targets (list, 0);
targets = gtk_target_table_new_from_list (list, &n_targets);
int size = SBYTES(value);
gchar *str = xmalloc(size + 1);
memcpy(str, SSDATA(value), size);
str[size] = '\0';
widget = FRAME_GTK_WIDGET(f);
g_object_set_qdata_full(G_OBJECT(widget), quark_data, str, xfree);
g_object_set_qdata_full(G_OBJECT(widget), quark_size, GSIZE_TO_POINTER(size), NULL);
PGTK_TRACE("set_with_owner: owner=%p", FRAME_GTK_WIDGET(f));
if (gtk_clipboard_set_with_owner (cb,
targets, n_targets,
get_func, clear_func,
G_OBJECT(FRAME_GTK_WIDGET(f)))) {
PGTK_TRACE("set_with_owner succeeded..");
successful_p = Qt;
} else {
PGTK_TRACE("set_with_owner failed.");
}
gtk_clipboard_set_can_store (cb, NULL, 0);
gtk_target_table_free (targets, n_targets);
gtk_target_list_unref (list);
}
if (!EQ (Vpgtk_sent_selection_hooks, Qunbound))
{
/* FIXME: Use run-hook-with-args! */
for (rest = Vpgtk_sent_selection_hooks; CONSP (rest); rest = Fcdr (rest))
call3 (Fcar (rest), selection, target_symbol, successful_p);
}
return value;
}
DEFUN ("pgtk-disown-selection-internal", Fpgtk_disown_selection_internal,
Spgtk_disown_selection_internal, 1, 3, 0,
doc: /* If we own the selection SELECTION, disown it.
Disowning it means there is no such selection.
Sets the last-change time for the selection to TIME-OBJECT (by default
the time of the last event).
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
frame's display, or the first available X display.
On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
On MS-DOS, all this does is return non-nil if we own the selection.
On PGTK, the TIME-OBJECT is unused. */)
(Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
{
PGTK_TRACE("pgtk-disown-selection-internal.");
struct frame *f = frame_for_pgtk_selection (terminal);
GtkClipboard *cb;
if (!f)
return Qnil;
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection);
gtk_clipboard_clear(cb);
return Qt;
}
DEFUN ("pgtk-selection-exists-p", Fpgtk_selection_exists_p, Spgtk_selection_exists_p,
0, 2, 0, doc: /* Whether there is an owner for the given X selection.
SELECTION should be the name of the selection in question, typically
one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
these literal upper-case names.) The symbol nil is the same as
`PRIMARY', and t is the same as `SECONDARY'.
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
frame's display, or the first available X display.
On Nextstep, TERMINAL is unused. */)
(Lisp_Object selection, Lisp_Object terminal)
{
PGTK_TRACE("pgtk-selection-exists-p.");
struct frame *f = frame_for_pgtk_selection (terminal);
GtkClipboard *cb;
if (!f)
return Qnil;
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection);
return gtk_clipboard_wait_is_text_available(cb) ? Qt : Qnil;
}
DEFUN ("pgtk-selection-owner-p", Fpgtk_selection_owner_p, Spgtk_selection_owner_p,
0, 2, 0,
doc: /* Whether the current Emacs process owns the given X Selection.
The arg should be the name of the selection in question, typically one of
the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
\(Those are literal upper-case symbol names, since that's what X expects.)
For convenience, the symbol nil is the same as `PRIMARY',
and t is the same as `SECONDARY'.
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
frame's display, or the first available X display.
On Nextstep, TERMINAL is unused. */)
(Lisp_Object selection, Lisp_Object terminal)
{
PGTK_TRACE("pgtk-selection-owner-p.");
struct frame *f = frame_for_pgtk_selection (terminal);
GtkClipboard *cb;
GObject *obj;
GQuark quark_data, quark_size;
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection);
selection_type_to_quarks(gtk_clipboard_get_selection(cb), &quark_data, &quark_size);
obj = gtk_clipboard_get_owner(cb);
return g_object_get_qdata(obj, quark_data) != NULL ? Qt : Qnil;
}
DEFUN ("pgtk-get-selection-internal", Fpgtk_get_selection_internal,
Spgtk_get_selection_internal, 2, 4, 0,
doc: /* Return text selected from some X window.
SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
\(Those are literal upper-case symbol names, since that's what X expects.)
TARGET-TYPE is the type of data desired, typically `STRING'.
TIME-STAMP is the time to use in the XConvertSelection call for foreign
selections. If omitted, defaults to the time for the last event.
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
frame's display, or the first available X display.
On Nextstep, TIME-STAMP and TERMINAL are unused.
On PGTK, TIME-STAMP is unused. */)
(Lisp_Object selection_symbol, Lisp_Object target_type,
Lisp_Object time_stamp, Lisp_Object terminal)
{
struct frame *f = frame_for_pgtk_selection (terminal);
GtkClipboard *cb;
CHECK_SYMBOL (selection_symbol);
CHECK_SYMBOL (target_type);
if (EQ (target_type, QMULTIPLE))
error ("Retrieving MULTIPLE selections is currently unimplemented");
if (!f)
error ("PGTK selection unavailable for this frame");
cb = symbol_to_gtk_clipboard(FRAME_GTK_WIDGET(f), selection_symbol);
gchar *s = gtk_clipboard_wait_for_text(cb);
if (s == NULL)
return Qnil;
int size = strlen(s);
Lisp_Object str = make_unibyte_string (s, size);
Fput_text_property (make_fixnum (0), make_fixnum (size),
Qforeign_selection, QUTF8_STRING, str);
return str;
}
void
nxatoms_of_pgtkselect (void)
{
PGTK_TRACE("nxatoms_of_pgtkselect");
}
void
syms_of_pgtkselect (void)
{
PGTK_TRACE("syms_of_pgtkselect");
DEFSYM (QCLIPBOARD, "CLIPBOARD");
DEFSYM (QSECONDARY, "SECONDARY");
DEFSYM (QTEXT, "TEXT");
DEFSYM (QFILE_NAME, "FILE_NAME");
DEFSYM (QMULTIPLE, "MULTIPLE");
DEFSYM (Qforeign_selection, "foreign-selection");
DEFSYM (QUTF8_STRING, "UTF8_STRING");
defsubr (&Spgtk_disown_selection_internal);
defsubr (&Spgtk_get_selection_internal);
defsubr (&Spgtk_own_selection_internal);
defsubr (&Spgtk_selection_exists_p);
defsubr (&Spgtk_selection_owner_p);
#if 0
Vselection_alist = Qnil;
staticpro (&Vselection_alist);
#endif
DEFVAR_LISP ("pgtk-sent-selection-hooks", Vpgtk_sent_selection_hooks,
"A list of functions to be called when Emacs answers a selection request.\n\
The functions are called with four arguments:\n\
- the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
- the selection-type which Emacs was asked to convert the\n\
selection into before sending (for example, `STRING' or `LENGTH');\n\
- a flag indicating success or failure for responding to the request.\n\
We might have failed (and declined the request) for any number of reasons,\n\
including being asked for a selection that we no longer own, or being asked\n\
to convert into a type that we don't know about or that is inappropriate.\n\
This hook doesn't let you change the behavior of Emacs's selection replies,\n\
it merely informs you that they have happened.");
Vpgtk_sent_selection_hooks = Qnil;
}

31
src/pgtkselect.h Normal file
View File

@ -0,0 +1,31 @@
/* Definitions and headers for selection of pure Gtk+3.
Copyright (C) 1989, 1993, 2005, 2008-2017 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>. */
#include "dispextern.h"
#include "frame.h"
#ifdef HAVE_PGTK
#include <gtk/gtk.h>
extern void pgtk_selection_init(void);
void pgtk_selection_lost(GtkWidget *widget, GdkEventSelection *event, gpointer user_data);
#endif /* HAVE_PGTK */

6395
src/pgtkterm.c Normal file

File diff suppressed because it is too large Load Diff

569
src/pgtkterm.h Normal file
View File

@ -0,0 +1,569 @@
/* Definitions and headers for communication with pure Gtk+3.
Copyright (C) 1989, 1993, 2005, 2008-2017 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>. */
#include "dispextern.h"
#include "frame.h"
#include "character.h"
#include "font.h"
#include "sysselect.h"
#ifdef HAVE_PGTK
#include <gtk/gtk.h>
// #define PGTK_DEBUG 1
#ifdef PGTK_DEBUG
extern void pgtk_log(const char *file, int lineno, const char *fmt, ...)
ATTRIBUTE_FORMAT_PRINTF (3, 4);
#define PGTK_TRACE(fmt, ...) pgtk_log(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
extern void pgtk_backtrace(const char *file, int lineno);
#define PGTK_BACKTRACE() pgtk_backtrace(__FILE__, __LINE__)
#else
#define PGTK_TRACE(fmt, ...) ((void) 0)
#define PGTK_BACKTRACE() ((void) 0)
#endif
/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */
#if GTK_CHECK_VERSION (2, 14, 0)
#define USE_GTK_TOOLTIP
#endif
/* could use list to store these, but rest of emacs has a big infrastructure
for managing a table of bitmap "records" */
struct pgtk_bitmap_record
{
void *img;
char *file;
int refcount;
int height, width, depth;
};
#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define ALPHA_FROM_ULONG(color) ((color) >> 24)
#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
struct scroll_bar
{
/* These fields are shared by all vectors. */
union vectorlike_header header;
/* The window we're a scroll bar for. */
Lisp_Object window;
/* The next and previous in the chain of scroll bars in this frame. */
Lisp_Object next, prev;
/* Fields from `x_window' down will not be traced by the GC. */
/* The X window representing this scroll bar. */
Window x_window;
/* The position and size of the scroll bar in pixels, relative to the
frame. */
int top, left, width, height;
/* The starting and ending positions of the handle, relative to the
handle area (i.e. zero is the top position, not
SCROLL_BAR_TOP_BORDER). If they're equal, that means the handle
hasn't been drawn yet.
These are not actually the locations where the beginning and end
are drawn; in order to keep handles from becoming invisible when
editing large files, we establish a minimum height by always
drawing handle bottoms VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
where they would be normally; the bottom and top are in a
different co-ordinate system. */
int start, end;
/* If the scroll bar handle is currently being dragged by the user,
this is the number of pixels from the top of the handle to the
place where the user grabbed it. If the handle isn't currently
being dragged, this is -1. */
int dragging;
#if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
/* Last scroll bar part seen in xaw_jump_callback and xaw_scroll_callback. */
enum scroll_bar_part last_seen_part;
#endif
#if defined (USE_TOOLKIT_SCROLL_BARS) && !defined (USE_GTK)
/* Last value of whole for horizontal scrollbars. */
int whole;
#endif
/* True if the scroll bar is horizontal. */
bool horizontal;
};
/* init'd in pgtk_initialize_display_info () */
struct pgtk_display_info
{
/* Chain of all pgtk_display_info structures. */
struct pgtk_display_info *next;
/* The generic display parameters corresponding to this PGTK display. */
struct terminal *terminal;
/* This says how to access this display in Gdk. */
GdkDisplay *gdpy;
/* This is a cons cell of the form (NAME . FONT-LIST-CACHE). */
Lisp_Object name_list_element;
/* Number of frames that are on this display. */
int reference_count;
/* Logical identifier of this display. */
unsigned x_id;
/* Default name for all frames on this display. */
char *x_id_name;
/* The number of fonts loaded. */
int n_fonts;
/* Minimum width over all characters in all fonts in font_table. */
int smallest_char_width;
/* Minimum font height over all fonts in font_table. */
int smallest_font_height;
struct pgtk_bitmap_record *bitmaps;
ptrdiff_t bitmaps_size;
ptrdiff_t bitmaps_last;
/* DPI resolution of this screen */
double resx, resy;
/* Mask of things that cause the mouse to be grabbed */
int grabbed;
int n_planes;
int color_p;
Window root_window;
/* Xism */
XrmDatabase xrdb;
/* The cursor to use for vertical scroll bars. */
Emacs_Cursor vertical_scroll_bar_cursor;
/* The cursor to use for horizontal scroll bars. */
Emacs_Cursor horizontal_scroll_bar_cursor;
/* Information about the range of text currently shown in
mouse-face. */
Mouse_HLInfo mouse_highlight;
struct frame *x_highlight_frame;
struct frame *x_focus_frame;
/* The last frame mentioned in a FocusIn or FocusOut event. This is
separate from x_focus_frame, because whether or not LeaveNotify
events cause us to lose focus depends on whether or not we have
received a FocusIn event for it. */
struct frame *x_focus_event_frame;
/* The frame where the mouse was last time we reported a mouse event. */
struct frame *last_mouse_frame;
/* The frame where the mouse was last time we reported a mouse motion. */
struct frame *last_mouse_motion_frame;
/* Position where the mouse was last time we reported a motion.
This is a position on last_mouse_motion_frame. */
int last_mouse_motion_x;
int last_mouse_motion_y;
/* Where the mouse was last time we reported a mouse position. */
XRectangle last_mouse_glyph;
/* Time of last mouse movement. */
Time last_mouse_movement_time;
/* The scroll bar in which the last motion event occurred. */
void *last_mouse_scroll_bar;
/* The GDK cursor for scroll bars and popup menus. */
GdkCursor *xg_cursor;
/* The frame where the mouse was last time we reported a mouse position. */
struct frame *last_mouse_glyph_frame;
};
/* This is a chain of structures for all the PGTK displays currently in use. */
extern struct pgtk_display_info *x_display_list;
struct pgtk_output
{
#if 0
void *view;
void *miniimage;
#endif
unsigned long cursor_color;
unsigned long foreground_color;
unsigned long background_color;
void *toolbar;
/* Cursors */
Emacs_Cursor current_cursor;
Emacs_Cursor text_cursor;
Emacs_Cursor nontext_cursor;
Emacs_Cursor modeline_cursor;
Emacs_Cursor hand_cursor;
Emacs_Cursor hourglass_cursor;
Emacs_Cursor horizontal_drag_cursor;
Emacs_Cursor vertical_drag_cursor;
Emacs_Cursor left_edge_cursor;
Emacs_Cursor top_left_corner_cursor;
Emacs_Cursor top_edge_cursor;
Emacs_Cursor top_right_corner_cursor;
Emacs_Cursor right_edge_cursor;
Emacs_Cursor bottom_right_corner_cursor;
Emacs_Cursor bottom_edge_cursor;
Emacs_Cursor bottom_left_corner_cursor;
/* PGTK-specific */
Emacs_Cursor current_pointer;
/* Widget whose cursor is hourglass_cursor. This widget is temporarily
mapped to display an hourglass cursor. */
GtkWidget *hourglass_widget;
XGCValues cursor_xgcv;
/* lord knows why Emacs needs to know about our Window ids.. */
Window window_desc, parent_desc;
char explicit_parent;
struct font *font;
int baseline_offset;
/* If a fontset is specified for this frame instead of font, this
value contains an ID of the fontset, else -1. */
int fontset; /* only used with font_backend */
int icon_top;
int icon_left;
/* The size of the extra width currently allotted for vertical
scroll bars, in pixels. */
int vertical_scroll_bar_extra;
/* The height of the titlebar decoration (included in PGTKWindow's frame). */
int titlebar_height;
/* The height of the toolbar if displayed, else 0. */
int toolbar_height;
/* This is the Emacs structure for the PGTK display this frame is on. */
struct pgtk_display_info *display_info;
/* Non-zero if we are zooming (maximizing) the frame. */
int zooming;
/* Non-zero if we are doing an animation, e.g. toggling the tool bar. */
int in_animation;
/* The last size hints set. */
GdkGeometry size_hints;
long hint_flags;
/* The widget of this screen. This is the window of a top widget. */
GtkWidget *widget;
/* The widget of the edit portion of this screen; the window in
"window_desc" is inside of this. */
GtkWidget *edit_widget;
/* The widget used for laying out widgets vertically. */
GtkWidget *vbox_widget;
/* The widget used for laying out widgets horizontally. */
GtkWidget *hbox_widget;
/* The menubar in this frame. */
GtkWidget *menubar_widget;
/* The tool bar in this frame */
GtkWidget *toolbar_widget;
/* True if tool bar is packed into the hbox widget (i.e. vertical). */
bool_bf toolbar_in_hbox : 1;
bool_bf toolbar_is_packed : 1;
#ifdef USE_GTK_TOOLTIP
GtkTooltip *ttip_widget;
GtkWidget *ttip_lbl;
GtkWindow *ttip_window;
#endif /* USE_GTK_TOOLTIP */
/* Height of menu bar widget, in pixels. This value
is not meaningful if the menubar is turned off. */
int menubar_height;
/* Height of tool bar widget, in pixels. top_height is used if tool bar
at top, bottom_height if tool bar is at the bottom.
Zero if not using an external tool bar or if tool bar is vertical. */
int toolbar_top_height, toolbar_bottom_height;
/* Width of tool bar widget, in pixels. left_width is used if tool bar
at left, right_width if tool bar is at the right.
Zero if not using an external tool bar or if tool bar is horizontal. */
int toolbar_left_width, toolbar_right_width;
#ifdef USE_CAIRO
/* Cairo drawing context. */
cairo_t *cr_context;
/* Cairo surface for double buffering */
cairo_surface_t *cr_surface;
cairo_surface_t *cr_surface_visible_bell;
#endif
struct atimer *atimer_visible_bell;
int has_been_visible;
/* Relief GCs, colors etc. */
struct relief
{
XGCValues xgcv;
unsigned long pixel;
}
black_relief, white_relief;
/* The background for which the above relief GCs were set up.
They are changed only when a different background is involved. */
unsigned long relief_background;
/* Keep track of focus. May be EXPLICIT if we received a FocusIn for this
frame, or IMPLICIT if we received an EnterNotify.
FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
int focus_state;
};
/* this dummy decl needed to support TTYs */
struct x_output
{
int unused;
};
enum
{
/* Values for focus_state, used as bit mask.
EXPLICIT means we received a FocusIn for the frame and know it has
the focus. IMPLICIT means we received an EnterNotify and the frame
may have the focus if no window manager is running.
FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
FOCUS_NONE = 0,
FOCUS_IMPLICIT = 1,
FOCUS_EXPLICIT = 2
};
/* This gives the pgtk_display_info structure for the display F is on. */
#define FRAME_X_OUTPUT(f) ((f)->output_data.pgtk)
#define FRAME_DISPLAY_INFO(f) (FRAME_X_OUTPUT(f)->display_info)
#define FRAME_FOREGROUND_COLOR(f) (FRAME_X_OUTPUT(f)->foreground_color)
#define FRAME_BACKGROUND_COLOR(f) (FRAME_X_OUTPUT(f)->background_color)
#define FRAME_CURSOR_COLOR(f) (FRAME_X_OUTPUT(f)->cursor_color)
#define FRAME_POINTER_TYPE(f) (FRAME_X_OUTPUT(f)->current_pointer)
#define FRAME_FONT(f) (FRAME_X_OUTPUT(f)->font)
#define FRAME_GTK_OUTER_WIDGET(f) (FRAME_X_OUTPUT(f)->widget)
#define FRAME_GTK_WIDGET(f) (FRAME_X_OUTPUT(f)->edit_widget)
/* aliases */
#define FRAME_PGTK_VIEW(f) FRAME_GTK_WIDGET(f)
#define FRAME_X_WINDOW(f) FRAME_GTK_WIDGET(f)
#define FRAME_X_DISPLAY(f) (FRAME_DISPLAY_INFO(f)->gdpy)
#define DEFAULT_GDK_DISPLAY() gdk_display_get_default()
/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
#define PGTK_FACE_FOREGROUND(f) ((f)->foreground)
#define PGTK_FACE_BACKGROUND(f) ((f)->background)
#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID)
/* Compute pixel height of the frame's titlebar. */
#define FRAME_PGTK_TITLEBAR_HEIGHT(f) 0
#if 0
(PGTKHeight([FRAME_PGTK_VIEW (f) frame]) == 0 ? \
0 \
: (int)(PGTKHeight([FRAME_PGTK_VIEW (f) window].frame) \
- PGTKHeight([PGTKWindow contentRectForFrameRect: \
[[FRAME_PGTK_VIEW (f) window] frame] \
styleMask:[[FRAME_PGTK_VIEW (f) window] styleMask]])))
#endif
/* Compute pixel size for vertical scroll bars */
#define PGTK_SCROLL_BAR_WIDTH(f) \
(FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 \
? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
: (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f))) \
: 0)
/* Compute pixel size for horizontal scroll bars */
#define PGTK_SCROLL_BAR_HEIGHT(f) \
(FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) \
? rint (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0 \
? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) \
: (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f))) \
: 0)
/* Difference btwn char-column-calculated and actual SB widths.
This is only a concern for rendering when SB on left. */
#define PGTK_SCROLL_BAR_ADJUST(w, f) \
(WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) ? \
(FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f) \
- PGTK_SCROLL_BAR_WIDTH (f)) : 0)
/* Difference btwn char-line-calculated and actual SB heights.
This is only a concern for rendering when SB on top. */
#define PGTK_SCROLL_BAR_ADJUST_HORIZONTALLY(w, f) \
(WINDOW_HAS_HORIZONTAL_SCROLL_BARS (w) ? \
(FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f) \
- PGTK_SCROLL_BAR_HEIGHT (f)) : 0)
#define FRAME_MENUBAR_HEIGHT(f) (FRAME_X_OUTPUT(f)->menubar_height)
/* Calculate system coordinates of the left and top of the parent
window or, if there is no parent window, the screen. */
#define PGTK_PARENT_WINDOW_LEFT_POS(f) \
(FRAME_PARENT_FRAME (f) != NULL \
? [[FRAME_PGTK_VIEW (f) window] parentWindow].frame.origin.x : 0)
#define PGTK_PARENT_WINDOW_TOP_POS(f) \
(FRAME_PARENT_FRAME (f) != NULL \
? ([[FRAME_PGTK_VIEW (f) window] parentWindow].frame.origin.y \
+ [[FRAME_PGTK_VIEW (f) window] parentWindow].frame.size.height \
- FRAME_PGTK_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \
: [[[PGTKScreen screepgtk] objectAtIndex: 0] frame].size.height)
#define FRAME_PGTK_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table)
#define FRAME_TOOLBAR_TOP_HEIGHT(f) ((f)->output_data.pgtk->toolbar_top_height)
#define FRAME_TOOLBAR_BOTTOM_HEIGHT(f) \
((f)->output_data.pgtk->toolbar_bottom_height)
#define FRAME_TOOLBAR_HEIGHT(f) \
(FRAME_TOOLBAR_TOP_HEIGHT (f) + FRAME_TOOLBAR_BOTTOM_HEIGHT (f))
#define FRAME_TOOLBAR_LEFT_WIDTH(f) ((f)->output_data.pgtk->toolbar_left_width)
#define FRAME_TOOLBAR_RIGHT_WIDTH(f) ((f)->output_data.pgtk->toolbar_right_width)
#define FRAME_TOOLBAR_WIDTH(f) \
(FRAME_TOOLBAR_LEFT_WIDTH (f) + FRAME_TOOLBAR_RIGHT_WIDTH (f))
#define FRAME_FONTSET(f) (FRAME_X_OUTPUT(f)->fontset)
#define FRAME_BASELINE_OFFSET(f) (FRAME_X_OUTPUT(f)->baseline_offset)
#define BLACK_PIX_DEFAULT(f) 0x000000
#define WHITE_PIX_DEFAULT(f) 0xFFFFFF
/* First position where characters can be shown (instead of scrollbar, if
it is on left. */
#define FIRST_CHAR_POSITION(f) \
(! (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) ? 0 \
: FRAME_SCROLL_BAR_COLS (f))
/* Display init/shutdown functions implemented in pgtkterm.c */
extern struct pgtk_display_info *pgtk_term_init (Lisp_Object display_name, char *resource_name);
extern void pgtk_term_shutdown (int sig);
/* Implemented in pgtkterm, published in or needed from pgtkfns. */
extern void pgtk_clear_frame (struct frame *f);
extern char *pgtk_xlfd_to_fontname (const char *xlfd);
/* Implemented in pgtkfns. */
extern void pgtk_set_doc_edited (void);
extern const char *pgtk_get_defaults_value (const char *key);
/* Color management implemented in pgtkterm. */
extern bool pgtk_defined_color (struct frame *f,
const char *name,
Emacs_Color *color_def, bool alloc,
bool makeIndex);
extern void pgtk_query_color (struct frame *f, Emacs_Color *color);
extern void pgtk_query_colors (struct frame *f, Emacs_Color *colors, int ncolors);
extern int pgtk_parse_color (const char *color_name, Emacs_Color *color);
extern int pgtk_lisp_to_color (Lisp_Object color, Emacs_Color *col);
/* Implemented in pgtkterm.c */
extern void pgtk_clear_area (struct frame *f, int x, int y, int width, int height);
extern int pgtk_gtk_to_emacs_modifiers (int state);
extern void pgtk_clear_under_internal_border (struct frame *f);
extern void pgtk_set_event_handler(struct frame *f);
/* Implemented in pgtkterm.c */
extern int x_display_pixel_height (struct pgtk_display_info *);
extern int x_display_pixel_width (struct pgtk_display_info *);
/* Implemented in pgtkterm.c */
extern void x_destroy_window (struct frame *f);
extern void x_set_parent_frame (struct frame *f, Lisp_Object new_value,
Lisp_Object old_value);
extern void x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value,
Lisp_Object old_value);
extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
Lisp_Object old_value);
extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
Lisp_Object old_value);
extern int pgtk_select (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timespec *timeout,
sigset_t *sigmask);
/* Cairo related functions implemented in pgtkterm.c */
extern cairo_t *pgtk_begin_cr_clip (struct frame *f);
extern void pgtk_end_cr_clip (struct frame *f);
extern void pgtk_set_cr_source_with_gc_foreground (struct frame *f, XGCValues *gc);
extern void pgtk_set_cr_source_with_gc_background (struct frame *f, XGCValues *gc);
extern void pgtk_set_cr_source_with_color (struct frame *f, unsigned long color);
extern void pgtk_cr_draw_frame (cairo_t *cr, struct frame *f);
extern void pgtk_cr_destroy_surface(struct frame *f);
/* Symbol initializations implemented in each pgtk sources. */
extern void syms_of_pgtkterm (void);
extern void syms_of_pgtkfns (void);
extern void syms_of_pgtkmenu (void);
extern void syms_of_pgtkselect (void);
/* Implemented in pgtkselect. */
extern void nxatoms_of_pgtkselect (void);
/* Initialization and marking implemented in pgtkterm.c */
extern void init_pgtkterm (void);
extern void mark_pgtkterm(void);
extern void pgtk_delete_terminal (struct terminal *terminal);
extern void pgtk_make_frame_visible (struct frame *f);
extern void pgtk_make_frame_invisible (struct frame *f);
extern void x_wm_set_size_hint (struct frame *, long, bool);
extern void x_free_frame_resources (struct frame *);
extern void pgtk_iconify_frame (struct frame *f);
extern void x_focus_frame (struct frame *f, bool noactivate);
extern void pgtk_set_scroll_bar_default_width (struct frame *f);
extern void pgtk_set_scroll_bar_default_height (struct frame *f);
extern Lisp_Object x_get_focus_frame (struct frame *frame);
#endif /* HAVE_PGTK */

View File

@ -5599,8 +5599,12 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
timeout = make_timespec (0, 0);
#endif
#if defined HAVE_PGTK
nfds = pgtk_select (max_desc + 1,
&Available, (check_write ? &Writeok : 0),
NULL, &timeout, NULL);
#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);

View File

@ -60,7 +60,8 @@ enum output_method
output_x_window,
output_msdos_raw,
output_w32,
output_ns
output_ns,
output_pgtk
};
/* Input queue declarations and hooks. */
@ -445,6 +446,7 @@ struct terminal
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 */
} display_info;
@ -518,7 +520,7 @@ struct terminal
BGCOLOR. */
void (*query_frame_background_color) (struct frame *f, Emacs_Color *bgcolor);
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (HAVE_PGTK)
/* On frame F, translate pixel colors to RGB values for the NCOLORS
colors in COLORS. Use cached information, if available. */
@ -833,6 +835,9 @@ 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)
#endif
extern struct terminal *decode_live_terminal (Lisp_Object);

View File

@ -445,6 +445,8 @@ possible return values. */)
return Qpc;
case output_ns:
return Qns;
case output_pgtk:
return Qpgtk;
default:
emacs_abort ();
}

View File

@ -14330,8 +14330,10 @@ redisplay_tool_bar (struct frame *f)
f->tool_bar_redisplayed = true;
#ifdef HAVE_EXT_TOOL_BAR
#if 0
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
#endif
return false;
#else /* ! (HAVE_EXT_TOOL_BAR) */
@ -15485,7 +15487,7 @@ redisplay_internal (void)
if (!fr->glyphs_initialized_p)
return;
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
#if defined (USE_X_TOOLKIT) || (defined (USE_GTK) && !defined(HAVE_PGTK)) || defined (HAVE_NS)
if (popup_activated ())
{
return;
@ -28970,6 +28972,16 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
return x_reached;
}
static int draw_glyphs_debug(const char *file, int lineno,
struct window *w, int x, struct glyph_row *row,
enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
enum draw_glyphs_face hl, int overlaps)
{
return draw_glyphs(w, x, row, area, start, end, hl, overlaps);
}
#define draw_glyphs(w, x, r, a, s, e, h, o) \
draw_glyphs_debug(__FILE__, __LINE__, w, x, r, a, s, e, h, o)
/* Find the first glyph in the run of underlined glyphs preceding the
beginning of glyph string S, and return its font (which could be
NULL). This is needed because that font determines the underline
@ -32550,7 +32562,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
hlinfo->mouse_face_face_id
= face_at_buffer_position (w, mouse_charpos, &ignore,
mouse_charpos + 1,
!hlinfo->mouse_face_hidden, -1, 0);
!hlinfo->mouse_face_hidden, -1, 0);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
}
@ -33281,7 +33293,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
#if defined (USE_X_TOOLKIT) || (defined (USE_GTK) && !defined(HAVE_PGTK)) || defined (HAVE_NS) || defined (MSDOS)
if (popup_activated ())
return;
#endif

View File

@ -245,6 +245,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifdef HAVE_NS
#define GCGraphicsExposures 0
#endif /* HAVE_NS */
#ifdef HAVE_PGTK
#define GCGraphicsExposures 0
#endif /* HAVE_NS */
#endif /* HAVE_WINDOW_SYSTEM */
#include "buffer.h"
@ -571,6 +575,26 @@ x_free_gc (struct frame *f, Emacs_GC *gc)
}
#endif /* HAVE_NS */
#ifdef HAVE_PGTK
/* PGTK emulation of GCs */
static GC
x_create_gc (struct frame *f,
unsigned long mask,
XGCValues *xgcv)
{
GC gc = xmalloc (sizeof *gc);
*gc = *xgcv;
return gc;
}
static void
x_free_gc (struct frame *f, GC gc)
{
xfree (gc);
}
#endif /* HAVE_NS */
/***********************************************************************
Frames and faces
***********************************************************************/

View File

@ -26,7 +26,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <byteswap.h>
#include "lisp.h"
#ifndef HAVE_PGTK
#include "xterm.h"
#else
#include "gtkutil.h"
#endif
#include "xsettings.h"
#include "frame.h"
#include "keyboard.h"
@ -34,7 +38,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include "pdumper.h"
#ifndef HAVE_PGTK
#include <X11/Xproto.h>
#else
typedef unsigned short CARD16;
typedef unsigned int CARD32;
#endif
#ifdef HAVE_GSETTINGS
#include <glib-object.h>
@ -55,7 +64,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
static char *current_mono_font;
static char *current_font;
static struct x_display_info *first_dpyinfo;
static Display_Info *first_dpyinfo;
static Lisp_Object current_tool_bar_style;
/* Store a config changed event in to the event queue. */
@ -73,14 +82,18 @@ store_config_changed_event (Lisp_Object arg, Lisp_Object display_name)
/* Return true if DPYINFO is still valid. */
static bool
dpyinfo_valid (struct x_display_info *dpyinfo)
dpyinfo_valid (Display_Info *dpyinfo)
{
bool found = false;
if (dpyinfo != NULL)
{
struct x_display_info *d;
Display_Info *d;
for (d = x_display_list; !found && d; d = d->next)
#ifndef HAVE_PGTK
found = d == dpyinfo && d->display == dpyinfo->display;
#else
found = d == dpyinfo && d->gdpy == dpyinfo->gdpy;
#endif
}
return found;
}
@ -149,7 +162,7 @@ map_tool_bar_style (const char *tool_bar_style)
static void
store_tool_bar_style_changed (const char *newstyle,
struct x_display_info *dpyinfo)
Display_Info *dpyinfo)
{
Lisp_Object style = map_tool_bar_style (newstyle);
if (EQ (current_tool_bar_style, style))
@ -161,10 +174,12 @@ store_tool_bar_style_changed (const char *newstyle,
XCAR (dpyinfo->name_list_element));
}
#ifndef HAVE_PGTK
#if defined USE_CAIRO || defined HAVE_XFT
#define XSETTINGS_FONT_NAME "Gtk/FontName"
#endif
#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle"
#endif
enum {
SEEN_AA = 0x01,
@ -321,10 +336,11 @@ something_changed_gconfCB (GConfClient *client,
#endif /* USE_CAIRO || HAVE_XFT */
#ifndef HAVE_PGTK
/* Find the window that contains the XSETTINGS property values. */
static void
get_prop_window (struct x_display_info *dpyinfo)
get_prop_window (Display_Info *dpyinfo)
{
Display *dpy = dpyinfo->display;
@ -339,6 +355,9 @@ get_prop_window (struct x_display_info *dpyinfo)
XUngrabServer (dpy);
}
#endif
#ifndef HAVE_PGTK
#define PAD(nr) (((nr) + 3) & ~3)
@ -566,13 +585,15 @@ parse_settings (unsigned char *prop,
return settings_seen;
}
#endif
#ifndef HAVE_PGTK
/* Read settings from the XSettings property window on display for DPYINFO.
Store settings read in SETTINGS.
Return true iff successful. */
static bool
read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
read_settings (Display_Info *dpyinfo, struct xsettings *settings)
{
Atom act_type;
int act_form;
@ -600,12 +621,14 @@ read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
return got_settings;
}
#endif
#ifndef HAVE_PGTK
/* Apply Xft settings in SETTINGS to the Xft library.
Store a Lisp event that Xft settings changed. */
static void
apply_xft_settings (struct x_display_info *dpyinfo,
apply_xft_settings (Display_Info *dpyinfo,
struct xsettings *settings)
{
#ifdef HAVE_XFT
@ -731,12 +754,14 @@ apply_xft_settings (struct x_display_info *dpyinfo,
FcPatternDestroy (pat);
#endif /* HAVE_XFT */
}
#endif
#ifndef HAVE_PGTK
/* Read XSettings from the display for DPYINFO.
If SEND_EVENT_P store a Lisp event settings that changed. */
static void
read_and_apply_settings (struct x_display_info *dpyinfo, bool send_event_p)
read_and_apply_settings (Display_Info *dpyinfo, bool send_event_p)
{
struct xsettings settings;
@ -763,11 +788,13 @@ read_and_apply_settings (struct x_display_info *dpyinfo, bool send_event_p)
}
#endif
}
#endif
#ifndef HAVE_PGTK
/* Check if EVENT for the display in DPYINFO is XSettings related. */
void
xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
xft_settings_event (Display_Info *dpyinfo, const XEvent *event)
{
bool check_window_p = false, apply_settings_p = false;
@ -805,6 +832,7 @@ xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
if (apply_settings_p)
read_and_apply_settings (dpyinfo, true);
}
#endif
/* Initialize GSettings and read startup values. */
@ -940,10 +968,11 @@ init_gconf (void)
#endif /* HAVE_GCONF */
}
#ifndef HAVE_PGTK
/* Init Xsettings and read startup values. */
static void
init_xsettings (struct x_display_info *dpyinfo)
init_xsettings (Display_Info *dpyinfo)
{
Display *dpy = dpyinfo->display;
@ -959,13 +988,16 @@ init_xsettings (struct x_display_info *dpyinfo)
unblock_input ();
}
#endif
void
xsettings_initialize (struct x_display_info *dpyinfo)
xsettings_initialize (Display_Info *dpyinfo)
{
if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
init_gconf ();
#ifndef HAVE_PGTK
init_xsettings (dpyinfo);
#endif
init_gsettings ();
}

View File

@ -20,12 +20,23 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifndef XSETTINGS_H
#define XSETTINGS_H
#ifndef HAVE_PGTK
#include <X11/Xlib.h>
#endif
struct x_display_info;
struct pgtk_display_info;
extern void xsettings_initialize (struct x_display_info *);
extern void xft_settings_event (struct x_display_info *, const XEvent *);
#ifndef HAVE_PGTK
typedef struct x_display_info Display_Info;
#else
typedef struct pgtk_display_info Display_Info;
#endif
extern void xsettings_initialize (Display_Info *);
#ifndef HAVE_PGTK
extern void xft_settings_event (Display_Info *, const XEvent *);
#endif
extern const char *xsettings_get_system_font (void);
#ifdef USE_LUCID
extern const char *xsettings_get_system_normal_font (void);