emacs/lisp/term/pgtk-win.el

408 lines
14 KiB
EmacsLisp
Raw Normal View History

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):
2017-10-28 16:16:29 +09:00
;;;
;;; 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.
(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-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))
(defvar pgtk-preedit-overlay nil)
(defun pgtk-preedit-text (e)
(interactive "e")
(when pgtk-preedit-overlay
(delete-overlay pgtk-preedit-overlay))
(setq pgtk-preedit-overlay nil)
(let ((ovstr "")
(idx 0)
atts ov str color face-name)
(dolist (part (nth 1 e))
(setq str (car part))
(setq face-name (intern (format "pgtk-im-%d" idx)))
(eval
`(defface ,face-name nil "face of input method preedit"))
(setq atts nil)
(when (setq color (cdr-safe (assq 'fg (cdr part))))
(setq atts (append atts `(:foreground ,color))))
(when (setq color (cdr-safe (assq 'bg (cdr part))))
(setq atts (append atts `(:background ,color))))
(when (setq color (cdr-safe (assq 'ul (cdr part))))
(setq atts (append atts `(:underline ,color))))
(face-spec-set face-name `((t . ,atts)))
(add-text-properties 0 (length str) `(face ,face-name) str)
(setq ovstr (concat ovstr str))
(setq idx (1+ idx)))
(setq ov (make-overlay (point) (point)))
(overlay-put ov 'before-string ovstr)
(setq pgtk-preedit-overlay ov)))
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):
2017-10-28 16:16:29 +09:00
(provide 'pgtk-win)
(provide 'term/pgtk-win)
;;; pgtk-win.el ends here