Hamish Macdonald <hamishm(a)lucent.com> writes:
Now that GNOME ships with a (mostly-working) session manager,
I'm
thinking an interesting project might be to extend XEmacs to take
advantage of those session manager capabilities
Kondara, a Japanese GNU/Linux distribution, has its own version of
XEmacs which supports XSMP and XDND. Attached patch is extracted from
ftp://ftp.kondara.org/pub/Kondara/SRPMS/SRPMS/xemacs-21.1.9-1k9.nosrc.rpm.
I don't understand this code. Does it fit your plan?
diff -ur -x configure xemacs-21.1.9/configure.in xemacs-21.1.9-new/configure.in
--- xemacs-21.1.9/configure.in Wed Feb 9 10:40:53 2000
+++ xemacs-21.1.9-new/configure.in Sat Feb 19 18:53:13 2000
@@ -474,6 +474,7 @@
with_dragndrop | \
with_cde | \
with_offix | \
+ with_xdnd | \
with_gpm | \
with_xpm | \
with_xface | \
@@ -2537,7 +2538,7 @@
dnl if test "$with_tty" = "no" ; then
dnl AC_MSG_ERROR([No window system support and no TTY support - Unable to proceed.])
dnl fi
- for feature in tooltalk cde offix session xim xmu \
+ for feature in tooltalk cde offix xdnd session xim xmu \
xface
do
if eval "test -n \"\$with_${feature}\" -a
\"\$with_${feature}\" != no" ; then
@@ -2566,6 +2567,14 @@
dnl if test "$with_session" = "yes"; then
if test "$with_session" != "no"; then
AC_DEFINE(HAVE_SESSION)
+ dnl XSMP session management
+ AC_CHECK_LIB(SM, SmcOpenConnection, have_xsmp=yes, have_xsmp=no)
+ if test "$have_xsmp" != "no"; then
+ AC_DEFINE(HAVE_XSMP)
+ XE_ADD_OBJS(xsmp.o)
+ XE_PREPEND(-lICE, libs_x)
+ XE_PREPEND(-lSM, libs_x)
+ fi
fi
dnl Autodetect Xauth
@@ -2659,6 +2668,19 @@
XE_APPEND(OffiX, dragndrop_proto)
fi
+dnl Xdnd Drag'n'Drop support
+test "$window_system" != "x11" && with_xdnd=no
+if test "$with_dragndrop" = no; then
+ AC_MSG_WARN([No Xdnd without generic Drag'n'Drop support])
+ with_xdnd=no
+fi
+test -z "$with_xdnd" && with_xdnd=no
+if test "$with_xdnd" = "yes"; then
+ AC_DEFINE(HAVE_XDND_DND)
+ XE_APPEND(xdnd.o, dnd_objs)
+ XE_APPEND(Xdnd, dragndrop_proto)
+fi
+
dnl Autodetect Drag'n'Drop support
dnl always included if CDE, Offix, or MSWindows are defined
AC_MSG_CHECKING(if drag and drop API is needed)
@@ -3036,9 +3058,9 @@
fi
dnl Back to our regularly scheduled wnn hunting
if test -z "$with_wnn" -o "$with_wnn" = "yes"; then
- AC_CHECK_LIB(wnn,jl_dic_list_e,libwnn=wnn,
+ AC_CHECK_LIB(wnn6,jl_dic_list_e,libwnn=wnn6,
AC_CHECK_LIB(wnn4,jl_dic_list_e,libwnn=wnn4,
- AC_CHECK_LIB(wnn6,jl_dic_list_e,libwnn=wnn6,
+ AC_CHECK_LIB(wnn,jl_dic_list_e,libwnn=wnn,
AC_CHECK_LIB(wnn6_fromsrc,dic_list_e,libwnn=wnn6_fromsrc,with_wnn=no))))
fi
test -z "$with_wnn" && with_wnn=yes
@@ -4079,6 +4101,7 @@
test "$with_cde" = yes && echo " Compiling in support for
CDE."
test "$with_tooltalk" = yes && echo " Compiling in support for
ToolTalk."
test "$with_offix" = yes && echo " Compiling in support for
OffiX."
+test "$with_xdnd" = yes && echo " Compiling in support for
Xdnd."
test "$with_dragndrop" = yes && echo " Compiling in EXPERIMENTAL
support for Drag'n'Drop ($dragndrop_proto )."
test "$with_workshop" = yes && echo " Compiling in support for
Sun WorkShop."
test "$with_session" != no && echo " Compiling in support for
proper session-management."
diff -ur -x configure xemacs-21.1.9/configure.usage xemacs-21.1.9-new/configure.usage
--- xemacs-21.1.9/configure.usage Wed Aug 12 06:53:33 1998
+++ xemacs-21.1.9-new/configure.usage Sat Feb 19 18:53:13 2000
@@ -82,6 +82,7 @@
*WARNING* The Drag'n'drop support is under development
and is considered experimental.
--with-cde (*) Compile in support for CDE drag and drop.
+--with-xdnd (*) Compile in support for Xdnd drag and drop.
--with-offix (*) Compile in support for OffiX drag and drop.
*WARNING* If you compile in OffiX, you may not be
able to use multiple X displays success-
diff -ur -x configure xemacs-21.1.9/lib-src/gnuslib.c xemacs-21.1.9-new/lib-src/gnuslib.c
--- xemacs-21.1.9/lib-src/gnuslib.c Thu Feb 26 15:03:26 1998
+++ xemacs-21.1.9-new/lib-src/gnuslib.c Sat Feb 19 18:53:13 2000
@@ -434,7 +434,7 @@
#else
while ((length = read(s,buffer,GSERV_BUFSZ)) > 0 ||
(length == -1 && errno == EINTR)) {
- if (length) {
+ if (length > 0) {
buffer[length] = '\0';
if (echo) {
fputs(buffer,stdout);
diff -ur -x configure xemacs-21.1.9/lisp/dialog.el xemacs-21.1.9-new/lisp/dialog.el
--- xemacs-21.1.9/lisp/dialog.el Sun Nov 9 16:06:29 1997
+++ xemacs-21.1.9-new/lisp/dialog.el Sat Feb 19 18:53:13 2000
@@ -103,9 +103,9 @@
An ITEM may also be nil--that means to put all preceding items
on the left of the dialog box and all following items on the right."
(cond
- ((eventp position)
+ ((and (eventp position) (frame-live-p (event-frame position)))
(select-frame (event-frame position)))
- ((framep position)
+ ((frame-live-p position)
(select-frame position))
((windowp position)
(select-window position)))
diff -ur -x configure xemacs-21.1.9/lisp/dumped-lisp.el
xemacs-21.1.9-new/lisp/dumped-lisp.el
--- xemacs-21.1.9/lisp/dumped-lisp.el Sun Aug 15 10:29:51 1999
+++ xemacs-21.1.9-new/lisp/dumped-lisp.el Sat Feb 19 18:53:13 2000
@@ -176,6 +176,7 @@
window-system toolbar) "toolbar-items")
(when-feature x "x-win-xfree86")
(when-feature x "x-win-sun")
+ (when-feature x "xsmp")
;; preload the mswindows code.
(when-feature mswindows "msw-glyphs")
(when-feature mswindows "msw-faces")
diff -ur -x configure xemacs-21.1.9/lisp/files.el xemacs-21.1.9-new/lisp/files.el
--- xemacs-21.1.9/lisp/files.el Tue Feb 8 11:54:41 2000
+++ xemacs-21.1.9-new/lisp/files.el Sat Feb 19 18:53:13 2000
@@ -2476,17 +2476,18 @@
;; We should fix the dialog box rather than disabling
;; this! --hniksic
- (list (list ?\C-r (lambda (buf)
- ;; #### FSF has an EXIT-ACTION argument
- ;; to `view-buffer'.
- (view-buffer buf)
- (setq view-exit-action
- (lambda (ignore)
- (exit-recursive-edit)))
- (recursive-edit)
- ;; Return nil to ask about BUF again.
- nil)
- "display the current buffer"))))
+; (list (list ?\C-r (lambda (buf)
+; ;; #### FSF has an EXIT-ACTION argument
+; ;; to `view-buffer'.
+; (view-buffer buf)
+; (setq view-exit-action
+; (lambda (ignore)
+; (exit-recursive-edit)))
+; (recursive-edit)
+; ;; Return nil to ask about BUF again.
+; nil)
+; "display the current buffer"))
+ ))
(abbrevs-done
(and save-abbrevs abbrevs-changed
(progn
diff -ur -x configure xemacs-21.1.9/lisp/gnuserv.el xemacs-21.1.9-new/lisp/gnuserv.el
--- xemacs-21.1.9/lisp/gnuserv.el Tue Feb 8 11:54:42 2000
+++ xemacs-21.1.9-new/lisp/gnuserv.el Sun Feb 20 06:21:57 2000
@@ -333,11 +333,15 @@
;;
;; ID - file descriptor of the given client;
;; <text> - the actual contents of the request.
+(defun discard-one-request (string)
+ (if (string-match "\C-d" string)
+ (substring string (+ 1 (string-match "\C-d" string)))
+ ""))
(defun gnuserv-process-filter (proc string)
"Process gnuserv client requests to execute Emacs commands."
(setq gnuserv-string (concat gnuserv-string string))
;; C-d means end of request.
- (when (string-match "\C-d\\'" gnuserv-string)
+ (while (string-match "\C-d" gnuserv-string)
(cond ((string-match "^[0-9]+" gnuserv-string) ; client request id
(let ((header (read-from-string gnuserv-string)))
;; Set the client we are talking to.
@@ -346,18 +350,15 @@
(condition-case oops
(eval (car (read-from-string gnuserv-string (cdr header))))
;; In case of an error, write the description to the
- ;; client, and then signal it.
- (error (setq gnuserv-string "")
- (when gnuserv-current-client
- (gnuserv-write-to-client gnuserv-current-client oops))
+ ;; client
+ (error (gnuserv-write-to-client (car header) oops)
(setq gnuserv-current-client nil)
- (signal (car oops) (cdr oops)))
- (quit (setq gnuserv-string "")
- (when gnuserv-current-client
- (gnuserv-write-to-client gnuserv-current-client oops))
- (setq gnuserv-current-client nil)
- (signal 'quit nil)))
- (setq gnuserv-string "")))
+ (unless gnuserv-process
+ (signal (car oops) (cdr oops))))
+ (quit (gnuserv-write-to-client (car header) oops)
+ (setq gnuserv-current-client nil)))
+ (setq gnuserv-string
+ (discard-one-request gnuserv-string))))
(t
(error "%s: invalid response from gnuserv" gnuserv-string)
(setq gnuserv-string "")))))
diff -ur -x configure xemacs-21.1.9/lisp/xsmp.el xemacs-21.1.9-new/lisp/xsmp.el
--- xemacs-21.1.9/lisp/xsmp.el Sun Feb 20 06:24:42 2000
+++ xemacs-21.1.9-new/lisp/xsmp.el Sat Feb 19 18:53:13 2000
@@ -0,0 +1,31 @@
+;; XSMP support for XEmacs
+;; created Feb 13 2000 by Akira Higuchi <a(a)kondara.org>
+;;
+
+(defun xsmp-save-yourself (shutdown)
+ (save-some-buffers nil t)
+ (and (or (not (memq t (mapcar #'(lambda (buf) (and (buffer-file-name buf)
+ (buffer-modified-p buf)))
+ (buffer-list))))
+ (not shutdown)
+ (yes-or-no-p "Modified buffers exist; exit anyway? "))
+ (or (not (fboundp 'process-list))
+ ;; process-list is not defined on VMS.
+ (let ((processes (process-list))
+ active)
+ (while processes
+ (and (memq (process-status (car processes)) '(run stop open))
+ (let ((val (process-kill-without-query (car processes))))
+ (process-kill-without-query (car processes) val)
+ val)
+ (setq active t))
+ (setq processes (cdr processes)))
+ (or
+ (not active)
+ (save-excursion
+ (save-window-excursion
+ (delete-other-windows)
+ (list-processes)
+ (yes-or-no-p
+ "Active processes exist; kill them and exit anyway? "))))))
+ ))
diff -ur -x configure xemacs-21.1.9/lwlib/lwlib-Xaw.c xemacs-21.1.9-new/lwlib/lwlib-Xaw.c
--- xemacs-21.1.9/lwlib/lwlib-Xaw.c Mon Jan 19 10:57:47 1998
+++ xemacs-21.1.9-new/lwlib/lwlib-Xaw.c Sat Feb 19 18:53:13 2000
@@ -491,16 +491,22 @@
LWLIB_ID id;
Widget *kids = 0;
Widget widget;
- Arg al [1];
+ Arg al [2];
+ Cardinal i, nkids = 0;
if (! XtIsSubclass (shell, shellWidgetClass))
abort ();
XtSetArg (al [0], XtNchildren, &kids);
- XtGetValues (shell, al, 1);
- if (!kids || !*kids)
- abort ();
- widget = kids [0];
- if (! XtIsSubclass (widget, dialogWidgetClass))
+ XtSetArg (al [1], XtNnumChildren, &nkids);
+ XtGetValues (shell, al, 2);
+ if (!kids)
abort ();
+ for (i = 0; i < nkids; i++, kids++)
+ {
+ widget = kids[0];
+ if (XtIsSubclass (widget, dialogWidgetClass))
+ break;
+ }
+ if (i == kids) abort ();
id = lw_get_widget_id (widget);
if (! id) abort ();
diff -ur -x configure xemacs-21.1.9/lwlib/xlwmenu.c xemacs-21.1.9-new/lwlib/xlwmenu.c
--- xemacs-21.1.9/lwlib/xlwmenu.c Sun Jun 13 14:16:45 1999
+++ xemacs-21.1.9-new/lwlib/xlwmenu.c Sat Feb 19 18:53:13 2000
@@ -2649,7 +2649,7 @@
xgcv.foreground = mw->menu.foreground;
xgcv.background = mw->core.background_pixel;
- xgcv.fill_style = FillStippled;
+ xgcv.fill_style = FillOpaqueStippled;
xgcv.stipple = mw->menu.gray_pixmap;
mw->menu.inactive_gc = XtGetGC ((Widget)mw,
(flags | GCFillStyle | GCStipple),
@@ -2667,7 +2667,7 @@
xgcv.background = mw->core.background_pixel;
mw->menu.button_gc = XtGetGC ((Widget)mw, flags, &xgcv);
- xgcv.fill_style = FillStippled;
+ xgcv.fill_style = FillOpaqueStippled;
xgcv.stipple = mw->menu.gray_pixmap;
mw->menu.inactive_button_gc = XtGetGC ((Widget)mw,
(flags | GCFillStyle | GCStipple),
diff -ur -x configure xemacs-21.1.9/src/Makefile.in.in
xemacs-21.1.9-new/src/Makefile.in.in
--- xemacs-21.1.9/src/Makefile.in.in Sat Jun 20 09:58:42 1998
+++ xemacs-21.1.9-new/src/Makefile.in.in Sat Feb 19 18:53:14 2000
@@ -283,9 +283,9 @@
all: ${other_files}
# endif /* EXTERNAL_WIDGET */
-# if defined (HAVE_OFFIX_DND) || defined (HAVE_CDE)
+# if defined (HAVE_XDND_DND) || (HAVE_OFFIX_DND) || defined (HAVE_CDE)
dnd_objs = @dnd_objs@
-# endif /* HAVE_OFFIX_DND || HAVE_CDE */
+# endif /* HAVE_XDND_DND || HAVE_OFFIX_DND || HAVE_CDE */
X11_objs = EmacsFrame.o EmacsShell.o TopLevelEmacsShell.o TransientEmacsShell.o
EmacsManager.o $(external_widget_objs) $(dnd_objs)
#endif /* HAVE_X_WINDOWS */
diff -ur -x configure xemacs-21.1.9/src/config.h.in xemacs-21.1.9-new/src/config.h.in
--- xemacs-21.1.9/src/config.h.in Wed Jul 7 12:10:32 1999
+++ xemacs-21.1.9-new/src/config.h.in Sat Feb 19 18:53:14 2000
@@ -443,11 +443,17 @@
/* Compile in support for OffiX Drag and Drop? */
#undef HAVE_OFFIX_DND
+/* Compile in support for Xdnd Drag and Drop? */
+#undef HAVE_XDND_DND
+
/* Compile in generic Drag'n'Drop API */
#undef HAVE_DRAGNDROP
/* Compile in support for proper session-management. */
#undef HAVE_SESSION
+
+/* Compile in support for XSMP session-management */
+#undef HAVE_XSMP
/* Define this if you want Mule support (multi-byte character support).
There may be some performance penalty, although it should be small
diff -ur -x configure xemacs-21.1.9/src/device-x.c xemacs-21.1.9-new/src/device-x.c
--- xemacs-21.1.9/src/device-x.c Sat Dec 4 13:13:05 1999
+++ xemacs-21.1.9-new/src/device-x.c Sat Feb 19 18:53:15 2000
@@ -49,9 +49,15 @@
#include "sysfile.h"
#include "systime.h"
+#ifdef HAVE_XSMP
+#include "xsmp.h"
+#endif
#ifdef HAVE_OFFIX_DND
#include "offix.h"
#endif
+#ifdef HAVE_XDND_DND
+#include "xdnd.h"
+#endif
Lisp_Object Vdefault_x_device;
#if defined(MULE) && (defined(LWLIB_MENUBARS_MOTIF) || defined(HAVE_XIM) ||
defined (USE_XFONTSET))
@@ -557,9 +563,15 @@
}
#endif /* HAVE_SESSION */
+#ifdef HAVE_XSMP
+ XSMPInitialize (d, app_shell);
+#endif
#ifdef HAVE_OFFIX_DND
DndInitialize ( app_shell );
+#endif
+#ifdef HAVE_XDND_DND
+ XDndInitialize ( app_shell );
#endif
Vx_initial_argv_list = make_arg_list (argc, argv);
diff -ur -x configure xemacs-21.1.9/src/dragdrop.c xemacs-21.1.9-new/src/dragdrop.c
--- xemacs-21.1.9/src/dragdrop.c Fri Oct 16 07:29:17 1998
+++ xemacs-21.1.9-new/src/dragdrop.c Sat Feb 19 18:53:15 2000
@@ -139,4 +139,7 @@
#ifdef HAVE_OFFIX_DND
Vdragdrop_protocols = Fcons ( intern ("offix") , Vdragdrop_protocols );
#endif
+#ifdef HAVE_XDND_DND
+ Vdragdrop_protocols = Fcons ( intern ("xdnd") , Vdragdrop_protocols );
+#endif
}
diff -ur -x configure xemacs-21.1.9/src/emacs.c xemacs-21.1.9-new/src/emacs.c
--- xemacs-21.1.9/src/emacs.c Sat Dec 4 13:13:05 1999
+++ xemacs-21.1.9-new/src/emacs.c Sat Feb 19 18:53:15 2000
@@ -47,6 +47,10 @@
#include "sysdll.h"
#endif
+#ifdef HAVE_XSMP
+#include "xsmp.h"
+#endif
+
#if defined (HAVE_LOCALE_H) && \
(defined (I18N2) || defined (I18N3) || defined (I18N4))
#include <locale.h>
@@ -734,6 +738,19 @@
argmatch (argv, argc, "-V", 0, 2, NULL, &skip_args))
noninteractive = 1, skip_args--;
+#ifdef HAVE_XSMP
+ {
+ char *client_id;
+ char *command_str;
+ if (argmatch (argv, argc, "-sm-client-id", "--sm-client-id", 12,
+ &client_id, &skip_args))
+ XSMPSetClientID(client_id);
+ if (argmatch (argv, argc, "-sm-restart-command",
"--sm-restart-command",
+ 16, &command_str, &skip_args))
+ XSMPSetRestartCommand(command_str);
+ }
+#endif
+
/* Now, figure out which type of console is our first console. */
display_arg = 0;
@@ -805,7 +822,7 @@
#endif /* HAVE_WINDOW_SYSTEM */
noninteractive1 = noninteractive;
-
+
/****** Now initialize everything *******/
/* First, do really basic environment initialization -- catching signals
@@ -899,6 +916,9 @@
#ifdef HAVE_DRAGNDROP
syms_of_dragdrop ();
#endif
+#ifdef HAVE_XSMP
+ syms_of_xsmp ();
+#endif
syms_of_event_stream ();
syms_of_events ();
syms_of_extents ();
@@ -1742,10 +1762,12 @@
{ "-t", "--terminal", 95, 1 },
{ "-nw", "--no-windows", 90, 0 },
{ "-batch", "--batch", 85, 0 },
- { "-debug-paths", "--debug-paths", 82, 0 },
- { "-help", "--help", 80, 0 },
+ { "-debug-paths", "--debug-paths", 84, 0 },
+ { "-help", "--help", 83, 0 },
{ "-version", "--version", 75, 0 },
{ "-V", 0, 75, 0 },
+ { "-sm-client-id", "--sm-client-id", 82, 1 },
+ { "-sm-restart-command", "--sm-restart-command", 81, 1 },
{ "-d", "--display", 80, 1 },
{ "-display", 0, 80, 1 },
{ "-NXHost", 0, 79, 0 },
diff -ur -x configure xemacs-21.1.9/src/event-Xt.c xemacs-21.1.9-new/src/event-Xt.c
--- xemacs-21.1.9/src/event-Xt.c Thu Jun 17 05:45:57 1999
+++ xemacs-21.1.9-new/src/event-Xt.c Sat Feb 19 18:53:15 2000
@@ -66,6 +66,10 @@
#include "offix.h"
#endif
+#ifdef HAVE_XDND_DND
+#include "xdnd.h"
+#endif
+
#ifdef WINDOWSNT
/* Hmm, under unix we want X modifiers, under NT we want X modifiers if
we are running X and Windows modifiers otherwise.
@@ -1232,7 +1236,14 @@
break;
}
+
#endif /* HAVE_OFFIX_DND */
+
+#ifdef HAVE_XDND_DND
+ if (XDndExamineClientMessage(x_event))
+ return 0;
+#endif /* HAVE_XDND_DND */
+
if (ev->message_type == DEVICE_XATOM_WM_PROTOCOLS (d)
&& (Atom) (ev->data.l[0]) == DEVICE_XATOM_WM_TAKE_FOCUS (d)
&& (Atom) (ev->data.l[1]) == 0)
@@ -1242,7 +1253,57 @@
}
/* fall through */
- default: /* it's a magic event */
+ default:
+#ifdef HAVE_XDND_DND
+ if (x_event->type == SelectionNotify)
+ {
+ char *urilist;
+ struct frame *frame;
+ Lisp_Object l_type, l_dndlist, l_item;
+ struct gcpro gcpro1, gcpro2, gcpro3;
+
+ GCPRO3 (l_type, l_dndlist, l_item);
+
+ frame = x_any_window_to_frame (d, x_event->xselection.requestor);
+ if (!frame)
+ return 0;
+ XSETFRAME (emacs_event->channel, frame);
+
+ l_type = l_dndlist = l_item = Qnil;
+ urilist = XDndExamineSelectionNotify(x_event,
+ &(emacs_event->event.misc.x),
+ &(emacs_event->event.misc.y) );
+ if (urilist)
+ {
+ char *uri;
+ int i;
+ for (i = 0, uri = urilist; uri[0]; uri += i)
+ {
+ for (i = 0; uri[i] >= 32 && uri[i] != 0; i++);
+ if (i > 0)
+ {
+ l_item = make_string ((Bufbyte *)uri, i);
+ l_dndlist = Fcons (l_item, l_dndlist);
+ }
+ for ( ; uri[i] < 32 && uri[i] != 0; i++);
+ }
+ l_type = Qdragdrop_URL;
+ XFree (urilist);
+ /* emacs_event->event.misc.{x|y} are already set */
+ emacs_event->event_type = misc_user_event;
+ emacs_event->timestamp = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
+ emacs_event->event.misc.modifiers = 0;
+ emacs_event->event.misc.button = Button1;
+ emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
+ emacs_event->event.misc.object = Fcons (l_type, l_dndlist);
+ }
+ UNGCPRO;
+ if (urilist)
+ break;
+ }
+#endif
+
+ /* it's a magic event */
{
struct frame *frame;
Window w;
diff -ur -x configure xemacs-21.1.9/src/file-coding.c xemacs-21.1.9-new/src/file-coding.c
--- xemacs-21.1.9/src/file-coding.c Mon Jun 14 15:32:05 1999
+++ xemacs-21.1.9-new/src/file-coding.c Sat Feb 19 18:53:15 2000
@@ -3925,7 +3925,7 @@
charset = str->iso2022.charset[reg];
/* Error checking: */
- if (NILP (charset) || str->iso2022.invalid_designated[reg]
+ if (!CHARSETP(charset) || str->iso2022.invalid_designated[reg]
|| (((c & 0x7F) == ' ' || (c & 0x7F) == ISO_CODE_DEL)
&& XCHARSET_CHARS (charset) == 94))
/* Mrmph. We are trying to invoke a register that has no
diff -ur -x configure xemacs-21.1.9/src/frame-x.c xemacs-21.1.9-new/src/frame-x.c
--- xemacs-21.1.9/src/frame-x.c Sat Sep 25 23:51:26 1999
+++ xemacs-21.1.9-new/src/frame-x.c Sat Feb 19 18:53:16 2000
@@ -62,6 +62,10 @@
#include "events-mod.h"
#endif
+#ifdef HAVE_XDND_DND
+#include "xdnd.h"
+#endif
+
/* Default properties to use when creating frames. */
Lisp_Object Vdefault_x_frame_plist;
@@ -2093,6 +2097,14 @@
#ifdef HAVE_XIM
XIM_init_frame (f);
#endif /* HAVE_XIM */
+
+#ifdef HAVE_XSMP
+ XSMPInitWidget(shell_widget);
+#endif
+
+#ifdef HAVE_XDND_DND
+ XDndInitWidget(shell_widget);
+#endif
#ifdef HACK_EDITRES
/* Allow XEmacs to respond to EditRes requests. See the O'Reilly Xt */
diff -ur -x configure xemacs-21.1.9/src/input-method-xlib.c
xemacs-21.1.9-new/src/input-method-xlib.c
--- xemacs-21.1.9/src/input-method-xlib.c Mon Dec 6 13:31:48 1999
+++ xemacs-21.1.9-new/src/input-method-xlib.c Sat Feb 19 18:53:16 2000
@@ -337,7 +337,9 @@
if (!xim)
{
+#if 0
xim_info ("X Input Method open failed. Waiting for an XIM to be
enabled.\n");
+#endif
return;
}
diff -ur -x configure xemacs-21.1.9/src/intl.c xemacs-21.1.9-new/src/intl.c
--- xemacs-21.1.9/src/intl.c Sun Dec 14 12:52:05 1997
+++ xemacs-21.1.9-new/src/intl.c Sat Feb 19 18:53:16 2000
@@ -60,7 +60,9 @@
if (!input_method)
{
+#if 0
stderr_out ("WARNING: XOpenIM() failed...no input server\n");
+#endif
return;
}
diff -ur -x configure xemacs-21.1.9/src/mule-wnnfns.c xemacs-21.1.9-new/src/mule-wnnfns.c
--- xemacs-21.1.9/src/mule-wnnfns.c Sun Jul 12 16:30:42 1998
+++ xemacs-21.1.9-new/src/mule-wnnfns.c Sat Feb 19 18:53:16 2000
@@ -270,11 +270,19 @@
#include "window.h"
#include "sysdep.h"
-#include "wnn/commonhd.h"
+#if WNN6
+# include <wnn6/commonhd.h>
+#else
+# include <wnn/commonhd.h>
+#endif
#include "mule-charset.h"
-#include "wnn/jllib.h"
-#include "wnn/cplib.h"
-
+#if WNN6
+# include <wnn6/jllib.h>
+# include <wnn6/cplib.h>
+#else
+# include <wnn/jllib.h>
+# include <wnn/cplib.h>
+#endif
/* UCHAR が二重定義されるので */
#define _UCHAR_T
diff -ur -x configure xemacs-21.1.9/src/xdnd.c xemacs-21.1.9-new/src/xdnd.c
--- xemacs-21.1.9/src/xdnd.c Sun Feb 20 06:24:42 2000
+++ xemacs-21.1.9-new/src/xdnd.c Sat Feb 19 18:53:16 2000
@@ -0,0 +1,307 @@
+/*
+ * XDND drag-n-drop support for XEmacs
+ * created Dec 16 1999 by Akira Higuchi <a(a)kondara.org>
+ */
+
+#include <config.h>
+#include "systime.h"
+
+#include "xdnd.h"
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+
+#define DEBUG_DO(x)
+
+/* Display-wise atoms */
+#define XDND_XdndAware XInternAtom(d, "XdndAware", False)
+#define XDND_XdndPosition XInternAtom(d, "XdndPosition", False)
+#define XDND_XdndEnter XInternAtom(d, "XdndEnter", False)
+#define XDND_XdndLeave XInternAtom(d, "XdndLeave", False)
+#define XDND_XdndStatus XInternAtom(d, "XdndStatus", False)
+#define XDND_XdndDrop XInternAtom(d, "XdndDrop", False)
+#define XDND_XdndTypeList XInternAtom(d, "XdndTypeList", False)
+#define XDND_XdndActionCopy XInternAtom(d, "XdndActionCopy", False)
+#define XDND_XdndSelection XInternAtom(d, "XdndSelection", False)
+#define XDND_XdndFinished XInternAtom(d, "XdndFinished", False)
+#define XDND_atom_drop XInternAtom(d, "atom_drop", False)
+#define XDND_atom_urilist XInternAtom(d, "text/uri-list", False)
+
+#define XDND_DRAGGER_LOCK_TIMEOUT 30
+
+/*
+ * The following variables are set when we get XdndPosition message,
+ * and cleared when we get XdndLeave or SelectionNotify.
+ */
+static Display *dragger_display = NULL;
+static Window dragger_window = 0;
+static int drop_x = 0, drop_y = 0;
+static EMACS_TIME drag_time;
+
+void
+XDndInitialize(Widget shell)
+{
+ /* nothing to do */
+}
+
+void
+XDndInitWidget(Widget widget)
+{
+ Display *d;
+ Window w;
+ Atom version;
+
+ DEBUG_DO(printf("initializing window ...\n"));
+ d = XtDisplayOfObject(widget);
+ w = XtWindow(widget);
+ version = 3;
+ XChangeProperty(d, w, XDND_XdndAware, XA_ATOM, 32, PropModeReplace,
+ (unsigned char *)&version, 1);
+}
+
+static void
+send_finished(Window our_window)
+{
+ XEvent xev;
+ Display *d;
+ d = dragger_display;
+
+ DEBUG_DO(printf("send_finished\n"));
+ if (d == NULL || dragger_window == 0)
+ {
+ DEBUG_DO(printf("Why? send_finished failed\n"));
+ return;
+ }
+ memset (&xev, 0, sizeof(xev));
+ xev.xany.type = ClientMessage;
+ xev.xany.display = d;
+ xev.xclient.window = dragger_window;
+ xev.xclient.message_type = XDND_XdndFinished;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = our_window;
+ XSendEvent(d, dragger_window, 0, 0, &xev);
+}
+
+static int
+accept_drop_p(XEvent *ep)
+{
+ Display *d;
+ Window w;
+ EMACS_TIME current_time, time_diff;
+ long time_diff_long;
+
+ d = ep->xany.display;
+ w = ep->xany.window;
+ DEBUG_DO(printf("check if we accept drop\n"));
+ if ((dragger_display == NULL && dragger_window == 0) ||
+ (dragger_display == d && dragger_window == ep->xclient.data.l[0]))
+ {
+ DEBUG_DO(printf("OK. accept\n"));
+ return 1;
+ }
+ EMACS_GET_TIME(current_time);
+ EMACS_SUB_TIME(time_diff, current_time, drag_time);
+ if (EMACS_TIME_NEG_P(time_diff))
+ {
+ DEBUG_DO(printf("negative time. accept.\n"));
+ return 1;
+ }
+ EMACS_TIME_TO_INT(time_diff, time_diff_long);
+ if (time_diff_long > XDND_DRAGGER_LOCK_TIMEOUT)
+ {
+ DEBUG_DO(printf("timed out. accept.\n"));
+ return 1;
+ }
+ DEBUG_DO(printf("don't\n"));
+ return 0;
+}
+
+int
+XDndExamineClientMessage(XEvent *ep)
+{
+ Display *d;
+ Window w;
+
+ d = ep->xany.display;
+ w = ep->xany.window;
+ if (ep->xclient.message_type == XDND_XdndPosition)
+ {
+ XEvent xev;
+ DEBUG_DO(printf("XdndPosition %ld %ld\n",
+ ep->xclient.data.l[2] >> 16,
+ ep->xclient.data.l[2] & 0xffff));
+ memset (&xev, 0, sizeof(xev));
+ xev.xany.type = ClientMessage;
+ xev.xany.display = d;
+ xev.xclient.window = ep->xclient.data.l[0];
+ xev.xclient.message_type = XDND_XdndStatus;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = w;
+ if (accept_drop_p(ep))
+ {
+ xev.xclient.data.l[1] = 1; /* accept */
+ dragger_display = d;
+ dragger_window = ep->xclient.data.l[0];
+ drop_x = (ep->xclient.data.l[2] >> 16) & 0xffff;
+ drop_y = (ep->xclient.data.l[2] ) & 0xffff;
+ EMACS_GET_TIME(drag_time);
+ DEBUG_DO(printf("ACCEPT\n"));
+ }
+ else
+ {
+ /* Check timeout */
+ xev.xclient.data.l[1] = 0; /* reject */
+ DEBUG_DO(printf("REJECT\n"));
+ }
+ xev.xclient.data.l[2] = 0; /* x, y */
+ xev.xclient.data.l[3] = 0; /* w, h */
+ xev.xclient.data.l[4] = XDND_XdndActionCopy;
+ XSendEvent(d, ep->xclient.data.l[0],
+ 0, 0, &xev);
+ }
+ else if (ep->xclient.message_type == XDND_XdndEnter)
+ {
+ /* TODO: Check if the dragger supports text/uri-list */
+#if 0
+ int i;
+ unsigned long *buffer;
+ Atom actual_type;
+ int format;
+ unsigned long nitems, left;
+ buffer = NULL;
+ DEBUG_DO(printf("XdndEnter\n"));
+ XGetWindowProperty (d, ep->xclient.data.l[0],
+ XDND_XdndTypeList, 0, 65536/4, False, XA_ATOM,
+ &actual_type, &format, &nitems, &left,
+ (unsigned char **)&buffer);
+ for (i = 0; i < nitems; i++)
+ {
+ Atom a;
+ a = buffer[i];
+ DEBUG_DO(printf("%ld %s\n", a,
+ XGetAtomName (d, a)));
+ }
+#endif
+ }
+ else if (ep->xclient.message_type == XDND_XdndLeave)
+ {
+ DEBUG_DO(printf("XdndLeave\n"));
+ if (d == dragger_display && ep->xclient.data.l[0] == dragger_window)
+ {
+ DEBUG_DO(printf("clear dragger info\n"));
+ dragger_display = NULL;
+ dragger_window = 0;
+ }
+ }
+ else if (ep->xclient.message_type == XDND_XdndDrop)
+ {
+ DEBUG_DO(printf("XdndDrop\n"));
+ if (d == dragger_display && ep->xclient.data.l[0] == dragger_window)
+ {
+ DEBUG_DO(printf("convertselection\n"));
+ XConvertSelection(d, XDND_XdndSelection, XDND_atom_urilist,
+ XDND_atom_drop, w, CurrentTime);
+ }
+ else
+ {
+ send_finished(w);
+ }
+ }
+ else
+ {
+ DEBUG_DO(printf("unknown clientmessage\n"));
+ return 0;
+ }
+ return 1;
+}
+
+static void
+get_relative_offset (Window recvwin, int *x_r, int *y_r)
+{
+ Display *d;
+ Window w, root, parent;
+ int x, y;
+
+ d = dragger_display;
+ w = recvwin;
+ x = drop_x;
+ y = drop_y;
+ if (d == NULL || w == 0)
+ {
+ DEBUG_DO(printf("get_relative_offset: no dragger\n"));
+ return;
+ }
+ DEBUG_DO(printf("root offset %d %d\n", x, y));
+ do {
+ Window *children;
+ unsigned int nchildren, width, height, border, depth;
+ int rel_x, rel_y;
+ rel_x = rel_y = 0;
+ if (!XQueryTree(d, w, &root, &parent, &children, &nchildren))
+ return;
+ if (children)
+ XFree(children);
+ if (!XGetGeometry (d, w, &root, &rel_x, &rel_y, &width, &height,
+ &border, &depth))
+ return;
+ DEBUG_DO(printf("rel %d %d\n", rel_x, rel_y));
+ x -= rel_x; /* do we need to subtract 'border' too? */
+ y -= rel_y;
+ w = parent;
+ } while (parent != root);
+ *x_r = x;
+ *y_r = y;
+ DEBUG_DO(printf("offset %d %d\n", x, y));
+}
+
+char *
+XDndExamineSelectionNotify(XEvent *ep, int *x_r, int *y_r)
+{
+ Display *d;
+ Window w;
+ unsigned char *buffer;
+ Atom actual_type;
+ int format;
+ unsigned long nitems, left;
+ char *ret = NULL;
+
+ DEBUG_DO(printf("SelectionNotify 0x%lx\n", ep->xany.window));
+ DEBUG_DO(printf("selection 0x%lx property 0x%lx",
+ ep->xselection.selection,
+ ep->xselection.property));
+ d = ep->xany.display;
+ w = ep->xany.window;
+ if (ep->xselection.selection != XDND_XdndSelection)
+ return NULL;
+ if (ep->xselection.property != XDND_atom_drop)
+ {
+ DEBUG_DO(printf("WARNING: strange SelectionNotify event\n"));
+ /* return NULL; */
+ }
+
+ if (d != dragger_display)
+ {
+ /* Got SelectionNotify from unexpected dragger. Ignore it. */
+ DEBUG_DO(printf("dragger_display, display = %p, %p",
+ dragger_display, d));
+ return NULL;
+ }
+ DEBUG_DO(printf("got\n"));
+ XGetWindowProperty (d, w, XDND_atom_drop, 0, 65536, True,
+ XDND_atom_urilist, &actual_type, &format, &nitems,
+ &left, (unsigned char **)&ret);
+ buffer = NULL;
+ send_finished(w);
+ get_relative_offset(w, x_r, y_r);
+ dragger_display = NULL;
+ dragger_window = 0;
+ if (ret != NULL && left > 0)
+ {
+ /* Too long */
+ XFree(ret);
+ DEBUG_DO(printf("too long\n"));
+ ret = NULL;
+ }
+ return ret;
+}
diff -ur -x configure xemacs-21.1.9/src/xdnd.h xemacs-21.1.9-new/src/xdnd.h
--- xemacs-21.1.9/src/xdnd.h Sun Feb 20 06:24:42 2000
+++ xemacs-21.1.9-new/src/xdnd.h Sat Feb 19 18:53:16 2000
@@ -0,0 +1,16 @@
+/*
+ * XDND drag-n-drop support for XEmacs
+ * created Dec 16 1999 by Akira Higuchi <a(a)kondara.org>
+ */
+
+#ifndef _XEMACS_XDND_H_
+#define _XEMACS_XDND_H_
+
+#include "xintrinsic.h"
+
+void XDndInitialize(Widget shell);
+void XDndInitWidget(Widget widget);
+int XDndExamineClientMessage(XEvent *ep);
+char *XDndExamineSelectionNotify(XEvent *ep, int *x_r, int *y_r);
+
+#endif /* _XEMACS_XDND_H_ */
diff -ur -x configure xemacs-21.1.9/src/xsmp.c xemacs-21.1.9-new/src/xsmp.c
--- xemacs-21.1.9/src/xsmp.c Sun Feb 20 06:24:42 2000
+++ xemacs-21.1.9-new/src/xsmp.c Sat Feb 19 18:53:16 2000
@@ -0,0 +1,401 @@
+/*
+ * XSMP support for XEmacs
+ * created Feb 8 2000 by Akira Higuchi <a(a)kondara.org>
+ */
+
+#include <config.h>
+#include "xsmp.h"
+#include "lisp.h"
+#include "device.h"
+#include "buffer.h"
+#include "frame.h"
+#include "console-x.h"
+#include "EmacsFrameP.h"
+#include "events.h"
+
+#include <X11/SM/SMlib.h>
+#include <X11/Xatom.h>
+#include <X11/Core.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#define DEBUG_DO(x)
+
+static Lisp_Object Qxsmp_save_yourself;
+static Lisp_Object Qforce_dialog_box_use;
+static Lisp_Object Quse_dialog_box;
+
+static enum {
+ xsmp_state_normal,
+ xsmp_state_waiting_for_interact,
+ xsmp_state_interacting,
+ xsmp_state_waiting_for_save_complete,
+} xsmp_state = xsmp_state_normal;
+
+static char *xsmp_client_id = NULL;
+static char *xsmp_restart_command = NULL;
+
+static SmcConn smc_conn_current;
+static Bool shutdown_request, ready_to_shutdown;
+
+static Widget grab_widget = 0;
+static Bool editing_disabled = False;
+
+void
+XSMPSetClientID(const char *client_id)
+{
+ DEBUG_DO(printf("XSMPSetClientID %s\n", client_id));
+ if (xsmp_client_id) free(xsmp_client_id);
+ xsmp_client_id = NULL;
+ if (client_id)
+ xsmp_client_id = strdup(client_id);
+}
+
+void
+XSMPSetRestartCommand(const char *command_str)
+{
+ DEBUG_DO(printf("XSMPSetRestartCommand %s\n", command_str));
+ if (xsmp_restart_command) free(xsmp_restart_command);
+ xsmp_restart_command = NULL;
+ if (command_str)
+ xsmp_restart_command = xstrdup(command_str);
+}
+
+static void
+xsmp_ice_on_read(XtPointer closure, int *source, XtInputId *id)
+{
+ IceConn ice_conn;
+ IceProcessMessagesStatus status;
+ ice_conn = (IceConn) closure;
+ DEBUG_DO(printf("xsmp_ice_on_read\n"));
+ status = IceProcessMessages(ice_conn, NULL, NULL);
+}
+
+static void
+xsmp_ice_on_error(IceConn ice_conn)
+{
+ DEBUG_DO(printf("xsmp_ice_on_error\n"));
+}
+
+static void
+xsmp_enable_editing(void)
+{
+ DEBUG_DO(printf("xsmp_enable_editing\n"));
+ if (!editing_disabled)
+ return;
+ XtRemoveGrab(grab_widget);
+ editing_disabled = False;
+}
+
+static void
+xsmp_disable_editing(void)
+{
+ DEBUG_DO(printf("xsmp_disable_editing\n"));
+ if (editing_disabled)
+ return;
+ XtAddGrab(grab_widget, True, True);
+ editing_disabled = True;
+}
+
+static int
+xsmp_set_properties(SmcConn smc_conn, struct device *dev)
+{
+ SmPropValue prop_program, prop_userid, *prop_restart;
+ SmProp prop[] = {
+ { SmUserID, SmARRAY8, 1, &prop_userid },
+ { SmProgram, SmARRAY8, 1, &prop_program },
+ { SmCloneCommand, SmLISTofARRAY8, 1, &prop_program },
+ { SmRestartCommand, SmLISTofARRAY8, 0, NULL },
+ };
+ SmProp *props[] = { &prop[0], &prop[1], &prop[2], &prop[3] };
+ int i, j, nframes;
+ char uidstr[256];
+ Lisp_Object list;
+
+ sprintf(uidstr, "%d", getuid());
+
+ for (nframes = 0, list = dev->frame_list; !NILP(list); list = Fcdr(list))
+ {
+ Widget frame_widget;
+ frame_widget = FRAME_X_TEXT_WIDGET(XFRAME(Fcar(list)));
+ if (FRAME_VISIBLE_P(XFRAME(Fcar(list))))
+ {
+ if (!NILP(DEVMETH_OR_GIVEN(dev, get_frame_parent,
+ (XFRAME(Fcar(list))), Qnil)))
+ {
+ DEBUG_DO(printf("frame:transient\n"));
+ }
+ else
+ {
+ DEBUG_DO(printf("frame:visible\n"));
+ nframes++;
+ }
+ }
+ else if (!((EmacsFrame) frame_widget)->emacs_frame.initially_unmapped)
+ {
+ DEBUG_DO(printf("frame:live\n"));
+ nframes++;
+ }
+ else
+ {
+ DEBUG_DO(printf("frame:init_unmapped\n"));
+ }
+ }
+ DEBUG_DO(printf("nframes = %d\n", nframes));
+
+ prop_program.value = xsmp_restart_command ? xsmp_restart_command : "xemacs";
+ prop_program.length = strlen(prop_program.value);
+ prop_userid.value = uidstr;
+ prop_userid.length = strlen(uidstr);
+
+ j = 0;
+ prop_restart = xmalloc(5 * sizeof(*prop_restart));
+ prop_restart[j].value = xstrdup(prop_program.value);
+ prop_restart[j].length = strlen(prop_program.value);
+ j++;
+ prop_restart[j].value = xstrdup("--sm-client-id");
+ prop_restart[j].length = strlen("--sm-client-id");
+ j++;
+ prop_restart[j].value = xstrdup(xsmp_client_id ? xsmp_client_id : "");
+ prop_restart[j].length = strlen(prop_restart[j].value);
+ j++;
+ if (nframes == 0)
+ {
+ prop_restart[j].value = xstrdup("-unmapped");
+ prop_restart[j].length = strlen("-unmapped");
+ j++;
+ }
+ assert(j <= 4);
+
+ for (i = 1; i < nframes; i++)
+ {
+ prop_restart = xrealloc (prop_restart, (j + 5) * sizeof(*prop_restart));
+ prop_restart[j].value = xstrdup("-f");
+ prop_restart[j].length = strlen("-f");
+ j++;
+ prop_restart[j].value = xstrdup("make-frame");
+ prop_restart[j].length = strlen("make-frame");
+ j++;
+ }
+
+ LIST_LOOP (list, Vbuffer_alist)
+ {
+ Lisp_Object buf, filename, abspath;
+ buf = XCDR(XCAR(list));
+ if (!BUFFERP(buf))
+ continue;
+ filename = XBUFFER(buf)->filename;
+ if (!STRINGP(filename))
+ continue;
+ abspath = Fexpand_file_name(filename, Qnil);
+ if (!STRINGP(abspath))
+ continue;
+ prop_restart = xrealloc (prop_restart, (j + 5) * sizeof(*prop_restart));
+ /*
+ * We insert "+1" before filenames so that xemacs never treat these
+ * arguments as options.
+ */
+ prop_restart[j].value = xstrdup("+1");
+ prop_restart[j].length = strlen("+1");
+ j++;
+ prop_restart[j].value = xstrdup(XSTRING_DATA(abspath));
+ prop_restart[j].length = strlen(prop_restart[j].value);
+ j++;
+ }
+ prop[3].num_vals = j;
+ prop[3].vals = prop_restart;
+
+ SmcSetProperties(smc_conn, sizeof(props)/sizeof(props[0]), props);
+ for (i = 0; i < j; i++)
+ xfree(prop_restart[i].value);
+ xfree(prop_restart);
+ return nframes;
+}
+
+static Lisp_Object xsmp_interact_done_hook(Lisp_Object closure)
+{
+ Bool cancel_save;
+
+ cancel_save = !ready_to_shutdown;
+ DEBUG_DO(printf("xsmp_interact_done state:%d shutdown:%d cancel_save:%d\n",
+ xsmp_state, shutdown_request, cancel_save));
+ if (xsmp_state == xsmp_state_interacting)
+ {
+ SmcInteractDone(smc_conn_current,
+ (cancel_save && shutdown_request) ? True : False);
+ SmcSaveYourselfDone(smc_conn_current, !cancel_save);
+ }
+ else
+ {
+ /* we got ShutdownCancelled while interacting */
+ }
+ ready_to_shutdown = False;
+ xsmp_state = xsmp_state_normal;
+ return Qnil;
+}
+
+static void xsmp_on_interact(SmcConn smc_conn, SmPointer client_data)
+{
+ int speccount;
+ Lisp_Object tem, list;
+ struct device *dev;
+
+ DEBUG_DO(printf("xsmp_on_interact: %d\n", shutdown_request));
+ if (xsmp_state != xsmp_state_waiting_for_interact)
+ return;
+ speccount = specpdl_depth();
+ ready_to_shutdown = False;
+ xsmp_state = xsmp_state_interacting;
+
+ tem = Qnil;
+ /*
+ * We always use dialog box even if use-dialog-box is nil. The
+ * reason is that it's possible that all frames are on other
+ * desktop/viewport and therefore user can't notice that shutdown
+ * is in progress.
+ */
+ specbind(Qforce_dialog_box_use, Qt);
+ specbind(Quse_dialog_box, Qt);
+ dev = (struct device *) client_data;
+ for (list = dev->frame_list; !NILP(list); list = Fcdr(list))
+ if (FRAME_VISIBLE_P(XFRAME(Fcar(list))))
+ break;
+ record_unwind_protect(xsmp_interact_done_hook, Qnil);
+ tem = call1(Qxsmp_save_yourself, shutdown_request ? Qt : Qnil);
+ if (tem != Qnil)
+ ready_to_shutdown = True;
+ unbind_to(speccount, Qnil);
+ DEBUG_DO(printf("xsmp_interact: finished. ready_to_shutdown=%d\n",
+ ready_to_shutdown));
+}
+
+static void xsmp_on_save_yourself(SmcConn smc_conn, SmPointer client_data,
+ int save_type, Bool shutdown,
+ int interact_style, Bool fast)
+{
+ struct device *dev;
+ int nframes;
+ DEBUG_DO(printf("xsmp_on_save_yourself %p\n", client_data));
+ dev = (struct device *) client_data;
+ nframes = xsmp_set_properties(smc_conn, dev);
+ shutdown_request = shutdown;
+ if (interact_style == SmInteractStyleAny && !fast)
+ {
+ switch (save_type)
+ {
+ case SmSaveGlobal:
+ case SmSaveBoth:
+ if (SmcInteractRequest(smc_conn, SmDialogNormal,
+ xsmp_on_interact, client_data))
+ {
+ xsmp_state = xsmp_state_waiting_for_interact;
+ xsmp_disable_editing();
+ return;
+ }
+ break;
+ case SmSaveLocal:
+ break;
+ }
+ }
+ SmcSaveYourselfDone(smc_conn, True);
+ xsmp_state = xsmp_state_normal;
+}
+
+static void xsmp_on_die(SmcConn smc_conn, SmPointer client_data)
+{
+ DEBUG_DO(printf("xsmp_on_die\n"));
+ smc_conn_current = NULL;
+ xsmp_state = xsmp_state_normal;
+ Fkill_emacs(Qnil);
+}
+
+static void xsmp_on_save_complete(SmcConn smc_conn, SmPointer client_data)
+{
+ DEBUG_DO(printf("xsmp_on_save_complete\n"));
+ xsmp_enable_editing();
+ xsmp_state = xsmp_state_normal;
+}
+
+static void xsmp_on_shutdown_cancelled(SmcConn smc_conn, SmPointer client_data)
+{
+ struct device *dev;
+ DEBUG_DO(printf("xsmp_on_shutdown_cancelled %d\n", xsmp_state));
+ dev = (struct device *) client_data;
+ switch (xsmp_state)
+ {
+ case xsmp_state_normal:
+ break;
+ case xsmp_state_waiting_for_interact:
+ SmcSaveYourselfDone(smc_conn, True);
+ break;
+ case xsmp_state_interacting:
+ SmcSaveYourselfDone(smc_conn, True);
+ break;
+ case xsmp_state_waiting_for_save_complete:
+ break;
+ }
+ xsmp_enable_editing();
+ xsmp_state = xsmp_state_normal;
+}
+
+void syms_of_xsmp (void)
+{
+ defsymbol(&Qxsmp_save_yourself, "xsmp-save-yourself");
+ defsymbol(&Qforce_dialog_box_use, "force-dialog-box-use");
+ defsymbol(&Quse_dialog_box, "use-dialog-box");
+}
+
+void XSMPInitialize(struct device *dev, Widget shell)
+{
+ SmcCallbacks callbacks;
+ SmcConn smc_conn;
+ Display *d;
+ char error_string[4097];
+ char *old_client_id, *new_client_id;
+ static int initialized = 0;
+
+ DEBUG_DO(printf("XSMPInitialize %p %p\n", dev, shell));
+ if (initialized)
+ return;
+ initialized = 1;
+
+ old_client_id = xsmp_client_id;
+ callbacks.save_yourself.callback = xsmp_on_save_yourself;
+ callbacks.save_yourself.client_data = dev;
+ callbacks.die.callback = xsmp_on_die;
+ callbacks.save_complete.callback = xsmp_on_save_complete;
+ callbacks.shutdown_cancelled.callback = xsmp_on_shutdown_cancelled;
+ IceSetIOErrorHandler(xsmp_ice_on_error);
+ smc_conn = SmcOpenConnection(NULL, NULL, SmProtoMajor, SmProtoMinor,
+ SmcSaveYourselfProcMask | SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &callbacks, old_client_id, &new_client_id,
+ 4096, error_string);
+ XSMPSetClientID(new_client_id);
+ d = XtDisplayOfObject(shell);
+ if (smc_conn && xsmp_client_id)
+ {
+ IceConn ice_conn;
+ int ice_fd;
+ XtAppContext app;
+ smc_conn_current = smc_conn;
+ XChangeProperty (d, XtWindow(shell),
+ XInternAtom(d, "SM_CLIENT_ID", False),
+ XA_STRING, 8, PropModeReplace, xsmp_client_id,
+ strlen(xsmp_client_id));
+ ice_conn = SmcGetIceConnection(smc_conn);
+ ice_fd = IceConnectionNumber(ice_conn);
+ app = XtDisplayToApplicationContext(d);
+ XtAppAddInput(app, ice_fd, (XtPointer)XtInputReadMask, xsmp_ice_on_read,
+ ice_conn);
+ grab_widget = XtCreateWidget("grab_widget", widgetClass, shell,
+ NULL, 0);
+ DEBUG_DO(printf("ice_fd = %d\n", ice_fd));
+ }
+}
+
+void XSMPInitWidget(Widget widget)
+{
+ DEBUG_DO(printf("XSMPInitWidget\n"));
+}
diff -ur -x configure xemacs-21.1.9/src/xsmp.h xemacs-21.1.9-new/src/xsmp.h
--- xemacs-21.1.9/src/xsmp.h Sun Feb 20 06:24:42 2000
+++ xemacs-21.1.9-new/src/xsmp.h Sat Feb 19 18:53:16 2000
@@ -0,0 +1,19 @@
+/*
+ * XSMP support for XEmacs
+ * created Dec 16 1999 by Akira Higuchi <a(a)kondara.org>
+ */
+
+#ifndef _XEMACS_XSMP_H_
+#define _XEMACS_XSMP_H_
+
+#include "xintrinsic.h"
+#include "lisp.h"
+#include "device.h"
+
+void syms_of_xsmp(void);
+void XSMPSetClientID(const char *client_id);
+void XSMPSetRestartCommand(const char *command_str);
+void XSMPInitialize(struct device *d, Widget shell);
+void XSMPInitWidget(Widget widget);
+
+#endif /* _XEMACS_XSMP_H_ */