# HG changeset patch # User cvs # Date 1186994207 -7200 # Node ID c9fe270a41017d97248f3857cee1b7210de9145b # Parent 6e6992ccc4b69afc692427afc88403b85483fb16 Import from CVS: tag r21-0b43 diff -r 6e6992ccc4b6 -r c9fe270a4101 CHANGES-beta --- a/CHANGES-beta Mon Aug 13 10:35:55 2007 +0200 +++ b/CHANGES-beta Mon Aug 13 10:36:47 2007 +0200 @@ -1,4 +1,20 @@ -*- indented-text -*- +to 21.0 beta43 "Spanish" +-- texinfo documentation synched from GNU texinfo-3.12 +-- Manual cleanup from Adrian Aichner +-- Miscellaneous fixes from Rick Rankin +-- D'n'D fixes from Oliver Graf +-- startup changes from Stephen Turnbull +-- Miscellaneous fixes from Kirill Katsnelson +-- PNG Graphics fix from Gunnar Evermann +-- Miscellaneous MS windows patches from Andy Piper +-- Graphics update from Hrvoje Niksic +-- Miscellaneous patches from Hrvoje Niksic +-- NEWS updates from Hrvoje Niksic +-- Grayscale JPEG fix from Jareth Hein +-- Miscellaneous patches from Didier Verna +-- Miscellaneous patches from Altrasoft + to 21.0 beta42 "Somali" -- Sounds are no longer included in the core distribution -- Unexec fix for SGI from Olivier Galibert diff -r 6e6992ccc4b6 -r c9fe270a4101 ChangeLog --- a/ChangeLog Mon Aug 13 10:35:55 2007 +0200 +++ b/ChangeLog Mon Aug 13 10:36:47 2007 +0200 @@ -1,3 +1,33 @@ +1998-06-11 SL Baur + + * XEmacs 21.0-beta 43 is released. + +1998-06-04 Oliver Graf + + * tests/Dnd/README: a step-by-step test run + * tests/Dnd/droptest.el: some clarifications + * tests/Dnd/droptest.sh: created, creates test files + +1998-06-01 Oliver Graf + + * configure.in (summary): added experimental to dragndrop option + * configure.usage: added experimental note to --with-dragndrop + * tests/Dnd/droptest.el: extra start-drag-region function + changed the experimental- stuff + +1998-06-02 Andy Piper + + * etc/check_cygwin_setup.sh: set more intelligent defaults for + windows 95. + +1998-06-07 SL Baur + + * lwlib/xlwmenu.c: Add room for the 0 byte sentinel. + +1998-06-05 Colin Rafferty + + * lwlib/xlwmenu.c: Made newchars be as large as it needs to be. + 1998-06-01 SL Baur * XEmacs 21.0-beta42 is released. @@ -16,7 +46,7 @@ * configure.in: Switch from giflib to gifreader for our GIF image support (no other mods needed) -1998-05-28 Oliver Graf +1998-05-28 Oliver Graf * configure.in: only one DnD protocol, CDE has priority over OffiX @@ -24,10 +54,15 @@ * tests/Dnd/dragtest.el: removed * tests/Dnd/droptest.el: cosmetics and comments -1998-05-26 Oliver Graf +1998-05-26 Oliver Graf * tests/Dnd/droptest.el: adapted to CDE extensions +1998-05-25 Hans Guenter Weigand + + * configure.in: + * config.sub: add initial OpenBSD support + 1998-05-21 Andy Piper * configure.in: check for msw dialogs. diff -r 6e6992ccc4b6 -r c9fe270a4101 configure --- a/configure Mon Aug 13 10:35:55 2007 +0200 +++ b/configure Mon Aug 13 10:36:47 2007 +0200 @@ -12013,7 +12013,7 @@ test "$with_cde" = yes && echo " Compiling in support for CDE." test "$with_tooltalk" = yes && echo " Compiling in support for ToolTalk." test "$with_offix" = yes && echo " Compiling in support for OffiX." -test "$with_dragndrop" = yes && echo " Compiling in support for Drag'n'Drop ($dragndrop_proto )." +test "$with_dragndrop" = yes && echo " Compiling in EXPERIMENTAL support for Drag'n'Drop ($dragndrop_proto )." test "$with_workshop" = yes && echo " Compiling in support for Sun WorkShop." test "$with_session" != no && echo " Compiling in support for proper session-management." case "$with_menubars" in diff -r 6e6992ccc4b6 -r c9fe270a4101 configure.in --- a/configure.in Mon Aug 13 10:35:55 2007 +0200 +++ b/configure.in Mon Aug 13 10:36:47 2007 +0200 @@ -3928,7 +3928,7 @@ test "$with_cde" = yes && echo " Compiling in support for CDE." test "$with_tooltalk" = yes && echo " Compiling in support for ToolTalk." test "$with_offix" = yes && echo " Compiling in support for OffiX." -test "$with_dragndrop" = yes && echo " Compiling in support for Drag'n'Drop ($dragndrop_proto )." +test "$with_dragndrop" = yes && echo " Compiling in EXPERIMENTAL support for Drag'n'Drop ($dragndrop_proto )." test "$with_workshop" = yes && echo " Compiling in support for Sun WorkShop." test "$with_session" != no && echo " Compiling in support for proper session-management." case "$with_menubars" in diff -r 6e6992ccc4b6 -r c9fe270a4101 configure.usage --- a/configure.usage Mon Aug 13 10:35:55 2007 +0200 +++ b/configure.usage Mon Aug 13 10:36:47 2007 +0200 @@ -79,6 +79,8 @@ --with-dragndrop (*) Compile in the generic drag and drop API. This is automatically added if one of the drag and drop protocols is found (currently CDE, OffiX, MSWindows). + *WARNING* The Drag'n'drop support is under development + and is considered experimental. --with-cde (*) Compile in support for CDE drag and drop. --with-offix (*) Compile in support for OffiX drag and drop. --without-xmu (*) For those unfortunates whose vendors don't ship Xmu. diff -r 6e6992ccc4b6 -r c9fe270a4101 etc/NEWS --- a/etc/NEWS Mon Aug 13 10:35:55 2007 +0200 +++ b/etc/NEWS Mon Aug 13 10:36:47 2007 +0200 @@ -37,6 +37,16 @@ See the file `etc/PACKAGES' in the distribution for a full description. +** XEmacs is now supported under Microsoft Windows 95/98 and Windows +NT operating systems. For starters, look at the XEmacs on Windows FAQ +at . To +discuss Windows-specific issues, subscribe to the mailing list at +. + +** XEmacs will now use `XEmacs' as its application class if it finds +any `XEmacs' resources in the resource database. Otherwise, it will +continue to use the `Emacs' class. + ** When the Zmacs region is active, `M-x query-replace' and the other replace commands now operate on the region contents only. @@ -123,7 +133,7 @@ or the native C libraries support Japanese localization. This has been available since 20.3, only it hasn't been announced before. -** Jamie Zawinski's `gdb-highlight' program is now distributed with +** Jamie Zawinski's `gdb-highlight' extension is now distributed with the `debug' package. gdb-highlight makes most objects printed in a gdb buffer be mouse-sensitive: as text shows up in the buffer, it is parsed, and objects which are recognized have context-sensitive @@ -131,6 +141,10 @@ (add-hook 'gdb-mode-hook (lambda () (require 'gdb-highlight))) +** The package popper.el is now included in the edit-utils package. +It has been greatly enhanced with respect to the one once included +with the ilisp package and should work well under XEmacs 21.0. + ** C mode changes *** Multiline macros are now handled, both as they affect indentation, @@ -178,18 +192,12 @@ If you want spaces at the beginning of a line to start a paragraph, use the new mode, Paragraph Indent Text mode. -** In Info mode, dir files can be automatically rebuilt -when they do not exist or get out of date with respect to the info files -in the same directory. - -The default behaviour is to ask the user if he wants to rebuild an -outdated info file when doing so would overwrite the file. When the -user has no write access to an outdated info file or to an info -directory containing no dir file, a temporary dir file is built and used -instead without asking the user but issuing a warning. +** The `dir' files are no longer essential for functioning of the Info +subsystem. If the `dir' file does not exist in an Info directory, the +relevant information will be generated on-the-fly. This behaviour can be customized, look for `Info-rebuild-outdated-dir' -in the `info' customization group. +in the `info' customization group. #### Mention other variables! * Lisp and internal changes in XEmacs 21.0 @@ -208,11 +216,14 @@ precedence than the buffer locale. This is because the window locale is more specific than the buffer locale. +*** The new macro `let-specifier' can be used to temporarily add +specifications to specifiers. See the documentation for details. + *** The new specifiers `vertical-scrollbar-visible-p' and `horizontal-scrollbar-visible-p' may be used to control scrollbar -visibility. Previously, the only way to toggle scrollbar visibility -was to set a scrollbar's size to 0. This method is still supported -for backward compatibility. +visibility. Previously, the only way to remove a scrollbar was to set +its size to 0. This method is still supported for backward +compatibility. *** The new specifiers `scrollbar-on-left-p' and `scrollbar-on-top-p' may be used to control the position of the vertical and horizontal @@ -251,6 +262,26 @@ *** The behavior of `other-frame' command (`C-x 5 o') is unaffected by these changes. +** The function `select-window' now has an optional second argument +NORECORD which if non-nil inhibits the recording of a buffer change. + +** The function `vertical-motion' now correctly handles the second, +optional WINDOW argument. A new third argument PIXELS, if non-nil, +indicates that the returned motion should be in pixels. + +** The new function `vertical-motion-pixels' is similar to +vertical-motion but takes as input a vertical motion in pixels. + +** The new functions window-text-area-pixel-{width,height,edges} can +be used to obtain information about the text-displaying area of a +window. + +** The new functions `shrink-window-pixels' and `enlarge-window-pixels' +can be used to adjust the size of a window by a pixel amount. + +** The new function `window-displayed-text-pixel-height' can be used +to determine the height of the text actually displayed in a window. + ** The arithmetic comparison functions <, >, =, /= now accept a variable number of arguments. @@ -301,6 +332,10 @@ and returns the resulting string. This is consistent with other functions, like `list', `vector', etc. +** The function `temp-directory' is now available to return the +directory to store temporary files. On Unix this will be obtained +from TMPDIR, defaulting to `/tmp'. + ** The function load-average now accepts an optional argument USE-FLOATS. If it is non-nil, the load average values are returned as floating point numbers, rather than as integers to be divided by 100. diff -r 6e6992ccc4b6 -r c9fe270a4101 etc/check_cygwin_setup.sh --- a/etc/check_cygwin_setup.sh Mon Aug 13 10:35:55 2007 +0200 +++ b/etc/check_cygwin_setup.sh Mon Aug 13 10:36:47 2007 +0200 @@ -151,11 +151,21 @@ if [ "$HOME" = "" ]; then echo -n "HOME is not set, rectify?" if yorn; then - echo "please enter your home path [/winnt/profiles/$userid]" - read HOME junk - if [ "$HOME" = "" ]; then - HOME="/winnt/profiles/$userid" + if [ "$OS" = "Windows_NT" ] + then + echo "please enter your home path [/winnt/profiles/$userid]" + read HOME junk + if [ "$HOME" = "" ]; then + HOME="/winnt/profiles/$userid" + fi + else + echo "please enter your home path [/]" + read HOME junk + if [ "$HOME" = "" ]; then + HOME="/" + fi fi + echo "HOME=$HOME; export HOME" >> $HOME/.bashrc fi else @@ -171,7 +181,7 @@ echo "TERM is $TERM" fi -if echo $CYGWIN32 | grep tty; then +if echo $CYGWIN32 | grep -w tty; then echo "CYGWIN32 is $CYGWIN32" else echo "CYGWIN32 does not contain \"tty\" terminal may be deficient" diff -r 6e6992ccc4b6 -r c9fe270a4101 lib-src/ChangeLog --- a/lib-src/ChangeLog Mon Aug 13 10:35:55 2007 +0200 +++ b/lib-src/ChangeLog Mon Aug 13 10:36:47 2007 +0200 @@ -1,3 +1,9 @@ +1998-06-04 Andy Piper + + * Makefile.in.in (runemacs): add runemacs as a build target if + HAVE_MS_WINDOWS is defined. move cpp stuff up slightly so that + build targets can benefit from it. + 1998-05-31 Kirill M. Katsnelson * wakeup.c (sleep): Added NT preprocessor quirkfest. diff -r 6e6992ccc4b6 -r c9fe270a4101 lib-src/Makefile.in.in --- a/lib-src/Makefile.in.in Mon Aug 13 10:35:55 2007 +0200 +++ b/lib-src/Makefile.in.in Mon Aug 13 10:36:47 2007 +0200 @@ -63,10 +63,20 @@ ## ========================== Lists of Files =========================== +#define NO_SHORTNAMES +#define NOT_C_CODE +#include "../src/config.h" + ## Things that a user might actually run, ## which should be installed in bindir. -INSTALLABLES = etags ctags b2m gnuclient ootags +INSTALLABLES_BASE = etags ctags b2m gnuclient ootags INSTALLABLE_SCRIPTS = rcs-checkin pstogif install-sid send-pr gnudoit gnuattach +#ifdef HAVE_MS_WINDOWS +INSTALLABLES = $(INSTALLABLES_BASE) runemacs +#else +INSTALLABLES = $(INSTALLABLES_BASE) +#endif + ## Things that Emacs runs internally, or during the build process, ## which should not be installed in bindir. @@ -114,10 +124,6 @@ ## ========================== start of cpp stuff ======================= -#define NO_SHORTNAMES -#define NOT_C_CODE -#include "../src/config.h" - #ifdef USE_GNU_MAKE vpath %.c @srcdir@ vpath %.h @srcdir@ @@ -264,6 +270,14 @@ etags: ${etags_deps} $(CC) ${etags_args} -o $@ +runemacs_args = -I. $(cflags) -I${srcdir} -I${srcdir}/../src \ + -DVERSION='"${version}"' ${srcdir}/../nt/runemacs.c \ + $(ldflags) -Wl,--subsystem,windows +runemacs_deps = ${srcdir}/../nt/runemacs.c ../src/config.h + +runemacs: ${runemacs_deps} + $(CC) ${runemacs_args} -o $@ + ootags_args = -I. $(cflags) -I${srcdir} -I${srcdir}/../src \ -DVERSION='"${version}"' ${srcdir}/ootags.c \ $(GETOPTOBJS) regex.o $(ldflags) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/ChangeLog --- a/lisp/ChangeLog Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/ChangeLog Mon Aug 13 10:36:47 2007 +0200 @@ -1,3 +1,102 @@ +1998-06-10 Hrvoje Niksic + + * specifier.el (let-specifier): Tiny docfixes. + +1998-06-12 Andy Piper + + * msw-mouse.el: set selection-pointer-glyph to Normal. + +1998-06-09 Per Abrahamsen + + * wid-edit.el (widget-specify-secret): New function. + (widget-after-change): Use it. + (widget-specify-field): Use it. + +1998-06-08 Hrvoje Niksic + + * mouse.el (drag-window-divider): Use `(not done)' instead of + `doit'; reuse result of `window-pixel-edges'. + + * modeline.el (drag-modeline-event-lag): Rename to + drag-divider-event-lag. + +1998-06-07 Hrvoje Niksic + + * specifier.el (let-specifier): Rewritten not to generate needless + `let's; clarified documentation; support TAG-SET and HOW-TO-ADD + arguments. + +1998-05-28 Hrvoje Niksic + + * minibuf.el (read-file-name-1): Setup buffer-local value of + `completion-ignore-case' in completions buffer under Windows. + +1998-06-06 Kirill M. Katsnelson + + * about.el (about-maintainer-glyph): Fix support for not + compressed images. + +1998-06-04 Kirill M. Katsnelson + + * cmdloop.el (cancel-mode-internal): Defined this do-nothing function. + + * mouse.el (mouse-track): Cancel selection if misc-user event with + `cancel-mode-internal' function is fetched. + +1998-06-03 Hrvoje Niksic + + * files.el (save-some-buffers-1): Fixed return value. + +1998-06-01 Oliver Graf + + * dragdrop.el: added experimental + +1998-05-26 Stephen J. Turnbull + + * startup.el (after-init-hook, init-file-user, + user-init-directory, load-user-init-file): Purge references + to "~/.xemacs/init.el" from docstrings. + + (load-user-init-file) Use paths-construct-path to construct + paths to user init files. Go directly to ~/.emacs, do not + search ~/.xemacs/, do not load `default-custom-file'. + +1998-06-03 Hrvoje Niksic + + * files.el (interpreter-mode-alist): Catch wish and tclsh before + general *sh. + (inhibit-first-line-modes-regexps): Added `.tar.gz'. + +1998-06-03 Andy Piper + + * menubar-items.el (default-menubar): add Update Packages to customize + menu. + +1998-06-02 Andy Piper + + * faces.el: use toolbar face as a fallback for toolbar properties + in xpm-color-symbols instead of default. + + * msw-faces.el: rename 3d-object -> gui-element face. + +1998-06-06 SL Baur + + * startup.el (xemacs-startup-logo-function): New variable. + (startup-splash-frame): Use it. + +1998-06-02 Hrvoje Niksic + + * files.el (save-some-buffers): Would wait 1 second. + (save-some-buffers-1): Delete other windows here instead of in + `save-some-buffers'. + (save-some-buffers): Force redisplay only if windows were deleted. + +1998-06-02 Didier Verna + + * cus-face.el (custom-face-attributes): generalized the use of + toggle buttons for boolean attributes. + Re-ordered the items a bit. + 1998-06-01 SL Baur * sound.el (default-sound-directory): Use `locate-data-directory' diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/about.el --- a/lisp/about.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/about.el Mon Aug 13 10:36:47 2007 +0200 @@ -565,8 +565,8 @@ (make-glyph [string :data "[Error]"])) (file (make-glyph - (if (featurep 'xbm) - `([xbm :data ,data] + (if (featurep 'xpm) + `([xpm :file ,file] [string :data "[Image]"]) `([string :data "[Image]"])))) (t diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/cmdloop.el --- a/lisp/cmdloop.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/cmdloop.el Mon Aug 13 10:36:47 2007 +0200 @@ -105,6 +105,17 @@ (delete-other-windows)) ((string-match "^ \\*" (buffer-name (current-buffer))) (bury-buffer)))) + +;; `cancel-mode-internal' is a function of a misc-user event, which is +;; queued when window system directs XEmacs frame to cancel any modal +;; behavior it exposes, like mouse pointer grabbing. +;; +;; This function does nothing at the top level, but the code which +;; runs modal event loops, such as selection drag loop in `mouse-track', +;; check if misc-user function symbol is `cancel-mode-internal', and +;; takes necessary cleanup actions. +(defun cancel-mode-internal (object) + (setq zmacs-region-stays t)) ;; Someone wrote: "This should really be a ring of last errors." ;; diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/cus-face.el --- a/lisp/cus-face.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/cus-face.el Mon Aug 13 10:36:47 2007 +0200 @@ -55,18 +55,7 @@ ;;; Font Attributes. (defconst custom-face-attributes - '((:bold (boolean :tag "Bold" - :help-echo "Control whether a bold font should be used.") - custom-set-face-bold custom-face-bold) - (:italic (boolean :tag "Italic" - :help-echo "\ -Control whether an italic font should be used.") - custom-set-face-italic custom-face-italic) - (:underline (boolean :tag "Underline" - :help-echo "\ -Control whether the text should be underlined.") - set-face-underline-p face-underline-p) - (:foreground (color :tag "Foreground" + '((:foreground (color :tag "Foreground" :value "" :help-echo "Set foreground color.") set-face-foreground face-foreground-name) @@ -74,11 +63,10 @@ :value "" :help-echo "Set background color.") set-face-background face-background-name) - ;; #### Should make it work on X - (:inverse-video (boolean :tag "Inverse" - :help-echo "\ -Control whether the text should be inverted. Works only on TTY-s") - set-face-reverse-p face-reverse-p) + (:size (editable-field :format "Size: %v" + :help-echo "\ +Text size (e.g. 9pt or 2mm).") + custom-set-face-font-size custom-face-font-size) (:stipple (editable-field :format "Stipple: %v" :help-echo "Name of background bitmap file.") set-face-stipple custom-face-stipple) @@ -86,14 +74,26 @@ :help-echo "\ Name of font family to use (e.g. times).") custom-set-face-font-family custom-face-font-family) - (:size (editable-field :format "Size: %v" - :help-echo "\ -Text size (e.g. 9pt or 2mm).") - custom-set-face-font-size custom-face-font-size) + (:bold (toggle :format "%[Bold%]: %v\n" + :help-echo "Control whether a bold font should be used.") + custom-set-face-bold custom-face-bold) + (:italic (toggle :format "%[Italic%]: %v\n" + :help-echo "\ +Control whether an italic font should be used.") + custom-set-face-italic custom-face-italic) + (:underline (toggle :format "%[Underline%]: %v\n" + :help-echo "\ +Control whether the text should be underlined.") + set-face-underline-p face-underline-p) + ;; #### Should make it work on X (:strikethru (toggle :format "%[Strikethru%]: %v\n" :help-echo "\ Control whether the text should be strikethru.") - set-face-strikethru-p face-strikethru-p)) + set-face-strikethru-p face-strikethru-p) + (:inverse-video (toggle :format "%[Inverse Video%]: %v\n" + :help-echo "\ +Control whether the text should be inverted. Works only on TTY-s") + set-face-reverse-p face-reverse-p)) "Alist of face attributes. The elements are of the form (KEY TYPE SET GET) where KEY is a symbol diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/dragdrop.el --- a/lisp/dragdrop.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/dragdrop.el Mon Aug 13 10:36:47 2007 +0200 @@ -39,29 +39,29 @@ ;; Anyway: is dragdrop- a good prefix for all this? ;; What if someone trys drop in the minibuffer? (defgroup drag-n-drop nil - "Window system-independent drag'n'drop support." + "*{EXPERIMENTAL} Window system-independent drag'n'drop support." :group 'editing) (defcustom dragdrop-drop-at-point nil - "*If non-nil, the drop handler functions will drop text at the cursor location. + "*{EXPERIMENTAL} If non-nil, drop text at the cursor location. Otherwise, the cursor will be moved to the location of the pointer drop before text is inserted." :type 'boolean :group 'drag-n-drop) (defcustom dragdrop-autoload-tm-view nil - "*If non-nil, autoload tm-view if a MIME buffer needs to be decoded. + "*{EXPERIMENTAL} If non-nil, autoload tm-view to decode MIME data. Otherwise, the buffer is only decoded if tm-view is already avaiable." :type 'boolean :group 'drag-n-drop) ;; the widget for editing the drop-functions (define-widget 'dragdrop-function-widget 'list - "Widget for editing drop dispatch functions." + "*{EXPERIMENTAL} Widget for editing drop dispatch functions." :args `((choice :tag "Function" - (function-item dragdrop-drop-url-default) - (function-item dragdrop-drop-mime-default) - (function-item dragdrop-drop-log-function) + (function-item experimental-dragdrop-drop-url-default) + (function-item experimental-dragdrop-drop-mime-default) + (function-item experimental-dragdrop-drop-log-function) (function :tag "Other" nil)) (choice :tag "Button" :value t (choice-item :tag "Ignore" t) @@ -83,9 +83,9 @@ (sexp :tag "Arg" :value nil))) :value '(nil t t)) -(defcustom dragdrop-drop-functions '((dragdrop-drop-url-default t t) - (dragdrop-drop-mime-default t t)) - "This is the standart drop function search list. +(defcustom experimental-dragdrop-drop-functions '((experimental-dragdrop-drop-url-default t t) + (experimental-dragdrop-drop-mime-default t t)) + "*{EXPERIMENTAL} This is the standart drop function search list. Each element is a list of a function, a button selector, a modifier selector and optional argumets to the function call. The function must accept at least two arguments: first is the event @@ -96,39 +96,39 @@ :type '(repeat dragdrop-function-widget)) (defgroup dnd-debug nil - "Drag'n'Drop debugging options." + "*{EXPERIMENTAL} Drag'n'Drop debugging options." :group 'drag-n-drop) (defcustom dragdrop-drop-log nil - "If non-nil, every drop is logged. + "*{EXPERIMENTAL} If non-nil, every drop is logged. The name of the buffer is set in the custom 'dragdrop-drop-log-name" :group 'dnd-debug :type 'boolean) (defcustom dragdrop-drop-log-name "*drop log buffer*" - "The name of the buffer used to log drops. + "*{EXPERIMENTAL} The name of the buffer used to log drops. Set dragdrop-drop-log to non-nil to enable this feature." :group 'dnd-debug :type 'string) (defvar dragdrop-drop-log-buffer nil - "Buffer to log drops in debug mode.") + "*{EXPERIMENTAL} Buffer to log drops in debug mode.") ;; ;; Drop API ;; (defun dragdrop-drop-dispatch (object) - "This function identifies DROP type misc-user-events. + "*{EXPERIMENTAL} This function identifies DROP type misc-user-events. It calls functions which will handle the drag." (let ((event current-mouse-event)) (and dragdrop-drop-log - (dragdrop-drop-log-function event object)) + (experimental-dragdrop-drop-log-function event object)) (dragdrop-drop-find-functions event object))) (defun dragdrop-drop-find-functions (event object) "Finds valid drop-handle functions and executes them to dispose the drop. -It does this by looking for extent-properties called 'dragdrop-drop-functions -and for variables named like this." +It does this by looking for extent-properties called +'experimental-dragdrop-drop-functions and for variables named like this." (catch 'dragdrop-drop-is-done (and (event-over-text-area-p event) ;; let's search the extents @@ -141,15 +141,17 @@ (or pos (setq pos cpos)) (select-window window) (setq buffer (window-buffer)) - (let ((ext (extent-at pos buffer 'dragdrop-drop-functions))) + (let ((ext (extent-at pos buffer 'experimental-dragdrop-drop-functions))) (while (not (eq ext nil)) (dragdrop-drop-do-functions - (extent-property ext 'dragdrop-drop-functions) + (extent-property ext 'experimental-dragdrop-drop-functions) event object) - (setq ext (extent-at pos buffer 'dragdrop-drop-functions ext))))))) - ;; now look into the variable dragdrop-drop-functions - (dragdrop-drop-do-functions dragdrop-drop-functions event object))) + (setq ext (extent-at pos buffer + 'experimental-dragdrop-drop-functions + ext))))))) + ;; now look into the variable experimental-dragdrop-drop-functions + (dragdrop-drop-do-functions experimental-dragdrop-drop-functions event object))) (defun dragdrop-compare-mods (first-mods second-mods) "Returns t if both first-mods and second-mods contain the same elements. @@ -181,8 +183,8 @@ (setq drop-funs (cdr drop-funs)))) nil) -(defun dragdrop-drop-log-function (event object &optional message buffer) - "Logs any drops into a buffer. +(defun experimental-dragdrop-drop-log-function (event object &optional message buffer) + "*{EXPERIMENTAL} Logs any drops into a buffer. If buffer is nil, it inserts the data into a buffer called after dragdrop-drop-log-name. If dragdrop-drop-log is non-nil, this is done automatically for each drop. @@ -223,8 +225,8 @@ (insert "----------\n")) nil) -(defun dragdrop-drop-url-default (event object) - "Default handler for dropped URL data. +(defun experimental-dragdrop-drop-url-default (event object) + "*{EXPERIMENTAL} Default handler for dropped URL data. Finds files and URLs. Returns nil if object does not contain URL data." (cond ((eq (car object) 'dragdrop-URL) (let ((data (cdr object)) @@ -253,8 +255,8 @@ t)) (t nil))) -(defun dragdrop-drop-mime-default (event object) - "Default handler for dropped MIME data. +(defun experimental-dragdrop-drop-mime-default (event object) + "*{EXPERIMENTAL} Default handler for dropped MIME data. Inserts text into buffer, creates MIME buffers for other types. Returns nil if object does not contain MIME data." (cond ((eq (car object) 'dragdrop-MIME) @@ -342,29 +344,29 @@ ;; ;; Drag API ;; -(defun dragdrop-drag (event object) - "The generic drag function. +(defun experimental-dragdrop-drag (event object) + "*{EXPERIMENTAL} The generic drag function. Tries to do the best with object in the selected protocol. Object must comply to the standart drag'n'drop object format." (error "Not implemented")) -(defun dragdrop-drag-region (event begin end) - "Drag a region. +(defun experimental-dragdrop-drag-region (event begin end) + "*{EXPERIMENTAL} Drag a region. This function uses special data types if the low-level protocol requires it. It does so by calling dragdrop-drag-pure-text." (dragdrop-drag-pure-text event (buffer-substring-no-properties begin end))) -(defun dragdrop-drag-pure-text (event text) - "Drag text-only data. +(defun experimental-dragdrop-drag-pure-text (event text) + "*{EXPERIMENTAL} Drag text-only data. Takes care of special low-level protocol data types. Text must be a list of strings." (error "Not implemented")) -(defun dragdrop-drag-pure-file (event file) - "Drag filepath-only data. +(defun experimental-dragdrop-drag-pure-file (event file) + "*{EXPERIMENTAL} Drag filepath-only data. Takes care of special low-level protocol data types. file must be a list of strings." (error "Not implemented")) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/faces.el --- a/lisp/faces.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/faces.el Mon Aug 13 10:36:47 2007 +0200 @@ -1671,19 +1671,18 @@ (or (and (featurep 'x) - (or - (x-get-resource "backgroundToolBarColor" - "BackgroundToolBarColor" 'string) - (x-get-resource "background" "Background" 'string))) + (x-get-resource "backgroundToolBarColor" + "BackgroundToolBarColor" 'string)) + + (face-background 'toolbar) "Gray80"))) (purecopy '("foregroundToolBarColor" (or (and (featurep 'x) - (or - (x-get-resource "foregroundToolBarColor" - "ForegroundToolBarColor" 'string) - (x-get-resource "foreground" "Foreground" 'string))) + (x-get-resource "foregroundToolBarColor" + "ForegroundToolBarColor" 'string)) + (face-foreground 'toolbar) "Black"))) ))) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/files.el --- a/lisp/files.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/files.el Mon Aug 13 10:36:47 2007 +0200 @@ -1132,6 +1132,15 @@ "File local-variables error: %s" (error-message-string err)))))) +;; #### This variable sucks in the package model. There should be a +;; way for new packages to add their entries to auto-mode-alist in a +;; clean way. Per Abrahamsen suggested splitting auto-mode-alist to +;; several distinct variables such as, in order of precedence, +;; `user-auto-mode-alist' for users, `package-auto-mode-alist' for +;; packages and `auto-mode-alist' (which might also be called +;; `default-auto-mode-alist') for default stuff, such as some of the +;; entries below. + (defvar auto-mode-alist '(("\\.te?xt\\'" . text-mode) ("\\.[ch]\\'" . c-mode) @@ -1165,9 +1174,8 @@ ("/\\.\\(bash_\\|z\\)?\\(profile\\|login\||logout\\)\\'" . sh-mode) ("/\\.\\([ckz]sh\\|bash\\|tcsh\\|es\\|xinit\\|startx\\)rc\\'" . sh-mode) ("/\\.\\([kz]shenv\\|xsession\\)\\'" . sh-mode) -;;; The following should come after the ChangeLog pattern -;;; for the sake of ChangeLog.1, etc. -;;; and after the .scm.[0-9] pattern too. + ;; The following come after the ChangeLog pattern for the sake of + ;; ChangeLog.1, etc. and after the .scm.[0-9] pattern too. ("\\.[12345678]\\'" . nroff-mode) ("\\.[tT]e[xX]\\'" . tex-mode) ("\\.\\(sty\\|cls\\|bbl\\)\\'" . latex-mode) @@ -1224,8 +1232,8 @@ (defvar interpreter-mode-alist '(("^#!.*csh" . sh-mode) + ("^#!.*\\b\\(scope\\|wish\\|tcl\\|tclsh\\|expect\\)" . tcl-mode) ("^#!.*sh\\b" . sh-mode) - ("^#!.*\\b\\(scope\\|wish\\|tcl\\|expect\\)" . tcl-mode) ("perl" . perl-mode) ("python" . python-mode) ("awk\\b" . awk-mode) @@ -1246,7 +1254,8 @@ with the name of the interpreter specified in the first line. If it matches, mode MODE is selected.") -(defvar inhibit-first-line-modes-regexps (purecopy '("\\.tar\\'" "\\.tgz\\'")) +(defvar inhibit-first-line-modes-regexps (purecopy '("\\.tar\\'" "\\.tgz\\'" + "\\.tar\\.gz\\'")) "List of regexps; if one matches a file name, don't look for `-*-'.") (defvar inhibit-first-line-modes-suffixes nil @@ -2405,80 +2414,86 @@ ;; usual drill. (save-some-buffers-1 arg exiting nil) ;; Else, protect the windows. - (delete-other-windows) - (save-window-excursion - (save-some-buffers-1 arg exiting t)) - ;; Force redisplay. #### Perhaps this should be handled - ;; automatically by `save-window-excursion'. - (sit-for 1)))) + (when (save-window-excursion + (save-some-buffers-1 arg exiting t)) + ;; Force redisplay. + (sit-for 0))))) ;; XEmacs - do not use queried flag (defun save-some-buffers-1 (arg exiting switch-buffer) - (let ((files-done - (map-y-or-n-p - (lambda (buffer) - (and (buffer-modified-p buffer) - (not (buffer-base-buffer buffer)) - ;; XEmacs addition: - (not (symbol-value-in-buffer 'save-buffers-skip buffer)) - (or - (buffer-file-name buffer) - (and exiting - (progn - (set-buffer buffer) - (and buffer-offer-save (> (buffer-size) 0))))) - (if arg - t - ;; #### We should provide a per-buffer means to - ;; disable the switching. - (when switch-buffer - ;; #### Consider using `display-buffer' here for 21.1! - ;(display-buffer buffer nil (selected-frame))) - (switch-to-buffer buffer t)) - (if (buffer-file-name buffer) - (format "Save file %s? " - (buffer-file-name buffer)) - (format "Save buffer %s? " - (buffer-name buffer)))))) - (lambda (buffer) - (set-buffer buffer) - (condition-case () - (save-buffer) - (error nil))) - (buffer-list) - '("buffer" "buffers" "save") - ;;instead of this we just say "yes all", "no all", etc. - ;;"save all the rest" - ;;"save only this buffer" "save no more buffers") - ;; this is rather bogus. --ben - ;; (it makes the dialog box too big, and you get an error - ;; "wrong type argument: framep, nil" when you hit q after - ;; choosing the option from the dialog box) + (let* ((switched nil) + (files-done + (map-y-or-n-p + (lambda (buffer) + (and (buffer-modified-p buffer) + (not (buffer-base-buffer buffer)) + ;; XEmacs addition: + (not (symbol-value-in-buffer 'save-buffers-skip buffer)) + (or + (buffer-file-name buffer) + (and exiting + (progn + (set-buffer buffer) + (and buffer-offer-save (> (buffer-size) 0))))) + (if arg + t + ;; #### We should provide a per-buffer means to + ;; disable the switching. For instance, you might + ;; want to turn it off for buffers the contents of + ;; which is meaningless to humans, such as + ;; `.newsrc.eld'. + (when switch-buffer + (unless (one-window-p) + (delete-other-windows)) + (setq switched t) + ;; #### Consider using `display-buffer' here for 21.1! + ;;(display-buffer buffer nil (selected-frame))) + (switch-to-buffer buffer t)) + (if (buffer-file-name buffer) + (format "Save file %s? " + (buffer-file-name buffer)) + (format "Save buffer %s? " + (buffer-name buffer)))))) + (lambda (buffer) + (set-buffer buffer) + (condition-case () + (save-buffer) + (error nil))) + (buffer-list) + '("buffer" "buffers" "save") + ;;instead of this we just say "yes all", "no all", etc. + ;;"save all the rest" + ;;"save only this buffer" "save no more buffers") + ;; this is rather bogus. --ben + ;; (it makes the dialog box too big, and you get an error + ;; "wrong type argument: framep, nil" when you hit q after + ;; choosing the option from the dialog box) - ;; We should fix the dialog box rather than disabling - ;; this! --hniksic - (list (list ?\C-r (lambda (buf) - ;; #### FSF has an EXIT-ACTION argument - ;; to `view-buffer'. - (view-buffer buf) - (setq view-exit-action - (lambda (ignore) - (exit-recursive-edit))) - (recursive-edit) - ;; Return nil to ask about BUF again. - nil) - "display the current buffer")))) - (abbrevs-done - (and save-abbrevs abbrevs-changed - (progn - (if (or arg - (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name))) - (write-abbrev-file nil)) - ;; Don't keep bothering user if he says no. - (setq abbrevs-changed nil) - t)))) + ;; We should fix the dialog box rather than disabling + ;; this! --hniksic + (list (list ?\C-r (lambda (buf) + ;; #### FSF has an EXIT-ACTION argument + ;; to `view-buffer'. + (view-buffer buf) + (setq view-exit-action + (lambda (ignore) + (exit-recursive-edit))) + (recursive-edit) + ;; Return nil to ask about BUF again. + nil) + "display the current buffer")))) + (abbrevs-done + (and save-abbrevs abbrevs-changed + (progn + (if (or arg + (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name))) + (write-abbrev-file nil)) + ;; Don't keep bothering user if he says no. + (setq abbrevs-changed nil) + t)))) (or (> files-done 0) abbrevs-done - (display-message 'no-log "(No files need saving)")))) + (display-message 'no-log "(No files need saving)")) + switched)) (defun not-modified (&optional arg) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/menubar-items.el --- a/lisp/menubar-items.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/menubar-items.el Mon Aug 13 10:36:47 2007 +0200 @@ -231,7 +231,8 @@ ["Saved..." customize-saved] ["Set..." customize-customized] ["Apropos..." customize-apropos] - ["Browse..." customize-browse]) + ["Browse..." customize-browse] + ["Update Packages" package-get-custom]) ("Editing Options" ["Overstrike" (progn diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/minibuf.el --- a/lisp/minibuf.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/minibuf.el Mon Aug 13 10:36:47 2007 +0200 @@ -1606,6 +1606,10 @@ initial-contents completer) (let ((rfhookfun (lambda () + ;; #### SCREAM! Create a `file-system-ignore-case' + ;; function, so this kind of stuff is generalized! + (and (eq system-type 'windows-nt) + (set (make-local-variable 'completion-ignore-case) t)) (set (make-local-variable 'completion-display-completion-list-function) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/modeline.el --- a/lisp/modeline.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/modeline.el Mon Aug 13 10:36:47 2007 +0200 @@ -39,14 +39,19 @@ "Modeline customizations." :group 'environment) -(defcustom drag-modeline-event-lag 150 - "*The pause (in msecs) between drag modeline events before redisplaying. +(defcustom drag-divider-event-lag 150 + "*The pause (in msecs) between divider drag events before redisplaying. If this value is too small, dragging will be choppy because redisplay cannot keep up. If it is too large, dragging will be choppy because of the explicit redisplay delay specified." :type 'integer + ;; #### Fix group. :group 'modeline) +(define-obsolete-variable-alias + 'drag-modeline-event-lag + 'drag-divider-event-lag) + (defcustom modeline-click-swaps-buffers nil "*If non-nil, clicking on the modeline changes the current buffer. Click on the left half of the modeline cycles forward through the @@ -123,7 +128,7 @@ ;; occurred in some other frame. ;; drag if this is a mouse motion event and the time ;; between this event and the last event is greater than - ;; drag-modeline-event-lag. + ;; drag-divider-event-lag. ;; do nothing if this is any other kind of event. (cond ((or (misc-user-event-p event) (key-press-event-p event)) @@ -145,7 +150,7 @@ ((not (eq start-event-frame (event-frame event))) (setq done t)) ((< (abs (- (event-timestamp event) last-timestamp)) - drag-modeline-event-lag) + drag-divider-event-lag) nil) (t ;; (set-modeline-hscroll start-event-window diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/mouse.el --- a/lisp/mouse.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/mouse.el Mon Aug 13 10:36:47 2007 +0200 @@ -629,7 +629,9 @@ event mouse-track-click-count) (mouse-track-run-hook 'mouse-track-click-hook event mouse-track-click-count))) - ((key-press-event-p event) + ((or (key-press-event-p event) + (and (misc-user-event-p event) + (eq (event-function event) 'cancel-mode-internal))) (error "Selection aborted")) (t (dispatch-event event)))) @@ -1424,12 +1426,14 @@ (let* ((window (event-window event)) (frame (event-channel event)) (last-timestamp (event-timestamp event)) - (doit t)) - (while doit - (let ((old-right (caddr (window-pixel-edges window))) - (old-left (car (window-pixel-edges window))) - (backup-conf (current-window-configuration frame)) - (old-edges-all-windows (mapcar 'window-pixel-edges (window-list)))) + done) + (while (not done) + (let* ((edges (window-pixel-edges window)) + (old-right (caddr edges)) + (old-left (car edges)) + (backup-conf (current-window-configuration frame)) + (old-edges-all-windows (mapcar 'window-pixel-edges + (window-list)))) ;; This is borrowed from modeline.el: ;; requeue event and quit if this is a misc-user, eval or @@ -1438,24 +1442,24 @@ ;; occurred in some other frame. ;; drag if this is a mouse motion event and the time ;; between this event and the last event is greater than - ;; drag-modeline-event-lag. + ;; drag-divider-event-lag. ;; do nothing if this is any other kind of event. (setq event (next-event event)) (cond ((or (misc-user-event-p event) (key-press-event-p event)) (setq unread-command-events (nconc unread-command-events (list event)) - doit nil)) + done t)) ((button-release-event-p event) - (setq doit nil)) + (setq done t)) ((button-event-p event) - (setq doit nil)) + (setq done t)) ((not (motion-event-p event)) (dispatch-event event)) ((not (eq frame (event-frame event))) - (setq doit nil)) + (setq done t)) ((< (abs (- (event-timestamp event) last-timestamp)) - drag-modeline-event-lag)) + drag-divider-event-lag)) (t (setq last-timestamp (event-timestamp event)) ;; Enlarge the window, calculating change in characters diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/msw-faces.el --- a/lisp/msw-faces.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/msw-faces.el Mon Aug 13 10:36:47 2007 +0200 @@ -34,9 +34,9 @@ (defun mswindows-init-device-faces (device) (set-face-font 'default '((mswindows default) . "Courier New:Regular:10") 'global) - ;; 3d objects - (set-face-foreground '3d-object '((mswindows default) . "Black") 'global) - (set-face-background '3d-object '((mswindows default) . "Gray75") 'global) + ;; gui elements + (set-face-foreground 'gui-element '((mswindows default) . "Black") 'global) + (set-face-background 'gui-element '((mswindows default) . "Gray75") 'global) (set-face-foreground 'default '((mswindows default) . "black") 'global) (set-face-background 'default '((mswindows default) . "white") 'global) ) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/msw-mouse.el --- a/lisp/msw-mouse.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/msw-mouse.el Mon Aug 13 10:36:47 2007 +0200 @@ -34,6 +34,8 @@ [resource :resource-type cursor :resource-id "Ibeam"]) (set-glyph-image nontext-pointer-glyph [resource :resource-type cursor :resource-id "Normal"]) +(set-glyph-image selection-pointer-glyph + [resource :resource-type cursor :resource-id "Normal"]) (set-glyph-image modeline-pointer-glyph [resource :resource-type cursor :resource-id "SizeNS"]) (set-glyph-image divider-pointer-glyph diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/specifier.el --- a/lisp/specifier.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/specifier.el Mon Aug 13 10:36:47 2007 +0200 @@ -403,88 +403,97 @@ how-to-add)))) value) -;; Note: you cannot replace the following macro with `letf' because -;; `specifier-instance' does not have a setf method defined. (I tried -;; to use `set-specifier' as the setf method for `specifier-instance', -;; but it doesn't work for `letf' because set-specifier to the old -;; value cannot be used to "undo" a previous set-specifier, as letf -;; expects.) -;; -;; This macro might perhaps be made simpler, with an addition to -;; `remove-specifier'. Example (simplified for clarity): -;; -;; (defmacro let-specifier (specifier value domain &rest body) -;; `(unwind-protect -;; (progn -;; (add-spec-to-specifier ,specifier ,value ,domain nil 'prepend) -;; ,@body) -;; (remove-specifier ,specifier ,domain))) -;; -;; So, the idea is to unconditionally prepend a specification for -;; DOMAIN, and unconditionally remove it. This does not work because -;; `remove-specifier' removes *all* the specifications of DOMAIN, -;; nuking the old ones, in the process. (for this purpose, it might -;; make sense for `remove-specifier' to have a HOW-TO-REMOVE -;; argument.) -;; -;; The following version remembers the old speclist and returns it -;; later. It's probably less error-prone anyway. +(defmacro let-specifier (specifier-list &rest body) + "Add specifier specs, evaluate forms in BODY and restore the specifiers. +\(let-specifier SPECIFIER-LIST BODY...) + +Each element of SPECIFIER-LIST should look like this: +\(SPECIFIER VALUE &optional LOCALE TAG-SET HOW-TO-ADD). -(defmacro let-specifier (specifier-list &rest body) - "(let-specifier SPECIFIER-LIST BODY): bind specifiers and evaluate BODY. +SPECIFIER is the specifier to be temporarily modified. VALUE is the +instantiator to be temporarily added to SPECIFIER in LOCALE. LOCALE, +TAG-SET and HOW-TO-ADD have the same meaning as in +`add-spec-to-specifier'. + +The code resulting from macro expansion will add specifications to +specifiers using `add-spec-to-specifier'. After BODY is finished, the +temporary specifications are removed and old spec-lists are restored. + +LOCALE, TAG-SET and HOW-TO-ADD may be omitted, and default to nil. The value of the last form in BODY is returned. -Each element of SPECIFIER-LIST should be a list of -\(SPECIFIER VALUE DOMAIN). VALUE and DOMAIN may be omitted, and default -to nil. The elements of SPECIFIER-LIST are evaluated sequentially. + +NOTE: If you want the specifier's instance to change in all +circumstances, use (selected-window) as the LOCALE. If LOCALE is nil +or omitted, it defaults to `global'. -For meaning of DOMAIN, see `specifier-instance'." - ;; Error-checking - (dolist (listel specifier-list) - (or (and (consp listel) - (<= (length listel) 3)) - (signal 'error (list "Should be a 3-element list" listel)))) - ;; Set up fresh symbols to avoid name clashes. - (let* ((specvarlist (mapcar #'(lambda (ignored) (gensym "specifier-")) - specifier-list)) - (valvarlist (mapcar #'(lambda (ignored) (gensym "value-")) - specifier-list)) - (domvarlist (mapcar #'(lambda (ignored) (gensym "domain-")) - specifier-list)) - (oldvarlist (mapcar #'(lambda (ignored) (gensym "old-")) - specifier-list))) - ;; Bind the appropriate variables. - `(let* (,@(mapcar* (lambda (symbol listel) - (list symbol (nth 0 listel))) - specvarlist specifier-list) - ,@(mapcar* (lambda (symbol listel) - (list symbol (nth 1 listel))) - valvarlist specifier-list) - ,@(mapcar* (lambda (symbol listel) - (list symbol (nth 2 listel))) - domvarlist specifier-list) - ,@(mapcar* (lambda (symbol specifier domain) - (list symbol `(specifier-spec-list - ,specifier ,domain))) - oldvarlist specvarlist domvarlist)) - (unwind-protect - (progn - ,@(mapcar* (lambda (specifier value domain) - `(add-spec-to-specifier - ,specifier ,value ,domain - nil 'prepend)) - specvarlist valvarlist domvarlist) - ,@body) - ,@(apply - #'nconc - ;; Reverse the unwinding order for marginal safety gain. - (nreverse - (mapcar* - (lambda (specifier domain oldvalue) - `((remove-specifier ,specifier ,domain) - (add-spec-list-to-specifier ,specifier ,oldvalue))) - specvarlist domvarlist oldvarlist))))))) +Example: + (let-specifier ((modeline-shadow-thickness 0 (selected-window))) + (sit-for 1))" + (check-argument-type 'listp specifier-list) + (flet ((gensym-frob (x name) + (if (or (atom x) (eq (car x) 'quote)) + (list x) + (list (gensym name) x)))) + ;; VARLIST is a list of + ;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE) + ;; (TAG-SET) (HOW-TO-ADD)) + ;; If any of these is an atom, then a separate symbol is + ;; unnecessary, the CAR will contain the atom and CDR will be nil. + (let* ((varlist (mapcar #'(lambda (listel) + (or (and (consp listel) + (<= (length listel) 5) + (> (length listel) 1)) + (signal 'error + (list + "should be a list of 2-5 elements" + listel))) + ;; VALUE, TAG-SET and HOW-TO-ADD are + ;; referenced only once, so we needn't + ;; frob them with gensym. + (list (gensym-frob (nth 0 listel) "specifier-") + (list (nth 1 listel)) + (gensym-frob (nth 2 listel) "locale-") + (list (nth 3 listel)) + (list (nth 4 listel)))) + specifier-list)) + ;; OLDVALLIST is a list of (OLDVALSYM OLDVALFORM) + (oldvallist (mapcar #'(lambda (varel) + (list (gensym "old-") + `(specifier-spec-list + ,(car (nth 0 varel)) + ,(car (nth 2 varel))))) + varlist))) + ;; Bind the appropriate variables. + `(let* (,@(mapcan #'(lambda (varel) + (delq nil (mapcar + #'(lambda (varcons) + (and (cdr varcons) varcons)) + varel))) + varlist) + ,@oldvallist) + (unwind-protect + (progn + ,@(mapcar #'(lambda (varel) + `(add-spec-to-specifier + ,(car (nth 0 varel)) ,(car (nth 1 varel)) + ,(car (nth 2 varel)) ,(car (nth 3 varel)) + ,(car (nth 4 varel)))) + varlist) + ,@body) + ;; Reverse the unwinding order, so that using the same + ;; specifier multiple times works. + ,@(apply #'nconc (nreverse (mapcar* + #'(lambda (oldval varel) + `((remove-specifier + ,(car (nth 0 varel)) + ,(car (nth 2 varel))) + (add-spec-list-to-specifier + ,(car (nth 0 varel)) + ,(car oldval)))) + oldvallist varlist)))))))) -;; (cl-prettyexpand '(let-specifier ((modeline-shadow-thickness 0 (selected-window)) (fubar 0 baz)) (sit-for 1))) +;; Evaluate this for testing: +; (cl-prettyexpand '(let-specifier ((modeline-shadow-thickness 0 (selected-window) 'x) (fubar (value) baz)) (sit-for 1))) (define-specifier-tag 'win 'device-on-window-system-p) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/startup.el --- a/lisp/startup.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/startup.el Mon Aug 13 10:36:47 2007 +0200 @@ -78,7 +78,7 @@ (defvar after-init-hook nil "*Functions to call after loading the init file (`.emacs'). The call is not protected by a condition-case, so you can set `debug-on-error' -in `init.el', and put all the actual code on `after-init-hook'.") +in `.emacs', and put all the actual code on `after-init-hook'.") (defvar term-setup-hook nil "*Functions to be called after loading terminal-specific Lisp code. @@ -110,8 +110,8 @@ originally logged in, or it may be a string containing a user's name. In either of the latter cases, `(concat \"~\" init-file-user \"/\")' -evaluates to the name of the directory where the `init.el' file was -looked for. +evaluates to the name of the directory in which the `.emacs' file was +searched for. Setting `init-file-user' does not prevent Emacs from loading `site-start.el'. The only way to do that is to use `--no-site-file'.") @@ -613,35 +613,36 @@ (setq term nil)))))) (defconst user-init-directory "/.xemacs/" - "Directory where user initialization and user-installed packages may go.") + "Directory where user-installed packages may go.") (define-obsolete-variable-alias 'emacs-user-extension-dir 'user-init-directory) (defun load-user-init-file (init-file-user) - "This function actually reads the init files. -First try .xemacs/init, then try .emacs, but only load one of the two." + "This function actually reads the init file, .emacs." (when init-file-user +;; purge references to init.el and options.el +;; convert these to use paths-construct-path for eventual migration to init.el +;; needs to be converted when idiom for constructing "~user" paths is created +; (setq user-init-file +; (paths-construct-path (list (concat "~" init-file-user) +; user-init-directory +; "init.el"))) +; (unless (file-exists-p (expand-file-name user-init-file)) (setq user-init-file - (cond - ((eq system-type 'ms-dos) - (concat "~" init-file-user user-init-directory "init.el")) - (t - (concat "~" init-file-user user-init-directory "init.el")))) - (unless (file-exists-p (expand-file-name user-init-file)) - (setq user-init-file - (cond - ((eq system-type 'ms-dos) - (concat "~" init-file-user "/_emacs")) - (t - (concat "~" init-file-user "/.emacs"))))) + (paths-construct-path (list (concat "~" init-file-user) + (cond + ((eq system-type 'ms-dos) "_emacs") + (t ".emacs"))))) +; ) (load user-init-file t t t) - (let ((default-custom-file (concat "~" - init-file-user - user-init-directory - "options.el"))) - (when (string= custom-file default-custom-file) - (load default-custom-file t t))) +;; This should not be loaded since custom stuff currently goes into .emacs +; (let ((default-custom-file +; (paths-construct-path (list (concat "~" init-file-user) +; user-init-directory +; "options.el"))) +; (when (string= custom-file default-custom-file) +; (load default-custom-file t t))) (unless inhibit-default-init (let ((inhibit-startup-message nil)) ;; Users are supposed to be told their rights. @@ -978,10 +979,14 @@ For tips and answers to frequently asked questions, see the XEmacs FAQ. \(It's on the Help menu, or type " (key xemacs-local-faq) " [a capital F!].\)")))) +(defvar xemacs-startup-logo-function nil + "If non-nil, function called to provide the startup logo. +This function should return an initialized glyph if it is used.") + (defun startup-splash-frame () (let ((p (point)) - (logo (cond ((featurep 'infodock) - (make-glyph (locate-data-file "altrasoft-slogo.xpm"))) + (logo (cond (xemacs-startup-logo-function + (funcall xemacs-startup-logo-function)) (t xemacs-logo))) (cramped-p (eq 'tty (console-type)))) (unless cramped-p (insert "\n")) diff -r 6e6992ccc4b6 -r c9fe270a4101 lisp/wid-edit.el --- a/lisp/wid-edit.el Mon Aug 13 10:35:55 2007 +0200 +++ b/lisp/wid-edit.el Mon Aug 13 10:36:47 2007 +0200 @@ -338,7 +338,26 @@ (set-extent-property extent 'button-or-field t) (set-extent-property extent 'keymap map) (set-extent-property extent 'face face) - (widget-handle-help-echo extent help-echo))) + (widget-handle-help-echo extent help-echo)) + (widget-specify-secret widget)) + +(defun widget-specify-secret (field) + "Replace text in FIELD with value of `:secret', if non-nil." + (let ((secret (widget-get field :secret)) + (size (widget-get field :size))) + (when secret + (let ((begin (widget-field-start field)) + (end (widget-field-end field))) + (when size + (while (and (> end begin) + (eq (char-after (1- end)) ?\ )) + (setq end (1- end)))) + (while (< begin end) + (let ((old (char-after begin))) + (unless (eq old secret) + (subst-char-in-region begin (1+ begin) old secret) + (put-text-property begin (1+ begin) 'secret old)) + (setq begin (1+ begin)))))))) (defun widget-specify-button (widget from to) "Specify button for WIDGET between FROM and TO." @@ -1481,8 +1500,7 @@ (when field (unless (eq field other) (debug "Change in different fields")) - (let ((size (widget-get field :size)) - (secret (widget-get field :secret))) + (let ((size (widget-get field :size))) (when size (let ((begin (widget-field-start field)) (end (widget-field-end field))) @@ -1504,19 +1522,7 @@ (while (and (eq (preceding-char) ?\ ) (> (point) begin)) (delete-backward-char 1))))))) - (when secret - (let ((begin (widget-field-start field)) - (end (widget-field-end field))) - (when size - (while (and (> end begin) - (eq (char-after (1- end)) ?\ )) - (setq end (1- end)))) - (while (< begin end) - (let ((old (char-after begin))) - (unless (eq old secret) - (subst-char-in-region begin (1+ begin) old secret) - (put-text-property begin (1+ begin) 'secret old)) - (incf begin)))))) + (widget-specify-secret field)) (widget-apply field :notify field))) (error (debug "After Change")))) diff -r 6e6992ccc4b6 -r c9fe270a4101 lwlib/xlwmenu.c --- a/lwlib/xlwmenu.c Mon Aug 13 10:35:55 2007 +0200 +++ b/lwlib/xlwmenu.c Mon Aug 13 10:36:47 2007 +0200 @@ -417,7 +417,8 @@ int drop; # endif #endif - char newchars[64]; + char* newchars; + int charslength; char *chars; int i, j; @@ -429,8 +430,10 @@ #else chars = string; #endif - - for (i = j = 0; chars[i] && (j < (int) sizeof (newchars)); i++) + charslength = strlen (chars); + newchars = (char *) alloca (charslength + 1); + + for (i = j = 0; chars[i] && (j < charslength); i++) if (chars[i]=='%'&&chars[i+1]=='_') i++; else diff -r 6e6992ccc4b6 -r c9fe270a4101 man/ChangeLog --- a/man/ChangeLog Mon Aug 13 10:35:55 2007 +0200 +++ b/man/ChangeLog Mon Aug 13 10:36:47 2007 +0200 @@ -1,3 +1,72 @@ +1998-06-10 Hrvoje Niksic + + * lispref/windows.texi (Resizing Windows): Document + `enlarge-window-pixels' and `shrink-window-pixels'. + + * lispref/positions.texi (Screen Lines): Update documentation of + `vertical-motion'. + (Screen Lines): Document `vertical-motion-pixels'. + + * lispref/frames.texi (Input Focus): Document `focus-frame', + `save-selected-frame' and `with-selected-frame'. + +1998-06-10 Hrvoje Niksic + + * lispref/searching.texi (Regexp Search): Document `split-path'. + + * lispref/files.texi (Unique File Names): Update docs for + `make-temp-name'; document `temp-directory'. + +1998-06-10 Hrvoje Niksic + + * lispref/os.texi (Recording Input): Update docs for `recent-keys'. + + * lispref/specifiers.texi (Specifier Instancing): Correct + instantiation order. + (Specifier Instancing Functions): Ditto. + +1998-06-11 Oliver Graf + + * lispref/lispref.texi: references to Drag'n'Drop fixed + * lispref/modes.texi: references to Drag'n'Drop fixed + * lispref/scrollbars.texi: references to Drag'n'Drop fixed + * lispref/dragndrop.texi: naming changed to Drag and Drop + added some docu about the drop procedure + +1998-06-09 Adrian Aichner + + * info-stnd.texi: added ../info/ to @setfilename. + * info.texi: added ../info/ to @setfilename. + * lispref/commands.texi: see ALL. + * lispref/frames.texi: see ALL. + * lispref/os.texi: see ALL. + * lispref/text.texi: see ALL. + * new-users-guide/custom1.texi: broke line after enumerated @item. + * new-users-guide/custom2.texi: see ALL. + * new-users-guide/edit.texi: see ALL. + * new-users-guide/enter.texi: see ALL. + * new-users-guide/files.texi: see ALL. + * new-users-guide/help.texi + * new-users-guide/modes.texi: see ALL. + * new-users-guide/new-users-guide.texi: see ALL. + * new-users-guide/region.texi: see ALL. + * new-users-guide/search.texi: see ALL. + * new-users-guide/xmenu.texi: see ALL. + * standards.texi: added ../info/ to @setfilename. + * texinfo.texi: added ../info/ to @setfilename, broke line after + @noindent. Changed @var{arg-not-used-by-@TeX{}} to + @var{arg-not-used-by-@@TeX{}} to make `texinfo-format-buffer' + happy. + * xemacs-faq.texi: added ../info/ to @setfilename. + * ALL: corrected INFO-FILE-NAME to lispref and xemacs in relevant + p?xefs (most were empty, some elisp and emacs), used + PRINTED-MANUAL-TITLE "XEmacs Lisp Reference Manual" and "XEmacs + User's Manual" respectively for all these. + +1998-06-01 Oliver Graf + + * lispref/dragndrop.texi: added experimental + 1998-05-28 Oliver Graf * lispref/dragndrop.texi: a warning, and a bit more text this time diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/commands.texi --- a/man/lispref/commands.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/commands.texi Mon Aug 13 10:36:47 2007 +0200 @@ -2298,7 +2298,7 @@ "Text deleted this way cannot be yanked back!\n") @end example - @xref{Disabling,,, emacs, The XEmacs Reference Manual}, for the details on + @xref{Disabling,,, xemacs, The XEmacs User's Manual}, for the details on what happens when a disabled command is invoked interactively. Disabling a command has no effect on calling it as a function from Lisp programs. @@ -2365,7 +2365,7 @@ There are a number of commands devoted to the editing and recall of previous commands. The commands @code{repeat-complex-command}, and @code{list-command-history} are described in the user manual -(@pxref{Repetition,,, emacs, The XEmacs Reference Manual}). Within the +(@pxref{Repetition,,, xemacs, The XEmacs User's Manual}). Within the minibuffer, the history commands used are the same ones available in any minibuffer. @@ -2419,4 +2419,4 @@ @c Broke paragraph to prevent overfull hbox. --rjc 15mar92 The commands are described in the user's manual (@pxref{Keyboard -Macros,,, xemacs, The XEmacs Reference Manual}). +Macros,,, xemacs, The XEmacs User's Manual}). diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/dragndrop.texi --- a/man/lispref/dragndrop.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/dragndrop.texi Mon Aug 13 10:36:47 2007 +0200 @@ -4,12 +4,12 @@ @c Original reference is (c) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. @c See the file lispref.texi for copying conditions. @setfilename ../../info/dragndrop.texi -@node Drag'n'Drop, Modes, Scrollbars, Top -@chapter Drag'n'Drop -@cindex drag'n'drop +@node Drag and Drop, Modes, Scrollbars, Top +@chapter Drag and Drop +@cindex drag and drop @emph{WARNING}: the Drag'n'Drop API is still under development and the -interface may change! +interface may change! The current implementation is considered experimental. Drag'n'drop is a way to transfer information between multiple applications. To do this serveral GUIs define their own protocols. Examples are OffiX, CDE, @@ -86,7 +86,7 @@ @subsection Loose ends The following protocols will be supported soon: Xdnd, Motif, Xde (if I -get some specs). +get some specs), KDE OffiX (if KDE can find XEmacs windows). In particular Xdnd will be one of the protocols that can benefit from the XEmacs API, cause it also uses MIME types to encode dragged data. @@ -101,8 +101,20 @@ misc-user-event. This misc-user-event has its function argument set to -dragdrop-drop-dispatch and the object contains the data of the drop -(converted to URL/MIME specific data). +@code{dragdrop-drop-dispatch} and the object contains the data of the drop +(converted to URL/MIME specific data). This function will search the variable +@code{experimental-dragdrop-drop-functions} for a function that can handle the +dropped data. + +To modify the drop behaviour, the user can modify the variable +@code{experimental-dragdrop-drop-functions}. Each element of this list +specifies a possible handler for dropped data. The first one that can handle +the data will return @code{t} and exit. Another possibility is to set a +extent-property with the same name. Extents are checked prior to the +variable. + +The customization group @code{drag-n-drop} shows all variables of user +interest. @node Drag Interface @section Drag Interface diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/files.texi --- a/man/lispref/files.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/files.texi Mon Aug 13 10:36:47 2007 +0200 @@ -1633,31 +1633,43 @@ construct a name for such a file: @example -(make-temp-name (concat "/tmp/" @var{name-of-application})) +(make-temp-name (expand-file-name @var{name-of-application} (temp-directory))) @end example @noindent -Here we use the directory @file{/tmp/} because that is the standard -place on Unix for temporary files. The job of @code{make-temp-name} is -to prevent two different users or two different processes from trying to -use the same name. +Here we use @code{(temp-directory)} to specify a directory for temporary +files---under Unix, it will normally evaluate to @file{"/tmp/"}. The +job of @code{make-temp-name} is to prevent two different users or two +different processes from trying to use the same name. -@defun make-temp-name string -This function generates a string that can be used as a unique name. The -name starts with @var{string}, and ends with a number that is different -in each XEmacs process. +@defun temp-directory +This function returns the name of the directory to use for temporary +files. Under Unix, this will be the value of @code{TMPDIR}, defaulting +to @file{/tmp}. On Windows, this will be obtained from the @code{TEMP} +or @code{TMP} environment variables, defaulting to @file{/}. + +Note that the @code{temp-directory} function does not exist under FSF +Emacs. +@end defun + +@defun make-temp-name prefix +This function generates a temporary file name starting with +@var{prefix}. The Emacs process number forms part of the result, so +there is no danger of generating a name being used by another process. @example @group (make-temp-name "/tmp/foo") - @result{} "/tmp/foo021304" + @result{} "/tmp/fooGaAQjC" @end group @end example -To prevent conflicts among different libraries running in the same -XEmacs, each Lisp program that uses @code{make-temp-name} should have its -own @var{string}. The number added to the end of the name distinguishes -between the same application running in different XEmacs processes. +In addition, this function makes an attempt to choose a name that does +not specify an existing file. To make this work, @var{prefix} should be +an absolute file name. + +To avoid confusion, each Lisp application should preferably use a unique +@var{prefix} to @code{make-temp-name}. @end defun @node File Name Completion diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/frames.texi --- a/man/lispref/frames.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/frames.texi Mon Aug 13 10:36:47 2007 +0200 @@ -139,7 +139,7 @@ the frame appear with the wrong ones and then change to the specified ones. If that bothers you, you can specify the same geometry and appearance with X resources; those do take affect before the frame is -created. @xref{Resources X,, X Resources, emacs, The XEmacs User's Manual}. +created. @xref{Resources X,, X Resources, xemacs, The XEmacs User's Manual}. X resource settings typically apply to all frames. If you want to specify some X resources solely for the sake of the initial frame, and @@ -170,7 +170,7 @@ If you use options that specify window appearance when you invoke XEmacs, they take effect by adding elements to @code{default-frame-plist}. One exception is @samp{-geometry}, which adds the specified position to -@code{initial-frame-plist} instead. @xref{Command Arguments,,, emacs, +@code{initial-frame-plist} instead. @xref{Command Arguments,,, xemacs, The XEmacs User's Manual}. @node X Frame Properties @@ -670,19 +670,39 @@ focus of the X server if any. The selection of @var{frame} lasts until the next time the user does something to select a different frame, or until the next time this function is called. -@end defun -Note that this does not actually cause the window-system focus to be set -to this frame, or the @code{select-frame-hook} or +Note that @code{select-frame} does not actually cause the window-system +focus to be set to this frame, or the @code{select-frame-hook} or @code{deselect-frame-hook} to be run, until the next time that XEmacs is waiting for an event. -Also note that when the variable @code{focus-follows-mouse} is non-nil, -the frame selection is temporary and is reverted when the current -command terminates, much like the buffer selected by @code{set-buffer}. -In order to effect a permanent focus change use @code{focus-frame}. +Also note that when the variable @code{focus-follows-mouse} is +non-@code{nil}, the frame selection is temporary and is reverted when +the current command terminates, much like the buffer selected by +@code{set-buffer}. In order to effect a permanent focus change use +@code{focus-frame}. +@end defun + +@defun focus-frame frame +This function selects @var{frame} and gives it the window system focus. +The operation of @code{focus-frame} is not affected by the value of +@code{focus-follows-mouse}. +@end defun -@ignore (FSF Emacs) +@defmac save-selected-frame forms@dots{} +This macro records the selected frame, executes @var{forms} in sequence, +then restores the earlier selected frame. The value returned is the +value of the last form. +@end defmac + +@defmac with-selected-frame frame forms@dots{} +This macro records the selected frame, then selects @var{frame} and +executes @var{forms} in sequence. After the last form is finished, the +earlier selected frame is restored. The value returned is the value of +the last form. +@end defmac + +@ignore (FSF Emacs, continued from defun select-frame) XEmacs cooperates with the X server and the window managers by arranging to select frames according to what the server and window manager ask for. It does so by generating a special kind of input event, called a diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/lispref.texi --- a/man/lispref/lispref.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/lispref.texi Mon Aug 13 10:36:47 2007 +0200 @@ -154,7 +154,7 @@ * Dialog Boxes:: Creating dialog boxes. * Toolbar:: Controlling the toolbar. * Scrollbars:: Controlling the scrollbars. -* Drag'n'Drop:: Generic API to inter-application communication +* Drag and Drop:: Generic API to inter-application communication via specific protocols. * Modes:: Defining major and minor modes. * Documentation:: Writing and using documentation strings. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/modes.texi --- a/man/lispref/modes.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/modes.texi Mon Aug 13 10:36:47 2007 +0200 @@ -3,7 +3,7 @@ @c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. @c See the file lispref.texi for copying conditions. @setfilename ../../info/modes.info -@node Modes, Documentation, Drag'n'Drop, Top +@node Modes, Documentation, Drag and Drop, Top @chapter Major and Minor Modes @cindex mode diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/os.texi --- a/man/lispref/os.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/os.texi Mon Aug 13 10:36:47 2007 +0200 @@ -168,7 +168,7 @@ switches @samp{-q} and @samp{-u} affect the use of the init file; @samp{-q} says not to load an init file, and @samp{-u} says to load a specified user's init file instead of yours. @xref{Entering XEmacs,,, -emacs, The XEmacs Reference Manual}. +xemacs, The XEmacs User's Manual}. @cindex default init file A site may have a @dfn{default init file}, which is the library named @@ -195,7 +195,7 @@ byte-compile it (@pxref{Byte Compilation}), and make your @file{.emacs} file load the other file using @code{load} (@pxref{Loading}). - @xref{Init File Examples,,, emacs, The XEmacs Reference Manual}, for + @xref{Init File Examples,,, xemacs, The XEmacs User's Manual}, for examples of how to make various commonly desired customizations in your @file{.emacs} file. @@ -363,8 +363,8 @@ The command line arguments are parsed by the @code{command-line-1} function in the @file{startup.el} file. See also @ref{Command -Switches, , Command Line Switches and Arguments, emacs, The XEmacs -Reference Manual}. +Switches, , Command Line Switches and Arguments, xemacs, The XEmacs +User's Manual}. @end defvar @defvar command-line-args @@ -1386,13 +1386,35 @@ @node Recording Input @subsection Recording Input -@defun recent-keys -This function returns a vector containing the last 100 input events -from the keyboard or mouse. All input events are included, whether or -not they were used as parts of key sequences. Thus, you always get the -last 100 inputs, not counting keyboard macros. (Events from keyboard -macros are excluded because they are less interesting for debugging; it -should be enough to see the events that invoked the macros.) +@defun recent-keys &optional number +This function returns a vector containing recent input events from the +keyboard or mouse. By default, 100 events are recorded, which is how +many @code{recent-keys} returns. + +All input events are included, whether or not they were used as parts of +key sequences. Thus, you always get the last 100 inputs, not counting +keyboard macros. (Events from keyboard macros are excluded because they +are less interesting for debugging; it should be enough to see the +events that invoked the macros.) + +If @var{number} is specified, not more than @var{number} events will be +returned. You may change the number of stored events using +@code{set-recent-keys-ring-size}. +@end defun + +@defun recent-keys-ring-size +This function returns the number of recent events stored internally. +This is also the maximum number of events @code{recent-keys} can +return. By default, 100 events are stored. +@end defun + +@defun set-recent-keys-ring-size size +This function changes the number of events stored by XEmacs and returned +by @code{recent-keys}. + +For example, @code{(set-recent-keys-ring-size 250)} will make XEmacs +remember last 250 events and will make @code{recent-keys} return last +250 events by default. @end defun @deffn Command open-dribble-file filename diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/positions.texi --- a/man/lispref/positions.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/positions.texi Mon Aug 13 10:36:47 2007 +0200 @@ -472,18 +472,24 @@ @defun vertical-motion count &optional window -This function moves point to the start of the screen line @var{count} -screen lines down from the screen line containing point. If @var{count} +This function moves point to the start of the frame line @var{count} +frame lines down from the frame line containing point. If @var{count} is negative, it moves up instead. @code{vertical-motion} returns the number of lines moved. The value may be less in absolute value than @var{count} if the beginning or end of the buffer was reached. -The window @var{window} is used for obtaining parameters such as the -width, the horizontal scrolling, and the display table. But -@code{vertical-motion} always operates on the current buffer, even if -@var{window} currently displays some other buffer. +Note that @code{vertical-motion} sets @var{window}'s buffer's point, not +@var{window}'s point. (This differs from FSF Emacs, which buggily always +sets current buffer's point, regardless of @var{window}.) +@end defun + +@defun vertical-motion-pixels count &optional window +This function is identical to @code{vertical-motion}, except that it +returns the vertical pixel height of the motino which took place, +instead of the actual number of lines moved. A motion of zero lines +returns the height of the current line. @end defun @deffn Command move-to-window-line count &optional window diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/scrollbars.texi --- a/man/lispref/scrollbars.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/scrollbars.texi Mon Aug 13 10:36:47 2007 +0200 @@ -3,7 +3,7 @@ @c Copyright (C) 1995 Ben Wing. @c See the file lispref.texi for copying conditions. @setfilename ../../info/glyphs.info -@node Scrollbars, Drag'n'Drop, Toolbar, top +@node Scrollbars, Drag and Drop, Toolbar, top @chapter scrollbars @cindex scrollbars diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/searching.texi --- a/man/lispref/searching.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/searching.texi Mon Aug 13 10:36:47 2007 +0200 @@ -786,6 +786,13 @@ @end example @end defun +@defun split-path path +This function splits a search path into a list of strings. The path +components are separated with the characters specified with +@code{path-separator}. Under Unix, @code{path-separator} will normally +be @samp{:}, while under Windows, it will be @samp{;}. +@end defun + @defun looking-at regexp This function determines whether the text in the current buffer directly following point matches the regular expression @var{regexp}. ``Directly diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/specifiers.texi --- a/man/lispref/specifiers.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/specifiers.texi Mon Aug 13 10:36:47 2007 +0200 @@ -141,7 +141,7 @@ this window?''. More specifically, a specifier contains a set of @dfn{specifications}, -each of which associates a @dfn{locale} (a buffer object, a window +each of which associates a @dfn{locale} (a window object, a buffer object, a frame object, a device object, or the symbol @code{global}) with an @dfn{inst-list}, which is a list of one or more @dfn{inst-pairs}. (For each possible locale, there can be at most one @@ -210,15 +210,15 @@ @itemize @bullet @item First, XEmacs searches for a specification whose locale is the same as -the window's buffer. If that fails, the search is repeated, looking for -a locale that is the same as the window itself. If that fails, the -search is repeated using the window's frame, then using the device that -frame is on. Finally, the specification whose locale is the symbol -@code{global} (if there is such a specification) is considered. +the window. If that fails, the search is repeated, looking for a locale +that is the same as the window's buffer. If that fails, the search is +repeated using the window's frame, then using the device that frame is +on. Finally, the specification whose locale is the symbol @code{global} +(if there is such a specification) is considered. @item The inst-pairs contained in the specification that was found are considered in their order in the inst-list, looking for one whose tag -set matches the device that is derived from the window domain. (The +set matches the device that is derived from the window domain. (The tag set is an unordered list of zero or more tag symbols. For all tags that have predicates associated with them, the predicate must match the device.) @@ -399,7 +399,7 @@ @defun add-spec-to-specifier specifier instantiator &optional locale tag-set how-to-add This function adds a specification to @var{specifier}. The -specification maps from @var{locale} (which should be a buffer, window, +specification maps from @var{locale} (which should be a window, buffer, frame, device, or the symbol @code{global}, and defaults to @code{global}) to @var{instantiator}, whose allowed values depend on the type of the specifier. Optional argument @var{tag-set} limits the @@ -453,7 +453,7 @@ @itemize @bullet @item -@var{locale} := a buffer, a window, a frame, a device, or @code{global} +@var{locale} := a window, a buffer, a frame, a device, or @code{global} @item @var{tag-set} := an unordered list of zero or more @var{tags}, each of which is a symbol @@ -478,6 +478,46 @@ more convenient and should be used instead. @end defun +@deffn Macro let-specifier specifier-list &rest body +This special form temporarily adds specifications to specifiers, +evaluates forms in @var{body} and restores the specifiers to their +previous states. The specifiers and their temporary specifications are +listed in @var{specifier-list}. + +The format of @var{specifier-list} is + +@example +((@var{specifier} @var{value} &optional @var{locale} @var{tag-set} @var{how-to-add}) ...) +@end example + +@var{specifier} is the specifier to be temporarily modified. +@var{value} is the instantiator to be temporarily added to specifier in +@var{locale}. @var{locale}, @var{tag-set} and @var{how-to-add} have the +same meaning as in @code{add-spec-to-specifier}. + +This special form is implemented as a macro; the code resulting from +macro expansion will add specifications to specifiers using +@code{add-spec-to-specifier}. After forms in @var{body} are evaluated, +the temporary specifications are removed and old specifier spec-lists +are restored. + +@var{locale}, @var{tag-set} and @var{how-to-add} may be omitted, and +default to @code{nil}. The value of the last form in @var{body} is +returned. + +NOTE: If you want the specifier's instance to change in all +circumstances, use @code{(selected-window)} as the @var{locale}. If +@var{locale} is @code{nil} or omitted, it defaults to @code{global}. + +The following example removes the 3D modeline effect in the currently +selected window for the duration of a second: + +@example +(let-specifier ((modeline-shadow-thickness 0 (selected-window))) + (sit-for 1)) +@end example +@end deffn + @defun set-specifier specifier value &optional how-to-add This function adds some specifications to @var{specifier}. @var{value} can be a single instantiator or tagged instantiator (added as a global @@ -582,12 +622,12 @@ This function returns the spec-list of specifications for @var{specifier} in @var{locale}. -If @var{locale} is a particular locale (a buffer, window, frame, device, +If @var{locale} is a particular locale (a window, buffer, frame, device, or the symbol @code{global}), a spec-list consisting of the specification for that locale will be returned. -If @var{locale} is a locale type (i.e. a symbol @code{buffer}, -@code{window}, @code{frame}, or @code{device}), a spec-list of the +If @var{locale} is a locale type (i.e. a symbol @code{window}, +@code{buffer}, @code{frame}, or @code{device}), a spec-list of the specifications for all locales of that type will be returned. If @var{locale} is @code{nil} or the symbol @code{all}, a spec-list of @@ -753,9 +793,9 @@ @enumerate @item -A specification whose locale is the window's buffer; +A specification whose locale is the window itself; @item -A specification whose locale is the window itself; +A specification whose locale is the window's buffer; @item A specification whose locale is the window's frame; @item diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/text.texi --- a/man/lispref/text.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/text.texi Mon Aug 13 10:36:47 2007 +0200 @@ -1132,7 +1132,7 @@ This command fills the paragraph at or after point. If @var{justify} is non-@code{nil}, each line is justified as well. It uses the ordinary paragraph motion commands to find paragraph -boundaries. @xref{Paragraphs,,, emacs, The XEmacs User's Manual}. +boundaries. @xref{Paragraphs,,, xemacs, The XEmacs User's Manual}. @end deffn @deffn Command fill-region start end &optional justify diff -r 6e6992ccc4b6 -r c9fe270a4101 man/lispref/windows.texi --- a/man/lispref/windows.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/lispref/windows.texi Mon Aug 13 10:36:47 2007 +0200 @@ -1661,6 +1661,14 @@ @end example @end deffn +@deffn Command enlarge-window-pixels count &optional side window +This function makes the selected window @var{count} pixels larger. When +called from Lisp, optional second argument @var{side} non-@code{nil} +means to grow sideways @var{count} pixels, and optional third argument +@var{window} specifies the window to change instead of the selected +window. +@end deffn + @deffn Command shrink-window size &optional horizontal This function is like @code{enlarge-window} but negates the argument @var{size}, making the selected window smaller by giving lines (or @@ -1683,6 +1691,14 @@ @end example @end deffn +@deffn Command shrink-window-pixels count &optional side window +This function makes the selected window @var{count} pixels smaller. +When called from Lisp, optional second argument @var{side} +non-@code{nil} means to shrink sideways @var{count} pixels, and optional +third argument @var{window} specifies the window to change instead of +the selected window. +@end deffn + @cindex minimum window size The following two variables constrain the window-size-changing functions to a minimum height and width. @@ -1705,6 +1721,7 @@ value below that is ignored. The default value is 10. @end defopt +@c This is not yet implemented. Why is it "documented"? @defvar window-size-change-functions This variable holds a list of functions to be called if the size of any window changes for any reason. The functions are called just once per diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/custom1.texi --- a/man/new-users-guide/custom1.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/custom1.texi Mon Aug 13 10:36:47 2007 +0200 @@ -19,7 +19,7 @@ the examples in this section, highlight that region and evaluate the region by giving the command @kbd{M-x eval-region}. You will be able to see the results of your customizations in that Emacs session only -(@pxref{Lisp Eval,,,,XEmacs User's Manual}). +(@pxref{Lisp Eval,,,xemacs,XEmacs User's Manual}). @comment node-name, next, previous, up @menu @@ -32,17 +32,18 @@ @cindex key bindings @cindex keystrokes - Most of Emacs commands use key sequences. @xref{Keystrokes,,,,XEmacs -Manual}, for more information about Keys and Commands. In Emacs, the -keys themselves carry no meaning unless they are bound to a -function. For example, @kbd{C-n} moves the cursor to the next line -because its bound to the function @b{next-line}. Similarly, @kbd{C-p} -moves to the previous line because its bound to the function -@b{previous-line}. The functions themselves define a particular -behavior. You can customize the key @kbd{C-n} to move to the previous -line by binding it to @b{previous-line} and @kbd{C-p} to move to the -next line by binding it to @b{next-line}. To bind keys to globally run -commands you need to use the following syntax in your @b{.emacs} file: + Most of Emacs commands use key +sequences. @xref{Keystrokes,,,xemacs,XEmacs User's Manual}, for more +information about Keys and Commands. In Emacs, the keys themselves carry +no meaning unless they are bound to a function. For example, @kbd{C-n} +moves the cursor to the next line because its bound to the function +@b{next-line}. Similarly, @kbd{C-p} moves to the previous line because +its bound to the function @b{previous-line}. The functions themselves +define a particular behavior. You can customize the key @kbd{C-n} to +move to the previous line by binding it to @b{previous-line} and +@kbd{C-p} to move to the next line by binding it to @b{next-line}. To +bind keys to globally run commands you need to use the following syntax +in your @b{.emacs} file: @cindex binding keys @example @@ -142,9 +143,9 @@ @findex make-symbolic-link @noindent Both the examples bind the key @kbd{C-xl} to run the function -@code{make-symbolic-link} (@pxref{Misc File Ops,,,,XEmacs User's +@code{make-symbolic-link} (@pxref{Misc File Ops,,,xemacs,XEmacs User's Manual}). However, the second example will bind the key only for C -mode. @xref{Major Modes,,,,XEmacs User's Manual}, for more +mode. @xref{Major Modes,,,xemacs,XEmacs User's Manual}, for more information on Major Modes in XEmacs. @@ -166,7 +167,8 @@ Some of the functions which are available to you for customization are: @enumerate -@item add-menu-item: @var{(menu-name item-name function enabled-p +@item +add-menu-item: @var{(menu-name item-name function enabled-p &optional before)} This function will add a menu item to a menu, creating the menu first if @@ -257,7 +259,8 @@ @findex delete-menu-item @cindex deleting menu items -@item delete-menu-item: @var{(menu-path)} +@item +delete-menu-item: @var{(menu-path)} This function will remove the menu item defined by @var{menu-name} from the menu hierarchy. Look at the following examples and the comments just above them which specify what the examples do. @@ -282,7 +285,8 @@ @findex disable-menu-item @cindex disabling menu items -@item disable-menu-item: @var{(menu-name)} +@item +disable-menu-item: @var{(menu-name)} Disables the specified menu item. The following example @example @@ -296,7 +300,8 @@ @findex enable-menu-item @cindex enabling menu items -@item enable-menu-item: @var{(menu-name)} +@item +enable-menu-item: @var{(menu-name)} Enables the specified previously disabled menu item. @example @@ -309,7 +314,8 @@ @findex relabel-menu-items @cindex relabelling menu items -@item relabel-menu-item: @var{(menu-name new-name)} +@item +relabel-menu-item: @var{(menu-name new-name)} Change the string of the menu item specified by @var{menu-name} to @var{new-name}. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/custom2.texi --- a/man/new-users-guide/custom2.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/custom2.texi Mon Aug 13 10:36:47 2007 +0200 @@ -194,7 +194,7 @@ local to a buffer and then to switch to its global value. You can also have a @dfn{local variables list} in a file which specifies the values to use for certain Emacs variables when you edit that -file. @xref{Variables,,,,XEmacs User's Manual}, for information on +file. @xref{Variables,,,xemacs,XEmacs User's Manual}, for information on these options. @@ -424,7 +424,7 @@ @end itemize For more information on initializing your @file{.emacs} file, -@xref{Init File,,,,XEmacs User's Manual}. You should also look at +@xref{Init File,,,xemacs,XEmacs User's Manual}. You should also look at @file{/usr/local/lib/xemacs-20.0/etc/sample.emacs}, which is a sample @file{.emacs} file. It contains some of the commonly desired customizations in Emacs. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/edit.texi --- a/man/new-users-guide/edit.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/edit.texi Mon Aug 13 10:36:47 2007 +0200 @@ -82,7 +82,7 @@ Emacs automatically splits lines when they become too long, if you turn on a special mode called @dfn{Auto Fill} mode. -@xref{Filling,,,,XEmacs User's Manual}, for information on using Auto Fill +@xref{Filling,,,xemacs,XEmacs User's Manual}, for information on using Auto Fill mode. @@ -262,8 +262,8 @@ @end example @noindent You can obviously use @kbd{C-b} to move backward rather than giving -negative arguments to @kbd{C-n}. @xref{Numeric Arguments,,,,XEmacs -Manual}, for more information on numeric arguments. +negative arguments to @kbd{C-n}. @xref{Numeric Arguments,,,xemacs,XEmacs +User's Manual}, for more information on numeric arguments. @comment node-name, next, previous, up @node Undo, , Numeric Argument, Edit @@ -287,7 +287,7 @@ keyboards so it might be better to use the above command. @end table - @xref{Undoing Changes,,,,XEmacs User's Manual}, for more information on + @xref{Undoing Changes,,,xemacs,XEmacs User's Manual}, for more information on undoing changes. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/enter.texi --- a/man/new-users-guide/enter.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/enter.texi Mon Aug 13 10:36:47 2007 +0200 @@ -12,7 +12,7 @@ A @b{buffer} is a region of memory holding characters. It is the basic editing unit; one buffer corresponds to one piece of text being edited. You can have multiple buffers but you can edit only one buffer -at any one time. For more information, @xref{Buffers,,,,XEmacs User's +at any one time. For more information, @xref{Buffers,,,xemacs,XEmacs User's Manual}. @item File @@ -71,7 +71,7 @@ corresponding key commands are displayed right besides them. The five default menus on the menubar that you will see on the frame are @b{File}, @b{Edit}, @b{Options}, @b{Buffers} and @b{Help}. @xref{XEmacs -Pull-down Menus,,,,XEmacs User's Manual}, for detailed information on +Pull-down Menus,,,xemacs,XEmacs User's Manual}, for detailed information on the functions provided by the pull-down menus. The Emacs frame has a rectangle shaped box at the extreme right and you can @@ -121,7 +121,7 @@ Suspend Emacs (@code{suspend-emacs}). If used under the X window system, this command will shrink the X window containing the Emacs frame to an icon. Clicking on the icon will resume that Emacs process -again. @xref{Exiting Emacs,,,,XEmacs User's Manual}. +again. @xref{Exiting Emacs,,,xemacs,XEmacs User's Manual}. @item C-x C-c Kill Emacs (@code{save-buffers-kill-emacs}). You can also select @@ -168,7 +168,7 @@ @var{buf} is the name of the window's chosen @dfn{buffer}. If you are editing a file (which is the selected buffer), the file name appears -in @var{buf}. @xref{Buffers,,,,XEmacs User's Manual}. +in @var{buf}. @xref{Buffers,,,xemacs,XEmacs User's Manual}. @var{pos} contains : @table @samp @@ -188,18 +188,18 @@ buffer. At any time, each buffer is in one and only one major mode. The available major modes include Fundamental mode (the least specialized), Text mode, Lisp mode, and C mode. @xref{Major -Modes,,,,XEmacs User's Manual}, for details on how the modes differ +Modes,,,xemacs,XEmacs User's Manual}, for details on how the modes differ and how you select one. @var{minor} is a list of some of the @dfn{minor modes} that are turned on in the window's chosen buffer. For example, @samp{Fill} means that Auto Fill mode is on which means that lines are broken -automatically when they become too wide. @xref{Minor Modes,,,,XEmacs -Reference Manual}, for more information on various minor modes and how -to enable them. +automatically when they become too wide. @xref{Minor +Modes,,,xemacs,XEmacs User's Manual}, for more information on various +minor modes and how to enable them. You can also display time in the mode line. @xref{The Mode -Line,,,,XEmacs User's Manual}, for more information regarding the +Line,,,xemacs,XEmacs User's Manual}, for more information regarding the mode line. @@ -241,7 +241,7 @@ @noindent This error message will be accompanied by a beep. Some XEmacs commands will print informative messages in the @dfn{echo area}. @xref{The Echo -Area,,,,XEmacs User's Manual}, for more information on the @dfn{echo +Area,,,xemacs,XEmacs User's Manual}, for more information on the @dfn{echo area}. @end itemize diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/files.texi --- a/man/new-users-guide/files.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/files.texi Mon Aug 13 10:36:47 2007 +0200 @@ -71,7 +71,7 @@ command. Similarly, you can also remove a directory by using the command @kbd{remove-directory}. The command @kbd{M-x pwd} will print the current buffer's default directory. For more information on file names, -@xref{File Names,,,,XEmacs User's Manual}. +@xref{File Names,,,xemacs,XEmacs User's Manual}. @node Visiting, Saving Files, File Names, Files @@ -197,7 +197,7 @@ You can also undo all the changes made since the file was visited or saved by reading the text from the file again (called @dfn{reverting}). For more information on this option, -@xref{Reverting,,,,XEmacs User's Manual}. +@xref{Reverting,,,xemacs,XEmacs User's Manual}. @vindex make-backup-files When you save a file in Emacs, it destroys its old contents. However, @@ -209,7 +209,7 @@ to @samp{t} (@pxref{Setting Variables}). The backup file will contain the contents from the last time you visited the file. Emacs also provides options for creating numbered backups. For more information on -backups, @xref{Backup,,,,XEmacs User's Manual}. +backups, @xref{Backup,,,xemacs,XEmacs User's Manual}. @cindex auto saving Emacs also saves all the files from time to time so that in case of a @@ -219,7 +219,7 @@ character @samp{#} in front and back. For example a file called "myfile.texinfo" would be named as @file{#myfile.texinfo#}. For information on controlling auto-saving and recovering data from -auto-saving, @xref{Auto Save Files,,,,XEmacs User's Manual}. +auto-saving, @xref{Auto Save Files,,,xemacs,XEmacs User's Manual}. @cindex simultaneous editing Emacs provides protection from simultaneous editing which occurs if @@ -228,7 +228,7 @@ modified. If any other user tries to modify that file, it will inform the user about the lock and provide some options. For more information on protection against simultaneous -editing, @xref{Interlocking,,,,XEmacs User's Manual}. +editing, @xref{Interlocking,,,xemacs,XEmacs User's Manual}. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/help.texi --- a/man/new-users-guide/help.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/help.texi Mon Aug 13 10:36:47 2007 +0200 @@ -171,8 +171,8 @@ @end table -For more information on the Help facility, @xref{Help,,,,XEmacs -Reference Manual}. +For more information on the Help facility, @xref{Help,,,xemacs,XEmacs +User's Manual}. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/modes.texi --- a/man/new-users-guide/modes.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/modes.texi Mon Aug 13 10:36:47 2007 +0200 @@ -66,15 +66,15 @@ @cindex nroff-mode Use this mode when you have to format a text with nroff before it can be available in readable form. It redefines some indentation -commands. @xref{Nroff Mode,,,,XEmacs User's Manual}, for information +commands. @xref{Nroff Mode,,,xemacs,XEmacs User's Manual}, for information on this mode. @item tex-mode @cindex tex-mode Use this mode if you are using the LaTeX text-formatter. It provides commands for insertion of quotes, braces and other characters. It also -allows you to format the buffer for printing. @xref{TeX Mode,,,,XEmacs -Manual}, for information on this mode. +allows you to format the buffer for printing. @xref{TeX +Mode,,,xemacs,XEmacs User's Manual}, for information on this mode. @item texinfo-mode @cindex texinfo-mode @@ -94,13 +94,13 @@ @cindex outline-mode Use this mode for editing outlines. When you enable this mode, you can make part of the text temporarily invisible so that you can see the -overall structure of the outline. @xref{Outline Mode,,,,XEmacs User's +overall structure of the outline. @xref{Outline Mode,,,xemacs,XEmacs User's Manual}, for information on this mode. @item c-mode @cindex c-mode Use this mode for C programs. It will redefine some indentation -commands. @xref{C Indent,,,,XEmacs User's Manual}. +commands. @xref{C Indent,,,xemacs,XEmacs User's Manual}. @item lisp-mode @cindex lisp-mode @@ -111,12 +111,12 @@ @cindex fortran-mode Use this mode for Fortran programs. This mode provides special commands to move around and some other indentation commands. For more -information on this mode, @xref{Fortran,,,,XEmacs User's Manual}. +information on this mode, @xref{Fortran,,,xemacs,XEmacs User's Manual}. @item edit-picture @cindex edit-picture This is the picture mode which you can use to create a picture out of -text characters. @xref{Picture,,,,XEmacs User's Manual}, for more +text characters. @xref{Picture,,,xemacs,XEmacs User's Manual}, for more information. @item asm-mode @@ -204,7 +204,7 @@ @b{Options} menu from the menu-bar. @item abbrev-mode -@cindex abbrev-modex +@cindex abbrev-mode After you enable this mode, you can define words which will expand into some different text i.e. you can define abbreviations. For example, you might define "expand" to "expand will eventually expand to this @@ -216,7 +216,7 @@ @end example @noindent - @xref{Abbrevs,,,,XEmacs User's Manual}, for more information on this + @xref{Abbrevs,,,xemacs,XEmacs User's Manual}, for more information on this mode and on defining abbreviations. @item auto-save-mode diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/new-users-guide.texi --- a/man/new-users-guide/new-users-guide.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/new-users-guide.texi Mon Aug 13 10:36:47 2007 +0200 @@ -202,12 +202,12 @@ XEmacs is a @dfn{display} editor because normally the text being edited is visible on the screen and is updated automatically as you -type. @xref{Frame,Display, , ,XEmacs User's Manual}. +type. @xref{Frame,Display,,xemacs,XEmacs User's Manual}. It is a @dfn{real-time} editor because the display is updated very frequently, usually after each character or pair of characters you type. This minimizes the amount of information you must keep in your head as -you edit. @xref{Basic,Real-time,Basic Editing, ,XEmacs User's +you edit. @xref{Basic,Real-time,Basic Editing,xemacs,XEmacs User's Manual}. It is advanced because it provides facilities that go beyond @@ -221,17 +221,17 @@ @dfn{Self-documenting} means that at any time you can type a special character, @kbd{Control-h}, to find out what your options are. You can also use @kbd{C-h} to find out what a command does, or to find all the -commands relevant to a topic. @xref{Help,,,,XEmacs User's Manual}. +commands relevant to a topic. @xref{Help,,,xemacs,XEmacs User's Manual}. @dfn{Customizable} means you can change the definitions of Emacs commands. For example, if you use a programming language in which comments start with @samp{<**} and end with @samp{**>}, you can tell the Emacs comment manipulation commands to use those strings -(@pxref{Comments,,,,XEmacs User's Manual}). Another sort of +(@pxref{Comments,,,xemacs,XEmacs User's Manual}). Another sort of customization is rearrangement of the command set. For example, you can set up the four basic cursor motion commands (up, down, left and right) on keys in a diamond pattern on the keyboard if you prefer. -@xref{Customization,,,,XEmacs User's Manual}. +@xref{Customization,,,xemacs,XEmacs User's Manual}. @dfn{Extensible} means you can go beyond simple customization and write entirely new commands, programs in the Lisp language to be run by diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/region.texi --- a/man/new-users-guide/region.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/region.texi Mon Aug 13 10:36:47 2007 +0200 @@ -66,7 +66,7 @@ @end table @noindent You can also give arguments to @kbd{C-<} or @kbd{C->}. @xref{The Mark -and the Region,,,,XEmacs User's Manual}, for more information. +and the Region,,,xemacs,XEmacs User's Manual}, for more information. @comment node-name, next, previous, up @node Mouse, Region Operation, Selecting Text, Select and Move @@ -82,7 +82,7 @@ whole line triple-click anywhere on the line with the left-mouse-button. You can also use the @b{Copy} item from the @b{Edit} menu on the menu-bar to select text. This kind of selection is called -@b{Clipboard} selection, @xref{X Clipboard Selection,,,,XEmacs User's +@b{Clipboard} selection, @xref{X Clipboard Selection,,,xemacs,XEmacs User's Manual}, for more information. To select an arbitrary region, follow these steps: @@ -100,7 +100,7 @@ @end enumerate The selected region of text is highlighted. - @xref{Selecting Text with the Mouse,,,,XEmacs User's Manual}, for + @xref{Selecting Text with the Mouse,,,xemacs,XEmacs User's Manual}, for more information regarding the Mouse and additional mouse operations. @comment node-name, next, previous, up @@ -122,23 +122,24 @@ type @kbd{C-SPC}. Then go to the end of the paragraph and type @kbd{C-w}. The entire paragraph will be deleted. You can also select the text with a mouse and type @kbd{C-w} to kill the entire -region. @xref{Killing,,,,XEmacs User's Manual}, for more information. +region. @xref{Killing,,,xemacs,XEmacs User's Manual}, for more information. @item -Save the text in a buffer or a file (@pxref{Accumulating Text,,,,XEmacs -Manual}). +Save the text in a buffer or a file (@pxref{Accumulating +Text,,,xemacs,XEmacs User's Manual}). @item You can convert the case of the text with @kbd{C-x C-l} or @kbd{C-x C-u} If you type @kbd{C-x C-u} the selected text will become all upper-case. If you type @kbd{C-x C-l} the selected text will become all lower-case. @item -Print hardcopy with @kbd{M-x print-region}. @xref{Hardcopy,,,,XEmacs -Manual}, for more information. This command will print a hardcopy of only -the selected text. +Print hardcopy with @kbd{M-x +print-region}. @xref{Hardcopy,,,xemacs,XEmacs User's Manual}, for more +information. This command will print a hardcopy of only the selected +text. @item Indent it with @kbd{C-x @key{TAB}} or @kbd{C-M-\} -@xref{Indentation,,,,XEmacs User's Manual}, for more information. +@xref{Indentation,,,xemacs,XEmacs User's Manual}, for more information. @end itemize @@ -224,11 +225,11 @@ @end table @noindent -@xref{Accumulating Text,,,,XEmacs User's Manual}, for more +@xref{Accumulating Text,,,xemacs,XEmacs User's Manual}, for more information regarding this topic. You can also use @dfn{rectangle commands} for operating on rectangular -areas of text. @xref{Rectangles,,,,XEmacs User's Manual}, for more +areas of text. @xref{Rectangles,,,xemacs,XEmacs User's Manual}, for more information regarding rectangle commands. Emacs also provides @dfn{registers} which serve as temporary storage for @@ -236,7 +237,7 @@ store @dfn{regions}, a @dfn{rectangle}, or a @dfn{mark} i.e. a cursor position. Whatever you store in register stays there until you store something else in that register. To find out about commands which -manipulate registers @xref{Registers,,,,XEmacs User's Manual}. +manipulate registers @xref{Registers,,,xemacs,XEmacs User's Manual}. diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/search.texi --- a/man/new-users-guide/search.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/search.texi Mon Aug 13 10:36:47 2007 +0200 @@ -72,7 +72,7 @@ @end table For information on how Emacs searches for words and regular -expressions, @xref{Search,,,,XEmacs User's Manual}. +expressions, @xref{Search,,,xemacs,XEmacs User's Manual}. To replace all occurrences of a string in Emacs, you can use the following command: @@ -102,8 +102,8 @@ @key{RET}. After all the occurrences are replaced you will see the message "Done" in the echo area. If you want only some occurrences of the string to be replaced, use @kbd{M-x query-replace RET RET - RET}. For more information, @xref{Query Replace,,,,XEmacs -Manual}. + RET}. For more information, @xref{Query +Replace,,,xemacs,XEmacs User's Manual}. XEmacs also provides a utility for checking spellings. Use @kbd{M-x ispell-buffer} to check for spellings in the whole buffer. You can also diff -r 6e6992ccc4b6 -r c9fe270a4101 man/new-users-guide/xmenu.texi --- a/man/new-users-guide/xmenu.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/new-users-guide/xmenu.texi Mon Aug 13 10:36:47 2007 +0200 @@ -89,20 +89,20 @@ @item C-x 4 f @var{filename} @key{RET} Visit file @var{filename} and select its buffer in another window. This -runs @code{find-file-other-window}. @xref{Visiting,,,,XEmacs +runs @code{find-file-other-window}. @xref{Visiting,,,xemacs,XEmacs User's Manual}. It will prompt you for a filename. @item C-x 4 d @var{directory} @key{RET} Select a Dired buffer for directory @var{directory} in another window. -This runs @code{dired-other-window}. @xref{Dired,,,,XEmacs User's +This runs @code{dired-other-window}. @xref{Dired,,,xemacs,XEmacs User's Manual}. @item C-x 4 m Start composing a mail message in another window. This runs @code{mail-other-window}, and its same-window version is @kbd{C-x m}. -@xref{Sending Mail,,,,XEmacs User's Manual}, for information on how +@xref{Sending Mail,,,xemacs,XEmacs User's Manual}, for information on how to @b{S}end @b{M}ail using XEmacs. @xref{Reading Mail With -Rmail,,,,XEmacs User's Manual}, for information on reading mail using +Rmail,,,xemacs,XEmacs User's Manual}, for information on reading mail using @b{Rmail}. @end table @@ -299,7 +299,7 @@ selection are not the same thing. You can paste in text you have placed in the clipboard using @b{Copy} or @b{Cut}. You can also use @b{Paste} to insert text that was pasted into the clipboard from other -applications. @xref{X Clipboard Selection,,,,XEmacs User's Manual}, +applications. @xref{X Clipboard Selection,,,xemacs,XEmacs User's Manual}, for information on using Clipboard Selection. @item Clear @@ -318,8 +318,8 @@ Selecting this item will cause emacs to re-interpret all of the keystrokes which were saved between selections of the @b{Start Macro Recording} and @b{End Macro Recording} menu items. You can now execute -the most recent keyboard macro. @xref{Keyboard Macros,,,,XEmacs -Reference Manual}, for further information. +the most recent keyboard macro. @xref{Keyboard Macros,,,xemacs,XEmacs +User's Manual}, for further information. @end table @comment node-name, next, previous, up @@ -375,18 +375,18 @@ @kbd{M-x} which has a shorter keybinding, you will be shown the alternate binding before the command executes. For example if you type @kbd{M-x find-file-other-window} which performs the same function as the -@b{Open in New Frame...} in @b{File} menu you will see the following +@b{Open in Other Window...} in @b{File} menu you will see the following message: @example -M-x find-file-other-frame (bound to keys: C-x 4 f, C-x 4 C-f) +M-x find-file-other-window (bound to keys: C-x 4 f, C-x 4 C-f) @end example @item Syntax Highlighting You can customize your @code{.emacs} file to include the font-lock mode so that when you select this item, the comments will be displayed in one face, strings in another, reserved words in another, and so -on. @xref{Customization,,,,XEmacs User's Manual}, for more +on. @xref{Customization,,,xemacs,XEmacs User's Manual}, for more information on customizing @code{.emacs} file. After selecting this item, you will find your code a lot easier to read. When @b{Fonts} is selected, different parts of the program will appear in different diff -r 6e6992ccc4b6 -r c9fe270a4101 man/standards.texi --- a/man/standards.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/standards.texi Mon Aug 13 10:36:47 2007 +0200 @@ -1,6 +1,6 @@ \input texinfo @c -*-texinfo-*- @c %**start of header -@setfilename standards.info +@setfilename ../info/standards.info @settitle GNU Coding Standards @c UPDATE THIS DATE WHENEVER YOU MAKE CHANGES! @set lastupdate 17 May 1996 diff -r 6e6992ccc4b6 -r c9fe270a4101 man/texinfo.tex --- a/man/texinfo.tex Mon Aug 13 10:35:55 2007 +0200 +++ b/man/texinfo.tex Mon Aug 13 10:36:47 2007 +0200 @@ -1,32 +1,40 @@ -%% TeX macros to handle Texinfo files. -%% $Id: texinfo.tex,v 1.4 1997/08/10 04:40:34 steve Exp $ - -% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, -% 94, 95, 96, 97 Free Software Foundation, Inc. - -%This texinfo.tex file 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 2, or (at -%your option) any later version. - -%This texinfo.tex file 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 this texinfo.tex file; see the file COPYING. If not, write -%to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -%Boston, MA 02111-1307, USA. - - -%In other words, you are welcome to use, share and improve this program. -%You are forbidden to forbid anyone else to use, share and improve -%what you give them. Help stamp out software-hoarding! - - -% Send bug reports to bug-texinfo@prep.ai.mit.edu. -% Please include a *precise* test case in each bug report. +% texinfo.tex -- TeX macros to handle Texinfo files. +% $Id: texinfo.tex,v 1.5 1998/06/13 04:28:12 steve Exp $ +% +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98 +% Free Software Foundation, Inc. +% +% This texinfo.tex file 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 2, or (at +% your option) any later version. +% +% This texinfo.tex file 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 this texinfo.tex file; see the file COPYING. If not, write +% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% ftp://ftp.cs.umb.edu/pub/tex/texinfo.tex +% /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% +% Send bug reports to bug-texinfo@gnu.org. +% Please include a precise test case in each bug report, +% including a complete document with which we can reproduce the problem. +% +% Texinfo macros (with @macro) are *not* supported by texinfo.tex. You +% have to run makeinfo -E to expand macros first; the texi2dvi script +% does this. % Make it possible to create a .fmt file just by loading this file: @@ -36,7 +44,7 @@ % This automatically updates the version number based on RCS. \def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}} -\deftexinfoversion$Revision: 1.4 $ +\deftexinfoversion$Revision: 1.5 $ \message{Loading texinfo package [Version \texinfoversion]:} % If in a .fmt file, print the version number @@ -54,7 +62,8 @@ \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end -\let\ptexequiv = \equiv +\let\ptexequiv=\equiv +\let\ptexexclam=\! \let\ptexi=\i \let\ptexlbrace=\{ \let\ptexrbrace=\} @@ -441,14 +450,11 @@ % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } -% @enddots{} is an end-of-sentence ellipsis. -\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000} - % @! is an end-of-sentence bang. -\gdef\!{!\spacefactor=3000 } +\def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. -\gdef\?{?\spacefactor=3000 } +\def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would @@ -573,9 +579,27 @@ \let\br = \par -% @dots{} output some dots - -\def\dots{$\ldots$} +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{\hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil +}} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + % @page forces the start of a new page @@ -1236,7 +1260,7 @@ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} -\def\titlefont#1{{\titlefonts #1}} +\def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc @@ -1263,6 +1287,10 @@ % \textfonts +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 @@ -1300,15 +1328,15 @@ \null } \let\ttfont=\t -\def\samp #1{`\tclose{#1}'\null} +\def\samp#1{`\tclose{#1}'\null} \setfont\smallrm\rmshape{8}{1000} \font\smallsy=cmsy9 \def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{% - \raise0.4pt\hbox{$\langle$}\kern-.08em\vtop{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt - \hbox{\raise0.4pt\hbox{\vphantom{$\langle$}}#1}}% + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% - \kern-.06em\raise0.4pt\hbox{$\rangle$}}}} + \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} @@ -1421,7 +1449,7 @@ % rms does not like the angle brackets --karl, 17may97. % So now @email is just like @uref. -%\def\email#1{$\langle${\tt #1}$\rangle$} +%\def\email#1{\angleleft{\tt #1}\angleright} \let\email=\uref % Check if we are currently using a typewriter font. Since all the @@ -2043,10 +2071,7 @@ % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. - -%%%% -% Dimensions - +% \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace @@ -2056,15 +2081,15 @@ \multitablecolspace=12pt \multitablelinespace=0pt -%%%% % Macros used to set up halign preamble: +% \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent -%% 2/1/96, to allow fractions to be given with more than one digit. +% 2/1/96, to allow fractions to be given with more than one digit. \def\pickupwholefraction#1 {\global\advance\colcount by1 % \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}% \setuptable} @@ -2090,80 +2115,84 @@ \ifx\go\pickupwholefraction\else\let\go\setuptable\fi% \fi\go} -%%%% % multitable syntax \def\tab{&\hskip1sp\relax} % 2/2/96 % tiny skip here makes sure this column space is % maintained, even if it is never used. - -%%%% % @multitable ... @end multitable definitions: \def\multitable{\parsearg\dotable} - \def\dotable#1{\bgroup -\let\item\cr -\tolerance=9500 -\hbadness=9500 -\setmultitablespacing -\parskip=\multitableparskip -\parindent=\multitableparindent -\overfullrule=0pt -\global\colcount=0\relax% -\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}% - % To parse everything between @multitable and @item : -\setuptable#1 \endsetuptable - % Need to reset this to 0 after \setuptable. -\global\colcount=0\relax% - % - % This preamble sets up a generic column definition, which will - % be used as many times as user calls for columns. - % \vtop will set a single line and will also let text wrap and - % continue for many paragraphs if desired. -\halign\bgroup&\global\advance\colcount by 1\relax% -\multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname - % In order to keep entries from bumping into each other - % we will add a \leftskip of \multitablecolspace to all columns after - % the first one. - % If a template has been used, we will add \multitablecolspace - % to the width of each template entry. - % If user has set preamble in terms of percent of \hsize - % we will use that dimension as the width of the column, and - % the \leftskip will keep entries from bumping into each other. - % Table will start at left margin and final column will justify at - % right margin. -\ifnum\colcount=1 -\else - \ifsetpercent + \vskip\parskip + \let\item\crcr + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% + % + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip \else - % If user has set preamble in terms of percent of \hsize - % we will advance \hsize by \multitablecolspace - \advance\hsize by \multitablecolspace + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace \fi - % In either case we will make \leftskip=\multitablecolspace: -\leftskip=\multitablecolspace -\fi - % Ignoring space at the beginning and end avoids an occasional spurious - % blank line, when TeX decides to break the line at the space before the - % box from the multistrut, so the strut ends up on a line by itself. - % For example: - % @multitable @columnfractions .11 .89 - % @item @code{#} - % @tab Legal holiday which is valid in major parts of the whole country. - % Is automatically provided with highlighting sequences respectively marking - % characters. - \noindent\ignorespaces##\unskip\multistrut}\cr - % \everycr will reset column counter, \colcount, at the end of - % each line. Every column entry will cause \colcount to advance by one. - % The table preamble - % looks at the current \colcount to find the correct column width. -\global\everycr{\noalign{% -% \filbreak%% keeps underfull box messages off when table breaks over pages. -% Maybe so, but it also creates really weird page breaks when the table -% breaks over pages Wouldn't \vfil be better? Wait until the problem -% manifests itself, so it can be fixed for real --karl. -\global\colcount=0\relax}} + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. @@ -2510,6 +2539,11 @@ \indexbreaks % % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, @@ -2531,7 +2565,6 @@ % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 - \catcode`\@ = 11 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s @@ -3427,11 +3460,12 @@ % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) -% -% \turnoffactive is for the sake of @" used for umlauts. \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks - \entry{\turnoffactive #1}{\turnoffactive #2}% + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, so characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. @@ -3497,30 +3531,35 @@ % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup -\catcode `\\=0 \catcode `\{=1 \catcode `\}=2 -\catcode `\$=3 \catcode `\&=4 \catcode `\#=6 -\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie -\catcode `\%=14 -\catcode 43=12 % plus -\catcode`\"=12 -\catcode`\==12 -\catcode`\|=12 -\catcode`\<=12 -\catcode`\>=12 -\escapechar=`\\ -% -\let\,=\ptexcomma -\let\{=\ptexlbrace -\let\}=\ptexrbrace -\let\.=\ptexdot -\let\*=\ptexstar -\let\dots=\ptexdots -\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% -\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% -\def\@{@}% -\let\bullet=\ptexbullet -\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext -% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie + \catcode `\%=14 + \catcode 43=12 % plus + \catcode`\"=12 + \catcode`\==12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\{=\ptexlbrace + \let\}=\ptexrbrace + \let\*=\ptexstar + \let\t=\ptext + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @endlisp. @@ -4373,7 +4412,7 @@ \def\refx#1#2{% \expandafter\ifx\csname X#1\endcsname\relax % If not defined, say something at least. - $\langle$un\-de\-fined$\rangle$% + \angleleft un\-de\-fined\angleright \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else @@ -4390,10 +4429,13 @@ } % This is the macro invoked by entries in the aux file. -\def\xrdef #1#2{{% - \catcode`\'=\other - \expandafter\gdef\csname X#1\endcsname{#2}% -}} +% +\def\xrdef#1{\begingroup + % Reenable \ as an escape while reading the second argument. + \catcode`\\ = 0 + \afterassignment\endgroup + \expandafter\gdef\csname X#1\endcsname +} % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup @@ -4617,7 +4659,7 @@ % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. -\openin 1 = xepsf.tex +\openin 1 = epsf.tex \ifeof 1 \else \closein 1 \def\epsfannounce{\toks0 = }% do not bother showing banner diff -r 6e6992ccc4b6 -r c9fe270a4101 man/texinfo.texi --- a/man/texinfo.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/texinfo.texi Mon Aug 13 10:36:47 2007 +0200 @@ -1,14 +1,15 @@ \input texinfo.tex @c -*-texinfo-*- -@c $Id: texinfo.texi,v 1.5 1997/08/10 04:40:35 steve Exp $ +@c $Id: texinfo.texi,v 1.6 1998/06/13 04:28:16 steve Exp $ @c %**start of header @c All text is ignored before the setfilename. @setfilename texinfo @settitle Texinfo @value{edition} -@set edition 2.24 -@set update-month July 1997 -@set update-date 25 @value{update-month} +@c Edition number is now the same as the Texinfo distribution version number. +@set edition 3.12 +@set update-month February 1998 +@set update-date 27 @value{update-month} @c Define a new index for options. @defcodeindex op @@ -44,17 +45,16 @@ @c @@clear smallbook @c Currently undocumented command, 5 December 1993: -@c @c nwnode (Same as node, but no warnings; for `makeinfo'.) @ifinfo This file documents Texinfo, a documentation system that can produce both on-line information and a printed manual from a single source file. -Copyright (C) 1988, 90, 91, 92, 93, 95, 96, 97 Free Software Foundation, Inc. - -This is the second edition of the Texinfo documentation,@* -and is consistent with version 2 of @file{texinfo.tex}. +Copyright (C) 1988, 90, 91, 92, 93, 95, 96, 97, 98 +Free Software Foundation, Inc. + +This edition is for Texinfo version @value{edition}. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -86,7 +86,7 @@ @c use the new format for titles @title Texinfo @subtitle The GNU Documentation Format -@subtitle Edition @value{edition}, for Texinfo Version Three +@subtitle for Texinfo version @value{edition} @subtitle @value{update-month} @author Robert J.@: Chassell @@ -97,22 +97,16 @@ @page @vskip 0pt plus 1filll -Copyright @copyright{} 1988, 90, 91, 92, 93, 95, 96, 97 +Copyright @copyright{} 1988, 90, 91, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc. -@sp 2 -This is the second edition of the Texinfo documentation,@* -and is consistent with version 2 of @file{texinfo.tex}. -@sp 2 - Published by the Free Software Foundation @* 59 Temple Place Suite 330 @* Boston, MA 02111-1307 @* USA @* -Printed copies are available for $15 each.@* -ISBN 1-882114-64-7 +ISBN 1-882114-65-5 @c ISBN 1-882114-63-9 is for edition 2.20 of 28 February 1995 -@c ISBN 1-882114-64-7 is for edition 2.23 of 1 October 1996. +@c ISBN 1-882114-64-7 is for edition 2.24 of November 1996. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -143,7 +137,7 @@ the menu lists all the lower level nodes in the document.@refill This is Edition @value{edition} of the Texinfo documentation, -@w{@value{update-date},} for Texinfo Version Three. +@w{@value{update-date}}. @end ifinfo @c Here is a spare copy of the chapter menu entry descriptions, @@ -1470,7 +1464,7 @@ @example @group @r{Internet address:} - bug-texinfo@@prep.ai.mit.edu + bug-texinfo@@gnu.org @end group @end example @@ -2205,7 +2199,7 @@ you must run the @code{texindex} command after first running the @code{tex} typesetting command; and then you must run the @code{tex} command again. Or else run the @code{texi2dvi} command which -automatically creates indices as needed.@refill +automatically creates indices as needed (@pxref{Format with texi2dvi}). Often, when you are writing a document, you want to typeset and print only part of a file to see what it will look like. You can use the @@ -6809,13 +6803,13 @@ For example: @example -Send bug reports to @@email@{bug-texinfo@@@@prep.ai.mit.edu@}. -Send suggestions to the @@email@{bug-texinfo@@@@prep.ai.mit.edu, same place@}. +Send bug reports to @@email@{bug-texinfo@@@@gnu.org@}. +Send suggestions to the @@email@{bug-texinfo@@@@gnu.org, same place@}. @end example @noindent produces @example -Send bug reports to @email{bug-texinfo@@prep.ai.mit.edu}. -Send suggestions to the @email{bug-texinfo@@prep.ai.mit.edu, same place}. +Send bug reports to @email{bug-texinfo@@gnu.org}. +Send suggestions to the @email{bug-texinfo@@gnu.org, same place}. @end example @@ -10677,13 +10671,6 @@ @code{@@deftypefun} creates an entry in the index of functions for @var{name}.@refill -@item @@deftypemethod @var{class} @var{data-type} @var{method-name} @var{arguments}@dots{} -@findex deftypefun -The @code{@@deftypemethod} command is the definition command for methods -in object-oriented typed languages, such as C++ and Java. It is similar -to the @code{@@deftypefn} with the addition of the @var{class} parameter -to specify the class containing the method. - @end table @@ -12071,25 +12058,28 @@ @code{texindex}. This is usually ok while you are debugging.@refill + @node Format with texi2dvi, Print with lpr, Format with tex/texindex, Format/Print Hardcopy @comment node-name, next, previous, up @section Format using @code{texi2dvi} @pindex texi2dvi @r{(shell script)} -The @code{texi2dvi} command is a shell script that automatically runs -both @code{tex} and @code{texindex} as many times as necessary to -produce a DVI file with up-to-date, sorted indices. It simplifies the +The @code{texi2dvi} command automatically runs both @code{tex} and +@code{texindex} as many times as necessary to produce a DVI file with +up-to-date, sorted indices. It simplifies the @code{tex}---@code{texindex}---@code{tex} sequence described in the previous section. -@need 1000 -The syntax for @code{texi2dvi} is like this (where @samp{prompt$} is the +The syntax for @code{texi2dvi} is like this (where @samp{prompt$} is your shell prompt):@refill @example prompt$ @kbd{texi2dvi @var{filename}@dots{}} @end example +For a list of options, run @samp{texi2dvi --help}. + + @node Print with lpr, Within Emacs, Format with texi2dvi, Format/Print Hardcopy @comment node-name, next, previous, up @section Shell Print Using @code{lpr -d} @@ -15213,7 +15203,7 @@ @example This file documents @dots{} -Copyright 1997 Free Software Foundation, Inc. +Copyright 1998 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and @@ -15473,7 +15463,7 @@ @group @@page @@vskip 0pt plus 1filll -Copyright @@copyright@{@} 1997 Free Software Foundation, Inc. +Copyright @@copyright@{@} 1998 Free Software Foundation, Inc. @@end titlepage @end group @@ -16686,19 +16676,20 @@ @cindex @TeX{}, how to obtain @c !!! Here is information about obtaining TeX. Update it whenever. -@c !!! Also consider updating TeX.README on prep. +@c !!! Also consider updating TeX.README on ftp.gnu.org. @c Updated by RJC on 1 March 1995, conversation with MacKay. @c Updated by kb@cs.umb.edu on 29 July 1996. @c Updated by kb@cs.umb.edu on 25 April 1997. +@c Updated by kb@cs.umb.edu on 27 February 1998. @TeX{} is freely redistributable. You can obtain @TeX{} for Unix systems via anonymous ftp or on physical media. The core material -consists of the Web2c @TeX{} distribution (@uref{http://www.tug.org/web2c}). +consists of the Web2c @TeX{} distribution (@uref{http://tug.org/web2c}). Instructions for retrieval by anonymous ftp and information on other available distributions: @example -@uref{ftp://ftp.tug.org/tex/unixtex.ftp} -@uref{http://www.tug.org/unixtex.ftp} +@uref{ftp://tug.org/tex/unixtex.ftp} +@uref{http://tug.org/unixtex.ftp} @end example The Free Software Foundation provides a core distribution on its Source @@ -16718,12 +16709,12 @@ 59 Temple Place Suite 330 Boston, MA @ @ 02111-1307 USA -Telephone: @w{@t{+}1--617--542--5942} -Fax: (including Japan) @w{@t{+}1--617--542--2652} +Telephone: @w{+1-617-542-5942} +Fax: (including Japan) @w{+1-617-542-2652} Free Dial Fax (in Japan): -@w{ } @w{ } @w{ } 0031--13--2473 (KDD) -@w{ } @w{ } @w{ } 0066--3382--0158 (IDC) -Electronic mail: @code{gnu@@prep.ai.mit.edu} +@w{ } @w{ } @w{ } 0031-13-2473 (KDD) +@w{ } @w{ } @w{ } 0066-3382-0158 (IDC) +Electronic mail: @code{gnu@@gnu.org} @end group @end display @end iftex @@ -16735,19 +16726,19 @@ Boston, MA @w{ } 02111-1307 USA -Telephone: @w{@t{+}1-617-542-5942} -Fax: (including Japan) @w{@t{+}1-617-542-2652} +Telephone: @w{+1-617-542-5942} +Fax: (including Japan) @w{+1-617-542-2652} Free Dial Fax (in Japan): @w{ } @w{ } @w{ } 0031-13-2473 (KDD) @w{ } @w{ } @w{ } 0066-3382-0158 (IDC) -Electronic mail: @code{gnu@@prep.ai.mit.edu} +Electronic mail: @code{gnu@@gnu.org} @end group @end display @end ifinfo @item To order a complete distribution on CD-ROM, please see -@uref{http://www.tug.org/tex-live.html}. (This distribution is also +@uref{http://tug.org/tex-live.html}. (This distribution is also available by FTP; see the URL's above.) @item @@ -16762,7 +16753,7 @@ University of Washington Seattle, WA @w{ } 98195 USA -Telephone: @t{+}1--206--543--2268 +Telephone: +1-206-543-2268 Electronic mail: @code{mackay@@cs.washington.edu} @end group @end display @@ -16775,7 +16766,7 @@ @end itemize Many other @TeX{} distributions are available; see -@uref{http://www.tug.org/}. +@uref{http://tug.org/}. @c These are no longer ``new'', and the explanations diff -r 6e6992ccc4b6 -r c9fe270a4101 man/xemacs-faq.texi --- a/man/xemacs-faq.texi Mon Aug 13 10:35:55 2007 +0200 +++ b/man/xemacs-faq.texi Mon Aug 13 10:36:47 2007 +0200 @@ -1,13 +1,13 @@ \input texinfo.tex @c -*-texinfo-*- @c %**start of header -@setfilename xemacs-faq.info +@setfilename ../info/xemacs-faq.info @settitle Frequently asked questions about XEmacs @setchapternewpage off @c %**end of header @finalout @titlepage @title XEmacs FAQ -@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 1998/05/10 00:25:35 $ +@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 1998/06/13 04:28:18 $ @sp 1 @author Tony Rossini @author Ben Wing @@ -1022,10 +1022,12 @@ Egg consists of following parts: @enumerate -@item Input character Translation System (ITS) layer. +@item +Input character Translation System (ITS) layer. It translates ASCII inputs to Kana/PinYin/Hangul characters. -@item Kana/PinYin/Hangul to Kanji transfer layer. +@item +Kana/PinYin/Hangul to Kanji transfer layer. It is interface layer for network Kana-Kanji server (Wnn and Sj3). @end enumerate diff -r 6e6992ccc4b6 -r c9fe270a4101 nt/ChangeLog --- a/nt/ChangeLog Mon Aug 13 10:35:55 2007 +0200 +++ b/nt/ChangeLog Mon Aug 13 10:36:47 2007 +0200 @@ -1,3 +1,17 @@ +1998-06-08 Kirill M. Katsnelson + + * config.h: Undefined DONT_ENCAPSULATE. + Defined ENCAPSULATE_* for fopem, open, rename and mkdir. + Removed MS-DOS code remains. + +1998-06-03 Rick Rankin + + * Makefile.cygwin: created to compile runemacs.c. This should + probably have a Makefile.in, but... + + * runemacs.c: modified to check to see if xemacs is a symbolic + link when compiled under Cygwin. + 1998-05-31 Kirill M. Katsnelson * xemacs.mak: Added lib-src/wakeup.exe diff -r 6e6992ccc4b6 -r c9fe270a4101 nt/Makefile.cygwin --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nt/Makefile.cygwin Mon Aug 13 10:36:47 2007 +0200 @@ -0,0 +1,15 @@ +MSW_LIBS =-luser32 -lgdi32 -lcomdlg32 +LDFLAGS =-Wl,--subsystem,windows +CFLAGS =-g + +bindir =/usr/local/bin + +INSTALL = /usr/local/src/xemacs-21.0-b42/lib-src/installexe.sh /d/cygnus/h-i386-cygwin32/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +runemacs.exe: runemacs.o + $(CC) $(LDFLAGS) runemacs.o $(MSW_LIBS) -o $@ + +install: runemacs.exe + $(INSTALL_PROGRAM) runemacs.exe $(bindir) diff -r 6e6992ccc4b6 -r c9fe270a4101 nt/config.h --- a/nt/config.h Mon Aug 13 10:35:55 2007 +0200 +++ b/nt/config.h Mon Aug 13 10:36:47 2007 +0200 @@ -547,65 +547,14 @@ circumstances; this can be used to make sure things compile OK on various systems. */ #undef DEBUG_ENCAPSULATION -#define DONT_ENCAPSULATE - -/* basic system calls */ - -#if defined (INTERRUPTIBLE_IO) || defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_READ -# define ENCAPSULATE_WRITE -#endif -#if defined (INTERRUPTIBLE_OPEN) || defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_OPEN -#endif -#if defined (INTERRUPTIBLE_CLOSE) || defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_CLOSE -#endif - -/* stdio calls */ - -#if defined (INTERRUPTIBLE_IO) || defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_FREAD -# define ENCAPSULATE_FWRITE -#endif -#if defined (INTERRUPTIBLE_OPEN) || defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_FOPEN -#endif -#if defined (INTERRUPTIBLE_CLOSE) || defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_FCLOSE -#endif - -/* directory calls */ -#if defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_CHDIR -# define ENCAPSULATE_MKDIR -# define ENCAPSULATE_OPENDIR -# define ENCAPSULATE_READDIR -# define ENCAPSULATE_RMDIR -#endif - -/* file-information calls */ +/* System calls that are encapsulated */ +#define ENCAPSULATE_RENAME +#define ENCAPSULATE_OPEN +#define ENCAPSULATE_FOPEN +#define ENCAPSULATE_MKDIR -#if defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_ACCESS -# define ENCAPSULATE_LSTAT -# define ENCAPSULATE_READLINK -# define ENCAPSULATE_STAT -#endif - -/* file-manipulation calls */ - -#if defined (DEBUG_ENCAPSULATION) -# define ENCAPSULATE_CHMOD -# define ENCAPSULATE_CREAT -# define ENCAPSULATE_LINK -# define ENCAPSULATE_RENAME -# define ENCAPSULATE_SYMLINK -# define ENCAPSULATE_UNLINK -#endif - -#if (defined (MSDOS) && defined (FEPCTRL)) || (defined (WIN32) && defined (USE_IME)) +#if defined (WIN32) && defined (USE_IME) #define HAVE_FEP #endif diff -r 6e6992ccc4b6 -r c9fe270a4101 nt/runemacs.c --- a/nt/runemacs.c Mon Aug 13 10:35:55 2007 +0200 +++ b/nt/runemacs.c Mon Aug 13 10:36:47 2007 +0200 @@ -26,6 +26,11 @@ #include #include +#if defined(__CYGWIN32__) +#include +#include +#endif + int WINAPI WinMain (HINSTANCE hSelf, HINSTANCE hPrev, LPSTR cmdline, int nShow) { @@ -79,8 +84,44 @@ strcat (p, " "); } #else +#if defined(__CYGWIN32__) + { + struct stat stbuf; + char sym_link_name[MAX_PATH+1], real_name[MAX_PATH+1]; + + strcpy(sym_link_name, new_cmdline); + strcat(sym_link_name, "\\xemacs"); + if (lstat(sym_link_name, &stbuf) == 0) + { + if ((stbuf.st_mode & S_IFLNK) == S_IFLNK) + { + if (readlink(sym_link_name, real_name, sizeof(real_name)) == -1) + { + MessageBox (NULL, "Error reading symbolic link for xemacs", + "Error", MB_ICONSTOP); + return 1; + } + else + { + strcat(new_cmdline, "\\"); + strcat(new_cmdline, real_name); + strcat(new_cmdline, " "); + } + } + else + strcat(new_cmdline, "\\xemacs "); + } + else + { + MessageBox (NULL, "can't locate XEmacs executable", + "Error", MB_ICONSTOP); + return 1; + } + } +#else strcat (new_cmdline, "\\xemacs.exe "); #endif +#endif /* Append original arguments if any; first look for -wait as first argument, and apply that ourselves. */ diff -r 6e6992ccc4b6 -r c9fe270a4101 src/ChangeLog --- a/src/ChangeLog Mon Aug 13 10:35:55 2007 +0200 +++ b/src/ChangeLog Mon Aug 13 10:36:47 2007 +0200 @@ -1,3 +1,134 @@ +1998-06-10 Samuel Mikes + + * fileio.c (directory-sep-char): Escape backslashes. + +1998-06-10 Hrvoje Niksic + + * event-stream.c: Fix docstring reference. + +1998-06-12 Hrvoje Niksic + + * alloc.c (make_float): Remove useless initialization of `next' + field. + (make_pure_float): Ditto. + + * lisp.h (struct Lisp_Float): Rename `next' to `__unused__next'. + +1998-06-08 Kirill M. Katsnelson + + * fileio.c (Fmake_directory_internal): Remove conditionals + on WINDOWSNT when calling mkdir. + + * ntproc.c: Deleted the following unused functions: + register_child, reap_subprocess, sys_wait. + + * nt.c (sys_rename): Ifzeroed this implementation. + Deleted the following unused functions: + sys_access, sys_chdir, sys_chmod, sys_creat, sys_link, sys_mkdir, + sys_mktemp, sys_rmdir, sys_unlink, sys_close, sys_dup, sys_dup2, + sys_read, sys_write. + Merger sys_fopen and sys_open with sysdep.c implementation. + + * sysdep.c: Removed MS-DOS code. + (sys_rename): Deal with Microsoft rename weirdness. + (sys_open): Implemented for Windows. + (sys_fopen): Ditto. + (sys_mkdir): Ditto. + +1998-06-08 Kirill M. Katsnelson + + * buffer.c (complex_vars_of_buffer): Removed %t description from + the docstring. + +1998-06-04 Rick Rankin + + * scrollbar-msw.c: initialize the cbSize element of the + SCROLLINFO struct before calling SetScrollInfo. WinNT seems + to ignore the value of cbSize, but Win95 (and I presume Win98) + appear to want it set to sizeof(SCROLLINFO). + +1998-06-04 Kirill M. Katsnelson + + * event-stream.c: Defined Qcancel_mode_internal. + (syms_of_event_stream): defsymbol'ed it. + + * events.h: Externed it. + + * event-msw.c (mswindows_wnd_proc, WM_CANCELMODE): Added this handler. + +1998-06-04 Oliver Graf + + * frame-x.c (x_cde_destroy_callback): free the data + (cde-start-drag-internal) corrected root position, 21.1 needs this + hardcoded in Button events + (offix-start-drag-internal) corrected root position + +1998-06-03 Kirill M. Katsnelson + + * process-nt.c (signal_cannot_launch): Use signal_simple_error() + instead of error(). + +1998-06-03 Kirill M. Katsnelson + + * dialog-msw.c (button_width): Removed `inline' from the function + declaration. + +1998-06-03 Rick Rankin + + * frame-msw.c: add WS_VISIBLE flag to the first frame created. + Note that adding this flag to subsequent frames causes problems. + +1998-06-03 Gunnar Evermann + + * glyphs-eimage.c (png_instantiate) move 'struct + png_memory_storage tbr' out of nested block to avoid dangling + reference + +1998-06-02 Andy Piper + + * faces.h: + * faces.c: rename 3d-object -> gui-element. add toolbar face which + inherits from gui-element. + + * glyphs-msw.c: use DIBitmaps for xbm bitmaps to be consistent + with existing code, generate masks correctly. + +1998-06-03 P. E. Jareth Hein + + * glyphs-eimage.c: Changed included header for gifs to use + Gifreader instead of giflib. + + * glyphs-x.c: removed the image-related functions that were + moved into glyphs-eimage. + +1998-06-02 David Bush + + * glyphs.c (bitmap_to_lisp_data) Define XFree to be free + if built without X Windows support. + +1998-06-02 Hrvoje Niksic + + * fns.c (Fconcat): Synch docstring with new reality. + +1998-06-03 SL Baur + + * frame.c: Remove reference to msdos.h (which is going away). + Suggested by Hrvoje Niksic and Kirill Katsnelson. + +1998-06-02 P. E. Jareth Hein + + * glyphs-eimage.c (jpeg_instantiate): Fix handling of + grayscale images/ + + +1998-05-30 Kirill M. Katsnelson + + * events.h: Fixed commentary about misc-user scrollbar events. + + * scrollbar-x.c (x_update_vertical_scrollbar_callback): Use frame + object as an event channel, instead of window object. + (x_update_horizontal_scrollbar_callback): Ditto. + 1998-05-29 Andy Piper * ntplay.c (play_sound_data_1) new function. convert alloca data @@ -208,6 +339,17 @@ (x_cde_convert_callback) made the thing working (cde-start-drag-internal) also debugging +1998-05-25 Hans Guenter Weigand + + * m/sparc.h: + * getloadavg.c: + * malloc.c: + * unexec.c: + * mem-limits.h: + - add __OpenBSD__ where __NetBSD__ was found. + - TODO: replace platform-specific conditional compilation by + feature tests in configure.in. + 1998-05-15 Greg Klanderman * window.c (Fwindow_displayed_text_pixel_height): New function. diff -r 6e6992ccc4b6 -r c9fe270a4101 src/alloc.c --- a/src/alloc.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/alloc.c Mon Aug 13 10:36:47 2007 +0200 @@ -1270,7 +1270,6 @@ ALLOCATE_FIXED_TYPE (float, struct Lisp_Float, f); set_lheader_implementation (&(f->lheader), lrecord_float); - float_next (f) = ((struct Lisp_Float *) -1); float_data (f) = float_value; XSETFLOAT (val, f); return val; @@ -2748,7 +2747,6 @@ pure_bytes_used += sizeof (struct Lisp_Float); bump_purestat (&purestat_float, sizeof (struct Lisp_Float)); - float_next (f) = ((struct Lisp_Float *) -1); float_data (f) = num; XSETFLOAT (val, f); return val; diff -r 6e6992ccc4b6 -r c9fe270a4101 src/buffer.c --- a/src/buffer.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/buffer.c Mon Aug 13 10:36:47 2007 +0200 @@ -2347,7 +2347,6 @@ %P -- print percent of buffer above bottom of window, perhaps plus Top, or print Bottom or All. %n -- print Narrow if appropriate. - %t -- Under MS-DOS, print T if files is text, B if binary. %C -- under XEmacs/mule, print the mnemonic for `buffer-file-coding-system'. %[ -- print one [ for each recursive editing level. %] similar. %% -- print %. %- -- print infinitely many dashes. diff -r 6e6992ccc4b6 -r c9fe270a4101 src/depend --- a/src/depend Mon Aug 13 10:35:55 2007 +0200 +++ b/src/depend Mon Aug 13 10:36:47 2007 +0200 @@ -110,7 +110,7 @@ fns.o: $(LISP_H) buffer.h bufslots.h bytecode.h commands.h conslots.h console.h device.h events.h extents.h frame.h frameslots.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h scrollbar.h specifier.h symeval.h symsinit.h systime.h toolbar.h font-lock.o: $(LISP_H) buffer.h bufslots.h chartab.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h symeval.h symsinit.h syntax.h frame-tty.o: $(LISP_H) conslots.h console-tty.h console.h device.h events.h frame.h frameslots.h lisp-disunion.h lisp-union.h lrecord.h scrollbar.h specifier.h symeval.h symsinit.h syssignal.h systime.h systty.h toolbar.h -frame.o: $(LISP_H) buffer.h bufslots.h conslots.h console.h device.h events.h extents.h faces.h frame.h frameslots.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h menubar.h msdos.h mule-charset.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h sysdep.h systime.h toolbar.h window.h winslots.h +frame.o: $(LISP_H) buffer.h bufslots.h conslots.h console.h device.h events.h extents.h faces.h frame.h frameslots.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h menubar.h mule-charset.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h sysdep.h systime.h toolbar.h window.h winslots.h free-hook.o: $(LISP_H) hash.h lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h general.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h getloadavg.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h sysfile.h @@ -140,11 +140,10 @@ md5.o: $(LISP_H) buffer.h bufslots.h file-coding.h lisp-disunion.h lisp-union.h lrecord.h lstream.h mule-charset.h symeval.h symsinit.h menubar.o: $(LISP_H) buffer.h bufslots.h conslots.h console.h device.h frame.h frameslots.h gui.h lisp-disunion.h lisp-union.h lrecord.h menubar.h mule-charset.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h minibuf.o: $(LISP_H) buffer.h bufslots.h commands.h conslots.h console-stream.h console.h device.h events.h frame.h frameslots.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h systime.h toolbar.h window.h winslots.h -msdos.o: $(LISP_H) conslots.h console.h device.h frame.h frameslots.h lisp-disunion.h lisp-union.h lrecord.h msdos.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h systime.h toolbar.h window.h winslots.h nas.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h syssignal.h nt.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h nt.h ntheap.h symeval.h symsinit.h sysproc.h syssignal.h systime.h ntheap.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h ntheap.h symeval.h symsinit.h -ntplay.o: config.h +ntplay.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h sysfile.h ntproc.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h nt.h ntheap.h process.h symeval.h symsinit.h sysproc.h syssignal.h systime.h syswait.h objects-tty.o: $(LISP_H) conslots.h console-tty.h console.h device.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects-tty.h objects.h specifier.h symeval.h symsinit.h syssignal.h systty.h objects.o: $(LISP_H) buffer.h bufslots.h conslots.h console.h device.h elhash.h faces.h frame.h frameslots.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h diff -r 6e6992ccc4b6 -r c9fe270a4101 src/dialog-msw.c --- a/src/dialog-msw.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/dialog-msw.c Mon Aug 13 10:36:47 2007 +0200 @@ -174,7 +174,7 @@ } /* Given button TEXT, return button width in DLU */ -static inline unsigned int +static unsigned int button_width (Lisp_Object text) { unsigned int width = X_DLU_PER_CHAR * XSTRING_CHAR_LENGTH (text); diff -r 6e6992ccc4b6 -r c9fe270a4101 src/event-msw.c --- a/src/event-msw.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/event-msw.c Mon Aug 13 10:36:47 2007 +0200 @@ -1824,6 +1824,14 @@ } break; + case WM_CANCELMODE: + ReleaseCapture (); + /* Queue a `cancel-mode-internal' misc user event, so mouse + selection would be canceled if any */ + mswindows_enqueue_misc_user_event (mswindows_find_frame (hwnd), + Qcancel_mode_internal, Qnil); + break; + #ifdef HAVE_TOOLBARS case WM_NOTIFY: { diff -r 6e6992ccc4b6 -r c9fe270a4101 src/event-stream.c --- a/src/event-stream.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/event-stream.c Mon Aug 13 10:36:47 2007 +0200 @@ -157,6 +157,9 @@ Lisp_Object Vcurrent_mouse_event; +/* This is fbound in cmdloop.el, see the commentary there */ +Lisp_Object Qcancel_mode_internal; + /* If not Qnil, event objects to be read as the next command input */ Lisp_Object Vunread_command_events; Lisp_Object Vunread_command_event; /* obsoleteness support */ @@ -3864,7 +3867,7 @@ DEFUN ("recent-keys", Frecent_keys, 0, 1, 0, /* Return a vector of recent keyboard or mouse button events read. If NUMBER is non-nil, not more than NUMBER events will be returned. -Change number of events stored using `set-recent-keys-size'. +Change number of events stored using `set-recent-keys-ring-size'. This copies the event objects into a new vector; it is safe to keep and modify them. @@ -4959,6 +4962,8 @@ defsymbol (&Qmenu_right, "menu-right"); defsymbol (&Qmenu_select, "menu-select"); defsymbol (&Qmenu_escape, "menu-escape"); + + defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); } void diff -r 6e6992ccc4b6 -r c9fe270a4101 src/events.h --- a/src/events.h Mon Aug 13 10:35:55 2007 +0200 +++ b/src/events.h Mon Aug 13 10:36:47 2007 +0200 @@ -508,6 +508,7 @@ extern Lisp_Object QKbackspace, QKdelete, QKescape, QKlinefeed, QKreturn; extern Lisp_Object QKspace, QKtab, Qmouse_event_p, Vcharacter_set_property; +extern Lisp_Object Qcancel_mode_internal; /* Note: under X Windows, MOD_ALT is generated by the Alt key if there are both Alt and Meta keys. If there are no Meta keys, then Alt generates diff -r 6e6992ccc4b6 -r c9fe270a4101 src/faces.c --- a/src/faces.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/faces.c Mon Aug 13 10:36:47 2007 +0200 @@ -54,13 +54,12 @@ /* These faces are used directly internally. We use these variables to be able to reference them directly and save the overhead of calling Ffind_face. */ -Lisp_Object Vdefault_face, Vmodeline_face, V3d_object_face; +Lisp_Object Vdefault_face, Vmodeline_face, Vgui_element_face; Lisp_Object Vleft_margin_face, Vright_margin_face, Vtext_cursor_face; -Lisp_Object Vpointer_face; -Lisp_Object Vvertical_divider_face; +Lisp_Object Vpointer_face, Vvertical_divider_face, Vtoolbar_face; /* Qdefault, Qhighlight defined in general.c */ -Lisp_Object Qmodeline, Q3d_object, Qleft_margin, Qright_margin, Qtext_cursor; +Lisp_Object Qmodeline, Qgui_element, Qleft_margin, Qright_margin, Qtext_cursor; Lisp_Object Qvertical_divider; /* In the old implementation Vface_list was a list of the face names, @@ -1752,7 +1751,7 @@ { /* Qdefault defined in general.c */ defsymbol (&Qmodeline, "modeline"); - defsymbol (&Q3d_object, "3d-object"); + defsymbol (&Qgui_element, "gui-element"); defsymbol (&Qleft_margin, "left-margin"); defsymbol (&Qright_margin, "right-margin"); defsymbol (&Qtext_cursor, "text-cursor"); @@ -1805,10 +1804,12 @@ staticpro (&Vdefault_face); Vdefault_face = Qnil; - staticpro (&V3d_object_face); - V3d_object_face = Qnil; + staticpro (&Vgui_element_face); + Vgui_element_face = Qnil; staticpro (&Vmodeline_face); Vmodeline_face = Qnil; + staticpro (&Vtoolbar_face); + Vtoolbar_face = Qnil; staticpro (&Vvertical_divider_face); Vvertical_divider_face = Qnil; @@ -1936,39 +1937,54 @@ list1 (Fcons (Qnil, Qnil))); set_specifier_fallback (Fget (Vdefault_face, Qreverse, Qnil), list1 (Fcons (Qnil, Qnil))); - - /* mustn't inherit bg pixmaps from the default face */ - V3d_object_face = Fmake_face (Q3d_object, build_string ("3d object face"), - Qnil); + + /* gui-element is the parent face of all gui elements such as + modeline, vertical divider and toolbar. */ + Vgui_element_face = Fmake_face (Qgui_element, + build_string ("gui element face"), + Qnil); /* Now create the other faces that redisplay needs to refer to directly. We could create them in Lisp but it's simpler this way since we need to get them anyway. */ + + /* modeline is gui element. */ Vmodeline_face = Fmake_face (Qmodeline, build_string ("modeline face"), Qnil); - /* modeline-face should not inherit colors from the default face. */ set_specifier_fallback (Fget (Vmodeline_face, Qforeground, Qunbound), - Fget (V3d_object_face, Qforeground, Qunbound)); + Fget (Vgui_element_face, Qforeground, Qunbound)); set_specifier_fallback (Fget (Vmodeline_face, Qbackground, Qunbound), - Fget (V3d_object_face, Qbackground, Qunbound)); - set_specifier_fallback (Fget (Vmodeline_face, Qbackground_pixmap, - Qnil), - Fget (V3d_object_face, Qbackground_pixmap, Qunbound)); + Fget (Vgui_element_face, Qbackground, Qunbound)); + set_specifier_fallback (Fget (Vmodeline_face, Qbackground_pixmap, Qnil), + Fget (Vgui_element_face, Qbackground_pixmap, + Qunbound)); + + /* toolbar is another gui element */ + Vtoolbar_face = Fmake_face (Qtoolbar, + build_string ("toolbar face"), + Qnil); + set_specifier_fallback (Fget (Vtoolbar_face, Qforeground, Qunbound), + Fget (Vgui_element_face, Qforeground, Qunbound)); + set_specifier_fallback (Fget (Vtoolbar_face, Qbackground, Qunbound), + Fget (Vgui_element_face, Qbackground, Qunbound)); + set_specifier_fallback (Fget (Vtoolbar_face, Qbackground_pixmap, Qnil), + Fget (Vgui_element_face, Qbackground_pixmap, + Qunbound)); + /* vertical divider is another gui element */ Vvertical_divider_face = Fmake_face (Qvertical_divider, build_string ("vertical divider face"), Qnil); - /* #### vertical-divider-face should not inherit from modeline face. - Perhaps there must be a 3d-object-face to supply default foreground, - background and pixmap. */ + set_specifier_fallback (Fget (Vvertical_divider_face, Qforeground, Qunbound), - Fget (V3d_object_face, Qforeground, Qunbound)); + Fget (Vgui_element_face, Qforeground, Qunbound)); set_specifier_fallback (Fget (Vvertical_divider_face, Qbackground, Qunbound), - Fget (V3d_object_face, Qbackground, Qunbound)); + Fget (Vgui_element_face, Qbackground, Qunbound)); set_specifier_fallback (Fget (Vvertical_divider_face, Qbackground_pixmap, Qunbound), - Fget (V3d_object_face, Qbackground_pixmap, Qunbound)); + Fget (Vgui_element_face, Qbackground_pixmap, + Qunbound)); Vleft_margin_face = Fmake_face (Qleft_margin, build_string ("left margin face"), diff -r 6e6992ccc4b6 -r c9fe270a4101 src/faces.h --- a/src/faces.h Mon Aug 13 10:35:55 2007 +0200 +++ b/src/faces.h Mon Aug 13 10:36:47 2007 +0200 @@ -260,7 +260,8 @@ extern Lisp_Object Qstrikethru, Vbuilt_in_face_specifiers, Vdefault_face; extern Lisp_Object Vleft_margin_face, Vpointer_face, Vright_margin_face; -extern Lisp_Object Vtext_cursor_face, Vvertical_divider_face; +extern Lisp_Object Vtext_cursor_face, Vvertical_divider_face; +extern Lisp_Object Vtoolbar_face, Vgui_element_face; void mark_all_faces_as_clean (void); void init_frame_faces (struct frame *f); diff -r 6e6992ccc4b6 -r c9fe270a4101 src/fileio.c --- a/src/fileio.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/fileio.c Mon Aug 13 10:36:47 2007 +0200 @@ -1830,11 +1830,7 @@ if (dir [XSTRING_LENGTH (dirname_) - 1] == '/') dir [XSTRING_LENGTH (dirname_) - 1] = 0; -#ifdef WINDOWSNT - if (mkdir (dir) != 0) -#else if (mkdir (dir, 0777) != 0) -#endif report_file_error ("Creating directory", list1 (dirname_)); return Qnil; @@ -4306,7 +4302,7 @@ DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char /* Directory separator character for built-in functions that return file names. -The value should be either ?/ or ?\ (any other value is treated as ?\). +The value should be either ?/ or ?\\ (any other value is treated as ?\\). This variable affects the built-in functions only on Windows, on other platforms, it is initialized so that Lisp code can find out what the normal separator is. diff -r 6e6992ccc4b6 -r c9fe270a4101 src/fns.c --- a/src/fns.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/fns.c Mon Aug 13 10:36:47 2007 +0200 @@ -478,10 +478,10 @@ The result is a string whose elements are the elements of all the arguments. Each argument may be a string or a list or vector of characters. -Do not use individual integers as arguments! -The behavior of `concat' in that case will be changed later! -If your program passes an integer as an argument to `concat', -you should change it right away not to do so. +As of XEmacs 21.0, this function does NOT accept individual integers +as arguments. Old code that relies on, for example, (concat "foo" 50) +returning "foo50" will fail. To fix such code, either apply +`int-to-string' to the integer argument, or use `format'. */ (int nargs, Lisp_Object *args)) { diff -r 6e6992ccc4b6 -r c9fe270a4101 src/frame-msw.c --- a/src/frame-msw.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/frame-msw.c Mon Aug 13 10:36:47 2007 +0200 @@ -85,6 +85,7 @@ XEMACS_RECT_WH rect_default; DWORD style, exstyle; HWND hwnd, hwnd_parent; + static BOOL first_frame = 1; /* Pick up relevant properties */ initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil); @@ -143,6 +144,12 @@ exstyle = MSWINDOWS_FRAME_EXSTYLE; hwnd_parent = NULL; + if (first_frame) + { + style |= WS_VISIBLE; + first_frame = 0; + } + /* We always create am overlapped frame with default size, and later adjust only requested geometry parameters. */ rect_default.left = rect_default.top = CW_USEDEFAULT; diff -r 6e6992ccc4b6 -r c9fe270a4101 src/frame-x.c --- a/src/frame-x.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/frame-x.c Mon Aug 13 10:36:47 2007 +0200 @@ -976,12 +976,41 @@ #include
static Widget CurrentDragWidget = NULL; +static XtCallbackRec dnd_convert_cb_rec[2]; +static XtCallbackRec dnd_destroy_cb_rec[2]; +static int drag_not_done = 0; static void x_cde_destroy_callback (Widget widget, XtPointer clientData, XtPointer callData) { + DtDndDragFinishCallbackStruct *dragFinishInfo = + (DtDndDragFinishCallbackStruct *)callData; + DtDndContext *dragData = dragFinishInfo->dragData; + int i; + + /* free the items */ + if (callData != NULL && dragData != NULL) + { + if (dragData->protocol == DtDND_BUFFER_TRANSFER) + { + for (i = 0; i < dragData->numItems; i++) + { + XtFree(dragData->data.buffers[i].bp); + if (dragData->data.buffers[i].name) + XtFree(dragData->data.buffers[i].name); + } + } + else + { + for (i = 0; i < dragData->numItems; i++) + XtFree(dragData->data.files[i]); + } + } + + /* free the data string */ xfree (clientData); + CurrentDragWidget = NULL; } @@ -995,12 +1024,12 @@ char *textptr = NULL; int i; - if(convertInfo == NULL) + if (convertInfo == NULL) { return; } - if((convertInfo->dragData->protocol != DtDND_BUFFER_TRANSFER + if ((convertInfo->dragData->protocol != DtDND_BUFFER_TRANSFER && convertInfo->dragData->protocol != DtDND_FILENAME_TRANSFER) || (convertInfo->reason != DtCR_DND_CONVERT_DATA)) { @@ -1026,15 +1055,10 @@ convertInfo->status = DtDND_SUCCESS; } - -static XtCallbackRec dnd_convert_cb_rec[2]; -static XtCallbackRec dnd_destroy_cb_rec[2]; -static int drag_not_done = 0; - static Lisp_Object abort_current_drag(Lisp_Object arg) { - if(CurrentDragWidget && drag_not_done) + if (CurrentDragWidget && drag_not_done) { XmDragCancel(CurrentDragWidget); CurrentDragWidget = NULL; @@ -1061,6 +1085,7 @@ Display *display = XtDisplayOfObject (wid); struct device *d = get_device_from_display (display); struct x_device *xd = DEVICE_X_DATA (d); + XWindowAttributes win_attrib; unsigned int modifier = 0, state = 0; char *Ctext; int numItems = 0, textlen = 0, pos = 0; @@ -1083,14 +1108,23 @@ x_event.xbutton.send_event = False; x_event.xbutton.display = XtDisplayOfObject(wid); x_event.xbutton.window = XtWindowOfObject(wid); - x_event.xbutton.root = XRootWindow(x_event.xkey.display, 0); + x_event.xbutton.root = XRootWindow(x_event.xbutton.display, 0); x_event.xbutton.subwindow = 0; x_event.xbutton.time = lisp_event->timestamp; x_event.xbutton.x = lisp_event->event.button.x; x_event.xbutton.y = lisp_event->event.button.y; - x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */ - x_event.xbutton.y_root = lisp_event->event.button.y; - + if (Success == XGetWindowAttributes (x_event.xbutton.display, + x_event.xbutton.window, + &win_attrib)) + { + x_event.xbutton.x_root = win_attrib.x + lisp_event->event.button.x; + x_event.xbutton.y_root = win_attrib.y + lisp_event->event.button.y; + } + else + { + x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */ + x_event.xbutton.y_root = lisp_event->event.button.y; + } modifier = lisp_event->event.button.modifiers; if (modifier & MOD_SHIFT) state |= ShiftMask; if (modifier & MOD_CONTROL) state |= ControlMask; @@ -1277,6 +1311,7 @@ Display *display = XtDisplayOfObject (wid); struct device *d = get_device_from_display (display); struct x_device *xd = DEVICE_X_DATA (d); + XWindowAttributes win_attrib; unsigned int modifier = 0, state = 0; char *dnd_data = NULL; unsigned long dnd_len = 0; @@ -1345,8 +1380,18 @@ x_event.xbutton.time = lisp_event->timestamp; x_event.xbutton.x = lisp_event->event.button.x; x_event.xbutton.y = lisp_event->event.button.y; - x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */ - x_event.xbutton.y_root = lisp_event->event.button.y; + if (Success == XGetWindowAttributes (x_event.xbutton.display, + x_event.xbutton.window, + &win_attrib)) + { + x_event.xbutton.x_root = win_attrib.x + lisp_event->event.button.x; + x_event.xbutton.y_root = win_attrib.y + lisp_event->event.button.y; + } + else + { + x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */ + x_event.xbutton.y_root = lisp_event->event.button.y; + } modifier = lisp_event->event.button.modifiers; if (modifier & MOD_SHIFT) state |= ShiftMask; @@ -1365,6 +1410,7 @@ if (dnd_dealloc) xfree (dnd_data); + /* the next thing blocks everything... */ if (DndHandleDragging(wid, &x_event)) return Qt; } diff -r 6e6992ccc4b6 -r c9fe270a4101 src/frame.c --- a/src/frame.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/frame.c Mon Aug 13 10:36:47 2007 +0200 @@ -35,9 +35,6 @@ #include "frame.h" #include "glyphs.h" #include "menubar.h" -#ifdef MSDOS -#include "msdos.h" -#endif #include "redisplay.h" #include "scrollbar.h" #include "window.h" diff -r 6e6992ccc4b6 -r c9fe270a4101 src/glyphs-eimage.c --- a/src/glyphs-eimage.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/glyphs-eimage.c Mon Aug 13 10:36:47 2007 +0200 @@ -35,7 +35,7 @@ Improved GIF/JPEG support added by Bill Perry for 19.14 Cleanup/simplification of error handling by Ben Wing for 19.14 Pointer/icon overhaul, more restructuring by Ben Wing for 19.14 - GIF support changed to external GIFlib 3.1 by Jareth Hein for 21.0 + GIF support changed to external Gifreader lib by Jareth Hein for 21.0 Many changes for color work and optimizations by Jareth Hein for 21.0 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 TIFF code by Jareth Hein for 21.0 @@ -403,10 +403,23 @@ */ { + int jpeg_gray = 0; /* if we're dealing with a grayscale */ /* Step 4: set parameters for decompression. */ - /* Now that we're using EImages, use the default of all data in 24bit color. - The backend routine will take care of any necessary reductions. */ + /* Now that we're using EImages, send all data as 24bit color. + The backend routine will take care of any necessary reductions. + We do have to handle the grayscale case ourselves, however. */ + if (cinfo.jpeg_color_space == JCS_GRAYSCALE) + { + cinfo.out_color_space = JCS_GRAYSCALE; + jpeg_gray = 1; + } + else + { + /* we're relying on the jpeg driver to do any other conversions, + or signal an error if the conversion isn't supported. */ + cinfo.out_color_space = JCS_RGB; + } /* Step 5: Start decompressor */ jpeg_start_decompress (&cinfo); @@ -451,13 +464,26 @@ for (i = 0; i < cinfo.output_width; i++) { int clr; + if (jpeg_gray) + { + unsigned char val; #if (BITS_IN_JSAMPLE == 8) - for (clr = 0; clr < 3; clr++) - *op++ = (unsigned char)*jp++; + val = (unsigned char)*jp++; #else /* other option is 12 */ - for (clr = 0; clr < 3; clr++) - *op++ = (unsigned char)(*jp++ >> 4); + val = (unsigned char)(*jp++ >> 4); #endif + for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */ + *op++ = val; + } + else + { + for (clr = 0; clr < 3; clr++) +#if (BITS_IN_JSAMPLE == 8) + *op++ = (unsigned char)*jp++; +#else /* other option is 12 */ + *op++ = (unsigned char)(*jp++ >> 4); +#endif + } } } } @@ -490,7 +516,7 @@ * GIF * **********************************************************************/ -#include +#include static void gif_validate (Lisp_Object instantiator) @@ -798,6 +824,7 @@ struct png_unwind_data unwind; int speccount = specpdl_depth (); int height, width; + struct png_memory_storage tbr; /* Data to be read */ /* PNG variables */ png_structp png_ptr; @@ -844,7 +871,6 @@ Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); CONST Extbyte *bytes; Extcount len; - struct png_memory_storage tbr; /* Data to be read */ assert (!NILP (data)); diff -r 6e6992ccc4b6 -r c9fe270a4101 src/glyphs-msw.c --- a/src/glyphs-msw.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/glyphs-msw.c Mon Aug 13 10:36:47 2007 +0200 @@ -1530,23 +1530,37 @@ padded to a multiple of 16. Scan lines are stored in increasing byte order from left to right, big-endian within a byte. 0 = black, 1 = white. */ -static HBITMAP -xbm_create_bitmap_from_data (char *data, - unsigned int width, unsigned int height) +HBITMAP +xbm_create_bitmap_from_data (HDC hdc, char *data, + unsigned int width, unsigned int height, + int mask, COLORREF fg, COLORREF bg) { int old_width = (width + 7)/8; int new_width = 2*((width + 15)/16); unsigned char *offset; + void *bmp_buf = 0; unsigned char *new_data, *new_offset; - unsigned int i; - int j; - HBITMAP hb; + int i, j; + BITMAPINFO* bmp_info = + xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD)); + HBITMAP bitmap; - new_data = (unsigned char *) xmalloc (height*new_width); + if (!bmp_info) + return NULL; + + new_data = (unsigned char *) xmalloc (height * new_width); + + if (!new_data) + { + xfree (bmp_info); + return NULL; + } + for (i=0; i> 4]); } } - hb = CreateBitmap (width, height, 1, 1, new_data); + + /* if we want a mask invert the bits */ + if (!mask) + { + new_offset = &new_data[height * new_width]; + while (new_offset-- != new_data) + { + *new_offset ^= 0xff; + } + } + + bmp_info->bmiHeader.biWidth=width; + bmp_info->bmiHeader.biHeight=-height; + bmp_info->bmiHeader.biPlanes=1; + bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); + bmp_info->bmiHeader.biBitCount=1; + bmp_info->bmiHeader.biCompression=BI_RGB; + bmp_info->bmiHeader.biClrUsed = 2; + bmp_info->bmiHeader.biClrImportant = 2; + bmp_info->bmiHeader.biSizeImage = height * new_width; + bmp_info->bmiColors[0].rgbRed = GetRValue (fg); + bmp_info->bmiColors[0].rgbGreen = GetGValue (fg); + bmp_info->bmiColors[0].rgbBlue = GetBValue (fg); + bmp_info->bmiColors[0].rgbReserved = 0; + bmp_info->bmiColors[1].rgbRed = GetRValue (bg); + bmp_info->bmiColors[1].rgbGreen = GetGValue (bg); + bmp_info->bmiColors[1].rgbBlue = GetBValue (bg); + bmp_info->bmiColors[1].rgbReserved = 0; + + bitmap = CreateDIBSection (hdc, + bmp_info, + DIB_RGB_COLORS, + &bmp_buf, + 0,0); + + xfree (bmp_info); + + if (!bitmap || !bmp_buf) + { + xfree (new_data); + return NULL; + } + + /* copy in the actual bitmap */ + memcpy (bmp_buf, new_data, height * new_width); xfree (new_data); - return hb; + return bitmap; } /* Given inline data for a mono pixmap, initialize the given @@ -1578,9 +1636,14 @@ Lisp_Object mask_filename) { Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); + struct frame* f = XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device))); Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground); Lisp_Object background = find_keyword_in_vector (instantiator, Q_background); enum image_instance_type type; + COLORREF black = PALETTERGB (0,0,0); + COLORREF white = PALETTERGB (255,255,255); + + HDC hdc = FRAME_MSWINDOWS_CDC (f); if (!DEVICE_MSWINDOWS_P (XDEVICE (device))) signal_simple_error ("Not an MS-Windows device", device); @@ -1605,26 +1668,30 @@ | IMAGE_POINTER_MASK); mswindows_initialize_dibitmap_image_instance (ii, type); - IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; - IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; + IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = find_keyword_in_vector (instantiator, Q_file); + IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; + IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; + IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0); XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0); - IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; - IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask; - IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = - xbm_create_bitmap_from_data ((Extbyte *) bits, width, height); + IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask : + xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height, + TRUE, black, white); switch (type) { case IMAGE_MONO_PIXMAP: + IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = + xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height, + FALSE, black, black); break; case IMAGE_COLOR_PIXMAP: { - unsigned long fg = PALETTERGB (0,0,0); - unsigned long bg = PALETTERGB (255,255,255); + COLORREF fg = black; + COLORREF bg = white; if (!NILP (foreground) && !COLOR_INSTANCEP (foreground)) foreground = @@ -1644,22 +1711,38 @@ IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; IMAGE_INSTANCE_PIXMAP_BG (ii) = background; + + IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = + xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height, + FALSE, fg, black); } break; case IMAGE_POINTER: { + COLORREF fg = black; + COLORREF bg = white; + if (NILP (foreground)) foreground = pointer_fg; if (NILP (background)) background = pointer_bg; + XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), + find_keyword_in_vector (instantiator, Q_hotspot_x)); + XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), + find_keyword_in_vector (instantiator, Q_hotspot_y)); IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; IMAGE_INSTANCE_PIXMAP_BG (ii) = background; - IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = - find_keyword_in_vector (instantiator, Q_hotspot_x); - IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = - find_keyword_in_vector (instantiator, Q_hotspot_y); + if (COLOR_INSTANCEP (foreground)) + fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground)); + if (COLOR_INSTANCEP (background)) + bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background)); + + IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = + xbm_create_bitmap_from_data (hdc, (Extbyte *) bits, width, height, + TRUE, fg, black); + mswindows_initialize_image_instance_icon (ii, TRUE); } break; @@ -1678,6 +1761,9 @@ Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data); Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file); struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + struct frame* f = XFRAME (DEVICE_SELECTED_FRAME + (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)))); + HDC hdc = FRAME_MSWINDOWS_CDC (f); HBITMAP mask = 0; CONST char *gcc_may_you_rot_in_hell; @@ -1686,10 +1772,13 @@ GET_C_STRING_BINARY_DATA_ALLOCA (XCAR (XCDR (XCDR (mask_data))), gcc_may_you_rot_in_hell); mask = - xbm_create_bitmap_from_data ( (unsigned char *) + xbm_create_bitmap_from_data ( hdc, + (unsigned char *) gcc_may_you_rot_in_hell, XINT (XCAR (mask_data)), - XINT (XCAR (XCDR (mask_data)))); + XINT (XCAR (XCDR (mask_data))), FALSE, + PALETTERGB (0,0,0), + PALETTERGB (255,255,255)); } init_image_instance_from_xbm_inline (ii, width, height, bits, diff -r 6e6992ccc4b6 -r c9fe270a4101 src/glyphs-x.c --- a/src/glyphs-x.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/glyphs-x.c Mon Aug 13 10:36:47 2007 +0200 @@ -61,26 +61,12 @@ #include "sysfile.h" -#ifdef HAVE_PNG -#ifdef __cplusplus -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#endif -#else #include -#endif + #ifdef FILE_CODING #include "file-coding.h" #endif -#undef HAVE_PNG -#undef HAVE_TIFF -#undef HAVE_JPEG -#undef HAVE_GIF - #if INTBITS == 32 # define FOUR_BYTE_TYPE unsigned int #elif LONGBITS == 32 @@ -98,26 +84,6 @@ Lisp_Object Qxface; #endif -#ifdef HAVE_TIFF -DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); -Lisp_Object Qtiff; -#endif - -#ifdef HAVE_JPEG -DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg); -Lisp_Object Qjpeg; -#endif - -#ifdef HAVE_GIF -DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif); -Lisp_Object Qgif; -#endif - -#ifdef HAVE_PNG -DEFINE_IMAGE_INSTANTIATOR_FORMAT (png); -Lisp_Object Qpng; -#endif - DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); Lisp_Object Qcursor_font; @@ -1499,1792 +1465,6 @@ #endif /* HAVE_XPM */ -#ifdef HAVE_JPEG - -/********************************************************************** - * JPEG * - **********************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#ifdef __cplusplus -} -#endif - -/*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/ -static void -jpeg_validate (Lisp_Object instantiator) -{ - file_or_data_must_be_present (instantiator); -} - -static Lisp_Object -jpeg_normalize (Lisp_Object inst, Lisp_Object console_type) -{ - return simple_image_type_normalize (inst, console_type, Qjpeg); -} - -static int -jpeg_possible_dest_types (void) -{ - return IMAGE_COLOR_PIXMAP_MASK; -} - -/* To survive the otherwise baffling complexity of making sure - everything gets cleaned up in the presence of an error, we - use an unwind_protect(). */ - -struct jpeg_unwind_data -{ - Display *dpy; - Colormap cmap; - /* Stream that we need to close */ - FILE *instream; - /* Object that holds state info for JPEG decoding */ - struct jpeg_decompress_struct *cinfo_ptr; - /* EImage data */ - unsigned char *eimage; - /* Pixels to keep around while the image is active */ - unsigned long *pixels; - int npixels, pixcount; - /* Client-side image structure */ - XImage *ximage; - /* Tempfile to remove */ -#ifdef USE_TEMP_FILES_FOR_JPEG_IMAGES - char tempfile[50]; - int tempfile_needs_to_be_removed; -#endif -}; - -static Lisp_Object -jpeg_instantiate_unwind (Lisp_Object unwind_obj) -{ - struct jpeg_unwind_data *data = - (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj); - - free_opaque_ptr (unwind_obj); - if (data->cinfo_ptr) - jpeg_destroy_decompress (data->cinfo_ptr); - - if (data->instream) - fclose (data->instream); - - if (data->eimage) xfree (data->eimage); - - if (data->npixels > 0) - XFreeColors (data->dpy, data->cmap, data->pixels, data->npixels, 0L); - if (data->pixcount) - xfree (data->pixels); - - if (data->ximage) - { - if (data->ximage->data) - { - xfree (data->ximage->data); - data->ximage->data = 0; - } - XDestroyImage (data->ximage); - } -#if USE_TEMP_FILES_FOR_JPEG_IMAGES - if (data->tempfile_needs_to_be_removed) - unlink (data->tempfile); -#endif - - return Qnil; -} - -/* - * ERROR HANDLING: - * - * The JPEG library's standard error handler (jerror.c) is divided into - * several "methods" which you can override individually. This lets you - * adjust the behavior without duplicating a lot of code, which you might - * have to update with each future release. - * - * Our example here shows how to override the "error_exit" method so that - * control is returned to the library's caller when a fatal error occurs, - * rather than calling exit() as the standard error_exit method does. - * - * We use C's setjmp/longjmp facility to return control. This means that the - * routine which calls the JPEG library must first execute a setjmp() call to - * establish the return point. We want the replacement error_exit to do a - * longjmp(). But we need to make the setjmp buffer accessible to the - * error_exit routine. To do this, we make a private extension of the - * standard JPEG error handler object. (If we were using C++, we'd say we - * were making a subclass of the regular error handler.) - * - * Here's the extended error handler struct: - */ - -struct my_jpeg_error_mgr -{ - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -#if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) -METHODDEF(void) -#else -METHODDEF void -#endif -our_init_source (j_decompress_ptr cinfo) -{ -} - -#if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) -METHODDEF(boolean) -#else -METHODDEF boolean -#endif -our_fill_input_buffer (j_decompress_ptr cinfo) -{ - /* Insert a fake EOI marker */ - struct jpeg_source_mgr *src = cinfo->src; - static JOCTET buffer[2]; - - buffer[0] = (JOCTET) 0xFF; - buffer[1] = (JOCTET) JPEG_EOI; - - src->next_input_byte = buffer; - src->bytes_in_buffer = 2; - return TRUE; -} - -#if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) -METHODDEF(void) -#else -METHODDEF void -#endif -our_skip_input_data (j_decompress_ptr cinfo, long num_bytes) -{ - struct jpeg_source_mgr *src = NULL; - - src = (struct jpeg_source_mgr *) cinfo->src; - - if (!src) - { - return; - } else if (num_bytes > src->bytes_in_buffer) - { - ERREXIT(cinfo, JERR_INPUT_EOF); - /*NOTREACHED*/ - } - - src->bytes_in_buffer -= num_bytes; - src->next_input_byte += num_bytes; -} - -#if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) -METHODDEF(void) -#else -METHODDEF void -#endif -our_term_source (j_decompress_ptr cinfo) -{ -} - -typedef struct -{ - struct jpeg_source_mgr pub; -} our_jpeg_source_mgr; - -static void -jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len) -{ - struct jpeg_source_mgr *src; - - if (cinfo->src == NULL) - { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof(our_jpeg_source_mgr)); - src = (struct jpeg_source_mgr *) cinfo->src; - src->next_input_byte = data; - } - src = (struct jpeg_source_mgr *) cinfo->src; - src->init_source = our_init_source; - src->fill_input_buffer = our_fill_input_buffer; - src->skip_input_data = our_skip_input_data; - src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->term_source = our_term_source; - src->bytes_in_buffer = len; - src->next_input_byte = data; -} - -#if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) -METHODDEF(void) -#else -METHODDEF void -#endif -my_jpeg_error_exit (j_common_ptr cinfo) -{ - /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ - struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err; - - /* Return control to the setjmp point */ - longjmp (myerr->setjmp_buffer, 1); -} - -#if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) -METHODDEF(void) -#else -METHODDEF void -#endif -my_jpeg_output_message (j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); - warn_when_safe (Qjpeg, Qinfo, "%s", buffer); -} - -/* The code in this routine is based on example.c from the JPEG library - source code and from gif_instantiate() */ -static void -jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) -{ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - Display *dpy; - Colormap cmap; - Visual *vis; - /* It is OK for the unwind data to be local to this function, - because the unwind-protect is always executed when this - stack frame is still valid. */ - struct jpeg_unwind_data unwind; - int speccount = specpdl_depth (); - - /* This struct contains the JPEG decompression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct my_jpeg_error_mgr jerr; - - if (!DEVICE_X_P (XDEVICE (device))) - signal_simple_error ("Not an X device", device); - - dpy = DEVICE_X_DISPLAY (XDEVICE (device)); - cmap = DEVICE_X_COLORMAP (XDEVICE(device)); - vis = DEVICE_X_VISUAL (XDEVICE(device)); - - /* Step -1: First record our unwind-protect, which will clean up after - any exit, normal or not */ - - xzero (unwind); - unwind.dpy = dpy; - unwind.cmap = cmap; - record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind)); - -#ifdef USE_TEMP_FILES_FOR_JPEG_IMAGES - /* Step 0: Write out to a temp file. - - The JPEG routines require you to read from a file unless - you provide your own special input handlers, which I don't - feel like doing. */ - { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - - assert (!NILP (data)); - - write_lisp_string_to_temp_file (data, unwind.tempfile); - unwind.tempfile_needs_to_be_removed = 1; - - /* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - if ((unwind.instream = fopen (unwind.tempfile, "r")) == NULL) - report_file_error ("Opening JPEG temp file", - list1 (build_string (unwind.tempfile))); - } -#endif - - /* Step 1: allocate and initialize JPEG decompression object */ - - /* We set up the normal JPEG error routines, then override error_exit. */ - cinfo.err = jpeg_std_error (&jerr.pub); - jerr.pub.error_exit = my_jpeg_error_exit; - jerr.pub.output_message = my_jpeg_output_message; - - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp (jerr.setjmp_buffer)) - { - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - - { - Lisp_Object errstring; - char buffer[JMSG_LENGTH_MAX]; - - /* Create the message */ - (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer); - errstring = build_string (buffer); - - signal_image_error_2 ("JPEG decoding error", - errstring, instantiator); - } - } - - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress (&cinfo); - unwind.cinfo_ptr = &cinfo; - - /* Step 2: specify data source (eg, a file) */ - -#ifdef USE_TEMP_FILES_FOR_JPEG_IMAGES - jpeg_stdio_src (&cinfo, unwind.instream); -#else - { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - CONST Extbyte *bytes; - Extcount len; - - /* #### This is a definite problem under Mule due to the amount of - stack data it might allocate. Need to be able to convert and - write out to a file. */ - GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); - jpeg_memory_src (&cinfo, (JOCTET *) bytes, len); - } -#endif - - /* Step 3: read file parameters with jpeg_read_header() */ - - jpeg_read_header (&cinfo, TRUE); - /* We can ignore the return value from jpeg_read_header since - * (a) suspension is not possible with the stdio data source, and - * (b) we passed TRUE to reject a tables-only JPEG file as an error. - * See libjpeg.doc for more info. - */ - -#if 0 - /* Step 4: set parameters for decompression. */ - - if (vis->class == PseudoColor) - { - - /* We request that the JPEG file be automatically quantized into - 8-bit color in case it's not already (many JPEGs are stored in - 24-bit color). "Two-pass quantize" means that the colormap - is determined on-the-fly for this particular image rather than - quantizing to a supplied colormap. We can get away with this - because we then use allocate_nearest_color(). - - #### Note of course that this is not the most color-effective - way of doing things -- we could quantize an image that has - lots of very similar colors, and eat up the colormap with these - (useless to other images) colors. Unfortunately I don't think - there's any "general" way of maximizing the overall image - quality of lots of images, given that we don't know the - colors of the images until we come across each one. Best we - could do would be various sorts of heuristics, which I don't - feel like dealing with now. A better scheme would be the - way things are done under MS Windows, where the colormap is - dynamically adjusted for various applications; but that kind - of thing would have to be provided by X, which it isn't. */ - - cinfo.quantize_colors = TRUE; - cinfo.two_pass_quantize = TRUE; - cinfo.colormap = NULL; - } - - /* Step 5: Start decompressor */ - - jpeg_start_decompress (&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* At this point we know the size of the image and the colormap. */ - - /* Step 5.33: Allocate the colors */ - if (vis->class == PseudoColor) - { - int i; - unwind.pixcount = 32; - unwind.pixels = xnew_array (unsigned long, unwind.pixcount); - unwind.npixels = 0; - - /* Allocate pixels for the various colors. */ - for (i = 0; i < cinfo.actual_number_of_colors; i++) - { - XColor color; - int ri, gi, bi, res; - - ri = 0; - gi = cinfo.out_color_components > 1 ? 1 : 0; - bi = cinfo.out_color_components > 2 ? 2 : 0; - - /* Ok... apparently, an entry of cinfo.colormap can be NULL if - there are no bits of that color in the image. How incredibly - gross. Wouldn't it be nice to have exceptions!? */ - color.red = cinfo.colormap[ri] ? cinfo.colormap[ri][i] << 8 : 0; - color.green = cinfo.colormap[gi] ? cinfo.colormap[gi][i] << 8 : 0; - color.blue = cinfo.colormap[bi] ? cinfo.colormap[bi][i] << 8 : 0; - color.flags = DoRed | DoGreen | DoBlue; - - res = allocate_nearest_color (dpy, cmap, vis, &color); - if (res > 0 && res < 3) - { - DO_REALLOC(unwind.pixels, unwind.pixcount, unwind.npixels+1, unsigned long); - unwind.pixels[unwind.npixels] = color.pixel; - unwind.npixels++; - } - } - } - - /* Step 5.66: Create the image */ - { - int height = cinfo.output_height; - int width = cinfo.output_width; - int depth; - int bitmap_pad; - - depth = DEVICE_X_DEPTH(XDEVICE(device)); - - /* first get bitmap_pad (from XPM) */ - bitmap_pad = ((depth > 16) ? 32 : - (depth > 8) ? 16 : - 8); - - unwind.ximage = XCreateImage (dpy, vis, depth, ZPixmap, 0, 0, width, height, - bitmap_pad, 0); - - if (!unwind.ximage) - signal_image_error ("Unable to create X image struct", instantiator); - - /* now that bytes_per_line must have been set properly alloc data */ - unwind.ximage->data = - (char *) xmalloc (unwind.ximage->bytes_per_line * height); - } - - /* Step 6: Read in the data and put into image */ - { - JSAMPARRAY row_buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - * In this example, we need to make an output work buffer of the right size. - */ - /* JSAMPLEs per row in output buffer. - Since we asked for quantized output, cinfo.output_components - will always be 1. */ - row_stride = cinfo.output_width * cinfo.output_components; - /* Make a one-row-high sample array that will go away when done - with image */ - row_buffer = ((*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1)); - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - while (cinfo.output_scanline < cinfo.output_height) - { - int i; - int scanline = cinfo.output_scanline; - - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - jpeg_read_scanlines (&cinfo, row_buffer, 1); - - for (i = 0; i < (int) cinfo.output_width; i++) - XPutPixel (unwind.ximage, i, scanline, - /* Let's make sure we avoid getting bit like - what happened for GIF's. It's probably the - case that JSAMPLE's are unsigned chars as - opposed to chars, but you never know. - - (They could even be shorts if the library - was compiled with 12-bit samples -- #### - We should deal with this possibility) */ - unwind.pixels[(unsigned char) row_buffer[0][i]]); - } - } -#else - { - /* Step 4: set parameters for decompression. */ - - /* Now that we're using EImages, use the default of all data in 24bit color. - The backend routine will take care of any necessary reductions. */ - - /* Step 5: Start decompressor */ - jpeg_start_decompress (&cinfo); - - /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/ - - unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3); - if (!unwind.eimage) - signal_image_error("Unable to allocate enough memory for image", instantiator); - - { - JSAMPARRAY row_buffer; /* Output row buffer */ - JSAMPLE *jp; - int row_stride; /* physical row width in output buffer */ - unsigned char *op = unwind.eimage; - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available - * We need to make an output work buffer of the right size. - */ - /* JSAMPLEs per row in output buffer. */ - row_stride = cinfo.output_width * cinfo.output_components; - /* Make a one-row-high sample array that will go away when done - with image */ - row_buffer = ((*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1)); - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - while (cinfo.output_scanline < cinfo.output_height) - { - int i; - - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - (void) jpeg_read_scanlines (&cinfo, row_buffer, 1); - jp = row_buffer[0]; - for (i = 0; i < cinfo.output_width; i++) - { - int clr; -#if (BITS_IN_JSAMPLE == 8) - for (clr = 0; clr < 3; clr++) - *op++ = (unsigned char)*jp++; -#else /* other option is 12 */ - for (clr = 0; clr < 3; clr++) - *op++ = (unsigned char)(*jp++ >> 4); -#endif - } - } - unwind.ximage = convert_EImage_to_XImage (device, cinfo.output_width, cinfo.output_height, unwind.eimage, - &unwind.pixels, &unwind.pixcount, &unwind.npixels); - if (!unwind.ximage) - signal_image_error("JPEG conversion failed", instantiator); - } - } - -#endif - /* Step 6.5: Create the pixmap and set up the image instance */ - init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, - cmap, unwind.pixels, unwind.npixels, - instantiator); - - /* Step 7: Finish decompression */ - - jpeg_finish_decompress (&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* And we're done! - - Now that we've succeeded, we don't want the pixels - freed right now. They're kept around in the image instance - structure until it's destroyed. */ - unwind.npixels = 0; - unwind.pixcount = 0; - - /* This will clean up everything else. */ - unbind_to (speccount, Qnil); -} - -#endif /* HAVE_JPEG */ - -#ifdef HAVE_GIF -/* #define USE_TEMP_FILES_FOR_GIF_IMAGES */ -/********************************************************************** - * GIF * - **********************************************************************/ - -#include - -static void -gif_validate (Lisp_Object instantiator) -{ - file_or_data_must_be_present (instantiator); -} - -static Lisp_Object -gif_normalize (Lisp_Object inst, Lisp_Object console_type) -{ - return simple_image_type_normalize (inst, console_type, Qgif); -} - -static int -gif_possible_dest_types (void) -{ - return IMAGE_COLOR_PIXMAP_MASK; -} - -/* To survive the otherwise baffling complexity of making sure - everything gets cleaned up in the presence of an error, we - use an unwind_protect(). */ - -struct gif_unwind_data -{ - Display *dpy; - Colormap cmap; - unsigned char *eimage; - /* Object that holds the decoded data from a GIF file */ - GifFileType *giffile; - /* Pixels to keep around while the image is active */ - unsigned long *pixels; - int npixels, pixcount; - /* Client-side image structure */ - XImage *ximage; -#ifdef USE_TEMP_FILES_FOR_GIF_IMAGES - /* Tempfile to remove */ - char tempfile[50]; - int tempfile_needs_to_be_removed; -#endif -}; - -static Lisp_Object -gif_instantiate_unwind (Lisp_Object unwind_obj) -{ - struct gif_unwind_data *data = - (struct gif_unwind_data *) get_opaque_ptr (unwind_obj); - - free_opaque_ptr (unwind_obj); - if (data->giffile) - { - DGifCloseFile (data->giffile); - GifFree(data->giffile); - } - if (data->eimage) xfree(data->eimage); -#ifdef USE_TEMP_FILES_FOR_GIF_IMAGES - if (data->tempfile_needs_to_be_removed) - unlink (data->tempfile); -#endif - if (data->npixels > 0) - XFreeColors (data->dpy, data->cmap, data->pixels, data->npixels, 0L); - if (data->pixcount > 0) - xfree (data->pixels); - if (data->ximage) - { - if (data->ximage->data) - { - xfree (data->ximage->data); - data->ximage->data = 0; - } - XDestroyImage (data->ximage); - } - - return Qnil; -} - -#ifndef USE_TEMP_FILES_FOR_GIF_IMAGES -typedef struct gif_memory_storage -{ - Extbyte *bytes; /* The data */ - Extcount len; /* How big is it? */ - int index; /* Where are we? */ -} gif_memory_storage; - -static size_t -gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data) -{ - gif_memory_storage *mem = (gif_memory_storage*)data; - - if (size > (mem->len - mem->index)) - return -1; - memcpy(buf, mem->bytes + mem->index, size); - mem->index = mem->index + size; - return size; -} - -static int -gif_memory_close(VoidPtr data) -{ - return 0; -} - -#endif -struct gif_error_struct -{ - CONST char *err_str; /* return the error string */ - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -static void -gif_error_func(CONST char *err_str, VoidPtr error_ptr) -{ - struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr; - - /* return to setjmp point */ - error_data->err_str = err_str; - longjmp (error_data->setjmp_buffer, 1); -} - -static void -gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) -{ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - Display *dpy; - Colormap cmap; - Visual *vis; - /* It is OK for the unwind data to be local to this function, - because the unwind-protect is always executed when this - stack frame is still valid. */ - struct gif_unwind_data unwind; - int speccount = specpdl_depth (); -#ifndef USE_TEMP_FILES_FOR_GIF_IMAGES - gif_memory_storage mem_struct; - struct gif_error_struct gif_err; - Extbyte *bytes; - Extcount len; -#endif - if (!DEVICE_X_P (XDEVICE (device))) - signal_simple_error ("Not an X device", device); - - dpy = DEVICE_X_DISPLAY (XDEVICE (device)); - cmap = DEVICE_X_COLORMAP (XDEVICE(device)); - vis = DEVICE_X_VISUAL (XDEVICE(device)); - - xzero (unwind); - unwind.dpy = dpy; - unwind.cmap = cmap; - record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind)); - - /* 1. Now decode the data. */ - - { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - - assert (!NILP (data)); - - if (!(unwind.giffile = GifSetup())) - signal_image_error ("Insufficent memory to instantiate GIF image", instantiator); - - /* set up error facilities */ - if (setjmp(gif_err.setjmp_buffer)) - { - /* An error was signaled. No clean up is needed, as unwind handles that - for us. Just pass the error along. */ - Lisp_Object errstring; - errstring = build_string (gif_err.err_str); - signal_image_error_2 ("GIF decoding error", errstring, instantiator); - } - GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err); - -#ifdef USE_TEMP_FILES_FOR_GIF_IMAGES - write_lisp_string_to_temp_file (data, unwind.tempfile); - unwind.tempfile_needs_to_be_removed = 1; - DGifOpenFileName (unwind.giffile, unwind.tempfile); -#else - GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); - mem_struct.bytes = bytes; - mem_struct.len = len; - mem_struct.index = 0; - GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct); - GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct); - DGifInitRead(unwind.giffile); -#endif - /* Then slurp the image into memory, decoding along the way. - The result is the image in a simple one-byte-per-pixel - format (#### the GIF routines only support 8-bit GIFs, - it appears). */ - DGifSlurp (unwind.giffile); - } - -#if 0 - /* 2. Now allocate the colors for the image. */ - { - int i; - ColorMapObject *cmo = unwind.giffile->SColorMap; - /* Just in case the image contains out-of-range pixels, we go - ahead and allocate space for all of them. */ - unwind.pixels = xnew_array (unsigned long, 256); - unwind.npixels = 0; - - for (i = 0; i < 256; i++) - unwind.pixels[i] = 0; /* Use a reasonable color for out of range. */ - - /* Allocate pixels for the various colors. */ - for (i = 0; i < cmo->ColorCount; i++) - { - int res; - XColor color; - - color.red = cmo->Colors[i].Red << 8; - color.green = cmo->Colors[i].Green << 8; - color.blue = cmo->Colors[i].Blue << 8; - color.flags = DoRed | DoGreen | DoBlue; - - res = allocate_nearest_color (dpy, cmap, vis, &color); - if (res > 0 && res < 3) - { - unwind.pixels[unwind.npixels] = color.pixel; - unwind.npixels++; - } - } - } - - /* 3. Now create the image */ - { - int height = unwind.giffile->SHeight; - int width = unwind.giffile->SWidth; - int depth; - int bitmap_pad; - int i, j, row, pass, interlace; - /* interlaced gifs have rows in this order: - 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ - static int InterlacedOffset[] = { 0, 4, 2, 1 }; - static int InterlacedJumps[] = { 8, 8, 4, 2 }; - - depth = DEVICE_X_DEPTH(XDEVICE(device)); - - /* first get bitmap_pad (from XPM) */ - bitmap_pad = ((depth > 16) ? 32 : - (depth > 8) ? 16 : - 8); - - unwind.ximage = XCreateImage (dpy, vis, - depth, ZPixmap, 0, 0, width, height, - bitmap_pad, 0); - - if (!unwind.ximage) - signal_image_error ("Unable to create X image struct", instantiator); - - /* now that bytes_per_line must have been set properly alloc data */ - unwind.ximage->data = - (char *) xmalloc (unwind.ximage->bytes_per_line * height); - - /* write the data -- - #### XPutPixel() is a client-side-only function but could - still be slow. Another possibility is to just convert to - XPM format and use the Xpm routines, which optimize this - stuff; but it's doubtful that this will be faster in the - long run, what with all the XPM overhead. If this proves - to be a bottleneck here, maybe we should just copy the - optimization routines from XPM (they're in turn mostly - copied from the Xlib source code). */ - - /* Note: We just use the first image in the file and ignore the rest. - We check here that that image covers the full "screen" size. - I don't know whether that's always the case. - -dkindred@cs.cmu.edu */ - if (unwind.giffile->SavedImages[0].ImageDesc.Height != height - || unwind.giffile->SavedImages[0].ImageDesc.Width != width - || unwind.giffile->SavedImages[0].ImageDesc.Left != 0 - || unwind.giffile->SavedImages[0].ImageDesc.Top != 0) - signal_image_error ("First image in GIF file is not full size", - instantiator); - - interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace; - pass = 0; - row = interlace ? InterlacedOffset[pass] : 0; - for (i = 0; i < height; i++) - { - if (interlace && row >= height) - row = InterlacedOffset[++pass]; - - for (j = 0; j < width; j++) - XPutPixel (unwind.ximage, j, row, - unwind.pixels[(unsigned char) - /* incorrect signed declaration - of RasterBits[] */ - (unwind.giffile->SavedImages[0]. - RasterBits[i * width + j])]); - - row += interlace ? InterlacedJumps[pass] : 1; - } - } -#else - /* 3. Now create the EImage */ - { - ColorMapObject *cmo = unwind.giffile->SColorMap; - int height = unwind.giffile->SHeight; - int width = unwind.giffile->SWidth; - int i, j, row, pass, interlace; - unsigned char *eip; - /* interlaced gifs have rows in this order: - 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ - static int InterlacedOffset[] = { 0, 4, 2, 1 }; - static int InterlacedJumps[] = { 8, 8, 4, 2 }; - - unwind.eimage = (unsigned char*) xmalloc (width * height * 3); - if (!unwind.eimage) - signal_image_error("Unable to allocate enough memory for image", instantiator); - - /* write the data in EImage format (8bit RGB triples) */ - - /* Note: We just use the first image in the file and ignore the rest. - We check here that that image covers the full "screen" size. - I don't know whether that's always the case. - -dkindred@cs.cmu.edu */ - if (unwind.giffile->SavedImages[0].ImageDesc.Height != height - || unwind.giffile->SavedImages[0].ImageDesc.Width != width - || unwind.giffile->SavedImages[0].ImageDesc.Left != 0 - || unwind.giffile->SavedImages[0].ImageDesc.Top != 0) - signal_image_error ("First image in GIF file is not full size", - instantiator); - - interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace; - pass = 0; - row = interlace ? InterlacedOffset[pass] : 0; - eip = unwind.eimage; - for (i = 0; i < height; i++) - { - if (interlace && row >= height) - row = InterlacedOffset[++pass]; - eip = unwind.eimage + (row * width * 3); - for (j = 0; j < width; j++) - { - unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j]; - *eip++ = cmo->Colors[pixel].Red; - *eip++ = cmo->Colors[pixel].Green; - *eip++ = cmo->Colors[pixel].Blue; - } - row += interlace ? InterlacedJumps[pass] : 1; - } - unwind.ximage = convert_EImage_to_XImage (device, width, height, unwind.eimage, - &unwind.pixels, &unwind.pixcount, &unwind.npixels); - if (!unwind.ximage) - signal_image_error("GIF conversion failed", instantiator); - } -#endif - /* 4. Now create the pixmap and set up the image instance */ - init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, - cmap, unwind.pixels, unwind.npixels, - instantiator); - /* Now that we've succeeded, we don't want the pixels - freed right now. They're kept around in the image instance - structure until it's destroyed. */ - unwind.npixels = 0; - unwind.pixcount = 0; - unbind_to (speccount, Qnil); -} - -#endif /* HAVE_GIF */ - - -#ifdef HAVE_PNG -/* #define USE_TEMP_FILES_FOR_PNG_IMAGES 1 */ - -/********************************************************************** - * PNG * - **********************************************************************/ -static void -png_validate (Lisp_Object instantiator) -{ - file_or_data_must_be_present (instantiator); -} - -static Lisp_Object -png_normalize (Lisp_Object inst, Lisp_Object console_type) -{ - return simple_image_type_normalize (inst, console_type, Qpng); -} - -static int -png_possible_dest_types (void) -{ - return IMAGE_COLOR_PIXMAP_MASK; -} - -#ifndef USE_TEMP_FILES_FOR_PNG_IMAGES -struct png_memory_storage -{ - CONST Extbyte *bytes; /* The data */ - Extcount len; /* How big is it? */ - int index; /* Where are we? */ -}; - -static void -png_read_from_memory(png_structp png_ptr, png_bytep data, - png_size_t length) -{ - struct png_memory_storage *tbr = - (struct png_memory_storage *) png_get_io_ptr (png_ptr); - - if (length > (tbr->len - tbr->index)) - png_error (png_ptr, (png_const_charp) "Read Error"); - memcpy (data,tbr->bytes + tbr->index,length); - tbr->index = tbr->index + length; -} -#endif /* !USE_TEMP_FILES_FOR_PNG_IMAGES */ - -struct png_error_struct -{ - CONST char *err_str; - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -/* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own - structure, and there are cases where the size can be different from - between inside the libarary, and inside the code! To do an end run - around this, use our own error functions, and don't rely on things - passed in the png_ptr to them. This is an ugly hack and must - go away when the lisp engine is threaded! */ -static struct png_error_struct png_err_stct; - -static void -png_error_func (png_structp png_ptr, png_const_charp msg) -{ - png_err_stct.err_str = msg; - longjmp (png_err_stct.setjmp_buffer, 1); -} - -static void -png_warning_func (png_structp png_ptr, png_const_charp msg) -{ - warn_when_safe (Qpng, Qinfo, "%s", msg); -} - -struct png_unwind_data -{ - Display *dpy; - Colormap cmap; - FILE *instream; - unsigned char *eimage; - png_structp png_ptr; - png_infop info_ptr; - unsigned long *pixels; - int npixels, pixcount; - XImage *ximage; -#ifdef USE_TEMP_FILES_FOR_PNG_IMAGESS - char tempfile[50]; - int tempfile_needs_to_be_removed; -#endif -}; - -static Lisp_Object -png_instantiate_unwind (Lisp_Object unwind_obj) -{ - struct png_unwind_data *data = - (struct png_unwind_data *) get_opaque_ptr (unwind_obj); - - free_opaque_ptr (unwind_obj); - if (data->png_ptr) - png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL); - if (data->instream) - fclose (data->instream); - if (data->npixels > 0) - XFreeColors (data->dpy, data->cmap, data->pixels, data->npixels, 0L); - if (data->pixcount > 0) - xfree (data->pixels); - - if (data->eimage) - xfree (data->eimage); - if (data->ximage) - { - if (data->ximage->data) - { - xfree (data->ximage->data); - data->ximage->data = 0; - } - XDestroyImage (data->ximage); - } -#ifdef USE_TEMP_FILES_FOR_PNG_IMAGES - if (data->tempfile_needs_to_be_removed) - unlink (data->tempfile); -#endif - return Qnil; -} - -static void -png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) -{ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - Display *dpy; - Colormap cmap; - Visual *vis; - struct png_unwind_data unwind; - int speccount = specpdl_depth (); - - /* PNG variables */ - png_structp png_ptr; - png_infop info_ptr; - - if (!DEVICE_X_P (XDEVICE (device))) - signal_simple_error ("Not an X device", device); - - dpy = DEVICE_X_DISPLAY (XDEVICE (device)); - cmap = DEVICE_X_COLORMAP (XDEVICE(device)); - vis = DEVICE_X_VISUAL (XDEVICE(device)); - - /* Initialize all PNG structures */ - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct, - png_error_func, png_warning_func); - if (!png_ptr) - signal_image_error ("Error obtaining memory for png_read", instantiator); - info_ptr = png_create_info_struct (png_ptr); - if (!info_ptr) - { - png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - signal_image_error ("Error obtaining memory for png_read", instantiator); - } - - xzero (unwind); - unwind.png_ptr = png_ptr; - unwind.info_ptr = info_ptr; - unwind.dpy = dpy; - unwind.cmap = cmap; - - record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind)); - - /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from - this file, example.c from the libpng 0.81 distribution, and the - pngtopnm sources. -WMP- - */ - /* It has been further modified to handle the API changes for 0.96, - and is no longer usable for previous versions. jh - */ - - /* Set the jmp_buf reurn context for png_error ... if this returns !0, then - we ran into a problem somewhere, and need to clean up after ourselves. */ - if (setjmp (png_err_stct.setjmp_buffer)) - { - /* Something blew up: just display the error (cleanup happens in the unwind) */ - signal_image_error_2 ("Error decoding PNG", - build_string(png_err_stct.err_str), - instantiator); - } - - /* Initialize the IO layer and read in header information */ - { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - CONST Extbyte *bytes; - Extcount len; - struct png_memory_storage tbr; /* Data to be read */ - - assert (!NILP (data)); - - /* #### This is a definite problem under Mule due to the amount of - stack data it might allocate. Need to think about using Lstreams */ - GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); - tbr.bytes = bytes; - tbr.len = len; - tbr.index = 0; - png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory); - } - - png_read_info (png_ptr, info_ptr); - -#if 0 - /* set up the transformations you want. Note that these are - all optional. Only call them if you want them */ - /* tell libpng to strip 16 bit depth files down to 8 bits */ - if (info_ptr->bit_depth == 16) - png_set_strip_16 (png_ptr); - if (info_ptr->bit_depth < 8) - png_set_packing (png_ptr); - /* ##### Perhaps some way to specify the screen gamma should be in here? */ - - { - int height = info_ptr->height; - int width = info_ptr->width; - int depth = info_ptr->bit_depth; - int linesize = max (info_ptr->bit_depth >> 3, 1) * width; - int bitmap_pad; - int y; - XColor color; - png_byte *png_pixels; - png_byte **row_pointers; - png_color static_color_cube[216]; - - /* Wow, allocate all the memory. Truly, exciting. */ - unwind.pixcount = 32; - unwind.pixels = xnew_array (unsigned long, unwind.pixcount); - png_pixels = xnew_array (png_byte, linesize * height); - row_pointers = xnew_array (png_byte *, height); - - for (y = 0; y < height; y++) - row_pointers[y] = png_pixels + (linesize * y); - - /* #### This is where we should handle transparency, but I am unsure of - how exactly to get that information right now, in a safe manner. */ -#if 0 - { - png_color_16 current_background; - - /* Some appropriate magic should go here to get the current - buffers (device?) background color and convert it to a - png_color_16 struct */ - if (info_ptr->valid & PNG_INFO_bKGD) - png_set_background (png_ptr, &(info_ptr->background), PNG_GAMMA_FILE, - 1, 1.0); - else - png_set_background (png_ptr, ¤t_background, PNG_GAMMA_SCREEN, - 0, 1.0); - } -#endif - - if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - (vis->class == PseudoColor)) - { - if (!(info_ptr->valid & PNG_INFO_PLTE)) - { - for (y = 0; y < 216; y++) - { - static_color_cube[y].red = (png_byte) ((y % 6) * 255.0 / 5); - static_color_cube[y].green = (png_byte) (((y / 6) % 6) * 255.0 / 5); - static_color_cube[y].blue = (png_byte) ((y / 36) * 255.0 / 5); - } - png_set_dither (png_ptr, static_color_cube, 216, 216, NULL, 1); - } - else - { - png_set_dither (png_ptr, info_ptr->palette, info_ptr->num_palette, - info_ptr->num_palette, info_ptr->hist, 1); - } - } - - png_read_image (png_ptr, row_pointers); - png_read_end (png_ptr, info_ptr); - - /* Ok, now we go and allocate all the colors */ - if (info_ptr->valid & PNG_INFO_PLTE) - { - unwind.npixels = 0; - for (y = 0; y < info_ptr->num_palette; y++) - { - int res; - color.red = info_ptr->palette[y].red << 8; - color.green = info_ptr->palette[y].green << 8; - color.blue = info_ptr->palette[y].blue << 8; - color.flags = DoRed | DoGreen | DoBlue; - res = allocate_nearest_color (dpy, cmap, vis, &color); - if (res > 0 && res < 3) - { - DO_REALLOC(unwind.pixels, unwind.pixcount, unwind.npixels+1, unsigned long); - unwind.pixels[unwind.npixels] = color.pixel; - unwind.npixels++; - } - } - } - else - { - unwind.npixels = 0; - for (y = 0; y < 216; y++) - { - int res; - color.red = static_color_cube[y].red << 8; - color.green = static_color_cube[y].green << 8; - color.blue = static_color_cube[y].blue << 8; - color.flags = DoRed|DoGreen|DoBlue; - res = allocate_nearest_color (dpy, cmap, vis, &color); - if (res > 0 && res < 3) - { - unwind.pixels[unwind.npixels] = color.pixel; - unwind.npixels++; - } - } - } - -#ifdef PNG_SHOW_COMMENTS - /* #### - * I turn this off by default now, because the !%^@#!% comments - * show up every time the image is instantiated, which can get - * really really annoying. There should be some way to pass this - * type of data down into the glyph code, where you can get to it - * from lisp anyway. - WMP - */ - { - int i; - - for (i = 0 ; i < info_ptr->num_text ; i++) - { - /* How paranoid do I have to be about no trailing NULLs, and - using (int)info_ptr->text[i].text_length, and strncpy and a temp - string somewhere? */ - - warn_when_safe (Qpng, Qinfo, "%s - %s", - info_ptr->text[i].key, - info_ptr->text[i].text); - } - } -#endif - - /* Now create the image */ - - depth = DEVICE_X_DEPTH(XDEVICE(device)); - - /* first get bitmap_pad (from XPM) */ - bitmap_pad = ((depth > 16) ? 32 : - (depth > 8) ? 16 : - 8); - - unwind.ximage = XCreateImage (dpy, vis, - depth, ZPixmap, 0, 0, width, height, - bitmap_pad, 0); - - if (!unwind.ximage) - signal_image_error ("Unable to create X image struct", - instantiator); - - /* now that bytes_per_line must have been set properly alloc data */ - unwind.ximage->data = (char *) xmalloc (unwind.ximage->bytes_per_line * - height); - - { - int i, j; - for (i = 0; i < height; i++) - for (j = 0; j < width; j++) - XPutPixel (unwind.ximage, j, i, - unwind.pixels[png_pixels[i * width + j]]); - } - - xfree (row_pointers); - xfree (png_pixels); - } -#else - { - int height = info_ptr->height; - int width = info_ptr->width; - int y; - unsigned char **row_pointers; - - /* Wow, allocate all the memory. Truly, exciting. */ - unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3); - /* libpng expects that the image buffer passed in contains a - picture to draw on top of if the png has any transparencies. - This could be a good place to pass that in... */ - - row_pointers = xnew_array (png_byte *, height); - - for (y = 0; y < height; y++) - row_pointers[y] = unwind.eimage + (width * 3 * y); - - /* Now that we're using EImage, ask for 8bit RGB triples for any type - of image*/ - /* convert palatte images to full RGB */ - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_set_expand (png_ptr); - /* send grayscale images to RGB too */ - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb (png_ptr); - /* we can't handle alpha values */ - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) - png_set_strip_alpha (png_ptr); - /* rip out any transparancy layers/colors */ - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) - { - png_set_expand (png_ptr); - png_set_strip_alpha (png_ptr); - } - /* tell libpng to strip 16 bit depth files down to 8 bits */ - if (info_ptr->bit_depth == 16) - png_set_strip_16 (png_ptr); - /* if the image is < 8 bits, pad it out */ - if (info_ptr->bit_depth < 8) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) - png_set_expand (png_ptr); - else - png_set_packing (png_ptr); - } - -#if 1 /* tests? or permanent? */ - { - /* if the png specifies a background chunk, go ahead and - use it */ - png_color_16 my_background, *image_background; - - /* ### how do I get the background of the current frame? */ - my_background.red = 0x7fff; - my_background.green = 0x7fff; - my_background.blue = 0x7fff; - - if (png_get_bKGD (png_ptr, info_ptr, &image_background)) - png_set_background (png_ptr, image_background, - PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); - else - png_set_background (png_ptr, &my_background, - PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); - } -#endif - png_read_image (png_ptr, row_pointers); - png_read_end (png_ptr, info_ptr); - -#ifdef PNG_SHOW_COMMENTS - /* #### - * I turn this off by default now, because the !%^@#!% comments - * show up every time the image is instantiated, which can get - * really really annoying. There should be some way to pass this - * type of data down into the glyph code, where you can get to it - * from lisp anyway. - WMP - */ - { - int i; - - for (i = 0 ; i < info_ptr->num_text ; i++) - { - /* How paranoid do I have to be about no trailing NULLs, and - using (int)info_ptr->text[i].text_length, and strncpy and a temp - string somewhere? */ - - warn_when_safe (Qpng, Qinfo, "%s - %s", - info_ptr->text[i].key, - info_ptr->text[i].text); - } - } -#endif - - xfree (row_pointers); - unwind.ximage = convert_EImage_to_XImage (device, width, height, unwind.eimage, - &unwind.pixels, &unwind.pixcount, &unwind.npixels); - if (!unwind.ximage) - signal_image_error ("PNG conversion failed", instantiator); - } -#endif - - init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, - cmap, unwind.pixels, unwind.npixels, - instantiator); - - /* This will clean up everything else. */ - unwind.npixels = 0; - unwind.pixcount = 0; - unbind_to (speccount, Qnil); -} - -#endif /* HAVE_PNG */ - - -#ifdef HAVE_TIFF -#include "tiffio.h" - -/********************************************************************** - * TIFF * - **********************************************************************/ -static void -tiff_validate (Lisp_Object instantiator) -{ - file_or_data_must_be_present (instantiator); -} - -static Lisp_Object -tiff_normalize (Lisp_Object inst, Lisp_Object console_type) -{ - return simple_image_type_normalize (inst, console_type, Qtiff); -} - -static int -tiff_possible_dest_types (void) -{ - return IMAGE_COLOR_PIXMAP_MASK; -} - -struct tiff_unwind_data -{ - Display *dpy; - Colormap cmap; - unsigned char *eimage; - /* Object that holds the decoded data from a TIFF file */ - TIFF *tiff; - /* Pixels to keep around while the image is active */ - unsigned long *pixels; - int npixels,pixcount; - /* Client-side image structure */ - XImage *ximage; -}; - -static Lisp_Object -tiff_instantiate_unwind (Lisp_Object unwind_obj) -{ - struct tiff_unwind_data *data = - (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj); - - free_opaque_ptr (unwind_obj); - if (data->tiff) - { - TIFFClose(data->tiff); - } - if (data->eimage) - xfree (data->eimage); - if (data->npixels > 0) - XFreeColors (data->dpy, data->cmap, data->pixels, data->npixels, 0L); - if (data->pixcount) - xfree (data->pixels); - if (data->ximage) - { - if (data->ximage->data) - { - xfree (data->ximage->data); - data->ximage->data = 0; - } - XDestroyImage (data->ximage); - } - - return Qnil; -} - -typedef struct tiff_memory_storage -{ - Extbyte *bytes; /* The data */ - Extcount len; /* How big is it? */ - int index; /* Where are we? */ -} tiff_memory_storage; - -static size_t -tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size) -{ - tiff_memory_storage *mem = (tiff_memory_storage*)data; - - if (size > (mem->len - mem->index)) - return (size_t) -1; - memcpy(buf, mem->bytes + mem->index, size); - mem->index = mem->index + size; - return size; -} - -static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size) -{ - abort(); - return 0; /* Shut up warnings. */ -} - -static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence) -{ - tiff_memory_storage *mem = (tiff_memory_storage*)data; - int newidx; - switch(whence) { - case SEEK_SET: - newidx = off; - break; - case SEEK_END: - newidx = mem->len + off; - break; - case SEEK_CUR: - newidx = mem->index + off; - break; - default: - fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n"); - return -1; - } - - if ((newidx > mem->len) || (newidx < 0)) - return -1; - - mem->index = newidx; - return newidx; -} - -static int -tiff_memory_close(thandle_t data) -{ - return 0; -} - -static int -tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize) -{ - return 0; -} - -static void -tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize) -{ - return; -} - -static toff_t -tiff_memory_size(thandle_t data) -{ - tiff_memory_storage *mem = (tiff_memory_storage*)data; - return mem->len; -} - -struct tiff_error_struct -{ -#if HAVE_VSNPRINTF - char err_str[256]; -#else - char err_str[1024]; /* return the error string */ -#endif - jmp_buf setjmp_buffer; /* for return to caller */ -}; - -/* jh 98/03/12 - ###This struct for passing data to the error functions - is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't - have any place to store error func data. This should be rectified - before XEmacs gets threads! */ -static struct tiff_error_struct tiff_err_data; - -static void -tiff_error_func(CONST char *module, CONST char *fmt, ...) -{ - va_list vargs; - - va_start (vargs, fmt); -#if HAVE_VSNPRINTF - vsnprintf (tiff_err_data.err_str, 255, fmt, vargs); -#else - /* pray this doesn't overflow... */ - vsprintf (tiff_err_data.err_str, fmt, vargs); -#endif - va_end (vargs); - /* return to setjmp point */ - longjmp (tiff_err_data.setjmp_buffer, 1); -} - -static void -tiff_warning_func(CONST char *module, CONST char *fmt, ...) -{ - va_list vargs; -#if HAVE_VSNPRINTF - char warn_str[256]; -#else - char warn_str[1024]; -#endif - - va_start (vargs, fmt); -#if HAVE_VSNPRINTF - vsnprintf (warn_str, 255, fmt, vargs); -#else - vsprintf (warn_str, fmt, vargs); -#endif - va_end (vargs); - warn_when_safe (Qtiff, Qinfo, "%s - %s", - module, warn_str); -} - -static void -tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) -{ - struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - Colormap cmap; - Display *dpy; - tiff_memory_storage mem_struct; - /* It is OK for the unwind data to be local to this function, - because the unwind-protect is always executed when this - stack frame is still valid. */ - struct tiff_unwind_data unwind; - int speccount = specpdl_depth (); - - if (!DEVICE_X_P (XDEVICE (device))) - signal_simple_error ("Not an X device", device); - - dpy = DEVICE_X_DISPLAY (XDEVICE (device)); - cmap = DEVICE_X_COLORMAP (XDEVICE(device)); - - xzero (unwind); - unwind.dpy = dpy; - unwind.cmap = cmap; - record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind)); - - /* set up error facilities */ - if (setjmp (tiff_err_data.setjmp_buffer)) - { - /* An error was signaled. No clean up is needed, as unwind handles that - for us. Just pass the error along. */ - signal_image_error_2 ("TIFF decoding error", - build_string(tiff_err_data.err_str), - instantiator); - } - TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func); - TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func); - { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); - Extbyte *bytes; - Extcount len; - - uint32 width, height; - uint32 *raster; - unsigned char *ep; - - assert (!NILP (data)); - - /* #### This is a definite problem under Mule due to the amount of - stack data it might allocate. Think about Lstreams... */ - GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); - mem_struct.bytes = bytes; - mem_struct.len = len; - mem_struct.index = 0; - - unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct, - (TIFFReadWriteProc)tiff_memory_read, - (TIFFReadWriteProc)tiff_memory_write, - tiff_memory_seek, tiff_memory_close, tiff_memory_size, - tiff_map_noop, tiff_unmap_noop); - if (!unwind.tiff) - signal_image_error ("Insufficent memory to instantiate TIFF image", instantiator); - - TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); - unwind.eimage = (unsigned char *) xmalloc (width * height * 3); - - /* ### This is little more than proof-of-concept/function testing. - It needs to be reimplimented via scanline reads for both memory - compactness. */ - raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); - if (raster != NULL) - { - int i,j; - uint32 *rp; - ep = unwind.eimage; - rp = raster; - if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0)) - { - for (i = height - 1; i >= 0; i--) - { - /* This is to get around weirdness in the libtiff library where properly - made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */ - rp = raster + (i * width); - for (j = 0; j < width; j++) - { - *ep++ = (unsigned char)TIFFGetR(*rp); - *ep++ = (unsigned char)TIFFGetG(*rp); - *ep++ = (unsigned char)TIFFGetB(*rp); - rp++; - } - } - } - _TIFFfree (raster); - } else - signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator); - - unwind.ximage = convert_EImage_to_XImage (device, width, height, unwind.eimage, - &unwind.pixels, &unwind.pixcount, &unwind.npixels); - if (!unwind.ximage) - signal_image_error ("TIFF conversion failed", instantiator); - } - /* Now create the pixmap and set up the image instance */ - init_image_instance_from_x_image (ii, unwind.ximage, dest_mask, - cmap, unwind.pixels, unwind.npixels, - instantiator); - /* Now that we've succeeded, we don't want the pixels - freed right now. They're kept around in the image instance - structure until it's destroyed. */ - unwind.npixels = 0; - unwind.pixcount = 0; - unbind_to (speccount, Qnil); -} - -#endif /* HAVE_TIFF */ - - #ifdef HAVE_XFACE /********************************************************************** @@ -4164,54 +2344,6 @@ IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string); IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string); -#ifdef HAVE_JPEG - INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg"); - - IIFORMAT_HAS_METHOD (jpeg, validate); - IIFORMAT_HAS_METHOD (jpeg, normalize); - IIFORMAT_HAS_METHOD (jpeg, possible_dest_types); - IIFORMAT_HAS_METHOD (jpeg, instantiate); - - IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string); - IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string); -#endif - -#ifdef HAVE_GIF - INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif"); - - IIFORMAT_HAS_METHOD (gif, validate); - IIFORMAT_HAS_METHOD (gif, normalize); - IIFORMAT_HAS_METHOD (gif, possible_dest_types); - IIFORMAT_HAS_METHOD (gif, instantiate); - - IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string); - IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string); -#endif - -#ifdef HAVE_PNG - INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png"); - - IIFORMAT_HAS_METHOD (png, validate); - IIFORMAT_HAS_METHOD (png, normalize); - IIFORMAT_HAS_METHOD (png, possible_dest_types); - IIFORMAT_HAS_METHOD (png, instantiate); - - IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string); - IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string); -#endif - -#ifdef HAVE_TIFF - INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff"); - - IIFORMAT_HAS_METHOD (tiff, validate); - IIFORMAT_HAS_METHOD (tiff, normalize); - IIFORMAT_HAS_METHOD (tiff, possible_dest_types); - IIFORMAT_HAS_METHOD (tiff, instantiate); - - IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string); - IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string); -#endif - #ifdef HAVE_XFACE INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xface, "xface"); @@ -4242,22 +2374,6 @@ void vars_of_glyphs_x (void) { -#ifdef HAVE_JPEG - Fprovide (Qjpeg); -#endif - -#ifdef HAVE_GIF - Fprovide (Qgif); -#endif - -#ifdef HAVE_PNG - Fprovide (Qpng); -#endif - -#ifdef HAVE_TIFF - Fprovide (Qtiff); -#endif - #ifdef HAVE_XFACE Fprovide (Qxface); #endif diff -r 6e6992ccc4b6 -r c9fe270a4101 src/glyphs.c --- a/src/glyphs.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/glyphs.c Mon Aug 13 10:36:47 2007 +0200 @@ -1600,6 +1600,9 @@ -- maybe return an error, or return Qnil. */ +#ifndef HAVE_X_WINDOWS +#define XFree(data) free(data) +#endif Lisp_Object bitmap_to_lisp_data (Lisp_Object name, int *xhot, int *yhot, diff -r 6e6992ccc4b6 -r c9fe270a4101 src/lisp.h --- a/src/lisp.h Mon Aug 13 10:35:55 2007 +0200 +++ b/src/lisp.h Mon Aug 13 10:36:47 2007 +0200 @@ -1142,13 +1142,15 @@ #ifdef LISP_FLOAT_TYPE -/* Note: the 'next' field is there to ensure that there is enough room - for the next pointer float type's free list. */ +/* Note: the 'unused__next__' field exists only to ensure that the + `next' pointer fits within the structure, for the purposes of the + free list. This makes a difference in the unlikely case of + sizeof(double) being smaller than sizeof(void *). */ struct Lisp_Float { struct lrecord_header lheader; - union { double d; struct Lisp_Float *next; } data; + union { double d; struct Lisp_Float *unused__next__; } data; }; DECLARE_LRECORD (float, struct Lisp_Float); @@ -1159,7 +1161,6 @@ #define CHECK_FLOAT(x) CHECK_RECORD (x, float) #define CONCHECK_FLOAT(x) CONCHECK_RECORD (x, float) -#define float_next(f) ((f)->data.next) #define float_data(f) ((f)->data.d) #define XFLOATINT(n) extract_float (n) diff -r 6e6992ccc4b6 -r c9fe270a4101 src/msdos.c --- a/src/msdos.c Mon Aug 13 10:35:55 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2509 +0,0 @@ -/* MS-DOS specific C utilities. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of XEmacs. - -XEmacs 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 2, or (at your option) any -later version. - -XEmacs 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 XEmacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Synched up with: FSF 19.30. */ - -/* Contributed by Morten Welinder */ -/* New display, keyboard, and mouse control by Kim F. Storm */ - -/* Note: some of the stuff here was taken from end of sysdep.c in demacs. */ - -#define DONT_ENCAPSULATE - -#include - -#ifdef MSDOS -#include -#include -#include -#include -#include "lisp.h" -#include "dosfns.h" -#include "msdos.h" -#include "redisplay.h" -#include "systime.h" -#include "termhooks.h" -#include "frame.h" -#include "window.h" -#include -#include - -static unsigned long -event_timestamp (void) -{ - struct time t; - unsigned long s; - - gettime (&t); - s = t.ti_min; - s *= 60; - s += t.ti_sec; - s *= 1000; - s += t.ti_hund * 10; - - return s; -} - - -/* ------------------------ Mouse control --------------------------- - * - * Coordinates are in screen positions and zero based. - * Mouse buttons are numbered from left to right and also zero based. - */ - -int have_mouse; /* 0: no, 1: enabled, -1: disabled */ -static int mouse_visible; - -static int mouse_last_x; -static int mouse_last_y; - -static int mouse_button_translate[NUM_MOUSE_BUTTONS]; -static int mouse_button_count; - -void -mouse_on (void) -{ - union REGS regs; - - if (have_mouse > 0 && !mouse_visible) - { - if (termscript) - fprintf (termscript, ""); - regs.x.ax = 0x0001; - int86 (0x33, ®s, ®s); - mouse_visible = 1; - } -} - -void -mouse_off (void) -{ - union REGS regs; - - if (have_mouse > 0 && mouse_visible) - { - if (termscript) - fprintf (termscript, ""); - regs.x.ax = 0x0002; - int86 (0x33, ®s, ®s); - mouse_visible = 0; - } -} - -void -mouse_moveto (int x, int y) -{ - union REGS regs; - - if (termscript) - fprintf (termscript, "", x, y); - regs.x.ax = 0x0004; - mouse_last_x = regs.x.cx = x * 8; - mouse_last_y = regs.x.dx = y * 8; - int86 (0x33, ®s, ®s); -} - -static int -mouse_pressed (int b, int *xp, int *yp) -{ - union REGS regs; - - if (b >= mouse_button_count) - return 0; - regs.x.ax = 0x0005; - regs.x.bx = mouse_button_translate[b]; - int86 (0x33, ®s, ®s); - if (regs.x.bx) - *xp = regs.x.cx / 8, *yp = regs.x.dx / 8; - return (regs.x.bx != 0); -} - -static int -mouse_released (int b, int *xp, int *yp) -{ - union REGS regs; - - if (b >= mouse_button_count) - return 0; - regs.x.ax = 0x0006; - regs.x.bx = mouse_button_translate[b]; - int86 (0x33, ®s, ®s); - if (regs.x.bx) - *xp = regs.x.cx / 8, *yp = regs.x.dx / 8; - return (regs.x.bx != 0); -} - -static void -mouse_get_xy (int *x, int *y) -{ - union REGS regs; - - regs.x.ax = 0x0003; - int86 (0x33, ®s, ®s); - *x = regs.x.cx / 8; - *y = regs.x.dx / 8; -} - -void -mouse_get_pos (FRAME_PTR *f, int insist, Lisp_Object *bar_window, - Lisp_Object *x, Lisp_Object *y, enum scroll_bar_part *part, - unsigned long *time) -{ - int ix, iy; - union REGS regs; - - regs.x.ax = 0x0003; - int86 (0x33, ®s, ®s); - *f = selected_frame; - *bar_window = Qnil; - mouse_get_xy (&ix, &iy); - selected_frame->mouse_moved = 0; - *x = make_int (ix); - *y = make_int (iy); - *time = event_timestamp (); -} - -static void -mouse_check_moved (void) -{ - int x, y; - - mouse_get_xy (&x, &y); - selected_frame->mouse_moved |= (x != mouse_last_x || y != mouse_last_y); - mouse_last_x = x; - mouse_last_y = y; -} - -void -mouse_init (void) -{ - union REGS regs; - - if (termscript) - fprintf (termscript, ""); - - regs.x.ax = 0x0021; - int86 (0x33, ®s, ®s); - - regs.x.ax = 0x0007; - regs.x.cx = 0; - regs.x.dx = 8 * (ScreenCols () - 1); - int86 (0x33, ®s, ®s); - - regs.x.ax = 0x0008; - regs.x.cx = 0; - regs.x.dx = 8 * (ScreenRows () - 1); - int86 (0x33, ®s, ®s); - - mouse_moveto (0, 0); - mouse_visible = 0; -} - -/* ------------------------- Screen control ---------------------- - * - */ - -static int internal_terminal = 0; - -#ifndef HAVE_X_WINDOWS -extern unsigned char ScreenAttrib; -static int screen_face; -static int highlight; - -static int screen_size_X; -static int screen_size_Y; -static int screen_size; - -static int current_pos_X; -static int current_pos_Y; -static int new_pos_X; -static int new_pos_Y; - -static void *startup_screen_buffer; -static int startup_screen_size_X; -static int startup_screen_size_Y; -static int startup_pos_X; -static int startup_pos_Y; - -static int term_setup_done; - -/* Similar to the_only_frame. */ -struct x_output the_only_x_display; - -/* This is never dereferenced. */ -Display *x_current_display; - - -#define SCREEN_SET_CURSOR() \ - if (current_pos_X != new_pos_X || current_pos_Y != new_pos_Y) \ - ScreenSetCursor (current_pos_Y = new_pos_Y, current_pos_X = new_pos_X) - -static -dos_direct_output (int y, int x, char *buf, int len) -{ - int t = (int) ScreenPrimary + 2 * (x + y * screen_size_X); - - while (--len >= 0) { - dosmemput (buf++, 1, t); - t += 2; - } -} -#endif - -/* Flash the screen as a substitute for BEEPs. */ - -#if (__DJGPP__ < 2) -static void -do_visible_bell (unsigned char xorattr) -{ - asm volatile - (" movb $1,%%dl -visible_bell_0: - movl _ScreenPrimary,%%eax - call dosmemsetup - movl %%eax,%%ebx - movl %1,%%ecx - movb %0,%%al - incl %%ebx -visible_bell_1: - xorb %%al,%%gs:(%%ebx) - addl $2,%%ebx - decl %%ecx - jne visible_bell_1 - decb %%dl - jne visible_bell_3 -visible_bell_2: - movzwl %%ax,%%eax - movzwl %%ax,%%eax - movzwl %%ax,%%eax - movzwl %%ax,%%eax - decw %%cx - jne visible_bell_2 - jmp visible_bell_0 -visible_bell_3:" - : /* no output */ - : "m" (xorattr), "g" (screen_size) - : "%eax", "%ebx", /* "%gs",*/ "%ecx", "%edx"); -} - -static void -ScreenVisualBell (void) -{ - /* This creates an xor-mask that will swap the default fore- and - background colors. */ - do_visible_bell (((the_only_x_display.foreground_pixel - ^ the_only_x_display.background_pixel) - * 0x11) & 0x7f); -} -#endif - -#ifndef HAVE_X_WINDOWS - -/* - * If we write a character in the position where the mouse is, - * the mouse cursor may need to be refreshed. - */ - -static void -mouse_off_maybe (void) -{ - int x, y; - - if (!mouse_visible) - return; - - mouse_get_xy (&x, &y); - if (y != new_pos_Y || x < new_pos_X) - return; - - mouse_off (); -} - -static -IT_ring_bell (void) -{ - if (visible_bell) - { - mouse_off (); - ScreenVisualBell (); - } - else - { - union REGS inregs, outregs; - inregs.h.ah = 2; - inregs.h.dl = 7; - intdos (&inregs, &outregs); - } -} - -static void -IT_set_face (int face) -{ - struct face *fp; - extern struct face *intern_face (/* FRAME_PTR, struct face * */); - - if (face == 1 || (face == 0 && highlight)) - fp = FRAME_MODE_LINE_FACE (foo); - else if (face <= 0 || face >= FRAME_N_COMPUTED_FACES (foo)) - fp = FRAME_DEFAULT_FACE (foo); - else - fp = intern_face (selected_frame, FRAME_COMPUTED_FACES (foo)[face]); - if (termscript) - fprintf (termscript, "", FACE_FOREGROUND (fp), FACE_BACKGROUND (fp)); - screen_face = face; - ScreenAttrib = (FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp); -} - -static -IT_write_glyphs (GLYPH *str, int len) -{ - int newface; - int ch, l = len; - unsigned char *buf, *bp; - - if (len == 0) return; - - buf = bp = alloca (len * 2); - - while (--l >= 0) - { - newface = FAST_GLYPH_FACE (*str); - if (newface != screen_face) - IT_set_face (newface); - ch = FAST_GLYPH_CHAR (*str); - *bp++ = (unsigned char)ch; - *bp++ = ScreenAttrib; - - if (termscript) - fputc (ch, termscript); - str++; - } - - mouse_off_maybe (); - dosmemput (buf, 2 * len, - (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y)); - new_pos_X += len; -} - -static -IT_clear_end_of_line (int first_unused) -{ - char *spaces, *sp; - int i, j; - - IT_set_face (0); - if (termscript) - fprintf (termscript, ""); - i = (j = screen_size_X - new_pos_X) * 2; - spaces = sp = alloca (i); - - while (--j >= 0) - { - *sp++ = ' '; - *sp++ = ScreenAttrib; - } - - mouse_off_maybe (); - dosmemput (spaces, i, - (int)ScreenPrimary + 2 * (new_pos_X + screen_size_X * new_pos_Y)); -} - -static -IT_clear_screen (void) -{ - if (termscript) - fprintf (termscript, ""); - IT_set_face (0); - mouse_off (); - ScreenClear (); - new_pos_X = new_pos_Y = 0; -} - -static -IT_clear_to_end (void) -{ - if (termscript) - fprintf (termscript, ""); - - while (new_pos_Y < screen_size_Y) { - new_pos_X = 0; - IT_clear_end_of_line (0); - new_pos_Y++; - } -} - -static -IT_cursor_to (int y, int x) -{ - if (termscript) - fprintf (termscript, "\n", x, y); - new_pos_X = x; - new_pos_Y = y; -} - -static -IT_reassert_line_highlight (int new, int vpos) -{ - highlight = new; - IT_set_face (0); /* To possibly clear the highlighting. */ -} - -static -IT_change_line_highlight (int new_highlight, int vpos, int first_unused_hpos) -{ - highlight = new_highlight; - IT_set_face (0); /* To possibly clear the highlighting. */ - IT_cursor_to (vpos, 0); - IT_clear_end_of_line (first_unused_hpos); -} - -static -IT_update_begin (void) -{ - highlight = 0; - IT_set_face (0); /* To possibly clear the highlighting. */ - screen_face = -1; -} - -static -IT_update_end (void) -{ -} - -/* This was more or less copied from xterm.c */ -static void -IT_set_menu_bar_lines (Lisp_Object window, int n) -{ - struct window *w = XWINDOW (window); - - XSETINT (w->last_modified, 0); - XSETINT (w->top, XINT (w->top) + n); - XSETINT (w->height, XINT (w->height) - n); - - /* Handle just the top child in a vertical split. */ - if (!NILP (w->vchild)) - IT_set_menu_bar_lines (w->vchild, n); - - /* Adjust all children in a horizontal split. */ - for (window = w->hchild; !NILP (window); window = w->next) - { - w = XWINDOW (window); - IT_set_menu_bar_lines (window, n); - } -} - -/* - * IT_set_terminal_modes is called when emacs is started, - * resumed, and whenever the screen is redrawn! - */ - -static -IT_set_terminal_modes (void) -{ - char *colors; - FRAME_PTR f; - struct face *fp; - - if (termscript) - fprintf (termscript, "\n"); - highlight = 0; - - screen_size_X = ScreenCols (); - screen_size_Y = ScreenRows (); - screen_size = screen_size_X * screen_size_Y; - - new_pos_X = new_pos_Y = 0; - current_pos_X = current_pos_Y = -1; - - if (term_setup_done) - return; - term_setup_done = 1; - - startup_screen_size_X = screen_size_X; - startup_screen_size_Y = screen_size_Y; - - ScreenGetCursor (&startup_pos_Y, &startup_pos_X); - ScreenRetrieve (startup_screen_buffer = xmalloc (screen_size * 2)); - - if (termscript) - fprintf (termscript, "\n"); -} - -/* - * IT_reset_terminal_modes is called when emacs is - * suspended or killed. - */ - -static -IT_reset_terminal_modes (void) -{ - if (termscript) - fprintf (termscript, "\n"); - - highlight = 0; - - if (!term_setup_done) - return; - - ScreenUpdate (startup_screen_buffer); - ScreenSetCursor (startup_pos_Y, startup_pos_X); - xfree (startup_screen_buffer); - - if (termscript) - fprintf (termscript, "\n"); - - term_setup_done = 0; -} - -static -IT_set_terminal_window (void) -{ -} - -void -IT_set_frame_parameters (FRAME_PTR frame, Lisp_Object alist) -{ - Lisp_Object tail; - int redraw; - extern unsigned long load_color (); - FRAME_PTR f = (FRAME_PTR) &the_only_frame; - - redraw = 0; - for (tail = alist; CONSP (tail); tail = Fcdr (tail)) - { - Lisp_Object elt, prop, val; - - elt = Fcar (tail); - prop = Fcar (elt); - val = Fcdr (elt); - CHECK_SYMBOL (prop); - - if (EQ (prop, intern ("foreground-color"))) - { - unsigned long new_color = load_color (f, val); - if (new_color != ~0) - { - FRAME_FOREGROUND_PIXEL (f) = new_color; - redraw = 1; - } - } - else if (EQ (prop, intern ("background-color"))) - { - unsigned long new_color = load_color (f, val); - if (new_color != ~0) - { - FRAME_BACKGROUND_PIXEL (f) = new_color & ~8; - redraw = 1; - } - } - else if (EQ (prop, intern ("menu-bar-lines"))) - { - int new; - int old = FRAME_MENU_BAR_LINES (the_only_frame); - - if (INTEGERP (val)) - new = XINT (val); - else - new = 0; - FRAME_MENU_BAR_LINES (f) = new; - IT_set_menu_bar_lines (the_only_frame.root_window, new - old); - } - } - - if (redraw) - { - recompute_basic_faces (f); - Fredraw_frame (Fselected_frame (Qnil), Qnil); - } -} - -#endif /* !HAVE_X_WINDOWS */ - - -/* Do we need the internal terminal? */ -void -internal_terminal_init (void) -{ - char *term = getenv ("TERM"); - char *colors; - -#ifdef HAVE_X_WINDOWS - if (!inhibit_window_system) - return; -#endif - - internal_terminal - = (!noninteractive) && term && !strcmp (term, "internal"); - - if (getenv ("EMACSTEST")) - termscript = fopen (getenv ("EMACSTEST"), "wt"); - -#ifndef HAVE_X_WINDOWS - if (!internal_terminal || inhibit_window_system) - { - the_only_frame.output_method = output_termcap; - return; - } - - Vwindow_system = intern ("pc"); - - memset (&the_only_x_display, 0, sizeof the_only_x_display); - the_only_x_display.background_pixel = 7; /* White */ - the_only_x_display.foreground_pixel = 0; /* Black */ - colors = getenv ("EMACSCOLORS"); - if (colors && strlen (colors) >= 2) - { - the_only_x_display.foreground_pixel = colors[0] & 0x07; - the_only_x_display.background_pixel = colors[1] & 0x07; - } - the_only_x_display.line_height = 1; - the_only_frame.output_data.x = &the_only_x_display; - the_only_frame.output_method = output_msdos_raw; - the_only_x_display.font = (XFontStruct *)1; /* must *not* be zero */ - - init_frame_faces ((FRAME_PTR) &the_only_frame); - - ring_bell_hook = IT_ring_bell; - write_glyphs_hook = IT_write_glyphs; - cursor_to_hook = raw_cursor_to_hook = IT_cursor_to; - clear_to_end_hook = IT_clear_to_end; - clear_end_of_line_hook = IT_clear_end_of_line; - clear_frame_hook = IT_clear_screen; - change_line_highlight_hook = IT_change_line_highlight; - update_begin_hook = IT_update_begin; - update_end_hook = IT_update_end; - reassert_line_highlight_hook = IT_reassert_line_highlight; - - /* These hooks are called by term.c without being checked. */ - set_terminal_modes_hook = IT_set_terminal_modes; - reset_terminal_modes_hook = IT_reset_terminal_modes; - set_terminal_window_hook = IT_set_terminal_window; -#endif -} - -dos_get_saved_screen (char **screen, int *rows, int *cols) -{ -#ifndef HAVE_X_WINDOWS - *screen = startup_screen_buffer; - *cols = startup_screen_size_X; - *rows = startup_screen_size_Y; - return 1; -#else - return 0; -#endif -} - - - -/* ----------------------- Keyboard control ---------------------- - * - * Keymaps reflect the following keyboard layout: - * - * 0 1 2 3 4 5 6 7 8 9 10 11 12 BS - * TAB 15 16 17 18 19 20 21 22 23 24 25 26 (41) - * CLOK 30 31 32 33 34 35 36 37 38 39 40 (41) RET - * SH () 45 46 47 48 49 50 51 52 53 54 SHIFT - * SPACE - */ - -static int extended_kbd; /* 101 (102) keyboard present. */ - -struct dos_keyboard_map -{ - char *unshifted; - char *shifted; - char *alt_gr; -}; - - -static struct dos_keyboard_map us_keyboard = { -/* 0 1 2 3 4 5 */ -/* 01234567890123456789012345678901234567890 12345678901234 */ - "`1234567890-= qwertyuiop[] asdfghjkl;'\\ zxcvbnm,./ ", -/* 0123456789012345678901234567890123456789 012345678901234 */ - "~!@#$%^&*()_+ QWERTYUIOP{} ASDFGHJKL:\"| ZXCVBNM<>? ", - 0 /* no Alt-Gr key */ -}; - -static struct dos_keyboard_map fr_keyboard = { -/* 0 1 2 3 4 5 */ -/* 012 3456789012345678901234567890123456789012345678901234 */ - "ý&‚\",(-Š_€…)= azertyuiop^$ qsdfghjklm—* wxcvbnm;:! ", -/* 0123456789012345678901234567890123456789012345678901234 */ - " 1234567890ø+ AZERTYUIOPùœ QSDFGHJKLM%æ WXCVBN?./õ ", -/* 01234567 89012345678901234567890123456789012345678901234 */ - " ~#{[|`\\^@]} Ï " -}; - -static struct dos_keyboard_map dk_keyboard = { -/* 0 1 2 3 4 5 */ -/* 0123456789012345678901234567890123456789012345678901234 */ - "«1234567890+| qwertyuiop†~ asdfghjkl‘›' zxcvbnm,.- ", -/* 01 23456789012345678901234567890123456789012345678901234 */ - "õ!\"#$%&/()=?` QWERTYUIOP^ ASDFGHJKL’* ZXCVBNM;:_ ", -/* 0123456789012345678901234567890123456789012345678901234 */ - " @œ$ {[]} | " -}; - -static struct keyboard_layout_list -{ - int country_code; - struct dos_keyboard_map *keyboard_map; -} keyboard_layout_list[] = -{ - 1, &us_keyboard, - 33, &fr_keyboard, - 45, &dk_keyboard -}; - -static struct dos_keyboard_map *keyboard; -static int keyboard_map_all; - -int -dos_set_keyboard (int code, int always) -{ - int i; - - /* Initialize to US settings, for countries that don't have their own. */ - keyboard = keyboard_layout_list[0].keyboard_map; - keyboard_map_all = always; - dos_keyboard_layout = 1; - - for (i = 0; i < countof (keyboard_layout_list); i++) - if (code == keyboard_layout_list[i].country_code) - { - keyboard = keyboard_layout_list[i].keyboard_map; - keyboard_map_all = always; - dos_keyboard_layout = code; - return 1; - } - return 0; -} - -#define Ignore 0x0000 -#define Normal 0x0000 /* normal key - alt changes scan-code */ -#define FctKey 0x1000 /* func key if c == 0, else c */ -#define Special 0x2000 /* func key even if c != 0 */ -#define ModFct 0x3000 /* special if mod-keys, else 'c' */ -#define Map 0x4000 /* alt scan-code, map to unshift/shift key */ -#define KeyPad 0x5000 /* map to insert/kp-0 depending on c == 0xe0 */ -#define Grey 0x6000 /* Grey keypad key */ - -#define Alt 0x0100 /* alt scan-code */ -#define Ctrl 0x0200 /* ctrl scan-code */ -#define Shift 0x0400 /* shift scan-code */ - -static struct -{ - unsigned char char_code; /* normal code */ - unsigned char meta_code; /* M- code */ - unsigned char keypad_code; /* keypad code */ - unsigned char editkey_code; /* edit key */ -} keypad_translate_map[] = { - '0', '0', 0xb0, /* kp-0 */ 0x63, /* insert */ - '1', '1', 0xb1, /* kp-1 */ 0x57, /* end */ - '2', '2', 0xb2, /* kp-2 */ 0x54, /* down */ - '3', '3', 0xb3, /* kp-3 */ 0x56, /* next */ - '4', '4', 0xb4, /* kp-4 */ 0x51, /* left */ - '5', '5', 0xb5, /* kp-5 */ 0xb5, /* kp-5 */ - '6', '6', 0xb6, /* kp-6 */ 0x53, /* right */ - '7', '7', 0xb7, /* kp-7 */ 0x50, /* home */ - '8', '8', 0xb8, /* kp-8 */ 0x52, /* up */ - '9', '9', 0xb9, /* kp-9 */ 0x55, /* prior */ - '.', '-', 0xae, /* kp-decimal */ 0xff /* delete */ -}; - -static struct -{ - unsigned char char_code; /* normal code */ - unsigned char keypad_code; /* keypad code */ -} grey_key_translate_map[] = { - '/', 0xaf, /* kp-decimal */ - '*', 0xaa, /* kp-multiply */ - '-', 0xad, /* kp-subtract */ - '+', 0xab, /* kp-add */ - '\r', 0x8d /* kp-enter */ -}; - -static unsigned short -ibmpc_translate_map[] = -{ - /* --------------- 00 to 0f --------------- */ - Normal | 0xff, /* Ctrl Break + Alt-NNN */ - Alt | ModFct | 0x1b, /* Escape */ - Normal | 1, /* '1' */ - Normal | 2, /* '2' */ - Normal | 3, /* '3' */ - Normal | 4, /* '4' */ - Normal | 5, /* '5' */ - Normal | 6, /* '6' */ - Normal | 7, /* '7' */ - Normal | 8, /* '8' */ - Normal | 9, /* '9' */ - Normal | 10, /* '0' */ - Normal | 11, /* '-' */ - Normal | 12, /* '=' */ - Special | 0x08, /* Backspace */ - ModFct | 0x74, /* Tab/Backtab */ - - /* --------------- 10 to 1f --------------- */ - Map | 15, /* 'q' */ - Map | 16, /* 'w' */ - Map | 17, /* 'e' */ - Map | 18, /* 'r' */ - Map | 19, /* 't' */ - Map | 20, /* 'y' */ - Map | 21, /* 'u' */ - Map | 22, /* 'i' */ - Map | 23, /* 'o' */ - Map | 24, /* 'p' */ - Map | 25, /* '[' */ - Map | 26, /* ']' */ - ModFct | 0x0d, /* Return */ - Ignore, /* Ctrl */ - Map | 30, /* 'a' */ - Map | 31, /* 's' */ - - /* --------------- 20 to 2f --------------- */ - Map | 32, /* 'd' */ - Map | 33, /* 'f' */ - Map | 34, /* 'g' */ - Map | 35, /* 'h' */ - Map | 36, /* 'j' */ - Map | 37, /* 'k' */ - Map | 38, /* 'l' */ - Map | 39, /* ';' */ - Map | 40, /* '\'' */ - Map | 0, /* '`' */ - Ignore, /* Left shift */ - Map | 41, /* '\\' */ - Map | 45, /* 'z' */ - Map | 46, /* 'x' */ - Map | 47, /* 'c' */ - Map | 48, /* 'v' */ - - /* --------------- 30 to 3f --------------- */ - Map | 49, /* 'b' */ - Map | 50, /* 'n' */ - Map | 51, /* 'm' */ - Map | 52, /* ',' */ - Map | 53, /* '.' */ - Map | 54, /* '/' */ - Ignore, /* Right shift */ - Grey | 1, /* Grey * */ - Ignore, /* Alt */ - Normal | ' ', /* ' ' */ - Ignore, /* Caps Lock */ - FctKey | 0xbe, /* F1 */ - FctKey | 0xbf, /* F2 */ - FctKey | 0xc0, /* F3 */ - FctKey | 0xc1, /* F4 */ - FctKey | 0xc2, /* F5 */ - - /* --------------- 40 to 4f --------------- */ - FctKey | 0xc3, /* F6 */ - FctKey | 0xc4, /* F7 */ - FctKey | 0xc5, /* F8 */ - FctKey | 0xc6, /* F9 */ - FctKey | 0xc7, /* F10 */ - Ignore, /* Num Lock */ - Ignore, /* Scroll Lock */ - KeyPad | 7, /* Home */ - KeyPad | 8, /* Up */ - KeyPad | 9, /* Page Up */ - Grey | 2, /* Grey - */ - KeyPad | 4, /* Left */ - KeyPad | 5, /* Keypad 5 */ - KeyPad | 6, /* Right */ - Grey | 3, /* Grey + */ - KeyPad | 1, /* End */ - - /* --------------- 50 to 5f --------------- */ - KeyPad | 2, /* Down */ - KeyPad | 3, /* Page Down */ - KeyPad | 0, /* Insert */ - KeyPad | 10, /* Delete */ - Shift | FctKey | 0xbe, /* (Shift) F1 */ - Shift | FctKey | 0xbf, /* (Shift) F2 */ - Shift | FctKey | 0xc0, /* (Shift) F3 */ - Shift | FctKey | 0xc1, /* (Shift) F4 */ - Shift | FctKey | 0xc2, /* (Shift) F5 */ - Shift | FctKey | 0xc3, /* (Shift) F6 */ - Shift | FctKey | 0xc4, /* (Shift) F7 */ - Shift | FctKey | 0xc5, /* (Shift) F8 */ - Shift | FctKey | 0xc6, /* (Shift) F9 */ - Shift | FctKey | 0xc7, /* (Shift) F10 */ - Ctrl | FctKey | 0xbe, /* (Ctrl) F1 */ - Ctrl | FctKey | 0xbf, /* (Ctrl) F2 */ - - /* --------------- 60 to 6f --------------- */ - Ctrl | FctKey | 0xc0, /* (Ctrl) F3 */ - Ctrl | FctKey | 0xc1, /* (Ctrl) F4 */ - Ctrl | FctKey | 0xc2, /* (Ctrl) F5 */ - Ctrl | FctKey | 0xc3, /* (Ctrl) F6 */ - Ctrl | FctKey | 0xc4, /* (Ctrl) F7 */ - Ctrl | FctKey | 0xc5, /* (Ctrl) F8 */ - Ctrl | FctKey | 0xc6, /* (Ctrl) F9 */ - Ctrl | FctKey | 0xc7, /* (Ctrl) F10 */ - Alt | FctKey | 0xbe, /* (Alt) F1 */ - Alt | FctKey | 0xbf, /* (Alt) F2 */ - Alt | FctKey | 0xc0, /* (Alt) F3 */ - Alt | FctKey | 0xc1, /* (Alt) F4 */ - Alt | FctKey | 0xc2, /* (Alt) F5 */ - Alt | FctKey | 0xc3, /* (Alt) F6 */ - Alt | FctKey | 0xc4, /* (Alt) F7 */ - Alt | FctKey | 0xc5, /* (Alt) F8 */ - - /* --------------- 70 to 7f --------------- */ - Alt | FctKey | 0xc6, /* (Alt) F9 */ - Alt | FctKey | 0xc7, /* (Alt) F10 */ - Ctrl | FctKey | 0x6d, /* (Ctrl) Sys Rq */ - Ctrl | KeyPad | 4, /* (Ctrl) Left */ - Ctrl | KeyPad | 6, /* (Ctrl) Right */ - Ctrl | KeyPad | 1, /* (Ctrl) End */ - Ctrl | KeyPad | 3, /* (Ctrl) Page Down */ - Ctrl | KeyPad | 7, /* (Ctrl) Home */ - Alt | Map | 1, /* '1' */ - Alt | Map | 2, /* '2' */ - Alt | Map | 3, /* '3' */ - Alt | Map | 4, /* '4' */ - Alt | Map | 5, /* '5' */ - Alt | Map | 6, /* '6' */ - Alt | Map | 7, /* '7' */ - Alt | Map | 8, /* '8' */ - - /* --------------- 80 to 8f --------------- */ - Alt | Map | 9, /* '9' */ - Alt | Map | 10, /* '0' */ - Alt | Map | 11, /* '-' */ - Alt | Map | 12, /* '=' */ - Ctrl | KeyPad | 9, /* (Ctrl) Page Up */ - FctKey | 0xc8, /* F11 */ - FctKey | 0xc9, /* F12 */ - Shift | FctKey | 0xc8, /* (Shift) F11 */ - Shift | FctKey | 0xc9, /* (Shift) F12 */ - Ctrl | FctKey | 0xc8, /* (Ctrl) F11 */ - Ctrl | FctKey | 0xc9, /* (Ctrl) F12 */ - Alt | FctKey | 0xc8, /* (Alt) F11 */ - Alt | FctKey | 0xc9, /* (Alt) F12 */ - Ctrl | KeyPad | 8, /* (Ctrl) Up */ - Ctrl | Grey | 2, /* (Ctrl) Grey - */ - Ctrl | KeyPad | 5, /* (Ctrl) Keypad 5 */ - - /* --------------- 90 to 9f --------------- */ - Ctrl | Grey | 3, /* (Ctrl) Grey + */ - Ctrl | KeyPad | 2, /* (Ctrl) Down */ - Ctrl | KeyPad | 0, /* (Ctrl) Insert */ - Ctrl | KeyPad | 10, /* (Ctrl) Delete */ - Ctrl | FctKey | 0x09, /* (Ctrl) Tab */ - Ctrl | Grey | 0, /* (Ctrl) Grey / */ - Ctrl | Grey | 1, /* (Ctrl) Grey * */ - Alt | FctKey | 0x50, /* (Alt) Home */ - Alt | FctKey | 0x52, /* (Alt) Up */ - Alt | FctKey | 0x55, /* (Alt) Page Up */ - Ignore, /* NO KEY */ - Alt | FctKey | 0x51, /* (Alt) Left */ - Ignore, /* NO KEY */ - Alt | FctKey | 0x53, /* (Alt) Right */ - Ignore, /* NO KEY */ - Alt | FctKey | 0x57, /* (Alt) End */ - - /* --------------- a0 to af --------------- */ - Alt | KeyPad | 2, /* (Alt) Down */ - Alt | KeyPad | 3, /* (Alt) Page Down */ - Alt | KeyPad | 0, /* (Alt) Insert */ - Alt | KeyPad | 10, /* (Alt) Delete */ - Alt | Grey | 0, /* (Alt) Grey / */ - Alt | FctKey | 0x09, /* (Alt) Tab */ - Alt | Grey | 4 /* (Alt) Keypad Enter */ -}; - -/* These bit-positions corresponds to values returned by BIOS */ -#define SHIFT_P 0x0003 /* two bits! */ -#define CTRL_P 0x0004 -#define ALT_P 0x0008 -#define SCRLOCK_P 0x0010 -#define NUMLOCK_P 0x0020 -#define CAPSLOCK_P 0x0040 -#define ALT_GR_P 0x0800 -#define SUPER_P 0x4000 /* pseudo */ -#define HYPER_P 0x8000 /* pseudo */ - -static int -dos_get_modifiers (int *keymask) -{ - union REGS regs; - int mask; - int modifiers = 0; - - /* Calculate modifier bits */ - regs.h.ah = extended_kbd ? 0x12 : 0x02; - int86 (0x16, ®s, ®s); - - if (!extended_kbd) - { - mask = regs.h.al & (SHIFT_P | CTRL_P | ALT_P | - SCRLOCK_P | NUMLOCK_P | CAPSLOCK_P); - } - else - { - mask = regs.h.al & (SHIFT_P | - SCRLOCK_P | NUMLOCK_P | CAPSLOCK_P); - - /* Do not break international keyboard support. */ - /* When Keyb.Com is loaded, the right Alt key is */ - /* used for accessing characters like { and } */ - if (regs.h.ah & 2) /* Left ALT pressed ? */ - mask |= ALT_P; - - if ((regs.h.ah & 8) != 0) /* Right ALT pressed ? */ - { - mask |= ALT_GR_P; - if (dos_hyper_key == 1) - { - mask |= HYPER_P; - modifiers |= hyper_modifier; - } - else if (dos_super_key == 1) - { - mask |= SUPER_P; - modifiers |= super_modifier; - } - } - - if (regs.h.ah & 1) /* Left CTRL pressed - mask |= CTRL_P; - - if (regs.h.ah & 4) /* Right CTRL pressed ? */ - { - if (dos_hyper_key == 2) - { - mask |= HYPER_P; - modifiers |= hyper_modifier; - } - else if (dos_super_key == 2) - { - mask |= SUPER_P; - modifiers |= super_modifier; - } - else - mask |= CTRL_P; - } - } - - if (mask & SHIFT_P) - modifiers |= shift_modifier; - if (mask & CTRL_P) - modifiers |= ctrl_modifier; - if (mask & ALT_P) - modifiers |= meta_modifier; - - if (keymask) - *keymask = mask; - return modifiers; -} - -#define NUM_RECENT_DOSKEYS (100) -int recent_doskeys_index; /* Index for storing next element into recent_doskeys */ -int total_doskeys; /* Total number of elements stored into recent_doskeys */ -Lisp_Object recent_doskeys; /* A vector, holding the last 100 keystrokes */ - -DEFUN ("recent-doskeys", Frecent_doskeys, 0, 0, 0, /* -Return vector of last 100 keyboard input values seen in dos_rawgetc. -Each input key receives two values in this vector: first the ASCII code, -and then the scan code. -*/ - ()) -{ - Lisp_Object *keys = XVECTOR_DATA (recent_doskeys); - Lisp_Object val; - - if (total_doskeys < NUM_RECENT_DOSKEYS) - return Fvector (total_doskeys, keys); - else - { - val = Fvector (NUM_RECENT_DOSKEYS, keys); - memcpy (XVECTOR_DATA (val), - keys + recent_doskeys_index, - (NUM_RECENT_DOSKEYS - recent_doskeys_index) * sizeof (Lisp_Object)); - memcpy (XVECTOR_DATA (val) + NUM_RECENT_DOSKEYS - recent_doskeys_index, - keys, - recent_doskeys_index * sizeof (Lisp_Object)); - return val; - } -} - -/* Get a char from keyboard. Function keys are put into the event queue. */ -static int -dos_rawgetc (void) -{ - struct input_event event; - union REGS regs; - -#ifndef HAVE_X_WINDOWS - SCREEN_SET_CURSOR (); - if (!mouse_visible) mouse_on (); -#endif - - /* The following condition is equivalent to `kbhit ()', except that - it uses the bios to do its job. This pleases DESQview/X. */ - while ((regs.h.ah = extended_kbd ? 0x11 : 0x01), - int86 (0x16, ®s, ®s), - (regs.x.flags & 0x40) == 0) - { - union REGS regs; - REGISTER unsigned char c; - int sc, code, mask, kp_mode; - int modifiers; - - regs.h.ah = extended_kbd ? 0x10 : 0x00; - int86 (0x16, ®s, ®s); - c = regs.h.al; - sc = regs.h.ah; - - total_doskeys += 2; - XVECTOR_DATA (recent_doskeys)[recent_doskeys_index++] = make_int (c); - if (recent_doskeys_index == NUM_RECENT_DOSKEYS) - recent_doskeys_index = 0; - XVECTOR_DATA (recent_doskeys)[recent_doskeys_index++] = make_int (sc); - if (recent_doskeys_index == NUM_RECENT_DOSKEYS) - recent_doskeys_index = 0; - - modifiers = dos_get_modifiers (&mask); - -#ifndef HAVE_X_WINDOWS - if (!NILP (Vdos_display_scancodes)) - { - char buf[10]; - sprintf (buf, "%02x:%02x*%04x", - (unsigned) (sc&0xff), (unsigned) c, mask); - dos_direct_output (screen_size_Y - 2, screen_size_X - 12, buf, 10); - } -#endif - - if (sc == 0xe0) - { - switch (c) - { - case 10: /* Ctrl Grey Enter */ - code = Ctrl | Grey | 4; - break; - case 13: /* Grey Enter */ - code = Grey | 4; - break; - case '/': /* Grey / */ - code = Grey | 0; - break; - default: - continue; - }; - c = 0; - } - else - { - if (sc >= countof (ibmpc_translate_map)) - continue; - if ((code = ibmpc_translate_map[sc]) == Ignore) - continue; - } - - if (c == 0) - { - if (code & Alt) - modifiers |= meta_modifier; - if (code & Ctrl) - modifiers |= ctrl_modifier; - if (code & Shift) - modifiers |= shift_modifier; - } - - switch (code & 0xf000) - { - case ModFct: - if (c && !(mask & (SHIFT_P | ALT_P | CTRL_P | HYPER_P | SUPER_P))) - return c; - c = 0; /* Special */ - - case FctKey: - if (c != 0) - return c; - - case Special: - code |= 0xff00; - break; - - case Normal: - if (sc == 0) - { - if (c == 0) /* ctrl-break */ - continue; - return c; /* ALT-nnn */ - } - if (!keyboard_map_all) - { - if (c != ' ') - return c; - code = c; - break; - } - - case Map: - if (c && !(mask & ALT_P) && !((mask & SHIFT_P) && (mask & CTRL_P))) - if (!keyboard_map_all) - return c; - - code &= 0xff; - if (mask & ALT_P && code <= 10 && code > 0 && dos_keypad_mode & 0x200) - mask |= SHIFT_P; /* ALT-1 => M-! etc. */ - - if (mask & SHIFT_P) - { - code = keyboard->shifted[code]; - mask -= SHIFT_P; - modifiers &= ~shift_modifier; - } - else - if ((mask & ALT_GR_P) && keyboard->alt_gr && keyboard->alt_gr[code] != ' ') - code = keyboard->alt_gr[code]; - else - code = keyboard->unshifted[code]; - break; - - case KeyPad: - code &= 0xff; - if (c == 0xe0) /* edit key */ - kp_mode = 3; - else - if ((mask & (NUMLOCK_P|CTRL_P|SHIFT_P|ALT_P)) == NUMLOCK_P) /* numlock on */ - kp_mode = dos_keypad_mode & 0x03; - else - kp_mode = (dos_keypad_mode >> 4) & 0x03; - - switch (kp_mode) - { - case 0: - if (code == 10 && dos_decimal_point) - return dos_decimal_point; - return keypad_translate_map[code].char_code; - - case 1: - code = 0xff00 | keypad_translate_map[code].keypad_code; - break; - - case 2: - code = keypad_translate_map[code].meta_code; - modifiers = meta_modifier; - break; - - case 3: - code = 0xff00 | keypad_translate_map[code].editkey_code; - break; - } - break; - - case Grey: - code &= 0xff; - kp_mode = ((mask & (NUMLOCK_P|CTRL_P|SHIFT_P|ALT_P)) == NUMLOCK_P) ? 0x04 : 0x40; - if (dos_keypad_mode & kp_mode) - code = 0xff00 | grey_key_translate_map[code].keypad_code; - else - code = grey_key_translate_map[code].char_code; - break; - } - - make_event: - if (code == 0) - continue; - - if (code >= 0x100) - event.kind = non_ascii_keystroke; - else - event.kind = ascii_keystroke; - event.code = code; - event.modifiers = modifiers; - XSETFRAME (event.frame_or_window, selected_frame); - event.timestamp = event_timestamp (); - kbd_buffer_store_event (&event); - } - - if (have_mouse > 0) - { - int but, press, x, y, ok; - - /* Check for mouse movement *before* buttons. */ - mouse_check_moved (); - - for (but = 0; but < NUM_MOUSE_BUTTONS; but++) - for (press = 0; press < 2; press++) - { - if (press) - ok = mouse_pressed (but, &x, &y); - else - ok = mouse_released (but, &x, &y); - if (ok) - { - event.kind = mouse_click; - event.code = but; - event.modifiers = dos_get_modifiers (0) - | (press ? down_modifier : up_modifier); - event.x = x; - event.y = y; - XSETFRAME (event.frame_or_window, selected_frame); - event.timestamp = event_timestamp (); - kbd_buffer_store_event (&event); - } - } - } - - return -1; -} - -static int prev_get_char = -1; - -/* Return 1 if a key is ready to be read without suspending execution. */ -dos_keysns (void) -{ - if (prev_get_char != -1) - return 1; - else - return ((prev_get_char = dos_rawgetc ()) != -1); -} - -/* Read a key. Return -1 if no key is ready. */ -dos_keyread (void) -{ - if (prev_get_char != -1) - { - int c = prev_get_char; - prev_get_char = -1; - return c; - } - else - return dos_rawgetc (); -} - -#ifndef HAVE_X_WINDOWS -/* See xterm.c for more info. */ -void -pixel_to_glyph_coords (FRAME_PTR f, REGISTER int pix_x, REGISTER int pix_y, - REGISTER int *x, REGISTER int *y, - void /* XRectangle */ *bounds, - int noclip) -{ - if (bounds) abort (); - - /* Ignore clipping. */ - - *x = pix_x; - *y = pix_y; -} - -void -glyph_to_pixel_coords (FRAME_PTR f, REGISTER int x, REGISTER int y, - REGISTER int *pix_x, REGISTER int *pix_y) -{ - *pix_x = x; - *pix_y = y; -} - -/* Simulation of X's menus. Nothing too fancy here -- just make it work - for now. - - Actually, I don't know the meaning of all the parameters of the functions - here -- I only know how they are called by xmenu.c. I could of course - grab the nearest Xlib manual (down the hall, second-to-last door on the - left), but I don't think it's worth the effort. */ - -static XMenu * -IT_menu_create (void) -{ - XMenu *menu; - - menu = (XMenu *) xmalloc (sizeof (XMenu)); - menu->allocated = menu->count = menu->panecount = menu->width = 0; - return menu; -} - -/* Allocate some (more) memory for MENU ensuring that there is room for one - for item. */ - -static void -IT_menu_make_room (XMenu *menu) -{ - if (menu->allocated == 0) - { - int count = menu->allocated = 10; - menu->text = (char **) xmalloc (count * sizeof (char *)); - menu->submenu = (XMenu **) xmalloc (count * sizeof (XMenu *)); - menu->panenumber = (int *) xmalloc (count * sizeof (int)); - } - else if (menu->allocated == menu->count) - { - int count = menu->allocated = menu->allocated + 10; - menu->text - = (char **) xrealloc (menu->text, count * sizeof (char *)); - menu->submenu - = (XMenu **) xrealloc (menu->submenu, count * sizeof (XMenu *)); - menu->panenumber - = (int *) xrealloc (menu->panenumber, count * sizeof (int)); - } -} - -/* Search the given menu structure for a given pane number. */ - -static XMenu * -IT_menu_search_pane (XMenu *menu, int pane) -{ - int i; - XMenu *try; - - for (i = 0; i < menu->count; i++) - if (menu->submenu[i]) - { - if (pane == menu->panenumber[i]) - return menu->submenu[i]; - if ((try = IT_menu_search_pane (menu->submenu[i], pane))) - return try; - } - return (XMenu *) 0; -} - -/* Determine how much screen space a given menu needs. */ - -static void -IT_menu_calc_size (XMenu *menu, int *width, int *height) -{ - int i, h2, w2, maxsubwidth, maxheight; - - maxsubwidth = 0; - maxheight = menu->count; - for (i = 0; i < menu->count; i++) - { - if (menu->submenu[i]) - { - IT_menu_calc_size (menu->submenu[i], &w2, &h2); - if (w2 > maxsubwidth) maxsubwidth = w2; - if (i + h2 > maxheight) maxheight = i + h2; - } - } - *width = menu->width + maxsubwidth; - *height = maxheight; -} - -/* Display MENU at (X,Y) using FACES. */ - -static void -IT_menu_display (XMenu *menu, int y, int x, int *faces) -{ - int i, j, face, width; - GLYPH *text, *p; - char *q; - int mx, my; - int enabled, mousehere; - int row, col; - - width = menu->width; - text = (GLYPH *) xmalloc ((width + 2) * sizeof (GLYPH)); - ScreenGetCursor (&row, &col); - mouse_get_xy (&mx, &my); - IT_update_begin (); - for (i = 0; i < menu->count; i++) - { - IT_cursor_to (y + i, x); - enabled - = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]); - mousehere = (y + i == my && x <= mx && mx < x + width + 2); - face = faces[enabled + mousehere * 2]; - p = text; - *p++ = FAST_MAKE_GLYPH (' ', face); - for (j = 0, q = menu->text[i]; *q; j++) - *p++ = FAST_MAKE_GLYPH (*q++, face); - for (; j < width; j++) - *p++ = FAST_MAKE_GLYPH (' ', face); - *p++ = FAST_MAKE_GLYPH (menu->submenu[i] ? 16 : ' ', face); - IT_write_glyphs (text, width + 2); - } - IT_update_end (); - IT_cursor_to (row, col); - xfree (text); -} - -/* --------------------------- X Menu emulation ---------------------- */ - -/* Create a brand new menu structure. */ - -XMenu * -XMenuCreate (Display *foo1, Window foo2, char *foo3) -{ - return IT_menu_create (); -} - -/* Create a new pane and place it on the outer-most level. It is not - clear that it should be placed out there, but I don't know what else - to do. */ - -int -XMenuAddPane (Display *foo, XMenu *menu, char *txt, int enable) -{ - int len; - - if (!enable) - abort (); - - IT_menu_make_room (menu); - menu->submenu[menu->count] = IT_menu_create (); - menu->text[menu->count] = txt; - menu->panenumber[menu->count] = ++menu->panecount; - menu->count++; - if ((len = strlen (txt)) > menu->width) - menu->width = len; - return menu->panecount; -} - -/* Create a new item in a menu pane. */ - -int -XMenuAddSelection (Display *bar, XMenu *menu, int pane, - int foo, char *txt, int enable) -{ - int len; - - if (pane) - if (!(menu = IT_menu_search_pane (menu, pane))) - return XM_FAILURE; - IT_menu_make_room (menu); - menu->submenu[menu->count] = (XMenu *) 0; - menu->text[menu->count] = txt; - menu->panenumber[menu->count] = enable; - menu->count++; - if ((len = strlen (txt)) > menu->width) - menu->width = len; - return XM_SUCCESS; -} - -/* Decide where the menu would be placed if requested at (X,Y). */ - -void -XMenuLocate (Display *foo0, XMenu *menu, int foo1, int foo2, int x, int y, - int *ulx, int *uly, int *width, int *height) -{ - if (menu->count == 1 && menu->submenu[0]) - /* Special case: the menu consists of only one pane. */ - IT_menu_calc_size (menu->submenu[0], width, height); - else - IT_menu_calc_size (menu, width, height); - *ulx = x + 1; - *uly = y; - *width += 2; -} - -struct IT_menu_state -{ - void *screen_behind; - XMenu *menu; - int pane; - int x, y; -}; - - -/* Display menu, wait for user's response, and return that response. */ - -int -XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, - int x0, int y0, unsigned ButtonMask, char **txt) -{ - struct IT_menu_state *state; - int statecount; - int x, y, i, b; - int screensize; - int faces[4], selectface; - int leave, result, onepane; - - /* Just in case we got here without a mouse present... */ - if (have_mouse <= 0) - return XM_IA_SELECT; - - state = alloca_array (struct IT_menu_state, menu->panecount); - screensize = screen_size * 2; - faces[0] - = compute_glyph_face (&the_only_frame, - face_name_id_number - (&the_only_frame, - intern ("msdos-menu-passive-face")), - 0); - faces[1] - = compute_glyph_face (&the_only_frame, - face_name_id_number - (&the_only_frame, - intern ("msdos-menu-active-face")), - 0); - selectface - = face_name_id_number (&the_only_frame, intern ("msdos-menu-select-face")); - faces[2] = compute_glyph_face (&the_only_frame, selectface, faces[0]); - faces[3] = compute_glyph_face (&the_only_frame, selectface, faces[1]); - - statecount = 1; - state[0].menu = menu; - mouse_off (); - ScreenRetrieve (state[0].screen_behind = xmalloc (screensize)); - if ((onepane = menu->count == 1 && menu->submenu[0])) - { - menu->width = menu->submenu[0]->width; - state[0].menu = menu->submenu[0]; - } - else - { - state[0].menu = menu; - } - state[0].x = x0 - 1; - state[0].y = y0; - state[0].pane = onepane; - - mouse_last_x = -1; /* A hack that forces display. */ - leave = 0; - while (!leave) - { - if (!mouse_visible) mouse_on (); - mouse_check_moved (); - if (selected_frame->mouse_moved) - { - selected_frame->mouse_moved = 0; - result = XM_IA_SELECT; - mouse_get_xy (&x, &y); - for (i = 0; i < statecount; i++) - if (state[i].x <= x && x < state[i].x + state[i].menu->width + 2) - { - int dy = y - state[i].y; - if (0 <= dy && dy < state[i].menu->count) - { - if (!state[i].menu->submenu[dy]) - if (state[i].menu->panenumber[dy]) - result = XM_SUCCESS; - else - result = XM_IA_SELECT; - *pane = state[i].pane - 1; - *selidx = dy; - /* We hit some part of a menu, so drop extra menues that - have been opened. That does not include an open and - active submenu. */ - if (i != statecount - 2 - || state[i].menu->submenu[dy] != state[i+1].menu) - while (i != statecount - 1) - { - statecount--; - mouse_off (); - ScreenUpdate (state[statecount].screen_behind); - xfree (state[statecount].screen_behind); - } - if (i == statecount - 1 && state[i].menu->submenu[dy]) - { - IT_menu_display (state[i].menu, - state[i].y, - state[i].x, - faces); - state[statecount].menu = state[i].menu->submenu[dy]; - state[statecount].pane = state[i].menu->panenumber[dy]; - mouse_off (); - ScreenRetrieve (state[statecount].screen_behind - = xmalloc (screensize)); - state[statecount].x - = state[i].x + state[i].menu->width + 2; - state[statecount].y = y; - statecount++; - } - } - } - IT_menu_display (state[statecount - 1].menu, - state[statecount - 1].y, - state[statecount - 1].x, - faces); - } - for (b = 0; b < mouse_button_count; b++) - { - (void) mouse_pressed (b, &x, &y); - if (mouse_released (b, &x, &y)) - leave = 1; - } - } - - mouse_off (); - ScreenUpdate (state[0].screen_behind); - while (statecount--) - xfree (state[statecount].screen_behind); - return result; -} - -/* Dispose of a menu. */ - -void -XMenuDestroy (Display *foo, XMenu *menu) -{ - int i; - if (menu->allocated) - { - for (i = 0; i < menu->count; i++) - if (menu->submenu[i]) - XMenuDestroy (foo, menu->submenu[i]); - xfree (menu->text); - xfree (menu->submenu); - xfree (menu->panenumber); - } - xfree (menu); -} - -int -x_pixel_width (struct frame *f) -{ - return FRAME_WIDTH (f); -} - -int -x_pixel_height (struct frame *f) -{ - return FRAME_HEIGHT (f); -} -#endif /* !HAVE_X_WINDOWS */ - - -/* ----------------------- DOS / UNIX conversion --------------------- */ - -/* Destructively turn backslashes into slashes. */ - -void -dostounix_filename (REGISTER char *p) -{ - while (*p) - { - if (*p == '\\') - *p = '/'; - p++; - } -} - -/* Destructively turn slashes into backslashes. */ - -void -unixtodos_filename (REGISTER char *p) -{ - while (*p) - { - if (*p == '/') - *p = '\\'; - p++; - } -} - -/* Get the default directory for a given drive. 0=def, 1=A, 2=B, ... */ - -int -getdefdir (int drive, char *dst) -{ - union REGS regs; - - *dst++ = '/'; - regs.h.dl = drive; - regs.x.si = (int) dst; - regs.h.ah = 0x47; - intdos (®s, ®s); - return !regs.x.cflag; -} - -/* Remove all CR's that are followed by a LF. */ - -int -crlf_to_lf (REGISTER int n, REGISTER unsigned char *buf) -{ - unsigned char *np = buf; - unsigned char *startp = buf; - unsigned char *endp = buf + n; - unsigned char c; - - if (n == 0) - return n; - while (buf < endp - 1) - { - if (*buf == 0x0d) - { - if (*(++buf) != 0x0a) - *np++ = 0x0d; - } - else - *np++ = *buf++; - } - if (buf < endp) - *np++ = *buf++; - return np - startp; -} - -/* The Emacs root directory as determined by init_environment. */ - -static char emacsroot[MAXPATHLEN]; - -char * -rootrelativepath (char *rel) -{ - static char result[MAXPATHLEN + 10]; - - strcpy (result, emacsroot); - strcat (result, "/"); - strcat (result, rel); - return result; -} - -/* Define a lot of environment variables if not already defined. Don't - remove anything unless you know what you're doing -- lots of code will - break if one or more of these are missing. */ - -void -init_environment (int argc, char **argv, int skip_args) -{ - char *s, *t, *root; - int len; - - if (!initialized) - return; - - /* Find our root from argv[0]. Assuming argv[0] is, say, - "c:/emacs/bin/emacs.exe" our root will be "c:/emacs". */ - root = alloca (MAXPATHLEN + 20); - _fixpath (argv[0], root); - strlwr (root); - len = strlen (root); - while (len > 0 && root[len] != '/' && root[len] != ':') - len--; - root[len] = '\0'; - if (len > 4 && strcmp (root + len - 4, "/bin") == 0) - root[len - 4] = '\0'; - else - strcpy (root, "c:/emacs"); /* Only under debuggers, I think. */ - len = strlen (root); - strcpy (emacsroot, root); - - /* We default HOME to our root. */ - setenv ("HOME", root, 0); - - /* We default EMACSPATH to root + "/bin". */ - strcpy (root + len, "/bin"); - setenv ("EMACSPATH", root, 0); - - /* I don't expect anybody to ever use other terminals so the internal - terminal is the default. */ - setenv ("TERM", "internal", 0); - -#ifdef HAVE_X_WINDOWS - /* Emacs expects DISPLAY to be set. */ - setenv ("DISPLAY", "unix:0.0", 0); -#endif - - /* SHELL is a bit tricky -- COMSPEC is the closest we come, but we must - downcase it and mirror the backslashes. */ - s = getenv ("COMSPEC"); - if (!s) s = "c:/command.com"; - t = alloca (strlen (s) + 1); - strcpy (t, s); - strlwr (t); - dostounix_filename (t); - setenv ("SHELL", t, 0); - - /* PATH is also downcased and backslashes mirrored. */ - s = getenv ("PATH"); - if (!s) s = ""; - t = alloca (strlen (s) + 3); - /* Current directory is always considered part of MsDos's path but it is - not normally mentioned. Now it is. */ - strcat (strcpy (t, ".;"), s); - strlwr (t); - dostounix_filename (t); /* Not a single file name, but this should work. */ - setenv ("PATH", t, 1); - - /* In some sense all dos users have root privileges, so... */ - setenv ("USER", "root", 0); - setenv ("NAME", getenv ("USER"), 0); - - /* Time zone determined from country code. To make this possible, the - country code may not span more than one time zone. In other words, - in the USA, you lose. */ - if (!getenv ("TZ")) - switch (dos_country_code) - { - case 31: /* Belgium */ - case 32: /* The Netherlands */ - case 33: /* France */ - case 34: /* Spain */ - case 36: /* Hungary */ - case 38: /* Yugoslavia (or what's left of it?) */ - case 39: /* Italy */ - case 41: /* Switzerland */ - case 42: /* Tjekia */ - case 45: /* Denmark */ - case 46: /* Sweden */ - case 47: /* Norway */ - case 48: /* Poland */ - case 49: /* Germany */ - /* Daylight saving from last Sunday in March to last Sunday in - September, both at 2AM. */ - setenv ("TZ", "MET-01METDST-02,M3.5.0/02:00,M9.5.0/02:00", 0); - break; - case 44: /* United Kingdom */ - case 351: /* Portugal */ - case 354: /* Iceland */ - setenv ("TZ", "GMT+00", 0); - break; - case 81: /* Japan */ - case 82: /* Korea */ - setenv ("TZ", "JST-09", 0); - break; - case 90: /* Turkey */ - case 358: /* Finland */ - setenv ("TZ", "EET-02", 0); - break; - case 972: /* Israel */ - /* This is an approximation. (For exact rules, use the - `zoneinfo/israel' file which comes with DJGPP, but you need - to install it in `/usr/share/zoneinfo/' directory first.) */ - setenv ("TZ", "IST-02IDT-03,M4.1.6/00:00,M9.5.6/01:00", 0); - break; - } - init_gettimeofday (); -} - - - -static int break_stat; /* BREAK check mode status. */ -static int stdin_stat; /* stdin IOCTL status. */ - -/* These must be global. */ -static _go32_dpmi_seginfo ctrl_break_vector; -static _go32_dpmi_registers ctrl_break_regs; -static int ctrlbreakinstalled = 0; - -/* Interrupt level detection of Ctrl-Break. Don't do anything fancy here! */ - -void -ctrl_break_func (_go32_dpmi_registers *regs) -{ - Vquit_flag = Qt; -} - -void -install_ctrl_break_check (void) -{ - if (!ctrlbreakinstalled) - { - /* Don't press Ctrl-Break if you don't have either DPMI or Emacs - was compiler with Djgpp 1.11 maintenance level 5 or later! */ - ctrlbreakinstalled = 1; - ctrl_break_vector.pm_offset = (int) ctrl_break_func; - _go32_dpmi_allocate_real_mode_callback_iret (&ctrl_break_vector, - &ctrl_break_regs); - _go32_dpmi_set_real_mode_interrupt_vector (0x1b, &ctrl_break_vector); - } -} - -/* - * Turn off Dos' Ctrl-C checking and inhibit interpretation of - * control chars by Dos. - * Determine the keyboard type. - */ - -int -dos_ttraw (void) -{ - union REGS inregs, outregs; - static int first_time = 1; - - break_stat = getcbrk (); - setcbrk (0); - install_ctrl_break_check (); - - if (first_time) - { - inregs.h.ah = 0xc0; - int86 (0x15, &inregs, &outregs); - extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0); - - have_mouse = 0; - - if (internal_terminal -#ifdef HAVE_X_WINDOWS - && inhibit_window_system -#endif - ) - { - inregs.x.ax = 0x0021; - int86 (0x33, &inregs, &outregs); - have_mouse = (outregs.x.ax & 0xffff) == 0xffff; - if (!have_mouse) - { - /* Reportedly, the above doesn't work for some mouse drivers. There - is an additional detection method that should work, but might be - a little slower. Use that as an alternative. */ - inregs.x.ax = 0x0000; - int86 (0x33, &inregs, &outregs); - have_mouse = (outregs.x.ax & 0xffff) == 0xffff; - } - - if (have_mouse) - { - have_mouse = 1; /* enable mouse */ - mouse_visible = 0; - - if (outregs.x.bx == 3) - { - mouse_button_count = 3; - mouse_button_translate[0] = 0; /* Left */ - mouse_button_translate[1] = 2; /* Middle */ - mouse_button_translate[2] = 1; /* Right */ - } - else - { - mouse_button_count = 2; - mouse_button_translate[0] = 0; - mouse_button_translate[1] = 1; - } - mouse_position_hook = &mouse_get_pos; - mouse_init (); - } - } - - first_time = 0; - } - - inregs.x.ax = 0x4400; /* Get IOCTL status. */ - inregs.x.bx = 0x00; /* 0 = stdin. */ - intdos (&inregs, &outregs); - stdin_stat = outregs.h.dl; - - inregs.x.dx = stdin_stat | 0x0020; /* raw mode */ - inregs.x.ax = 0x4401; /* Set IOCTL status */ - intdos (&inregs, &outregs); - return !outregs.x.cflag; -} - -/* Restore status of standard input and Ctrl-C checking. */ -int -dos_ttcooked (void) -{ - union REGS inregs, outregs; - - setcbrk (break_stat); - mouse_off (); - - inregs.x.ax = 0x4401; /* Set IOCTL status. */ - inregs.x.bx = 0x00; /* 0 = stdin. */ - inregs.x.dx = stdin_stat; - intdos (&inregs, &outregs); - return !outregs.x.cflag; -} - - -/* Run command as specified by ARGV in directory DIR. - The command is run with input from TEMPIN and output to file TEMPOUT. */ -int -run_msdos_command (unsigned char **argv, Lisp_Object dir, - int tempin, int tempout) -{ - char *saveargv1, *saveargv2, **envv; - char oldwd[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ - int msshell, result = -1; - int in, out, inbak, outbak, errbak; - int x, y; - Lisp_Object cmd; - - /* Get current directory as MSDOS cwd is not per-process. */ - getwd (oldwd); - - cmd = Ffile_name_nondirectory (build_string (argv[0])); - msshell = !NILP (Fmember (cmd, Fsymbol_value (intern ("msdos-shells")))) - && !strcmp ("-c", argv[1]); - if (msshell) - { - saveargv1 = argv[1]; - saveargv2 = argv[2]; - argv[1] = "/c"; - if (argv[2]) - { - char *p = alloca (strlen (argv[2]) + 1); - - strcpy (argv[2] = p, saveargv2); - while (*p && isspace ((unsigned char) *p)) - p++; - while (*p && !isspace ((unsigned char) *p)) - if (*p == '/') - *p++ = '\\'; - else - p++; - } - } - - /* Build the environment array. */ - { - extern Lisp_Object Vprocess_environment; - Lisp_Object tmp, lst; - int i, len; - - lst = Vprocess_environment; - len = XINT (Flength (lst)); - - envv = alloca_array (char *, len + 1); - for (i = 0; i < len; i++) - { - tmp = Fcar (lst); - lst = Fcdr (lst); - CHECK_STRING (tmp); - envv[i] = alloca (XSTRING_LENGTH (tmp) + 1); - strcpy (envv[i], XSTRING_DATA (tmp)); - } - envv[len] = (char *) 0; - } - - if (STRINGP (dir)) - chdir (XSTRING_DATA (dir)); - inbak = dup (0); - outbak = dup (1); - errbak = dup (2); - if (inbak < 0 || outbak < 0 || errbak < 0) - goto done; /* Allocation might fail due to lack of descriptors. */ - - if (have_mouse > 0) - mouse_get_xy (&x, &y); - - dos_ttcooked (); /* do it here while 0 = stdin */ - - dup2 (tempin, 0); - dup2 (tempout, 1); - dup2 (tempout, 2); - - result = spawnve (P_WAIT, argv[0], argv, envv); - - dup2 (inbak, 0); - dup2 (outbak, 1); - dup2 (errbak, 2); - close (inbak); - close (outbak); - close (errbak); - - dos_ttraw (); - if (have_mouse > 0) - { - mouse_init (); - mouse_moveto (x, y); - } - - done: - chdir (oldwd); - if (msshell) - { - argv[1] = saveargv1; - argv[2] = saveargv2; - } - return result; -} - -croak (char *badfunc) -{ - stderr_out ("%s not yet implemented\r\n", badfunc); - reset_sys_modes (); - exit (1); -} - - -/* ------------------------- Compatibility functions ------------------- - * gethostname - * gettimeofday - */ - -/* - * Hostnames for a pc are not really funny, - * but they are used in change log so we emulate the best we can. - */ - -gethostname (char *p, int size) -{ - char *q = egetenv ("HOSTNAME"); - - if (!q) q = "pc"; - strcpy (p, q); - return 0; -} - -/* When time zones are set from Ms-Dos too many C-libraries are playing - tricks with time values. We solve this by defining our own version - of `gettimeofday' bypassing GO32. Our version needs to be initialized - once and after each call to `tzset' with TZ changed. That is - accomplished by aliasing tzset to init_gettimeofday. */ - -static struct tm time_rec; - -int -gettimeofday (struct timeval *tp, struct timezone *tzp) -{ - if (tp) - { - struct time t; - struct tm tm; - - gettime (&t); - if (t.ti_hour < time_rec.tm_hour) /* midnight wrap */ - { - struct date d; - getdate (&d); - time_rec.tm_year = d.da_year - 1900; - time_rec.tm_mon = d.da_mon - 1; - time_rec.tm_mday = d.da_day; - } - - time_rec.tm_hour = t.ti_hour; - time_rec.tm_min = t.ti_min; - time_rec.tm_sec = t.ti_sec; - - tm = time_rec; - tm.tm_gmtoff = dos_timezone_offset; - - tp->tv_sec = mktime (&tm); /* may modify tm */ - tp->tv_usec = t.ti_hund * (1000000 / 100); - } - /* Ignore tzp; it's obsolescent. */ - return 0; -} - - -/* - * A list of unimplemented functions that we silently ignore. - */ - -unsigned alarm (unsigned int s) {} -fork (void) { return 0; } -int kill (int x, int y) { return -1; } -nice (int p) {} -void volatile pause (void) {} -request_sigio (void) {} -setpgrp (void) {return 0; } -setpriority (int x, int y, int z) { return 0; } -sigsetmask (int x) { return 0; } -unrequest_sigio (void) {} - -int run_dos_timer_hooks = 0; - -#ifndef HAVE_SELECT -#include "sysselect.h" - -static int last_ti_sec = -1; -static int dos_menubar_clock_displayed = 0; - -static void -check_timer (struct time *t) -{ - gettime (t); - - if (t->ti_sec == last_ti_sec) - return; - last_ti_sec = t->ti_sec; - - if (!NILP (Vdos_menubar_clock)) - { - char clock_str[16]; - int len; - int min = t->ti_min; - int hour = t->ti_hour; - - if (dos_timezone_offset) - { - int tz = dos_timezone_offset; - min -= tz % 60; - if (min < 0) - min += 60, hour--; - else - if (min >= 60) - min -= 60, hour++; - - if ((hour -= (tz / 60)) < 0) - hour += 24; - else - hour %= 24; - } - - if ((dos_country_info[0x11] & 0x01) == 0) /* 12 hour clock */ - { - hour %= 12; - if (hour == 0) hour = 12; - } - - len = sprintf (clock_str, "%2d.%02d.%02d", hour, min, t->ti_sec); - dos_direct_output (0, screen_size_X - len - 1, clock_str, len); - dos_menubar_clock_displayed = 1; - } - else if (dos_menubar_clock_displayed) - { - /* Erase last displayed time. */ - dos_direct_output (0, screen_size_X - 9, " ", 8); - dos_menubar_clock_displayed = 0; - } - - if (!NILP (Vdos_timer_hooks)) - run_dos_timer_hooks++; -} - -/* Only event queue is checked. */ -int -sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, - EMACS_TIME *timeout) -{ - int check_input; - long timeoutval, clnow, cllast; - struct time t; - - check_input = 0; - if (rfds) - { - check_input = FD_ISSET (0, rfds); - FD_ZERO (rfds); - } - if (wfds) - FD_ZERO (wfds); - if (efds) - FD_ZERO (efds); - - if (nfds != 1) - abort (); - - /* If we are looking only for the terminal, with no timeout, - just read it and wait -- that's more efficient. */ - if (!timeout) - { - while (! detect_input_pending ()) - check_timer (&t); - } - else - { - timeoutval = EMACS_SECS (*timeout) * 100 + EMACS_USECS (*timeout) / 10000; - check_timer (&t); - cllast = t.ti_sec * 100 + t.ti_hund; - - while (!check_input || !detect_input_pending ()) - { - check_timer (&t); - clnow = t.ti_sec * 100 + t.ti_hund; - if (clnow < cllast) /* time wrap */ - timeoutval -= clnow + 6000 - cllast; - else - timeoutval -= clnow - cllast; - if (timeoutval <= 0) /* Stop on timer being cleared */ - return 0; - cllast = clnow; - } - } - - FD_SET (0, rfds); - return 1; -} -#endif - -/* - * Define overlayed functions: - * - * chdir -> sys_chdir - * tzset -> init_gettimeofday - * abort -> dos_abort - */ - -#ifdef chdir -#undef chdir -extern int chdir (CONST char *); - -int -sys_chdir (CONST char* path) -{ - int len = strlen (path); - char *tmp = (char *)path; - - if (*tmp && tmp[1] == ':') - { - if (getdisk () != tolower (tmp[0]) - 'a') - setdisk (tolower (tmp[0]) - 'a'); - tmp += 2; /* strip drive: KFS 1995-07-06 */ - len -= 2; - } - - if (len > 1 && (tmp[len - 1] == '/')) - { - char *tmp1 = (char *) alloca (len + 1); - strcpy (tmp1, tmp); - tmp1[len - 1] = 0; - tmp = tmp1; - } - return chdir (tmp); -} -#endif - -#ifdef tzset -#undef tzset -extern void tzset (void); - -void -init_gettimeofday (void) -{ - time_t ltm, gtm; - struct tm *lstm; - - tzset (); - ltm = gtm = time (NULL); - ltm = mktime (lstm = localtime (<m)); - gtm = mktime (gmtime (>m)); - time_rec.tm_hour = 99; /* force gettimeofday to get date */ - time_rec.tm_isdst = lstm->tm_isdst; - dos_timezone_offset = time_rec.tm_gmtoff = (int)(gtm - ltm) / 60; -} -#endif - -#ifdef abort -#undef abort -void -dos_abort (char *file, int line) -{ - char buffer1[200], buffer2[400]; - int i, j; - - sprintf (buffer1, "", file, line); - for (i = j = 0; buffer1[i]; i++) { - buffer2[j++] = buffer1[i]; - buffer2[j++] = 0x70; - } - dosmemput (buffer2, j, (int)ScreenPrimary); - ScreenSetCursor (2, 0); - abort (); -} -#endif - -void -syms_of_msdos (void) -{ - DEFSUBR (Frecent_doskeys); -} - -void -vars_of_msdos (void) -{ - recent_doskeys = Fmake_vector (make_int (NUM_RECENT_DOSKEYS), Qnil); - staticpro (&recent_doskeys); - -} - -#endif /* MSDOS */ diff -r 6e6992ccc4b6 -r c9fe270a4101 src/msdos.h --- a/src/msdos.h Mon Aug 13 10:35:55 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* MS-DOS specific C utilities, interface. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of XEmacs. - -XEmacs 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 2, or (at your option) any -later version. - -XEmacs 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 XEmacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Synched up with: FSF 19.28. */ - -#include -#include - -int dos_ttraw (); -int dos_ttcooked (); -int getdefdir (int, char*); -void unixtodos_filename (char *); -void dostounix_filename (char *); -void sleep_or_kbd_hit (int, int); -char *rootrelativepath (char *); -void init_environment (); -void internal_terminal_init (); -#ifndef _stdio_h_ -int internal_flush (FILE *); -#endif -void ctrl_break_func (_go32_dpmi_registers *); -void install_ctrl_break_check (); - -extern int have_mouse; -int mouse_init1 (); -void mouse_init (); -void mouse_on (); -void mouse_off (); -void mouse_moveto (int, int); -void mouse_check_moved (); -int mouse_pressed (int, int *, int *); -int mouse_released (int, int *, int *); -void init_gettimeofday (); diff -r 6e6992ccc4b6 -r c9fe270a4101 src/nt.c --- a/src/nt.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/nt.c Mon Aug 13 10:36:47 2007 +0200 @@ -24,51 +24,28 @@ /* Adapted for XEmacs by David Hobley */ /* Sync'ed with Emacs 19.34.6 by Marc Paquette */ -#include /* for offsetof */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -/* must include CRT headers *before* config.h */ -/* ### I don't believe it - martin */ -#include +#undef signal +#define getwd _getwd +#include "lisp.h" +#undef getwd + #include "systime.h" #include "syssignal.h" #include "sysproc.h" -#undef access -#undef chdir -#undef chmod -#undef creat -#undef ctime -#undef fopen -#undef link -#undef mkdir -#undef mktemp -#undef open -#undef rename -#undef rmdir -#undef unlink - -#undef close -#undef dup -#undef dup2 -#undef pipe -#undef read -#undef write -#undef closedir - -#define getwd _getwd -#include "lisp.h" -#undef getwd - +#include +#include +#include +#include +#include #include +#include +#include /* for offsetof */ +#include +#include +#include #include #include @@ -1215,230 +1192,8 @@ return &dir_static; } -/* Shadow some MSVC runtime functions to map requests for long filenames - to reasonable short names if necessary. This was originally added to - permit running Emacs on NT 3.1 on a FAT partition, which doesn't support - long file names. */ - -int -sys_access (const char * path, int mode) -{ - return _access (map_win32_filename (path, NULL), mode); -} - -int -sys_chdir (const char * path) -{ - return _chdir (map_win32_filename (path, NULL)); -} - -int -sys_chmod (const char * path, mode_t mode) -{ - return _chmod (map_win32_filename (path, NULL), mode); -} - -int -sys_creat (const char * path, mode_t mode) -{ - return _creat (map_win32_filename (path, NULL), mode); -} - -FILE * -sys_fopen(const char * path, const char * mode) -{ - int fd; - int oflag; - const char * mode_save = mode; - - /* Force all file handles to be non-inheritable. This is necessary to - ensure child processes don't unwittingly inherit handles that might - prevent future file access. */ - - if (mode[0] == 'r') - oflag = O_RDONLY; - else if (mode[0] == 'w' || mode[0] == 'a') - oflag = O_WRONLY | O_CREAT | O_TRUNC; - else - return NULL; - - /* Only do simplistic option parsing. */ - while (*++mode) - if (mode[0] == '+') - { - oflag &= ~(O_RDONLY | O_WRONLY); - oflag |= O_RDWR; - } - else if (mode[0] == 'b') - { - oflag &= ~O_TEXT; - oflag |= O_BINARY; - } - else if (mode[0] == 't') - { - oflag &= ~O_BINARY; - oflag |= O_TEXT; - } - else break; - - fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644); - if (fd < 0) - return NULL; - - return _fdopen (fd, mode_save); -} - -/* This only works on NTFS volumes, but is useful to have. */ -int -sys_link (const char * old, const char * new) -{ - HANDLE fileh; - int result = -1; - char oldname[MAX_PATH], newname[MAX_PATH]; - - if (old == NULL || new == NULL) -{ - errno = ENOENT; - return -1; -} - - strcpy (oldname, map_win32_filename (old, NULL)); - strcpy (newname, map_win32_filename (new, NULL)); - - fileh = CreateFile (oldname, 0, 0, NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (fileh != INVALID_HANDLE_VALUE) - { - int wlen; - - /* Confusingly, the "alternate" stream name field does not apply - when restoring a hard link, and instead contains the actual - stream data for the link (ie. the name of the link to create). - The WIN32_STREAM_ID structure before the cStreamName field is - the stream header, which is then immediately followed by the - stream data. */ - - struct { - WIN32_STREAM_ID wid; - WCHAR wbuffer[MAX_PATH]; /* extra space for link name */ - } data; - - wlen = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, newname, -1, - data.wid.cStreamName, MAX_PATH); - if (wlen > 0) - { - LPVOID context = NULL; - DWORD wbytes = 0; - - data.wid.dwStreamId = BACKUP_LINK; - data.wid.dwStreamAttributes = 0; - data.wid.Size.LowPart = wlen * sizeof(WCHAR); - data.wid.Size.HighPart = 0; - data.wid.dwStreamNameSize = 0; - - if (BackupWrite (fileh, (LPBYTE)&data, - offsetof (WIN32_STREAM_ID, cStreamName) - + data.wid.Size.LowPart, - &wbytes, FALSE, FALSE, &context) - && BackupWrite (fileh, NULL, 0, &wbytes, TRUE, FALSE, &context)) - { - /* succeeded */ - result = 0; - } - else - { - /* Should try mapping GetLastError to errno; for now just - indicate a general error (eg. links not supported). */ - errno = EINVAL; // perhaps EMLINK? - } - } - - CloseHandle (fileh); - } - else - errno = ENOENT; - - return result; -} - -int -sys_mkdir (const char * path, int mode_unused) -{ - return _mkdir (map_win32_filename (path, NULL)); -} - -/* Because of long name mapping issues, we need to implement this - ourselves. Also, MSVC's _mktemp returns NULL when it can't generate - a unique name, instead of setting the input template to an empty - string. - - Standard algorithm seems to be use pid or tid with a letter on the - front (in place of the 6 X's) and cycle through the letters to find a - unique name. We extend that to allow any reasonable character as the - first of the 6 X's. */ -char * -sys_mktemp (char * template) -{ - char * p; - int i; - unsigned uid = GetCurrentThreadId (); - static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; - - if (template == NULL) - return NULL; - p = template + strlen (template); - i = 5; - /* replace up to the last 5 X's with uid in decimal */ - while (--p >= template && p[0] == 'X' && --i >= 0) - { - p[0] = '0' + uid % 10; - uid /= 10; - } - - if (i < 0 && p[0] == 'X') - { - i = 0; - do - { - int save_errno = errno; - p[0] = first_char[i]; - if (sys_access (template, 0) < 0) - { - errno = save_errno; - return template; - } - } - while (++i < sizeof (first_char)); - } - - /* Template is badly formed or else we can't generate a unique name, - so return empty string */ - template[0] = 0; - return template; -} - -int -sys_open (const char * path, int oflag, int mode) -{ - int fd; - - /* Force all file handles to be non-inheritable. */ - fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, mode); - - if (fd >= MAXDESC) - { - _close (fd); - errno = EMFILE; - return -1; - } - - if (fd >= 0) - { - fd_info[fd].cp = 0; - } - return (fd); -} - +#if 0 +/* #### Have to check if all that sad story about '95 is true - kkm */ int sys_rename (const char * oldname, const char * newname) { @@ -1494,18 +1249,7 @@ return rename (temp, newname); } - -int -sys_rmdir (const char * path) -{ - return _rmdir (map_win32_filename (path, NULL)); -} - -int -sys_unlink (const char * path) -{ - return _unlink (map_win32_filename (path, NULL)); -} +#endif /* 0 */ static FILETIME utc_base_ft; static long double utc_base; @@ -1812,95 +1556,6 @@ return 0; } -/* Shadow main io functions: we need to handle pipes and sockets more - intelligently, and implement non-blocking mode as well. */ - -int -sys_close (int fd) -{ - int rc; - - if (fd < 0 || fd >= MAXDESC) - { - errno = EBADF; - return -1; - } - - if (fd_info[fd].cp) - { - child_process * cp = fd_info[fd].cp; - - fd_info[fd].cp = NULL; - - if (CHILD_ACTIVE (cp)) - { - /* if last descriptor to active child_process then cleanup */ - int i; - for (i = 0; i < MAXDESC; i++) - { - if (i == fd) - continue; - if (fd_info[i].cp == cp) - break; - } - if (i == MAXDESC) - { - delete_child (cp); - } - } - } - - /* Note that sockets do not need special treatment here (at least on - NT and Win95 using the standard tcp/ip stacks) - it appears that - closesocket is equivalent to CloseHandle, which is to be expected - because socket handles are fully fledged kernel handles. */ - rc = _close (fd); - - if (rc == 0) - fd_info[fd].flags = 0; - - return rc; -} - -int -sys_dup (int fd) -{ - int new_fd; - - new_fd = _dup (fd); - if (new_fd >= 0) - { - /* duplicate our internal info as well */ - fd_info[new_fd] = fd_info[fd]; - } - return new_fd; -} - - -int -sys_dup2 (int src, int dst) -{ - int rc; - - if (dst < 0 || dst >= MAXDESC) - { - errno = EBADF; - return -1; - } - - /* make sure we close the destination first if it's a pipe or socket */ - if (src != dst && fd_info[dst].flags != 0) - sys_close (dst); - - rc = _dup2 (src, dst); - if (rc == 0) - { - /* duplicate our internal info as well */ - fd_info[dst] = fd_info[src]; - } - return rc; -} - /* From callproc.c */ extern Lisp_Object Vbinary_process_input; extern Lisp_Object Vbinary_process_output; @@ -1995,182 +1650,6 @@ return cp->status; } -int -sys_read (int fd, char * buffer, size_t count) -{ - int nchars; - int to_read; - DWORD waiting; - char * orig_buffer = buffer; - - if (fd < 0 || fd >= MAXDESC) - { - errno = EBADF; - return -1; - } - - if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) - { - child_process *cp = fd_info[fd].cp; - - if ((fd_info[fd].flags & FILE_READ) == 0) - { - errno = EBADF; - return -1; - } - - nchars = 0; - - /* re-read CR carried over from last read */ - if (fd_info[fd].flags & FILE_LAST_CR) - { - if (fd_info[fd].flags & FILE_BINARY) abort (); - *buffer++ = 0x0d; - count--; - nchars++; - fd_info[fd].flags &= ~FILE_LAST_CR; - } - - /* presence of a child_process structure means we are operating in - non-blocking mode - otherwise we just call _read directly. - Note that the child_process structure might be missing because - reap_subprocess has been called; in this case the pipe is - already broken, so calling _read on it is okay. */ - if (cp) - { - int current_status = cp->status; - - switch (current_status) - { - case STATUS_READ_FAILED: - case STATUS_READ_ERROR: - /* report normal EOF if nothing in buffer */ - if (nchars <= 0) - fd_info[fd].flags |= FILE_AT_EOF; - return nchars; - - case STATUS_READ_READY: - case STATUS_READ_IN_PROGRESS: - errno = EWOULDBLOCK; - return -1; - - case STATUS_READ_SUCCEEDED: - /* consume read-ahead char */ - *buffer++ = cp->chr; - count--; - nchars++; - cp->status = STATUS_READ_ACKNOWLEDGED; - ResetEvent (cp->char_avail); - - case STATUS_READ_ACKNOWLEDGED: - break; - - default: - errno = EBADF; - return -1; - } - - if (fd_info[fd].flags & FILE_PIPE) - { - PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL); - to_read = min (waiting, (DWORD) count); - - if (to_read > 0) - nchars += _read (fd, buffer, to_read); - } - } - else - { - int nread = _read (fd, buffer, count); - if (nread >= 0) - nchars += nread; - else if (nchars == 0) - nchars = nread; - } - - if (nchars <= 0) - fd_info[fd].flags |= FILE_AT_EOF; - /* Perform text mode translation if required. */ - else if ((fd_info[fd].flags & FILE_BINARY) == 0) - { - unsigned lf_count = 0; - nchars = crlf_to_lf (nchars, orig_buffer, &lf_count); - /* If buffer contains only CR, return that. To be absolutely - sure we should attempt to read the next char, but in - practice a CR to be followed by LF would not appear by - itself in the buffer. */ - if (nchars > 1 && orig_buffer[nchars - 1] == 0x0d) - { - fd_info[fd].flags |= FILE_LAST_CR; - nchars--; - } - } - } - else - nchars = _read (fd, buffer, count); - - return nchars; -} - -/* For now, don't bother with a non-blocking mode */ -int -sys_write (int fd, const void * buffer, size_t count) -{ - int nchars; - - if (fd < 0 || fd >= MAXDESC) - { - errno = EBADF; - return -1; - } - - if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) - { - if ((fd_info[fd].flags & FILE_WRITE) == 0) - { - errno = EBADF; - return -1; - } - - /* Perform text mode translation if required. */ - if ((fd_info[fd].flags & FILE_BINARY) == 0) - { - char * tmpbuf = alloca (count * 2); - unsigned char * src = (void *)buffer; - unsigned char * dst = tmpbuf; - int nbytes = count; - - while (1) - { - unsigned char *next; - /* copy next line or remaining bytes */ - next = _memccpy (dst, src, '\n', nbytes); - if (next) - { - /* copied one line ending with '\n' */ - int copied = next - dst; - nbytes -= copied; - src += copied; - /* insert '\r' before '\n' */ - next[-1] = '\r'; - next[0] = '\n'; - dst = next + 1; - count++; - } - else - /* copied remaining partial line -> now finished */ - break; - } - buffer = tmpbuf; - } - } - - nchars = _write (fd, buffer, count); - - return nchars; -} - - void term_ntproc (int unused) { diff -r 6e6992ccc4b6 -r c9fe270a4101 src/ntproc.c --- a/src/ntproc.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/ntproc.c Mon Aug 13 10:36:47 2007 +0200 @@ -345,204 +345,6 @@ return FALSE; } -/* create_child doesn't know what emacs' file handle will be for waiting - on output from the child, so we need to make this additional call - to register the handle with the process - This way the select emulator knows how to match file handles with - entries in child_procs. */ -void -register_child (int pid, int fd) -{ - child_process *cp; - - cp = find_child_pid (pid); - if (cp == NULL) - { - DebPrint (("register_child unable to find pid %lu\n", pid)); - return; - } - -#ifdef FULL_DEBUG - DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid)); -#endif - - cp->fd = fd; - - /* thread is initially blocked until select is called; set status so - that select will release thread */ - cp->status = STATUS_READ_ACKNOWLEDGED; - - /* attach child_process to fd_info */ - if (fd_info[fd].cp != NULL) - { - DebPrint (("register_child: fd_info[%d] apparently in use!\n", fd)); - abort (); - } - - fd_info[fd].cp = cp; -} - -/* When a process dies its pipe will break so the reader thread will - signal failure to the select emulator. - The select emulator then calls this routine to clean up. - Since the thread signaled failure we can assume it is exiting. */ -static void -reap_subprocess (child_process *cp) -{ - if (cp->procinfo.hProcess) - { - /* Reap the process */ - if (WaitForSingleObject (cp->procinfo.hProcess, INFINITE) != WAIT_OBJECT_0) - DebPrint (("reap_subprocess.WaitForSingleObject (process) failed " - "with %lu for fd %ld\n", GetLastError (), cp->fd)); - CloseHandle (cp->procinfo.hProcess); - cp->procinfo.hProcess = NULL; - CloseHandle (cp->procinfo.hThread); - cp->procinfo.hThread = NULL; - } - - /* For asynchronous children, the child_proc resources will be freed - when the last pipe read descriptor is closed; for synchronous - children, we must explicitly free the resources now because - register_child has not been called. */ - if (cp->fd == -1) - delete_child (cp); -} - -/* Wait for any of our existing child processes to die - When it does, close its handle - Return the pid and fill in the status if non-NULL. */ - -int -sys_wait (int *status) -{ - DWORD active, retval; - int nh; - int pid; - child_process *cp, *cps[MAX_CHILDREN]; - HANDLE wait_hnd[MAX_CHILDREN]; - - nh = 0; - if (dead_child != NULL) - { - /* We want to wait for a specific child */ - wait_hnd[nh] = dead_child->procinfo.hProcess; - cps[nh] = dead_child; - if (!wait_hnd[nh]) abort (); - nh++; - active = 0; - goto get_result; - } - else - { - for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--) - /* some child_procs might be sockets; ignore them */ - if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess) - { - wait_hnd[nh] = cp->procinfo.hProcess; - cps[nh] = cp; - if (!wait_hnd[nh]) abort (); /* Sync with FSF Emacs 19.34.6 note: only in XEmacs */ - nh++; - } - } - - if (nh == 0) - { - /* Nothing to wait on, so fail */ - errno = ECHILD; - return -1; - } - - do - { - /* Check for quit about once a second. */ - QUIT; - active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000); - } while (active == WAIT_TIMEOUT); - - if (active == WAIT_FAILED) - { - errno = EBADF; - return -1; - } - else if (active >= WAIT_OBJECT_0 && - active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS) - { - active -= WAIT_OBJECT_0; - } - else if (active >= WAIT_ABANDONED_0 && - active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS) - { - active -= WAIT_ABANDONED_0; - } - else - abort (); - -get_result: - if (!GetExitCodeProcess (wait_hnd[active], &retval)) - { - DebPrint (("Wait.GetExitCodeProcess failed with %lu\n", - GetLastError ())); - retval = 1; - } - if (retval == STILL_ACTIVE) - { - /* Should never happen */ - DebPrint (("Wait.WaitForMultipleObjects returned an active process\n")); - errno = EINVAL; - return -1; - } - - /* Massage the exit code from the process to match the format expected - by the WIFSTOPPED et al macros in syswait.h. Only WIFSIGNALED and - WIFEXITED are supported; WIFSTOPPED doesn't make sense under NT. */ - - if (retval == STATUS_CONTROL_C_EXIT) - retval = SIGINT; - else - retval <<= 8; - - cp = cps[active]; - pid = cp->pid; -#ifdef FULL_DEBUG - DebPrint (("Wait signaled with process pid %d\n", cp->pid)); -#endif - - if (status) - { - *status = retval; - } - else if (synch_process_alive) - { - synch_process_alive = 0; - - /* Report the status of the synchronous process. */ - if (WIFEXITED (retval)) - synch_process_retcode = WRETCODE (retval); - else if (WIFSIGNALED (retval)) - { - int code = WTERMSIG (retval); - char *signame = 0; - - if (code < NSIG) - { - /* Suppress warning if the table has const char *. */ - signame = (char *) sys_siglist[code]; - } - if (signame == 0) - signame = "unknown"; - - synch_process_death = signame; - } - - reap_subprocess (cp); - } - - reap_subprocess (cp); - - return pid; -} - void win32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app) { diff -r 6e6992ccc4b6 -r c9fe270a4101 src/process-nt.c --- a/src/process-nt.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/process-nt.c Mon Aug 13 10:36:47 2007 +0200 @@ -422,7 +422,7 @@ signal_cannot_launch (Lisp_Object image_file, DWORD err) { mswindows_set_errno (err); - error ("Starting \"%S\": %s", image_file, strerror (errno)); + signal_simple_error_2 ("Error starting", image_file, lisp_strerror (errno)); } static int diff -r 6e6992ccc4b6 -r c9fe270a4101 src/scrollbar-msw.c --- a/src/scrollbar-msw.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/scrollbar-msw.c Mon Aug 13 10:36:47 2007 +0200 @@ -122,6 +122,7 @@ /* These might be optimized, but since at least one will change at each call, it's probably not worth it. */ + SCROLLBAR_MSW_INFO (sb).cbSize = sizeof(SCROLLINFO); SCROLLBAR_MSW_INFO (sb).nMin = new_minimum; SCROLLBAR_MSW_INFO (sb).nMax = new_maximum; SCROLLBAR_MSW_INFO (sb).nPage = new_slider_size + 1; /* for DISABLENOSCROLL */ diff -r 6e6992ccc4b6 -r c9fe270a4101 src/sysdep.c --- a/src/sysdep.c Mon Aug 13 10:35:55 2007 +0200 +++ b/src/sysdep.c Mon Aug 13 10:36:47 2007 +0200 @@ -413,7 +413,6 @@ #endif } -#ifndef MSDOS #ifndef WINDOWSNT /* Set up the terminal at the other end of a pseudo-terminal that we will be controlling an inferior through. @@ -526,7 +525,6 @@ #endif /* RTU */ } #endif /* WINDOWSNT */ -#endif /* not MSDOS */ #endif /* not NO_SUBPROCESSES */ @@ -579,10 +577,6 @@ static void sys_subshell (void) { -#ifdef MSDOS - int st; - char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ -#endif /* MSDOS */ int pid; struct save_signal saved_handlers[5]; Lisp_Object dir; @@ -635,11 +629,6 @@ { char *sh = 0; -#ifdef MSDOS /* MW, Aug 1993 */ - getwd (oldwd); - if (sh == 0) - sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */ -#endif if (sh == 0) sh = (char *) egetenv ("SHELL"); if (sh == 0) @@ -658,38 +647,22 @@ nice (-emacs_priority); /* Give the new shell the default priority */ #endif -#ifdef MSDOS - st = system (sh); - sys_chdir (oldwd); -#if 0 /* This is also reported if last command executed in subshell failed, KFS */ - if (st) - report_file_error ("Can't execute subshell", - Fcons (build_string (sh), Qnil)); -#endif -#else /* not MSDOS */ #ifdef WINDOWSNT /* Waits for process completion */ pid = _spawnlp (_P_WAIT, sh, sh, NULL); if (pid == -1) write (1, "Can't execute subshell", 22); -#if 0 -/* This relates to the GNU Emacs console port, not required under X ? */ - take_console (); -#endif #else /* not WINDOWSNT */ execlp (sh, sh, 0); write (1, "Can't execute subshell", 22); _exit (1); #endif /* not WINDOWSNT */ -#endif /* not MSDOS */ } save_signal_handlers (saved_handlers); synch_process_alive = 1; -#ifndef MSDOS wait_for_termination (pid); -#endif restore_signal_handlers (saved_handlers); } @@ -701,7 +674,7 @@ void sys_suspend (void) { -#if defined (SIGTSTP) && !defined (MSDOS) +#if defined (SIGTSTP) { int pgrp = EMACS_GET_PROCESS_GROUP (); EMACS_KILLPG (pgrp, SIGTSTP); @@ -730,7 +703,7 @@ * VMS machines or thost that use USG_JOBCTRL, * but I don't know how to do it, so... */ -#if defined (SIGTSTP) && !defined (MSDOS) +#if defined (SIGTSTP) kill(process, SIGTSTP); #endif } @@ -928,7 +901,7 @@ assert (DEVICE_TTY_P (d)); { int input_fd = CONSOLE_TTY_DATA (con)->infd; -#if defined (MSDOS) || defined(WIN32) +#if defined (WINDOWSNT) DEVICE_TTY_DATA (d)->ospeed = 15; #elif defined (HAVE_TERMIOS) struct termios sg; @@ -1373,7 +1346,7 @@ if (ioctl (fd, TCGETA, &settings->main) < 0) return -1; -#elif !defined MSDOS && !defined(WIN32) +#elif !defined (WINDOWSNT) /* I give up - I hope you have the BSD ioctls. */ if (ioctl (fd, TIOCGETP, &settings->main) < 0) return -1; @@ -1446,7 +1419,7 @@ if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0) return -1; -#elif !defined(MSDOS) && !defined(WIN32) +#elif !defined (WINDOWSNT) /* I give up - I hope you have the BSD ioctls. */ if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0) return -1; @@ -1629,14 +1602,14 @@ tty.main.c_iflag &= ~BRKINT; #endif /* AIX */ #else /* if not HAVE_TERMIO */ -#if !defined(MSDOS) && !defined(WIN32) +#if !defined (WINDOWSNT) con->tty_erase_char = make_char (tty.main.sg_erase); tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS); if (TTY_FLAGS (con).meta_key) tty.main.sg_flags |= ANYP; /* #### should we be using RAW mode here? */ tty.main.sg_flags |= /* interrupt_input ? RAW : */ CBREAK; -#endif /* not MSDOS or WIN32 */ +#endif /* not WINDOWSNT */ #endif /* not HAVE_TERMIO */ /* If going to use CBREAK mode, we must request C-g to interrupt @@ -1674,10 +1647,6 @@ #ifdef HAVE_LTCHARS tty.ltchars = new_ltchars; #endif /* HAVE_LTCHARS */ -#ifdef MSDOS - internal_terminal_init (); - dos_ttraw (); -#endif EMACS_SET_TTY (input_fd, &tty, 0); @@ -1832,10 +1801,6 @@ *heightp = size.ts_lines; } } -#elif defined MSDOS - *widthp = FrameCols (); - *heightp = FrameRows (); - #else /* system doesn't know size */ *widthp = 0; @@ -1917,10 +1882,6 @@ < 0 && errno == EINTR) ; -#ifdef MSDOS - dos_ttcooked (); -#endif - #ifdef SET_LINE_DISCIPLINE /* Ultrix's termios *ignores* any line discipline except TERMIODISC. A different old line discipline is therefore not restored, yet. @@ -2594,8 +2555,6 @@ #define PATHNAME_CONVERT_OUT(path) \ GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA ((CONST Bufbyte *) path, path) -/***** MSDOS versions are in msdos.c *****/ - /***************** low-level calls ****************/ /* @@ -2628,7 +2587,10 @@ va_end (ap); PATHNAME_CONVERT_OUT (path); -#ifdef INTERRUPTIBLE_OPEN +#if defined (WINDOWSNT) + /* Make all handles non-inheritable */ + return open (path, oflag | _O_NOINHERIT, mode); +#elif defined (INTERRUPTIBLE_OPEN) { int rtnval; while ((rtnval = open (path, oflag, mode)) == -1 @@ -2636,7 +2598,7 @@ return rtnval; } #else - return open (path, oflag, mode); + return open (path, oflag, mode); #endif } #endif /* ENCAPSULATE_OPEN */ @@ -2772,7 +2734,49 @@ sys_fopen (CONST char *path, CONST char *type) { PATHNAME_CONVERT_OUT (path); -#ifdef INTERRUPTIBLE_OPEN +#if defined (WINDOWSNT) + { + int fd; + int oflag; + const char * type_save = type; + + /* Force all file handles to be non-inheritable. This is necessary to + ensure child processes don't unwittingly inherit handles that might + prevent future file access. */ + + if (type[0] == 'r') + oflag = O_RDONLY; + else if (type[0] == 'w' || type[0] == 'a') + oflag = O_WRONLY | O_CREAT | O_TRUNC; + else + return 0; + + /* Only do simplistic option parsing. */ + while (*++type) + if (type[0] == '+') + { + oflag &= ~(O_RDONLY | O_WRONLY); + oflag |= O_RDWR; + } + else if (type[0] == 'b') + { + oflag &= ~O_TEXT; + oflag |= O_BINARY; + } + else if (type[0] == 't') + { + oflag &= ~O_BINARY; + oflag |= O_TEXT; + } + else break; + + fd = open (path, oflag | _O_NOINHERIT, 0644); + if (fd < 0) + return NULL; + + return _fdopen (fd, type_save); + } +#elif defined (INTERRUPTIBLE_OPEN) { FILE *rtnval; while (!(rtnval = fopen (path, type)) && (errno == EINTR)); @@ -2872,11 +2876,7 @@ sys_chdir (CONST char *path) { PATHNAME_CONVERT_OUT (path); -#ifdef MSDOS - return dos_chdir (path); -#else return chdir (path); -#endif } #endif /* ENCAPSULATE_CHDIR */ @@ -2886,7 +2886,11 @@ sys_mkdir (CONST char *path, mode_t mode) { PATHNAME_CONVERT_OUT (path); +#ifdef WINDOWSNT + return mkdir (path); +#else return mkdir (path, mode); +#endif } #endif /* ENCAPSULATE_MKDIR */ @@ -3080,6 +3084,14 @@ { PATHNAME_CONVERT_OUT (old); PATHNAME_CONVERT_OUT (new); +#ifdef WINDOWSNT + /* Windows rename fails if NEW exists */ + if (rename (old, new) == 0) + return 0; + if (errno != EEXIST) + return -1; + unlink (new); +#endif /* WINDOWSNT */ return rename (old, new); } #endif /* ENCAPSULATE_RENAME */ @@ -3347,7 +3359,7 @@ } else { - /* MS-DOS or equally lame OS */ + /* A lame OS */ *user_time = *real_time; *system_time = 0; } diff -r 6e6992ccc4b6 -r c9fe270a4101 tests/Dnd/README --- a/tests/Dnd/README Mon Aug 13 10:35:55 2007 +0200 +++ b/tests/Dnd/README Mon Aug 13 10:36:47 2007 +0200 @@ -3,8 +3,22 @@ This path contains test code for the new XEmacs Drag'n'Drop code. -Currently only drops are of interest. The internal -functions should work for OffiX, CDE, and MSWindows. +To test the code do the following: +1) call 'bash droptest.sh' to create the test files in /tmp +2) load and eval droptest.el in XEmacs +3) Try to do some internal DnD by using the sources and targets + in the new buffer +4) Do some external DnD: + 4a) OffiX: use files and editor of OffiX + drag something from files or editor into XEmacs + drag something from XEmacs to xv (only with OffiX patch, + editor or files -- files can only move and copy within + itself, cause OffiX is not quite the right thing to do) + 4b) CDE: use dtfile and dtpad instead, but here everything should + work. + 4c) MSWindows: well, explorer should do. But only file data + should work, and I don't know if the test + already handles this. The misc-user-event now also responds as a button-x-event to the event-* query functions. diff -r 6e6992ccc4b6 -r c9fe270a4101 tests/Dnd/droptest.el --- a/tests/Dnd/droptest.el Mon Aug 13 10:35:55 2007 +0200 +++ b/tests/Dnd/droptest.el Mon Aug 13 10:36:47 2007 +0200 @@ -23,6 +23,21 @@ (funcall (intern "cde-start-drag-internal") event t what))) (t display-message 'error "no valid drag protocols implemented"))) +(defun start-region-drag (event) + (interactive "_e") + (if (click-inside-extent-p event zmacs-region-extent) + ;; okay, this is a drag + (cond ((featurep 'offix) + (offix-start-drag-region event + (extent-start-position zmacs-region-extent) + (extent-end-position zmacs-region-extent))) + ((featurep 'cde) + ;; should also work with CDE + (cde-start-drag-region event + (extent-start-position zmacs-region-extent) + (extent-end-position zmacs-region-extent))) + (t (error "No offix or CDE support compiled in"))))) + (defun make-drop-targets () (let ((buf (get-buffer-create "*DND misc-user extent test buffer*")) (s nil) @@ -34,7 +49,7 @@ (setq e (point)) (setq ext (make-extent s e)) (set-extent-property ext - 'dragdrop-drop-functions + 'experimental-dragdrop-drop-functions '((do-nothing t t) (dnd-drop-message t t "on target 1"))) (set-extent-property ext 'mouse-face 'highlight) @@ -44,7 +59,7 @@ (setq e (point)) (setq ext (make-extent s e)) (set-extent-property ext - 'dragdrop-drop-functions + 'experimental-dragdrop-drop-functions '((dnd-drop-message t t "on target 2"))) (set-extent-property ext 'mouse-face 'highlight) (insert " ") @@ -53,7 +68,7 @@ (setq e (point)) (setq ext (make-extent s e)) (set-extent-property ext - 'dragdrop-drop-functions + 'experimental-dragdrop-drop-functions '((dnd-drop-message t t "on target 3"))) (set-extent-property ext 'mouse-face 'highlight) (newline 2))) @@ -125,11 +140,11 @@ (defun file-drag (event) (interactive "@e") - (start-drag event "/tmp/printcap" 2)) + (start-drag event "/tmp/DropTest.xpm" 2)) (defun cde-file-drag (event) (interactive "@e") - (start-drag event '("/tmp/printcap") t)) + (start-drag event '("/tmp/DropTest.xpm") t)) (defun url-drag (event) (interactive "@e") @@ -137,9 +152,9 @@ (defun files-drag (event) (interactive "@e") - (start-drag event '("/tmp/dragtest" "/tmp/droptest" "/tmp/printcap") 3)) + (start-drag event '("/tmp/DropTest.html" "/tmp/DropTest.xpm" "/tmp/DropTest.tex") 3)) -(setq dragdrop-drop-functions '((do-nothing t t) +(setq experimental-dragdrop-drop-functions '((do-nothing t t) ;; CDE does not have any button info... (dnd-drop-message 0 t "cde-drop somewhere else") (dnd-drop-message 2 t "region somewhere else") @@ -158,4 +173,4 @@ (use-local-map lmap) (local-set-key [q] 'end-dnd-demo) (setq button2-func (lookup-key global-map [button2])) -(global-unset-key [button2]) +(global-set-key [button2] 'start-region-drag) diff -r 6e6992ccc4b6 -r c9fe270a4101 tests/Dnd/droptest.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/Dnd/droptest.sh Mon Aug 13 10:36:47 2007 +0200 @@ -0,0 +1,102 @@ +#!/bin/sh + +cat README > /tmp/DropTest.txt + +cat > /tmp/DropTest.html < + +DropTest Page + + +

DropTest

+Just a Test! + + +EOF + +cat > /tmp/DropTest.tex < /tmp/DropTest.xpm <