Merge branch 'master' into comment-cache
[emacs.git] / lisp / term / pc-win.el
blobb6f2acc29782687b36770abd7e9d39b9d84c0702
1 ;;; pc-win.el --- setup support for `PC windows' (whatever that is) -*- lexical-binding:t -*-
3 ;; Copyright (C) 1994, 1996-1997, 1999, 2001-2017 Free Software
4 ;; Foundation, Inc.
6 ;; Author: Morten Welinder <terra@diku.dk>
7 ;; Maintainer: emacs-devel@gnu.org
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24 ;;; Commentary:
26 ;; This file is preloaded into Emacs by loadup.el. The functions in
27 ;; this file are then called during startup from startup.el. This
28 ;; means that just loading this file should not have any side effects
29 ;; besides defining functions and variables, and in particular should
30 ;; NOT initialize any window systems.
32 ;; The main entry points to this file's features are msdos-handle-args,
33 ;; msdos-create-frame-with-faces, msdos-initialize-window-system,
34 ;; terminal-init-internal. The last one is not supposed to be called,
35 ;; so it just errors out.
37 ;;; Code:
39 (if (not (fboundp 'msdos-remember-default-colors))
40 (error "%s: Loading pc-win.el but not compiled for MS-DOS"
41 (invocation-name)))
43 (declare-function msdos-remember-default-colors "msdos.c")
44 (declare-function w16-set-clipboard-data "w16select.c")
45 (declare-function w16-get-clipboard-data "w16select.c")
46 (declare-function msdos-setup-keyboard "internal" (frame))
48 ;; This was copied from etc/rgb.txt, except that some values were changed
49 ;; a bit to make them consistent with DOS console colors, and the RGB
50 ;; values were scaled up to 16 bits, as `tty-define-color' requires.
51 ;;;
52 ;; The mapping between the 16 standard EGA/VGA colors and X color names
53 ;; was done by running a Unix version of Emacs inside an X client and a
54 ;; DJGPP-compiled Emacs on the same PC. The names of X colors used to
55 ;; define the pixel values are shown as comments to each color below.
56 ;;;
57 ;; If you want to change the RGB values, keep in mind that various pieces
58 ;; of Emacs think that a color whose RGB values add up to less than 0.6 of
59 ;; the values for WHITE (i.e. less than 117963) are ``dark'', otherwise the
60 ;; color is ``light''; see `frame-set-background-mode' in lisp/faces.el for
61 ;; an example.
62 (defvar msdos-color-values
63 '(("black" 0 0 0 0)
64 ("blue" 1 0 0 52480) ; MediumBlue
65 ("green" 2 8704 35584 8704) ; ForestGreen
66 ("cyan" 3 0 52736 53504) ; DarkTurquoise
67 ("red" 4 45568 8704 8704) ; FireBrick
68 ("magenta" 5 35584 0 35584) ; DarkMagenta
69 ("brown" 6 40960 20992 11520) ; Sienna
70 ("lightgray" 7 48640 48640 48640) ; Gray
71 ("darkgray" 8 26112 26112 26112) ; Gray40
72 ("lightblue" 9 0 0 65535) ; Blue
73 ("lightgreen" 10 0 65535 0) ; Green
74 ("lightcyan" 11 0 65535 65535) ; Cyan
75 ("lightred" 12 65535 0 0) ; Red
76 ("lightmagenta" 13 65535 0 65535) ; Magenta
77 ("yellow" 14 65535 65535 0) ; Yellow
78 ("white" 15 65535 65535 65535))
79 "A list of MS-DOS console colors, their indices and 16-bit RGB values.")
81 ;; ---------------------------------------------------------------------------
82 ;; We want to delay setting frame parameters until the faces are setup
83 (defvar default-frame-alist nil)
84 ;(modify-frame-parameters terminal-frame default-frame-alist)
86 (defun msdos-face-setup ()
87 "Initial setup of faces for the MS-DOS display."
88 (set-face-foreground 'bold "yellow")
89 (set-face-foreground 'italic "red")
90 (set-face-foreground 'bold-italic "lightred")
91 (set-face-foreground 'underline "white")
93 (make-face 'msdos-menu-active-face)
94 (make-face 'msdos-menu-passive-face)
95 (make-face 'msdos-menu-select-face)
96 (set-face-foreground 'msdos-menu-active-face "white")
97 (set-face-foreground 'msdos-menu-passive-face "lightgray")
98 (set-face-background 'msdos-menu-active-face "blue")
99 (set-face-background 'msdos-menu-passive-face "blue")
100 (set-face-background 'msdos-menu-select-face "red"))
102 (defun msdos-handle-reverse-video (frame parameters)
103 "Handle the reverse-video frame parameter on MS-DOS frames."
104 (when (cdr (or (assq 'reverse parameters)
105 (assq 'reverse default-frame-alist)))
106 (let* ((params (frame-parameters frame))
107 (fg (cdr (assq 'foreground-color params)))
108 (bg (cdr (assq 'background-color params))))
109 (if (equal fg (cdr (assq 'mouse-color params)))
110 (modify-frame-parameters frame
111 (list (cons 'mouse-color bg))))
112 (if (equal fg (cdr (assq 'cursor-color params)))
113 (modify-frame-parameters frame
114 (list (cons 'cursor-color bg)))))))
116 ;; This must run after all the default colors are inserted into
117 ;; tty-color-alist, since msdos-handle-reverse-video needs to know the
118 ;; actual frame colors.
119 (defun msdos-setup-initial-frame ()
120 (modify-frame-parameters terminal-frame default-frame-alist)
121 ;; This remembers the screen colors after applying default-frame-alist,
122 ;; so that all subsequent frames could begin with those colors.
123 (msdos-remember-default-colors terminal-frame)
124 (modify-frame-parameters terminal-frame initial-frame-alist)
125 (msdos-handle-reverse-video terminal-frame
126 (frame-parameters terminal-frame))
128 (frame-set-background-mode terminal-frame)
129 (face-set-after-frame-default terminal-frame))
131 ;; We create frames as if we were a terminal, but without invoking the
132 ;; terminal-initialization function. Also, our handling of reverse
133 ;; video is slightly different.
134 (defun msdos-create-frame-with-faces (&optional parameters)
135 "Create a frame on MS-DOS display.
136 Optional frame parameters PARAMETERS specify the frame parameters.
137 Parameters not specified by PARAMETERS are taken from
138 `default-frame-alist'. If either PARAMETERS or `default-frame-alist'
139 contains a `reverse' parameter, handle that. Value is the new frame
140 created."
141 (let ((frame (make-terminal-frame parameters))
142 success)
143 (unwind-protect
144 (with-selected-frame frame
145 (msdos-handle-reverse-video frame (frame-parameters frame))
146 (unless (terminal-parameter frame 'terminal-initted)
147 (set-terminal-parameter frame 'terminal-initted t))
148 (frame-set-background-mode frame)
149 (face-set-after-frame-default frame)
150 (setq success t))
151 (unless success (delete-frame frame)))
152 frame))
154 ;; ---------------------------------------------------------------------------
155 ;; More or less useful imitations of certain X-functions. A lot of the
156 ;; values returned are questionable, but usually only the form of the
157 ;; returned value matters. Also, by the way, recall that `ignore' is
158 ;; a useful function for returning 'nil regardless of argument.
160 ;; Note: Any re-definition in this file of a function that is defined
161 ;; in C on other platforms, should either have no doc-string, or one
162 ;; that is identical to the C version, but with the arglist signature
163 ;; at the end. Otherwise help-split-fundoc gets confused on other
164 ;; platforms. (Bug#10783)
166 ;; From src/xfns.c
167 (defun x-list-fonts (_pattern &optional _face _frame _maximum width)
168 "Return a list of the names of available fonts matching PATTERN.
169 If optional arguments FACE and FRAME are specified, return only fonts
170 the same size as FACE on FRAME.
172 PATTERN should be a string containing a font name in the XLFD,
173 Fontconfig, or GTK format. A font name given in the XLFD format may
174 contain wildcard characters:
175 the * character matches any substring, and
176 the ? character matches any single character.
177 PATTERN is case-insensitive.
179 The return value is a list of strings, suitable as arguments to
180 `set-face-font'.
182 Fonts Emacs can't use may or may not be excluded
183 even if they match PATTERN and FACE.
184 The optional fourth argument MAXIMUM sets a limit on how many
185 fonts to match. The first MAXIMUM fonts are reported.
186 The optional fifth argument WIDTH, if specified, is a number of columns
187 occupied by a character of a font. In that case, return only fonts
188 the WIDTH times as wide as FACE on FRAME."
189 (if (or (null width) (and (numberp width) (= width 1)))
190 (list "ms-dos")
191 (list "no-such-font")))
192 (defun x-display-pixel-width (&optional frame) (frame-width frame))
193 (defun x-display-pixel-height (&optional frame) (frame-height frame))
194 (defun x-display-planes (&optional _frame) 4) ;bg switched to 16 colors as well
195 (defun x-display-color-cells (&optional _frame) 16)
196 (defun x-server-max-request-size (&optional _frame) 1000000) ; ???
197 (defun x-server-vendor (&optional _frame) t "GNU")
198 (defun x-server-version (&optional _frame) '(1 0 0))
199 (defun x-display-screens (&optional _frame) 1)
200 (defun x-display-mm-height (&optional _frame) 245) ; Guess the size of my
201 (defun x-display-mm-width (&optional _frame) 322) ; monitor, EZ...
202 (defun x-display-backing-store (&optional _frame) 'not-useful)
203 (defun x-display-visual-class (&optional _frame) 'static-color)
204 (fset 'x-display-save-under 'ignore)
205 (fset 'x-get-resource 'ignore)
207 ;; From lisp/term/x-win.el
208 (defvar x-display-name "pc"
209 "The name of the window display on which Emacs was started.
210 On X, the display name of individual X frames is recorded in the
211 `display' frame parameter.")
212 (defvar x-colors (mapcar 'car msdos-color-values)
213 "List of basic colors available on color displays.
214 For X, the list comes from the `rgb.txt' file,v 10.41 94/02/20.
215 For Nextstep, this is a list of non-PANTONE colors returned by
216 the operating system.")
218 ;; From lisp/term/w32-win.el
220 ;;;; Selections
222 ;; gui-get-selection is used in select.el
223 (cl-defmethod gui-backend-get-selection (_selection-symbol _target-type
224 &context (window-system pc))
225 "Return the value of the current selection.
226 Consult the selection. Treat empty strings as if they were unset."
227 ;; Don't die if x-get-selection signals an error.
228 (with-demoted-errors "w16-get-clipboard-data:%s"
229 (w16-get-clipboard-data)))
231 (declare-function w16-selection-exists-p "w16select.c")
232 ;; gui-selection-owner-p is used in simple.el.
233 (cl-defmethod gui-backend-selection-exists-p (selection
234 &context (window-system pc))
235 (w16-selection-exists-p selection))
237 (cl-defmethod gui-backend-selection-owner-p (selection
238 &context (window-system pc))
239 (w16-selection-owner-p selection))
241 (defun w16-selection-owner-p (_selection)
242 ;; FIXME: Other systems don't obey select-enable-clipboard here.
243 (if select-enable-clipboard
244 (let ((text
245 ;; Don't die if w16-get-clipboard-data signals an error.
246 (with-demoted-errors "w16-get-clipboard-data: %S"
247 (w16-get-clipboard-data))))
248 ;; We consider ourselves the owner of the selection
249 ;; if it does not exist, or exists and compares
250 ;; equal with the last text we've put into the
251 ;; Windows clipboard.
252 (cond
253 ((not text) t)
254 ((equal text gui--last-selected-text-clipboard) text)
255 (t nil)))))
257 ;; gui-set-selection is used in gui-set-selection.
258 (declare-function w16-set-clipboard-data "w16select.c"
259 (string &optional ignored))
260 (cl-defmethod gui-backend-set-selection (selection value
261 &context (window-system pc))
262 (if (not value)
263 (if (w16-selection-owner-p selection)
265 ;; FIXME: Other systems don't obey
266 ;; select-enable-clipboard here.
267 (with-demoted-errors "w16-set-clipboard-data: %S"
268 (w16-set-clipboard-data value))
269 value))
271 ;; From src/fontset.c:
272 (fset 'query-fontset 'ignore)
274 ;; From lisp/term/x-win.el: make iconify-or-deiconify-frame a no-op.
275 (fset 'iconify-or-deiconify-frame 'ignore)
277 ;; From lisp/frame.el
278 (fset 'set-default-font 'ignore)
279 (fset 'set-mouse-color 'ignore) ; We cannot, I think.
280 (fset 'set-cursor-color 'ignore) ; Hardware determined by char under.
281 (fset 'set-border-color 'ignore) ; Not useful.
283 (defvar msdos-last-help-message nil
284 "The last help message received via `show-help-function'.
285 This is used by `msdos-show-help'.")
287 (defvar msdos-previous-message nil
288 "The content of the echo area before help echo was displayed.")
290 (defun msdos-show-help (help)
291 "Function installed as `show-help-function' on MS-DOS frames."
292 (when (and (not (window-minibuffer-p)) ;Don't overwrite minibuffer contents.
293 (not cursor-in-echo-area)) ;Don't overwrite a prompt.
294 (cond
295 ((stringp help)
296 (setq help (replace-regexp-in-string "\n" ", " help))
297 (unless (or msdos-previous-message
298 (string-equal help (current-message))
299 (and (stringp msdos-last-help-message)
300 (string-equal msdos-last-help-message
301 (current-message))))
302 (setq msdos-previous-message (current-message)))
303 (setq msdos-last-help-message help)
304 (let ((message-truncate-lines nil)
305 (message-log-max nil))
306 (message "%s" help)))
307 ((stringp msdos-previous-message)
308 (let ((message-log-max nil))
309 (message "%s" msdos-previous-message)
310 (setq msdos-previous-message nil)))
312 (message nil)))))
315 ;; Initialization.
316 ;; ---------------------------------------------------------------------------
317 ;; This function is run, by the tty method of `frame-creation-function'
318 ;; (in faces.el), only for the initial frame (on each terminal, but we have
319 ;; only one).
320 ;; This works by setting the `terminal-initted' terminal parameter to
321 ;; this function, the first time `frame-creation-function' is
322 ;; called on that terminal. `frame-creation-function' is called
323 ;; directly from startup.el and also by `make-frame'.
324 ;; `make-frame' should call our own `frame-creation-function' method instead
325 ;; (see below) so if terminal-init-internal is called it means something is
326 ;; _very_ wrong, because "internal" terminal emulator should not be
327 ;; turned on if our window-system is not `pc'. Therefore, the only
328 ;; Right Thing for us to do here is scream bloody murder.
329 (defun terminal-init-internal ()
330 "Terminal initialization function for the MS-DOS \"internal\" terminal.
331 Errors out because it is not supposed to be called, ever."
332 (error "terminal-init-internal called for window-system `%s'"
333 (window-system)))
335 ;; window-system-initialization is called by startup.el:command-line.
336 (cl-defmethod window-system-initialization (&context (window-system pc)
337 &optional _display)
338 "Initialization function for the `pc' \"window system\"."
339 (or (eq (window-system) 'pc)
340 (error
341 "`msdos-initialize-window-system' called, but window-system is `%s'"
342 (window-system)))
343 ;; First, the keyboard.
344 (msdos-setup-keyboard terminal-frame) ; see internal.el
345 ;; Next, register the default colors.
346 (let* ((colors msdos-color-values)
347 (color (car colors)))
348 (tty-color-clear)
349 (while colors
350 (tty-color-define (car color) (cadr color) (cddr color))
351 (setq colors (cdr colors) color (car colors))))
352 ;; Modifying color mappings means realized faces don't
353 ;; use the right colors, so clear them.
354 (clear-face-cache)
355 ;; Now set up some additional faces.
356 (msdos-face-setup)
357 ;; Set up the initial frame.
358 (msdos-setup-initial-frame)
359 ;; Help echo is displayed in the echo area.
360 (setq show-help-function 'msdos-show-help)
361 ;; We want to delay the codepage-related setup until after user's
362 ;; .emacs is processed, because people might define their
363 ;; `dos-codepage-setup-hook' there.
364 (add-hook 'after-init-hook 'dos-codepage-setup)
365 ;; In multibyte mode, we want unibyte buffers to be displayed
366 ;; using the terminal coding system, so that they display
367 ;; correctly on the DOS terminal; in unibyte mode we want to see
368 ;; all 8-bit characters verbatim. In both cases, we want the
369 ;; entire range of 8-bit characters to arrive at our display code
370 ;; verbatim.
371 (standard-display-8bit 127 255)
372 ;; We are fast enough to make this optimization unnecessary.
373 (setq split-window-keep-point t)
374 ;; Arrange for the kill and yank functions to set and check the
375 ;; clipboard.
376 (menu-bar-enable-clipboard)
377 (run-hooks 'terminal-init-msdos-hook))
379 ;; frame-creation-function is called by frame.el:make-frame.
380 (cl-defmethod frame-creation-function (params &context (window-system pc))
381 (msdos-create-frame-with-faces params))
383 ;; We don't need anything beyond tty-handle-args for handling
384 ;; command-line argument; see startup.el.
385 (cl-defmethod handle-args-function (args &context (window-system pc))
386 (tty-handle-args args))
388 ;; ---------------------------------------------------------------------------
390 (provide 'pc-win)
391 (provide 'term/pc-win)
393 ;;; pc-win.el ends here