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:
parent
2c7687738d
commit
f6d8c5939b
91
configure.ac
91
configure.ac
@ -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
|
||||
|
@ -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.")
|
||||
|
@ -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"))
|
||||
|
@ -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))))
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.")
|
||||
|
@ -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."
|
||||
|
@ -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
429
lisp/term/pgtk-win.el
Normal 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
|
@ -46,6 +46,7 @@
|
||||
(pcase (or window-system 'tty)
|
||||
('x "X11")
|
||||
('ns "OpenStep")
|
||||
('pgtk "PureGTK")
|
||||
('tty "TTY")
|
||||
(_ nil)))))
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
15
src/emacs.c
15
src/emacs.c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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");
|
||||
|
11
src/frame.h
11
src/frame.h
@ -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. */
|
||||
|
||||
|
23
src/fringe.c
23
src/fringe.c
@ -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;
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -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
|
||||
|
327
src/gtkutil.c
327
src/gtkutil.c
@ -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)
|
||||
|
@ -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);
|
||||
|
53
src/image.c
53
src/image.c
@ -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
|
||||
|
@ -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
2778
src/pgtkfns.c
Normal file
File diff suppressed because it is too large
Load Diff
136
src/pgtkgui.h
Normal file
136
src/pgtkgui.h
Normal 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
466
src/pgtkselect.c
Normal 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
31
src/pgtkselect.h
Normal 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
6395
src/pgtkterm.c
Normal file
File diff suppressed because it is too large
Load Diff
569
src/pgtkterm.h
Normal file
569
src/pgtkterm.h
Normal 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 */
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -445,6 +445,8 @@ possible return values. */)
|
||||
return Qpc;
|
||||
case output_ns:
|
||||
return Qns;
|
||||
case output_pgtk:
|
||||
return Qpgtk;
|
||||
default:
|
||||
emacs_abort ();
|
||||
}
|
||||
|
18
src/xdisp.c
18
src/xdisp.c
@ -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
|
||||
|
24
src/xfaces.c
24
src/xfaces.c
@ -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
|
||||
***********************************************************************/
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user