# HG changeset patch # User ben # Date 1045810641 0 # Node ID b531bf8658e983deda413260ffb81b6337c58fd7 # Parent d9d08dc5e6174005080cf1598108c39968d1e0fe [xemacs-hg @ 2003-02-21 06:56:46 by ben] redisplay fixes et al. PROBLEMS: Add comment about Cygwin, unexec and sysmalloc. Move some non-general stuff out of general. Make a section for x86. configure.in: Add check for broken alloca in funcalls. mule/mule-cmds.el: Alias file-name to native not vice-versa. Do set EOL of native but not of process output to fix various problems and be consistent with code-init.el. code-cmds.el: Return a name not a coding system. code-init.el: Reindent. Remove `file-name' since it should always be the same as native. unicode.el: Rename to load-unicode-mapping-table as suggested by the anonymous (but rather Turnbullian) comment in unicode.c. xemacs.dsp: Add /k to default build. alloc.c: Make gc_currently_forbidden static. config.h.in, lisp.h: Move some stuff to lisp.h. console-gtk.h, console-impl.h, console-msw.h, console-x.h, event-Xt.c, event-msw.c, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-x.c, gtk-xemacs.c: Remove duplicated code to redraw exposed area. Add deadbox method needed by the generalized redraw code. Defer redrawing if already in redisplay. frame-msw.c, event-stream.c, frame.c: Add comments about calling Lisp. debug.c, general-slots.h: Move generalish symbols to general-slots.h. doprnt.c: reindent. lisp.h, dynarr.c: Add debug code for locking a dynarr to catch invalid mods. Use in redisplay.c. eval.c: file-coding.c: Define file-name as alias for native not vice-versa. frame-gtk.c, frame-x.c: Move Qwindow_id to general-slots. dialog-msw.c, glyphs-gtk.c, glyphs-msw.c, glyphs-widget.c, glyphs-x.c, gui.c, gui.h, menubar-msw.c, menubar.c: Ensure that various glyph functions that eval within redisplay protect the evals. Same for calls to internal_equal(). Modify various functions, e.g. gui_item_*(), to protect evals within redisplay, taking an in_redisplay parameter if it's possible for them to be called both inside and outside of redisplay. gutter.c: Defer specifier-changed updating till after redisplay, if necessary, since we need to enter redisplay to do it. gutter.c: Do nothing if in redisplay. lisp.h: Add version of alloca() for use in function calls. lisp.h: Add XCAD[D+]R up to 6 D's, and aliases X1ST, X2ND, etc. frame.c, frame.h, redisplay.c, redisplay.h, signal.c, toolbar.c: Redo critical-section code and move from frame.c to redisplay.c. Require that every place inside of redisplay catch errors itself, not at the edge of the critical section (thereby bypassing the rest of redisplay and leaving things in an inconsistent state). Introduce separate means of holding frame-size changes without entering a complete critical section. Introduce "post-redisplay" methods for deferring things till after redisplay. Abort if we enter redisplay reentrantly. Disable all quit checking in redisplay since it's too dangerous. Ensure that all calls to QUIT trigger an abort if unprotected. redisplay.c, scrollbar-gtk.c, scrollbar-x.c, scrollbar.c: Create enter/exit_redisplay_critical_section_maybe() for code that needs to ensure it's in a critical section but doesn't interfere with an existing critical section. sysdep.c: Use _wexecve() when under Windows NT for Unicode correctness. text.c, text.h: Add new_dfc() functions, which return an alloca()ed value rather than requiring an lvalue. (Not really used yet; used in another workspace, to come.) Add some macros for SIZED_EXTERNAL. Update the encoding aliases after involved scrutinization of the X manual. unicode.c: Answer the anonymous but suspiciously Turnbullian questions. Rename parse-unicode-translation-table to load-unicode-mapping-table, as suggested. diff -r d9d08dc5e617 -r b531bf8658e9 ChangeLog --- a/ChangeLog Thu Feb 20 22:52:51 2003 +0000 +++ b/ChangeLog Fri Feb 21 06:57:21 2003 +0000 @@ -1,3 +1,18 @@ +2003-02-20 Ben Wing + + * PROBLEMS: + * PROBLEMS (event-stream.c): Removed. + * PROBLEMS (ABSTRACT): + * PROBLEMS (patch.): + * PROBLEMS (Note): + Add comment about Cygwin, unexec and sysmalloc. + Move some non-general stuff out of general. + Make a section for x86. + + * configure.in (AC_INIT_NOTICE): + * configure.in (XE_COMPUTE_RUNPATH): + Add check for broken alloca in funcalls. + 2003-02-19 Ben Wing * Makefile.in.in: diff -r d9d08dc5e617 -r b531bf8658e9 PROBLEMS --- a/PROBLEMS Thu Feb 20 22:52:51 2003 +0000 +++ b/PROBLEMS Fri Feb 21 06:57:21 2003 +0000 @@ -60,55 +60,6 @@ link with it, you need the headers---and distros don't provide them with the libraries. You need the additional "development" package, too. -*** Don't use -O2 with gcc 2.8.1 and egcs 1.0 under SPARC architectures -without also using `-fno-schedule-insns'. - -gcc will generate incorrect code otherwise, typically resulting in -crashes in the function skip-syntax-backward. - -*** egcs-1.1 - -There have been reports of egcs-1.1 not compiling XEmacs correctly on -Alpha Linux. There have also been reports that egcs-1.0.3a is O.K. - -*** Don't use -O2 or -O3 with Cygwin 1.0, CodeFusion-99070 or gcc 2.7.2 on x86 -without also using `-fno-strength-reduce'. - -gcc will generate incorrect code otherwise. This bug is present in at -least 2.6.x and 2.7.[0-2]. This bug has been fixed in GCC 2.7.2.1 and -later. This bug is O/S independent, but is limited to x86 architectures. - -This problem is known to be fixed in egcs (or pgcc) 1.0 or later. - -Unfortunately, later releases of Cygnus-released compilers (not the -Net-released ones) have a bug with the same `problem signature'. - -If you're lucky, you'll get an error while compiling that looks like: - -event-stream.c:3189: internal error--unrecognizable insn: -(insn 256 14 15 (set (reg/v:SI 24) - (minus:SI (reg/v:SI 25) - (const_int 2))) -1 (insn_list 11 (nil)) - (nil)) - 0 0 [main] - -If you're unlucky, your code will simply execute incorrectly. - -*** Don't use gcc-2.95.2 with -mcpu=ultrasparc on Solaris 2.6. - -gcc will assume a 64-bit operating system, even though you've -merely told it to assume a 64-bit instruction set. - -*** Don't use -O2 with gcc 2.7.2 under Intel architectures without also -using `-fno-caller-saves'. - -gcc will generate incorrect code otherwise. This bug is still -present in gcc 2.7.2.3. There have been no reports to indicate the -bug is present in egcs 1.0 (or pgcc 1.0) or later. This bug is O/S -independent, but limited to x86 architectures. - -This problem is known to be fixed in egcs (or pgcc) 1.0 or later. - *** When using gcc, you get the error message "undefined symbol __fixunsdfsi". When using gcc, you get the error message "undefined symbol __main". @@ -163,6 +114,41 @@ This will rebuild all the needed .elc files. +** Intel Architecture General + +*** Don't use -O2 or -O3 with Cygwin 1.0, CodeFusion-99070 or gcc 2.7.2 on x86 +without also using `-fno-strength-reduce'. + +gcc will generate incorrect code otherwise. This bug is present in at +least 2.6.x and 2.7.[0-2]. This bug has been fixed in GCC 2.7.2.1 and +later. This bug is O/S independent, but is limited to x86 architectures. + +This problem is known to be fixed in egcs (or pgcc) 1.0 or later. + +Unfortunately, later releases of Cygnus-released compilers (not the +Net-released ones) have a bug with the same `problem signature'. + +If you're lucky, you'll get an error while compiling that looks like: + +event-stream.c:3189: internal error--unrecognizable insn: +(insn 256 14 15 (set (reg/v:SI 24) + (minus:SI (reg/v:SI 25) + (const_int 2))) -1 (insn_list 11 (nil)) + (nil)) + 0 0 [main] + +If you're unlucky, your code will simply execute incorrectly. + +*** Don't use -O2 with gcc 2.7.2 under Intel architectures without also +using `-fno-caller-saves'. + +gcc will generate incorrect code otherwise. This bug is still +present in gcc 2.7.2.3. There have been no reports to indicate the +bug is present in egcs 1.0 (or pgcc 1.0) or later. This bug is O/S +independent, but limited to x86 architectures. + +This problem is known to be fixed in egcs (or pgcc) 1.0 or later. + *** `compress' and `uncompress' not found and XFree86 XFree86 installs a very old version of libz.a by default ahead of where @@ -360,6 +346,17 @@ ** SunOS/Solaris +*** Don't use -O2 with gcc 2.8.1 and egcs 1.0 under SPARC architectures +without also using `-fno-schedule-insns'. + +gcc will generate incorrect code otherwise, typically resulting in +crashes in the function skip-syntax-backward. + +*** Don't use gcc-2.95.2 with -mcpu=ultrasparc on Solaris 2.6. + +gcc will assume a 64-bit operating system, even though you've +merely told it to assume a 64-bit instruction set. + *** Dumping error when using GNU binutils / GNU ld on a Sun. Errors similar to the following: @@ -480,6 +477,14 @@ broken. Use the ones in /usr/openwin/{include,lib} instead. ** Linux + +See also Intel Architecture General, above. + +*** egcs-1.1 on Alpha Linux + +There have been reports of egcs-1.1 not compiling XEmacs correctly on +Alpha Linux. There have also been reports that egcs-1.0.3a is O.K. + *** Under Linux, you get "too many arguments to function `getpgrp'". You have probably installed LessTiff under `/usr/local' and `libXm.so' @@ -735,6 +740,19 @@ ** Cygwin +See also Intel Architecture General, above. + +*** Signal 11 when building or running a dumped XEmacs. + +This appears to happen when using the traditional dumping mechanism and +the system malloc. Andy Piper writes: + + Traditional dumping on cygwin relies on using gmalloc (there are specific + hacks in our version of gmalloc to support this), I suspect using sysmalloc + is the problem. + +Try configuring with pdump or without system malloc. + *** In general use etc/check_cygwin_setup.sh to trap environment problems. The script etc/check_cygwin_setup.sh will attempt to detect whether @@ -1953,6 +1971,10 @@ ** Cygwin +*** Signal 11 when building or running a dumped XEmacs. + +See the section on Cygwin above, under building. + *** XEmacs fails to start because cygXpm-noX4.dll was not found. Andy Piper sez: diff -r d9d08dc5e617 -r b531bf8658e9 configure.in --- a/configure.in Thu Feb 20 22:52:51 2003 +0000 +++ b/configure.in Fri Feb 21 06:57:21 2003 +0000 @@ -6,7 +6,7 @@ #### Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. #### Copyright (C) 1993-1995 Board of Trustees, University of Illinois. #### Copyright (C) 1996, 1997 Sun Microsystems, Inc. -#### Copyright (C) 1995, 1996, 2002 Ben Wing. +#### Copyright (C) 1995, 1996, 2002, 2003 Ben Wing. #### Copyright (C) 2000, 2001 Martin Buchholz. #### Copyright (C) 1998, 1999 J. Kean Johnston. @@ -4156,6 +4156,61 @@ test -n "$ALLOCA" && XE_ADD_OBJS($ALLOCA) fi +AC_MSG_CHECKING(for working alloca in function calls) +AC_TRY_RUN([ +#if defined (__CYGWIN__) +#include +#elif defined (__GNUC__) +#define alloca __builtin_alloca +#elif defined (__DECC) +#include +#pragma intrinsic(alloca) +#elif defined (HAVE_ALLOCA_H) +#include +#elif defined (_AIX) +#pragma alloca +#elif ! defined (alloca) +#ifdef C_ALLOCA +#define alloca xemacs_c_alloca +#else +void *alloca (); +#endif /* C_ALLOCA */ +#endif /* !defined (alloca) */ + +void +f1 (double a, void *ptr, int b) +{ + unsigned char *ptr2 = (unsigned char *) ptr; + if (ptr2[0] != 0xBF || ptr2[1] != 0xBF || ptr2[3000] != 0xBF) + exit (1); + if (a != 3.1415 || b != -5490) + exit (1); +} + +int +f2 (short c, void *ptr, long e) +{ + unsigned char *ptr2 = (unsigned char *) ptr; + if (ptr2[0] != 0xFB || ptr2[1] != 0xFB || ptr2[1000] != 0xFB) + exit (1); + if (c != 665 || e != 776776776) + exit (1); + f1 (3.1415, memset (alloca (3001), 0xBF, 3001), -5490); + return 42; +} + +int +main (int argc, char *argv[]) +{ + if (f2 (665, memset (alloca (1001), 0xFB, 1001), 776776776) != 42) + return 1; + return 0; +} +], working_alloca_in_function_calls=yes, working_alloca_in_function_calls=no) +AC_MSG_RESULT($working_alloca_in_function_calls) +test "$working_alloca_in_function_calls" != "yes" && \ + AC_DEFINE(BROKEN_ALLOCA_IN_FUNCTION_CALLS) + dnl Check whether strcoll exists and works correctly. (This does more dnl than just check for its existence.) If so, it defines HAVE_STRCOLL. AC_FUNC_STRCOLL diff -r d9d08dc5e617 -r b531bf8658e9 lisp/ChangeLog --- a/lisp/ChangeLog Thu Feb 20 22:52:51 2003 +0000 +++ b/lisp/ChangeLog Fri Feb 21 06:57:21 2003 +0000 @@ -1,3 +1,30 @@ +2003-02-20 Ben Wing + + * mule/mule-cmds.el: + * mule/mule-cmds.el (get-native-coding-system-from-language-environment): + * mule/mule-cmds.el (set-language-environment-coding-systems): + * mule/mule-cmds.el (init-locale-at-early-startup): + Alias file-name to native not vice-versa. + Do set EOL of native but not of process output to fix various + problems and be consistent with code-init.el. + +2003-02-20 Ben Wing + + * code-cmds.el (coding-system-change-eol-conversion): + Return a name not a coding system. + + * code-init.el: + * code-init.el (coding-system-default-variable-list): + * code-init.el (get-coding-system-variable): + * code-init.el (set-coding-system-variable): + * code-init.el (coding-system-variable-default-value): + Reindent. Remove `file-name' since it should always be the same + as native. + + * unicode.el (load-unicode-tables): + Rename to load-unicode-mapping-table as suggested by the anonymous + (but rather Turnbullian) comment in unicode.c. + 2003-02-19 Ben Wing * mule/mule-msw-init.el: diff -r d9d08dc5e617 -r b531bf8658e9 lisp/code-cmds.el --- a/lisp/code-cmds.el Thu Feb 20 22:52:51 2003 +0000 +++ b/lisp/code-cmds.el Fri Feb 21 06:57:21 2003 +0000 @@ -53,7 +53,6 @@ (define-key coding-keymap "x" 'set-selection-coding-system) (define-key coding-keymap "X" 'set-next-selection-coding-system)) - (defun coding-system-change-eol-conversion (coding-system eol-type) "Return a coding system which differs from CODING-SYSTEM in eol conversion. The returned coding system converts end-of-line by EOL-TYPE @@ -75,19 +74,20 @@ (eq eol-type 'cr)) 'eol-cr) (t eol-type)))) - (let ((orig-eol-type (coding-system-eol-type coding-system))) - (if (null orig-eol-type) - (if (not eol-type) - coding-system - (coding-system-property coding-system eol-type)) - (let ((base (coding-system-base coding-system))) - (if (not eol-type) - base - (if (eq eol-type orig-eol-type) - coding-system - (setq orig-eol-type (coding-system-eol-type base)) - (if (null orig-eol-type) - (coding-system-property base eol-type)))))))) + (coding-system-name + (let ((orig-eol-type (coding-system-eol-type coding-system))) + (if (null orig-eol-type) + (if (not eol-type) + coding-system + (coding-system-property coding-system eol-type)) + (let ((base (coding-system-base coding-system))) + (if (not eol-type) + base + (if (eq eol-type orig-eol-type) + coding-system + (setq orig-eol-type (coding-system-eol-type base)) + (if (null orig-eol-type) + (coding-system-property base eol-type))))))))) ;; (defun coding-system-change-text-conversion (coding-system coding) ;; "Return a coding system which differs from CODING-SYSTEM in text conversion. diff -r d9d08dc5e617 -r b531bf8658e9 lisp/code-init.el --- a/lisp/code-init.el Thu Feb 20 22:52:51 2003 +0000 +++ b/lisp/code-init.el Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ ;;; code-init.el --- Handle coding system default values -;; Copyright (C) 2001, 2002 Ben Wing. +;; Copyright (C) 2001, 2002, 2003 Ben Wing. ;; This file is part of XEmacs. @@ -69,19 +69,28 @@ (eol-detection-enabled-p 'unix-no-mule-eol-detection) (t 'unix-no-mule-no-eol-detection))) +;; NOTE NOTE NOTE: These values may get overridden when the language +;; environment is initialized (set-language-environment-coding-systems). (defvar coding-system-variable-default-value-table - '((buffer-file-coding-system-for-read binary raw-text undecided raw-text undecided) - (default-buffer-file-coding-system binary binary iso-2022-8 raw-text-dos mswindows-multibyte-dos) - (file-name binary binary binary raw-text-dos mswindows-multibyte-system-default-dos) - (native binary binary binary raw-text-dos mswindows-multibyte-system-default-dos) - (keyboard binary raw-text undecided raw-text undecided) + '((buffer-file-coding-system-for-read + binary raw-text undecided raw-text undecided) + (default-buffer-file-coding-system + binary binary iso-2022-8 raw-text-dos mswindows-multibyte-dos) + (native + binary binary binary raw-text-dos mswindows-multibyte-system-default-dos) + (keyboard + binary raw-text undecided raw-text undecided) ;; the `terminal' coding system is used for output to stderr. such ;; streams do automatic lf->crlf encoding in the C library, so we need ;; to not do the same translations ourselves. - (terminal binary binary binary binary mswindows-multibyte-unix) - (default-process-coding-system-read binary raw-text undecided raw-text undecided) - (default-process-coding-system-write binary binary binary raw-text mswindows-multibyte-system-default) - (no-conversion-coding-system-mapping binary raw-text raw-text raw-text mswindows-multibyte) + (terminal + binary binary binary binary mswindows-multibyte-unix) + (default-process-coding-system-read + binary raw-text undecided raw-text undecided) + (default-process-coding-system-write + binary binary binary raw-text mswindows-multibyte-system-default) + (no-conversion-coding-system-mapping + binary raw-text raw-text raw-text mswindows-multibyte) )) (defvar coding-system-default-configuration-list @@ -94,7 +103,6 @@ (defvar coding-system-default-variable-list '(buffer-file-coding-system-for-read default-buffer-file-coding-system - file-name native keyboard terminal @@ -111,7 +119,6 @@ (buffer-file-coding-system-for-read buffer-file-coding-system-for-read) (default-buffer-file-coding-system (default-value 'buffer-file-coding-system)) - (file-name (coding-system-aliasee 'file-name)) (native (coding-system-aliasee 'native)) (keyboard (coding-system-aliasee 'keyboard)) (terminal (coding-system-aliasee 'terminal)) @@ -130,7 +137,6 @@ (set-buffer-file-coding-system-for-read value)) (default-buffer-file-coding-system (set-default-buffer-file-coding-system value)) - (file-name (define-coding-system-alias 'file-name value)) (native (define-coding-system-alias 'native value)) (keyboard (set-keyboard-coding-system value)) (terminal (set-terminal-coding-system value)) @@ -156,7 +162,6 @@ ------------------------------------------------------------------------------ bfcs-for-read binary raw-text undecided raw-text undecided default bfcs binary binary iso-2022-8 raw-text-dos MSW-MB-dos -file-name binary binary binary raw-text-dos MSW-MB-SD-dos native binary binary binary raw-text-dos MSW-MB-SD-dos keyboard binary raw-text undecided raw-text undecided terminal binary binary binary binary MSW-MB-unix @@ -184,18 +189,11 @@ system used to read the file in; the default value applies to newly created files. -`file-name' (file-name) - - The coding system named `file-name'. Changed using - `define-coding-system-alias'. Used internally when passing file - names to or from system API's, unless the particular API specifies - another coding system. - `native' (native) The coding system named `native'. Changed using `define-coding-system-alias'. Used internally when passing - non-file-name text to or from system API's, unless the particular + text to or from system API's, unless the particular API specifies another coding system. `keyboard' (keyboard) diff -r d9d08dc5e617 -r b531bf8658e9 lisp/mule/mule-cmds.el --- a/lisp/mule/mule-cmds.el Thu Feb 20 22:52:51 2003 +0000 +++ b/lisp/mule/mule-cmds.el Fri Feb 21 06:57:21 2003 +0000 @@ -3,7 +3,7 @@ ;; Copyright (C) 1995,1999 Electrotechnical Laboratory, JAPAN. ;; Licensed to the Free Software Foundation. ;; Copyright (C) 1997 MORIOKA Tomohiko -;; Copyright (C) 2000, 2001, 2002 Ben Wing. +;; Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. ;; Keywords: mule, multilingual @@ -1078,7 +1078,7 @@ system locale and is not influenced by LOCALE. (In other words, a program can't set the text encoding used to communicate with the OS. To get around this, we use Unicode whenever available, i.e. on Windows NT always and on -Windows 9x for a few system calls.)" +Windows 9x whenever a Unicode version of a system call is available.)" (if (eq system-type 'windows-nt) ;; should not apply to Cygwin, I don't think 'mswindows-multibyte-system-default @@ -1263,19 +1263,22 @@ (maybe-change-coding-system-with-eol default-coding eol-type)))) ;; (setq default-sendmail-coding-system default-coding) - ;; set the native and file-name aliases (currently always the same), - ;; and the terminal-write system. + ;; set the native coding system and the default process-output system. (let ((native (get-native-coding-system-from-language-environment language-name (current-locale)))) + (condition-case nil - (define-coding-system-alias 'file-name native) + (define-coding-system-alias 'native + (maybe-change-coding-system-with-eol native eol-type)) (error (warn "Invalid native-coding-system %s in language environment %s" native language-name))) - (define-coding-system-alias 'native 'file-name) + (define-coding-system-alias 'file-name 'native) + ;; process output should not have EOL conversion. under MS Windows + ;; and Cygwin, this screws things up (`cmd' is fine with just LF and + ;; `bash' chokes on CR-LF). (setq default-process-coding-system - (cons (car default-process-coding-system) - (maybe-change-coding-system-with-eol native eol-type)))))) + (cons (car default-process-coding-system) native))))) (defun init-locale-at-early-startup () "Don't call this." diff -r d9d08dc5e617 -r b531bf8658e9 lisp/unicode.el --- a/lisp/unicode.el Thu Feb 20 22:52:51 2003 +0000 +++ b/lisp/unicode.el Fri Feb 21 06:57:21 2003 +0000 @@ -164,7 +164,7 @@ (let ((undir (expand-file-name (car tables) data-directory))) (mapcar #'(lambda (args) - (apply 'parse-unicode-translation-table + (apply 'load-unicode-mapping-table (expand-file-name (car args) undir) (cdr args))) (cdr tables)))) diff -r d9d08dc5e617 -r b531bf8658e9 nt/ChangeLog --- a/nt/ChangeLog Thu Feb 20 22:52:51 2003 +0000 +++ b/nt/ChangeLog Fri Feb 21 06:57:21 2003 +0000 @@ -1,3 +1,8 @@ +2003-02-20 Ben Wing + + * xemacs.dsp (CFG): + Add /k to default build. + 2003-02-19 Ben Wing * xemacs.mak (DO_TEMACS): New. diff -r d9d08dc5e617 -r b531bf8658e9 nt/xemacs.dsp --- a/nt/xemacs.dsp Thu Feb 20 22:52:51 2003 +0000 +++ b/nt/xemacs.dsp Fri Feb 21 06:57:21 2003 +0000 @@ -58,7 +58,7 @@ # PROP Use_Debug_Libraries 1 # PROP Output_Dir "..\src" # PROP Intermediate_Dir "obj" -# PROP Cmd_Line "NMAKE /f xemacs.mak" +# PROP Cmd_Line "NMAKE /k /f xemacs.mak" # PROP Rebuild_Opt "/a" # PROP Target_File "..\src\xemacs.exe" # PROP Bsc_Name "..\src\temacs.bsc" diff -r d9d08dc5e617 -r b531bf8658e9 src/ChangeLog --- a/src/ChangeLog Thu Feb 20 22:52:51 2003 +0000 +++ b/src/ChangeLog Fri Feb 21 06:57:21 2003 +0000 @@ -1,3 +1,231 @@ +2003-02-20 Ben Wing + + * alloc.c: + * alloc.c (garbage_collect_1): + Make gc_currently_forbidden static. + + * config.h.in: + * lisp.h: + Move some stuff to lisp.h. + + * console-gtk.h: + * console-impl.h: + * console-impl.h (struct console_methods): + * console-msw.h: + * console-x.h: + * event-Xt.c (emacs_Xt_handle_magic_event): + * event-msw.c (emacs_mswindows_drain_queue): + * event-msw.c (mswindows_handle_paint): + * event-msw.c (emacs_mswindows_event_pending_p): + * redisplay-gtk.c: + * redisplay-gtk.c (gtk_clear_to_window_end): + * redisplay-msw.c: + * redisplay-msw.c (mswindows_redisplay_deadbox): + * redisplay-msw.c (mswindows_clear_region): + * redisplay-msw.c (mswindows_clear_frame): + * redisplay-msw.c (console_type_create_redisplay_mswindows): + * redisplay-output.c: + * redisplay-output.c (redisplay_output_window): + * redisplay-output.c (redisplay_redraw_exposed_window): + * redisplay-output.c (redisplay_redraw_exposed_area): + * redisplay-x.c: + * redisplay-x.c (x_generate_shadow_pixels): + * gtk-xemacs.c (gtk_xemacs_paint): + * gtk-xemacs.c (gtk_xemacs_expose): + Remove duplicated code to redraw exposed area. Add deadbox + method needed by the generalized redraw code. Defer redrawing + if already in redisplay. + + * frame-msw.c (mswindows_set_frame_size): + * event-stream.c (event_stream_drain_queue): + * event-stream.c (detect_input_pending): + * event-stream.c (Finput_pending_p): + * event-stream.c (event_stream_quit_p): + * event-stream.c (run_pre_idle_hook): + * event-stream.c (Fdiscard_input): + * frame.c: + Add comments about calling Lisp. + + * debug.c: + * debug.c (FROB): + * debug.c (syms_of_debug): + * general-slots.h: + Move generalish symbols to general-slots.h. + + * doprnt.c (get_doprnt_args): + * doprnt.c (emacs_doprnt_1): + reindent. + + * lisp.h (Dynarr_reset): + * lisp.h (Dynarr_add): + * lisp.h (Dynarr_increment): + * lisp.h (Dynarr_pop): + * lisp.h (Dynarr_delete_object): + * dynarr.c: + * dynarr.c (Dynarr_resize): + * dynarr.c (Dynarr_insert_many): + * dynarr.c (Dynarr_delete_many): + * dynarr.c (Dynarr_memory_usage): + Add debug code for locking a dynarr to catch invalid mods. + Use in redisplay.c. + + * eval.c: + * eval.c (throw_or_bomb_out): + * eval.c (Fsignal): + * eval.c (Feval): + * eval.c (Ffuncall): + * eval.c (set_trapping_problems_flags): + * eval.c (call_trapping_problems): + + * file-coding.c: + * file-coding.c (complex_vars_of_file_coding): + Define file-name as alias for native not vice-versa. + + * frame-gtk.c: + * frame-gtk.c (syms_of_frame_gtk): + * frame-x.c: + * frame-x.c (syms_of_frame_x): + Move Qwindow_id to general-slots. + + * dialog-msw.c (handle_question_dialog_box): + * glyphs-gtk.c (gtk_tab_control_redisplay): + * glyphs-msw.c: + * glyphs-msw.c (mswindows_redisplay_widget): + * glyphs-msw.c (mswindows_widget_instantiate): + * glyphs-msw.c (mswindows_button_instantiate): + * glyphs-msw.c (mswindows_button_redisplay): + * glyphs-msw.c (mswindows_tab_control_instantiate): + * glyphs-msw.c (mswindows_tab_control_redisplay): + * glyphs-widget.c: + * glyphs-widget.c (widget_normalize): + * glyphs-widget.c (tab_control_order_only_changed): + * glyphs-widget.c (layout_query_geometry): + * glyphs-x.c: + * glyphs-x.c (x_widget_instantiate): + * glyphs-x.c (x_button_instantiate): + * glyphs-x.c (x_progress_gauge_instantiate): + * glyphs-x.c (x_tab_control_instantiate): + * glyphs-x.c (x_tab_control_redisplay): + * gui.c: + * gui.c (gui_item_value): + * gui.c (gui_item_active_p): + * gui.c (gui_item_selected_p): + * gui.c (gui_item_list_find_selected): + * gui.c (gui_item_included_p): + * gui.c (gui_value_equal): + * gui.c (gui_item_equal_sans_selected): + * gui.c (gui_item_equal): + * gui.h: + * menubar-msw.c (populate_menu_add_item): + * menubar.c (Fmenu_find_real_submenu): + Ensure that various glyph functions that eval within redisplay + protect the evals. Same for calls to internal_equal(). + Modify various functions, e.g. gui_item_*(), to protect evals + within redisplay, taking an in_redisplay parameter if it's + possible for them to be called both inside and outside of + redisplay. + + * gutter.c: + * gutter.c (calculate_gutter_size): + * gutter.c (redraw_exposed_gutters): + * gutter.c (Fset_default_gutter_position): + * gutter.c (gutter_specs_changed): + * gutter.c (gutter_geometry_changed_in_window): + Defer specifier-changed updating till after redisplay, if + necessary, since we need to enter redisplay to do it. + + * gutter.c (Fredisplay_gutter_area): + Do nothing if in redisplay. + + * lisp.h: + Add version of alloca() for use in function calls. + + * lisp.h (XCADR): + Add XCAD[D+]R up to 6 D's, and aliases X1ST, X2ND, etc. + + * frame.c (invalidate_vertical_divider_cache_in_frame): + * frame.c (adjust_frame_size): + * frame.c (store_minibuf_frame_prop): + * frame.c (Fset_frame_properties): + * frame.c (internal_set_frame_size): + * frame.c (Fset_frame_height): + * frame.c (Fset_frame_pixel_height): + * frame.c (Fset_frame_displayable_pixel_height): + * frame.c (Fset_frame_width): + * frame.c (Fset_frame_pixel_width): + * frame.c (Fset_frame_displayable_pixel_width): + * frame.c (Fset_frame_size): + * frame.c (Fset_frame_pixel_size): + * frame.c (Fset_frame_displayable_pixel_size): + * frame.c (change_frame_size_1): + * frame.c (change_frame_size): + * frame.h: + * redisplay.c: + * redisplay.c (REDISPLAY_PREEMPTION_CHECK \): + * redisplay.c (generate_displayable_area): + * redisplay.c (regenerate_window): + * redisplay.c (enter_redisplay_critical_section): + * redisplay.c (exit_redisplay_critical_section): + * redisplay.c (redisplay_frame): + * redisplay.c (eval_within_redisplay): + * redisplay.c (free_display_line): + * redisplay.c (Fredisplay_echo_area): + * redisplay.c (vars_of_redisplay): + * redisplay.h: + * signal.c (check_what_happened): + * toolbar.c: + * toolbar.c (Fset_default_toolbar_position): + Redo critical-section code and move from frame.c to redisplay.c. + Require that every place inside of redisplay catch errors itself, + not at the edge of the critical section (thereby bypassing the + rest of redisplay and leaving things in an inconsistent state). + Introduce separate means of holding frame-size changes without + entering a complete critical section. Introduce "post-redisplay" + methods for deferring things till after redisplay. Abort if + we enter redisplay reentrantly. Disable all quit checking in + redisplay since it's too dangerous. Ensure that all calls to + QUIT trigger an abort if unprotected. + + * redisplay.c: + * scrollbar-gtk.c (gtk_update_frame_scrollbars): + * scrollbar-x.c (x_update_frame_scrollbars): + * scrollbar.c: + * scrollbar.c (update_window_scrollbars): + Create enter/exit_redisplay_critical_section_maybe() for code + that needs to ensure it's in a critical section but doesn't + interfere with an existing critical section. + + * sysdep.c: + * sysdep.c (qxe_execve): + Use _wexecve() when under Windows NT for Unicode correctness. + + * text.c: + * text.c (new_dfc_convert_now_damn_it): + * text.c (new_dfc_convert_malloc): + * text.c (find_pos_of_existing_active_dfc_e2c): + * text.c (new_dfc_convert_alloca): + * text.c (new_dfc_convert_size): + * text.c (reinit_vars_of_text): + * text.h: + * text.h (eicpy_ext_len): + * text.h (eicpy_ext): + * text.h (eito_external): + * text.h (Qx_atom_name_encoding): + Add new_dfc() functions, which return an alloca()ed value rather + than requiring an lvalue. (Not really used yet; used in another + workspace, to come.) Add some macros for SIZED_EXTERNAL. + + Update the encoding aliases after involved scrutinization of the + X manual. + + * unicode.c: + * unicode.c (init_blank_unicode_tables): + * unicode.c (init_charset_unicode_tables): + * unicode.c (syms_of_unicode): + Answer the anonymous but suspiciously Turnbullian questions. + Rename parse-unicode-translation-table to + load-unicode-mapping-table, as suggested. + 2003-02-19 Ben Wing * Makefile.in.in (all): New. diff -r d9d08dc5e617 -r b531bf8658e9 src/alloc.c --- a/src/alloc.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/alloc.c Fri Feb 21 06:57:21 2003 +0000 @@ -187,7 +187,7 @@ /* Nonzero when calling certain hooks or doing other things where a GC would be bad */ -int gc_currently_forbidden; +static int gc_currently_forbidden; /* Hooks. */ Lisp_Object Vpre_gc_hook, Qpre_gc_hook; @@ -4444,7 +4444,7 @@ speccount = begin_gc_forbidden (); need_to_signal_post_gc = 0; - recompute_funcall_allocation_flag(); + recompute_funcall_allocation_flag (); if (!gc_hooks_inhibited) run_hook_trapping_problems diff -r d9d08dc5e617 -r b531bf8658e9 src/config.h.in --- a/src/config.h.in Thu Feb 20 22:52:51 2003 +0000 +++ b/src/config.h.in Fri Feb 21 06:57:21 2003 +0000 @@ -1018,31 +1018,4 @@ #define ERROR_CHECK_STRUCTURES #endif /* ERROR_CHECK_ALL */ -/* Move these down here so that the s/m files (esp. windowsnt.h) can - set them. */ -#ifdef ERROR_CHECK_TYPES -#define type_checking_assert(assertion) assert (assertion) -#define type_checking_assert_at_line(assertion, file, line) \ - assert_at_line (assertion, file, line) -#else -#define type_checking_assert(assertion) -#define type_checking_assert_at_line(assertion, file, line) -#endif -#ifdef ERROR_CHECK_GC -#define gc_checking_assert(assertion) assert (assertion) -#define gc_checking_assert_at_line(assertion, file, line) \ - assert_at_line (assertion, file, line) -#else -#define gc_checking_assert(assertion) -#define gc_checking_assert_at_line(assertion, file, line) -#endif -#ifdef ERROR_CHECK_TEXT -#define text_checking_assert(assertion) assert (assertion) -#define text_checking_assert_at_line(assertion, file, line) \ - assert_at_line (assertion, file, line) -#else -#define text_checking_assert(assertion) -#define text_checking_assert_at_line(assertion, file, line) -#endif - #endif /* _SRC_CONFIG_H_ */ diff -r d9d08dc5e617 -r b531bf8658e9 src/console-gtk.h --- a/src/console-gtk.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/console-gtk.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* Define X 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. - Copyright (C) 2002 Ben Wing. + Copyright (C) 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -58,8 +58,6 @@ void signal_special_gtk_user_event (Lisp_Object channel, Lisp_Object function, Lisp_Object object); -void gtk_redraw_exposed_area (struct frame *f, int x, int y, - int width, int height); void gtk_output_string (struct window *w, struct display_line *dl, Ichar_dynarr *buf, int xpos, int xoffset, int start_pixpos, int width, face_index findex, diff -r d9d08dc5e617 -r b531bf8658e9 src/console-impl.h --- a/src/console-impl.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/console-impl.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,5 +1,5 @@ /* Define console object for XEmacs. - Copyright (C) 1996, 2002 Ben Wing + Copyright (C) 1996, 2002, 2003 Ben Wing This file is part of XEmacs. @@ -290,6 +290,10 @@ struct scrollbar_instance *, struct overhead_stats *); #endif + /* Paint the window's deadbox, a rectangle between window + borders and two short edges of both scrollbars. */ + void (*redisplay_deadbox_method) (struct window *w, int x, int y, int width, + int height); #endif /* HAVE_SCROLLBARS */ #ifdef HAVE_MENUBARS diff -r d9d08dc5e617 -r b531bf8658e9 src/console-msw.h --- a/src/console-msw.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/console-msw.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* 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. - Copyright (C) 2001, 2002 Ben Wing. + Copyright (C) 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -93,8 +93,6 @@ UINT msg, WPARAM wParam, LPARAM lParam); -void mswindows_redraw_exposed_area (struct frame *f, int x, int y, - int width, int height); void mswindows_size_frame_internal (struct frame *f, XEMACS_RECT_WH *dest); HWND mswindows_get_selected_frame_hwnd (void); void mswindows_enqueue_magic_event (HWND hwnd, UINT msg); diff -r d9d08dc5e617 -r b531bf8658e9 src/console-x.h --- a/src/console-x.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/console-x.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* Define X 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. - Copyright (C) 1996, 2002 Ben Wing. + Copyright (C) 1996, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -111,8 +111,6 @@ int signal_if_x_error (Display *dpy, int resumable_p); int x_IO_error_handler (Display *disp); -void x_redraw_exposed_area (struct frame *f, int x, int y, - int width, int height); void x_output_string (struct window *w, struct display_line *dl, Ichar_dynarr *buf, int xpos, int xoffset, int start_pixpos, int width, face_index findex, diff -r d9d08dc5e617 -r b531bf8658e9 src/debug.c --- a/src/debug.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/debug.c Fri Feb 21 06:57:21 2003 +0000 @@ -31,16 +31,14 @@ /* * To add a new debug class: - * 1. Add a symbol definition for it here, if one doesn't exist - * elsewhere. If you add it here, make sure to add a defsymbol - * line for it in syms_of_debug. + * 1. Add a symbol definition for it here or in general-slots.h, if one + * doesn't exist elsewhere. If you add it here, make sure to add a + * defsymbol line for it in syms_of_debug. * 2. Add an extern definition for the symbol to debug.h. * 3. Add entries for the class to struct debug_classes in debug.h. * 4. Add a FROB line for it in xemacs_debug_loop. */ -static Lisp_Object Qredisplay, Qbuffers, Qfaces, Qwindows, Qframes, Qdevices; - struct debug_classes active_debug_classes; enum debug_loop @@ -61,21 +59,21 @@ int flag = (op == X_ADD) ? 1 : 0; Lisp_Object retval = Qnil; -#define FROB(item) \ - if (op == X_LIST || op == X_ACTIVE || op == X_INIT || EQ (class_, Q##item)) \ - { \ - if (op == X_ADD || op == X_DELETE || op == X_INIT) \ - active_debug_classes.item = flag; \ - else if (op == X_LIST \ - || (op == X_ACTIVE && active_debug_classes.item)) \ - retval = Fcons (Q##item, retval); \ - else if (op == X_VALIDATE) \ - return Qt; \ - else if (op == X_SETTYPE) \ - active_debug_classes.types_of_##item = XINT (type); \ - else if (op == X_TYPE) \ - retval = make_int (active_debug_classes.types_of_##item); \ - if (op == X_INIT) active_debug_classes.types_of_##item = VALBITS; \ +#define FROB(item) \ + if (op == X_LIST || op == X_ACTIVE || op == X_INIT || EQ (class_, Q##item)) \ + { \ + if (op == X_ADD || op == X_DELETE || op == X_INIT) \ + active_debug_classes.item = flag; \ + else if (op == X_LIST \ + || (op == X_ACTIVE && active_debug_classes.item)) \ + retval = Fcons (Q##item, retval); \ + else if (op == X_VALIDATE) \ + return Qt; \ + else if (op == X_SETTYPE) \ + active_debug_classes.types_of_##item = XINT (type); \ + else if (op == X_TYPE) \ + retval = make_int (active_debug_classes.types_of_##item); \ + if (op == X_INIT) active_debug_classes.types_of_##item = VALBITS; \ } FROB (redisplay); @@ -187,13 +185,6 @@ void syms_of_debug (void) { - DEFSYMBOL (Qredisplay); - DEFSYMBOL (Qbuffers); - DEFSYMBOL (Qfaces); - DEFSYMBOL (Qwindows); - DEFSYMBOL (Qframes); - DEFSYMBOL (Qdevices); - DEFSUBR (Fadd_debug_class_to_check); DEFSUBR (Fdelete_debug_class_to_check); DEFSUBR (Fdebug_classes_being_checked); diff -r d9d08dc5e617 -r b531bf8658e9 src/dialog-msw.c --- a/src/dialog-msw.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/dialog-msw.c Fri Feb 21 06:57:21 2003 +0000 @@ -714,7 +714,8 @@ Lisp_Gui_Item *pgui_item = XGUI_ITEM (*gui_item); item_tem.style = (WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON - | (gui_item_active_p (*gui_item) ? 0 : WS_DISABLED)); + | (gui_item_active_p (*gui_item, 0) ? 0 : + WS_DISABLED)); item_tem.cx = button_width (pgui_item->name); /* Item ids are indices into dialog_items plus offset, to avoid having items by reserved ids (IDOK, IDCANCEL) */ diff -r d9d08dc5e617 -r b531bf8658e9 src/doprnt.c --- a/src/doprnt.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/doprnt.c Fri Feb 21 06:57:21 2003 +0000 @@ -358,7 +358,7 @@ } if (j == Dynarr_length (specs)) - syntax_error ("No conversion spec for argument", make_int (i)); + syntax_error ("No conversion spec for argument", make_int (i)); ch = spec->converter; @@ -431,10 +431,10 @@ /* allow too many args for string, but not too few */ if (nargs < get_args_needed (specs)) signal_error_1 (Qwrong_number_of_arguments, - list3 (Qformat, - make_int (nargs), - !NILP (format_reloc) ? format_reloc : - make_string (format_nonreloc, format_length))); + list3 (Qformat, + make_int (nargs), + !NILP (format_reloc) ? format_reloc : + make_string (format_nonreloc, format_length))); } else { diff -r d9d08dc5e617 -r b531bf8658e9 src/dynarr.c --- a/src/dynarr.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/dynarr.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ -/* Simple 'n' stupid dynamic-array module. +/* Support for dynamic arrays. Copyright (C) 1993 Sun Microsystems, Inc. - Copyright (C) 2002 Ben Wing. + Copyright (C) 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -155,7 +155,7 @@ { int newsize; double multiplier; - Dynarr *dy = (Dynarr *) d; + Dynarr *dy = (Dynarr *) Dynarr_verify (d); if (dy->max <= 8) multiplier = 2; @@ -180,11 +180,16 @@ Dynarr *dy = (Dynarr *) Dynarr_verify (d); Dynarr_resize (dy, dy->cur+len); +#if 0 + /* WTF? We should be catching these problems. */ /* Silently adjust start to be valid. */ if (start > dy->cur) start = dy->cur; else if (start < 0) start = 0; +#else + assert (start >= 0 && start <= dy->cur); +#endif if (start != dy->cur) { @@ -203,7 +208,7 @@ void Dynarr_delete_many (void *d, int start, int len) { - Dynarr *dy = (Dynarr *) d; + Dynarr *dy = (Dynarr *) Dynarr_verify (d); assert (start >= 0 && len >= 0 && start + len <= dy->cur); memmove ((char *) dy->base + start*dy->elsize, @@ -246,11 +251,11 @@ if (dy->base) { Bytecount malloc_used = malloced_storage_size (dy->base, - dy->elsize * dy->max, 0); + dy->elsize * dy->max, 0); /* #### This may or may not be correct. Some Dynarrs would prefer that we use dy->cur instead of dy->largest here. */ - int was_requested = dy->elsize * dy->largest; - int dynarr_overhead = dy->elsize * (dy->max - dy->largest); + Bytecount was_requested = dy->elsize * dy->largest; + Bytecount dynarr_overhead = dy->elsize * (dy->max - dy->largest); total += malloc_used; stats->was_requested += was_requested; diff -r d9d08dc5e617 -r b531bf8658e9 src/eval.c --- a/src/eval.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/eval.c Fri Feb 21 06:57:21 2003 +0000 @@ -404,7 +404,6 @@ #endif static int warning_will_be_discarded (Lisp_Object level); -static void check_proper_critical_section_nonlocal_exit_protection (void); /************************************************************************/ @@ -1442,6 +1441,34 @@ /* Non-local exits */ /************************************************************************/ +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS + +int +proper_redisplay_wrapping_in_place (void) +{ + return !in_display + || ((get_inhibit_flags () & INTERNAL_INHIBIT_ERRORS) + && (get_inhibit_flags () & INTERNAL_INHIBIT_THROWS)); +} + +static void +check_proper_critical_section_nonlocal_exit_protection (void) +{ + assert_with_message + (proper_redisplay_wrapping_in_place (), + "Attempted non-local exit from within redisplay without being properly wrapped"); +} + +static void +check_proper_critical_section_lisp_protection (void) +{ + assert_with_message + (proper_redisplay_wrapping_in_place (), + "Attempt to call Lisp code from within redisplay without being properly wrapped"); +} + +#endif /* ERROR_CHECK_TRAPPING_PROBLEMS */ + DEFUN ("catch", Fcatch, 1, UNEVALLED, 0, /* \(catch TAG BODY...): eval BODY allowing nonlocal exits using `throw'. TAG is evalled to get the tag to use. Then the BODY is executed. @@ -1613,7 +1640,9 @@ abort (); #endif +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS check_proper_critical_section_nonlocal_exit_protection (); +#endif /* If bomb_out_p is t, this is being called from Fsignal as a "last resort" when there is no handler for this error and @@ -2135,9 +2164,6 @@ #endif } -extern int in_display; -extern int gc_currently_forbidden; - /************************************************************************/ /* the workhorse error-signaling function */ @@ -2155,28 +2181,6 @@ { } -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - -static void -check_proper_critical_section_gc_protection (void) -{ - assert_with_message - (!in_display || gc_currently_forbidden, - "Potential GC from within redisplay without being properly wrapped"); -} - -#endif /* ERROR_CHECK_TRAPPING_PROBLEMS */ - -static void -check_proper_critical_section_nonlocal_exit_protection (void) -{ - assert_with_message - (!in_display - || ((get_inhibit_flags () & INTERNAL_INHIBIT_ERRORS) - && (get_inhibit_flags () & INTERNAL_INHIBIT_THROWS)), - "Attempted non-local exit from within redisplay without being properly wrapped"); -} - /* #### This function has not been synched with FSF. It diverges significantly. */ @@ -2234,7 +2238,9 @@ messy, difficult-to-debug ways. See enter_redisplay_critical_section(). */ +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS check_proper_critical_section_nonlocal_exit_protection (); +#endif conditions = Fget (error_symbol, Qerror_conditions, Qnil); @@ -3464,6 +3470,10 @@ int nargs; struct backtrace backtrace; +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS + check_proper_critical_section_lisp_protection (); +#endif + /* I think this is a pretty safe place to call Lisp code, don't you? */ while (!in_warnings && !NILP (Vpending_warnings) /* well, perhaps not so safe after all! */ @@ -3505,9 +3515,6 @@ } QUIT; -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - check_proper_critical_section_gc_protection (); -#endif if (need_to_garbage_collect) { struct gcpro gcpro1; @@ -3759,13 +3766,12 @@ Lisp_Object *fun_args = args + 1; Lisp_Object orig_fun; + /* QUIT will check for proper redisplay wrapping */ + QUIT; if (funcall_allocation_flag) { -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - check_proper_critical_section_gc_protection (); -#endif if (need_to_garbage_collect) /* Callers should gcpro lexpr args */ garbage_collect_1 (); @@ -4876,6 +4882,52 @@ call_trapping_problems_2, opaque); } +/* Turn on the trapping flags in FLAGS -- see call_trapping_problems(). + This cannot handle INTERNAL_INHIBIT_THROWS() or INTERNAL_INHIBIT_ERRORS + (because they ultimately boil down to a setjmp()!) -- you must directly + use call_trapping_problems() for that. Turn the flags off with + unbind_to(). Returns the "canonicalized" flags (particularly in the + case of INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY, which is shorthand for + various other flags). */ + +int +set_trapping_problems_flags (int flags) +{ + int new_inhibit_flags; + + if (flags & INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY) + flags |= INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION + | INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION + | INHIBIT_ENTERING_DEBUGGER + | INHIBIT_WARNING_ISSUE + | INHIBIT_GC; + + new_inhibit_flags = inhibit_flags | flags; + if (new_inhibit_flags != inhibit_flags) + internal_bind_int (&inhibit_flags, new_inhibit_flags); + + if (flags & INHIBIT_QUIT) + specbind (Qinhibit_quit, Qt); + + if (flags & UNINHIBIT_QUIT) + begin_do_check_for_quit (); + + if (flags & INHIBIT_GC) + begin_gc_forbidden (); + + /* #### If we have nested calls to call_trapping_problems(), and the + inner one creates some buffers/etc., should the outer one be able + to delete them? I think so, but it means we need to combine rather + than just reset the value. */ + if (flags & INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION) + internal_bind_lisp_object (&Vdeletable_permanent_display_objects, Qnil); + + if (flags & INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION) + internal_bind_lisp_object (&Vmodifiable_buffers, Qnil); + + return flags; +} + /* This is equivalent to (*fun) (arg), except that various conditions can be trapped or inhibited, according to FLAGS. @@ -5010,7 +5062,7 @@ Lisp_Object (*fun) (void *), void *arg) { - int speccount = specpdl_depth(); + int speccount = specpdl_depth (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; struct call_trapping_problems package; Lisp_Object opaque, thrown_tag, tem; @@ -5033,37 +5085,7 @@ package.data = Qnil; package.backtrace = Qnil; - if (flags & INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY) - flags |= INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION - | INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION - | INHIBIT_ENTERING_DEBUGGER - | INHIBIT_WARNING_ISSUE - | INHIBIT_GC; - - { - int new_inhibit_flags = inhibit_flags | flags; - if (new_inhibit_flags != inhibit_flags) - internal_bind_int (&inhibit_flags, new_inhibit_flags); - } - - if (flags & INHIBIT_QUIT) - specbind (Qinhibit_quit, Qt); - - if (flags & UNINHIBIT_QUIT) - begin_do_check_for_quit (); - - if (flags & INHIBIT_GC) - begin_gc_forbidden (); - - /* #### If we have nested calls to call_trapping_problems(), and the - inner one creates some buffers/etc., should the outer one be able - to delete them? I think so, but it means we need to combine rather - than just reset the value. */ - if (flags & INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION) - internal_bind_lisp_object (&Vdeletable_permanent_display_objects, Qnil); - - if (flags & INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION) - internal_bind_lisp_object (&Vmodifiable_buffers, Qnil); + flags = set_trapping_problems_flags (flags); if (flags & (INTERNAL_INHIBIT_THROWS | INTERNAL_INHIBIT_ERRORS)) opaque = make_opaque_ptr (&package); diff -r d9d08dc5e617 -r b531bf8658e9 src/event-Xt.c --- a/src/event-Xt.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/event-Xt.c Fri Feb 21 06:57:21 2003 +0000 @@ -1965,18 +1965,21 @@ case Expose: if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height) + event->xexpose.width, + event->xexpose.height) && !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height)) - x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); + redisplay_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, + event->xexpose.width, + event->xexpose.height); break; case GraphicsExpose: /* This occurs when an XCopyArea's source area was obscured or not available. */ - x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); + redisplay_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, + event->xexpose.width, + event->xexpose.height); break; case MapNotify: diff -r d9d08dc5e617 -r b531bf8658e9 src/event-msw.c --- a/src/event-msw.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/event-msw.c Fri Feb 21 06:57:21 2003 +0000 @@ -1323,6 +1323,7 @@ static void emacs_mswindows_drain_queue (void) { + /* This can call Lisp */ mswindows_drain_windows_queue (0); #ifdef HAVE_TTY drain_tty_devices (); @@ -2173,7 +2174,7 @@ if (!check_for_ignored_expose (frame, x, y, width, height)) { hold_ignored_expose_registration = 1; - mswindows_redraw_exposed_area (frame, x, y, width, height); + redisplay_redraw_exposed_area (frame, x, y, width, height); hold_ignored_expose_registration = 0; } EndPaint (hwnd, &paintStruct); @@ -4343,6 +4344,7 @@ static int emacs_mswindows_event_pending_p (int how_many) { + /* This can call Lisp */ if (!how_many) { mswindows_need_event (0); diff -r d9d08dc5e617 -r b531bf8658e9 src/event-stream.c --- a/src/event-stream.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/event-stream.c Fri Feb 21 06:57:21 2003 +0000 @@ -1882,6 +1882,7 @@ void event_stream_drain_queue (void) { + /* This can call Lisp */ if (event_stream && event_stream->drain_queue_cb) event_stream->drain_queue_cb (); } @@ -1890,6 +1891,7 @@ int detect_input_pending (int how_many) { + /* This can call Lisp */ Lisp_Object event; if (!NILP (Vunread_command_event)) @@ -1920,6 +1922,7 @@ */ ()) { + /* This can call Lisp */ return detect_input_pending (1) ? Qt : Qnil; } @@ -1977,6 +1980,7 @@ void event_stream_quit_p (void) { + /* This can call Lisp */ struct remove_quit_p_data data; /* Quit checking cannot happen in modal loop. Because it attempts to @@ -2173,6 +2177,7 @@ void run_pre_idle_hook (void) { + /* This can call Lisp */ if (!NILP (Vpre_idle_hook) && !detect_input_pending (1)) safe_run_hook_trapping_problems @@ -2615,6 +2620,7 @@ */ ()) { + /* This can call Lisp */ Lisp_Object concons; CONSOLE_LOOP (concons) diff -r d9d08dc5e617 -r b531bf8658e9 src/file-coding.c --- a/src/file-coding.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/file-coding.c Fri Feb 21 06:57:21 2003 +0000 @@ -2,7 +2,7 @@ #### rename me to coding-system.c or coding.c Copyright (C) 1991, 1995 Free Software Foundation, Inc. Copyright (C) 1995 Sun Microsystems, Inc. - Copyright (C) 2000, 2001, 2002 Ben Wing. + Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -4953,15 +4953,14 @@ Fdefine_coding_system_alias (intern ("no-conversion-mac"), intern ("raw-text-mac")); - /* These four below will get their defaults set correctly in - code-init.el. We init them now so we can handle stuff at dump + /* These three below will get their defaults set correctly + in code-init.el. We init them now so we can handle stuff at dump time before we get to code-init.el. */ - Fdefine_coding_system_alias (Qfile_name, Qbinary); - Fdefine_coding_system_alias (Qnative, Qfile_name); - + Fdefine_coding_system_alias (Qnative, Qbinary); Fdefine_coding_system_alias (Qterminal, Qbinary); Fdefine_coding_system_alias (Qkeyboard, Qbinary); + Fdefine_coding_system_alias (Qfile_name, Qnative); Fdefine_coding_system_alias (Qidentity, Qconvert_eol_lf); /* Need this for bootstrapping */ diff -r d9d08dc5e617 -r b531bf8658e9 src/frame-gtk.c --- a/src/frame-gtk.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/frame-gtk.c Fri Feb 21 06:57:21 2003 +0000 @@ -67,7 +67,6 @@ /* Default properties to use when creating frames. */ Lisp_Object Vdefault_gtk_frame_plist; -Lisp_Object Qwindow_id; Lisp_Object Qdetachable_menubar; Lisp_Object Qtext_widget; Lisp_Object Qcontainer_widget; @@ -1404,7 +1403,6 @@ void syms_of_frame_gtk (void) { - DEFSYMBOL (Qwindow_id); DEFSYMBOL (Qtext_widget); DEFSYMBOL (Qcontainer_widget); DEFSYMBOL (Qshell_widget); diff -r d9d08dc5e617 -r b531bf8658e9 src/frame-msw.c --- a/src/frame-msw.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/frame-msw.c Fri Feb 21 06:57:21 2003 +0000 @@ -341,6 +341,8 @@ rect.right = width; rect.bottom = height; + /* This can call Lisp, because it runs the window procedure, which can + call redisplay() */ AdjustWindowRectEx (&rect, qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_STYLE), GetMenu (FRAME_MSWINDOWS_HANDLE (f)) != NULL, diff -r d9d08dc5e617 -r b531bf8658e9 src/frame-x.c --- a/src/frame-x.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/frame-x.c Fri Feb 21 06:57:21 2003 +0000 @@ -67,7 +67,6 @@ /* Default properties to use when creating frames. */ Lisp_Object Vdefault_x_frame_plist; -Lisp_Object Qwindow_id; Lisp_Object Qx_resource_name; static const struct memory_description x_frame_data_description_1 [] = { @@ -2757,7 +2756,6 @@ void syms_of_frame_x (void) { - DEFSYMBOL (Qwindow_id); DEFSYMBOL (Qx_resource_name); DEFSUBR (Fx_window_id); diff -r d9d08dc5e617 -r b531bf8658e9 src/frame.c --- a/src/frame.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/frame.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ /* Generic frame functions. Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Copyright (C) 1995, 1996, 2002 Ben Wing. + Copyright (C) 1995, 1996, 2002, 2003 Ben Wing. Copyright (C) 1995 Sun Microsystems, Inc. This file is part of XEmacs. @@ -705,70 +705,6 @@ } -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - -static Lisp_Object -commit_ritual_suicide (Lisp_Object ceci_nest_pas_une_pipe) -{ - assert (!in_display); - return Qnil; -} - -#endif - -/* - * window size changes are held up during critical regions. Afterwards, - * we want to deal with any delayed changes. - */ -int -enter_redisplay_critical_section (void) -{ - int depth = specpdl_depth (); - - /* NOTE NOTE NOTE: Inside the redisplay critical section, every place - that could QUIT or call Lisp code needs to be wrapped, since GC - or a non-local exit will be fatal. The way to do this is with - call_trapping_problems(..., INHIBIT_GC), or the like. */ - -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - /* Force every call to QUIT to check for in_displayness. This will - verify proper wrapping, as in the previous comment, aborting if not. */ - something_happened++; - record_unwind_protect (commit_ritual_suicide, Qnil); -#endif - begin_gc_forbidden (); - in_display = 1; - - return depth; -} - -void -exit_redisplay_critical_section (int depth) -{ - Lisp_Object frmcons, devcons, concons; - - in_display = 0; - - unbind_to (depth); -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - something_happened--; -#endif - - /* we used to have a function to do this for only one frame, and - it was typical to call it at the end of a critical section - (which occurs once per frame); but what then happens if multiple - frames have frame changes held up? - - this means we are O(N^2) over frames. i seriously doubt it matters. - --ben */ - FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) - { - struct frame *f = XFRAME (XCAR (frmcons)); - if (f->size_change_pending) - change_frame_size (f, f->new_height, f->new_width, 0); - } -} - void invalidate_vertical_divider_cache_in_frame (struct frame *f) { @@ -785,10 +721,10 @@ void adjust_frame_size (struct frame *f) { + /* This can call Lisp. */ int keep_char_size = 0; Lisp_Object frame = wrap_frame (f); - if (!f->size_slipped) return; @@ -2316,9 +2252,9 @@ static void store_minibuf_frame_prop (struct frame *f, Lisp_Object val) { + /* This can call Lisp. */ Lisp_Object frame = wrap_frame (f); - if (WINDOWP (val)) { if (! MINI_WINDOW_P (XWINDOW (val))) @@ -2505,6 +2441,7 @@ */ (frame, plist)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); Lisp_Object tail; Lisp_Object *tailp; @@ -2816,8 +2753,9 @@ static void internal_set_frame_size (struct frame *f, int cols, int rows, int pretend) { + /* This can call Lisp. See mswindows_set_frame_size(). */ /* An explicit size change cancels any pending frame size adjustment */ - CLEAR_FRAME_SIZE_SLIPPED(f); + CLEAR_FRAME_SIZE_SLIPPED (f); if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size)) change_frame_size (f, rows, cols, 0); @@ -2832,6 +2770,7 @@ */ (frame, lines, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int height, width; frame = wrap_frame (f); @@ -2859,6 +2798,7 @@ */ (frame, height, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int pheight, width; frame = wrap_frame (f); @@ -2888,6 +2828,7 @@ */ (frame, height, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int pheight, width; frame = wrap_frame (f); @@ -2917,6 +2858,7 @@ */ (frame, cols, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int width, height; frame = wrap_frame (f); @@ -2944,6 +2886,7 @@ */ (frame, width, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int height, pwidth; frame = wrap_frame (f); @@ -2972,6 +2915,7 @@ */ (frame, width, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int height, pwidth; frame = wrap_frame (f); @@ -3000,6 +2944,7 @@ */ (frame, cols, rows, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int height, width; frame = wrap_frame (f); @@ -3025,6 +2970,7 @@ */ (frame, width, height, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int pheight, pwidth; frame = wrap_frame (f); @@ -3054,6 +3000,7 @@ */ (frame, width, height, pretend)) { + /* This can call Lisp. */ struct frame *f = decode_frame (frame); int pheight, pwidth; frame = wrap_frame (f); @@ -3264,7 +3211,7 @@ update code relies on this function to cause window `top' and `left' coordinates to be recomputed even though no frame size change occurs. --kyle */ - if (in_display) + if (in_display || hold_frame_size_changes) abort (); frame = wrap_frame (f); @@ -3439,7 +3386,7 @@ --andy. */ MARK_FRAME_SIZE_CHANGED (f); - if (delay || in_display || gc_in_progress) + if (delay || hold_frame_size_changes || gc_in_progress) { f->new_width = newwidth; f->new_height = newheight; diff -r d9d08dc5e617 -r b531bf8658e9 src/frame.h --- a/src/frame.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/frame.h Fri Feb 21 06:57:21 2003 +0000 @@ -138,8 +138,6 @@ void adjust_frame_size (struct frame *frame); void frame_size_slipped (Lisp_Object specifier, struct frame *f, Lisp_Object oldval); -int enter_redisplay_critical_section (void); -void exit_redisplay_critical_section (int); void select_frame_1 (Lisp_Object frame); void select_frame_2 (Lisp_Object frame); struct frame *selected_frame (void); diff -r d9d08dc5e617 -r b531bf8658e9 src/general-slots.h --- a/src/general-slots.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/general-slots.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ /* Commonly-used symbols -- include file Copyright (C) 1995 Sun Microsystems. - Copyright (C) 1995, 1996, 2000, 2001, 2002 Ben Wing. + Copyright (C) 1995, 1996, 2000, 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -63,6 +63,7 @@ SYMBOL (Qbottom); SYMBOL (Qbottom_margin); SYMBOL (Qbuffer); +SYMBOL (Qbuffers); SYMBOL (Qbuilt_in); SYMBOL (Qbutton); SYMBOL_KEYWORD (Q_buttons); @@ -99,6 +100,7 @@ SYMBOL (Qdescription); SYMBOL_KEYWORD (Q_descriptor); SYMBOL (Qdevice); +SYMBOL (Qdevices); SYMBOL_KEYWORD (Q_device); SYMBOL (Qdialog); SYMBOL (Qdirectory); @@ -118,12 +120,14 @@ SYMBOL (Qextents); SYMBOL (Qexternal); SYMBOL (Qface); +SYMBOL (Qfaces); SYMBOL (Qfallback); SYMBOL (Qfile); SYMBOL (Qfile_name); SYMBOL_KEYWORD (Q_filter); SYMBOL (Qfont); SYMBOL (Qframe); +SYMBOL (Qframes); SYMBOL (Qfrom_page); SYMBOL (Qfull_assoc); SYMBOL (Qfuncall); @@ -225,6 +229,7 @@ SYMBOL (Qradio); SYMBOL (Qrassoc); SYMBOL (Qrassq); +SYMBOL (Qredisplay); SYMBOL (Qremove_all); SYMBOL (Qrequire); SYMBOL (Qresource); @@ -280,6 +285,8 @@ SYMBOL (Qwidth); SYMBOL_KEYWORD (Q_width); SYMBOL (Qwindow); +SYMBOL (Qwindows); +SYMBOL (Qwindow_id); SYMBOL (Qwindow_system); SYMBOL (Qx); SYMBOL (Qy); diff -r d9d08dc5e617 -r b531bf8658e9 src/glyphs-gtk.c --- a/src/glyphs-gtk.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/glyphs-gtk.c Fri Feb 21 06:57:21 2003 +0000 @@ -2452,7 +2452,7 @@ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) { - if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) + if (gui_item_equal_sans_selected (XCAR (rest), selected, 0, 1)) { Lisp_Object old_selected =gui_item_list_find_selected (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); @@ -2494,17 +2494,21 @@ char *c_name = NULL; if (!STRINGP (pgui->name)) - pgui->name = Feval (pgui->name); - - CHECK_STRING (pgui->name); - - TO_EXTERNAL_FORMAT (LISP_STRING, pgui->name, - C_STRING_ALLOCA, c_name, - Qctext); - - gtk_notebook_append_page (nb, - gtk_vbox_new (FALSE, 3), - gtk_label_new (c_name)); + pgui->name = eval_within_redisplay (pgui->name); + + if (!STRINGP (pgui->name)) + warn_when_safe (Qredisplay, Qwarning, + "Name does not evaluate to string"); + else + { + TO_EXTERNAL_FORMAT (LISP_STRING, pgui->name, + C_STRING_ALLOCA, c_name, + Qctext); + + gtk_notebook_append_page (nb, + gtk_vbox_new (FALSE, 3), + gtk_label_new (c_name)); + } } /* Show all the new widgets we just added... */ diff -r d9d08dc5e617 -r b531bf8658e9 src/glyphs-msw.c --- a/src/glyphs-msw.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/glyphs-msw.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ /* mswindows-specific glyph objects. Copyright (C) 1998, 1999, 2000 Andy Piper. - Copyright (C) 2001, 2002 Ben Wing. + Copyright (C) 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -2039,7 +2039,7 @@ if (CONSP (item)) item = XCAR (item); - if (gui_item_active_p (item)) + if (gui_item_active_p (item, 1)) qxeSetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), GWL_STYLE, style & ~WS_DISABLED); else @@ -2230,7 +2230,7 @@ CHECK_MSWINDOWS_DEVICE (device); - if (!gui_item_active_p (gui)) + if (!gui_item_active_p (gui, 0)) flags |= WS_DISABLED; style = pgui->style; @@ -2375,7 +2375,7 @@ wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); /* set the checked state */ - if (gui_item_selected_p (gui)) + if (gui_item_selected_p (gui, 0)) qxeSendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else qxeSendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); @@ -2401,7 +2401,7 @@ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); /* buttons checked or otherwise */ - if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii))) + if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii), 1)) qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else @@ -2643,7 +2643,7 @@ { int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i); assert (idx == i); - if (gui_item_selected_p (XCAR (rest))) + if (gui_item_selected_p (XCAR (rest), 0)) selected = i; i++; } @@ -2657,7 +2657,8 @@ /* This function can GC if IN_REDISPLAY is false. */ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); #ifdef DEBUG_WIDGET_OUTPUT - stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); + stderr_out ("tab control %p redisplayed\n", + IMAGE_INSTANCE_SUBWINDOW_ID (ii)); #endif if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) || @@ -2682,9 +2683,10 @@ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) { - if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) + if (gui_item_equal_sans_selected (XCAR (rest), selected, 0, 1)) { - Lisp_Object old_selected = gui_item_list_find_selected + Lisp_Object old_selected = + gui_item_list_find_selected (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); /* Pick up the new selected item. */ @@ -2699,7 +2701,7 @@ qxeSendMessage (wnd, TCM_SETCURSEL, i, 0); #ifdef DEBUG_WIDGET_OUTPUT stderr_out ("tab control %p selected item %d\n", - IMAGE_INSTANCE_SUBWINDOW_ID (ii), i); + IMAGE_INSTANCE_SUBWINDOW_ID (ii), i); #endif break; } @@ -2716,7 +2718,7 @@ { add_tab_item (image_instance, wnd, XCAR (rest), IMAGE_INSTANCE_FRAME (ii), i); - if (gui_item_selected_p (XCAR (rest))) + if (gui_item_selected_p (XCAR (rest), 1)) selected_idx = i; i++; } diff -r d9d08dc5e617 -r b531bf8658e9 src/glyphs-widget.c --- a/src/glyphs-widget.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/glyphs-widget.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,5 +1,6 @@ /* Widget-specific glyph objects. Copyright (C) 1998, 1999, 2000, 2002 Andy Piper. + Copyright (C) 2003 Ben Wing. This file is part of XEmacs. @@ -670,7 +671,8 @@ #### should just normalize the data. */ if (!NILP (glyph)) { - substitute_keyword_value (inst, Q_image, glyph_instantiator_to_glyph (glyph)); + substitute_keyword_value (inst, Q_image, + glyph_instantiator_to_glyph (glyph)); } return inst; @@ -989,8 +991,10 @@ } /* Determine whether only the order has changed for a tab. */ -int tab_control_order_only_changed (Lisp_Object image_instance) +int +tab_control_order_only_changed (Lisp_Object image_instance) { + /* Called within redisplay */ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); int found = 0, len, pending_len; Lisp_Object rest; @@ -1013,7 +1017,7 @@ XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) { if (gui_item_equal_sans_selected (XCAR (rest), - XCAR (pending_rest), 0)) + XCAR (pending_rest), 0, 1)) { found = 1; break; @@ -1362,49 +1366,51 @@ /* Work out minimum space we need to fit all the items. This could have been fixed by the user. */ - if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) { + if (IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP (ii)) + { if (!NILP (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii))) - { + { Lisp_Object dynamic_width = - Feval (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)); + eval_within_redisplay (IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (ii)); if (INTP (dynamic_width)) - *width = XINT (dynamic_width); - } + *width = XINT (dynamic_width); + } else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_HORIZONTAL) - { + { *width = maxpw + ((nitems + 1) * widget_instance_border_width (ii) + IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2; - } + } else - { + { *width = maxpw + 2 * (widget_instance_border_width (ii) * 2 + IMAGE_INSTANCE_MARGIN_WIDTH (ii)); - } + } } /* Work out vertical spacings. */ - if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) { + if (IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP (ii)) + { if (!NILP (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii))) - { + { Lisp_Object dynamic_height = - Feval (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)); + eval_within_redisplay (IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (ii)); if (INTP (dynamic_height)) - *height = XINT (dynamic_height); - } + *height = XINT (dynamic_height); + } else if (IMAGE_INSTANCE_SUBWINDOW_LOGICAL_LAYOUT (ii)) - { + { *height = nitems * luh + ph_adjust; - } + } else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii) == LAYOUT_VERTICAL) - { + { *height = maxph + ((nitems + 1) * widget_instance_border_width (ii) + IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; - } + } else - { + { *height = maxph + (2 * widget_instance_border_width (ii) + IMAGE_INSTANCE_MARGIN_WIDTH (ii)) * 2 + ph_adjust; - } + } } #ifdef DEBUG_WIDGET_OUTPUT stderr_out ("layout wants %dx%d\n", *width, *height); diff -r d9d08dc5e617 -r b531bf8658e9 src/glyphs-x.c --- a/src/glyphs-x.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/glyphs-x.c Fri Feb 21 06:57:21 2003 +0000 @@ -2,7 +2,7 @@ Copyright (C) 1993, 1994 Free Software Foundation, Inc. Copyright (C) 1995 Board of Trustees, University of Illinois. Copyright (C) 1995 Tinker Systems - Copyright (C) 1995, 1996, 2001, 2002 Ben Wing + Copyright (C) 1995, 1996, 2001, 2002, 2003 Ben Wing Copyright (C) 1995 Sun Microsystems Copyright (C) 1999, 2000, 2002 Andy Piper @@ -2466,7 +2466,8 @@ /* update the font. */ update_widget_face (wv, ii, domain); - wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii), + wid = lw_create_widget (type, wv->name, id, wv, + IMAGE_INSTANCE_X_CLIPWIDGET (ii), False, 0, popup_selection_callback, 0); IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; @@ -2545,7 +2546,8 @@ int ac =0; #ifdef LWLIB_WIDGETS_MOTIF XtSetArg (al [ac], XmNlabelType, XmPIXMAP); ac++; - XtSetArg (al [ac], XmNlabelPixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph));ac++; + XtSetArg (al [ac], XmNlabelPixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); + ac++; #else XtSetArg (al [ac], XtNpixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph)); ac++; #endif @@ -2597,9 +2599,10 @@ /* instantiate a progress gauge */ static void -x_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) +x_progress_gauge_instantiate (Lisp_Object image_instance, + Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); @@ -2662,7 +2665,8 @@ #endif static void -x_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, +x_tab_control_instantiate (Lisp_Object image_instance, + Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { @@ -2682,8 +2686,7 @@ { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) - || + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) || IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)) { /* If only the order has changed then simply select the first @@ -2700,11 +2703,12 @@ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) { - if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) + if (gui_item_equal_sans_selected (XCAR (rest), selected, 0, 1)) { /* There may be an encapsulated way of doing this, but I couldn't find it. */ - Lisp_Object old_selected =gui_item_list_find_selected + Lisp_Object old_selected = + gui_item_list_find_selected (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); Arg al [1]; char* name; @@ -2715,8 +2719,9 @@ name, Qnative); /* The name may contain a `.' which confuses XtNameToWidget, so we do it ourselves. */ - children = XtCompositeChildren (IMAGE_INSTANCE_X_WIDGET_ID (ii), - &num_children); + children = + XtCompositeChildren (IMAGE_INSTANCE_X_WIDGET_ID (ii), + &num_children); for (i = 0; i < num_children; i++) { if (!strcmp (XtName (children [i]), name)) diff -r d9d08dc5e617 -r b531bf8658e9 src/gtk-xemacs.c --- a/src/gtk-xemacs.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/gtk-xemacs.c Fri Feb 21 06:57:21 2003 +0000 @@ -298,7 +298,8 @@ { GtkXEmacs *x = GTK_XEMACS (widget); struct frame *f = GTK_XEMACS_FRAME (x); - gtk_redraw_exposed_area (f, area->x, area->y, area->width, area->height); + redisplay_redraw_exposed_area (f, area->x, area->y, area->width, + area->height); } static void @@ -355,7 +356,7 @@ /* Now draw the actual frame data */ if (!check_for_ignored_expose (f, a->x, a->y, a->width, a->height) && !find_matching_subwindow (f, a->x, a->y, a->width, a->height)) - gtk_redraw_exposed_area (f, a->x, a->y, a->width, a->height); + redisplay_redraw_exposed_area (f, a->x, a->y, a->width, a->height); return (TRUE); } diff -r d9d08dc5e617 -r b531bf8658e9 src/gui.c --- a/src/gui.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/gui.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ /* Generic GUI code. (menubars, scrollbars, toolbars, dialogs) Copyright (C) 1995 Board of Trustees, University of Illinois. - Copyright (C) 1995, 1996, 2000, 2001, 2002 Ben Wing. + Copyright (C) 1995, 1996, 2000, 2001, 2002, 2003 Ben Wing. Copyright (C) 1995 Sun Microsystems, Inc. Copyright (C) 1998 Free Software Foundation, Inc. @@ -33,6 +33,7 @@ #include "elhash.h" #include "gui.h" #include "menubar.h" +#include "redisplay.h" Lisp_Object Qmenu_no_selection_hook; Lisp_Object Vmenu_no_selection_hook; @@ -381,18 +382,33 @@ Fplist_put (plist, Q_value, pgui_item->value); } +static int +gui_item_value (Lisp_Object form, int in_redisplay) +{ + /* This function can call Lisp. */ + +#ifndef ERROR_CHECK_DISPLAY + /* Shortcut to avoid evaluating Qt/Qnil each time; but don't do it when + error-checking so we catch unprotected eval within redisplay quicker */ + if (NILP (form)) + return 0; + if (EQ (form, Qt)) + return 1; +#endif + if (in_redisplay) + return !NILP (eval_within_redisplay (form)); + else + return !NILP (Feval (form)); +} + /* * Decide whether a GUI item is active by evaluating its :active form * if any */ int -gui_item_active_p (Lisp_Object gui_item) +gui_item_active_p (Lisp_Object gui_item, int in_redisplay) { - /* This function can call lisp */ - - /* Shortcut to avoid evaluating Qt each time */ - return (EQ (XGUI_ITEM (gui_item)->active, Qt) - || !NILP (Feval (XGUI_ITEM (gui_item)->active))); + return gui_item_value (XGUI_ITEM (gui_item)->active, in_redisplay); } /* set menu accelerator key to first underlined character in menu name */ @@ -436,23 +452,20 @@ * if any */ int -gui_item_selected_p (Lisp_Object gui_item) +gui_item_selected_p (Lisp_Object gui_item, int in_redisplay) { - /* This function can call lisp */ - - /* Shortcut to avoid evaluating Qt each time */ - return (EQ (XGUI_ITEM (gui_item)->selected, Qt) - || !NILP (Feval (XGUI_ITEM (gui_item)->selected))); + return gui_item_value (XGUI_ITEM (gui_item)->selected, in_redisplay); } Lisp_Object gui_item_list_find_selected (Lisp_Object gui_item_list) { - /* This function can GC. */ + /* This function can call Lisp but cannot GC because it is called within + redisplay, and redisplay disables GC. */ Lisp_Object rest; LIST_LOOP (rest, gui_item_list) { - if (gui_item_selected_p (XCAR (rest))) + if (gui_item_selected_p (XCAR (rest), 1)) return XCAR (rest); } return XCAR (gui_item_list); @@ -470,8 +483,7 @@ Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item); /* Evaluate :included first. Shortcut to avoid evaluating Qt each time */ - if (!EQ (pgui_item->included, Qt) - && NILP (Feval (pgui_item->included))) + if (!gui_item_value (pgui_item->included, 0)) return 0; /* Do :config if conflist is given */ @@ -619,17 +631,33 @@ return id; } +static int +gui_value_equal (Lisp_Object a, Lisp_Object b, int depth, int in_redisplay) +{ + if (in_redisplay) + return internal_equal_trapping_problems + (Qredisplay, "Error calling function within redisplay", 0, 0, + /* say they're not equal in case of error; code calling + gui_item_equal_sans_selected() in redisplay does extra stuff + only when equal */ + 0, a, b, depth); + else + return internal_equal (a, b, depth); +} + int -gui_item_equal_sans_selected (Lisp_Object obj1, Lisp_Object obj2, int depth) +gui_item_equal_sans_selected (Lisp_Object obj1, Lisp_Object obj2, int depth, + int in_redisplay) { Lisp_Gui_Item *p1 = XGUI_ITEM (obj1); Lisp_Gui_Item *p2 = XGUI_ITEM (obj2); - if (!(internal_equal (p1->name, p2->name, depth + 1) + if (!(gui_value_equal (p1->name, p2->name, depth + 1, in_redisplay) && - internal_equal (p1->callback, p2->callback, depth + 1) + gui_value_equal (p1->callback, p2->callback, depth + 1, in_redisplay) && - internal_equal (p1->callback_ex, p2->callback_ex, depth + 1) + gui_value_equal (p1->callback_ex, p2->callback_ex, depth + 1, + in_redisplay) && EQ (p1->suffix, p2->suffix) && @@ -658,8 +686,7 @@ Lisp_Gui_Item *p1 = XGUI_ITEM (obj1); Lisp_Gui_Item *p2 = XGUI_ITEM (obj2); - if (!(gui_item_equal_sans_selected (obj1, obj2, depth) - && + if (!(gui_item_equal_sans_selected (obj1, obj2, depth, 0) && EQ (p1->selected, p2->selected))) return 0; return 1; diff -r d9d08dc5e617 -r b531bf8658e9 src/gui.h --- a/src/gui.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/gui.h Fri Feb 21 06:57:21 2003 +0000 @@ -29,7 +29,8 @@ int separator_string_p (const Ibyte *s); void get_gui_callback (Lisp_Object, Lisp_Object *, Lisp_Object *); -int gui_item_equal_sans_selected (Lisp_Object obj1, Lisp_Object obj2, int depth); +int gui_item_equal_sans_selected (Lisp_Object obj1, Lisp_Object obj2, + int depth, int in_redisplay); @@ -76,13 +77,13 @@ Lisp_Object gui_parse_item_keywords (Lisp_Object item); Lisp_Object gui_parse_item_keywords_no_errors (Lisp_Object item); void gui_add_item_keywords_to_plist (Lisp_Object plist, Lisp_Object gui_item); -int gui_item_active_p (Lisp_Object); -int gui_item_selected_p (Lisp_Object); +int gui_item_active_p (Lisp_Object, int); +int gui_item_selected_p (Lisp_Object, int); Lisp_Object gui_item_list_find_selected (Lisp_Object gui_item_list); -int gui_item_included_p (Lisp_Object, Lisp_Object into); +int gui_item_included_p (Lisp_Object, Lisp_Object into); Lisp_Object gui_item_accelerator (Lisp_Object gui_item); Lisp_Object gui_name_accelerator (Lisp_Object name); -int gui_item_id_hash (Lisp_Object, Lisp_Object gui_item, int); +int gui_item_id_hash (Lisp_Object, Lisp_Object gui_item, int); Lisp_Object gui_item_display_flush_left (Lisp_Object gui_item); Lisp_Object gui_item_display_flush_right (Lisp_Object gui_item); Lisp_Object allocate_gui_item (void); diff -r d9d08dc5e617 -r b531bf8658e9 src/gutter.c --- a/src/gutter.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/gutter.c Fri Feb 21 06:57:21 2003 +0000 @@ -335,10 +335,11 @@ calculate_gutter_size (struct window *w, enum gutter_pos pos) { struct frame* f = XFRAME (WINDOW_FRAME (w)); - int count; - display_line_dynarr* ddla; + display_line_dynarr *ddla; Lisp_Object ret = Qnil; + /* Callers need to handle this. */ + assert (!in_display); /* degenerate case */ if (NILP (RAW_WINDOW_GUTTER (w, pos)) || @@ -347,26 +348,31 @@ NILP (w->buffer)) return Qnil; - /* Redisplay code that we use relies on GC not happening. Make it - so. */ - count = begin_gc_forbidden (); + if (!in_display) + { + int count; + + /* We are calling directly into redisplay from the outside, so turn on + critical section protection. */ + count = enter_redisplay_critical_section (); - ddla = Dynarr_new (display_line); - /* generate some display lines */ - generate_displayable_area (w, WINDOW_GUTTER (w, pos), - FRAME_LEFT_BORDER_END (f), - FRAME_TOP_BORDER_END (f), - FRAME_RIGHT_BORDER_START (f) - - FRAME_LEFT_BORDER_END (f), - FRAME_BOTTOM_BORDER_START (f) - - FRAME_TOP_BORDER_END (f), - ddla, 0, 0); + ddla = Dynarr_new (display_line); + /* generate some display lines */ + generate_displayable_area (w, WINDOW_GUTTER (w, pos), + FRAME_LEFT_BORDER_END (f), + FRAME_TOP_BORDER_END (f), + FRAME_RIGHT_BORDER_START (f) + - FRAME_LEFT_BORDER_END (f), + FRAME_BOTTOM_BORDER_START (f) + - FRAME_TOP_BORDER_END (f), + ddla, 0, 0); - /* Let GC happen again. */ - unbind_to (count); + /* Let GC happen again. */ + exit_redisplay_critical_section (count); - ret = make_int (calculate_gutter_size_from_display_lines (pos, ddla)); - free_display_lines (ddla); + ret = make_int (calculate_gutter_size_from_display_lines (pos, ddla)); + free_display_lines (ddla); + } return ret; } @@ -693,17 +699,13 @@ int height) { enum gutter_pos pos; - int depth; - /* We have to be "in display" when we output the gutter - make it - so. */ - depth = enter_redisplay_critical_section (); + /* We are already inside the critical section -- our caller did that. */ GUTTER_POS_LOOP (pos) { if (FRAME_GUTTER_VISIBLE (f, pos)) redraw_exposed_gutter (f, pos, x, y, width, height); } - exit_redisplay_critical_section (depth); } void @@ -749,13 +751,12 @@ if (cur != new) { - int depth; - /* 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 */ - depth = enter_redisplay_critical_section (); + int depth = begin_hold_frame_size_changes (); + set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil))); set_specifier_fallback (Vgutter[new], Vdefault_gutter); set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero))); @@ -769,9 +770,9 @@ Vdefault_gutter_border_width); set_specifier_fallback (Vgutter_visible_p[cur], list1 (Fcons (Qnil, Qt))); set_specifier_fallback (Vgutter_visible_p[new], Vdefault_gutter_visible_p); + Vdefault_gutter_position = position; - Vdefault_gutter_position = position; - exit_redisplay_critical_section (depth); + unbind_to (depth); } run_hook (Qdefault_gutter_position_changed_hook); @@ -885,21 +886,39 @@ Fset_specifier_dirty_flag (real_one[pos]); } +static void gutter_specs_changed (Lisp_Object specifier, struct window *w, + Lisp_Object oldval, enum gutter_pos pos); + +static void +gutter_specs_changed_1 (Lisp_Object arg) +{ + gutter_specs_changed (X1ST (arg), XWINDOW (X2ND (arg)), + X3RD (arg), (enum gutter_pos) XINT (X4TH (arg))); + free_list (arg); +} + static void gutter_specs_changed (Lisp_Object specifier, struct window *w, - Lisp_Object oldval, enum gutter_pos pos) + Lisp_Object oldval, enum gutter_pos pos) { - w->real_gutter[pos] = construct_window_gutter_spec (w, pos); - w->real_gutter_size[pos] = w->gutter_size[pos]; + if (in_display) + register_post_redisplay_action (gutter_specs_changed_1, + list4 (specifier, wrap_window (w), + oldval, make_int (pos))); + else + { + w->real_gutter[pos] = construct_window_gutter_spec (w, pos); + w->real_gutter_size[pos] = w->gutter_size[pos]; - if (EQ (w->real_gutter_size[pos], Qautodetect) - && !NILP (w->gutter_visible_p[pos])) - { - w->real_gutter_size [pos] = calculate_gutter_size (w, pos); + if (EQ (w->real_gutter_size[pos], Qautodetect) + && !NILP (w->gutter_visible_p[pos])) + { + w->real_gutter_size [pos] = calculate_gutter_size (w, pos); + } + MARK_GUTTER_CHANGED; + MARK_MODELINE_CHANGED; + MARK_WINDOWS_CHANGED (w); } - MARK_GUTTER_CHANGED; - MARK_MODELINE_CHANGED; - MARK_WINDOWS_CHANGED (w); } /* We define all of these so we can access which actual gutter changed. */ @@ -938,24 +957,43 @@ recompute_overlaying_specifier (Vgutter); } +static void gutter_geometry_changed_in_window (Lisp_Object specifier, + struct window *w, + Lisp_Object oldval); + +static void +gutter_geometry_changed_in_window_1 (Lisp_Object arg) +{ + gutter_geometry_changed_in_window (X1ST (arg), XWINDOW (X2ND (arg)), + X3RD (arg)); + free_list (arg); +} + static void gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w, Lisp_Object oldval) { - enum gutter_pos pos; - GUTTER_POS_LOOP (pos) + if (in_display) + register_post_redisplay_action (gutter_geometry_changed_in_window_1, + list3 (specifier, wrap_window (w), + oldval)); + else { - w->real_gutter_size[pos] = w->gutter_size[pos]; - if (EQ (w->real_gutter_size[pos], Qautodetect) - && !NILP (w->gutter_visible_p[pos])) + enum gutter_pos pos; + GUTTER_POS_LOOP (pos) { - w->real_gutter_size [pos] = calculate_gutter_size (w, pos); + w->real_gutter_size[pos] = w->gutter_size[pos]; + if (EQ (w->real_gutter_size[pos], Qautodetect) + && !NILP (w->gutter_visible_p[pos])) + { + w->real_gutter_size [pos] = calculate_gutter_size (w, pos); + } } - } - MARK_GUTTER_CHANGED; - MARK_MODELINE_CHANGED; - MARK_WINDOWS_CHANGED (w); + MARK_GUTTER_CHANGED; + MARK_MODELINE_CHANGED; + MARK_WINDOWS_CHANGED (w); + } } static void @@ -1055,6 +1093,10 @@ { Lisp_Object devcons, concons; + /* Can't reentrantly enter redisplay */ + if (in_display) + return Qnil; + DEVICE_LOOP_NO_BREAK (devcons, concons) { struct device *d = XDEVICE (XCAR (devcons)); diff -r d9d08dc5e617 -r b531bf8658e9 src/lisp.h --- a/src/lisp.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/lisp.h Fri Feb 21 06:57:21 2003 +0000 @@ -54,7 +54,7 @@ /* general definitions */ /************************************************************************/ -/* ------------------------ include files ------------------- */ +/* -------------------------- include files --------------------- */ /* We include the following generally useful header files so that you don't have to worry about prototypes when using the standard C @@ -70,7 +70,7 @@ #include #include -/* --------------------- error-checking sublevels --------------------- */ +/* -------------------------- error-checking ------------------------ */ /* The large categories established by configure can be subdivided into smaller subcategories, for problems in specific modules. You can't @@ -85,6 +85,51 @@ #define ERROR_CHECK_TRAPPING_PROBLEMS #endif +#ifdef ERROR_CHECK_TYPES +#define type_checking_assert(assertion) assert (assertion) +#define type_checking_assert_at_line(assertion, file, line) \ + assert_at_line (assertion, file, line) +#define type_checking_assert_with_message(assertion, msg) \ + assert_with_message (assertion, msg) +#else +#define type_checking_assert(assertion) +#define type_checking_assert_at_line(assertion, file, line) +#define type_checking_assert_with_message(assertion, msg) +#endif +#ifdef ERROR_CHECK_GC +#define gc_checking_assert(assertion) assert (assertion) +#define gc_checking_assert_at_line(assertion, file, line) \ + assert_at_line (assertion, file, line) +#define gc_checking_assert_with_message(assertion, msg) \ + assert_with_message (assertion, msg) +#else +#define gc_checking_assert(assertion) +#define gc_checking_assert_at_line(assertion, file, line) +#define gc_checking_assert_with_message(assertion, msg) +#endif +#ifdef ERROR_CHECK_TEXT +#define text_checking_assert(assertion) assert (assertion) +#define text_checking_assert_at_line(assertion, file, line) \ + assert_at_line (assertion, file, line) +#define text_checking_assert_with_message(assertion, msg) \ + assert_with_message (assertion, msg) +#else +#define text_checking_assert(assertion) +#define text_checking_assert_at_line(assertion, file, line) +#define text_checking_assert_with_message(assertion, msg) +#endif +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS +#define trapping_problems_checking_assert(assertion) assert (assertion) +#define trapping_problems_checking_assert_at_line(assertion, file, line) \ + assert_at_line (assertion, file, line) +#define trapping_problems_checking_assert_with_message(assertion, msg) \ + assert_with_message (assertion, msg) +#else +#define trapping_problems_checking_assert(assertion) +#define trapping_problems_checking_assert_at_line(assertion, file, line) +#define trapping_problems_checking_assert_with_message(assertion, msg) +#endif + /* ------------------------ definition of EMACS_INT ------------------- */ /* EMACS_INT is the underlying integral type into which a Lisp_Object must fit. @@ -578,7 +623,7 @@ /* Basic declaration at the top of all X-position classes (that can refer to buffers or strings). CL1 and CL2 are the equivalent more specific - classes referring only to buffers or strings, respefitvely. */ + classes referring only to buffers or strings, respectively. */ #define DECLARE_XPOS_CLASS(cl, countcl, cl1, cl2) \ DECLARE_INTCLASS (cl) \ @@ -1114,6 +1159,15 @@ (need_to_check_c_alloca ? xemacs_c_alloca (0) : 0, \ alloca (__temp_alloca_size__))) +/* Version of ALLOCA() that is guaranteed to work inside of function calls + (i.e., we call the C alloca if regular alloca() is broken inside of + function calls). */ +#ifdef BROKEN_ALLOCA_IN_FUNCTION_CALLS +#define ALLOCA_FUNCALL_OK(size) xemacs_c_alloca (size) +#else +#define ALLOCA_FUNCALL_OK(size) ALLOCA (size) +#endif + /* WARNING: If you use this, you must unbind_to() at the end of your function! */ @@ -1157,12 +1211,22 @@ /* ------------------------ dynamic arrays ------------------- */ +#ifdef ERROR_CHECK_STRUCTURES +#define Dynarr_declare(type) \ + type *base; \ + int locked; \ + int elsize; \ + int cur; \ + int largest; \ + int max +#else #define Dynarr_declare(type) \ type *base; \ int elsize; \ int cur; \ int largest; \ int max +#endif /* ERROR_CHECK_STRUCTURES */ typedef struct dynarr { @@ -1196,58 +1260,75 @@ return dy; } +DECLARE_INLINE_HEADER ( +Dynarr * +Dynarr_verify_mod_1 (void *d, const char *file, int line) +) +{ + Dynarr *dy = (Dynarr *) d; + assert_at_line (!dy->locked, file, line); + assert_at_line (dy->cur >= 0 && dy->cur <= dy->largest && + dy->largest <= dy->max, file, line); + return dy; +} + #define Dynarr_verify(d) Dynarr_verify_1 (d, __FILE__, __LINE__) +#define Dynarr_verify_mod(d) Dynarr_verify_mod_1 (d, __FILE__, __LINE__) +#define Dynarr_lock(d) (Dynarr_verify_mod (d)->locked = 1) +#define Dynarr_unlock(d) ((d)->locked = 0) #else #define Dynarr_verify(d) (d) +#define Dynarr_verify_mod(d) (d) +#define Dynarr_lock(d) +#define Dynarr_unlock(d) #endif /* ERROR_CHECK_STRUCTURES */ #define Dynarr_length(d) (Dynarr_verify (d)->cur) #define Dynarr_largest(d) (Dynarr_verify (d)->largest) -#define Dynarr_reset(d) (Dynarr_verify (d)->cur = 0) +#define Dynarr_reset(d) (Dynarr_verify_mod (d)->cur = 0) #define Dynarr_add_many(d, el, len) Dynarr_insert_many (d, el, len, (d)->cur) #define Dynarr_insert_many_at_start(d, el, len) \ Dynarr_insert_many (d, el, len, 0) #define Dynarr_add_literal_string(d, s) Dynarr_add_many (d, s, sizeof (s) - 1) -#define Dynarr_add_lisp_string(d, s, codesys) \ -do { \ - Lisp_Object dyna_ls_s = (s); \ - Lisp_Object dyna_ls_cs = (codesys); \ - Extbyte *dyna_ls_eb; \ - Bytecount dyna_ls_bc; \ - \ - TO_EXTERNAL_FORMAT (LISP_STRING, dyna_ls_s, \ - ALLOCA, (dyna_ls_eb, dyna_ls_bc), \ - dyna_ls_cs); \ - Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc); \ +#define Dynarr_add_lisp_string(d, s, codesys) \ +do { \ + Lisp_Object dyna_ls_s = (s); \ + Lisp_Object dyna_ls_cs = (codesys); \ + Extbyte *dyna_ls_eb; \ + Bytecount dyna_ls_bc; \ + \ + LISP_STRING_TO_SIZED_EXTERNAL (dyna_ls_s, dyna_ls_eb, \ + dyna_ls_bc, dyna_ls_cs); \ + Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc); \ } while (0) -#define Dynarr_add(d, el) ( \ - Dynarr_verify (d)->cur >= (d)->max ? Dynarr_resize ((d), (d)->cur+1) : \ - (void) 0, \ - ((d)->base)[(d)->cur++] = (el), \ +#define Dynarr_add(d, el) ( \ + Dynarr_verify_mod (d)->cur >= (d)->max ? Dynarr_resize ((d), (d)->cur+1) : \ + (void) 0, \ + ((d)->base)[(d)->cur++] = (el), \ (d)->cur > (d)->largest ? (d)->largest = (d)->cur : (int) 0) /* The following defines will get you into real trouble if you aren't careful. But they can save a lot of execution time when used wisely. */ -#define Dynarr_increment(d) ((d)->cur++) -#define Dynarr_set_size(d, n) ((d)->cur = n) - -#define Dynarr_pop(d) \ - (assert ((d)->cur > 0), (d)->cur--, Dynarr_at (d, (d)->cur)) -#define Dynarr_delete(d, i) Dynarr_delete_many (d, i, len) +#define Dynarr_increment(d) (Dynarr_verify_mod (d)->cur++) +#define Dynarr_set_size(d, n) (Dynarr_verify_mod (d)->cur = n) + +#define Dynarr_pop(d) \ + (assert ((d)->cur > 0), Dynarr_verify_mod (d)->cur--, \ + Dynarr_at (d, (d)->cur)) +#define Dynarr_delete(d, i) Dynarr_delete_many (d, i, 1) #define Dynarr_delete_by_pointer(d, p) \ Dynarr_delete_many (d, (p) - ((d)->base), 1) -#define Dynarr_delete_object(d, el) \ -do { \ - if (d != NULL) { \ - REGISTER int i; \ - for (i = Dynarr_length (d) - 1; i >= 0; i--) { \ - if (el == Dynarr_at (d, i)) { \ - Dynarr_delete_many (d, i, 1); \ - } \ - } \ - } \ +#define Dynarr_delete_object(d, el) \ +do \ +{ \ + REGISTER int i; \ + for (i = Dynarr_length (d) - 1; i >= 0; i--) \ + { \ + if (el == Dynarr_at (d, i)) \ + Dynarr_delete_many (d, i, 1); \ + } \ } while (0) #ifdef MEMORY_USAGE_STATS @@ -1633,6 +1714,23 @@ #define cons_cdr(a) ((a)->cdr_) #define XCAR(a) (XCONS (a)->car_) #define XCDR(a) (XCONS (a)->cdr_) +#define XCADR(a) (XCAR (XCDR (a))) +#define XCDDR(a) (XCDR (XCDR (a))) +#define XCADDR(a) (XCAR (XCDDR (a))) +#define XCDDDR(a) (XCDR (XCDDR (a))) +#define XCADDDR(a) (XCAR (XCDDDR (a))) +#define XCDDDDR(a) (XCDR (XCDDDR (a))) +#define XCADDDDR(a) (XCAR (XCDDDDR (a))) +#define XCDDDDDR(a) (XCDR (XCDDDDR (a))) +#define XCADDDDDR(a) (XCAR (XCDDDDDR (a))) +#define XCDDDDDDR(a) (XCDR (XCDDDDDR (a))) +#define X1ST(a) XCAR (a) +#define X2ND(a) XCADR (a) +#define X3RD(a) XCADDR (a) +#define X4TH(a) XCADDDR (a) +#define X5TH(a) XCADDDDR (a) +#define X6TH(a) XCADDDDDR (a) + #define XSETCAR(a, b) (XCONS (a)->car_ = (b)) #define XSETCDR(a, b) (XCONS (a)->cdr_ = (b)) #define LISTP(x) (CONSP(x) || NILP(x)) @@ -3959,6 +4057,7 @@ Lisp_Object handler_arg, Lisp_Object (*fun) (Lisp_Object), Lisp_Object arg); +int set_trapping_problems_flags (int flags); Lisp_Object call_trapping_problems (Lisp_Object warning_class, const char *warning_string, int flags, @@ -4018,6 +4117,7 @@ Lisp_Object, Error_Behavior, int, ...); /* C Code should be using internal_catch, record_unwind_p, condition_case_1 */ +int proper_redisplay_wrapping_in_place (void); Lisp_Object internal_catch (Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object, int * volatile, Lisp_Object * volatile); diff -r d9d08dc5e617 -r b531bf8658e9 src/menubar-msw.c --- a/src/menubar-msw.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/menubar-msw.c Fri Feb 21 06:57:21 2003 +0000 @@ -274,7 +274,7 @@ goto done; } - if (!gui_item_active_p (gui_item)) + if (!gui_item_active_p (gui_item, 0)) item_info.fState = MFS_GRAYED; /* Temptation is to put 'else' right here. Although, the displayed item won't have an arrow indicating that it is a @@ -329,7 +329,7 @@ if (!STRINGP (pgui_item->name)) pgui_item->name = Feval (pgui_item->name); - if (!gui_item_active_p (gui_item)) + if (!gui_item_active_p (gui_item, 0)) item_info.fState = MFS_GRAYED; style = (NILP (pgui_item->selected) || NILP (Feval (pgui_item->selected)) diff -r d9d08dc5e617 -r b531bf8658e9 src/menubar.c --- a/src/menubar.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/menubar.c Fri Feb 21 06:57:21 2003 +0000 @@ -202,7 +202,7 @@ desc = menu_parse_submenu_keywords (desc, gui_item); /* Check that this (sub)menu is active */ - if (!gui_item_active_p (gui_item)) + if (!gui_item_active_p (gui_item, 0)) RETURN_UNGCPRO (Qnil); /* Apply :filter */ diff -r d9d08dc5e617 -r b531bf8658e9 src/redisplay-gtk.c --- a/src/redisplay-gtk.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/redisplay-gtk.c Fri Feb 21 06:57:21 2003 +0000 @@ -2,7 +2,7 @@ Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1994 Lucid, Inc. Copyright (C) 1995 Sun Microsystems, Inc. - Copyright (C) 2002 Ben Wing. + Copyright (C) 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -73,10 +73,6 @@ static void gtk_output_horizontal_line (struct window *w, struct display_line *dl, struct rune *rb); -static void gtk_redraw_exposed_window (struct window *w, int x, int y, - int width, int height); -static void gtk_redraw_exposed_windows (Lisp_Object window, int x, int y, - int width, int height); static void gtk_clear_region (Lisp_Object locale, struct device* d, struct frame* f, face_index findex, int x, int y, int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, @@ -1469,133 +1465,6 @@ } } -/***************************************************************************** - gtk_redraw_exposed_window - - Given a bounding box for an area that needs to be redrawn, determine - what parts of what lines are contained within and re-output their - contents. - ****************************************************************************/ -static void -gtk_redraw_exposed_window (struct window *w, int x, int y, int width, int height) -{ - struct frame *f = XFRAME (w->frame); - int line; - int start_x, start_y, end_x, end_y; - int orig_windows_structure_changed; - - display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); - - if (!NILP (w->vchild)) - { - gtk_redraw_exposed_windows (w->vchild, x, y, width, height); - return; - } - else if (!NILP (w->hchild)) - { - gtk_redraw_exposed_windows (w->hchild, x, y, width, height); - return; - } - - /* If the window doesn't intersect the exposed region, we're done here. */ - if (x >= WINDOW_RIGHT (w) || (x + width) <= WINDOW_LEFT (w) - || y >= WINDOW_BOTTOM (w) || (y + height) <= WINDOW_TOP (w)) - { - return; - } - else - { - start_x = max (WINDOW_LEFT (w), x); - end_x = min (WINDOW_RIGHT (w), (x + width)); - start_y = max (WINDOW_TOP (w), y); - end_y = min (WINDOW_BOTTOM (w), y + height); - - /* We do this to make sure that the 3D modelines get redrawn if - they are in the exposed region. */ - orig_windows_structure_changed = f->windows_structure_changed; - f->windows_structure_changed = 1; - } - - if (window_needs_vertical_divider (w)) - { - gtk_output_vertical_divider (w, 0); - } - - for (line = 0; line < Dynarr_length (cdla); line++) - { - struct display_line *cdl = Dynarr_atp (cdla, line); - int top_y = cdl->ypos - cdl->ascent; - int bottom_y = cdl->ypos + cdl->descent; - - if (bottom_y >= start_y) - { - if (top_y > end_y) - { - if (line == 0) - continue; - else - break; - } - else - { - output_display_line (w, 0, cdla, line, start_x, end_x); - } - } - } - - f->windows_structure_changed = orig_windows_structure_changed; - - /* If there have never been any face cache_elements created, then this - expose event doesn't actually have anything to do. */ - if (Dynarr_largest (w->face_cachels)) - redisplay_clear_bottom_of_window (w, cdla, start_y, end_y); -} - -/***************************************************************************** - gtk_redraw_exposed_windows - - For each window beneath the given window in the window hierarchy, - ensure that it is redrawn if necessary after an Expose event. - ****************************************************************************/ -static void -gtk_redraw_exposed_windows (Lisp_Object window, int x, int y, int width, - int height) -{ - for (; !NILP (window); window = XWINDOW (window)->next) - gtk_redraw_exposed_window (XWINDOW (window), x, y, width, height); -} - -/***************************************************************************** - gtk_redraw_exposed_area - - For each window on the given frame, ensure that any area in the - Exposed area is redrawn. - ****************************************************************************/ -void -gtk_redraw_exposed_area (struct frame *f, int x, int y, int width, int height) -{ - /* If any window on the frame has had its face cache reset then the - redisplay structures are effectively invalid. If we attempt to - use them we'll blow up. We mark the frame as changed to ensure - that redisplay will do a full update. This probably isn't - necessary but it can't hurt. */ - -#ifdef HAVE_TOOLBARS - /* #### We would rather put these off as well but there is currently - no combination of flags which will force an unchanged toolbar to - redraw anyhow. */ - MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); -#endif - redraw_exposed_gutters (f, x, y, width, height); - - if (!f->window_face_cache_reset) - { - gtk_redraw_exposed_windows (f->root_window, x, y, width, height); - } - else - MARK_FRAME_CHANGED (f); -} - /**************************************************************************** gtk_clear_region diff -r d9d08dc5e617 -r b531bf8658e9 src/redisplay-msw.c --- a/src/redisplay-msw.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/redisplay-msw.c Fri Feb 21 06:57:21 2003 +0000 @@ -2,7 +2,7 @@ Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1994 Lucid, Inc. Copyright (C) 1995 Sun Microsystems, Inc. - Copyright (C) 2001, 2002 Ben Wing. + Copyright (C) 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -63,8 +63,6 @@ static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, int under, int strike); static void mswindows_output_vertical_divider (struct window *w, int clear); -static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, - int y, int width, int height); static void mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, struct display_box *db, @@ -714,8 +712,10 @@ * to by PRC, and paints only the intersection */ static void -mswindows_redisplay_deadbox_maybe (struct window *w, const RECT *prc) +mswindows_redisplay_deadbox (struct window *w, int x, int y, int width, + int height) { + RECT rc = { x, y, x + width, y + height }; int sbh = window_scrollbar_height (w); int sbw = window_scrollbar_width (w); RECT rect_dead, rect_paint; @@ -734,7 +734,7 @@ rect_dead.top = WINDOW_TEXT_BOTTOM (w); rect_dead.bottom = rect_dead.top + sbh; - if (IntersectRect (&rect_paint, &rect_dead, prc)) + if (IntersectRect (&rect_paint, &rect_dead, &rc)) { struct frame *f = XFRAME (WINDOW_FRAME (w)); FillRect (get_frame_dc (f, 1), &rect_paint, @@ -745,133 +745,6 @@ #endif /* HAVE_SCROLLBARS */ /***************************************************************************** - mswindows_redraw_exposed_window - - Given a bounding box for an area that needs to be redrawn, determine - what parts of what lines are contained within and re-output their - contents. - Copied from redisplay-x.c - ****************************************************************************/ -static void -mswindows_redraw_exposed_window (struct window *w, int x, int y, int width, - int height) -{ - struct frame *f = XFRAME (w->frame); - int line; - int orig_windows_structure_changed; - RECT rect_window = { WINDOW_LEFT (w), WINDOW_TOP (w), - WINDOW_RIGHT (w), WINDOW_BOTTOM (w) }; - RECT rect_expose = { x, y, x + width, y + height }; - RECT rect_draw; - - display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); - - if (!NILP (w->vchild)) - { - mswindows_redraw_exposed_windows (w->vchild, x, y, width, height); - return; - } - else if (!NILP (w->hchild)) - { - mswindows_redraw_exposed_windows (w->hchild, x, y, width, height); - return; - } - - /* If the window doesn't intersect the exposed region, we're done here. */ - if (!IntersectRect (&rect_draw, &rect_window, &rect_expose)) - return; - - /* We do this to make sure that the 3D modelines get redrawn if - they are in the exposed region. */ - orig_windows_structure_changed = f->windows_structure_changed; - f->windows_structure_changed = 1; - - if (window_needs_vertical_divider (w)) - { - mswindows_output_vertical_divider (w, 0); - } - - for (line = 0; line < Dynarr_length (cdla); line++) - { - struct display_line *cdl = Dynarr_atp (cdla, line); - - if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl) - >= rect_draw.top) - { - if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom) - { - if (line == 0) - continue; - else - break; - } - else - { - output_display_line (w, 0, cdla, line, - rect_draw.left, rect_draw.right); - } - } - } - - f->windows_structure_changed = orig_windows_structure_changed; - - /* If there have never been any face cache_elements created, then this - expose event doesn't actually have anything to do. */ - if (Dynarr_largest (w->face_cachels)) - redisplay_clear_bottom_of_window (w, cdla, rect_draw.top, rect_draw.bottom); - -#ifdef HAVE_SCROLLBARS - mswindows_redisplay_deadbox_maybe (w, &rect_expose); -#endif -} - -/***************************************************************************** - mswindows_redraw_exposed_windows - - For each window beneath the given window in the window hierarchy, - ensure that it is redrawn if necessary after an Expose event. - ****************************************************************************/ -static void -mswindows_redraw_exposed_windows (Lisp_Object window, int x, int y, int width, - int height) -{ - for (; !NILP (window); window = XWINDOW (window)->next) - mswindows_redraw_exposed_window (XWINDOW (window), x, y, width, height); -} - -/***************************************************************************** - mswindows_redraw_exposed_area - - For each window on the given frame, ensure that any area in the - Exposed area is redrawn. - ****************************************************************************/ -void -mswindows_redraw_exposed_area (struct frame *f, int x, int y, int width, int height) -{ - /* If any window on the frame has had its face cache reset then the - redisplay structures are effectively invalid. If we attempt to - use them we'll blow up. We mark the frame as changed to ensure - that redisplay will do a full update. This probably isn't - necessary but it can't hurt. */ -#ifdef HAVE_TOOLBARS - /* #### We would rather put these off as well but there is currently - no combination of flags which will force an unchanged toolbar to - redraw anyhow. */ - MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); -#endif - redraw_exposed_gutters (f, x, y, width, height); - - if (!f->window_face_cache_reset) - { - mswindows_redraw_exposed_windows (f->root_window, x, y, width, height); - GdiFlush(); - } - else - MARK_FRAME_CHANGED (f); -} - - -/***************************************************************************** mswindows_bevel_area Draw a 3d border around the specified area on window W. @@ -1338,15 +1211,15 @@ #ifdef HAVE_SCROLLBARS if (WINDOWP (locale)) - mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect); + mswindows_redisplay_deadbox (XWINDOW (locale), x, y, width, height); #endif } -/* XXX Implement me! */ +/* #### Implement me! */ static void mswindows_clear_frame (struct frame *f) { - GdiFlush(); + GdiFlush (); } @@ -1372,6 +1245,9 @@ CONSOLE_HAS_METHOD (mswindows, bevel_area); CONSOLE_HAS_METHOD (mswindows, output_string); CONSOLE_HAS_METHOD (mswindows, output_pixmap); +#ifdef HAVE_SCROLLBARS + CONSOLE_HAS_METHOD (mswindows, redisplay_deadbox); +#endif /* redisplay methods - printer */ CONSOLE_HAS_METHOD (msprinter, frame_output_end); diff -r d9d08dc5e617 -r b531bf8658e9 src/redisplay-output.c --- a/src/redisplay-output.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/redisplay-output.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,6 +1,6 @@ /* Synchronize redisplay structures and output changes. Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - Copyright (C) 1995, 1996, 2002 Ben Wing. + Copyright (C) 1995, 1996, 2002, 2003 Ben Wing. Copyright (C) 1996 Chuck Thompson. Copyright (C) 1999, 2002 Andy Piper. @@ -59,6 +59,8 @@ struct display_box* dest, struct display_glyph_area* glyphsrc, int fullheight_p, Lisp_Object); +static void redisplay_redraw_exposed_windows (Lisp_Object window, int x, + int y, int width, int height); /***************************************************************************** sync_rune_structs @@ -2491,6 +2493,177 @@ } /***************************************************************************** + redisplay_redraw_exposed_window + + Given a bounding box for an area that needs to be redrawn, determine + what parts of what lines are contained within and re-output their + contents. + ****************************************************************************/ +static void +redisplay_redraw_exposed_window (struct window *w, int x, int y, int width, + int height) +{ + struct frame *f = XFRAME (w->frame); + int line; + int start_x, start_y, end_x, end_y; + int orig_windows_structure_changed; + + display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); + + if (!NILP (w->vchild)) + { + redisplay_redraw_exposed_windows (w->vchild, x, y, width, height); + return; + } + else if (!NILP (w->hchild)) + { + redisplay_redraw_exposed_windows (w->hchild, x, y, width, height); + return; + } + + /* If the window doesn't intersect the exposed region, we're done here. */ + if (x >= WINDOW_RIGHT (w) || (x + width) <= WINDOW_LEFT (w) + || y >= WINDOW_BOTTOM (w) || (y + height) <= WINDOW_TOP (w)) + { + return; + } + else + { + start_x = max (WINDOW_LEFT (w), x); + end_x = min (WINDOW_RIGHT (w), (x + width)); + start_y = max (WINDOW_TOP (w), y); + end_y = min (WINDOW_BOTTOM (w), y + height); + + /* We do this to make sure that the 3D modelines get redrawn if + they are in the exposed region. */ + orig_windows_structure_changed = f->windows_structure_changed; + f->windows_structure_changed = 1; + } + + /* #### Not in GTK or MS Windows. I think is because of toolbars, which + are handled as widgets in GTK and MS Windows, but drawn ourselves in + X. For the moment I'm leaving this in, if it causes problems we have + some device method indicating whether we're drawing our own + toolbars. */ + redisplay_clear_top_of_window (w); + if (window_needs_vertical_divider (w)) + { + FRAMEMETH (f, output_vertical_divider, (w, 0)); + } + + for (line = 0; line < Dynarr_length (cdla); line++) + { + struct display_line *cdl = Dynarr_atp (cdla, line); + int top_y = DISPLAY_LINE_YPOS (cdl); + int bottom_y = DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl); + + if (bottom_y >= start_y) + { + if (top_y > end_y) + { + if (line == 0) + continue; + else + break; + } + else + { + output_display_line (w, 0, cdla, line, start_x, end_x); + } + } + } + + f->windows_structure_changed = orig_windows_structure_changed; + + /* If there have never been any face cache_elements created, then this + expose event doesn't actually have anything to do. */ + if (Dynarr_largest (w->face_cachels)) + redisplay_clear_bottom_of_window (w, cdla, start_y, end_y); + +#ifdef HAVE_SCROLLBARS + MAYBE_FRAMEMETH (f, redisplay_deadbox, (w, x, y, width, height)); +#endif +} + + +/***************************************************************************** + redisplay_redraw_exposed_windows + + For each window beneath the given window in the window hierarchy, + ensure that it is redrawn if necessary after an Expose event. + ****************************************************************************/ +static void +redisplay_redraw_exposed_windows (Lisp_Object window, int x, int y, int width, + int height) +{ + for (; !NILP (window); window = XWINDOW (window)->next) + redisplay_redraw_exposed_window (XWINDOW (window), x, y, width, height); +} + +static void +redisplay_redraw_exposed_area_1 (Lisp_Object arg) +{ + assert (!in_display); + redisplay_redraw_exposed_area (XFRAME (X1ST (arg)), + XINT (X2ND (arg)), + XINT (X3RD (arg)), + XINT (X4TH (arg)), + XINT (X5TH (arg))); + free_list (arg); +} + +/***************************************************************************** + redisplay_redraw_exposed_area + + For each window on the given frame, ensure that any area in the + Exposed area is redrawn. + ****************************************************************************/ +void +redisplay_redraw_exposed_area (struct frame *f, int x, int y, int width, + int height) +{ + int depth; + + if (in_display) + { + /* Not safe to do it now, so delay it */ + register_post_redisplay_action (redisplay_redraw_exposed_area_1, + list5 (wrap_frame (f), make_int (x), + make_int (y), make_int (width), + make_int (height))); + return; + } + + depth = enter_redisplay_critical_section (); + + MAYBE_FRAMEMETH (f, frame_output_begin, (f)); + + /* If any window on the frame has had its face cache reset then the + redisplay structures are effectively invalid. If we attempt to + use them we'll blow up. We mark the frame as changed to ensure + that redisplay will do a full update. This probably isn't + necessary but it can't hurt. */ +#ifdef HAVE_TOOLBARS + /* #### We would rather put these off as well but there is currently + no combination of flags which will force an unchanged toolbar to + redraw anyhow. */ + MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); +#endif + redraw_exposed_gutters (f, x, y, width, height); + + if (!f->window_face_cache_reset) + { + redisplay_redraw_exposed_windows (f->root_window, x, y, width, height); + /* #### Why not call this always? */ + MAYBE_FRAMEMETH (f, frame_output_end, (f)); + } + else + MARK_FRAME_CHANGED (f); + + exit_redisplay_critical_section (depth); +} + +/***************************************************************************** bevel_modeline Draw a 3d border around the modeline on window W. diff -r d9d08dc5e617 -r b531bf8658e9 src/redisplay-x.c --- a/src/redisplay-x.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/redisplay-x.c Fri Feb 21 06:57:21 2003 +0000 @@ -2,7 +2,7 @@ Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1994 Lucid, Inc. Copyright (C) 1995 Sun Microsystems, Inc. - Copyright (C) 2002 Ben Wing. + Copyright (C) 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -68,10 +68,6 @@ int cursor_start, int cursor_width); static void x_output_hline (struct window *w, struct display_line *dl, struct rune *rb); -static void x_redraw_exposed_window (struct window *w, int x, int y, - int width, int height); -static void x_redraw_exposed_windows (Lisp_Object window, int x, int y, - int width, int height); static void x_output_eol_cursor (struct window *w, struct display_line *dl, int xpos, face_index findex); static void x_clear_frame (struct frame *f); @@ -1676,137 +1672,6 @@ } } -/***************************************************************************** - x_redraw_exposed_window - - Given a bounding box for an area that needs to be redrawn, determine - what parts of what lines are contained within and re-output their - contents. - ****************************************************************************/ -static void -x_redraw_exposed_window (struct window *w, int x, int y, int width, int height) -{ - struct frame *f = XFRAME (w->frame); - int line; - int start_x, start_y, end_x, end_y; - int orig_windows_structure_changed; - - display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); - - if (!NILP (w->vchild)) - { - x_redraw_exposed_windows (w->vchild, x, y, width, height); - return; - } - else if (!NILP (w->hchild)) - { - x_redraw_exposed_windows (w->hchild, x, y, width, height); - return; - } - - /* If the window doesn't intersect the exposed region, we're done here. */ - if (x >= WINDOW_RIGHT (w) || (x + width) <= WINDOW_LEFT (w) - || y >= WINDOW_BOTTOM (w) || (y + height) <= WINDOW_TOP (w)) - { - return; - } - else - { - start_x = max (WINDOW_LEFT (w), x); - end_x = min (WINDOW_RIGHT (w), (x + width)); - start_y = max (WINDOW_TOP (w), y); - end_y = min (WINDOW_BOTTOM (w), y + height); - - /* We do this to make sure that the 3D modelines get redrawn if - they are in the exposed region. */ - orig_windows_structure_changed = f->windows_structure_changed; - f->windows_structure_changed = 1; - } - - redisplay_clear_top_of_window (w); - if (window_needs_vertical_divider (w)) - { - x_output_vertical_divider (w, 0); - } - - for (line = 0; line < Dynarr_length (cdla); line++) - { - struct display_line *cdl = Dynarr_atp (cdla, line); - int top_y = cdl->ypos - cdl->ascent; - int bottom_y = cdl->ypos + cdl->descent; - - if (bottom_y >= start_y) - { - if (top_y > end_y) - { - if (line == 0) - continue; - else - break; - } - else - { - output_display_line (w, 0, cdla, line, start_x, end_x); - } - } - } - - f->windows_structure_changed = orig_windows_structure_changed; - - /* If there have never been any face cache_elements created, then this - expose event doesn't actually have anything to do. */ - if (Dynarr_largest (w->face_cachels)) - redisplay_clear_bottom_of_window (w, cdla, start_y, end_y); -} - -/***************************************************************************** - x_redraw_exposed_windows - - For each window beneath the given window in the window hierarchy, - ensure that it is redrawn if necessary after an Expose event. - ****************************************************************************/ -static void -x_redraw_exposed_windows (Lisp_Object window, int x, int y, int width, - int height) -{ - for (; !NILP (window); window = XWINDOW (window)->next) - x_redraw_exposed_window (XWINDOW (window), x, y, width, height); -} - -/***************************************************************************** - x_redraw_exposed_area - - For each window on the given frame, ensure that any area in the - Exposed area is redrawn. - ****************************************************************************/ -void -x_redraw_exposed_area (struct frame *f, int x, int y, int width, int height) -{ - /* If any window on the frame has had its face cache reset then the - redisplay structures are effectively invalid. If we attempt to - use them we'll blow up. We mark the frame as changed to ensure - that redisplay will do a full update. This probably isn't - necessary but it can't hurt. */ - -#ifdef HAVE_TOOLBARS - /* #### We would rather put these off as well but there is currently - no combination of flags which will force an unchanged toolbar to - redraw anyhow. */ - MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); -#endif - redraw_exposed_gutters (f, x, y, width, height); - - if (!f->window_face_cache_reset) - { - x_redraw_exposed_windows (f->root_window, x, y, width, height); - - if (!(check_if_pending_expose_event (FRAME_XDEVICE (f)))) - XFlush (DEVICE_X_DISPLAY (FRAME_XDEVICE (f))); - } - else - MARK_FRAME_CHANGED (f); -} - /**************************************************************************** x_clear_region diff -r d9d08dc5e617 -r b531bf8658e9 src/redisplay.c --- a/src/redisplay.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/redisplay.c Fri Feb 21 06:57:21 2003 +0000 @@ -38,15 +38,9 @@ Third: It Is Better To Be Fast Than Not To Be ****************************************************************************/ -/* Note: The second rule used to prohibit running Elisp from within redisplay, - but that's not correct. - - Use - - callN_trapping_problems (..., INHIBIT_GC - | INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY) - - instead. +/* Note: The second rule used to prohibit running Elisp from within + redisplay, but that's not correct any more -- use + call*_trapping_problems() or call_with_suspended_errors() instead. --ben */ @@ -68,6 +62,7 @@ #include "insdel.h" #include "menubar.h" #include "objects-impl.h" +#include "opaque.h" #include "process.h" #include "profile.h" #include "redisplay.h" @@ -319,6 +314,7 @@ #define QUEUED_EVENTS_REQUIRED_FOR_PREEMPTION 4 +/* Note that doing this can call Lisp. */ #define REDISPLAY_PREEMPTION_CHECK \ ((void) \ (preempted = \ @@ -358,6 +354,10 @@ int in_display; /* 1 if in redisplay. */ +/* Whether we should delay size changes. Broken out of + enter_redisplay_critical_section(). */ +int hold_frame_size_changes; + int disable_preemption; /* Used for debugging redisplay and for force-redisplay. */ @@ -503,6 +503,8 @@ static Lisp_Object QSin_redisplay; +static Lisp_Object Vpost_redisplay_actions; + int column_number_start_at_one; Lisp_Object Qtop_bottom; @@ -5314,6 +5316,115 @@ return ret_charcount; } + +/* Tricky tricky tricky. generate_displayable_area() can (could) be called reentrantly, and redisplay is not prepared to handle this: + +assert_failed(const char * 0x0129c8c8 `string', int 5328, const char * 0x01274068 `string') line 3620 +Dynarr_verify_mod_1(void * 0x0250f228, const char * 0x0129c8c8 `string', int 5328) line 1256 + 36 bytes +generate_displayable_area(window * 0x02480028, long 38776292, int 0, int 0, int 265, int 169, display_line_dynarr * 0x0250f228, long 0, int 2) line 5328 + 25 bytes +output_gutter(frame * 0x0228ad90, gutter_pos TOP_GUTTER, int 1) line 409 + 69 bytes +redraw_exposed_gutter(frame * 0x0228ad90, gutter_pos TOP_GUTTER, int 8, int 23, int 249, int 127) line 687 + 15 bytes +redraw_exposed_gutters(frame * 0x0228ad90, int 8, int 23, int 249, int 127) line 703 + 29 bytes +mswindows_redraw_exposed_area(frame * 0x0228ad90, int 8, int 23, int 249, int 127) line 862 + 25 bytes +mswindows_handle_paint(frame * 0x0228ad90) line 2176 + 25 bytes +mswindows_wnd_proc(HWND__ * 0x001003e2, unsigned int 15, unsigned int 0, long 0) line 3233 + 45 bytes +intercepted_wnd_proc(HWND__ * 0x001003e2, unsigned int 15, unsigned int 0, long 0) line 2488 +USER32! 77e3a244() +USER32! 77e14730() +USER32! 77e1558a() +NTDLL! KiUserCallbackDispatcher@12 + 19 bytes +USER32! 77e14680() +USER32! 77e1a792() +qxeIsDialogMessage(HWND__ * 0x001003e2, tagMSG * 0x0082a93c {msg=0x0000000f wp=0x00000000 lp=0x00000000}) line 2298 + 14 bytes +mswindows_is_dialog_msg(tagMSG * 0x0082a93c {msg=0x0000000f wp=0x00000000 lp=0x00000000}) line 165 + 13 bytes +mswindows_drain_windows_queue(int 0) line 1282 + 9 bytes +emacs_mswindows_drain_queue() line 1326 + 7 bytes +event_stream_drain_queue() line 1887 +event_stream_quit_p() line 1992 +check_quit() line 993 +unbind_to_hairy(int 35) line 5963 +unbind_to_1(int 35, long 20888208) line 5945 + 200 bytes +specifier_instance_from_inst_list(long 21379344, long 38135616, long 36220304, long 20888208, _error_behavior_struct_ {...}, int 1, long 3) line 2522 + 16 bytes +specifier_instance(long 21379344, long 38135616, long 36220304, _error_behavior_struct_ {...}, int 1, int 0, long 3) line 2625 + 65 bytes +specifier_instance_no_quit(long 21379344, long 38135616, long 36220304, _error_behavior_struct_ {...}, int 0, long 1) line 2658 + 31 bytes +face_property_matching_instance(long 22612340, long 20860632, long 22530956, long 36220304, _error_behavior_struct_ {...}, int 0, long 1) line 565 + 48 bytes +ensure_face_cachel_contains_charset(face_cachel * 0x0082b014, long 36220304, long 22530956) line 1104 + 35 bytes +update_face_cachel_data(face_cachel * 0x0082b014, long 36220304, long 22612340) line 1304 + 19 bytes +query_string_geometry(long 21110576, long 22612340, int * 0x00000000, int * 0x0082b5b4, int * 0x00000000, long 38852960) line 2370 + 23 bytes +mswindows_widget_query_string_geometry(long 21110576, long 22612340, int * 0x0082b5b8, int * 0x0082b5b4, long 38852960) line 2914 + 25 bytes +widget_query_string_geometry(long 21110576, long 22612340, int * 0x0082b5b8, int * 0x0082b5b4, long 38852960) line 514 + 32 bytes +edit_field_query_geometry(long 38857648, int * 0x0082b7b4, int * 0x0082b7b8, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38852960) line 920 + 390 bytes +widget_query_geometry(long 38857648, int * 0x0082b7b4, int * 0x0082b7b8, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38852960) line 567 + 26 bytes +image_instance_query_geometry(long 38857648, int * 0x0082b7b4, int * 0x0082b7b8, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38852960) line 2015 + 26 bytes +glyph_query_geometry(long 38853384, int * 0x0082b7b4, int * 0x0082b7b8, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38852960) line 4197 + 25 bytes +layout_query_geometry(long 38852960, int * 0x0082b9cc, int * 0x0082b9d0, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38404624) line 1351 + 25 bytes +widget_query_geometry(long 38852960, int * 0x0082b9cc, int * 0x0082b9d0, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38404624) line 567 + 26 bytes +image_instance_query_geometry(long 38852960, int * 0x0082b9cc, int * 0x0082b9d0, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38404624) line 2015 + 26 bytes +glyph_query_geometry(long 38537976, int * 0x0082b9cc, int * 0x0082b9d0, image_instance_geometry IMAGE_DESIRED_GEOMETRY, long 38404624) line 4197 + 25 bytes +layout_layout(long 38404624, int 265, int 156, int -2, int -2, long 38273064) line 1468 + 23 bytes +widget_layout(long 38404624, int 265, int 156, int -2, int -2, long 38273064) line 626 + 30 bytes +image_instance_layout(long 38404624, int 265, int 156, int -2, int -2, long 38273064) line 2102 + 51 bytes +glyph_ascent(long 38404624, long 38273064) line 4009 + 21 bytes +update_glyph_cachel_data(window * 0x02480028, long 36201168, glyph_cachel * 0x0248c3d8) line 4272 + 13 bytes +get_glyph_cachel_index(window * 0x02480028, long 36201168) line 4306 + 17 bytes +add_glyph_rune(position_redisplay_data_type * 0x0082bf2c, glyph_block * 0x024bd028, int 0, int 0, glyph_cachel * 0x00000000) line 1800 + 15 bytes +add_glyph_runes(position_redisplay_data_type * 0x0082bf2c, int 0) line 2085 + 31 bytes +create_string_text_block(window * 0x02480028, long 38776292, display_line * 0x02514500, long 0, prop_block_dynarr * * 0x0082c13c, int 2) line 4907 + 14 bytes +generate_string_display_line(window * 0x02480028, long 38776292, display_line * 0x02514500, long 0, prop_block_dynarr * * 0x0082c13c, int 2) line 5293 + 29 bytes +generate_displayable_area(window * 0x02480028, long 38776292, int 0, int 0, int 265, int 169, display_line_dynarr * 0x0250f228, long 0, int 2) line 5372 + 29 bytes +output_gutter(frame * 0x0228ad90, gutter_pos TOP_GUTTER, int 0) line 409 + 69 bytes +update_frame_gutters(frame * 0x0228ad90) line 639 + 15 bytes +redisplay_frame(frame * 0x0228ad90, int 1) line 6792 + 9 bytes +redisplay_device(device * 0x0171df00, int 1) line 6911 + 11 bytes +redisplay_without_hooks() line 6957 + 11 bytes +redisplay_no_pre_idle_hook() line 7029 +redisplay() line 7011 +mswindows_wnd_proc(HWND__ * 0x001003e2, unsigned int 5, unsigned int 0, long 10223881) line 3424 +intercepted_wnd_proc(HWND__ * 0x001003e2, unsigned int 5, unsigned int 0, long 10223881) line 2488 +USER32! 77e3a244() +USER32! 77e16362() +USER32! 77e14c1a() +USER32! 77e1dd30() +mswindows_wnd_proc(HWND__ * 0x001003e2, unsigned int 71, unsigned int 0, long 8578308) line 3926 + 21 bytes +intercepted_wnd_proc(HWND__ * 0x001003e2, unsigned int 71, unsigned int 0, long 8578308) line 2488 +USER32! 77e3a244() +USER32! 77e14730() +USER32! 77e174b4() +NTDLL! KiUserCallbackDispatcher@12 + 19 bytes +mswindows_set_frame_size(frame * 0x0228ad90, int 265, int 156) line 355 +internal_set_frame_size(frame * 0x0228ad90, int 265, int 156, int 0) line 2754 + 24 bytes +Fset_frame_displayable_pixel_size(long 36220304, long 531, long 313, long 20888208) line 3004 + 32 bytes +Ffuncall(int 4, long * 0x0082e778) line 3844 + 168 bytes +execute_optimized_program(const unsigned char * 0x02286e48, int 40, long * 0x01529b80) line 609 + 16 bytes +funcall_compiled_function(long 22433308, int 0, long * 0x0082ec08) line 3452 + 85 bytes +Ffuncall(int 1, long * 0x0082ec04) line 3883 + 17 bytes +execute_optimized_program(const unsigned char * 0x02286d40, int 6, long * 0x01548ddc) line 609 + 16 bytes +funcall_compiled_function(long 22505864, int 11, long * 0x0082f00c) line 3452 + 85 bytes +Ffuncall(int 12, long * 0x0082f008) line 3883 + 17 bytes +execute_optimized_program(const unsigned char * 0x02503e38, int 47, long * 0x0152dc48) line 609 + 16 bytes +funcall_compiled_function(long 22436784, int 0, long * 0x0082f534) line 3452 + 85 bytes +Ffuncall(int 1, long * 0x0082f530) line 3883 + 17 bytes +apply1(long 22436784, long 20888208) line 4458 + 11 bytes +Fcall_interactively(long 20742816, long 20888208, long 20888208) line 460 + 13 bytes +Ffuncall(int 2, long * 0x0082f8ec) line 3844 + 127 bytes +call1(long 20854392, long 20742816) line 4489 + 11 bytes +execute_command_event(command_builder * 0x01798f98, long 24439276) line 4198 + 69 bytes +Fdispatch_event(long 24439276) line 4569 + 13 bytes +Fcommand_loop_1() line 569 + 9 bytes +command_loop_1(long 20888208) line 489 +condition_case_1(long 20886024, long (long)* 0x010955a0 command_loop_1(long), long 20888208, long (long, long)* 0x01095150 cmd_error(long, long), long 20888208) line 1917 + 7 bytes +command_loop_3() line 251 + 35 bytes +command_loop_2(long 20888208) line 264 +internal_catch(long 20650992, long (long)* 0x010952c0 command_loop_2(long), long 20888208, int * volatile 0x00000000, long * volatile 0x00000000) line 1527 + 7 bytes +initial_command_loop(long 20888208) line 300 + 28 bytes +xemacs_21_5_b10_i586_pc_win32(int 1, char * * 0x00e52620, char * * 0x00e52bb0, int 0) line 2356 +main(int 1, char * * 0x00e52620, char * * 0x00e52bb0) line 2733 +mainCRTStartup() line 338 + 17 bytes +KERNEL32! 77ea847c() + +*/ + + /* This is ripped off from regenerate_window. All we want to do is loop through elements in the string creating display lines until we have covered the provided area. Simple really. */ @@ -5373,8 +5484,10 @@ dlp->bounds = bounds; dlp->offset = 0; + Dynarr_lock (dla); next_pos = generate_string_display_line (w, disp_string, dlp, start_pos, &prop, default_face); + Dynarr_unlock (dla); /* we need to make sure that we continue along the line if there is more left to display otherwise we just end up redisplaying the same chunk over and over again. */ @@ -5521,7 +5634,9 @@ dlp->bounds = bounds; dlp->offset = 0; + Dynarr_lock (dla); start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type); + Dynarr_unlock (dla); if (yclip > dlp->ascent) { @@ -5577,8 +5692,11 @@ { /* #### This means that we've added a cursor at EOB twice. Yuck oh yuck. */ - struct display_block *db = - get_display_block_from_line (dlp, TEXT); + struct display_block *db; + + Dynarr_lock (dla); + db = get_display_block_from_line (dlp, TEXT); + Dynarr_unlock (dla); Dynarr_atp (db->runes, dlp->cursor_elt)->cursor_type = NO_CURSOR; dlp->cursor_elt = -1; @@ -6580,6 +6698,205 @@ } } +/* Register an action to be called at the end of redisplay. + in_display is 0 when this is called. + This is used when it is discovered that an action needs to be taken, + but it's during redisplay, so it's not safe. (Typically, it's an action + that needs to enter redisplay, which can't happen reentrantly.) + + NEVER signal an error in these functions. +*/ + +void +register_post_redisplay_action (void (*fun) (Lisp_Object), Lisp_Object arg) +{ + Vpost_redisplay_actions = nconc2 (Vpost_redisplay_actions, + list1 (Fcons (make_opaque_ptr + ((void *) fun), arg))); +} + +static void +run_post_redisplay_actions (void) +{ + while (!NILP (Vpost_redisplay_actions)) + { + Lisp_Object car = XCAR (Vpost_redisplay_actions); + void (*fun) (Lisp_Object) = + (void (*)(Lisp_Object)) get_opaque_ptr (XCAR (car)); + (*fun) (XCDR (car)); + free_opaque_ptr (XCAR (car)); + free_cons (car); + Vpost_redisplay_actions = XCDR (Vpost_redisplay_actions); + } +} + +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS + +static Lisp_Object +commit_ritual_suicide (Lisp_Object ceci_nest_pas_une_pipe) +{ + assert (!in_display); + return Qnil; +} + +#endif + +/* Within the guts of redisplay, we are defenseless and cannot allow any of + the following to happen: + + 1) garbage collection + 2) QUIT + 3) any non-local exits + 4) frame size changes + 5) deletion of any buffers, windows, frames, etc. + 6) modification of buffer text + 7) reentrant entry of redisplay (see the stack trace above + generate_displayable_area()) + + The general reason is that the redisplay code is written to assume that + it is the only code running, and thus (a) cannot tolerate structures + changed out from under it (hence 1, 4, 5, 6, 7) and (b) at various points + within redisplay the redisplay structures may be in an inconsistent + state and there are no unwind-protects to clean the structures up in + case of non-local exit (hence 2, 3). Fixing redisplay to address these + issues is hard and perhaps not worth it (and might slow things down a + fair amount). We address 1, 4, 5 and 6 ourselves inside of + enter_redisplay_critical_section() by simply inhibiting them, but we + cannot handle 2 and 3, which must be handled at the actual point where + they may occur (especially, internal_equal() or any place that may call + Lisp), by wrapping the code in call_trapping_problems() or + call_with_suspended_errors(). [[ NOTE: We could address QUIT by inhibiting + it but this would be anti-social because it would prevent the user from + interrupting any Lisp code called within the critical section. With the + call_*() wrapping, C-g will interrupt the Lisp code and throw back to + the innermost wrapping. ]] In fact we do turn off QUIT handling, since + it's just too dangerous otherwise. See below. + + Code calling enter_redisplay_critical_section() must check for reentrancy + (#7) and take appropriate corrective action. + + To help debug potential problems, we arrange (when + ERROR_CHECK_TRAPPING_PROBLEMS is set) to crash automatically every time + we execute QUIT or call Lisp code unless proper wrapping is in place, as + well as further checks when we actually Fsignal(), Fthrow(), + garbage_collect_1(). + + #### If a frame-size change does occur we should probably actually be + preempting redisplay. */ + +/* Count of number of recursive times we call + enter_redisplay_critical_section() or + enter_redisplay_critical_section_maybe(). + enter_redisplay_critical_section() cannot occur reentrantly but we have + to know in the *maybe() version whether to exit the section when we're + done. */ +static int in_display_nesting; + +static Lisp_Object +end_hold_frame_size_changes (Lisp_Object obj) +{ + if (!hold_frame_size_changes) + { + /* we used to have a function to do this for only one frame, and + it was typical to call it at the end of a critical section + (which occurs once per frame); but what then happens if multiple + frames have frame changes held up? + + This means we are O(N^2) over frames. I seriously doubt it matters. + --ben */ + Lisp_Object frmcons, devcons, concons; + + FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) + { + struct frame *f = XFRAME (XCAR (frmcons)); + if (f->size_change_pending) + change_frame_size (f, f->new_height, f->new_width, 0); + } + } + return Qnil; +} + +/* Call this to temporarily prevent frame-size changes from being processed. + To undo, use unbind_to(), passing it the value returned by this function. +*/ + +int +begin_hold_frame_size_changes (void) +{ + int depth = specpdl_depth (); + record_unwind_protect (end_hold_frame_size_changes, Qnil); + internal_bind_int (&hold_frame_size_changes, 1 + hold_frame_size_changes); + return depth; +} + +int +enter_redisplay_critical_section (void) +{ + int depth = specpdl_depth (); + + /* Reentrant entry is deadly. The calling function must check for this. */ + assert (!in_display); + begin_hold_frame_size_changes (); + /* Make sure in_display gets reset, but don't set it yet so that + commit_ritual_suicide() can be used. */ + internal_bind_int (&in_display, 0); + internal_bind_int (&in_display_nesting, 1 + in_display_nesting); +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS + /* Force every call to QUIT to check for in_displayness. This will + verify proper wrapping, as in the previous comment, aborting if not. */ + something_happened++; + /* Verify that no nonlocal exits blow past us. */ + record_unwind_protect (commit_ritual_suicide, Qnil); +#endif + in_display++; + + set_trapping_problems_flags (INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY); + /* Even checking for QUIT can cause arbitrary Lisp code to be executed, + e.g. through a menu handler. We really don't want that happening + inside of redisplay. Code that we `eval' is at least written with the + expectation that it's inside of redisplay, and shouldn't try anything + weird; but that's not the case for menu code (e.g. custom loads huge + amounts of LISP FILES from a menu handler! FMH!). Safest just to turn + this off. We could turn it on using UNINHIBIT_QUIT or + begin_do_check_for_quit() in certain places if we want, if we know + it's not in an especially tricky place. */ + begin_dont_check_for_quit (); + return depth; +} + +void +exit_redisplay_critical_section (int depth) +{ + in_display--; + assert (!in_display); + unbind_to (depth); + + run_post_redisplay_actions (); +} + +/* Enter the redisplay critical section if we're not already in it. This + is for code that needs frame changes held up and other protections from + being inside, but doesn't modify the redisplay structures, and doesn't + look at them in a way that they will be confused by inconsistencies. */ + +int +enter_redisplay_critical_section_maybe (void) +{ + if (!in_display) + return enter_redisplay_critical_section (); + else + return internal_bind_int (&in_display_nesting, 1 + in_display_nesting); +} + +void +exit_redisplay_critical_section_maybe (int depth) +{ + if (in_display_nesting == 1) + exit_redisplay_critical_section (depth); + else + unbind_to (depth); +} + /* Ensure that all windows on the given frame are correctly displayed. Return non-zero if pre-empted. */ @@ -6591,9 +6908,19 @@ assert (f->init_finished); + /* NOTE: Without sufficient checks for stream frames, we got weird + crashes in pdump. These came and went very easily -- adding the + critical-section code for redisplay was enough to trigger them. + Perhaps I should have debugged them but there didn't seem to be any + point. --ben */ if (FRAME_STREAM_P (f)) /* nothing to do */ return 0; + /* Reentrancy into redisplay can be deadly. See stack trace above + generate_displayable_area(). */ + if (in_display) + return 1; + if (preemption_check && !DEVICE_IMPL_FLAG (d, XDEVIMPF_DONT_PREEMPT_REDISPLAY)) { @@ -6630,11 +6957,11 @@ assert (!f->size_slipped); } - /* The menubar, toolbar, and icon updates must be done before + /* The menubar, toolbar, and icon updates should be done before enter_redisplay_critical_section is called and we are officially - 'in_display'. They may eval lisp code which may call QUIT. - If in_display is set, QUIT will abort (unless the code is wrapped - to protect against errors). */ + 'in_display'. They is because they tend to eval Lisp code, which + needs to be carefully wrapped within the critical section (and hence + is difficult to debug). */ #ifdef HAVE_MENUBARS /* Update the menubar. It is done first since it could change @@ -6679,32 +7006,8 @@ depth = enter_redisplay_critical_section (); /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ - /* Within this section, we are defenseless and assume that the - following cannot happen: - - 1) garbage collection - 2) QUIT - 3) Any non-local exits - 4) frame size changes - - We ensure (4) by calling enter_redisplay_critical_section(), which - will cause any pending frame size changes to get put on hold - till after the end of the critical section. (2) is required because - of the possibility of (3). (2) and (3) mean that any place that - can execute QUIT (e.g. internal_equal()), and especially any place - that executes Lisp code, need to be properly wrapped to protect - against these possibilities. This wrapping happens using - call_trapping_problems(..., INHIBIT_GC), or related functions. - - To help debug potential problems, we arrange (when - ERROR_CHECK_TRAPPING_PROBLEMS is set) to crash automatically every - time we execute QUIT or check to see whether garbage collection is - necessary, inside of an unprotected critical section, as well as - further checks when we actually Fsignal(), Fthrow(), - garbage_collect_1(). - - #### If a frame-size change does occur we should probably - actually be preempting redisplay. */ + + /* See comments in enter_redisplay_critical_section() */ MAYBE_DEVMETH (d, frame_output_begin, (f)); @@ -6715,7 +7018,11 @@ inhibit_quit. More importantly the code involving display lines *assumes* that GC will not happen and so does not GCPRO anything. Since we use this code the whole time with the gutters - we cannot allow GC to happen when manipulating the gutters. */ + we cannot allow GC to happen when manipulating the gutters. + + This must be inside of the critical section for various reasons. + For example, it messes with display structures, which be left in + an inconsistent state. */ update_frame_gutters (f); /* Erase the frame before outputting its contents. */ @@ -6920,16 +7227,10 @@ PROFILE_RECORD_EXITING_SECTION (QSin_redisplay); } -/* Note: All places in the C code that call redisplay() are prepared - to handle GCing. However, we can't currently handle GC inside the - guts of redisplay (#### someone should fix this), so we need to use - INHIBIT_GC when calling Lisp. - - #### We probably can't handle any deletion of existing buffers, frames, - windows, devices, consoles, text changes, etc. either. We should - - (a) Create the appropriate INHIBIT_ flags for this. - (b) In the longer run, fix redisplay to handle this. +/* Note: All places in the C code that call redisplay() are prepared to + handle GCing, which can happen from run_pre_idle_hook(). However, we + can't currently handle GC inside the guts of redisplay; see + enter_redisplay_critical_section(). (#### What about other external entry points to the redisplay code? Someone should go through and make sure that all callers can handle @@ -6967,8 +7268,7 @@ return eval_in_buffer_trapping_problems ("Error calling function within redisplay", current_buffer, - dont_trust_this_damn_sucker, - INHIBIT_GC | INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY); + dont_trust_this_damn_sucker, 0); } /* Efficiently determine the window line number, and return a pointer @@ -7308,7 +7608,7 @@ if (dl->display_blocks) { for (block = 0; block < Dynarr_largest (dl->display_blocks); block++) - { + { struct display_block *db = Dynarr_atp (dl->display_blocks, block); Dynarr_free (db->runes); @@ -9120,6 +9420,9 @@ { Lisp_Object devcons, concons; + if (in_display) + return Qnil; + DEVICE_LOOP_NO_BREAK (devcons, concons) { struct device *d = XDEVICE (XCAR (devcons)); @@ -9661,6 +9964,9 @@ QSin_redisplay = build_msg_string ("(in redisplay)"); staticpro (&QSin_redisplay); + Vpost_redisplay_actions = Qnil; + staticpro (&Vpost_redisplay_actions); + #if 0 staticpro (&last_arrow_position); staticpro (&last_arrow_string); diff -r d9d08dc5e617 -r b531bf8658e9 src/redisplay.h --- a/src/redisplay.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/redisplay.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* Redisplay data structures. Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1996 Chuck Thompson. - Copyright (C) 1995, 1996, 2002 Ben Wing. + Copyright (C) 1995, 1996, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -662,6 +662,10 @@ /* Nonzero if we're in a display critical section. */ extern int in_display; +/* Whether we should delay size changes. Broken out of + enter_redisplay_critical_section(). */ +extern int hold_frame_size_changes; + /* Nonzero means no need to redraw the entire frame on resuming a suspended Emacs. This is useful on terminals with multiple pages, where one page is used for Emacs and another for all else. */ @@ -827,5 +831,14 @@ void sync_display_line_structs (struct window *w, int line, int do_blocks, display_line_dynarr *cdla, display_line_dynarr *ddla); +void redisplay_redraw_exposed_area (struct frame *f, int x, int y, int width, + int height); +void register_post_redisplay_action (void (*fun) (Lisp_Object), + Lisp_Object arg); +int begin_hold_frame_size_changes (void); +int enter_redisplay_critical_section (void); +void exit_redisplay_critical_section (int); +int enter_redisplay_critical_section_maybe (void); +void exit_redisplay_critical_section_maybe (int depth); #endif /* INCLUDED_redisplay_h_ */ diff -r d9d08dc5e617 -r b531bf8658e9 src/scrollbar-gtk.c --- a/src/scrollbar-gtk.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/scrollbar-gtk.c Fri Feb 21 06:57:21 2003 +0000 @@ -436,15 +436,9 @@ void gtk_update_frame_scrollbars (struct frame *f) { - /* Consider this code to be "in_display" (in a critical section) so we - abort() if elisp or QUIT is not properly wrapped -- see - enter_redisplay_critical_section(). */ - in_display++; gtk_scrollbar_loop (GTK_UPDATE_FRAME_SCROLLBARS, f->root_window, XWINDOW_MIRROR (f->root_mirror), 0, (GdkWindow *) NULL); - in_display--; - if (in_display < 0) abort (); } #ifdef MEMORY_USAGE_STATS diff -r d9d08dc5e617 -r b531bf8658e9 src/scrollbar-x.c --- a/src/scrollbar-x.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/scrollbar-x.c Fri Feb 21 06:57:21 2003 +0000 @@ -686,14 +686,8 @@ void x_update_frame_scrollbars (struct frame *f) { - /* Consider this code to be "in_display" (in a critical section) so we - abort() if elisp or QUIT is not properly wrapped -- see - enter_redisplay_critical_section(). */ - in_display++; x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, XWINDOW_MIRROR (f->root_mirror), 0, (Window) NULL); - in_display--; - if (in_display < 0) abort (); } #ifdef MEMORY_USAGE_STATS diff -r d9d08dc5e617 -r b531bf8658e9 src/scrollbar.c --- a/src/scrollbar.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/scrollbar.c Fri Feb 21 06:57:21 2003 +0000 @@ -3,6 +3,7 @@ Copyright (C) 1995 Free Software Foundation, Inc. Copyright (C) 1995 Sun Microsystems, Inc. Copyright (C) 1995 Darrell Kindred . + Copyright (C) 2003 Ben Wing. This file is part of XEmacs. @@ -285,11 +286,12 @@ { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); + int depth; if (!HAS_DEVMETH_P (d, create_scrollbar_instance)) return; - in_display++; + depth = enter_redisplay_critical_section_maybe (); /* It is possible for this to get called from the mirror update routines. In that case the structure is in an indeterminate @@ -347,7 +349,7 @@ } } - in_display--; + exit_redisplay_critical_section_maybe (depth); } void diff -r d9d08dc5e617 -r b531bf8658e9 src/signal.c --- a/src/signal.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/signal.c Fri Feb 21 06:57:21 2003 +0000 @@ -428,21 +428,26 @@ void check_what_happened (void) { -#ifdef ERROR_CHECK_TRAPPING_PROBLEMS - if (in_display - && !((get_inhibit_flags () & INTERNAL_INHIBIT_ERRORS) - && (get_inhibit_flags () & INTERNAL_INHIBIT_THROWS))) - assert_with_message - (0, "QUIT called from within redisplay without being properly wrapped"); -#endif - /* No GC can happen anywhere here. handle_async_timeout_signal() prevents GC (from asynch timeout handler), so does check_quit() (from processing a message such as WM_INITMENU as a result of draining the message queue). establish_slow_interrupt_timer() is too low-level to do anything that might invoke QUIT or call Lisp code. */ - something_happened = 0; + +#ifdef ERROR_CHECK_TRAPPING_PROBLEMS + assert_with_message + (proper_redisplay_wrapping_in_place (), + "QUIT called from within redisplay without being properly wrapped"); + + /* When in a critical section, don't reset something_happened, so that + every single QUIT will verify proper wrapping. (something_happened + was set by enter_redisplay_critical_section() and will be reset + upon exit.) */ + if (!in_display) +#endif + something_happened = 0; + if (async_timeout_happened) { async_timeout_happened = 0; diff -r d9d08dc5e617 -r b531bf8658e9 src/sysdep.c --- a/src/sysdep.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/sysdep.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* Interfaces to system-dependent kernel and library entries. Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc. Copyright (C) 1995 Tinker Systems. - Copyright (C) 2000, 2001, 2002 Ben Wing. + Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -2469,6 +2469,11 @@ /* Encapsulations of system calls */ /************************************************************************/ +/* The documentation in VC++ claims that the pathname library functions + accept strings in the current locale-specific encoding, but that's + false, because they just call the native Win32 routines directly, which + always use the system-default encoding (which is what Qmswindows_tstr + will give us when not XEUNICODE_P). */ #ifdef WIN32_NATIVE #define PATHNAME_CONVERT_OUT(path, pathout) C_STRING_TO_TSTR (path, pathout) #else @@ -3223,6 +3228,12 @@ C_STRING_TO_EXTERNAL (envp[i], new_envp[i], Qnative); new_envp[envc] = NULL; +#if defined (WIN32_NATIVE) + if (XEUNICODE_P) + return _wexecve ((const wchar_t *) pathext, + (const wchar_t * const *) new_argv, + (const wchar_t * const *) new_envp); +#endif return execve (pathext, new_argv, new_envp); } diff -r d9d08dc5e617 -r b531bf8658e9 src/text.c --- a/src/text.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/text.c Fri Feb 21 06:57:21 2003 +0000 @@ -3219,6 +3219,156 @@ PROFILE_RECORD_EXITING_SECTION (QSin_internal_external_conversion); } +/* ----------------------------------------------------------------------- */ +/* New-style DFC converters (data is returned rather than stored into var) */ +/* ----------------------------------------------------------------------- */ + +/* We handle here the cases where SRC is a Lisp_Object, internal data + (sized or unsized), or external data (sized or unsized), and return type + is unsized alloca() or malloc() data. If the return type is a + Lisp_Object, use build_ext_string() for unsized external data, + make_ext_string() for sized external data. If the return type needs to + be sized data, use the *_TO_SIZED_*() macros, and for other more + complicated cases, use the original TO_*_FORMAT() macros. */ + +static void +new_dfc_convert_now_damn_it (const void *src, Bytecount src_size, + enum new_dfc_src_type type, + void **dst, Bytecount *dst_size, + Lisp_Object codesys) +{ + /* #### In the case of alloca(), it would be a bit more efficient, for + small strings, to use static Dynarr's like are used internally in + TO_*_FORMAT(), or some other way of avoiding malloc() followed by + free(). I doubt it really matters, though. */ + + switch (type) + { + case DFC_EXTERNAL: + TO_INTERNAL_FORMAT (C_STRING, src, + MALLOC, (*dst, *dst_size), codesys); + break; + + case DFC_SIZED_EXTERNAL: + TO_INTERNAL_FORMAT (DATA, (src, src_size), + MALLOC, (*dst, *dst_size), codesys); + break; + + case DFC_INTERNAL: + TO_EXTERNAL_FORMAT (C_STRING, src, + MALLOC, (*dst, *dst_size), codesys); + break; + + case DFC_SIZED_INTERNAL: + TO_EXTERNAL_FORMAT (DATA, (src, src_size), + MALLOC, (*dst, *dst_size), codesys); + break; + + case DFC_LISP_STRING: + TO_EXTERNAL_FORMAT (LISP_STRING, VOID_TO_LISP (src), + MALLOC, (*dst, *dst_size), codesys); + break; + + default: + abort (); + } +} + +void * +new_dfc_convert_malloc (const void *src, Bytecount src_size, + enum new_dfc_src_type type, Lisp_Object codesys) +{ + void *dst; + Bytecount dst_size; + + new_dfc_convert_now_damn_it (src, src_size, type, &dst, &dst_size, codesys); + return dst; +} + +/* For alloca(), things are trickier because the calling function needs to + allocate. This means that the caller needs to do the following: + + (a) invoke us to do the conversion, remember the data and return the size. + (b) alloca() the proper size. + (c) invoke us again to copy the data. + + We need to handle the possibility of two or more invocations of the + converter in the same expression. In such cases it's conceivable that + the evaluation of the sub-expressions will be overlapping (e.g. one size + function called, then the other one called, then the copy functions + called). To handle this, we keep a list of active data, indexed by the + src expression. (We use the stringize operator to avoid evaluating the + expression multiple times.) If the caller uses the exact same src + expression twice in two converter calls in the same subexpression, we + will lose, but at least we can check for this and abort(). We could + conceivably try to index on other parameters as well, but there is not + really any point. */ + +typedef struct +{ + const char *srctext; + void *dst; + Bytecount dst_size; +} dfc_e2c_vals; + +typedef struct +{ + Dynarr_declare (dfc_e2c_vals); +} dfc_e2c_vals_dynarr; + +static dfc_e2c_vals_dynarr *active_dfc_e2c; + +static int +find_pos_of_existing_active_dfc_e2c (const char *srctext) +{ + dfc_e2c_vals *vals = NULL; + int i; + + for (i = 0; i < Dynarr_length (active_dfc_e2c); i++) + { + vals = Dynarr_atp (active_dfc_e2c, i); + if (vals->srctext == srctext) + return i; + } + + return -1; +} + +void * +new_dfc_convert_alloca (const char *srctext, void *alloca_data) +{ + dfc_e2c_vals *vals; + int i = find_pos_of_existing_active_dfc_e2c (srctext); + + assert (i >= 0); + vals = Dynarr_atp (active_dfc_e2c, i); + assert (alloca_data); + memcpy (alloca_data, vals->dst, vals->dst_size + 2); + xfree (vals->dst); + Dynarr_delete (active_dfc_e2c, i); + return alloca_data; +} + +Bytecount +new_dfc_convert_size (const char *srctext, const void *src, + Bytecount src_size, enum new_dfc_src_type type, + Lisp_Object codesys) +{ + dfc_e2c_vals vals; + + assert (find_pos_of_existing_active_dfc_e2c (srctext) < 0); + + vals.srctext = srctext; + + new_dfc_convert_now_damn_it (src, src_size, type, &vals.dst, &vals.dst_size, + codesys); + + Dynarr_add (active_dfc_e2c, vals); + /* The size is always + 2 because we have double zero-termination at the + end of all data (for Unicode-correctness). */ + return vals.dst_size + 2; +} + /************************************************************************/ /* Basic Ichar functions */ @@ -3740,6 +3890,7 @@ Ibyte_dynarr *); conversion_out_dynarr_list = Dynarr_new2 (Extbyte_dynarr_dynarr, Extbyte_dynarr *); + active_dfc_e2c = Dynarr_new (dfc_e2c_vals); for (i = 0; i <= MAX_BYTEBPOS_GAP_SIZE_3; i++) three_to_one_table[i] = i / 3; diff -r d9d08dc5e617 -r b531bf8658e9 src/text.h --- a/src/text.h Thu Feb 20 22:52:51 2003 +0000 +++ b/src/text.h Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* Header file for text manipulation primitives and macros. Copyright (C) 1985-1995 Free Software Foundation, Inc. Copyright (C) 1995 Sun Microsystems, Inc. - Copyright (C) 2000, 2001, 2002 Ben Wing. + Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. This file is part of XEmacs. @@ -336,7 +336,7 @@ #endif /* MULE */ -int dfc_coding_system_is_unicode (Lisp_Object coding_system); +int dfc_coding_system_is_unicode (Lisp_Object codesys); DECLARE_INLINE_HEADER ( Bytecount dfc_external_data_len (const void *ptr, Lisp_Object codesys) @@ -1410,10 +1410,10 @@ ... from an ASCII string, with length specified. Non-ASCII characters in the string are *ILLEGAL* (read abort() with error-checking defined). void eicpy_ext (Eistring *eistr, const Extbyte *extdata, - Lisp_Object coding_system); + Lisp_Object codesys); ... from external null-terminated data, with coding system specified. void eicpy_ext_len (Eistring *eistr, const Extbyte *extdata, - Bytecount extlen, Lisp_Object coding_system); + Bytecount extlen, Lisp_Object codesys); ... from external data, with length and coding system specified. void eicpy_lstream (Eistring *eistr, Lisp_Object lstream); ... from an lstream; reads data till eof. Data must be in default @@ -1592,7 +1592,7 @@ * Converting to an external format * ********************************************** - void eito_external (Eistring *eistr, Lisp_Object coding_system); + void eito_external (Eistring *eistr, Lisp_Object codesys); Convert the Eistring to an external format and store the result in the string. NOTE: Further changes to the Eistring will *NOT* change the external data stored in the string. You will have to @@ -2003,24 +2003,23 @@ eicpy_ext_len (ei, ei6, ei6len, Qbinary); \ } while (0) -#define eicpy_ext_len(ei, extdata, extlen, coding_system) \ +#define eicpy_ext_len(ei, extdata, extlen, codesys) \ do { \ const Extbyte *ei7 = (extdata); \ int ei7len = (extlen); \ \ - TO_INTERNAL_FORMAT (DATA, (ei7, ei7len), \ - ALLOCA, ((ei)->data_, (ei)->bytelen_), \ - coding_system); \ + SIZED_EXTERNAL_TO_SIZED_C_STRING (ei7, ei7len, (ei)->data_, \ + (ei)->bytelen_, codesys); \ (ei)->max_size_allocated_ = (ei)->bytelen_ + 1; \ (ei)->charlen_ = bytecount_to_charcount ((ei)->data_, (ei)->bytelen_); \ } while (0) -#define eicpy_ext(ei, extdata, coding_system) \ -do { \ - const Extbyte *ei8 = (extdata); \ - \ - eicpy_ext_len (ei, ei8, dfc_external_data_len (ei8, coding_system), \ - coding_system); \ +#define eicpy_ext(ei, extdata, codesys) \ +do { \ + const Extbyte *ei8 = (extdata); \ + \ + eicpy_ext_len (ei, ei8, dfc_external_data_len (ei8, codesys), \ + codesys); \ } while (0) #define eicpy_lbuf(eistr, lisp_buf, off, charoff, len, charlen) \ @@ -2312,7 +2311,7 @@ /* ----- Converting to an external format ----- */ -#define eito_external(ei, coding_system) \ +#define eito_external(ei, codesys) \ do { \ if ((ei)->mallocp_) \ { \ @@ -2323,12 +2322,12 @@ } \ TO_EXTERNAL_FORMAT (DATA, ((ei)->data_, (ei)->bytelen_), \ MALLOC, ((ei)->extdata_, (ei)->extlen_), \ - coding_system); \ + codesys); \ } \ else \ TO_EXTERNAL_FORMAT (DATA, ((ei)->data_, (ei)->bytelen_), \ ALLOCA, ((ei)->extdata_, (ei)->extlen_), \ - coding_system); \ + codesys); \ } while (0) #define eiextdata(ei) ((ei)->extdata_) @@ -2457,10 +2456,57 @@ /* */ /************************************************************************/ /* - All client code should use only the two macros - - TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system) - TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system) + The macros below are used for converting data between different formats. + Generally, the data is textual, and the formats are related to + internationalization (e.g. converting between internal-format text and + UTF-8) -- but the mechanism is general, and could be used for anything, + e.g. decoding gzipped data. + + In general, conversion involves a source of data, a sink, the existing + format of the source data, and the desired format of the sink. The + macros below, however, always require that either the source or sink is + internal-format text. Therefore, in practice the conversions below + involve source, sink, an external format (specified by a coding system), + and the direction of conversion (internal->external or vice-versa). + + Sources and sinks can be raw data (sized or unsized -- when unsized, + input data is assumed to be null-terminated [double null-terminated for + Unicode-format data], and on output the length is not stored anywhere), + Lisp strings, Lisp buffers, lstreams, and opaque data objects. When the + output is raw data, the result can be allocated either with alloca() or + malloc(). (There is currently no provision for writing into a fixed + buffer. If you want this, use alloca() output and then copy the data -- + but be careful with the size! Unless you are very sure of the encoding + being used, upper bounds for the size are not in general computable.) + The obvious restrictions on source and sink types apply (e.g. Lisp + strings are a source and sink only for internal data). + + All raw data outputted will contain an extra null byte (two bytes for + Unicode -- currently, in fact, all output data, whether internal or + external, is double-null-terminated, but you can't count on this; see + below). This means that enough space is allocated to contain the extra + nulls; however, these nulls are not reflected in the returned output + size. + + The most basic macros are TO_EXTERNAL_FORMAT and TO_INTERNAL_FORMAT. + These can be used to convert between any kinds of sources or sinks. + However, 99% of conversions involve raw data or Lisp strings as both + source and sink, and usually data is output as alloca() rather than + malloc(). For this reason, convenience macros are defined for many types + of conversions involving raw data and/or Lisp strings, especially when + the output is an alloca()ed string. (When the destination is a + Lisp_String, there are other functions that should be used instead -- + build_ext_string() and make_ext_string(), for example.) The convenience + macros are of two types -- the older kind that store the result into a + specified variable, and the newer kind that return the result. The newer + kind of macros don't exist when the output is sized data, because that + would have two return values. NOTE: All convenience macros are + ultimately defined in terms of TO_EXTERNAL_FORMAT and TO_INTERNAL_FORMAT. + Thus, any comments below about the workings of these macros also apply to + all convenience macros. + + TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, codesys) + TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, codesys) Typical use is @@ -2648,13 +2694,13 @@ void dfc_convert_to_external_format (dfc_conversion_type source_type, dfc_conversion_data *source, - Lisp_Object coding_system, + Lisp_Object codesys, dfc_conversion_type sink_type, dfc_conversion_data *sink); void dfc_convert_to_internal_format (dfc_conversion_type source_type, dfc_conversion_data *source, - Lisp_Object coding_system, + Lisp_Object codesys, dfc_conversion_type sink_type, dfc_conversion_data *sink); /* CPP Trickery */ @@ -2766,19 +2812,131 @@ #define DFC_LISP_BUFFER_USE_CONVERTED_DATA(sink) \ Lstream_delete (XLSTREAM (dfc_sink.lisp_object)) +/* #define TEST_NEW_DFC */ + /* Convenience macros for extremely common invocations */ -#define C_STRING_TO_EXTERNAL(in, out, coding_system) \ - TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_ALLOCA, out, coding_system) -#define C_STRING_TO_EXTERNAL_MALLOC(in, out, coding_system) \ - TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, coding_system) -#define EXTERNAL_TO_C_STRING(in, out, coding_system) \ - TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_ALLOCA, out, coding_system) -#define EXTERNAL_TO_C_STRING_MALLOC(in, out, coding_system) \ - TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, coding_system) -#define LISP_STRING_TO_EXTERNAL(in, out, coding_system) \ - TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_ALLOCA, out, coding_system) -#define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, coding_system) \ - TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_MALLOC, out, coding_system) +#ifdef TEST_NEW_DFC +#define C_STRING_TO_EXTERNAL(in, out, codesys) \ + do { * (Extbyte **) &(out) = \ + NEW_C_STRING_TO_EXTERNAL (in, codesys); } while (0) +#define SIZED_C_STRING_TO_EXTERNAL(in, inlen, out, codesys) \ + do { * (Extbyte **) &(out) = \ + NEW_SIZED_C_STRING_TO_EXTERNAL (in, inlen, codesys); } while (0) +#define EXTERNAL_TO_C_STRING(in, out, codesys) \ + do { * (Ibyte **) &(out) = \ + NEW_EXTERNAL_TO_C_STRING (in, codesys); } while (0) +#define SIZED_EXTERNAL_TO_C_STRING(in, inlen, out, codesys) \ + do { * (Ibyte **) &(out) = \ + NEW_SIZED_EXTERNAL_TO_C_STRING (in, inlen, codesys); } while (0) +#define LISP_STRING_TO_EXTERNAL(in, out, codesys) \ + do { * (Extbyte **) &(out) = \ + NEW_LISP_STRING_TO_EXTERNAL (in, codesys); } while (0) +#else +#define C_STRING_TO_EXTERNAL(in, out, codesys) \ + TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_ALLOCA, out, codesys) +#define SIZED_C_STRING_TO_EXTERNAL(in, inlen, out, codesys) \ + TO_EXTERNAL_FORMAT (DATA, (in, inlen), C_STRING_ALLOCA, out, codesys) +#define EXTERNAL_TO_C_STRING(in, out, codesys) \ + TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_ALLOCA, out, codesys) +#define SIZED_EXTERNAL_TO_C_STRING(in, inlen, out, codesys) \ + TO_INTERNAL_FORMAT (DATA, (in, inlen), C_STRING_ALLOCA, out, codesys) +#define LISP_STRING_TO_EXTERNAL(in, out, codesys) \ + TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_ALLOCA, out, codesys) +#endif /* TEST_NEW_DFC */ + +#define C_STRING_TO_SIZED_EXTERNAL(in, out, outlen, codesys) \ + TO_EXTERNAL_FORMAT (C_STRING, in, ALLOCA, (out, outlen), codesys) +#define SIZED_C_STRING_TO_SIZED_EXTERNAL(in, inlen, out, outlen, codesys) \ + TO_EXTERNAL_FORMAT (DATA, (in, inlen), ALLOCA, (out, outlen), codesys) +#define EXTERNAL_TO_SIZED_C_STRING(in, out, outlen, codesys) \ + TO_INTERNAL_FORMAT (C_STRING, in, ALLOCA, (out, outlen), codesys) +#define SIZED_EXTERNAL_TO_SIZED_C_STRING(in, inlen, out, outlen, codesys) \ + TO_INTERNAL_FORMAT (DATA, (in, inlen), ALLOCA, (out, outlen), codesys) +#define LISP_STRING_TO_SIZED_EXTERNAL(in, out, outlen, codesys) \ + TO_EXTERNAL_FORMAT (LISP_STRING, in, ALLOCA, (out, outlen), codesys) + +/* In place of EXTERNAL_TO_LISP_STRING(), use build_ext_string() and/or + make_ext_string(). */ + +#ifdef TEST_NEW_DFC +#define C_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ + do { * (Extbyte **) &(out) = \ + NEW_C_STRING_TO_EXTERNAL_MALLOC (in, codesys); } while (0) +#define EXTERNAL_TO_C_STRING_MALLOC(in, out, codesys) \ + do { * (Ibyte **) &(out) = \ + NEW_EXTERNAL_TO_C_STRING_MALLOC (in, codesys); } while (0) +#define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ + do { * (Extbyte **) &(out) = \ + NEW_LISP_STRING_TO_EXTERNAL_MALLOC (in, codesys); } while (0) +#else +#define C_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ + TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, codesys) +#define EXTERNAL_TO_C_STRING_MALLOC(in, out, codesys) \ + TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, codesys) +#define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ + TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_MALLOC, out, codesys) +#endif /* TEST_NEW_DFC */ + +enum new_dfc_src_type +{ + DFC_EXTERNAL, + DFC_SIZED_EXTERNAL, + DFC_INTERNAL, + DFC_SIZED_INTERNAL, + DFC_LISP_STRING +}; + +void *new_dfc_convert_malloc (const void *src, Bytecount src_size, + enum new_dfc_src_type type, Lisp_Object codesys); +void *new_dfc_convert_alloca (const char *srctext, void *alloca_data); +Bytecount new_dfc_convert_size (const char *srctext, const void *src, + Bytecount src_size, enum new_dfc_src_type type, + Lisp_Object codesys); + +/* Version of EXTERNAL_TO_C_STRING that *RETURNS* the translated string, + still in alloca() space. Requires some trickiness to do this, but gets + it done! */ + +/* NOTE: If you make two invocations of the dfc functions below in the same + subexpression and use the exact same expression for the source in both + cases, you will lose. In this unlikely case, you will get an abort, and + need to rewrite the code. +*/ + +/* We need to use ALLOCA_FUNCALL_OK here. Some compilers have been known + to choke when alloca() occurs as a funcall argument, and so we check + this in configure. Rewriting the expressions below to use a temporary + variable, so that the call to alloca() is outside of + new_dfc_convert_alloca(), won't help because the entire NEW_DFC call + could be inside of a function call. */ + +#define NEW_DFC_CONVERT_1_ALLOCA(src, src_size, type, codesys) \ + new_dfc_convert_alloca \ + (#src, ALLOCA_FUNCALL_OK (new_dfc_convert_size (#src, src, src_size, \ + type, codesys))) + +#define NEW_EXTERNAL_TO_C_STRING(src, codesys) \ + (Ibyte *) NEW_DFC_CONVERT_1_ALLOCA (src, -1, DFC_EXTERNAL, codesys) +#define NEW_EXTERNAL_TO_C_STRING_MALLOC(src, codesys) \ + (Ibyte *) new_dfc_convert_malloc (src, -1, DFC_EXTERNAL, codesys) +#define NEW_SIZED_EXTERNAL_TO_C_STRING(src, len, codesys) \ + (Ibyte *) NEW_DFC_CONVERT_1_ALLOCA (src, len, DFC_SIZED_EXTERNAL, codesys) +#define NEW_SIZED_EXTERNAL_TO_C_STRING_MALLOC(src, len, codesys) \ + (Ibyte *) new_dfc_convert_malloc (src, len, DFC_SIZED_EXTERNAL, codesys) +#define NEW_C_STRING_TO_EXTERNAL(src, codesys) \ + (Extbyte *) NEW_DFC_CONVERT_1_ALLOCA (src, -1, DFC_INTERNAL, codesys) +#define NEW_C_STRING_TO_EXTERNAL_MALLOC(src, codesys) \ + (Extbyte *) new_dfc_convert_malloc (src, -1, DFC_INTERNAL, codesys) +#define NEW_SIZED_C_STRING_TO_EXTERNAL(src, len, codesys) \ + (Extbyte *) NEW_DFC_CONVERT_1_ALLOCA (src, len, DFC_SIZED_INTERNAL, codesys) +#define NEW_SIZED_C_STRING_TO_EXTERNAL_MALLOC(src, len, codesys) \ + (Extbyte *) new_dfc_convert_malloc (src, len, DFC_SIZED_INTERNAL, codesys) +#define NEW_LISP_STRING_TO_EXTERNAL(src, codesys) \ + (Extbyte *) NEW_DFC_CONVERT_1_ALLOCA (LISP_TO_VOID (src), -1, \ + DFC_LISP_STRING, codesys) +#define NEW_LISP_STRING_TO_EXTERNAL_MALLOC(src, codesys) \ + (Extbyte *) new_dfc_convert_malloc (LISP_TO_VOID (src), -1, \ + DFC_LISP_STRING, codesys) /* Standins for various encodings, until we know them better */ #define Qcommand_argument_encoding Qnative @@ -2788,25 +2946,94 @@ #define Qmswindows_host_name_encoding Qmswindows_multibyte #define Qmswindows_service_name_encoding Qmswindows_multibyte -/* Standins for various X encodings, until we know them better */ +/* Standins for various X encodings, until we know them better. + + About encodings in X: + + X works with 5 different encodings: + + -- "Host Portable Character Encoding" == printable ASCII + space, tab, + newline + + -- STRING encoding == ASCII + Latin-1 + tab, newline + + -- Locale-specific encoding + + -- Compound text == STRING encoding + ISO-2022 escape sequences to + switch between different locale-specific encodings. + + -- ANSI C wide-character encoding + + The Host Portable Character Encoding (HPCE) is used for atom names, font + names, color names, keysyms, geometry strings, resource manager quarks, + display names, locale names, and various other things. When describing + such strings, the X manual typically says "If the ... is not in the Host + Portable Character Encoding, the result is implementation dependent." + + The wide-character encoding is used only in the Xwc* functions, which + are provided as equivalents to Xmb* functions. + + STRING and compound text are used in the value of string properties and + selection data, both of which are values with an associated type atom, + which can be STRING or COMPOUND_TEXT. It can also be a locale name, as + specified in setlocale() (#### as usual, there is no normalization + whatsoever of these names). + + X also defines a type called "TEXT", which is used only as a requested + type, and produces data in a type "convenient to the owner". However, + there is some indication that X expects this to be the locale-specific + encoding. + + According to the glossary, the locale is used in + + -- Encoding and processing of input method text + -- Encoding of resource files and values + -- Encoding and imaging of text strings + -- Encoding and decoding for inter-client text communication + + The functions XmbTextListToTextProperty and XmbTextPropertyToTextList + (and Xwc* equivalents) can be used to convert between the + locale-specific encoding (XTextStyle), STRING (XStringStyle), and + compound text (XCompoundTextStyle), as well as XStdICCTextStyle, which + converts to STRING if possible, and if not, COMPOUND_TEXT. This is + used, for example, in XmbSetWMProperties, in the window_name and + icon_name properties (WM_NAME and WM_ICON_NAME), which are in the + locale-specific encoding on input, and are stored as STRING if possible, + COMPOUND_TEXT otherwise. + */ /* !!#### Need to verify the encoding used in lwlib -- Qnative or Qctext? Almost certainly the former. Use a standin for now. */ #define Qlwlib_encoding Qnative -#define Qx_atom_name_encoding Qctext -/* font names are often stored in atoms, so it gets sticky if we set this - to something different from atom-name encoding */ -#define Qx_font_name_encoding Qctext - -#define Qx_color_name_encoding Qctext - +/* The Host Portable Character Encoding. */ +#define Qx_hpc_encoding Qnative + +#define Qx_atom_name_encoding Qx_hpc_encoding +#define Qx_font_name_encoding Qx_hpc_encoding +#define Qx_color_name_encoding Qx_hpc_encoding +#define Qx_keysym_encoding Qx_hpc_encoding +#define Qx_geometry_encoding Qx_hpc_encoding +#define Qx_resource_name_encoding Qx_hpc_encoding +#define Qx_application_class_encoding Qx_hpc_encoding /* the following probably must agree with Qcommand_argument_encoding and Qenvironment_variable_encoding */ -#define Qx_display_name_encoding Qnative +#define Qx_display_name_encoding Qx_hpc_encoding +#define Qx_xpm_data_encoding Qx_hpc_encoding + +/* RedHat 6.2 contains a locale called "Francais" with the C-cedilla + encoded in ISO2022! */ +#define Qlocale_name_encoding Qctext #define Qstrerror_encoding Qnative +/* Encoding for strings coming from Offix drag-n-drop */ +#define Qoffix_dnd_encoding Qnative + +/* !!#### This exists to remind us that our hexify routine is totally + un-Muleized. */ +#define Qdnd_hexify_encoding Qascii + #define GET_STRERROR(var, num) \ do { \ int __gsnum__ = (num); \ diff -r d9d08dc5e617 -r b531bf8658e9 src/toolbar.c --- a/src/toolbar.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/toolbar.c Fri Feb 21 06:57:21 2003 +0000 @@ -1,7 +1,7 @@ /* Generic toolbar implementation. Copyright (C) 1995 Board of Trustees, University of Illinois. Copyright (C) 1995 Sun Microsystems, Inc. - Copyright (C) 1995, 1996 Ben Wing. + Copyright (C) 1995, 1996, 2003 Ben Wing. Copyright (C) 1996 Chuck Thompson. This file is part of XEmacs. @@ -257,8 +257,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 */ - int depth = enter_redisplay_critical_section (); + int depth = begin_hold_frame_size_changes (); set_specifier_fallback (Vtoolbar[cur], list1 (Fcons (Qnil, Qnil))); set_specifier_fallback (Vtoolbar[new], Vdefault_toolbar); set_specifier_fallback (Vtoolbar_size[cur], list1 (Fcons (Qnil, Qzero))); @@ -275,7 +274,7 @@ set_specifier_fallback (Vtoolbar_visible_p[new], Vdefault_toolbar_visible_p); Vdefault_toolbar_position = position; - exit_redisplay_critical_section (depth); + unbind_to (depth); } return position; diff -r d9d08dc5e617 -r b531bf8658e9 src/unicode.c --- a/src/unicode.c Thu Feb 20 22:52:51 2003 +0000 +++ b/src/unicode.c Fri Feb 21 06:57:21 2003 +0000 @@ -54,7 +54,11 @@ something evil and unpredictable? Signaling an error is OK: for all national standards, the national to Unicode map is an inclusion (1-to-1). Any character set that does not behave that way is - broken according to the Unicode standard. */ + broken according to the Unicode standard. + + Answer: You will get an abort(), since the purpose of the sledgehammer + routines is self-checking. The above problem with non-1-to-1 mapping + occurs in the Big5 tables, as provided by the Unicode Consortium. */ /* #define SLEDGEHAMMER_CHECK_UNICODE */ @@ -164,7 +168,10 @@ #ifdef MULE /* #### Using ints for to_unicode is OK (as long as they are >= 32 bits). - However, shouldn't the shorts below be unsigned? */ + However, shouldn't the shorts below be unsigned? + + Answer: Doesn't matter because the values being converted to are only + 96x96. */ static int *to_unicode_blank_1; static int **to_unicode_blank_2; @@ -299,7 +306,11 @@ for (i = 0; i < 256; i++) { /* #### IMWTK: Why does using -1 here work? Simply because there are - no existing 96x96 charsets? */ + no existing 96x96 charsets? + + Answer: I don't understand the concern. -1 indicates there is no + entry for this particular codepoint, which is always the case for + blank tables. */ from_unicode_blank_1[i] = (short) -1; from_unicode_blank_2[i] = from_unicode_blank_1; from_unicode_blank_3[i] = from_unicode_blank_2; @@ -354,7 +365,7 @@ } /* Allocate and blank the tables. - Loading them up is done by parse-unicode-translation-table. */ + Loading them up is done by load-unicode-mapping-table. */ void init_charset_unicode_tables (Lisp_Object charset) { @@ -1055,6 +1066,8 @@ The language-specific precedence list is meant to be set as part of the language environment initialization; the default precedence list is meant to be set by the user. + +#### NOTE: This interface may be changed. */ ()) { @@ -1073,13 +1086,17 @@ precedence, respectively. This means that users are sometimes going to want to set Vlanguage_unicode_precedence_list. Furthermore, this should be language-local (buffer-local would be a - reasonable approximation). */ + reasonable approximation). + + Answer: You are right, this needs rethinking. */ DEFUN ("set-language-unicode-precedence-list", Fset_language_unicode_precedence_list, 1, 1, 0, /* Set the language-specific precedence of charsets in Unicode decoding. LIST is a list of charsets. See `unicode-precedence-list' for more information. + +#### NOTE: This interface may be changed. */ (list)) { @@ -1098,6 +1115,8 @@ 0, 0, 0, /* Return the language-specific precedence list used for Unicode decoding. See `unicode-precedence-list' for more information. + +#### NOTE: This interface may be changed. */ ()) { @@ -1110,6 +1129,8 @@ Set the default precedence list used for Unicode decoding. This is intended to be set by the user. See `unicode-precedence-list' for more information. + +#### NOTE: This interface may be changed. */ (list)) { @@ -1128,6 +1149,8 @@ 0, 0, 0, /* Return the default precedence list used for Unicode decoding. See `unicode-precedence-list' for more information. + +#### NOTE: This interface may be changed. */ ()) { @@ -1259,9 +1282,7 @@ return Qnil; } -/* #### shouldn't this interface be called load-unicode-mapping-table - for consistency with Unicode Consortium terminology? */ -DEFUN ("parse-unicode-translation-table", Fparse_unicode_translation_table, +DEFUN ("load-unicode-mapping-table", Fload_unicode_mapping_table, 2, 6, 0, /* Load Unicode tables with the Unicode mapping data in FILENAME for CHARSET. Data is text, in the form of one translation per line -- charset @@ -1331,7 +1352,7 @@ big5 = 1; else invalid_constant - ("Unrecognized `parse-unicode-translation-table' flag", elt); + ("Unrecognized `load-unicode-mapping-table' flag", elt); } } @@ -2315,7 +2336,7 @@ DEFSUBR (Fdefault_unicode_precedence_list); DEFSUBR (Fset_unicode_conversion); - DEFSUBR (Fparse_unicode_translation_table); + DEFSUBR (Fload_unicode_mapping_table); DEFSYMBOL (Qignore_first_column); #endif /* MULE */