Mercurial > hg > xemacs-beta
changeset 249:83b3d10dcba9 r20-5b23
Import from CVS: tag r20-5b23
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:19:09 +0200 |
parents | ad40ac2754d8 |
children | f385a461c9aa |
files | CHANGES-beta ChangeLog configure configure.in etc/NEWS etc/aliases.ksh lisp/ChangeLog lisp/about.el lisp/help-nomule.el lisp/help.el lisp/loadup.el lisp/mouse.el lisp/msw-select.el nt/ChangeLog nt/xemacs.mak src/ChangeLog src/Makefile.in.in src/alloc.c src/chartab.c src/console-msw.c src/console-msw.h src/device-msw.c src/device.h src/emacsfns.h src/eval.c src/event-msw.c src/event-msw.h src/event-stream.c src/events.c src/events.h src/faces.c src/frame-msw.c src/frame.c src/glyphs.c src/keymap.c src/lread.c src/md5.c src/menubar-msw.c src/msw-proc.c src/mule-ccl.c src/mule-coding.c src/mule-coding.h src/objects-msw.c src/redisplay-msw.c src/redisplay.c src/s/sunos4-0.h src/scrollbar-msw.c src/select-msw.c src/toolbar.c src/unexcw.cc version.sh |
diffstat | 51 files changed, 1674 insertions(+), 1926 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES-beta Mon Aug 13 10:18:22 2007 +0200 +++ b/CHANGES-beta Mon Aug 13 10:19:09 2007 +0200 @@ -1,4 +1,8 @@ -*- indented-text -*- +to 20.5 beta23 "Jining Grey" +-- MS Windows DnD stuffs courtesy of Jonathon Harris +-- Miscellaneous bug fixes + to 20.5 beta22 "Grison's Striped" -- Port to mklinux courtesy of Kaoru Fukui -- Miscellaneous bug fixes
--- a/ChangeLog Mon Aug 13 10:18:22 2007 +0200 +++ b/ChangeLog Mon Aug 13 10:19:09 2007 +0200 @@ -1,3 +1,19 @@ +1998-02-03 SL Baur <steve@altair.xemacs.org> + + * XEmacs 20.5-beta23 is released. + +1998-02-01 SL Baur <steve@altair.xemacs.org> + + * etc/aliases.ksh: igrep from the shell command line. + From Karl M. Hegbloom <karlheg@bittersweet.inetarena.com> + +1998-01-31 SL Baur <steve@altair.xemacs.org> + + * etc/aliases.ksh: Add `mak' function to create beta.err for + build-report. + From Adrian Aichner <aichner@ecf.teradyne.com> + Suggested by Karl M. Hegbloom <karlheg@bittersweet.inetarena.com> + 1998-01-27 SL Baur <steve@altair.xemacs.org> * XEmacs 20.5-beta22 is released.
--- a/configure Mon Aug 13 10:18:22 2007 +0200 +++ b/configure Mon Aug 13 10:19:09 2007 +0200 @@ -4888,8 +4888,8 @@ with_dialogs=msw with_toolbars=no with_tty=no - extra_objs="$extra_objs console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o msw-proc.o" && if test "$extra_verbose" = "yes"; then - echo " xemacs will be linked with \"console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o msw-proc.o\"" + extra_objs="$extra_objs console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o" && if test "$extra_verbose" = "yes"; then + echo " xemacs will be linked with \"console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o\"" fi fi fi
--- a/configure.in Mon Aug 13 10:18:22 2007 +0200 +++ b/configure.in Mon Aug 13 10:19:09 2007 +0200 @@ -2125,7 +2125,7 @@ with_dialogs=msw with_toolbars=no with_tty=no - XE_ADD_OBJS(console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o msw-proc.o) + XE_ADD_OBJS(console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o) fi fi
--- a/etc/NEWS Mon Aug 13 10:18:22 2007 +0200 +++ b/etc/NEWS Mon Aug 13 10:19:09 2007 +0200 @@ -86,6 +86,12 @@ This information is used to control the customize-changed-options command. +** The new command `add-log-convert' can be used to convert the +old-style (pre-20.3) ChangeLog buffers to new style, for +consistency. A reminder: if you wish to revert to old-style +ChangeLogs instead, customize the value of `add-log-time-format' +variable. + ** XEmacs/Mule (internationalization) changes. *** Egg/SJ3 input method is now officially supported. Quail and
--- a/etc/aliases.ksh Mon Aug 13 10:18:22 2007 +0200 +++ b/etc/aliases.ksh Mon Aug 13 10:19:09 2007 +0200 @@ -24,6 +24,8 @@ # Shortcuts for sh-derived Unix shells (ksh, zsh, bash) +# From Steve Baur <steve@altair.xemacs.org> +# Run temacs as XEmacs function runtemacs { if [ ! -x temacs ]; then @@ -33,3 +35,26 @@ ./temacs -batch -l loadup.el run-temacs "$@" } + +# From Adrian Aichner <aichner@ecf.teradyne.com> +# Convenience function for running build-report +function mak +{ + make "$@" 2>&1 | tee beta.err +} +# export -f mak + +# From Karl Hegbloom <karlheg@bittersweet.inetarena.com> +# igrep from the shell command line +function listargs +{ + for arg in "$@"; do + echo " \"$arg\"" + done +} + +function igrep +{ + exp="$1"; shift + gnudoit -q "(igrep nil \"$exp\" '($(listargs "$@")))" +}
--- a/lisp/ChangeLog Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/ChangeLog Mon Aug 13 10:19:09 2007 +0200 @@ -1,3 +1,21 @@ +1997-12-30 Colin Rafferty <colin@xemacs.org> + + * help.el (describe-beta): Made it use `locate-data-file'. + (describe-distribution): Ditto. + (describe-copying): Ditto. + (describe-project): Ditto. + (view-emacs-news): Ditto. + + * help-nomule.el (help-with-tutorial): Made it use + `locate-data-file' to find tutorial. + +1998-01-28 Jonathon Harris <jhar@tardis.ed.ac.uk> + + * about.el: Corrected my email address. + + * mouse.el: Added 'mouse-mswindows-drop' similar to + 'mouse-offix-drop'. + 1998-01-27 SL Baur <steve@altair.xemacs.org> * loadup.el (running-xemacs): Spelling fix.
--- a/lisp/about.el Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/about.el Mon Aug 13 10:19:09 2007 +0200 @@ -1303,7 +1303,7 @@ (print-short "ChangGil Han" "cghan@phys401.phys.pusan.ac.kr") (print-short "Derek Harding" "dharding@lssec.bt.co.uk") (print-short "Michael Harnois" "mharnois@sbt.net") - (print-short "Jonathan Harris" "jharris@tardis.co.uk") + (print-short "Jonathan Harris" "jhar@tardis.ed.ac.uk") (print-short "John Haxby" "J.Haxby@isode.com") (print-short "Karl M. Hegbloom" "karlheg@inetarena.com") (print-short "Benedikt Heinen" "beh@icemark.thenet.ch")
--- a/lisp/help-nomule.el Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/help-nomule.el Mon Aug 13 10:19:09 2007 +0200 @@ -70,8 +70,7 @@ ;; independently, so we must guess the coding according to ;; the language. (let ((coding-system-for-read (nth 2 language))) - (insert-file-contents (expand-file-name tutorial - data-directory))) + (insert-file-contents (locate-data-file tutorial))) (goto-char (point-min)) ;; The 'didactic' blank lines: possibly insert blank lines ;; around <<nya nya nya>> and replace << >> with [ ].
--- a/lisp/help.el Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/help.el Mon Aug 13 10:19:09 2007 +0200 @@ -552,20 +552,20 @@ "Display info on how to obtain the latest version of XEmacs." (interactive) (find-file-read-only - (expand-file-name "DISTRIB" data-directory))) + (locate-data-file "DISTRIB"))) (defun describe-beta () "Display info on how to deal with Beta versions of XEmacs." (interactive) (find-file-read-only - (expand-file-name "BETA" data-directory)) + (locate-data-file "BETA")) (goto-char (point-min))) (defun describe-copying () "Display info on how you may redistribute copies of XEmacs." (interactive) (find-file-read-only - (expand-file-name "COPYING" data-directory)) + (locate-data-file "COPYING")) (goto-char (point-min))) (defun describe-pointer () @@ -577,7 +577,7 @@ "Display info on the GNU project." (interactive) (find-file-read-only - (expand-file-name "GNU" data-directory)) + (locate-data-file "GNU")) (goto-char (point-min))) (defun describe-no-warranty () @@ -660,7 +660,7 @@ (defun view-emacs-news () "Display info on recent changes to XEmacs." (interactive) - (find-file (expand-file-name "NEWS" data-directory))) + (find-file (locate-data-file "NEWS"))) (defun xemacs-www-page () "Go to the XEmacs World Wide Web page."
--- a/lisp/loadup.el Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/loadup.el Mon Aug 13 10:19:09 2007 +0200 @@ -184,10 +184,13 @@ (message "Dumping under the name xemacs") ;; This is handled earlier in the build process. ;; (condition-case () (delete-file "xemacs") (file-error nil)) - (when (fboundp 'really-free) - (really-free)) - (dump-emacs "xemacs" "temacs") - (kill-emacs)) + (test-atoms) + (when (fboundp 'really-free) + (really-free)) + (test-atoms) + (dump-emacs "xemacs" "temacs") + (test-atoms) + (kill-emacs)) (when (member "run-temacs" command-line-args) (message "\nBootstrapping from temacs...")
--- a/lisp/mouse.el Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/mouse.el Mon Aug 13 10:19:09 2007 +0200 @@ -42,16 +42,21 @@ ;; enable drag regions (ograf@fga.de) ;; if button2 is dragged from within a region, this becomes a drop -(if (featurep '(or offix cde)) +(if (featurep '(or offix cde mswindows)) (global-set-key 'button2 'mouse-drag-or-yank) (global-set-key 'button2 'mouse-yank)) -;; enable drops from OffiX (ograf@fga.de) -;; accept any button1,2,3 drop with `mouse-offix-drop' +;; enable drops from OffiX (ograf@fga.de) or mswindows +;; accept any button1,2,3 drop with `mouse-offix-drop' or 'mswindows-mouse-drop' (cond ((featurep 'offix) (global-set-key 'drop1 'mouse-offix-drop) (global-set-key 'drop2 'mouse-offix-drop) - (global-set-key 'drop3 'mouse-offix-drop))) + (global-set-key 'drop3 'mouse-offix-drop)) + ((featurep 'mswindows) + (global-set-key 'drop0 'mouse-mswindows-drop) + (global-set-key 'drop1 'mouse-mswindows-drop) + (global-set-key 'drop2 'mouse-mswindows-drop) + (global-set-key 'drop3 'mouse-mswindows-drop))) (defgroup mouse nil "Window system-independent mouse support." @@ -247,6 +252,44 @@ (make-frame-visible frame)))) (undo-boundary))) +(defun mouse-mswindows-drop (event) + "Do something with a drop event. Inserts Text drops and + executes appropriate commands for specific drops. + Text drops follow the `mouse-yank-at-point' variable." + (interactive "e") + (let* ((type (car (event-drag-and-drop-data event))) + (data (cadr (event-drag-and-drop-data event))) + (frame (event-channel event)) + (window (if frame (event-window event) (frame-selected-window)))) + (cond ((= type 2) ;; file + (let ((x pop-up-windows)) + (setq pop-up-windows nil) + (cond (window + (select-window window))) + (switch-to-buffer (find-file-noselect data)) + (make-frame-visible frame) + (setq pop-up-windows x))) + ((= type 3) ;; files + (let ((x pop-up-windows)) + (setq pop-up-windows nil) + (while (not (eq data ())) + (pop-to-buffer (find-file-noselect (car data)) nil frame) + (setq data (cdr data))) + (make-frame-visible frame) + (setq pop-up-windows x))) + ((= type 4) ;; text + (and (not mouse-yank-at-point) + (mouse-set-point event)) + (insert data)) + (t ;; this is raw data or unknown stuff + (let ((buf (generate-new-buffer "DndRawData"))) + (set-buffer buf) + (pop-to-buffer buf nil frame) + (insert data) + (hexlify-buffer) + (make-frame-visible frame)))) + (undo-boundary))) + (defun mouse-eval-sexp (click force-window) "Evaluate the sexp under the mouse. Usually, this is the last sexp before the click, but if you click on a left paren, then it is the sexp beginning
--- a/lisp/msw-select.el Mon Aug 13 10:18:22 2007 +0200 +++ b/lisp/msw-select.el Mon Aug 13 10:19:09 2007 +0200 @@ -32,16 +32,6 @@ ;;; Code: -;(defun mswindows-paste-clipboard () -; "Insert the current contents of the Clipboard at point." -; (interactive "*") -; (setq last-command nil) -; (setq this-command 'yank) ; so that yank-pop works. -; (let ((clip (mswindows-get-clipboard))) -; (or clip (error "there is no clipboard selection")) -; (push-mark) -; (insert clip))) - (defun mswindows-paste-clipboard () "Insert the current contents of the mswindows clipboard at point, replacing the active selection if there is one."
--- a/nt/ChangeLog Mon Aug 13 10:18:22 2007 +0200 +++ b/nt/ChangeLog Mon Aug 13 10:19:09 2007 +0200 @@ -1,3 +1,8 @@ +1998-01-28 Jonathon Harris <jhar@tardis.ed.ac.uk> + + * xemacs.mak: Updated accordingly. + Creates the MSVC browse info immediately after the link. + 1997-12-29 Kirill M. Katsnelson <kkm@kis.ru> * config.h: Suppressed MSVC warning 'relational' : signed/unsigned
--- a/nt/xemacs.mak Mon Aug 13 10:18:22 2007 +0200 +++ b/nt/xemacs.mak Mon Aug 13 10:19:09 2007 +0200 @@ -294,8 +294,7 @@ $(XEMACS)\src\objects-msw.c \ $(XEMACS)\src\redisplay-msw.c \ $(XEMACS)\src\scrollbar-msw.c \ - $(XEMACS)\src\select-msw.c \ - $(XEMACS)\src\msw-proc.c + $(XEMACS)\src\select-msw.c !endif !if $(HAVE_MULE) @@ -396,8 +395,7 @@ $(OUTDIR)\objects-msw.obj \ $(OUTDIR)\redisplay-msw.obj \ $(OUTDIR)\scrollbar-msw.obj \ - $(OUTDIR)\select-msw.obj \ - $(OUTDIR)\msw-proc.obj + $(OUTDIR)\select-msw.obj !endif !if $(HAVE_MULE) @@ -536,7 +534,6 @@ link.exe @<< $(TEMACS_LFLAGS) $(TEMACS_OBJS) $(TEMACS_LIBS) << - !$(TEMACS) -batch -l update-elc.el xemacs.res: xemacs.rc rc xemacs.rc @@ -566,7 +563,7 @@ !$(LIB_SRC)\make-docfile.exe -a $(DOC) -d $(TEMACS_SRC) $(DOC_SRC8) !$(LIB_SRC)\make-docfile.exe -a $(DOC) -d $(TEMACS_SRC) $(DOC_SRC9) -update-elc: $(LOADPATH)\startup.el +update-elc: !$(TEMACS) -batch -l update-elc.el rebuild: $(TEMACS_DIR)\puresize-adjust.h @@ -584,7 +581,7 @@ #------------------------------------------------------------------------------ # use this rule to build the complete system -all: $(LASTFILE) $(LWLIB) $(SUPPORT_PROGS) $(TEMACS) $(TEMACS_BROWSE) $(DOC) dump-xemacs +all: $(LASTFILE) $(LWLIB) $(SUPPORT_PROGS) $(TEMACS) $(TEMACS_BROWSE) update-elc $(DOC) dump-xemacs -del rebuild temacs: $(TEMACS) @@ -626,7 +623,7 @@ -del /s /q *.bak *.elc *.orig *.rej depend: - mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) -- $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c + mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w2048 -- $(TEMACS_CPP_FLAGS) -- $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c # DO NOT DELETE THIS LINE -- make depend depends on it. mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) -- $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(DOC_SRC9) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c
--- a/src/ChangeLog Mon Aug 13 10:18:22 2007 +0200 +++ b/src/ChangeLog Mon Aug 13 10:19:09 2007 +0200 @@ -1,5 +1,102 @@ +1998-02-01 Kyle Jones <kyle_jones@wonderworks.com> + + * redisplay.c (redisplay_window): After outputting + the window, invalidate its the line start cache if the + we're displaying the minibuffer window and the echo + area is active. The cache is only valid for the echo + area buffer, and that buffer isn't associated with the + minibuffer window anymore. + +1998-01-31 SL Baur <steve@altair.xemacs.org> + + * alloc.c (disksave_object_finalization): Additional checking for + sanity when zeroing out unused portions of string_chars_block's. + (Fpurecopy): Spelling fixes in comment. + (PURESIZE_SLOP): Set default slop to 0. + +1998-01-31 Kyle Jones <kyle_jones@wonderworks.com> + + * chartab.c (make_char_table): Initialize mirror + tables with Spunct in all the slots. Syntax table + initialization doesn't touch slots for nonexistent + characters sets. If character sets corresponding to + those slots are created later Qnil values in the slots + will cause crashes. + (copy_char_table_entry): Return copy not original. + +1998-01-28 Jonathon Harris <jhar@tardis.ed.ac.uk> + + * msw-proc.c: + * event-msw.h: + * event-msw.c: + * console-msw.h: + Deleted the first two and merged them into the last two files. + + * device-msw.c: + * event-msw.c: + * frame-msw.c: + Added file-based drag and drop support. The "System/Open" DDE command + is also implemented as if it were a drag and drop operation. + + * emacsfns.h: + * event-stream.c: + * events.c: + * events.h: + * frame.c: + * keymap.c: + Replaced all "#ifdef HAVE_OFFIX_DND" with + "#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)" + + * device.h: Added DEVICE_MSWINDOWS_P and related macros. + + * objects-msw.c: + * select-msw.c: + Eliminated warnings. + + * redisplay-msw.c: Changed color of "dead" box between scrollbars + to windows' "button" color for compatibility with other windows apps. + +1998-01-20 Stephen Turnbull <turnbull@sk.tsukuba.ac.jp> + + * Makefile.in.in: move `rm puresize-adjust.h' from distclean + to mostlyclean + +1998-01-29 SL Baur <steve@altair.xemacs.org> + + * Makefile.in.in (dlopen.o): Add dependencies. + + * s/sunos4-0.h: Conditionalize use of broken-sun.h for old Gccs. + Suggested by Amir J Katz <amir@ndsoft.com> + +1998-01-28 SL Baur <steve@altair.xemacs.org> + + * faces.c (init_device_faces): This function can call lisp. + +1998-01-28 P. E. Jareth Hein <jareth@camelot-soft.com> + + * mule-coding.h: + * mule-coding.c: (determine_real_coding_system): removed the + static declaration to allow reuse. + + * md5.c (Fmd5): Rewrote to fully support MULE, as well as streamline + the code. + + * mule-ccl.c (ccl_driver): Set initial values of variables to shut up + the compiler and to give better error message if a quit happens before + any ccl_code is generated. + +1998-01-28 SL Baur <steve@altair.xemacs.org> + + * glyphs.c (allocate_glyph): This function can GC. + Wrap GCPRO around unprotected function calls. + (specifier_vars_of_glyphs): Comment change -- Can we GC here? + 1998-01-27 SL Baur <steve@altair.xemacs.org> + * lread.c (Fload_internal): Add extra GCPRO around call to + Fassoc. + Enable purespace usage counts always. + * m/powerpc.h: Isolate changes for mklinux from AIX. 1998-01-27 Hrvoje Niksic <hniksic@srce.hr>
--- a/src/Makefile.in.in Mon Aug 13 10:18:22 2007 +0200 +++ b/src/Makefile.in.in Mon Aug 13 10:19:09 2007 +0200 @@ -614,13 +614,14 @@ .PHONY: mostlyclean clean distclean realclean versionclean extraclean mostlyclean: - $(RM) temacs puremacs quantmacs prefix-args depend.* *.o *.i core + $(RM) temacs puremacs quantmacs prefix-args depend.* *.o *.i \ + core puresize-adjust.h clean: mostlyclean versionclean $(RM) libextcli* update-elc.stamp ## This is used in making a distribution. ## Do not use it on development directories! distclean: clean - $(RM) config.h paths.h puresize-adjust.h Emacs.ad.h \ + $(RM) config.h paths.h Emacs.ad.h \ Makefile Makefile.in TAGS xemacs.* realclean: distclean versionclean: @@ -1325,6 +1326,8 @@ dired.o: regex.h dired.o: sysdir.h dired.o: sysfile.h +dlopen.o: config.h +dlopen.o: buffer.h doc.o: blocktype.h doc.o: buffer.h doc.o: bufslots.h
--- a/src/alloc.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/alloc.c Mon Aug 13 10:19:09 2007 +0200 @@ -2794,13 +2794,13 @@ * But purified aggregate objects like lists and vectors * can contain uninterned symbols. If there are no * other non-pure references to the symbol, then the - * symbol is not proteted from garabge colelction + * symbol is not protected from garbage collection * because the collector does not mark the contents of * purified objects. So to protect the symbols, an impure * reference has to be kept for each uninterned symbol * that is referenced by a pure object. All such * symbols are stored in the hashtable pointed to by - * Vpure_uninterened_symbol_table, which is itself + * Vpure_uninterned_symbol_table, which is itself * staticpro'd. */ if (EQ (XSYMBOL (obj)->obarray, Vobarray)) @@ -2858,14 +2858,14 @@ extern Lisp_Object Vemacs_beta_version; /* This used to be NILP(Vemacs_beta_version) ? 512 : 4; */ #ifndef PURESIZE_SLOP -#define PURESIZE_SLOP 4 +#define PURESIZE_SLOP 0 #endif int slop = PURESIZE_SLOP; sprintf (buf, "Purespace usage: %ld of %ld (%d%%", pureptr, (long) get_PURESIZE(), (int) (pureptr / (get_PURESIZE() / 100.0) + 0.5)); - if (lost > 2) { + if (lost > ((slop ? slop : 1) / 1024)) { sprintf (buf + strlen (buf), " -- %dk wasted", lost); if (die_if_pure_storage_exceeded) { puresize_adjust_h (pureptr + slop); @@ -4222,20 +4222,28 @@ /* Run the disksave finalization methods of all live objects. */ disksave_object_finalization_1 (); +#if 0 /* I don't see any point in this. The purespace starts out all 0's */ /* Zero out the unused portion of purespace */ if (!pure_lossage) memset ( (char *) (PUREBEG + pureptr), 0, (((char *) (PUREBEG + get_PURESIZE())) - ((char *) (PUREBEG + pureptr)))); +#endif /* Zero out the uninitialized (really, unused) part of the containers for the live strings. */ { struct string_chars_block *scb; for (scb = first_string_chars_block; scb; scb = scb->next) - /* from the block's fill ptr to the end */ - memset ((scb->string_chars + scb->pos), 0, - sizeof (scb->string_chars) - scb->pos); + { + int count = sizeof (scb->string_chars) - scb->pos; + + assert (count >= 0 && count < STRING_CHARS_BLOCK_SIZE); + if (count != 0) { + /* from the block's fill ptr to the end */ + memset ((scb->string_chars + scb->pos), 0, count); + } + } } /* There, that ought to be enough... */
--- a/src/chartab.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/chartab.c Mon Aug 13 10:19:09 2007 +0200 @@ -595,6 +595,8 @@ if (ty == CHAR_TABLE_TYPE_SYNTAX) { ct->mirror_table = Fmake_char_table (Qgeneric); + fill_char_table (XCHAR_TABLE (ct->mirror_table), + make_int (Spunct)); } else ct->mirror_table = Qnil; @@ -645,7 +647,7 @@ ctenew->level2[i] = new; } - XSETCHAR_TABLE_ENTRY (obj, cte); + XSETCHAR_TABLE_ENTRY (obj, ctenew); return obj; }
--- a/src/console-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/console-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -31,6 +31,7 @@ #include "console-msw.h" + DEFINE_CONSOLE_TYPE (mswindows); @@ -73,3 +74,74 @@ { Fprovide (Qmswindows); } + + +#ifdef DEBUG_XEMACS +#include "events.h" +#include "opaque.h" +/* + * Random helper functions for debugging. + * Intended for use in the MSVC "Watch" window which doesn't like + * the aborts that the error_check_foo() functions can make. + */ +struct lrecord_header *DHEADER(Lisp_Object obj) +{ + return (LRECORDP (obj)) ? XRECORD_LHEADER (obj) : NULL; +} + +int *DOPAQUE_DATA (Lisp_Object obj) +{ + return (OPAQUEP (obj)) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL; +} + +struct Lisp_Event *DEVENT(Lisp_Object obj) +{ + return (EVENTP (obj)) ? XEVENT (obj) : NULL; +} + +struct Lisp_Cons *DCONS(Lisp_Object obj) +{ + return (CONSP (obj)) ? XCONS (obj) : NULL; +} + +Lisp_Object DCAR(Lisp_Object obj) +{ + return (CONSP (obj)) ? XCAR (obj) : 0; +} + +Lisp_Object DCDR(Lisp_Object obj) +{ + return (CONSP (obj)) ? XCDR (obj) : 0; +} + +struct Lisp_Cons *DCONSCDR(Lisp_Object obj) +{ + return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCONS (XCDR (obj)) : 0; +} + +Lisp_Object DCARCDR(Lisp_Object obj) +{ + return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCAR (XCDR (obj)) : 0; +} + +char *DSTRING(Lisp_Object obj) +{ + return (STRINGP (obj)) ? XSTRING_DATA (obj) : NULL; +} + +struct Lisp_Vector *DVECTOR(Lisp_Object obj) +{ + return (VECTORP (obj)) ? XVECTOR (obj) : NULL; +} + +struct Lisp_Symbol *DSYMBOL(Lisp_Object obj) +{ + return (SYMBOLP (obj)) ? XSYMBOL (obj) : NULL; +} + +char *DSYMNAME(Lisp_Object obj) +{ + return (SYMBOLP (obj)) ? XSYMBOL (obj)->name->_data : NULL; +} + +#endif
--- a/src/console-msw.h Mon Aug 13 10:18:22 2007 +0200 +++ b/src/console-msw.h Mon Aug 13 10:19:09 2007 +0200 @@ -1,4 +1,4 @@ -/* Define mswindowsindows-specific console, device, and frame object for XEmacs. +/* Define mswindows-specific console, device, and frame object for XEmacs. Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. @@ -35,6 +35,32 @@ #include "console.h" #include "windows.h" +#include "ddeml.h" /* DDE management library */ +#include "shellapi.h" /* FileManager/Explorer drag and drop */ + +/* + * XXX FIXME: The following X modifier defs in events-mod.h clash with win32 + * hotkey defs in winuser.h. For the moment lose the win32 versions. + * Maybe we should rename all of MOD_* to something that doesn't clash. + */ +#ifdef MOD_CONTROL +# undef MOD_CONTROL +#endif +#ifdef MOD_ALT +# undef MOD_ALT +#endif +#ifdef MOD_SHIFT +# undef MOD_SHIFT +#endif + + +/* The name of the main window class */ +#define XEMACS_CLASS "XEmacs" + + +/* + * Console + */ DECLARE_CONSOLE_TYPE (mswindows); @@ -44,6 +70,10 @@ }; +/* + * Device + */ + struct mswindows_device { int logpixelsx, logpixelsy; @@ -63,6 +93,10 @@ #define DEVICE_MSWINDOWS_VERTSIZE(d) (DEVICE_MSWINDOWS_DATA (d)->vertsize) +/* + * Frame + */ + struct mswindows_frame { /* win32 window handle */ @@ -99,10 +133,48 @@ #define FRAME_MSWINDOWS_MENU_HASHTABLE(f) (FRAME_MSWINDOWS_DATA (f)->menu_hashtable) #define FRAME_MSWINDOWS_MENU_CHECKSUM(f) (FRAME_MSWINDOWS_DATA (f)->menu_checksum) +/* win32 window LONG indices */ +#define XWL_FRAMEOBJ 0 +#define XWL_COUNT 1 /* Number of LONGs that we use */ +#define MSWINDOWS_WINDOW_EXTRA_BYTES (XWL_COUNT*4) + + /* - * Redisplay functions + * Events + */ + +/* win32 messages / magic event types */ +#define EVENT_MSWINDOWS_MAGIC_TYPE(e) \ + ((e)->event.magic.underlying_mswindows_event) +#define XM_BUMPQUEUE (WM_USER + 101) +#define XM_MAPFRAME (WM_USER + 102) +#define XM_UNMAPFRAME (WM_USER + 103) + + +/* + * Random globals */ + +/* win32 "Windows" procedure */ +LRESULT WINAPI mswindows_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam); + void mswindows_redraw_exposed_area (struct frame *f, int x, int y, - int width, int height); + int width, int height); + +/* win32 DDE management library */ +#define MSWINDOWS_DDE_ITEM_OPEN "Open" +extern DWORD mswindows_dde_mlid; +extern HSZ mswindows_dde_service; +extern HSZ mswindows_dde_topic_system; +extern HSZ mswindows_dde_item_open; +HDDEDATA CALLBACK mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, + HSZ hszTopic, HSZ hszItem, HDDEDATA hdata, + DWORD dwData1, DWORD dwData2); + +void mswindows_enqueue_dispatch_event (Lisp_Object event); +void mswindows_enqueue_magic_event (HWND hwnd, UINT message); +Lisp_Object mswindows_cancel_dispatch_event (struct Lisp_Event* event); +Lisp_Object mswindows_pump_outstanding_events (void); #endif /* _XEMACS_CONSOLE_MSW_H_ */
--- a/src/device-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/device-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -35,16 +35,22 @@ #include "console-msw.h" #include "console-stream.h" #include "events.h" -#include "event-msw.h" #include "faces.h" #include "frame.h" +#include "sysdep.h" + +/* win32 DDE management library globals */ +DWORD mswindows_dde_mlid; +HSZ mswindows_dde_service; +HSZ mswindows_dde_topic_system; +HSZ mswindows_dde_item_open; Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win; static void mswindows_init_device (struct device *d, Lisp_Object props) { - WNDCLASS wc; + WNDCLASSEX wc; HWND desktop; HDC hdc; @@ -71,6 +77,7 @@ DEVICE_CLASS(d) = Qcolor; /* Register the main window class */ + wc.cbSize = sizeof (WNDCLASSEX); wc.style = CS_OWNDC; /* One DC per window */ wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc; wc.cbClsExtra = 0; @@ -83,7 +90,32 @@ wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); wc.lpszMenuName = NULL; wc.lpszClassName = XEMACS_CLASS; - RegisterClass(&wc); /* XXX FIXME: Should use RegisterClassEx */ + wc.hIconSm = LoadImage (GetModuleHandle (NULL), XEMACS_CLASS, + IMAGE_ICON, 16, 16, 0); + RegisterClassEx (&wc); +} + +static void +mswindows_finish_init_device (struct device *d, Lisp_Object props) +{ + /* Initialise DDE management library and our related globals */ + mswindows_dde_mlid = 0; + DdeInitialize (&mswindows_dde_mlid, mswindows_dde_callback, + APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES| + CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS, 0); + + mswindows_dde_service = DdeCreateStringHandle (mswindows_dde_mlid, XEMACS_CLASS, 0); + mswindows_dde_topic_system = DdeCreateStringHandle (mswindows_dde_mlid, SZDDESYS_TOPIC, 0); + mswindows_dde_item_open = DdeCreateStringHandle (mswindows_dde_mlid, + TEXT(MSWINDOWS_DDE_ITEM_OPEN), 0); + DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER); +} + +static void +mswindows_delete_device (struct device *d) +{ + DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_REGISTER); + DdeUninitialize (mswindows_dde_mlid); } static int @@ -138,9 +170,9 @@ console_type_create_device_mswindows (void) { CONSOLE_HAS_METHOD (mswindows, init_device); -/* CONSOLE_HAS_METHOD (mswindows, finish_init_device); */ + CONSOLE_HAS_METHOD (mswindows, finish_init_device); /* CONSOLE_HAS_METHOD (mswindows, mark_device); */ -/* CONSOLE_HAS_METHOD (mswindows, delete_device); */ + CONSOLE_HAS_METHOD (mswindows, delete_device); CONSOLE_HAS_METHOD (mswindows, device_pixel_width); CONSOLE_HAS_METHOD (mswindows, device_pixel_height); CONSOLE_HAS_METHOD (mswindows, device_mm_width);
--- a/src/device.h Mon Aug 13 10:18:22 2007 +0200 +++ b/src/device.h Mon Aug 13 10:19:09 2007 +0200 @@ -275,6 +275,10 @@ #define CHECK_X_DEVICE(z) CHECK_DEVICE_TYPE (z, x) #define CONCHECK_X_DEVICE(z) CONCHECK_DEVICE_TYPE (z, x) +#define DEVICE_MSWINDOWS_P(dev) CONSOLE_TYPESYM_MSWINDOWS_P (DEVICE_TYPE (dev)) +#define CHECK_MSWINDOWS_DEVICE(z) CHECK_DEVICE_TYPE (z, mswindows) +#define CONCHECK_MSWINDOWS_DEVICE(z) CONCHECK_DEVICE_TYPE (z, mswindows) + #define DEVICE_TTY_P(dev) CONSOLE_TYPESYM_TTY_P (DEVICE_TYPE (dev)) #define CHECK_TTY_DEVICE(z) CHECK_DEVICE_TYPE (z, tty) #define CONCHECK_TTY_DEVICE(z) CONCHECK_DEVICE_TYPE (z, tty)
--- a/src/emacsfns.h Mon Aug 13 10:18:22 2007 +0200 +++ b/src/emacsfns.h Mon Aug 13 10:19:09 2007 +0200 @@ -1202,7 +1202,7 @@ extern Lisp_Object Qdevice; extern Lisp_Object Qdimension; extern Lisp_Object Qdisplay; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) extern Lisp_Object Qdnd_data; #endif extern Lisp_Object Qdoc_string;
--- a/src/eval.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/eval.c Mon Aug 13 10:19:09 2007 +0200 @@ -4926,6 +4926,7 @@ */ (stream, detailed)) { + /* This function can GC */ struct backtrace *backlist = backtrace_list; struct catchtag *catches = catchlist; int speccount = specpdl_depth_counter;
--- a/src/event-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/event-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -33,8 +33,17 @@ #include <config.h> #include "lisp.h" +#include "console-msw.h" + +#ifdef HAVE_SCROLLBARS +# include "scrollbar-msw.h" +#endif + +#ifdef HAVE_MENUBARS +# include "menubar-msw.h" +#endif + #include "device.h" -#include "console-msw.h" #include "emacsfns.h" #include "events.h" #include "frame.h" @@ -44,7 +53,35 @@ #include "syswait.h" #include "systime.h" -#include "event-msw.h" +#include "events-mod.h" + +#ifdef HAVE_MENUBARS +#define ADJR_MENUFLAG TRUE +#else +#define ADJR_MENUFLAG FALSE +#endif + +/* Fake key modifier which is attached to a quit char event. + Removed upon dequeueing an event */ +#define FAKE_MOD_QUIT 0x80 + +/* Timer ID used for button2 emulation */ +#define BUTTON_2_TIMER_ID 1 + +/* Drag and drop event data types (subset of types in offix-types.h) */ +#define DndFile 2 +#define DndFiles 3 +#define DndText 4 + + +static Lisp_Object mswindows_find_frame (HWND hwnd); +static Lisp_Object mswindows_find_console (HWND hwnd); +static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); +static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); +static void mswindows_set_chord_timer (HWND hwnd); +static int mswindows_button2_near_enough (POINTS p1, POINTS p2); +static int mswindows_current_layout_has_AltGr (void); + static struct event_stream *mswindows_event_stream; @@ -57,19 +94,14 @@ static Lisp_Object mswindows_u_dispatch_event_queue, mswindows_u_dispatch_event_queue_tail; static Lisp_Object mswindows_s_dispatch_event_queue, mswindows_s_dispatch_event_queue_tail; -/* - * List of mswindows waitable handles. - * Apart from the dispatch queue semaphore, all of these handles may be waited - * on multiple times in emacs_mswindows_next_event before being processed and so - * must be manual-reset events. - */ +/* The number of things we can wait on */ +#define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1) + +/* List of mswindows waitable handles. */ static HANDLE mswindows_waitable[MAX_WAITABLE]; -/* random emacs info associated with each of the wait handles */ -static mswindows_waitable_info_type mswindows_waitable_info[MAX_WAITABLE]; - /* Count of quit chars currently in the queue */ -/* Incremented in WM_CHAR handler in msw-proc.c +/* Incremented in WM_[SYS]KEYDOWN handler in the mswindows_wnd_proc() Decremented in mswindows_dequeue_dispatch_event() */ int mswindows_quit_chars_count = 0; @@ -96,10 +128,15 @@ { return (sevt->event_type == key_press_event || sevt->event_type == button_press_event - || sevt->event_type == button_release_event); + || sevt->event_type == button_release_event + || sevt->event_type == dnd_drop_event); } -/* +/************************************************************************/ +/* Dispatch queue management */ +/************************************************************************/ + +/* * Add an emacs event to the proper dispatch queue */ void @@ -117,6 +154,69 @@ PostMessage (NULL, XM_BUMPQUEUE, 0, 0); } +void +mswindows_enqueue_magic_event (HWND hwnd, UINT message) +{ + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event* event = XEVENT (emacs_event); + + event->channel = mswindows_find_frame (hwnd); + event->timestamp = GetMessageTime(); + event->event_type = magic_event; + EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; + + mswindows_enqueue_dispatch_event (emacs_event); +} + +static void +mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when) +{ + + /* We always use last message time, because mouse button + events may get delayed, and XEmacs double click + recognition will fail */ + + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event* event = XEVENT(emacs_event); + + event->channel = mswindows_find_frame(hwnd); + event->timestamp = when; + event->event.button.button = + (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : + ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); + event->event.button.x = where.x; + event->event.button.y = where.y; + event->event.button.modifiers = mswindows_modifier_state (NULL, 0); + + if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || + message==WM_RBUTTONDOWN) + { + event->event_type = button_press_event; + SetCapture (hwnd); + } + else + { + event->event_type = button_release_event; + ReleaseCapture (); + } + + mswindows_enqueue_dispatch_event (emacs_event); +} + +static void +mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) +{ + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event* event = XEVENT(emacs_event); + + event->channel = mswindows_find_console(hwnd); + event->timestamp = GetMessageTime(); + event->event_type = key_press_event; + event->event.key.keysym = keysym; + event->event.key.modifiers = mods; + mswindows_enqueue_dispatch_event (emacs_event); +} + /* * Remove and return the first emacs event on the dispatch queue. * Give a preference to user events over non-user ones. @@ -204,6 +304,11 @@ return Qnil; } + +/************************************************************************/ +/* Event pump */ +/************************************************************************/ + static Lisp_Object mswindows_modal_loop_error_handler (Lisp_Object cons_sig_data, Lisp_Object u_n_u_s_e_d) @@ -312,98 +417,16 @@ /* This function can call lisp */ Lisp_Object result = Qt; - + struct gcpro gcpro1; + GCPRO1 (result); + if (NILP(mswindows_error_caught_in_modal_loop)) result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil); + UNGCPRO; return result; } -/* - * Find a free waitable slot - */ -#if 0 /* NOTUSED */ -static int -mswindows_find_free_waitable(void) -{ - int i; - for (i=0; i<mswindows_waitable_count; i++) - if (mswindows_waitable_info[i].type == mswindows_waitable_type_none) - return i; - assert (mswindows_waitable_count < MAX_WAITABLE); - return mswindows_waitable_count++; -} -#endif -/* - * Create a new waitable using the type and data passed in by the info structure - * Returns a pointer to the info associated with the assigned waitable object - */ -mswindows_waitable_info_type * -mswindows_add_waitable(mswindows_waitable_info_type *info) -{ - int waitable; - - switch (info->type) - { - case mswindows_waitable_type_dispatch: - assert (0); /* kkm - should not get here */ - /* Can only have one waitable for the dispatch queue, and it's the first one */ - assert (mswindows_waitable_count++ == 0); - waitable=0; -#if 0 - InitializeCriticalSection(&mswindows_dispatch_crit); -#endif - assert (mswindows_waitable[0] = CreateSemaphore (NULL, 0, 0x7fffffff, NULL)); - return mswindows_waitable_info+0; - - default: - assert(0); - } - mswindows_waitable_info[waitable].type = info->type; - return mswindows_waitable_info+waitable; -} - -/* - * Remove a waitable using the type and data passed in by the info structure. - */ -void -mswindows_remove_waitable(mswindows_waitable_info_type *info) -{ - int waitable; - - switch (info->type) - { - - default: - assert(0); - } - - CloseHandle(mswindows_waitable[waitable]); - mswindows_waitable[waitable] = 0; - mswindows_waitable_info[waitable].type = mswindows_waitable_type_none; - if (waitable == mswindows_waitable_count-1) - --mswindows_waitable_count; -} - -/* - * Callback procedure for synchronous timer messages - */ -static void CALLBACK -mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) -{ - Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event *event = XEVENT (emacs_event); - - if (KillTimer (NULL, id_timer)) - --mswindows_pending_timers_count; - - event->channel = Qnil; - event->timestamp = dwtime; - event->event_type = timeout_event; - event->event.timeout.interval_id = id_timer; - - mswindows_enqueue_dispatch_event (emacs_event); -} static void mswindows_drain_windows_queue () @@ -523,20 +546,841 @@ { /* XXX FIXME: We should do some kind of round-robin scheme to ensure fairness */ int waitable = active - WAIT_OBJECT_0; - mswindows_waitable_info_type *info = mswindows_waitable_info + waitable; - - switch (info->type) - { - /* XXX FIXME: Should enque subprocess event here so that it is not lost */ - default: - assert(0); - } + assert(0); /* #### */ } } /* while */ return; } +/************************************************************************/ +/* Event generators */ +/************************************************************************/ + +/* + * Callback procedure for synchronous timer messages + */ +static void CALLBACK +mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) +{ + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event *event = XEVENT (emacs_event); + + if (KillTimer (NULL, id_timer)) + --mswindows_pending_timers_count; + + event->channel = Qnil; + event->timestamp = dwtime; + event->event_type = timeout_event; + event->event.timeout.interval_id = id_timer; + + mswindows_enqueue_dispatch_event (emacs_event); +} + +/* + * Callback procedure for dde messages + */ +HDDEDATA CALLBACK +mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, + HSZ hszTopic, HSZ hszItem, HDDEDATA hdata, + DWORD dwData1, DWORD dwData2) +{ + switch (uType) + { + case XTYP_CONNECT: + if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) + return (HDDEDATA)TRUE; + return (HDDEDATA)FALSE; + + case XTYP_WILDCONNECT: + { + /* We only support one {service,topic} pair */ + HSZPAIR pairs[2] = { + { mswindows_dde_service, mswindows_dde_topic_system }, { 0, 0 } }; + + if (!(hszItem || DdeCmpStringHandles (hszItem, mswindows_dde_service)) && + !(hszTopic || DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))); + return (DdeCreateDataHandle (mswindows_dde_mlid, (LPBYTE)pairs, + sizeof (pairs), 0L, 0, uFmt, 0)); + } + return (HDDEDATA)NULL; + + case XTYP_EXECUTE: + if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) + { + DWORD len = DdeGetData (hdata, NULL, 0, 0); + char *cmd = alloca (len+1); + char *end; + Lisp_Object l_dndlist; + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event *event = XEVENT (emacs_event); + + DdeGetData (hdata, cmd, len, 0); + cmd[len] = '\0'; + DdeFreeDataHandle (hdata); + + /* Check syntax & that it's an [Open("foo")] command */ + /* #### Ought to be generalised and accept some other commands */ + if (*cmd == '[') + cmd++; + if (strnicmp (cmd, MSWINDOWS_DDE_ITEM_OPEN, + strlen (MSWINDOWS_DDE_ITEM_OPEN))) + return DDE_FNOTPROCESSED; + cmd += strlen (MSWINDOWS_DDE_ITEM_OPEN); + while (*cmd==' ') + cmd++; + if (*cmd!='(' || *(cmd+1)!='\"') + return DDE_FNOTPROCESSED; + end = (cmd+=2); + while (*end && *end!='\"') + end++; + if (!*end) + return DDE_FNOTPROCESSED; + *end = '\0'; + if (*(++end)!=')') + return DDE_FNOTPROCESSED; + if (*(++end)==']') + end++; + if (*end) + return DDE_FNOTPROCESSED; + + l_dndlist = make_ext_string (cmd, strlen(cmd), FORMAT_FILENAME); + + event->channel = Qnil; + event->timestamp = GetTickCount(); + event->event_type = dnd_drop_event; + event->event.dnd_drop.button = 0; + event->event.dnd_drop.modifiers = 0; + event->event.dnd_drop.x = -1; + event->event.dnd_drop.y = -1; + event->event.dnd_drop.data = Fcons (make_int (DndFile), + Fcons (l_dndlist, Qnil)); + mswindows_enqueue_dispatch_event (emacs_event); + + return (HDDEDATA) DDE_FACK; + } + DdeFreeDataHandle (hdata); + return (HDDEDATA) DDE_FNOTPROCESSED; + + default: + return (HDDEDATA) NULL; + } + +} + +/* + * The windows procedure for the window class XEMACS_CLASS + */ +LRESULT WINAPI +mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + /* Note: Remember to initialise emacs_event and event before use. + This code calls code that can GC. You must GCPRO before calling such code. */ + Lisp_Object emacs_event = Qnil; + Lisp_Object fobj = Qnil; + + struct Lisp_Event *event; + struct frame *frame; + struct mswindows_frame* msframe; + + switch (message) + { + case WM_ERASEBKGND: + /* Erase background only during non-dynamic sizing */ + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + if (msframe->sizing && !mswindows_dynamic_frame_resize) + goto defproc; + return 1; + + case WM_CLOSE: + fobj = mswindows_find_frame (hwnd); + enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt)); + mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + BYTE keymap[256]; + int has_AltGr = mswindows_current_layout_has_AltGr (); + int mods; + Lisp_Object keysym; + + GetKeyboardState (keymap); + mods = mswindows_modifier_state (keymap, has_AltGr); + + /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */ + if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) + mswindows_enqueue_keypress_event (hwnd, keysym, mods); + else + { + int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); + BYTE keymap_orig[256]; + MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) }; + memcpy (keymap_orig, keymap, 256); + + /* Clear control and alt modifiers out of the keymap */ + keymap [VK_RCONTROL] = 0; + keymap [VK_LMENU] = 0; + if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) + { + keymap [VK_LCONTROL] = 0; + keymap [VK_CONTROL] = 0; + keymap [VK_RMENU] = 0; + keymap [VK_MENU] = 0; + } + SetKeyboardState (keymap); + + /* Have some WM_[SYS]CHARS in the queue */ + TranslateMessage (&msg); + + while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE) + ||PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) + { + int ch = msg.wParam; + /* CH is a character code for the key: + 'C' for Shift+C and Ctrl+Shift+C + 'c' for c and Ctrl+c */ + + /* #### If locale is not C, US or other latin-1, + isalpha() maybe not what do we mean */ + + /* XEmacs doesn't seem to like Shift on non-alpha keys */ + if (!isalpha(ch)) + mods &= ~MOD_SHIFT; + + /* Un-capitalise alpha control keys */ + if ((mods & MOD_CONTROL) && isalpha(ch)) + ch |= ('A' ^ 'a'); + + /* If a quit char with no modifiers other than control and + shift, then mark it with a fake modifier, which is removed + upon dequeueing the event */ + /* #### This might also not withstand localization, if + quit character is not a latin-1 symbol */ + if (((quit_ch < ' ' && (mods & MOD_CONTROL) && quit_ch + 'a' - 1 == ch) + || (quit_ch >= ' ' && !(mods & MOD_CONTROL) && quit_ch == ch)) + && ((mods & ~(MOD_CONTROL | MOD_SHIFT)) == 0)) + { + mods |= FAKE_MOD_QUIT; + ++mswindows_quit_chars_count; + } + + mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods); + } /* while */ + SetKeyboardState (keymap_orig); + } /* else */ + } + goto defproc; + + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + /* Real middle mouse button has nothing to do with emulated one: + if one wants to exercise fingers playing chords on the mouse, + he is allowed to do that! */ + mswindows_enqueue_mouse_button_event (hwnd, message, + MAKEPOINTS (lParam), GetMessageTime()); + break; + + case WM_LBUTTONUP: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->last_click_time = GetMessageTime(); + + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_lbutton = 0; + if (msframe->ignore_next_lbutton_up) + { + msframe->ignore_next_lbutton_up = 0; + } + else if (msframe->button2_is_down) + { + msframe->button2_is_down = 0; + msframe->ignore_next_rbutton_up = 1; + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + else + { + if (msframe->button2_need_rbutton) + { + msframe->button2_need_rbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + break; + + case WM_RBUTTONUP: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->last_click_time = GetMessageTime(); + + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_rbutton = 0; + if (msframe->ignore_next_rbutton_up) + { + msframe->ignore_next_rbutton_up = 0; + } + else if (msframe->button2_is_down) + { + msframe->button2_is_down = 0; + msframe->ignore_next_lbutton_up = 1; + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + else + { + if (msframe->button2_need_lbutton) + { + msframe->button2_need_lbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + break; + + case WM_LBUTTONDOWN: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + + if (msframe->button2_need_lbutton) + { + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_lbutton = 0; + msframe->button2_need_rbutton = 0; + if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam))) + { + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + msframe->button2_is_down = 1; + } + else + { + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + } + else + { + mswindows_set_chord_timer (hwnd); + msframe->button2_need_rbutton = 1; + msframe->last_click_point = MAKEPOINTS (lParam); + } + msframe->last_click_time = GetMessageTime(); + break; + + case WM_RBUTTONDOWN: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + + if (msframe->button2_need_rbutton) + { + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_lbutton = 0; + msframe->button2_need_rbutton = 0; + if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam))) + { + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + msframe->button2_is_down = 1; + } + else + { + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + } + else + { + mswindows_set_chord_timer (hwnd); + msframe->button2_need_lbutton = 1; + msframe->last_click_point = MAKEPOINTS (lParam); + } + msframe->last_click_time = GetMessageTime(); + break; + + case WM_TIMER: + if (wParam == BUTTON_2_TIMER_ID) + { + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + KillTimer (hwnd, BUTTON_2_TIMER_ID); + + if (msframe->button2_need_lbutton) + { + msframe->button2_need_lbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + } + else if (msframe->button2_need_rbutton) + { + msframe->button2_need_rbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + } + } + else + assert ("Spurious timer fired" == 0); + break; + + case WM_MOUSEMOVE: + /* Optimization: don't report mouse movement while size is changind */ + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + if (!msframe->sizing) + { + /* When waiting for the second mouse button to finish + button2 emulation, and have moved too far, just pretend + as if timer has expired. This impoves drag-select feedback */ + if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton) + && !mswindows_button2_near_enough (msframe->last_click_point, + MAKEPOINTS (lParam))) + { + KillTimer (hwnd, BUTTON_2_TIMER_ID); + SendMessage (hwnd, WM_TIMER, BUTTON_2_TIMER_ID, 0); + } + + emacs_event = Fmake_event (Qnil, Qnil); + event = XEVENT(emacs_event); + + event->channel = mswindows_find_frame(hwnd); + event->timestamp = GetMessageTime(); + event->event_type = pointer_motion_event; + event->event.motion.x = MAKEPOINTS(lParam).x; + event->event.motion.y = MAKEPOINTS(lParam).y; + event->event.motion.modifiers = mswindows_modifier_state (NULL, 0); + + mswindows_enqueue_dispatch_event (emacs_event); + } + break; + + case WM_PAINT: + { + PAINTSTRUCT paintStruct; + + frame = XFRAME (mswindows_find_frame (hwnd)); + + BeginPaint (hwnd, &paintStruct); + mswindows_redraw_exposed_area (frame, + paintStruct.rcPaint.left, paintStruct.rcPaint.top, + paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); + EndPaint (hwnd, &paintStruct); + } + break; + + case WM_SIZE: + /* We only care about this message if our size has really changed */ + if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED) + { + RECT rect; + int columns, rows; + + fobj = mswindows_find_frame (hwnd); + frame = XFRAME (fobj); + msframe = FRAME_MSWINDOWS_DATA (frame); + + /* We cannot handle frame map and unmap hooks right in + this routine, because these may throw. We queue + magic events to run these hooks instead - kkm */ + + if (wParam==SIZE_MINIMIZED) + { + /* Iconified */ + FRAME_VISIBLE_P (frame) = 0; + mswindows_enqueue_magic_event (hwnd, XM_UNMAPFRAME); + Fframe_iconified_p (fobj); + } + else + { + int was_visible = FRAME_VISIBLE_P (frame); + if (!msframe->sizing && !was_visible) + mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME); + + GetClientRect(hwnd, &rect); + FRAME_VISIBLE_P(frame) = 1; + FRAME_PIXWIDTH(frame) = rect.right; + FRAME_PIXHEIGHT(frame) = rect.bottom; + pixel_to_char_size (frame, rect.right, rect.bottom, &columns, &rows); + change_frame_size (frame, rows, columns, 1); + + if (msframe->sizing && mswindows_dynamic_frame_resize) + redisplay (); + } + } + break; + + /* Misc magic events which only require that the frame be identified */ + case WM_SETFOCUS: + case WM_KILLFOCUS: + mswindows_enqueue_magic_event (hwnd, message); + break; + + case WM_WINDOWPOSCHANGING: + { + WINDOWPOS *wp = (LPWINDOWPOS) lParam; + WINDOWPLACEMENT wpl = { sizeof(WINDOWPLACEMENT) }; + GetWindowPlacement(hwnd, &wpl); + + /* Only interested if size is changing and we're not being iconified */ + if ((wpl.showCmd != SW_SHOWMINIMIZED) && !(wp->flags & SWP_NOSIZE)) + { + RECT ncsize = { 0, 0, 0, 0 }; + int pixwidth, pixheight; + AdjustWindowRectEx (&ncsize, GetWindowLong (hwnd, GWL_STYLE), + GetMenu(hwnd) != NULL, + GetWindowLong (hwnd, GWL_EXSTYLE)); + + round_size_to_char (XFRAME (mswindows_find_frame (hwnd)), + wp->cx - (ncsize.right - ncsize.left), + wp->cy - (ncsize.bottom - ncsize.top), + &pixwidth, &pixheight); + + /* Convert client sizes to window sizes */ + pixwidth += (ncsize.right - ncsize.left); + pixheight += (ncsize.bottom - ncsize.top); + + if (wpl.showCmd != SW_SHOWMAXIMIZED) + { + /* Adjust so that the bottom or right doesn't move if it's + * the top or left that's being changed */ + RECT rect; + GetWindowRect (hwnd, &rect); + + if (rect.left != wp->x) + wp->x += wp->cx - pixwidth; + if (rect.top != wp->y) + wp->y += wp->cy - pixheight; + } + + wp->cx = pixwidth; + wp->cy = pixheight; + } + } + break; + + case WM_ENTERSIZEMOVE: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->sizing = 1; + return 0; + + case WM_EXITSIZEMOVE: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->sizing = 0; + /* Queue noop event */ + mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE); + return 0; + +#ifdef HAVE_SCROLLBARS + case WM_VSCROLL: + case WM_HSCROLL: + { + /* Direction of scroll is determined by scrollbar instance. */ + int code = (int) LOWORD(wParam); + int pos = (short int) HIWORD(wParam); + HWND hwndScrollBar = (HWND) lParam; + struct gcpro gcpro1, gcpro2; + + mswindows_handle_scrollbar_event (hwndScrollBar, code, pos); + GCPRO2 (emacs_event, fobj); + if (UNBOUNDP(mswindows_pump_outstanding_events())) /* Can GC */ + { + /* Error during event pumping - cancel scroll */ + SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); + } + UNGCPRO; + break; + } +#endif + +#ifdef HAVE_MENUBARS + case WM_INITMENU: + if (UNBOUNDP (mswindows_handle_wm_initmenu ( + (HMENU) wParam, + XFRAME (mswindows_find_frame (hwnd))))) + SendMessage (hwnd, WM_CANCELMODE, 0, 0); + break; + + case WM_INITMENUPOPUP: + if (!HIWORD(lParam)) + { + if (UNBOUNDP (mswindows_handle_wm_initmenupopup ( + (HMENU) wParam, + XFRAME (mswindows_find_frame (hwnd))))) + SendMessage (hwnd, WM_CANCELMODE, 0, 0); + } + break; + + case WM_EXITMENULOOP: + if (UNBOUNDP (mswindows_handle_wm_exitmenuloop ( + XFRAME (mswindows_find_frame (hwnd))))) + SendMessage (hwnd, WM_CANCELMODE, 0, 0); + break; + +#endif /* HAVE_MENUBARS */ + + case WM_COMMAND: + { + WORD id = LOWORD (wParam); + frame = XFRAME (mswindows_find_frame (hwnd)); + +#ifdef HAVE_MENUBARS + if (!NILP (mswindows_handle_wm_command (frame, id))) + break; +#endif + +#ifdef HAVE_TOOLBARS + O Toolbar Implementor, this place may have something for you!; +#endif + + /* Bite me - a spurious command. No abort(), for safety */ + /* #### Perhaps, this message should be changed */ + error ("Cannot decode command. Tell kkm he's a parallelogramm, if you know" + " what does that mean!"); + } + break; + + case WM_DROPFILES: /* implementation ripped-off from event-Xt.c */ + { + UINT filecount, i, len; + POINT point; + char filename[MAX_PATH]; + Lisp_Object l_type, l_dndlist = Qnil, l_item; + + emacs_event = Fmake_event (Qnil, Qnil); + event = XEVENT(emacs_event); + + if (!DragQueryPoint ((HANDLE) wParam, &point)) + point.x = point.y = -1; /* outside client area */ + + filecount = DragQueryFile ((HANDLE) wParam, -1, NULL, 0); + if (filecount == 1) + { + l_type = make_int (DndFile); + len = DragQueryFile ((HANDLE) wParam, 0, filename, MAX_PATH); + l_dndlist = make_ext_string (filename, len, FORMAT_FILENAME); + } + else + { + l_type = make_int (DndFiles); + for (i=0; i<filecount; i++) + { + len = DragQueryFile ((HANDLE) wParam, i, filename, MAX_PATH); + l_item = make_ext_string (filename, len, FORMAT_FILENAME); + l_dndlist = Fcons (l_item, l_dndlist); /* reverse order */ + } + } + DragFinish ((HANDLE) wParam); + + event->channel = mswindows_find_frame(hwnd); + event->timestamp = GetMessageTime(); + event->event_type = dnd_drop_event; + event->event.dnd_drop.button = 1; /* #### Should try harder */ + event->event.dnd_drop.modifiers = mswindows_modifier_state (NULL, 0); + event->event.dnd_drop.x = point.x; + event->event.dnd_drop.y = point.y; + event->event.dnd_drop.data = Fcons (l_type, Fcons (l_dndlist, Qnil)); + + mswindows_enqueue_dispatch_event (emacs_event); + } + break; + + defproc: + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } + return (0); +} + + +/************************************************************************/ +/* keyboard, mouse & other helpers for the windows procedure */ +/************************************************************************/ +static void +mswindows_set_chord_timer (HWND hwnd) +{ + int interval; + + /* We get half system threshold as it seems to + long before drag-selection is shown */ + if (mswindows_button2_chord_time <= 0) + interval = GetDoubleClickTime () / 2; + else + interval = mswindows_button2_chord_time; + + SetTimer (hwnd, BUTTON_2_TIMER_ID, interval, 0); +} + +static int +mswindows_button2_near_enough (POINTS p1, POINTS p2) +{ + int dx, dy; + if (mswindows_button2_max_skew_x <= 0) + dx = GetSystemMetrics (SM_CXDOUBLECLK) / 2; + else + dx = mswindows_button2_max_skew_x; + + if (mswindows_button2_max_skew_y <= 0) + dy = GetSystemMetrics (SM_CYDOUBLECLK) / 2; + else + dy = mswindows_button2_max_skew_y; + + return abs (p1.x - p2.x) < dx && abs (p1.y- p2.y)< dy; +} + +static int +mswindows_current_layout_has_AltGr (void) +{ + /* This simple caching mechanism saves 10% of CPU + time when a key typed at autorepeat rate of 30 cps! */ + static HKL last_hkl = 0; + static int last_hkl_has_AltGr; + + HKL current_hkl = GetKeyboardLayout (0); + if (current_hkl != last_hkl) + { + TCHAR c; + last_hkl_has_AltGr = 0; + /* In this loop, we query whether a character requires + AltGr to be down to generate it. If at least such one + found, this means that the layout does regard AltGr */ + for (c = ' '; c <= 0xFFU && c != 0 && !last_hkl_has_AltGr; ++c) + if (HIBYTE (VkKeyScan (c)) == 6) + last_hkl_has_AltGr = 1; + last_hkl = current_hkl; + } + return last_hkl_has_AltGr; +} + + +/* Returns the state of the modifier keys in the format expected by the + * Lisp_Event key_data, button_data and motion_data modifiers member */ +int mswindows_modifier_state (BYTE* keymap, int has_AltGr) +{ + int mods = 0; + + if (keymap == NULL) + { + keymap = (BYTE*) alloca(256); + GetKeyboardState (keymap); + has_AltGr = mswindows_current_layout_has_AltGr (); + } + + if (has_AltGr && (keymap [VK_LCONTROL] & 0x80) && (keymap [VK_RMENU] & 0x80)) + { + mods |= (keymap [VK_LMENU] & 0x80) ? MOD_META : 0; + mods |= (keymap [VK_RCONTROL] & 0x80) ? MOD_CONTROL : 0; + } + else + { + mods |= (keymap [VK_MENU] & 0x80) ? MOD_META : 0; + mods |= (keymap [VK_CONTROL] & 0x80) ? MOD_CONTROL : 0; + } + + mods |= (keymap [VK_SHIFT] & 0x80) ? MOD_SHIFT : 0; + + return mods; +} + +/* + * Translate a mswindows virtual key to a keysym. + * Only returns non-Qnil for keys that don't generate WM_CHAR messages + * or whose ASCII codes (like space) xemacs doesn't like. + * Virtual key values are defined in winresrc.h + * XXX I'm not sure that KEYSYM("name") is the best thing to use here. + */ +Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods) +{ + switch (mswindows_key) + { + /* First the predefined ones */ + case VK_BACK: return QKbackspace; + case VK_TAB: return QKtab; + case '\n': return QKlinefeed; /* No VK_LINEFEED in winresrc.h */ + case VK_RETURN: return QKreturn; + case VK_ESCAPE: return QKescape; + case VK_SPACE: return QKspace; + case VK_DELETE: return QKdelete; + + /* The rest */ + case VK_CLEAR: return KEYSYM ("clear"); /* Should do ^L ? */ + case VK_PRIOR: return KEYSYM ("prior"); + case VK_NEXT: return KEYSYM ("next"); + case VK_END: return KEYSYM ("end"); + case VK_HOME: return KEYSYM ("home"); + case VK_LEFT: return KEYSYM ("left"); + case VK_UP: return KEYSYM ("up"); + case VK_RIGHT: return KEYSYM ("right"); + case VK_DOWN: return KEYSYM ("down"); + case VK_SELECT: return KEYSYM ("select"); + case VK_PRINT: return KEYSYM ("print"); + case VK_EXECUTE: return KEYSYM ("execute"); + case VK_SNAPSHOT: return KEYSYM ("print"); + case VK_INSERT: return KEYSYM ("insert"); + case VK_HELP: return KEYSYM ("help"); +#if 0 /* XXX What are these supposed to do? */ + case VK_LWIN return KEYSYM (""); + case VK_RWIN return KEYSYM (""); +#endif + case VK_APPS: return KEYSYM ("menu"); + case VK_F1: return KEYSYM ("f1"); + case VK_F2: return KEYSYM ("f2"); + case VK_F3: return KEYSYM ("f3"); + case VK_F4: return KEYSYM ("f4"); + case VK_F5: return KEYSYM ("f5"); + case VK_F6: return KEYSYM ("f6"); + case VK_F7: return KEYSYM ("f7"); + case VK_F8: return KEYSYM ("f8"); + case VK_F9: return KEYSYM ("f9"); + case VK_F10: return KEYSYM ("f10"); + case VK_F11: return KEYSYM ("f11"); + case VK_F12: return KEYSYM ("f12"); + case VK_F13: return KEYSYM ("f13"); + case VK_F14: return KEYSYM ("f14"); + case VK_F15: return KEYSYM ("f15"); + case VK_F16: return KEYSYM ("f16"); + case VK_F17: return KEYSYM ("f17"); + case VK_F18: return KEYSYM ("f18"); + case VK_F19: return KEYSYM ("f19"); + case VK_F20: return KEYSYM ("f20"); + case VK_F21: return KEYSYM ("f21"); + case VK_F22: return KEYSYM ("f22"); + case VK_F23: return KEYSYM ("f23"); + case VK_F24: return KEYSYM ("f24"); + } + return Qnil; +} + +/* + * Find the console that matches the supplied mswindows window handle + */ +Lisp_Object +mswindows_find_console (HWND hwnd) +{ + Lisp_Object concons; + + CONSOLE_LOOP (concons) + { + Lisp_Object console = XCAR (concons); + /* We only support one console so this must be it */ + return console; + } + + return Qnil; +} + +/* + * Find the frame that matches the supplied mswindows window handle + */ +static Lisp_Object +mswindows_find_frame (HWND hwnd) +{ + return (Lisp_Object) GetWindowLong (hwnd, XWL_FRAMEOBJ); +} + + /************************************************************************/ /* methods */ @@ -554,7 +1398,8 @@ if (milliseconds < 1) milliseconds = 1; ++mswindows_pending_timers_count; - return SetTimer (NULL, 0, milliseconds, mswindows_wm_timer_callback); + return SetTimer (NULL, 0, milliseconds, + (TIMERPROC) mswindows_wm_timer_callback); } static void @@ -617,11 +1462,6 @@ static void emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) { -#if 0 - stderr_out("magic %x, (%d,%d), (%d,%d)\n", - EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event), - rect->left, rect->top, rect->right, rect->bottom); -#endif switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event)) { case WM_SETFOCUS: @@ -662,7 +1502,7 @@ } break; - /* XXX What about Enter & Leave */ + /* #### What about Enter & Leave */ #if 0 va_run_hook_with_args (in_p ? Qmouse_enter_frame_hook : Qmouse_leave_frame_hook, 1, frame);
--- a/src/event-msw.h Mon Aug 13 10:18:22 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* mswindows-specific defines for event-handling. - Copyright (C) 1997 Jonathan Harris. - -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: Not in FSF. */ - -/* Authorship: - - Jonathan Harris, November 1997 for 20.4. - */ - -#ifndef _XEMACS_EVENT_MSW_H_ -#define _XEMACS_EVENT_MSW_H_ - -#include <windows.h> - -/* - * XXX FIXME: The following X modifier defs in events-mod.h clash with win32 - * hotkey defs in winuser.h. For the moment lose the win32 versions. - * Maybe we should rename all of MOD_* to something that doesn't clash. - */ -#ifdef MOD_CONTROL -# undef MOD_CONTROL -#endif -#ifdef MOD_ALT -# undef MOD_ALT -#endif -#ifdef MOD_SHIFT -# undef MOD_SHIFT -#endif -#include "events-mod.h" - -/* The name of the main window class */ -#define XEMACS_CLASS "XEmacs" - -/* Granularity of timeouts in milliseconds & max number of active timeouts */ -#define MSW_TIMEOUT_GRANULARITY 25 -#define MSW_TIMEOUT_MAX 32 - -/* Random globals */ -LRESULT WINAPI mswindows_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -Lisp_Object mswindows_pump_outstanding_events (void); -Lisp_Object mswindows_protect_modal_loop (Lisp_Object (*bfun) (Lisp_Object barg), - Lisp_Object barg); -void mswindows_unmodalize_signal_maybe (void); -void mswindows_enqueue_dispatch_event (Lisp_Object event); -void mswindows_enqueue_magic_event (HWND hwnd, UINT message); - -extern int mswindows_quit_chars_count; - -/* These are Lisp integer variables */ -/* Jonsthan, these need not to be globals after merge -- kkm */ -extern int mswindows_dynamic_frame_resize; -extern int mswindows_num_mouse_buttons; -extern int mswindows_button2_max_skew_x; -extern int mswindows_button2_max_skew_y; -extern int mswindows_button2_chord_time; - -/* - * Event generating stuff - */ - -/* The number of things we can wait on */ -#define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1) - -typedef enum mswindows_waitable_type -{ - mswindows_waitable_type_none, - mswindows_waitable_type_dispatch, - mswindows_waitable_type_timeout, - mswindows_waitable_type_process, - mswindows_waitable_type_socket -} mswindows_waitable_type; - -typedef struct mswindows_timeout_data -{ - int milliseconds; - int id; -} mswindows_timeout_data; - -typedef struct mswindows_waitable_info_type -{ - mswindows_waitable_type type; - union - { - mswindows_timeout_data timeout; - } data; -} mswindows_waitable_info_type; - -mswindows_waitable_info_type *mswindows_add_waitable(mswindows_waitable_info_type *info); -void mswindows_remove_waitable(mswindows_waitable_info_type *info); - -/* - * Some random function declarations in msw-proc.c - */ -extern void mswindows_enqeue_dispatch_event (Lisp_Object event); -Lisp_Object mswindows_cancel_dispatch_event (struct Lisp_Event* event); - -/* - * Inside mswindows magic events - */ -#define EVENT_MSWINDOWS_MAGIC_EVENT(e) \ - ((e)->event.magic.underlying_mswindows_event) -#define EVENT_MSWINDOWS_MAGIC_TYPE(e) \ - (EVENT_MSWINDOWS_MAGIC_EVENT(e).message) -#define EVENT_MSWINDOWS_MAGIC_DATA(e) \ - (*((RECT *) (&(EVENT_MSWINDOWS_MAGIC_EVENT(e).data)))) - -/* - * Messages and magic events IDs - */ -#define XM_BUMPQUEUE (WM_USER + 101) -#define XM_MAPFRAME (WM_USER + 102) -#define XM_UNMAPFRAME (WM_USER + 103) - -/* - * Window LONGs indices - */ -#define XWL_FRAMEOBJ 0 - -/* This must be number of the above long multiplied by 4 */ -#define MSWINDOWS_WINDOW_EXTRA_BYTES 4 - -/* Fake key modifiers which attached to a quit char event. - Removed upon dequeueing an event */ -#define FAKE_MOD_QUIT 0x80 - -#endif /* _XEMACS_EVENT_MSW_H_ */
--- a/src/event-stream.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/event-stream.c Mon Aug 13 10:19:09 2007 +0200 @@ -2175,7 +2175,7 @@ default: goto RETURN; case button_release_event: -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif case misc_user_event: @@ -3969,7 +3969,7 @@ if (EVENTP (event) && (XEVENT_TYPE (event) == button_press_event || XEVENT_TYPE (event) == button_release_event -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) || XEVENT_TYPE (event) == dnd_drop_event #endif || XEVENT_TYPE (event) == misc_user_event)) @@ -4003,7 +4003,7 @@ { case button_press_event : case button_release_event : -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif case misc_user_event : @@ -4109,7 +4109,7 @@ else if (e->event_type == button_press_event || e->event_type == button_release_event) e->event.button.modifiers |= MOD_META; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) else if (e->event_type == dnd_drop_event) e->event.dnd_drop.modifiers |= MOD_META; #endif @@ -4212,7 +4212,7 @@ break; case button_press_event: case button_release_event: -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif case misc_user_event: @@ -4442,7 +4442,7 @@ { case button_press_event: case button_release_event: -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif case key_press_event:
--- a/src/events.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/events.c Mon Aug 13 10:19:09 2007 +0200 @@ -66,7 +66,7 @@ Lisp_Object Qkey_press, Qbutton_press, Qbutton_release, Qmisc_user; Lisp_Object Qascii_character; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) Lisp_Object Qdnd_drop_event_p; Lisp_Object Qdnd_drop; #endif @@ -135,7 +135,7 @@ case magic_event: case empty_event: case dead_event: -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif break; @@ -215,7 +215,7 @@ case dead_event: write_c_string ("#<DEALLOCATED-EVENT", printcharfun); break; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: print_event_1 ("#<dnd-drop-event ", obj, printcharfun); break; @@ -273,7 +273,7 @@ internal_equal (e1->event.magic_eval.object, e2->event.magic_eval.object, 0)); -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: return (e1->event.dnd_drop.button == e2->event.dnd_drop.button && e1->event.dnd_drop.modifiers == e2->event.dnd_drop.modifiers && @@ -350,7 +350,7 @@ (unsigned long) e->event.magic_eval.internal_function, internal_hash (e->event.magic_eval.object, depth + 1)); -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: return HASH4 (hash, e->event.dnd_drop.button, e->event.dnd_drop.modifiers, LISP_HASH(e->event.dnd_drop.data)); @@ -369,12 +369,7 @@ #endif #ifdef HAVE_MS_WINDOWS if (CONSOLE_MSWINDOWS_P (con)) - return HASH6 (hash, e->event.magic.underlying_mswindows_event.message, - e->event.magic.underlying_mswindows_event.data[0], - e->event.magic.underlying_mswindows_event.data[1], - e->event.magic.underlying_mswindows_event.data[2], - e->event.magic.underlying_mswindows_event.data[3] - ); + return HASH2 (hash, e->event.magic.underlying_mswindows_event); #endif } @@ -487,7 +482,7 @@ e->event_type = button_release_event; else if (EQ (type, Qmotion)) e->event_type = pointer_motion_event; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) else if (EQ (type, Qdnd_drop)) { e->event_type = dnd_drop_event; @@ -606,7 +601,7 @@ CHECK_NATNUM (value); e->timestamp = XINT (value); } -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) else if (EQ (keyword, Qdnd_data)) { Lisp_Object dnd_tail; @@ -630,7 +625,7 @@ e->event.dnd_drop.data = Fcopy_tree (value, Qnil); } } -#endif /* HAVE_OFFIX_DND */ +#endif /* HAVE_OFFIX_DND || HAVE_MS_WINDOWS */ else signal_simple_error ("Invalid property", keyword); } /* while */ @@ -649,7 +644,7 @@ if (e->event_type == pointer_motion_event || e->event_type == button_press_event || e->event_type == button_release_event -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) || e->event_type == dnd_drop_event #endif ) @@ -666,7 +661,7 @@ } else if (e->event_type == button_press_event || e->event_type == button_release_event -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) || e->event_type == dnd_drop_event #endif ) @@ -685,14 +680,14 @@ break; case button_press_event: case button_release_event: -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif if (!e->event.button.button) error ("Undefined button for %s event", e->event_type == button_press_event ? "buton-press" : -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) e->event_type == button_release_event ? "button-release" : "dnd-drop" #else @@ -956,7 +951,7 @@ case button_press_event: case button_release_event: case misc_user_event: -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: #endif return 1; @@ -1216,7 +1211,7 @@ int mouse_p = 0; int mod = 0; Lisp_Object key; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) int dnd_p = 0; #endif @@ -1263,7 +1258,7 @@ else strcpy (buf, "???"); return; } -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: { dnd_p++; @@ -1297,7 +1292,7 @@ --mouse_p; } -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) switch (dnd_p) { case 1: @@ -1440,7 +1435,7 @@ case process_event: return Qprocess; case timeout_event: return Qtimeout; case eval_event: return Qeval; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: return Qdnd_drop; #endif case magic_event: @@ -1497,7 +1492,7 @@ */ (event)) { -#ifndef HAVE_OFFIX_DND +#if !defined(HAVE_OFFIX_DND) && !defined(HAVE_MS_WINDOWS) CHECK_EVENT_TYPE2 (event, button_press_event, button_release_event, Qbutton_event_p); @@ -1507,7 +1502,7 @@ return Qzero; #endif /* !HAVE_WINDOW_SYSTEM */ -#else /* HAVE_OFFIX_DND */ +#else /* HAVE_OFFIX_DND || HAVE_MS_WINDOWS */ CHECK_LIVE_EVENT (event); if (XEVENT(event)->event_type == (button_press_event) || @@ -1541,7 +1536,7 @@ return make_int (XEVENT (event)->event.button.modifiers); case pointer_motion_event: return make_int (XEVENT (event)->event.motion.modifiers); -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: return make_int (XEVENT (event)->event.dnd_drop.modifiers); #endif @@ -1586,7 +1581,7 @@ *x = XEVENT (event)->event.button.x; *y = XEVENT (event)->event.button.y; } -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) else if (XEVENT (event)->event_type == dnd_drop_event) { *x = XEVENT (event)->event.dnd_drop.x; @@ -1743,7 +1738,7 @@ pix_x = XEVENT (event)->event.button.x; pix_y = XEVENT (event)->event.button.y; break; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event : pix_x = XEVENT (event)->event.dnd_drop.x; pix_y = XEVENT (event)->event.dnd_drop.y; @@ -2103,7 +2098,7 @@ */ (event)) { -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) again: CHECK_LIVE_EVENT (event); switch (XEVENT (event)->event_type) @@ -2114,9 +2109,9 @@ event = wrong_type_argument (Qdnd_drop_event_p, event); goto again; } -#else /* !HAVE_OFFIX_DND */ +#else /* !(HAVE_OFFIX_DND || HAVE_MS_WINDOWS) */ return Qnil; -#endif /* HAVE_OFFIX_DND */ +#endif /* HAVE_OFFIX_DND || HAVE_MS_WINDOWS */ } DEFUN ("event-properties", Fevent_properties, 1, 1, 0, /* @@ -2173,7 +2168,7 @@ props = Fcons (Qfunction, Fcons (Fevent_function (event), props)); break; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: props = Fcons (Qy, Fcons (Fevent_y_pixel (event), props)); props = Fcons (Qx, Fcons (Fevent_x_pixel (event), props)); @@ -2262,7 +2257,7 @@ defsymbol (&Qbutton_release, "button-release"); defsymbol (&Qmisc_user, "misc-user"); defsymbol (&Qascii_character, "ascii-character"); -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) defsymbol (&Qdnd_drop_event_p, "dnd-drop-event-p"); defsymbol (&Qdnd_drop, "dnd-drop"); #endif
--- a/src/events.h Mon Aug 13 10:18:22 2007 +0200 +++ b/src/events.h Mon Aug 13 10:19:09 2007 +0200 @@ -255,7 +255,7 @@ a magic_event; the Lisp programmer need not know anything more. - #ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) dnd_drop_event dnd_drag_event (* to be implemented *) button What button went down or up. @@ -302,7 +302,7 @@ magic_eval_event, eval_event, misc_user_event, -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) dnd_drop_event, #endif dead_event @@ -355,7 +355,7 @@ Lisp_Object object; }; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) struct dnd_drop_data { int button; @@ -378,11 +378,7 @@ XEvent underlying_x_event; #endif #ifdef HAVE_MS_WINDOWS - struct - { - int message; - unsigned long data[4]; /* XXX Big enough for biggest thing? */ - } underlying_mswindows_event; + int underlying_mswindows_event; #endif }; @@ -409,7 +405,7 @@ struct eval_data eval; /* misc_user_event uses this too */ union magic_data magic; struct magic_eval_data magic_eval; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) struct dnd_drop_data dnd_drop; #endif } event;
--- a/src/faces.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/faces.c Mon Aug 13 10:19:09 2007 +0200 @@ -872,6 +872,8 @@ void init_device_faces (struct device *d) { + /* This function can call lisp */ + /* When making the initial terminal device, there is no Lisp code loaded, so we can't do this. */ if (initialized)
--- a/src/frame-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/frame-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -32,7 +32,6 @@ #include "lisp.h" #include "console-msw.h" -#include "event-msw.h" #include "buffer.h" #include "faces.h" @@ -132,6 +131,7 @@ /* Don't do this earlier or we get a WM_PAINT before the frame is ready*/ ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL); SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f)); + DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE); } static void
--- a/src/frame.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/frame.c Mon Aug 13 10:19:09 2007 +0200 @@ -54,7 +54,7 @@ Lisp_Object Vmap_frame_hook, Qmap_frame_hook; Lisp_Object Vunmap_frame_hook, Qunmap_frame_hook; int allow_deletion_of_last_visible_frame; -#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) +#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) Lisp_Object Vdrag_and_drop_functions, Qdrag_and_drop_functions; #endif Lisp_Object Vmouse_motion_handler; @@ -2892,7 +2892,7 @@ defsymbol (&Qmouse_leave_frame_hook, "mouse-leave-frame-hook"); defsymbol (&Qmap_frame_hook, "map-frame-hook"); defsymbol (&Qunmap_frame_hook, "unmap-frame-hook"); -#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) +#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) defsymbol (&Qdrag_and_drop_functions, "drag-and-drop-functions"); #endif @@ -3082,7 +3082,7 @@ */ ); allow_deletion_of_last_visible_frame = 0; -#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) +#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) DEFVAR_LISP ("drag-and-drop-functions", &Vdrag_and_drop_functions /* Function or functions to run when an object is dropped on a frame. Each function is called with either two or three args. If called with @@ -3091,7 +3091,7 @@ and the textual representation of the dragged object. */ ); Vdrag_and_drop_functions = Qnil; -#endif /* HAVE_CDE */ +#endif /* HAVE_CDE || HAVE_OFFIX_DND || HAVE_MS_WINDOWS */ DEFVAR_LISP ("mouse-motion-handler", &Vmouse_motion_handler /* Handler for motion events. One arg, the event.
--- a/src/glyphs.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/glyphs.c Mon Aug 13 10:19:09 2007 +0200 @@ -2057,12 +2057,13 @@ void (*after_change) (Lisp_Object glyph, Lisp_Object property, Lisp_Object locale)) { + /* This function can GC */ Lisp_Object obj = Qnil; struct Lisp_Glyph *g = alloc_lcrecord_type (struct Lisp_Glyph, lrecord_glyph); g->type = type; - g->image = Fmake_specifier (Qimage); + g->image = Fmake_specifier (Qimage); /* This function can GC */ switch (g->type) { case GLYPH_BUFFER: @@ -2082,18 +2083,31 @@ abort (); } - set_specifier_fallback (g->image, list1 (Fcons (Qnil, Vthe_nothing_vector))); - g->contrib_p = Fmake_specifier (Qboolean); - set_specifier_fallback (g->contrib_p, list1 (Fcons (Qnil, Qt))); - /* #### should have a specifier for the following */ - g->baseline = Fmake_specifier (Qgeneric); - set_specifier_fallback (g->baseline, list1 (Fcons (Qnil, Qnil))); - g->face = Qnil; - g->plist = Qnil; - g->after_change = after_change; - XSETGLYPH (obj, g); - - set_image_attached_to (g->image, obj, Qimage); + /* I think Fmake_specifier can GC. I think set_specifier_fallback can GC. */ + /* We're getting enough reports of odd behavior in this area it seems */ + /* best to GCPRO everything. */ + { + Lisp_Object tem1 = list1 (Fcons (Qnil, Vthe_nothing_vector)); + Lisp_Object tem2 = list1 (Fcons (Qnil, Qt)); + Lisp_Object tem3 = list1 (Fcons (Qnil, Qnil)); + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + + GCPRO4 (obj, tem1, tem2, tem3); + + set_specifier_fallback (g->image, tem1); + g->contrib_p = Fmake_specifier (Qboolean); + set_specifier_fallback (g->contrib_p, tem2); + /* #### should have a specifier for the following */ + g->baseline = Fmake_specifier (Qgeneric); + set_specifier_fallback (g->baseline, tem3); + g->face = Qnil; + g->plist = Qnil; + g->after_change = after_change; + XSETGLYPH (obj, g); + + set_image_attached_to (g->image, obj, Qimage); + UNGCPRO; + } return obj; } @@ -2853,6 +2867,8 @@ void specifier_vars_of_glyphs (void) { + /* #### Can we GC here? The set_specifier_* calls definitely need */ + /* protection. */ /* display tables */ DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /*
--- a/src/keymap.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/keymap.c Mon Aug 13 10:19:09 2007 +0200 @@ -239,7 +239,7 @@ Qbutton6, Qbutton7; Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up, Qbutton4up, Qbutton5up, Qbutton6up, Qbutton7up; -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) Lisp_Object Qdrop0, Qdrop1, Qdrop2, Qdrop3, Qdrop4, Qdrop5, Qdrop6, Qdrop7; #endif Lisp_Object Qmenu_selection; @@ -1432,7 +1432,7 @@ returned_value->modifiers = XEVENT (spec)->event.button.modifiers; break; } -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) case dnd_drop_event: { switch (XEVENT (spec)->event.dnd_drop.button) @@ -1553,7 +1553,7 @@ EQ (raw_key.keysym, Qbutton5) || EQ (raw_key.keysym, Qbutton5up) || EQ (raw_key.keysym, Qbutton6) || EQ (raw_key.keysym, Qbutton6up) || EQ (raw_key.keysym, Qbutton7) || EQ (raw_key.keysym, Qbutton7up) -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) || EQ (raw_key.keysym, Qdrop0) || EQ (raw_key.keysym, Qdrop1) || EQ (raw_key.keysym, Qdrop2) || EQ (raw_key.keysym, Qdrop3) || EQ (raw_key.keysym, Qdrop4) || EQ (raw_key.keysym, Qdrop5) || @@ -4290,7 +4290,7 @@ defsymbol (&Qbutton5up, "button5up"); defsymbol (&Qbutton6up, "button6up"); defsymbol (&Qbutton7up, "button7up"); -#ifdef HAVE_OFFIX_DND +#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS) defsymbol (&Qdrop0, "drop0"); defsymbol (&Qdrop1, "drop1"); defsymbol (&Qdrop2, "drop2");
--- a/src/lread.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/lread.c Mon Aug 13 10:19:09 2007 +0200 @@ -566,10 +566,10 @@ struct gcpro gcpro1, gcpro2, gcpro3; int reading_elc = 0; int message_p = NILP (nomessage); -#ifdef DEBUG_XEMACS +/*#ifdef DEBUG_XEMACS*/ static Lisp_Object last_file_loaded; int pure_usage = 0; -#endif +/*#endif*/ #ifdef DOS_NT int dosmode = O_TEXT; #endif /* DOS_NT */ @@ -578,14 +578,14 @@ CHECK_STRING (file); -#ifdef DEBUG_XEMACS +/*#ifdef DEBUG_XEMACS*/ if (purify_flag && noninteractive) { message_p = 1; last_file_loaded = file; pure_usage = purespace_usage (); } -#endif /* DEBUG_XEMACS */ +/*#endif /* DEBUG_XEMACS */ /* If file name is magic, call the handler. */ handler = Ffind_file_name_handler (file, Qload); @@ -799,7 +799,7 @@ /* #### Disgusting kludge */ /* Run any load-hooks for this file. */ /* #### An even more disgusting kludge. There is horrible code */ - /* this is relying on the fact that dumped lisp files are found */ + /* that is relying on the fact that dumped lisp files are found */ /* via `load-path' search. */ Lisp_Object name = file; @@ -808,7 +808,13 @@ name = Ffile_name_nondirectory(file); } - tem = Fassoc (name, Vafter_load_alist); + { + struct gcpro ngcpro1; + + NGCPRO1 (name); + tem = Fassoc (name, Vafter_load_alist); + NUNGCPRO; + } if (!NILP (tem)) { struct gcpro ngcpro1; @@ -821,7 +827,7 @@ } } -#ifdef DEBUG_XEMACS +/*#ifdef DEBUG_XEMACS*/ if (purify_flag && noninteractive) { if (EQ (last_file_loaded, file)) @@ -830,7 +836,7 @@ message ("Loading %s ...done (%d)", XSTRING_DATA (file), purespace_usage() - pure_usage); } -#endif /* DEBUG_XEMACS */ +/*#endif /* DEBUG_XEMACS */ if (!noninteractive) PRINT_LOADING_MESSAGE ("done");
--- a/src/md5.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/md5.c Mon Aug 13 10:19:09 2007 +0200 @@ -24,13 +24,17 @@ */ /* Synched up with: Not in FSF. */ -/* This file has been Mule-ized. See comment at Fmd5(), though. */ +/* This file has been Mule-ized. */ #include <config.h> #include "lisp.h" #include "buffer.h" #include "insdel.h" +#include "lstream.h" +#ifdef MULE +#include "mule-coding.h" +#endif typedef unsigned char *POINTER;/* POINTER defines a generic pointer type */ typedef unsigned short int UINT2;/* UINT2 defines a two byte word */ @@ -355,24 +359,19 @@ /* XEmacs interface code. */ Lisp_Object Qmd5; -/* #### There could be potential problems here with Mule. I don't - know enough about the uses of MD5 to be able to tell for sure - whether this is a problem. The basic potential problem is that - the hash value will be computed based on the internal representation - of the buffer; this would likely cause problems if the string - contains extended characters, because the extended characters - will get sent over the wire in an external form that is different - from their internal representation, and thus their MD5 hash would - be different. */ - -DEFUN ("md5", Fmd5, 1, 3, 0, /* +DEFUN ("md5", Fmd5, 1, 5, 0, /* Return the MD5 (a secure message digest algorithm) of an object. OBJECT is either a string or a buffer. Optional arguments START and END denote buffer positions for computing the -hash of a portion of OBJECT. +hash of a portion of OBJECT. The optional CODING argument specifies the coding +system the text is to be represented in while computing the digest. This only +has meaning with MULE, and defaults to the current format of the data. +If ERROR-ME-NOT is nil, report an error if the coding system can't be +determined. Else assume binary coding if all else fails. */ - (object, start, end)) + (object, start, end, coding, error_me_not)) { + /* This function can GC */ MD_CTX context; unsigned char digest[16]; unsigned char thehash[32]; @@ -384,31 +383,126 @@ { MDUpdate (&context, (CONST unsigned char *) "", 0); } - else if (BUFFERP (object)) - { - struct buffer *b = decode_buffer (object, 1); - Bufpos begv, endv; - Lisp_Object string; - - /* Figure out where we need to get info from */ - get_buffer_range_char (b, start, end, &begv, &endv, GB_ALLOW_NIL); - - /* Get the string data from the buffer */ - string = make_string_from_buffer (b, begv, endv - begv); - - /* Compute the digest */ - MDUpdate (&context, (unsigned char *) XSTRING_DATA (string), - XSTRING_LENGTH (string)); - } else { - Bytecount len, bstart, bend; - CHECK_STRING (object); - get_string_range_byte (object, start, end, &bstart, &bend, - GB_HISTORICAL_STRING_BEHAVIOR); - len = bend - bstart; - MDUpdate (&context, ((unsigned char *) XSTRING_DATA (object) - + bstart), len); + Lisp_Object instream, outstream; + Lstream *istr, *ostr; + static Extbyte_dynarr *conversion_out_dynarr; + char tempbuf[1024]; /* some random amount */ + struct gcpro gcpro1, gcpro2; +#ifdef MULE + Lisp_Object conv_out_stream, coding_system; + Lstream *costr; + struct gcpro gcpro3; +#endif + + if (!conversion_out_dynarr) + conversion_out_dynarr = Dynarr_new (Extbyte); + else + Dynarr_reset (conversion_out_dynarr); + + /* set up the in stream */ + if (BUFFERP (object)) + { + struct buffer *b = decode_buffer (object, 1); + Bufpos begv, endv; + /* Figure out where we need to get info from */ + get_buffer_range_char (b, start, end, &begv, &endv, GB_ALLOW_NIL); + + instream = make_lisp_buffer_input_stream (b, begv, endv, 0); + } + else + { + Bytecount bstart, bend; + CHECK_STRING (object); + get_string_range_byte (object, start, end, &bstart, &bend, + GB_HISTORICAL_STRING_BEHAVIOR); + instream = make_lisp_string_input_stream (object, bstart, bend); + } + istr = XLSTREAM (instream); + +#ifdef MULE + /* Find out what format the buffer will be saved in, so we can make + the digest based on what it will look like on disk */ + if (NILP(coding)) + { + if (BUFFERP(object)) + { + /* Use the file coding for this buffer by default */ + coding_system = XBUFFER(object)->buffer_file_coding_system; + } + else + { + /* attempt to autodetect the coding of the string. Note: this VERY hit-and-miss */ + enum eol_type eol = EOL_AUTODETECT; + coding_system = Fget_coding_system(Qundecided); + determine_real_coding_system(istr, &coding_system, &eol); + } + if (NILP(coding_system)) + coding_system = Fget_coding_system(Qbinary); + else + { + coding_system = Ffind_coding_system (coding_system); + if (NILP(coding_system)) + coding_system = Fget_coding_system(Qbinary); + } + } + else + { + coding_system = Ffind_coding_system (coding); + if (NILP(coding_system)) + if (NILP(error_me_not)) + signal_simple_error("No such coding system", coding); + else + coding_system = Fget_coding_system(Qbinary); /* default to binary */ + } +#endif + + /* setup the out stream */ + outstream = make_dynarr_output_stream((unsigned_char_dynarr *)conversion_out_dynarr); + ostr = XLSTREAM (outstream); +#ifdef MULE + /* setup the conversion stream */ + conv_out_stream = make_encoding_output_stream (ostr, coding_system); + costr = XLSTREAM (conv_out_stream); + GCPRO3 (instream, outstream, conv_out_stream); +#else + GCPRO2 (instream, outstream); +#endif + + /* Get the data while doing the conversion */ + while (1) { + int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf)); + if (!size_in_bytes) + break; + /* It does seem the flushes are necessary... */ +#ifdef MULE + Lstream_write (costr, tempbuf, size_in_bytes); + Lstream_flush (costr); +#else + Lstream_write (ostr, tempbuf, size_in_bytes); +#endif + Lstream_flush (ostr); + + /* Update the digest */ + + MDUpdate (&context, (unsigned char *)Dynarr_atp(conversion_out_dynarr, 0), + Dynarr_length(conversion_out_dynarr)); + /* reset the dynarr */ + Lstream_rewind(ostr); + } + Lstream_close (istr); +#ifdef MULE + Lstream_close (costr); +#endif + Lstream_close (ostr); + + UNGCPRO; + Lstream_delete (istr); + Lstream_delete (ostr); +#ifdef MULE + Lstream_delete (costr); +#endif } MDFinal (digest, &context);
--- a/src/menubar-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/menubar-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -83,7 +83,6 @@ #include "console-msw.h" #include "emacsfns.h" #include "elhash.h" -#include "event-msw.h" #include "events.h" #include "frame.h" #include "gui.h"
--- a/src/msw-proc.c Mon Aug 13 10:18:22 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,876 +0,0 @@ -/* mswindows specific event-handling. - Copyright (C) 1997 Jonathan Harris. - -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: Not in FSF. */ - -/* Authorship: - - Jonathan Harris, November 1997 for 20.4. - */ - -#include <config.h> -#include "lisp.h" - -#include "console-msw.h" -#include "device.h" -#include "frame.h" -#include "events.h" -#include "event-msw.h" -#include "redisplay.h" - -#ifdef HAVE_SCROLLBARS -# include "scrollbar-msw.h" -#endif - -#ifdef HAVE_MENUBARS -# include "menubar-msw.h" -#endif - -#ifdef DEBUG_XEMACS -# include "opaque.h" /* For the debug functions at the end of this file */ -# undef DEBUG_MESSAGES -# undef DEBUG_TIMEOUTS -#endif - -#ifdef HAVE_MENUBARS -#define ADJR_MENUFLAG TRUE -#else -#define ADJR_MENUFLAG FALSE -#endif - -/* Timer ID used for button2 emulation */ -#define BUTTON_2_TIMER_ID 1 - -static Lisp_Object mswindows_find_frame (HWND hwnd); -static Lisp_Object mswindows_find_console (HWND hwnd); -static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); -static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); -#if 0 /* NOTUSED */ -static int mswindows_enqueue_timeout (int milliseconds); -static void mswindows_dequeue_timeout (int interval_id); - -/* Timeout queue */ -struct mswindows_timeout -{ - int ticks; - int interval_id; - struct mswindows_timeout *next; -}; -typedef struct mswindows_timeout mswindows_timeout; -static mswindows_timeout timeout_pool[MSW_TIMEOUT_MAX]; -static mswindows_timeout *timeout_head = NULL; - -static int timeout_mswindows_id; -#endif - -/*----------------------------------------------------------------------------*/ -/* Enqueue helpers */ -/*----------------------------------------------------------------------------*/ - -void -mswindows_enqueue_magic_event (HWND hwnd, UINT message) -{ - Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT (emacs_event); - - event->channel = mswindows_find_frame (hwnd); - event->timestamp = GetMessageTime(); - event->event_type = magic_event; - EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; - - mswindows_enqueue_dispatch_event (emacs_event); -} - -static void -mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when) -{ - - /* We always use last message time, because mouse button - events may get delayed, and XEmacs double click - recognition will fail */ - - Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT(emacs_event); - - event->channel = mswindows_find_frame(hwnd); - event->timestamp = when; - event->event.button.button = - (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : - ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); - event->event.button.x = where.x; - event->event.button.y = where.y; - event->event.button.modifiers = mswindows_modifier_state (NULL, 0); - - if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || - message==WM_RBUTTONDOWN) - { - event->event_type = button_press_event; - SetCapture (hwnd); - } - else - { - event->event_type = button_release_event; - ReleaseCapture (); - } - - mswindows_enqueue_dispatch_event (emacs_event); -} - -static void -mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) -{ - Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT(emacs_event); - - event->channel = mswindows_find_console(hwnd); - event->timestamp = GetMessageTime(); - event->event_type = key_press_event; - event->event.key.keysym = keysym; - event->event.key.modifiers = mods; - mswindows_enqueue_dispatch_event (emacs_event); -} - -static void -mswindows_set_chord_timer (HWND hwnd) -{ - int interval; - - /* We get half system threshold as it seems to - long before drag-selection is shown */ - if (mswindows_button2_chord_time <= 0) - interval = GetDoubleClickTime () / 2; - else - interval = mswindows_button2_chord_time; - - SetTimer (hwnd, BUTTON_2_TIMER_ID, interval, 0); -} - -static int -mswindows_button2_near_enough (POINTS p1, POINTS p2) -{ - int dx, dy; - if (mswindows_button2_max_skew_x <= 0) - dx = GetSystemMetrics (SM_CXDOUBLECLK) / 2; - else - dx = mswindows_button2_max_skew_x; - - if (mswindows_button2_max_skew_y <= 0) - dy = GetSystemMetrics (SM_CYDOUBLECLK) / 2; - else - dy = mswindows_button2_max_skew_y; - - return abs (p1.x - p2.x) < dx && abs (p1.y- p2.y)< dy; -} - -static int -mswindows_current_layout_has_AltGr () -{ - /* This simple caching mechanism saves 10% of CPU - time when a key typed at autorepeat rate of 30 cps! */ - static HKL last_hkl = 0; - static int last_hkl_has_AltGr; - - HKL current_hkl = GetKeyboardLayout (0); - if (current_hkl != last_hkl) - { - TCHAR c; - last_hkl_has_AltGr = 0; - /* In this loop, we query whether a character requires - AltGr to be down to generate it. If at least such one - found, this means that the layout does regard AltGr */ - for (c = ' '; c <= 0xFFU && c != 0 && !last_hkl_has_AltGr; ++c) - if (HIBYTE (VkKeyScan (c)) == 6) - last_hkl_has_AltGr = 1; - last_hkl = current_hkl; - } - return last_hkl_has_AltGr; -} - -/* - * The windows procedure for the window class XEMACS_CLASS - * Stuffs messages in the mswindows event queue - */ -LRESULT WINAPI -mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - /* Note: Remember to initialise these before use */ - Lisp_Object emacs_event; - struct Lisp_Event *event; - Lisp_Object fobj; - struct frame *frame; - struct mswindows_frame* msframe; - - switch (message) - { - case WM_ERASEBKGND: - /* Erase background only during non-dynamic sizing */ - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - if (msframe->sizing && !mswindows_dynamic_frame_resize) - goto defproc; - return 1; - - case WM_CLOSE: - fobj = mswindows_find_frame (hwnd); - enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt)); - mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - BYTE keymap[256]; - int has_AltGr = mswindows_current_layout_has_AltGr (); - int mods; - Lisp_Object keysym; - - GetKeyboardState (keymap); - mods = mswindows_modifier_state (keymap, has_AltGr); - - /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */ - if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) - mswindows_enqueue_keypress_event (hwnd, keysym, mods); - else - { - int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); - BYTE keymap_orig[256]; - MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) }; - memcpy (keymap_orig, keymap, 256); - - /* Clear control and alt modifiers out of the keymap */ - keymap [VK_RCONTROL] = 0; - keymap [VK_LMENU] = 0; - if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) - { - keymap [VK_LCONTROL] = 0; - keymap [VK_CONTROL] = 0; - keymap [VK_RMENU] = 0; - keymap [VK_MENU] = 0; - } - SetKeyboardState (keymap); - - /* Have some WM_[SYS]CHARS in the queue */ - TranslateMessage (&msg); - - while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE) - ||PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) - { - int ch = msg.wParam; - /* CH is a character code for the key: - 'C' for Shift+C and Ctrl+Shift+C - 'c' for c and Ctrl+c */ - - /* #### If locale is not C, US or other latin-1, - isalpha() maybe not what do we mean */ - - /* XEmacs doesn't seem to like Shift on non-alpha keys */ - if (!isalpha(ch)) - mods &= ~MOD_SHIFT; - - /* Un-capitalise alpha control keys */ - if ((mods & MOD_CONTROL) && isalpha(ch)) - ch |= ('A' ^ 'a'); - - /* If a quit char with no modifiers other than control and - shift, then mark it with a fake modifier, which is removed - upon dequeueing the event */ - /* #### This might also not withstand localization, if - quit character is not a latin-1 symbol */ - if (((quit_ch < ' ' && (mods & MOD_CONTROL) && quit_ch + 'a' - 1 == ch) - || (quit_ch >= ' ' && !(mods & MOD_CONTROL) && quit_ch == ch)) - && ((mods & ~(MOD_CONTROL | MOD_SHIFT)) == 0)) - { - mods |= FAKE_MOD_QUIT; - ++mswindows_quit_chars_count; - } - - mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods); - } /* while */ - SetKeyboardState (keymap_orig); - } /* else */ - } - goto defproc; - - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - /* Real middle mouse button has nothing to do with emulated one: - if one wants to exercise fingers playing chords on the mouse, - he is allowed to do that! */ - mswindows_enqueue_mouse_button_event (hwnd, message, - MAKEPOINTS (lParam), GetMessageTime()); - break; - - case WM_LBUTTONUP: - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - msframe->last_click_time = GetMessageTime(); - - KillTimer (hwnd, BUTTON_2_TIMER_ID); - msframe->button2_need_lbutton = 0; - if (msframe->ignore_next_lbutton_up) - { - msframe->ignore_next_lbutton_up = 0; - } - else if (msframe->button2_is_down) - { - msframe->button2_is_down = 0; - msframe->ignore_next_rbutton_up = 1; - mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP, - MAKEPOINTS (lParam), GetMessageTime()); - } - else - { - if (msframe->button2_need_rbutton) - { - msframe->button2_need_rbutton = 0; - mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, - MAKEPOINTS (lParam), GetMessageTime()); - } - mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP, - MAKEPOINTS (lParam), GetMessageTime()); - } - break; - - case WM_RBUTTONUP: - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - msframe->last_click_time = GetMessageTime(); - - KillTimer (hwnd, BUTTON_2_TIMER_ID); - msframe->button2_need_rbutton = 0; - if (msframe->ignore_next_rbutton_up) - { - msframe->ignore_next_rbutton_up = 0; - } - else if (msframe->button2_is_down) - { - msframe->button2_is_down = 0; - msframe->ignore_next_lbutton_up = 1; - mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP, - MAKEPOINTS (lParam), GetMessageTime()); - } - else - { - if (msframe->button2_need_lbutton) - { - msframe->button2_need_lbutton = 0; - mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, - MAKEPOINTS (lParam), GetMessageTime()); - } - mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP, - MAKEPOINTS (lParam), GetMessageTime()); - } - break; - - case WM_LBUTTONDOWN: - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - - if (msframe->button2_need_lbutton) - { - KillTimer (hwnd, BUTTON_2_TIMER_ID); - msframe->button2_need_lbutton = 0; - msframe->button2_need_rbutton = 0; - if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam))) - { - mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN, - MAKEPOINTS (lParam), GetMessageTime()); - msframe->button2_is_down = 1; - } - else - { - mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, - msframe->last_click_point, msframe->last_click_time); - mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, - MAKEPOINTS (lParam), GetMessageTime()); - } - } - else - { - mswindows_set_chord_timer (hwnd); - msframe->button2_need_rbutton = 1; - msframe->last_click_point = MAKEPOINTS (lParam); - } - msframe->last_click_time = GetMessageTime(); - break; - - case WM_RBUTTONDOWN: - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - - if (msframe->button2_need_rbutton) - { - KillTimer (hwnd, BUTTON_2_TIMER_ID); - msframe->button2_need_lbutton = 0; - msframe->button2_need_rbutton = 0; - if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam))) - { - mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN, - MAKEPOINTS (lParam), GetMessageTime()); - msframe->button2_is_down = 1; - } - else - { - mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, - msframe->last_click_point, msframe->last_click_time); - mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, - MAKEPOINTS (lParam), GetMessageTime()); - } - } - else - { - mswindows_set_chord_timer (hwnd); - msframe->button2_need_lbutton = 1; - msframe->last_click_point = MAKEPOINTS (lParam); - } - msframe->last_click_time = GetMessageTime(); - break; - - case WM_TIMER: - if (wParam == BUTTON_2_TIMER_ID) - { - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - KillTimer (hwnd, BUTTON_2_TIMER_ID); - - if (msframe->button2_need_lbutton) - { - msframe->button2_need_lbutton = 0; - mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, - msframe->last_click_point, msframe->last_click_time); - } - else if (msframe->button2_need_rbutton) - { - msframe->button2_need_rbutton = 0; - mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, - msframe->last_click_point, msframe->last_click_time); - } - } - else - assert ("Spurious timer fired" == 0); - break; - - case WM_MOUSEMOVE: - /* Optimization: don't report mouse movement while size is changind */ - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - if (!msframe->sizing) - { - /* When waiting for the second mouse button to finish - button2 emulation, and have moved too far, just pretend - as if timer has expired. This impoves drag-select feedback */ - if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton) - && !mswindows_button2_near_enough (msframe->last_click_point, - MAKEPOINTS (lParam))) - { - KillTimer (hwnd, BUTTON_2_TIMER_ID); - SendMessage (hwnd, WM_TIMER, BUTTON_2_TIMER_ID, 0); - } - - emacs_event = Fmake_event (Qnil, Qnil); - event = XEVENT(emacs_event); - - event->channel = mswindows_find_frame(hwnd); - event->timestamp = GetMessageTime(); - event->event_type = pointer_motion_event; - event->event.motion.x = MAKEPOINTS(lParam).x; - event->event.motion.y = MAKEPOINTS(lParam).y; - event->event.motion.modifiers = mswindows_modifier_state (NULL, 0); - - mswindows_enqueue_dispatch_event (emacs_event); - } - break; - - case WM_PAINT: - { - PAINTSTRUCT paintStruct; - - frame = XFRAME (mswindows_find_frame (hwnd)); - - BeginPaint (hwnd, &paintStruct); - mswindows_redraw_exposed_area (frame, - paintStruct.rcPaint.left, paintStruct.rcPaint.top, - paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); - EndPaint (hwnd, &paintStruct); - } - break; - - case WM_SIZE: - /* We only care about this message if our size has really changed */ - if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED) - { - RECT rect; - int columns, rows; - - fobj = mswindows_find_frame (hwnd); - frame = XFRAME (fobj); - msframe = FRAME_MSWINDOWS_DATA (frame); - - /* We cannot handle frame map and unmap hooks right in - this routine, because these may throw. We queue - magic events to run these hooks instead - kkm */ - - if (wParam==SIZE_MINIMIZED) - { - /* Iconified */ - FRAME_VISIBLE_P (frame) = 0; - mswindows_enqueue_magic_event (hwnd, XM_UNMAPFRAME); - Fframe_iconified_p (fobj); - } - else - { - int was_visible = FRAME_VISIBLE_P (frame); - if (!msframe->sizing && !was_visible) - mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME); - - GetClientRect(hwnd, &rect); - FRAME_VISIBLE_P(frame) = 1; - FRAME_PIXWIDTH(frame) = rect.right; - FRAME_PIXHEIGHT(frame) = rect.bottom; - pixel_to_char_size (frame, rect.right, rect.bottom, &columns, &rows); - change_frame_size (frame, rows, columns, 1); - - if (msframe->sizing && mswindows_dynamic_frame_resize) - redisplay (); - } - } - break; - - /* Misc magic events which only require that the frame be identified */ - case WM_SETFOCUS: - case WM_KILLFOCUS: - mswindows_enqueue_magic_event (hwnd, message); - break; - - case WM_WINDOWPOSCHANGING: - { - WINDOWPOS *wp = (LPWINDOWPOS) lParam; - WINDOWPLACEMENT wpl = { sizeof(WINDOWPLACEMENT) }; - GetWindowPlacement(hwnd, &wpl); - - /* Only interested if size is changing and we're not being iconified */ - if ((wpl.showCmd != SW_SHOWMINIMIZED) && !(wp->flags & SWP_NOSIZE)) - { - RECT ncsize = { 0, 0, 0, 0 }; - int pixwidth, pixheight; - AdjustWindowRectEx (&ncsize, GetWindowLong (hwnd, GWL_STYLE), - GetMenu(hwnd) != NULL, - GetWindowLong (hwnd, GWL_EXSTYLE)); - - round_size_to_char (XFRAME (mswindows_find_frame (hwnd)), - wp->cx - (ncsize.right - ncsize.left), - wp->cy - (ncsize.bottom - ncsize.top), - &pixwidth, &pixheight); - - /* Convert client sizes to window sizes */ - pixwidth += (ncsize.right - ncsize.left); - pixheight += (ncsize.bottom - ncsize.top); - - if (wpl.showCmd != SW_SHOWMAXIMIZED) - { - /* Adjust so that the bottom or right doesn't move if it's - * the top or left that's being changed */ - RECT rect; - GetWindowRect (hwnd, &rect); - - if (rect.left != wp->x) - wp->x += wp->cx - pixwidth; - if (rect.top != wp->y) - wp->y += wp->cy - pixheight; - } - - wp->cx = pixwidth; - wp->cy = pixheight; - } - } - break; - - case WM_ENTERSIZEMOVE: - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - msframe->sizing = 1; - return 0; - - case WM_EXITSIZEMOVE: - msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); - msframe->sizing = 0; - /* Queue noop event */ - mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE); - return 0; - -#ifdef HAVE_SCROLLBARS - case WM_VSCROLL: - case WM_HSCROLL: - { - /* Direction of scroll is determined by scrollbar instance. */ - int code = (int) LOWORD(wParam); - int pos = (short int) HIWORD(wParam); - HWND hwndScrollBar = (HWND) lParam; - mswindows_handle_scrollbar_event (hwndScrollBar, code, pos); - - if (UNBOUNDP(mswindows_pump_outstanding_events())) - { - /* Error during event pumping - cancel scroll */ - SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); - } - - break; - } -#endif - -#ifdef HAVE_MENUBARS - case WM_INITMENU: - if (UNBOUNDP (mswindows_handle_wm_initmenu ( - (HMENU) wParam, - XFRAME (mswindows_find_frame (hwnd))))) - SendMessage (hwnd, WM_CANCELMODE, 0, 0); - break; - - case WM_INITMENUPOPUP: - if (!HIWORD(lParam)) - { - if (UNBOUNDP (mswindows_handle_wm_initmenupopup ( - (HMENU) wParam, - XFRAME (mswindows_find_frame (hwnd))))) - SendMessage (hwnd, WM_CANCELMODE, 0, 0); - } - break; - - case WM_EXITMENULOOP: - if (UNBOUNDP (mswindows_handle_wm_exitmenuloop ( - XFRAME (mswindows_find_frame (hwnd))))) - SendMessage (hwnd, WM_CANCELMODE, 0, 0); - break; - -#endif /* HAVE_MENUBARS */ - - case WM_COMMAND: - { - WORD id = LOWORD (wParam); - frame = XFRAME (mswindows_find_frame (hwnd)); - -#ifdef HAVE_MENUBARS - if (!NILP (mswindows_handle_wm_command (frame, id))) - break; -#endif - -#ifdef HAVE_TOOLBARS - O Toolbar Implementor, this place may have something for you!; -#endif - - /* Bite me - a spurious command. No abort(), for safety */ - /* #### Perhaps, this message should be changed */ - error ("Cannot decode command. Tell kkm he's a parallelogramm, if you know" - " what does that mean!"); - } - break; - - defproc: - default: - return DefWindowProc (hwnd, message, wParam, lParam); - } - return (0); -} - -/* Returns the state of the modifier keys in the format expected by the - * Lisp_Event key_data, button_data and motion_data modifiers member */ -int mswindows_modifier_state (BYTE* keymap, int has_AltGr) -{ - int mods = 0; - - if (keymap == NULL) - { - keymap = (BYTE*) alloca(256); - GetKeyboardState (keymap); - has_AltGr = mswindows_current_layout_has_AltGr (); - } - - if (has_AltGr && (keymap [VK_LCONTROL] & 0x80) && (keymap [VK_RMENU] & 0x80)) - { - mods |= (keymap [VK_LMENU] & 0x80) ? MOD_META : 0; - mods |= (keymap [VK_RCONTROL] & 0x80) ? MOD_CONTROL : 0; - } - else - { - mods |= (keymap [VK_MENU] & 0x80) ? MOD_META : 0; - mods |= (keymap [VK_CONTROL] & 0x80) ? MOD_CONTROL : 0; - } - - mods |= (keymap [VK_SHIFT] & 0x80) ? MOD_SHIFT : 0; - - return mods; -} - -/* - * Translate a mswindows virtual key to a keysym. - * Only returns non-Qnil for keys that don't generate WM_CHAR messages - * or whose ASCII codes (like space) xemacs doesn't like. - * Virtual key values are defined in winresrc.h - * XXX I'm not sure that KEYSYM("name") is the best thing to use here. - */ -Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods) -{ - switch (mswindows_key) - { - /* First the predefined ones */ - case VK_BACK: return QKbackspace; - case VK_TAB: return QKtab; - case '\n': return QKlinefeed; /* No VK_LINEFEED in winresrc.h */ - case VK_RETURN: return QKreturn; - case VK_ESCAPE: return QKescape; - case VK_SPACE: return QKspace; - case VK_DELETE: return QKdelete; - - /* The rest */ - case VK_CLEAR: return KEYSYM ("clear"); /* Should do ^L ? */ - case VK_PRIOR: return KEYSYM ("prior"); - case VK_NEXT: return KEYSYM ("next"); - case VK_END: return KEYSYM ("end"); - case VK_HOME: return KEYSYM ("home"); - case VK_LEFT: return KEYSYM ("left"); - case VK_UP: return KEYSYM ("up"); - case VK_RIGHT: return KEYSYM ("right"); - case VK_DOWN: return KEYSYM ("down"); - case VK_SELECT: return KEYSYM ("select"); - case VK_PRINT: return KEYSYM ("print"); - case VK_EXECUTE: return KEYSYM ("execute"); - case VK_SNAPSHOT: return KEYSYM ("print"); - case VK_INSERT: return KEYSYM ("insert"); - case VK_HELP: return KEYSYM ("help"); -#if 0 /* XXX What are these supposed to do? */ - case VK_LWIN return KEYSYM (""); - case VK_RWIN return KEYSYM (""); -#endif - case VK_APPS: return KEYSYM ("menu"); - case VK_F1: return KEYSYM ("f1"); - case VK_F2: return KEYSYM ("f2"); - case VK_F3: return KEYSYM ("f3"); - case VK_F4: return KEYSYM ("f4"); - case VK_F5: return KEYSYM ("f5"); - case VK_F6: return KEYSYM ("f6"); - case VK_F7: return KEYSYM ("f7"); - case VK_F8: return KEYSYM ("f8"); - case VK_F9: return KEYSYM ("f9"); - case VK_F10: return KEYSYM ("f10"); - case VK_F11: return KEYSYM ("f11"); - case VK_F12: return KEYSYM ("f12"); - case VK_F13: return KEYSYM ("f13"); - case VK_F14: return KEYSYM ("f14"); - case VK_F15: return KEYSYM ("f15"); - case VK_F16: return KEYSYM ("f16"); - case VK_F17: return KEYSYM ("f17"); - case VK_F18: return KEYSYM ("f18"); - case VK_F19: return KEYSYM ("f19"); - case VK_F20: return KEYSYM ("f20"); - case VK_F21: return KEYSYM ("f21"); - case VK_F22: return KEYSYM ("f22"); - case VK_F23: return KEYSYM ("f23"); - case VK_F24: return KEYSYM ("f24"); - } - return Qnil; -} - -/* - * Find the console that matches the supplied mswindows window handle - */ -Lisp_Object -mswindows_find_console (HWND hwnd) -{ - Lisp_Object concons; - - CONSOLE_LOOP (concons) - { - Lisp_Object console = XCAR (concons); - /* We only support one console so this must be it */ - return console; - } - - return Qnil; -} - -/* - * Find the frame that matches the supplied mswindows window handle - */ -static Lisp_Object -mswindows_find_frame (HWND hwnd) -{ - return (Lisp_Object) GetWindowLong (hwnd, XWL_FRAMEOBJ); -} - - -#ifdef DEBUG_XEMACS -/* - * Random helper functions for debugging. - * Intended for use in the MSVC "Watch" window which doesn't like - * the aborts that the error_check_foo() functions can make. - */ -struct lrecord_header *DHEADER(Lisp_Object obj) -{ - return (LRECORDP (obj)) ? XRECORD_LHEADER (obj) : NULL; -} - -int *DOPAQUE_DATA (Lisp_Object obj) -{ - return (OPAQUEP (obj)) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL; -} - -struct Lisp_Event *DEVENT(Lisp_Object obj) -{ - return (EVENTP (obj)) ? XEVENT (obj) : NULL; -} - -struct Lisp_Cons *DCONS(Lisp_Object obj) -{ - return (CONSP (obj)) ? XCONS (obj) : NULL; -} - -Lisp_Object DCAR(Lisp_Object obj) -{ - return (CONSP (obj)) ? XCAR (obj) : 0; -} - -Lisp_Object DCDR(Lisp_Object obj) -{ - return (CONSP (obj)) ? XCDR (obj) : 0; -} - -struct Lisp_Cons *DCONSCDR(Lisp_Object obj) -{ - return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCONS (XCDR (obj)) : 0; -} - -Lisp_Object DCARCDR(Lisp_Object obj) -{ - return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCAR (XCDR (obj)) : 0; -} - -char *DSTRING(Lisp_Object obj) -{ - return (STRINGP (obj)) ? XSTRING_DATA (obj) : NULL; -} - -struct Lisp_Vector *DVECTOR(Lisp_Object obj) -{ - return (VECTORP (obj)) ? XVECTOR (obj) : NULL; -} - -struct Lisp_Symbol *DSYMBOL(Lisp_Object obj) -{ - return (SYMBOLP (obj)) ? XSYMBOL (obj) : NULL; -} - -char *DSYMNAME(Lisp_Object obj) -{ - return (SYMBOLP (obj)) ? XSYMBOL (obj)->name->_data : NULL; -} - -#endif
--- a/src/mule-ccl.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/mule-ccl.c Mon Aug 13 10:19:09 2007 +0200 @@ -530,10 +530,11 @@ { int *reg = ccl->reg; int ic = ccl->ic; - int code, field1, field2; + int code = -1; /* init to illegal value, */ + int field1, field2; Lisp_Object *ccl_prog = ccl->prog; unsigned char *src = source, *src_end = src + src_bytes; - int jump_address; + int jump_address = 0; /* shut up the compiler */ int i, j, op; int stack_idx = 0; /* For the moment, we only support depth 256 of stack. */
--- a/src/mule-coding.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/mule-coding.c Mon Aug 13 10:19:09 2007 +0200 @@ -1452,7 +1452,7 @@ This function does not automatically fetch subsidiary coding systems; that should be unnecessary with the explicit eol-type argument. */ -static void +void determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out, enum eol_type *eol_type_in_out) {
--- a/src/mule-coding.h Mon Aug 13 10:18:22 2007 +0200 +++ b/src/mule-coding.h Mon Aug 13 10:19:09 2007 +0200 @@ -451,4 +451,6 @@ Lisp_Object codesys); extern void set_encoding_stream_coding_system (Lstream *stream, Lisp_Object codesys); +extern void determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out, + enum eol_type *eol_type_in_out); #endif /* _XEMACS_MULE_CODING_H_ */
--- a/src/objects-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/objects-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -1050,10 +1050,10 @@ GetTextMetrics(hdc, &metrics); SelectObject(hdc, holdfont); ReleaseDC(hwnd, hdc); - f->width = metrics.tmAveCharWidth; - f->height = metrics.tmHeight; - f->ascent = metrics.tmAscent; - f->descent = metrics.tmDescent; + f->width = (unsigned short) metrics.tmAveCharWidth; + f->height = (unsigned short) metrics.tmHeight; + f->ascent = (unsigned short) metrics.tmAscent; + f->descent = (unsigned short) metrics.tmDescent; f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); }
--- a/src/redisplay-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/redisplay-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -538,7 +538,7 @@ if (IntersectRect (&rect_paint, &rect_dead, prc)) FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint, - (HBRUSH)GetClassLong (FRAME_MSWINDOWS_HANDLE(f), GCL_HBRBACKGROUND)); + (HBRUSH) (COLOR_BTNFACE+1)); } #endif /* HAVE_SCROLLBARS */
--- a/src/redisplay.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/redisplay.c Mon Aug 13 10:19:09 2007 +0200 @@ -5250,6 +5250,13 @@ update_line_start_cache (w, start, end, pointm, 1); redisplay_output_window (w); + /* + * If we just displayed the echo area, the line start cache is + * no longer valid, because the minibuffer window is assocaited + * with the window now. + */ + if (echo_active) + w->line_cache_last_updated = make_int (-1); } /* #### This should be dependent on face changes and will need to be
--- a/src/s/sunos4-0.h Mon Aug 13 10:18:22 2007 +0200 +++ b/src/s/sunos4-0.h Mon Aug 13 10:19:09 2007 +0200 @@ -54,7 +54,25 @@ */ /* Since lcc is not going to be heavily used anymore if it ever was, I'm putting broken-sun.h back in. */ +/* Since Gcc 2.8 appears to have fixed the problem, I'm conditionalizing */ +/* this ugly hack. */ + +#if defined (__GNUC__) +#if defined (__GNUC_MINOR__) +#if ((__GNUC__ == 2) && (__GNUC_MINOR__ > 7)) || ((__GNUC__ > 2)) +/* Don't include for gcc 2.8.0*/ +#else #include "../broken-sun.h" +#endif + +#else /* __GNUC_MINOR__ is undefined */ +#include "../broken-sun.h" +#endif + +#else +/* Not GNU C */ +#endif + extern char *strdup (); extern char *ttyname (int); extern void tzsetwall (void);
--- a/src/scrollbar-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/scrollbar-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -27,11 +27,11 @@ #include "lisp.h" #include "console-msw.h" +#include "scrollbar-msw.h" + #include "frame.h" #include "window.h" -#include "scrollbar-msw.h" #include "events.h" -#include "event-msw.h" /* This has really different semantics in Windows than in Motif. There's no corresponding method; we just do not change slider
--- a/src/select-msw.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/select-msw.c Mon Aug 13 10:19:09 2007 +0200 @@ -84,7 +84,7 @@ GlobalUnlock (h); - i = SetClipboardData (CF_TEXT, h); + i = (SetClipboardData (CF_TEXT, h) != NULL); CloseClipboard (); GlobalFree (h);
--- a/src/toolbar.c Mon Aug 13 10:18:22 2007 +0200 +++ b/src/toolbar.c Mon Aug 13 10:19:09 2007 +0200 @@ -269,6 +269,7 @@ /* The following calls will automatically cause the dirty flags to be set; we delay frame size changes to avoid lots of frame flickering. */ + /* #### I think this should be GC protected. -sb */ hold_frame_size_changes (); set_specifier_fallback (Vtoolbar[cur], list1 (Fcons (Qnil, Qnil))); set_specifier_fallback (Vtoolbar[new], Vdefault_toolbar);
--- a/src/unexcw.cc Mon Aug 13 10:18:22 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,606 +0,0 @@ -/* unexec for GNU Emacs on Cygwin32. - Copyright (C) 1994, 1998 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. - -*/ - -/* Adapted from unexnt.c Andy Piper (andyp@parallax.co.uk) 13-1-98 */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <config.h> -#include <string.h> - -#define PERROR(arg) perror(arg);exit(-1) - -#ifndef HAVE_COFF_H -extern "C" void -unexec (char *, char *, void *, void *, void *) -{ - PERROR("cannot unexec() coff.h not installed"); -} - -extern "C" void run_time_remap (char *) -{} -#else - -#include <windows.h> -/* - * unfortunately we need this c++ to get at the internals of cygwin - */ -class pinfo; -class per_process -{ - public: - char *initial_sp; - - /* The offset of these 3 values can never change. */ - /* magic_biscuit is the size of this class and should never change. */ - int magic_biscuit; - int version_major; - int version_minor; - - struct _reent **impure_ptr_ptr; - char ***envptr; - - /* Used to point to the memory machine we should use - - usually points back into the dll, but can be overridden by the user. */ - void *(*malloc)(size_t); - void (*free)(void *); - void *(*realloc)(void *, size_t); - - int *fmode_ptr; - - int (*main)(int, char **, char **); - void (**ctors)(); - void (**dtors)(); - - /* For fork */ - void *data_start; - void *data_end; - void *bss_start; - void *bss_end; - - /* For future expansion of values set by the app. */ - void *public_reserved[4]; - - /* The rest are *internal* to cygwin.dll. - Those that are here because we want the child to inherit the value from - the parent (which happens when bss is copied) are marked as such. */ - - /* FIXME: Which of these can go elsewhere? */ - - /* FIXME: Delete, make `self' a global. */ - pinfo *self; /* pointer only valid in self process */ - - /* non-zero of ctors have been run. Inherited from parent. */ - int run_ctors_p; - - /* These will be non-zero if the above (malloc,free,realloc) have been - overridden. */ - /* FIXME: not currently used */ - int __imp_malloc; - int __imp_free; - int __imp_realloc; - - /* Heap management. Inherited from parent. */ - void *base; /* bottom of the heap */ - void *ptr; /* current index into heap */ - int size; /* current size of heap */ - - /* Mask of what to trace. Inherited from parent. - See sys/strace.h for details. The value of this is changeable from other - tasks via the `cygwin' utility so we want this in the shared data area - (and thus the process table since there's one of these per task). - However, we also want to turn on stracing as soon as possible and - therefore before we know which process table entry to use. So we put it - here, and have a pointer to it in the process table. */ - int strace_mask; - - /* Non-zero means the task was forked. The value is the pid. - Inherited from parent. */ - int forkee; - - void *hmodule; - - void* /*HANDLE*/ signal_arrived; - /* For future expansion, so apps won't have to be relinked if we - add an item. */ - void *internal_reserved[9]; - - /* struct file_queue *dq; !!! this may need to be nuked ? */ -}; - -extern per_process cygwin_statu; /* pointer into the application's static data */ - -#include <coff.h> - -#define ALLOC_UNIT 0xFFFF -#define ALLOC_MASK ~((unsigned long)(ALLOC_UNIT)) -#define ALIGN_ALLOC(addr) \ -((((unsigned long)addr) + ALLOC_UNIT) & ALLOC_MASK) -#define SIZEOF_PER_PROCESS (42 * 4) - -/* - * Heap related stuff. - */ -#define get_reserved_heap_size() (*heap_size) -#define get_committed_heap_size() \ -(int)((unsigned char*)(*heap_index)-(unsigned char*)(*heap_base)) -#define get_heap_start() (*heap_base) -#define get_heap_end() (*heap_index) - -extern "C" { -void** heap_base = &cygwin_statu.base; -void** heap_index = &cygwin_statu.ptr; -int* heap_size = &cygwin_statu.size; -int* heap_flag = &cygwin_statu.forkee; -void* per_process_data = &cygwin_statu; -/* To prevent zero-initialized variables from being placed into the bss - section, use non-zero values to represent an uninitialized state. */ -#define UNINIT_PTR ((void *) 0xF0A0F0A0) -#define UNINIT_LONG (0xF0A0F0A0L) - -void* local_heap_base=UNINIT_PTR; -void* local_heap_index=UNINIT_PTR; -unsigned long local_heap_size=UNINIT_LONG; - -/* Recreate the heap created during dumping. */ - -enum { - HEAP_UNINITIALIZED = 1, - HEAP_UNLOADED, - HEAP_LOADED -}; - -/* Basically, our "initialized" flag. */ -int heap_state = HEAP_UNINITIALIZED; - -/* So we can find our heap in the file to recreate it. */ -unsigned long heap_index_in_executable = UNINIT_LONG; - -static void get_section_info (int a_out, char* a_name); -static void copy_executable_and_dump_data_section (int a_out, int a_new); -static void dump_heap (int a_out, int a_new); -static void dup_file_area(int a_out, int a_new, long size); - -/* Cached info about the .data section in the executable. */ -void* data_start_va = UNINIT_PTR; -unsigned long data_size = UNINIT_LONG; - -/* Cached info about the .bss section in the executable. */ -void* bss_start = UNINIT_PTR; -unsigned long bss_size = UNINIT_LONG; -FILHDR f_hdr; -PEAOUTHDR f_ohdr; -SCNHDR f_data, f_bss, f_text, f_idata; -} -#define PERROR(arg) perror(arg);exit(-1) -#define CHECK_AOUT_POS(a) \ -if (lseek(a_out, 0, SEEK_CUR) != a) \ -{ \ - printf("we are at %lx, should be at %lx\n", \ - lseek(a_out, 0, SEEK_CUR), a); \ - exit(-1); \ -} - -/* Dump out .data and .bss sections into a new executable. */ -extern "C" void -unexec (char *out_name, char *in_name, void *start_data, void *, void *) -{ - /* ugly nt hack - should be in lisp */ - char new_name[MAX_PATH], a_name[MAX_PATH]; - char *ptr; - - /* Make sure that the input and output filenames have the - ".exe" extension...patch them up if they don't. */ - strcpy (a_name, in_name); - ptr = a_name + strlen (a_name) - 4; - if (strcmp (ptr, ".exe")) - strcat (a_name, ".exe"); - - strcpy (new_name, out_name); - ptr = new_name + strlen (new_name) - 4; - if (strcmp (ptr, ".exe")) - strcat (new_name, ".exe"); - /* save heap info in our data segment so that we can recreate after - dumping */ - - local_heap_base = *heap_base; - local_heap_size = *heap_size; - local_heap_index = *heap_index; - - /* We need to round off our heap to NT's allocation unit (64KB). */ - /* round_heap (get_allocation_unit ()); */ - - int a_new, a_out = -1; - - if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) - { - PERROR (a_name); - } - if ((a_new = creat (new_name, 0666)) < 0) - { - PERROR (new_name); - } - - /* Get the interesting section info, like start and size of .bss... */ - get_section_info (a_out, a_name); - - /* Set the flag (before dumping). */ - heap_state = HEAP_UNLOADED; - - copy_executable_and_dump_data_section (a_out, a_new); - dump_heap (a_out, a_new); - - close(a_out); - close(a_new); -} - -/* Flip through the executable and cache the info necessary for dumping. */ -static void get_section_info (int a_out, char* a_name) -{ - if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) - { - PERROR (a_name); - } - - if (f_hdr.e_magic != DOSMAGIC) - { - PERROR("unknown exe header"); - } - - /* Check the NT header signature ... */ - if (f_hdr.nt_signature != NT_SIGNATURE) - { - PERROR("invalid nt header"); - } - - /* Flip through the sections for .data and .bss ... */ - if (f_hdr.f_opthdr > 0) - { - if (read (a_out, &f_ohdr, AOUTSZ) != AOUTSZ) - { - PERROR (a_name); - } - } - /* Loop through .data & .bss section headers, copying them in */ - lseek (a_out, sizeof (f_hdr) + f_hdr.f_opthdr, 0); - - if (read (a_out, &f_text, sizeof (f_text)) != sizeof (f_text) - && - strcmp (f_text.s_name, ".text")) - { - PERROR ("no .text section"); - } - - /* The .bss section. */ - if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss) - && - strcmp (f_bss.s_name, ".bss")) - { - PERROR ("no .bss section"); - } - extern int my_ebss; - bss_start = (void *) ((char*)f_ohdr.ImageBase + f_bss.s_vaddr); - bss_size = (unsigned long)((char*)&my_ebss-(char*)bss_start); - - /* must keep bss data that we want to be blank as blank */ - printf("found bss - keeping %lx of %lx bytes\n", bss_size, f_ohdr.bsize); - - /* The .data section. */ - if (read (a_out, &f_data, sizeof (f_data)) != sizeof (f_data) - && - strcmp (f_data.s_name, ".data")) - { - PERROR ("no .data section"); - } - - /* From lastfile.c */ - extern char my_edata[]; - - /* The .data section. */ - data_start_va = (void *) ((char*)f_ohdr.ImageBase + f_data.s_vaddr); - - /* We want to only write Emacs data back to the executable, - not any of the library data (if library data is included, - then a dumped Emacs won't run on system versions other - than the one Emacs was dumped on). */ - data_size = my_edata - data_start_va; - - /* The .idata section. */ - if (read (a_out, &f_idata, sizeof (f_idata)) != sizeof (f_idata) - && - strcmp (f_idata.s_name, ".idata")) - { - PERROR ("no .idata section"); - } -} - -/* The dump routines. */ - -static void -copy_executable_and_dump_data_section (int a_out, int a_new) -{ - long size=0; - unsigned long new_data_size, new_bss_size, f_data_s_vaddr, - file_sz_change, f_data_s_scnptr, bss_padding; - int i; - SCNHDR section; - /* calculate new sizes f_ohdr.dsize is the total initalized data - size on disk which is f_data.s_size + f_idata.s_size. - f_ohdr.data_start is the base addres of all data and so should - not be changed. *.s_vaddr is the virtual address of the start - of the section normalzed from f_ohdr.ImageBase. *.s_paddr - appears to be the number of bytes in the section actually used - (whereas *.s_size is aligned). - - bsize is now 0 since subsumed into .data - dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr) - f_data.s_vaddr is f_bss.s_vaddr - f_data.s_size is new dsize maybe. - what about s_paddr & s_scnptr? */ - /* this is the amount the file increases in size */ - *heap_flag=1; // kludge to get mem to remap - new_bss_size=f_data.s_vaddr - f_bss.s_vaddr; - file_sz_change=new_bss_size; - new_data_size=f_ohdr.dsize + new_bss_size; - f_data_s_scnptr = f_data.s_scnptr; - f_data_s_vaddr = f_data.s_vaddr; - f_data.s_vaddr = f_bss.s_vaddr; - f_data.s_paddr += new_bss_size; - - if (f_data.s_size + f_idata.s_size != f_ohdr.dsize) - { - printf("section size doesn't tally with dsize %lx != %lx\n", - f_data.s_size + f_idata.s_size, f_ohdr.dsize); - } - f_data.s_size += new_bss_size; - lseek (a_new, 0, SEEK_SET); - /* write file header */ - f_hdr.f_symptr += file_sz_change; - f_hdr.f_nscns--; - printf("writing file header\n"); - if (write(a_new, &f_hdr, sizeof(f_hdr)) != sizeof(f_hdr)) - { - PERROR("failed to write file header"); - } - /* write optional header fixing dsize & bsize*/ - printf("writing optional header\n"); - printf("new data size is %lx, >= %lx\n", new_data_size, - f_ohdr.dsize + f_ohdr.bsize); - if (new_data_size < f_ohdr.dsize + f_ohdr.bsize ) - { - PERROR("new data size is < approx"); - } - f_ohdr.dsize=new_data_size; - f_ohdr.bsize=0; - if (write(a_new, &f_ohdr, sizeof(f_ohdr)) != sizeof(f_ohdr)) - { - PERROR("failed to write optional header"); - } - /* write text as is */ - printf("writing text header (unchanged)\n"); - - if (write(a_new, &f_text, sizeof(f_text)) != sizeof(f_text)) - { - PERROR("failed to write text header"); - } - - /* write new data header */ - printf("writing .data header\n"); - - if (write(a_new, &f_data, sizeof(f_data)) != sizeof(f_data)) - { - PERROR("failed to write data header"); - } - - printf("writing .idata header\n"); - f_idata.s_scnptr += file_sz_change; - if (f_idata.s_lnnoptr != 0) f_idata.s_lnnoptr += file_sz_change; - if (f_idata.s_relptr != 0) f_idata.s_relptr += file_sz_change; - if (write(a_new, &f_idata, sizeof(f_idata)) != sizeof(f_idata)) - { - PERROR("failed to write idata header"); - } - - /* copy other section headers adjusting the file offset */ - for (i=0; i<(f_hdr.f_nscns-3); i++) - { - if (read (a_out, §ion, sizeof (section)) != sizeof (section)) - { - PERROR ("no .data section"); - } - - section.s_scnptr += file_sz_change; - if (section.s_lnnoptr != 0) section.s_lnnoptr += file_sz_change; - if (section.s_relptr != 0) section.s_relptr += file_sz_change; - - if (write(a_new, §ion, sizeof(section)) != sizeof(section)) - { - PERROR("failed to write data header"); - } - } - - /* dump bss to maintain offsets */ - memset(&f_bss, 0, sizeof(f_bss)); - if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss)) - { - PERROR("failed to write bss header"); - } - - - size=lseek(a_new, 0, SEEK_CUR); - CHECK_AOUT_POS(size); - - /* copy eveything else until start of data */ - size = f_data_s_scnptr - lseek (a_out, 0, SEEK_CUR); - - printf ("copying executable up to data section ... %lx bytes\n", - size); - dup_file_area(a_out, a_new, size); - - CHECK_AOUT_POS(f_data_s_scnptr); - - /* dump bss + padding between sections */ - printf ("dumping .bss into executable... %lx bytes\n", bss_size); - if (write(a_new, bss_start, bss_size) != (int)bss_size) - { - PERROR("failed to write bss section"); - } - /* pad, needs to be zero */ - bss_padding = new_bss_size - bss_size; - printf ("padding .bss ... %lx bytes\n", bss_padding); - void* empty_space = malloc(bss_padding); - memset(empty_space, 0, bss_padding); - if (write(a_new, empty_space, bss_padding) != (int)bss_padding) - { - PERROR("failed to write bss section"); - } - free(empty_space); - - /* Get a pointer to the raw data in our address space. */ - printf ("dumping .data section... %lx bytes\n", data_size); - if (write(a_new, data_start_va, data_size) != (int)data_size) - { - PERROR("failed to write data section"); - } - - lseek(a_out, f_data_s_scnptr + data_size, SEEK_SET); - - size = (((unsigned long)per_process_data-f_ohdr.ImageBase)-f_data_s_vaddr) - - data_size; - /* write rest of .data to cygwin per process */ - printf ("copying from .data to cygwin per_process... %lx bytes\n", size); - dup_file_area(a_out, a_new, size); - - /* now write out the per process information */ - printf ("dumping to cygwin per_process... %x bytes at %p\n", - SIZEOF_PER_PROCESS, per_process_data); - - per_process newpp; - memset(&newpp, 0, SIZEOF_PER_PROCESS); - newpp.base = cygwin_statu.base; - newpp.ptr = cygwin_statu.ptr; - newpp.size = cygwin_statu.size; - - if (write(a_new, &newpp, SIZEOF_PER_PROCESS) - != (int)SIZEOF_PER_PROCESS) - { - PERROR("failed to write per_process info"); - } - free(empty_space); - - /* dump the rest */ - size = lseek(a_out, SIZEOF_PER_PROCESS, SEEK_CUR); - size = f_idata.s_scnptr - size; - dup_file_area(a_out, a_new, size); - - // lseek(a_out, f_idata.s_scnptr, SEEK_CUR); - CHECK_AOUT_POS(f_idata.s_scnptr); - /* now dump - idata don't need to do this cygwin ds is in .data! */ - printf ("dumping .idata section... %lx bytes\n", f_idata.s_size); - - dup_file_area(a_out,a_new,f_idata.s_size); - - /* write rest of file */ - printf ("writing rest of file\n"); - size = lseek(a_out, 0, SEEK_END); - size = size - (f_idata.s_scnptr + f_idata.s_size); /* length remaining in a_out */ - lseek(a_out, f_idata.s_scnptr + f_idata.s_size, SEEK_SET); - - dup_file_area(a_out, a_new, size); -} - -/* - * copy from aout to anew - */ -static void dup_file_area(int a_out, int a_new, long size) -{ - char page[BUFSIZ]; - long n; - for (; size > 0; size -= sizeof (page)) - { - n = size > sizeof (page) ? sizeof (page) : size; - if (read (a_out, page, n) != n || write (a_new, page, n) != n) - { - PERROR ("dump_out()"); - } - } -} - -static void dump_heap (int a_out, int a_new) -{ - void *heap_data; - unsigned long heap_size; - - printf ("Dumping heap into executable...\n"); - - heap_size = get_committed_heap_size (); - heap_data = get_heap_start (); - - printf ("heap start in process - %p \n", heap_data); - printf ("heap size in bytes %lx\n", heap_size); - - /* nt version rounds heap start - don't see why we should */ - heap_index_in_executable = lseek(a_new, 0, SEEK_CUR); - - if (write(a_new, heap_data, heap_size) != (int)heap_size) - { - PERROR("failed to write data section"); - } -} - -extern "C" void run_time_remap (char *a_name) -{ - int a_out=-1; - - if ((*heap_base)!=local_heap_base - ||(*heap_index)<local_heap_index - ||(*heap_size)<local_heap_size) - { - PERROR("heap parameters not in bss"); - } - - if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) - { - PERROR (a_name); - } - - /* load the heap */ - lseek(a_out, heap_index_in_executable, SEEK_SET); - - if (read (a_out, get_heap_start(), - (int)((unsigned char*)(local_heap_index) - -(unsigned char*)(local_heap_base))) < 0) - { - PERROR (a_name); - } - close(a_out); - - /* switch to new heap */ - heap_state=HEAP_LOADED; - *heap_flag=0; - - close(a_out); -} - -#endif /* HAVE_COFF_H */