diff options
author | John Wiegley <johnw@newartisans.com> | 2016-01-11 22:48:07 -0800 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2016-01-11 22:48:07 -0800 |
commit | 8d7128c46de2af10d50c1495a075d66b702f6d21 (patch) | |
tree | 248825b1d310edff622e05241c9ee8f5d60d9c14 | |
parent | 8df9e56b4ad9704747dd8af7a049da9ee6ab3a00 (diff) | |
parent | 9ee6ecb840c57aaf87316bccc2a892265087bafe (diff) | |
download | emacs-8d7128c46de2af10d50c1495a075d66b702f6d21.tar.gz emacs-8d7128c46de2af10d50c1495a075d66b702f6d21.tar.bz2 emacs-8d7128c46de2af10d50c1495a075d66b702f6d21.zip |
Merge from origin/emacs-25
9ee6ecb lisp/emacs-lisp/chart.el (chart-new-buffer): Move to silence byte compiler.
526d80c Port chart.el methods to cl-generic.
410bb69 Add nt/INSTALL.W64 build instructions
8f5b524 Add new input method 'programmer-dvorak'
6d11f6e Allow to invoke original M-TAB binding in 'flyspell-prog-mode'
bb83bb1 Fix EWW rendering of long RTL lines
b1a8509 fix bug#21054
ce5ad12 Clean up cairo printing code
-rw-r--r-- | etc/NEWS | 2 | ||||
-rw-r--r-- | lisp/emacs-lisp/chart.el | 47 | ||||
-rw-r--r-- | lisp/leim/quail/programmer-dvorak.el | 145 | ||||
-rw-r--r-- | lisp/net/shr.el | 5 | ||||
-rw-r--r-- | lisp/textmodes/flyspell.el | 210 | ||||
-rw-r--r-- | nt/INSTALL | 3 | ||||
-rw-r--r-- | nt/INSTALL.W64 | 224 | ||||
-rw-r--r-- | src/gtkutil.c | 41 | ||||
-rw-r--r-- | src/xfns.c | 46 | ||||
-rw-r--r-- | src/xterm.c | 16 |
10 files changed, 560 insertions, 179 deletions
@@ -270,7 +270,7 @@ hiding character but the default `.' can be used by let-binding the variable `read-hide-char'. --- -** New input method: `tamil-dvorak'. +** New input methods: `tamil-dvorak' and `programmer-dvorak'. * Editing Changes in Emacs 25.1 diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index c0a42038e94..aa7d8dd9880 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -60,6 +60,7 @@ ;; with all the bitmaps you want to use. (require 'eieio) +(eval-when-compile (require 'cl-generic)) ;;; Code: (define-obsolete-variable-alias 'chart-map 'chart-mode-map "24.1") @@ -124,14 +125,6 @@ too much in text characters anyways.") (font-lock-mode -1) ;Isn't it off already? --Stef ) -(defun chart-new-buffer (obj) - "Create a new buffer NAME in which the chart OBJ is displayed. -Returns the newly created buffer." - (with-current-buffer (get-buffer-create (format "*%s*" (oref obj title))) - (chart-mode) - (setq chart-local-object obj) - (current-buffer))) - (defclass chart () ((title :initarg :title :initform "Emacs Chart") @@ -156,7 +149,15 @@ Returns the newly created buffer." ) "Superclass for all charts to be displayed in an Emacs buffer.") -(defmethod initialize-instance :AFTER ((obj chart) &rest _fields) +(defun chart-new-buffer (obj) + "Create a new buffer NAME in which the chart OBJ is displayed. +Returns the newly created buffer." + (with-current-buffer (get-buffer-create (format "*%s*" (oref obj title))) + (chart-mode) + (setq chart-local-object obj) + (current-buffer))) + +(cl-defmethod initialize-instance :after ((obj chart) &rest _fields) "Initialize the chart OBJ being created with FIELDS. Make sure the width/height is correct." (oset obj x-width (- (window-width) 10)) @@ -201,7 +202,7 @@ Make sure the width/height is correct." :initform vertical)) "Subclass for bar charts (vertical or horizontal).") -(defmethod chart-draw ((c chart) &optional buff) +(cl-defmethod chart-draw ((c chart) &optional buff) "Start drawing a chart object C in optional BUFF. Erases current contents of buffer." (save-excursion @@ -221,19 +222,19 @@ Erases current contents of buffer." (message "Rendering chart...done") )) -(defmethod chart-draw-title ((c chart)) +(cl-defmethod chart-draw-title ((c chart)) "Draw a title upon the chart. Argument C is the chart object." (chart-display-label (oref c title) 'horizontal 0 0 (window-width) (oref c title-face))) -(defmethod chart-size-in-dir ((c chart) dir) +(cl-defmethod chart-size-in-dir ((c chart) dir) "Return the physical size of chart C in direction DIR." (if (eq dir 'vertical) (oref c y-width) (oref c x-width))) -(defmethod chart-draw-axis ((c chart)) +(cl-defmethod chart-draw-axis ((c chart)) "Draw axis into the current buffer defined by chart C." (let ((ymarg (oref c y-margin)) (xmarg (oref c x-margin)) @@ -247,7 +248,7 @@ Argument C is the chart object." ymarg (+ ymarg xlen))) ) -(defmethod chart-axis-draw ((a chart-axis) &optional dir margin zone start end) +(cl-defmethod chart-axis-draw ((a chart-axis) &optional dir margin zone start end) "Draw some axis for A in direction DIR with MARGIN in boundary. ZONE is a zone specification. START and END represent the boundary." @@ -257,7 +258,7 @@ START and END represent the boundary." 1 0)) start end (oref a name-face))) -(defmethod chart-translate-xpos ((c chart) x) +(cl-defmethod chart-translate-xpos ((c chart) x) "Translate in chart C the coordinate X into a screen column." (let ((range (oref (oref c x-axis) bounds))) (+ (oref c x-margin) @@ -266,7 +267,7 @@ START and END represent the boundary." (float (- (cdr range) (car range)))))))) ) -(defmethod chart-translate-ypos ((c chart) y) +(cl-defmethod chart-translate-ypos ((c chart) y) "Translate in chart C the coordinate Y into a screen row." (let ((range (oref (oref c y-axis) bounds))) (+ (oref c x-margin) @@ -276,7 +277,7 @@ START and END represent the boundary." (float (- (cdr range) (car range))))))))) ) -(defmethod chart-axis-draw ((a chart-axis-range) &optional dir margin zone _start _end) +(cl-defmethod chart-axis-draw ((a chart-axis-range) &optional dir margin zone _start _end) "Draw axis information based upon a range to be spread along the edge. A is the chart to draw. DIR is the direction. MARGIN, ZONE, START, and END specify restrictions in chart space." @@ -313,7 +314,7 @@ MARGIN, ZONE, START, and END specify restrictions in chart space." (setq i (+ i j)))) ) -(defmethod chart-translate-namezone ((c chart) n) +(cl-defmethod chart-translate-namezone ((c chart) n) "Return a dot-pair representing a positional range for a name. The name in chart C of the Nth name resides. Automatically compensates for direction." @@ -329,7 +330,7 @@ Automatically compensates for direction." (+ m -1 (round (* lpn (+ 1.0 (float n)))))) )) -(defmethod chart-axis-draw ((a chart-axis-names) &optional dir margin zone _start _end) +(cl-defmethod chart-axis-draw ((a chart-axis-names) &optional dir margin zone _start _end) "Draw axis information based upon A range to be spread along the edge. Optional argument DIR is the direction of the chart. Optional arguments MARGIN, ZONE, START and END specify boundaries of the drawing." @@ -368,7 +369,7 @@ Optional arguments MARGIN, ZONE, START and END specify boundaries of the drawing s (cdr s)))) ) -(defmethod chart-draw-data ((c chart-bar)) +(cl-defmethod chart-draw-data ((c chart-bar)) "Display the data available in a bar chart C." (let* ((data (oref c sequences)) (dir (oref c direction)) @@ -413,7 +414,7 @@ Optional arguments MARGIN, ZONE, START and END specify boundaries of the drawing (setq data (cdr data)))) ) -(defmethod chart-add-sequence ((c chart) &optional seq axis-label) +(cl-defmethod chart-add-sequence ((c chart) &optional seq axis-label) "Add to chart object C the sequence object SEQ. If AXIS-LABEL, then the axis stored in C is updated with the bounds of SEQ, or is created with the bounds of SEQ." @@ -445,7 +446,7 @@ or is created with the bounds of SEQ." ;;; Charting optimizers -(defmethod chart-trim ((c chart) max) +(cl-defmethod chart-trim ((c chart) max) "Trim all sequences in chart C to be at most MAX elements long." (let ((s (oref c sequences))) (while s @@ -455,7 +456,7 @@ or is created with the bounds of SEQ." (setq s (cdr s)))) ) -(defmethod chart-sort ((c chart) pred) +(cl-defmethod chart-sort ((c chart) pred) "Sort the data in chart C using predicate PRED. See `chart-sort-matchlist' for more details." (let* ((sl (oref c sequences)) diff --git a/lisp/leim/quail/programmer-dvorak.el b/lisp/leim/quail/programmer-dvorak.el new file mode 100644 index 00000000000..a74fb5bc6b6 --- /dev/null +++ b/lisp/leim/quail/programmer-dvorak.el @@ -0,0 +1,145 @@ +;;; programmer-dvorak.el --- Quail package for the programmer Dvorak layout + +;; Copyright (C) 2015 Free Software Foundation, Inc. + +;; Author: Joakim Jalap <joakim.jalap@fastmail.com> + +;; Keywords: input method, Dvorak + +;; This file is released under the terms 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 <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; This file provides an input method for the programmers Dvorak keyboard +;;; layout by Roland Kaufman (<http://www.kaufmann.no/roland/dvorak/>). + +;;; Code: + +(require 'quail) + +(quail-define-package + "programmer-dvorak" "English" "DVP@" t + "An English (ASCII) dvorak layout optimized for programming, with for example + brackets and parens more easily reachable." + nil t t t t nil nil nil nil nil t) + +;; &% [7 {5 }3 (1 =9 *0 )2 +4 ]6 !8 #` $~ +;; ;: ,< .> pP yY fF gG cC rR lL /? @^ +;; aA oO eE uU iI dD hH tT nN sS -_ \| +;; '" qQ jJ kK xX bB mM wW vV zZ +;; + +(quail-define-rules + ("-" ?!) + ("=" ?#) + ("`" ?$) + ("q" ?\;) + ("w" ?,) + ("e" ?.) + ("r" ?p) + ("t" ?y) + ("y" ?f) + ("u" ?g) + ("i" ?c) + ("o" ?r) + ("p" ?l) + ("[" ?/) + ("]" ?@) + ("a" ?a) + ("s" ?o) + ("d" ?e) + ("f" ?u) + ("g" ?i) + ("h" ?d) + ("j" ?h) + ("k" ?t) + ("l" ?n) + (";" ?s) + ("'" ?-) + ("\\" ?\\) + ("z" ?\') + ("x" ?q) + ("c" ?j) + ("v" ?k) + ("b" ?x) + ("n" ?b) + ("m" ?m) + ("," ?w) + ("." ?v) + ("/" ?z) + + ("_" ?8) + ("+" ?`) + ("~" ?~) + ("Q" ?:) + ("W" ?<) + ("E" ?>) + ("R" ?P) + ("T" ?Y) + ("Y" ?F) + ("U" ?G) + ("I" ?C) + ("O" ?R) + ("P" ?L) + ("{" ??) + ("}" ?^) + ("A" ?A) + ("S" ?O) + ("D" ?E) + ("F" ?U) + ("G" ?I) + ("H" ?D) + ("J" ?H) + ("K" ?T) + ("L" ?N) + (":" ?S) + ("\"" ?_) + ("|" ?|) + ("Z" ?\") + ("X" ?Q) + ("C" ?J) + ("V" ?K) + ("B" ?X) + ("N" ?B) + ("M" ?M) + ("<" ?W) + (">" ?V) + ("?" ?Z) + + ("1" ?&) + ("2" ?\[) + ("3" ?{) + ("4" ?}) + ("5" ?\() + ("6" ?=) + ("7" ?\*) + ("8" ?\)) + ("9" ?+) + ("0" ?\]) + + ("!" ?%) + ("@" ?7) + ("#" ?5) + ("$" ?3) + ("%" ?1) + ("^" ?9) + ("&" ?0) + ("*" ?2) + ("(" ?4) + (")" ?6) + ) + +;;; programmer-dvorak.el ends here diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 0effa93b197..7ee382f2f22 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -259,6 +259,11 @@ DOM should be a parse tree as generated by (* (frame-char-width) 2) 0))))) bidi-display-reordering) + ;; If the window was hscrolled for some reason, shr-fill-lines + ;; below will misbehave, because it silently assumes that it + ;; starts with a non-hscrolled window (vertical-motion will move + ;; to a wrong place otherwise). + (set-window-hscroll nil 0) (shr-descend dom) (shr-fill-lines start (point)) (shr-remove-trailing-whitespace start (point)) diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index 6c4a731629c..8d13aa1dd5b 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -399,6 +399,9 @@ like <img alt=\"Some thing.\">." (interactive) (setq flyspell-generic-check-word-predicate #'flyspell-generic-progmode-verify) + (setq-local flyspell--prev-meta-tab-binding + (or (local-key-binding "\M-\t" t) + (global-key-binding "\M-\t" t))) (flyspell-mode 1) (run-hooks 'flyspell-prog-mode-hook)) @@ -1904,105 +1907,114 @@ before point that's highlighted as misspelled." "Correct the current word. This command proposes various successive corrections for the current word." (interactive) - (let ((pos (point)) - (old-max (point-max))) - ;; Use the correct dictionary. - (flyspell-accept-buffer-local-defs) - (if (and (eq flyspell-auto-correct-pos pos) - (consp flyspell-auto-correct-region)) - ;; We have already been using the function at the same location. - (let* ((start (car flyspell-auto-correct-region)) - (len (cdr flyspell-auto-correct-region))) - (flyspell-unhighlight-at start) - (delete-region start (+ start len)) - (setq flyspell-auto-correct-ring (cdr flyspell-auto-correct-ring)) - (let* ((word (car flyspell-auto-correct-ring)) - (len (length word))) - (rplacd flyspell-auto-correct-region len) - (goto-char start) - (if flyspell-abbrev-p - (if (flyspell-already-abbrevp (flyspell-abbrev-table) - flyspell-auto-correct-word) - (flyspell-change-abbrev (flyspell-abbrev-table) - flyspell-auto-correct-word - word) - (flyspell-define-abbrev flyspell-auto-correct-word word))) - (funcall flyspell-insert-function word) - (flyspell-word) - (flyspell-display-next-corrections flyspell-auto-correct-ring)) - (flyspell-ajust-cursor-point pos (point) old-max) - (setq flyspell-auto-correct-pos (point))) - ;; Fetch the word to be checked. - (let ((word (flyspell-get-word))) - (if (consp word) - (let ((start (car (cdr word))) - (end (car (cdr (cdr word)))) - (word (car word)) - poss ispell-filter) - (setq flyspell-auto-correct-word word) - ;; Now check spelling of word.. - (ispell-send-string "%\n") ;Put in verbose mode. - (ispell-send-string (concat "^" word "\n")) - ;; Wait until ispell has processed word. - (while (progn - (accept-process-output ispell-process) - (not (string= "" (car ispell-filter))))) - ;; Remove leading empty element. - (setq ispell-filter (cdr ispell-filter)) - ;; Ispell process should return something after word is sent. - ;; Tag word as valid (i.e., skip) otherwise. - (or ispell-filter - (setq ispell-filter '(*))) - (if (consp ispell-filter) - (setq poss (ispell-parse-output (car ispell-filter)))) - (cond - ((or (eq poss t) (stringp poss)) - ;; Don't correct word. - t) - ((null poss) - ;; Ispell error. - (error "Ispell: error in Ispell process")) - (t - ;; The word is incorrect, we have to propose a replacement. - (let ((replacements (if flyspell-sort-corrections - (sort (car (cdr (cdr poss))) 'string<) - (car (cdr (cdr poss)))))) - (setq flyspell-auto-correct-region nil) - (if (consp replacements) - (progn - (let ((replace (car replacements))) - (let ((new-word replace)) - (if (not (equal new-word (car poss))) - (progn - ;; the save the current replacements - (setq flyspell-auto-correct-region - (cons start (length new-word))) - (let ((l replacements)) - (while (consp (cdr l)) - (setq l (cdr l))) - (rplacd l (cons (car poss) replacements))) - (setq flyspell-auto-correct-ring - replacements) - (flyspell-unhighlight-at start) - (delete-region start end) - (funcall flyspell-insert-function new-word) - (if flyspell-abbrev-p - (if (flyspell-already-abbrevp - (flyspell-abbrev-table) word) - (flyspell-change-abbrev - (flyspell-abbrev-table) - word - new-word) - (flyspell-define-abbrev word - new-word))) - (flyspell-word) - (flyspell-display-next-corrections - (cons new-word flyspell-auto-correct-ring)) - (flyspell-ajust-cursor-point pos - (point) - old-max)))))))))) - (setq flyspell-auto-correct-pos (point)) - (ispell-pdict-save t))))))) + ;; If we are not in the construct where flyspell should be active, + ;; invoke the original binding of M-TAB, if that was recorded. + (if (and (local-variable-p 'flyspell--prev-meta-tab-binding) + (commandp flyspell--prev-meta-tab-binding t) + (fboundp flyspell-generic-check-word-predicate) + (not (funcall flyspell-generic-check-word-predicate)) + (equal (where-is-internal 'flyspell-auto-correct-word nil t) + [?\M-\t])) + (call-interactively flyspell--prev-meta-tab-binding) + (let ((pos (point)) + (old-max (point-max))) + ;; Use the correct dictionary. + (flyspell-accept-buffer-local-defs) + (if (and (eq flyspell-auto-correct-pos pos) + (consp flyspell-auto-correct-region)) + ;; We have already been using the function at the same location. + (let* ((start (car flyspell-auto-correct-region)) + (len (cdr flyspell-auto-correct-region))) + (flyspell-unhighlight-at start) + (delete-region start (+ start len)) + (setq flyspell-auto-correct-ring (cdr flyspell-auto-correct-ring)) + (let* ((word (car flyspell-auto-correct-ring)) + (len (length word))) + (rplacd flyspell-auto-correct-region len) + (goto-char start) + (if flyspell-abbrev-p + (if (flyspell-already-abbrevp (flyspell-abbrev-table) + flyspell-auto-correct-word) + (flyspell-change-abbrev (flyspell-abbrev-table) + flyspell-auto-correct-word + word) + (flyspell-define-abbrev flyspell-auto-correct-word word))) + (funcall flyspell-insert-function word) + (flyspell-word) + (flyspell-display-next-corrections flyspell-auto-correct-ring)) + (flyspell-ajust-cursor-point pos (point) old-max) + (setq flyspell-auto-correct-pos (point))) + ;; Fetch the word to be checked. + (let ((word (flyspell-get-word))) + (if (consp word) + (let ((start (car (cdr word))) + (end (car (cdr (cdr word)))) + (word (car word)) + poss ispell-filter) + (setq flyspell-auto-correct-word word) + ;; Now check spelling of word.. + (ispell-send-string "%\n") ;Put in verbose mode. + (ispell-send-string (concat "^" word "\n")) + ;; Wait until ispell has processed word. + (while (progn + (accept-process-output ispell-process) + (not (string= "" (car ispell-filter))))) + ;; Remove leading empty element. + (setq ispell-filter (cdr ispell-filter)) + ;; Ispell process should return something after word is sent. + ;; Tag word as valid (i.e., skip) otherwise. + (or ispell-filter + (setq ispell-filter '(*))) + (if (consp ispell-filter) + (setq poss (ispell-parse-output (car ispell-filter)))) + (cond + ((or (eq poss t) (stringp poss)) + ;; Don't correct word. + t) + ((null poss) + ;; Ispell error. + (error "Ispell: error in Ispell process")) + (t + ;; The word is incorrect, we have to propose a replacement. + (let ((replacements (if flyspell-sort-corrections + (sort (car (cdr (cdr poss))) 'string<) + (car (cdr (cdr poss)))))) + (setq flyspell-auto-correct-region nil) + (if (consp replacements) + (progn + (let ((replace (car replacements))) + (let ((new-word replace)) + (if (not (equal new-word (car poss))) + (progn + ;; the save the current replacements + (setq flyspell-auto-correct-region + (cons start (length new-word))) + (let ((l replacements)) + (while (consp (cdr l)) + (setq l (cdr l))) + (rplacd l (cons (car poss) replacements))) + (setq flyspell-auto-correct-ring + replacements) + (flyspell-unhighlight-at start) + (delete-region start end) + (funcall flyspell-insert-function new-word) + (if flyspell-abbrev-p + (if (flyspell-already-abbrevp + (flyspell-abbrev-table) word) + (flyspell-change-abbrev + (flyspell-abbrev-table) + word + new-word) + (flyspell-define-abbrev word + new-word))) + (flyspell-word) + (flyspell-display-next-corrections + (cons new-word flyspell-auto-correct-ring)) + (flyspell-ajust-cursor-point pos + (point) + old-max)))))))))) + (setq flyspell-auto-correct-pos (point)) + (ispell-pdict-save t)))))))) ;;*---------------------------------------------------------------------*/ ;;* flyspell-auto-correct-previous-pos ... */ diff --git a/nt/INSTALL b/nt/INSTALL index e1d9e0633c7..1be6d99c02e 100644 --- a/nt/INSTALL +++ b/nt/INSTALL @@ -12,6 +12,9 @@ build will run on Windows 9X and newer systems). Do not use this recipe with Cygwin. For building on Cygwin, use the normal installation instructions, ../INSTALL. + For building Emacs using the MinGW64/MSYS2 toolchain, see the + instructions in the file INSTALL.W64 in this directory. + * For the brave (a.k.a. "impatient"): For those who have a working MSYS/MinGW development environment and diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64 new file mode 100644 index 00000000000..95fbfe014d3 --- /dev/null +++ b/nt/INSTALL.W64 @@ -0,0 +1,224 @@ + Building and Installing Emacs on 64-bit MS-Windows + using MSYS2 and MinGW-w64 + + Copyright (c) 2015 Free Software Foundation, Inc. + See the end of the file for license conditions. + +This document describes how to compile a 64-bit GNU Emacs using MSYS2 +and MinGW-w64. For instructions for building a 32-bit Emacs using +MSYS and MinGW, see the file INSTALL in this directory. + +Do not use this recipe with Cygwin. For building on Cygwin, use the normal +installation instructions in ../INSTALL. + +* Requirements + +The total space required is 3GB: 1.8GB for MSYS2 / MinGW-w64 and 1.2GB for +Emacs with the full repository, or less if you're using a release tarball. + +* Set up the MinGW-w64 / MSYS2 build environment + +MinGW-w64 provides a complete runtime for projects built with GCC for 64-bit +Windows -- it's located at http://mingw-w64.org/. + +MSYS2 is a Cygwin-derived software distribution for Windows which provides +build tools for MinGW-w64 -- see http://msys2.github.io/. + +** Download and install MinGW-w64 and MSYS2 + +You can download the x86_64 version of MSYS2 (i.e. msys2-x86_64-<date>.exe) +from + + https://sourceforge.net/projects/msys2/files/Base/x86_64 + +Run this file to install MSYS2 in your preferred directory, e.g. the default +C:\msys64 -- this will install MinGW-w64 also. Note that directory names +containing spaces may cause problems. + +Then you'll need to add the following directories to your Windows PATH +environment variable: + + c:\msys64\usr\bin;c:\msys64\mingw64\bin + +you can do this through Control Panel / System and Security / System / +Advanced system settings / Environment Variables / Edit path. + +Adding these directories to your PATH tells Emacs where to find the DLLs it +needs to run, and some optional commands like grep and find. These commands +will also be available at the Windows console. + +** Download and install the necessary packages + +Run msys2_shell.bat in your MSYS2 directory and you will see a BASH window +opened. + +In the BASH prompt, use the following command to install the necessary +packages (you can copy and paste it into the shell with Shift + Insert): + + pacman -S base-devel \ + mingw-w64-x86_64-toolchain \ + mingw-w64-x86_64-xpm-nox \ + mingw-w64-x86_64-libtiff \ + mingw-w64-x86_64-giflib \ + mingw-w64-x86_64-libpng \ + mingw-w64-x86_64-libjpeg-turbo \ + mingw-w64-x86_64-librsvg \ + mingw-w64-x86_64-libxml2 \ + mingw-w64-x86_64-gnutls + +The packages include the base developer tools (autoconf, automake, grep, make, +etc.), the compiler toolchain (gcc, gdb, etc.), several image libraries, an +XML library, and the GnuTLS (transport layer security) library. Only the +first three packages are required (base-devel, toolchain, xpm-nox); the rest +are optional. + +You now have a complete build environment for Emacs. + +* Install Git (optional) and disable autocrlf + +If you're going to be building the development version of Emacs from the Git +repository, and you don't already have Git on your system, you can install it +in your MSYS2 environment with: + + pacman -S git + +The autocrlf feature of Git may interfere with the configure file, so it is +best to disable this feature by running the command: + + git config core.autocrlf false + +* Get the Emacs source code + +Now you can either get an existing release version of the Emacs source code +from the GNU ftp site, or get the more current version and history from the +Git repository. + +You can always find the most recent information on these sources from the GNU +Savannah Emacs site, https://savannah.gnu.org/projects/emacs. + +** From the FTP site + +The Emacs ftp site is located at http://ftp.gnu.org/gnu/emacs/ - download the +version you want to build and put the file into a location like C:\emacs\, +then uncompress it with tar. This will put the Emacs source into a folder like +C:\emacs\emacs-24.5: + + cd /c/emacs + tar xJf emacs-24.5.tar.xz + +** From the Git repository + +To download the Git repository, do something like the following -- this will +put the Emacs source into C:\emacs\emacs-25: + + mkdir /c/emacs + cd /c/emacs + git clone git://git.sv.gnu.org/emacs.git emacs-25 + +(We recommend using the command shown on Savannah Emacs project page.) + +* Build Emacs + +Now you're ready to build and install Emacs with autogen, configure, make, +and make install. + +First we need to switch to the MinGW-w64 environment. Exit the MSYS2 BASH +console and run mingw64_shell.bat in the C:\msys64 folder, then cd back to +your Emacs source directory, e.g.: + + cd /c/emacs/emacs-25 + +** Run autogen + +If you are building the development sources, run autogen to generate the +configure script (note: this step is not necessary if you are using a +release source tarball, as the configure file is included): + + ./autogen.sh + +** Run configure + +Now you can run configure, which will build the various Makefiles -- note +that the example given here is just a simple one - for more information +on the options available please see the INSTALL file in this directory. + +The '--prefix' option specifies a location for the resulting binary files, +which 'make install' will use - in this example we set it to C:\emacs\emacs-25. +If a prefix is not specified the files will be put in the standard Unix +directories located in your C:\msys64 directory, but this is not recommended. + +Note also that we need to disable Imagemagick because Emacs does not yet +support it on Windows. + + PKG_CONFIG_PATH=/mingw64/lib/pkgconfig \ + ./configure --prefix=/c/emacs/emacs-25 --without-imagemagick + +** Run make + +This will compile Emacs and build the executables, putting them in the src +directory: + + make + +To speed up the process, you can try running + + make -jN + +where N is the number of cores in your system -- if your MSYS2 make supports +parallel execution it will run significantly faster. + +** Run make install + +Now you can run "make install", which will copy the executable and +other files to the location specified in the configure step. This will +create the bin, libexec, share, and var directories: + + make install + +You can also say + + make install prefix=/c/somewhere + +to install them somewhere else. + +* Test Emacs + +To test it out, run + + ./bin/runemacs.exe -Q + +and if all went well, you will have a new 64-bit version of Emacs. + +* Make a shortcut + +To make a shortcut to run the new Emacs, right click on the location where you +want to put it, e.g. the Desktop, select New / Shortcut, then select +runemacs.exe in the bin folder of the new Emacs, and give it a name. + +You can set any command line options by right clicking on the resulting +shortcut, select Properties, then add any options to the Target command, +e.g. --debug-init. + +* Credits + +Thanks to Chris Zheng for the original build outline as used by the +emacsbinw64 project, located at: + + https://sourceforge.net/p/emacsbinw64/wiki/Build%20guideline%20for%20MSYS2-MinGW-w64%20system/ + +* License + +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 <http://www.gnu.org/licenses/>. diff --git a/src/gtkutil.c b/src/gtkutil.c index 90683eba7b8..1cf8ae7c5ab 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -4084,31 +4084,11 @@ xg_page_setup_dialog (void) Lisp_Object xg_get_page_setup (void) { - Lisp_Object result, orientation_symbol; GtkPageOrientation orientation; + Lisp_Object orientation_symbol; if (page_setup == NULL) page_setup = gtk_page_setup_new (); - result = list4 (Fcons (Qleft_margin, - make_float (gtk_page_setup_get_left_margin (page_setup, - GTK_UNIT_POINTS))), - Fcons (Qright_margin, - make_float (gtk_page_setup_get_right_margin (page_setup, - GTK_UNIT_POINTS))), - Fcons (Qtop_margin, - make_float (gtk_page_setup_get_top_margin (page_setup, - GTK_UNIT_POINTS))), - Fcons (Qbottom_margin, - make_float (gtk_page_setup_get_bottom_margin (page_setup, - GTK_UNIT_POINTS)))); - result = Fcons (Fcons (Qheight, - make_float (gtk_page_setup_get_page_height (page_setup, - GTK_UNIT_POINTS))), - result); - result = Fcons (Fcons (Qwidth, - make_float (gtk_page_setup_get_page_width (page_setup, - GTK_UNIT_POINTS))), - result); orientation = gtk_page_setup_get_orientation (page_setup); if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT) orientation_symbol = Qportrait; @@ -4118,9 +4098,24 @@ xg_get_page_setup (void) orientation_symbol = Qreverse_portrait; else if (orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) orientation_symbol = Qreverse_landscape; - result = Fcons (Fcons (Qorientation, orientation_symbol), result); - return result; + return listn (CONSTYPE_HEAP, 7, + Fcons (Qorientation, orientation_symbol), +#define MAKE_FLOAT_PAGE_SETUP(f) make_float (f (page_setup, GTK_UNIT_POINTS)) + Fcons (Qwidth, + MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_page_width)), + Fcons (Qheight, + MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_page_height)), + Fcons (Qleft_margin, + MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_left_margin)), + Fcons (Qright_margin, + MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_right_margin)), + Fcons (Qtop_margin, + MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_top_margin)), + Fcons (Qbottom_margin, + MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_bottom_margin)) +#undef MAKE_FLOAT_PAGE_SETUP + ); } static void diff --git a/src/xfns.c b/src/xfns.c index 3f95f7b79fb..d8ba49587f1 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -6564,31 +6564,27 @@ present and mapped to the usual X keysyms. */) DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0, doc: /* Return image data of FRAMES in TYPE format. FRAMES should be nil (the selected frame), a frame, or a list of -frames (each of which corresponds to one page). Optional arg TYPE -should be either `pdf' (default), `png', `postscript', or `svg'. -Supported types are determined by the compile-time configuration of -cairo. */) +frames (each of which corresponds to one page). Each frame should be +visible. Optional arg TYPE should be either `pdf' (default), `png', +`postscript', or `svg'. Supported types are determined by the +compile-time configuration of cairo. */) (Lisp_Object frames, Lisp_Object type) { - Lisp_Object result, rest, tmp; + Lisp_Object rest, tmp; cairo_surface_type_t surface_type; - if (NILP (frames)) - frames = selected_frame; if (!CONSP (frames)) frames = list1 (frames); tmp = Qnil; for (rest = frames; CONSP (rest); rest = XCDR (rest)) { - struct frame *f = XFRAME (XCAR (rest)); - - if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f)) - error ("Invalid frame"); - + struct frame *f = decode_window_system_frame (XCAR (rest)); Lisp_Object frame; XSETFRAME (frame, f); + if (!FRAME_VISIBLE_P (f)) + error ("Frames to be exported must be visible."); tmp = Fcons (frame, tmp); } frames = Fnreverse (tmp); @@ -6624,9 +6620,7 @@ cairo. */) #endif error ("Unsupported export type"); - result = x_cr_export_frames (frames, surface_type); - - return result; + return x_cr_export_frames (frames, surface_type); } #ifdef USE_GTK @@ -6654,8 +6648,12 @@ The return value is an alist containing the following keys: on, in points. The paper width can be obtained as the sum of width, left-margin, and -right-margin values. Likewise, the paper height is the sum of height, -top-margin, and bottom-margin values. */) +right-margin values if the page orientation is `portrait' or +`reverse-portrait'. Otherwise, it is the sum of width, top-margin, +and bottom-margin values. Likewise, the paper height is the sum of +height, top-margin, and bottom-margin values if the page orientation +is `portrait' or `reverse-portrait'. Otherwise, it is the sum of +height, left-margin, and right-margin values. */) (void) { Lisp_Object result; @@ -6675,29 +6673,29 @@ visible. */) (Lisp_Object frames) { Lisp_Object rest, tmp; + int count; - if (NILP (frames)) - frames = selected_frame; if (!CONSP (frames)) frames = list1 (frames); tmp = Qnil; for (rest = frames; CONSP (rest); rest = XCDR (rest)) { - struct frame *f = XFRAME (XCAR (rest)); - if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f)) - error ("Invalid frame"); + struct frame *f = decode_window_system_frame (XCAR (rest)); Lisp_Object frame; XSETFRAME (frame, f); - if (!EQ (Fframe_visible_p (frame), Qt)) + if (!FRAME_VISIBLE_P (f)) error ("Frames to be printed must be visible."); tmp = Fcons (frame, tmp); } frames = Fnreverse (tmp); /* Make sure the current matrices are up-to-date. */ - Fredisplay (Qt); + count = SPECPDL_INDEX (); + specbind (Qredisplay_dont_pause, Qt); + redisplay_preserve_echo_area (32); + unbind_to (count, Qnil); block_input (); xg_print_frames_dialog (frames); diff --git a/src/xterm.c b/src/xterm.c index acb6566d51d..c5c8b5f70fd 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -569,7 +569,8 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type) Lisp_Object acc = Qnil; int count = SPECPDL_INDEX (); - Fredisplay (Qt); + specbind (Qredisplay_dont_pause, Qt); + redisplay_preserve_echo_area (31); f = XFRAME (XCAR (frames)); frames = XCDR (frames); @@ -611,24 +612,18 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type) cr = cairo_create (surface); cairo_surface_destroy (surface); record_unwind_protect (x_cr_destroy, make_save_ptr (cr)); - unblock_input (); while (1) { - QUIT; - - block_input (); x_free_cr_resources (f); FRAME_CR_CONTEXT (f) = cr; x_clear_area (f, 0, 0, width, height); expose_frame (f, 0, 0, width, height); FRAME_CR_CONTEXT (f) = NULL; - unblock_input (); if (NILP (frames)) break; - block_input (); cairo_surface_show_page (surface); f = XFRAME (XCAR (frames)); frames = XCDR (frames); @@ -636,18 +631,21 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type) height = FRAME_PIXEL_HEIGHT (f); if (surface_set_size_func) (*surface_set_size_func) (surface, width, height); + unblock_input (); + QUIT; + block_input (); } #ifdef CAIRO_HAS_PNG_FUNCTIONS if (surface_type == CAIRO_SURFACE_TYPE_IMAGE) { - block_input (); cairo_surface_flush (surface); cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc); - unblock_input (); } #endif + unblock_input (); + unbind_to (count, Qnil); return CALLN (Fapply, intern ("concat"), Fnreverse (acc)); |