diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/Imakefile kterm-6.2.0-wp-BGP-19990719-beta-XSMP/Imakefile
--- kterm-6.2.0-wp-BGP-19990719-beta/Imakefile	Fri Sep 10 00:31:26 1999
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/Imakefile	Fri Sep 10 00:34:38 1999
@@ -46,14 +46,20 @@
         TEKSRCS = TekPrsTbl.c Tekproc.c
         TEKOBJS = TekPrsTbl.o Tekproc.o
 #endif
+#ifdef KTERM_SESSION
+    SESSIONSRCS = session.c
+    SESSIONOBJS = session.o
+#endif
           SRCS1 = button.c charproc.c cursor.c data.c input.c \
 		  main.c menu.c misc.c screen.c scrollbar.c tabs.c \
 		  util.c VTPrsTbl.c \
-		  $(TEKSRCS) gset.c convert.c $(XIMSRCS) $(KINPUT2SRCS)
+		  $(TEKSRCS) gset.c convert.c $(XIMSRCS) $(KINPUT2SRCS) \
+		  $(SESSIONSRCS)
           OBJS1 = button.o charproc.o cursor.o data.o input.o \
 		  main.o menu.o misc.o screen.o scrollbar.o tabs.o \
 		  util.o VTPrsTbl.o \
-		  $(TEKOBJS) gset.o convert.o $(XIMOBJS) $(KINPUT2OBJS)
+		  $(TEKOBJS) gset.o convert.o $(XIMOBJS) $(KINPUT2OBJS) \
+		  $(SESSIONOBJS)
            SRCS = $(SRCS1)
            OBJS = $(OBJS1)
        DEPLIBS1 = XkbClientDepLibs XawClientDepLibs
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/charproc.c kterm-6.2.0-wp-BGP-19990719-beta-XSMP/charproc.c
--- kterm-6.2.0-wp-BGP-19990719-beta/charproc.c	Fri Sep 10 00:31:26 1999
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/charproc.c	Fri Sep 10 00:34:38 1999
@@ -1291,11 +1291,11 @@
 			Index(screen, 1);
 			if (term->flags & LINEFEED)
 				CarriageReturn(screen);
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 			if (XtAppPending(app_con) > 0 ||
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 			if (QLength(screen->display) > 0 ||
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 			    GetBytesAvailable (ConnectionNumber(screen->display)) > 0)
 			  xevents();
 			parsestate = groundtable;
@@ -1816,11 +1816,11 @@
 		      if (!screen->instatus)
 #endif /* STATUSLINE */
 			Index(screen, 1);
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 			if (XtAppPending(app_con) > 0 ||
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 			if (QLength(screen->display) > 0 ||
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 			    GetBytesAvailable (ConnectionNumber(screen->display)) > 0)
 			  xevents();
 			parsestate = groundtable;
@@ -1834,11 +1834,11 @@
 			Index(screen, 1);
 			CarriageReturn(screen);
 			
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 			if (XtAppPending(app_con) > 0 ||
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 			if (QLength(screen->display) > 0 ||
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 			    GetBytesAvailable (ConnectionNumber(screen->display)) > 0)
 			  xevents();
 			parsestate = groundtable;
@@ -2208,7 +2208,7 @@
 	} else
 	    FD_ZERO (&write_mask);
 	select_timeout.tv_sec = 0;
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 	/*
 	 * if there's either an XEvent or an XtTimeout pending, just take
 	 * a quick peek, i.e. timeout from the select() immediately.  If
@@ -2220,11 +2220,11 @@
 	else
 		select_timeout.tv_usec = 50000;
 	i = Select(max_plus1, &select_mask, &write_mask, NULL, &select_timeout);
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 	select_timeout.tv_usec = 0;
 	i = Select(max_plus1, &select_mask, &write_mask, NULL,
 		   QLength(screen->display) ? &select_timeout : NULL);
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 	if (i < 0) {
 	    if (errno != EINTR)
 		SysError(ERROR_SELECT);
@@ -2238,11 +2238,11 @@
 
 	/* if there are X events already in our queue, it
 	   counts as being readable */
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 	if (XtAppPending(app_con) || 
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 	if (QLength(screen->display) || 
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 	    FD_ISSET (ConnectionNumber(screen->display), &select_mask)) {
 	    xevents();
 	}
@@ -3547,6 +3547,10 @@
 			   &sizehints);
 	XFlush (XtDisplay(term));	/* get it out to window manager */
 
+#ifdef KTERM_SESSION
+	kterm_session_set_sm_client_id();
+#endif
+
 	/* use ForgetGravity instead of SouthWestGravity because translating
 	   the Expose events for ConfigureNotifys is too hard */
 	values->bit_gravity = term->misc.resizeGravity == NorthWestGravity ?
@@ -4200,11 +4204,11 @@
 			        * (screen->max_row + 1) + 2 * screen->border,
 			    &junk, &junk);
 			XSync(screen->display, FALSE);	/* synchronize */
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 			if(XtAppPending(app_con))
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 			if(QLength(screen->display) > 0)
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 				xevents();
 		}
 		CursorSet(screen, 0, 0, term->flags);
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/kterm.h kterm-6.2.0-wp-BGP-19990719-beta-XSMP/kterm.h
--- kterm-6.2.0-wp-BGP-19990719-beta/kterm.h	Fri Jul 12 14:01:37 1996
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/kterm.h	Fri Sep 10 00:34:38 1999
@@ -37,5 +37,6 @@
 #define KTERM_COLOR	/* color sequence */
 #define KTERM_NOTEK	/* disables Tektronix emulation */
 #undef  KTERM_XAW3D	/* Xaw3d -DARROW_SCROLLBAR support */
+#define KTERM_SESSION   /* XSM protocol */
 
 #endif /* !_KTERM_H_ */
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/main.c kterm-6.2.0-wp-BGP-19990719-beta-XSMP/main.c
--- kterm-6.2.0-wp-BGP-19990719-beta/main.c	Fri Sep 10 00:31:26 1999
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/main.c	Fri Sep 17 21:17:02 1999
@@ -88,6 +88,9 @@
 #include <sys/socket.h>
 #endif /* KEEPALIVE */
 
+#include "session.h"
+#include "resource.h"
+
 #ifdef att
 #define ATT
 #endif
@@ -133,6 +136,7 @@
 #endif
 
 #ifdef linux
+#define USE_TERMIOS
 #define USE_SYSV_TERMIO
 #define USE_SYSV_PGRP
 #define USE_SYSV_UTMP
@@ -593,39 +597,7 @@
 char *ProgramName;
 Boolean sunFunctionKeys;
 
-static struct _resource {
-    char *xterm_name;
-    char *icon_geometry;
-    char *title;
-    char *icon_name;
-    char *term_name;
-    char *tty_modes;
-    Boolean utmpInhibit;
-    Boolean sunFunctionKeys;	/* %%% should be widget resource? */
-    Boolean wait_for_map;
-    Boolean useInsertMode;
-#ifdef __sgi
-    Boolean useLocale;
-#endif
-#ifdef KEEPALIVE
-    Boolean keepalive;
-#endif
-#ifdef WALLPAPER
-    char *wallpaper;
-    char *wp_position;
-    char *wp_bright;
-    char *wp_fade;
-    char *hide_wallpaper;
-    char *hide_wp_position;
-    char *hide_wp_bright;
-    char *hide_wp_fade;
-    int inheriting;
-    char *ip_shade;
-    char *ip_fade;
-    char *ip_hide;
-    char *ip_hide_fade;
-#endif /* WALLPAPER */
-} resource;
+struct _resource resource;
 
 /* used by VT (charproc.c) */
 
@@ -648,6 +620,8 @@
 	offset(term_name), XtRString, (caddr_t) NULL},
     {"ttyModes", "TtyModes", XtRString, sizeof(char *),
 	offset(tty_modes), XtRString, (caddr_t) NULL},
+    {"smClientId", "SmClientId", XtRString, sizeof(char *),
+	offset(sm_client_id), XtRString, (caddr_t) NULL},
     {"utmpInhibit", "UtmpInhibit", XtRBoolean, sizeof (Boolean),
 	offset(utmpInhibit), XtRString, "false"},
     {"sunFunctionKeys", "SunFunctionKeys", XtRBoolean, sizeof (Boolean),
@@ -850,6 +824,7 @@
 {"-st",		"*statusLine",	XrmoptionNoArg,		(caddr_t) "on"},
 {"+st",		"*statusLine",	XrmoptionNoArg,		(caddr_t) "off"},
 #endif /* STATUSLINE */
+{"-sm-client-id", ".smClientId", XrmoptionSepArg,	(caddr_t) NULL},
 };
 
 static struct _options {
@@ -1088,6 +1063,9 @@
 # ifdef	KTERM_NOTEK
     printopt(" [KTERM_NOTEK]");
 # endif
+# ifdef KTERM_SESSION
+    printopt(" [KTERM_SESSION]");
+# endif
 # ifdef STATUSLINE
     printopt(" [STATUSLINE]");
 # endif
@@ -1642,7 +1620,7 @@
       p++;
     while(isdigit(*p))
       p++;
-    /* % $B;XDj(B */
+    /* %  */
     if(*p == '%'){
       tmp_y = atoi(tmp_p);
       tmp = 0;
@@ -2378,7 +2356,9 @@
 #endif	/* } TIOCSLTC */
 #ifdef USE_TERMIOS /* { */
 	d_tio.c_cc[VSUSP] = CSUSP;
+#ifndef linux
 	d_tio.c_cc[VDSUSP] = '\000';
+#endif
 	d_tio.c_cc[VREPRINT] = '\377';
 	d_tio.c_cc[VDISCARD] = '\377';
 	d_tio.c_cc[VWERASE] = '\377';
@@ -2403,7 +2383,6 @@
 	XtGetApplicationResources(toplevel, (XtPointer) &resource,
 				  application_resources,
 				  XtNumber(application_resources), NULL, 0);
-
 #ifdef __sgi
 	if (resource.useLocale)
 	    setlocale(LC_ALL,"");
@@ -2608,6 +2587,9 @@
 	    XtSetValues (toplevel, args, 2);
 	}
 
+#ifdef KTERM_SESSION
+	kterm_session_init(ProgramName, resource.sm_client_id);
+#endif
 
 #ifndef KTERM_NOTEK
 	if(inhibit & I_TEK)
@@ -2753,7 +2735,7 @@
 
 	wp_init_image(screen, resource, XtWindow(toplevel));
 
-	/* $BJI;f$r@_Dj(B */
+	/*  */
 	if(screen->wp.pix_wp.pix != None){
 	  XSetWindowBackgroundPixmap(screen->display, XtWindow(toplevel), screen->wp.pix_wp.pix);
 	  if(!resource.wp_fade){
@@ -4904,7 +4886,7 @@
     ioctl (fd, FIONREAD, (char *) &arg);
     return (int) arg;
 #else
-#if defined(KTERM_XAW3D) && defined(FIORDCK)
+#if (defined(KTERM_XAW3D) || defined(KTERM_SESSION)) && defined(FIORDCK)
     return ioctl (fd, FIORDCHK, NULL);
 #else /* !KTERM_XAW3D || !FIORDCK */
     struct pollfd pollfds[1];
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/misc.c kterm-6.2.0-wp-BGP-19990719-beta-XSMP/misc.c
--- kterm-6.2.0-wp-BGP-19990719-beta/misc.c	Fri Sep 10 00:31:26 1999
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/misc.c	Fri Sep 10 00:34:38 1999
@@ -72,13 +72,13 @@
 	XEvent event;
 	register TScreen *screen = &term->screen;
 	extern XtAppContext app_con;
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 	XtInputMask input_mask;
-#endif /* KTERM_XAW3D */
+#endif /* KTERM_XAW3D || KTERM_SESSION */
 
 	if(screen->scroll_amt)
 		FlushScroll(screen);
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 	/*
 	 * process timeouts, relying on the fact that XtAppProcessEvent
 	 * will process the timeout and return without blockng on the 
@@ -87,24 +87,26 @@
 	 */
 	while ((input_mask = XtAppPending(app_con)) & XtIMTimer)
 		XtAppProcessEvent(app_con, XtIMTimer);
+	while ((input_mask = XtAppPending(app_con)) & XtIMAlternateInput)
+		XtAppProcessEvent(app_con, XtIMAlternateInput);
 	/*
 	 * If there's no XEvents, don't wait around...
 	 */
 	if ((input_mask & XtIMXEvent) != XtIMXEvent)
 		return;
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 	if (!XPending (screen->display))
 	    /* protect against events/errors being swallowed by us or Xlib */
 	    return;
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 	do {
 		if (waitingForTrackInfo)
 			return;
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 		XtAppNextEvent (app_con, &event);
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 		XNextEvent (screen->display, &event);
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 		/*
 		 * Hack to get around problems with the toolkit throwing away
 		 * eventing during the exclusive grab of the menu popup.  By
@@ -140,11 +142,12 @@
 		     (event.xany.type != ButtonPress) &&
 		     (event.xany.type != ButtonRelease)))
 		    XtDispatchEvent(&event);
-#ifdef KTERM_XAW3D
-	} while ((input_mask = XtAppPending(app_con)) & XtIMXEvent);
-#else /* !KTERM_XAW3D */
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
+	} while ((input_mask = XtAppPending(app_con)) &
+		 (XtIMXEvent | XtIMAlternateInput));
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 	} while (QLength(screen->display) > 0);
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 }
 
 
@@ -852,19 +855,19 @@
     register TScreen *screen = &term->screen;
     struct timeval curtime;
     long now_msecs;
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
     extern XtAppContext app_con;
-#endif /* KTERM_XAW3D */
+#endif /* KTERM_XAW3D || KTERM_SESSION */
 
     /* has enough time gone by that we are allowed to ring
        the bell again? */
     if(screen->bellSuppressTime) {
 	if(screen->bellInProgress) {
-#ifdef KTERM_XAW3D
+#if defined(KTERM_XAW3D) || defined(KTERM_SESSION)
 	    if (XtAppPending(app_con) > 0 ||
-#else /* !KTERM_XAW3D */
+#else /* !(KTERM_XAW3D || KTERM_SESSION) */
 	    if (QLength(screen->display) > 0 ||
-#endif /* !KTERM_XAW3D */
+#endif /* !(KTERM_XAW3D || KTERM_SESSION) */
 		GetBytesAvailable (ConnectionNumber(screen->display)) > 0)
 		xevents();
 	    if(screen->bellInProgress) { /* even after new events? */
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/resource.h kterm-6.2.0-wp-BGP-19990719-beta-XSMP/resource.h
--- kterm-6.2.0-wp-BGP-19990719-beta/resource.h	Thu Jan  1 09:00:00 1970
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/resource.h	Fri Sep 17 21:17:23 1999
@@ -0,0 +1,41 @@
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+struct _resource {
+    char *xterm_name;
+    char *icon_geometry;
+    char *title;
+    char *icon_name;
+    char *term_name;
+    char *tty_modes;
+    char *sm_client_id;
+    Boolean utmpInhibit;
+    Boolean sunFunctionKeys;	/* %%% should be widget resource? */
+    Boolean wait_for_map;
+    Boolean useInsertMode;
+#ifdef __sgi
+    Boolean useLocale;
+#endif
+#ifdef KEEPALIVE
+    Boolean keepalive;
+#endif
+#ifdef WALLPAPER
+    char *wallpaper;
+    char *wp_position;
+    char *wp_bright;
+    char *wp_fade;
+    char *hide_wallpaper;
+    char *hide_wp_position;
+    char *hide_wp_bright;
+    char *hide_wp_fade;
+    int inheriting;
+    char *ip_shade;
+    char *ip_fade;
+    char *ip_hide;
+    char *ip_hide_fade;
+#endif /* WALLPAPER */
+};
+
+extern struct _resource resource;
+
+#endif
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/screen.c kterm-6.2.0-wp-BGP-19990719-beta-XSMP/screen.c
--- kterm-6.2.0-wp-BGP-19990719-beta/screen.c	Fri Sep 10 00:31:26 1999
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/screen.c	Fri Sep 10 00:36:01 1999
@@ -46,9 +46,7 @@
 #include <sys/ptem.h>
 #endif
 
-#ifndef WALLPAPER /* XXX WALLPAPER */
-extern Char *calloc(), *malloc(), *realloc();
-#endif
+extern void *calloc(), *malloc(), *realloc();
 extern void free();
 
 ScrnBuf Allocate (nrow, ncol, addr)
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/scrollbar.c kterm-6.2.0-wp-BGP-19990719-beta-XSMP/scrollbar.c
--- kterm-6.2.0-wp-BGP-19990719-beta/scrollbar.c	Fri Sep 10 00:31:26 1999
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/scrollbar.c	Fri Sep 10 00:36:39 1999
@@ -345,9 +345,7 @@
 	register TScreen *screen = &xw->screen;
 	register int border = 2 * screen->border;
 	register int i;
-#ifndef WALLPAPER /* XXX WALLPAPER */
-	Char *realloc(), *calloc();
-#endif
+	void *realloc(), *calloc();
 
 	if(screen->scrollbar)
 		return;
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/session.c kterm-6.2.0-wp-BGP-19990719-beta-XSMP/session.c
--- kterm-6.2.0-wp-BGP-19990719-beta/session.c	Thu Jan  1 09:00:00 1970
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/session.c	Sun Sep 19 00:50:25 1999
@@ -0,0 +1,373 @@
+#include "ptyx.h"
+#include "session.h"
+
+#include <X11/Intrinsic.h>
+#include <X11/Xatom.h>
+#include <X11/SM/SMlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "resource.h"
+
+#define DEBUG_SESSION(x)
+
+extern XtermWidget term;
+extern Widget toplevel;
+
+static char *kterm_session_argv0 = NULL;
+static SmcConn sm_conn = NULL;
+static IceConn ice_conn = NULL;
+static int ice_fd = -1;
+static char *sm_client_id = NULL;
+static enum {
+	kterm_session_state_normal,
+	kterm_session_state_waiting_for_interact,
+	kterm_session_state_interacting,
+	kterm_session_state_waiting_for_save_complete,
+} session_state = kterm_session_state_normal;
+
+static void
+kterm_session_ice_read(XtPointer closure, int *source, XtInputId *id)
+{
+	IceProcessMessagesStatus status;
+	DEBUG_SESSION(printf("read\n"));
+	status = IceProcessMessages(ice_conn, NULL, NULL);
+	if (status == IceProcessMessagesIOError) {
+		DEBUG_SESSION(printf("SmcCloseConnection\n"));
+		SmcCloseConnection (sm_conn, 0, NULL);
+		session_state = kterm_session_state_normal;
+		ice_fd   = -1;
+		ice_conn = NULL; 
+		sm_conn  = NULL;
+	}
+}
+
+static void
+kterm_session_callback_die(SmcConn smc_conn, SmPointer client_data)
+{
+	DEBUG_SESSION(printf("die\n"));
+	exit(0);
+}
+
+static void
+kterm_session_get_geometry(int *px, int *py, int *pw, int *ph, int *iconic)
+{
+	Window win, parent, root, *children;
+	unsigned int nchildren;
+	unsigned int posx, posy, width, height, d1, d2;
+	XWindowAttributes attr;
+	parent = win = XtWindow(toplevel);
+	do {
+		win = parent;
+		if (!XQueryTree(XtDisplay(toplevel), win, &root, &parent,
+				&children, &nchildren))
+			return;
+		if (children)
+			XFree(children);
+	} while (parent != root);
+	if (XGetGeometry(XtDisplay(toplevel), win, &root,
+			 &posx, &posy, &width, &height, &d1, &d2)) {
+		*px = posx;
+		*py = posy;
+		*pw = width;
+		*ph = height;
+	}
+	if (XGetWindowAttributes(XtDisplay(toplevel), win, &attr)) {
+		*iconic = (attr.map_state == IsViewable) ? 0 : 1;
+	}
+}
+
+static void
+set_prop(SmPropValue *prop, int offset, char *str)
+{
+	prop[offset].value = str;
+	prop[offset].length = strlen(str);
+}
+
+static char*
+xcolor_to_str(char* buf, XColor* c)
+{
+	sprintf(buf, "#%04x%04x%04x", (int)c->red, (int)c->green, (int)c->blue);
+	return buf;
+}
+
+static void
+kterm_session_set_properties(void)
+{
+	SmPropValue prop_program, prop_userid, *prop_restart;
+	SmProp prop[] = {
+		{ SmUserID,           SmARRAY8,       1, &prop_userid  },
+		{ SmProgram,          SmARRAY8,       1, &prop_program },
+		{ SmCloneCommand,     SmLISTofARRAY8, 0, NULL          },
+		{ SmRestartCommand,   SmLISTofARRAY8, 0, NULL          },
+	};
+	SmProp *props[] = { &prop[0], &prop[1], &prop[2], &prop[3] };
+	char geomstr[400], uidstr[100], lspstr[100];
+	char fg[32], bg[32], cr[32];
+	int posx, posy, width, height, iconic;
+	int i;
+
+	sprintf(uidstr, "%d", term->screen.uid);
+	sprintf(lspstr, "%d", term->screen.linespace);
+	posx = posy = 0;
+	width = 80;
+	height = 24;
+	iconic = 0;
+	kterm_session_get_geometry(&posx, &posy, &width, &height, &iconic);
+	width = term->screen.max_col + 1;
+	height = term->screen.max_row + 1;
+	sprintf(geomstr, "%dx%d+%d+%d", width, height, posx, posy);
+	DEBUG_SESSION(printf("geometry: %s\n", geomstr));
+	DEBUG_SESSION(printf("client_id: %s\n", sm_client_id));
+
+	prop_program.value = kterm_session_argv0;
+	prop_program.length = strlen(kterm_session_argv0);
+	prop_userid.value = uidstr;
+	prop_userid.length = strlen(uidstr);
+
+	
+	prop_restart = malloc(sizeof(SmPropValue) * 100);
+	i = 0;
+	/* Program Name */
+	set_prop(prop_restart, i++, prop_program.value);
+	/* Geometry */
+	set_prop(prop_restart, i++, "-geometry");
+	set_prop(prop_restart, i++, geomstr);
+	/* Iconic State */
+	if (iconic)
+		set_prop(prop_restart, i++, "-iconic");
+	/* Kanji Mode */
+	set_prop(prop_restart, i++, "-km");
+	if (term->flags & EUC_KANJI) {
+		set_prop(prop_restart, i++, "euc");
+	} else if (term->flags & SJIS_KANJI) {
+		set_prop(prop_restart, i++, "sjis");
+	} else {
+		set_prop(prop_restart, i++, "jis");
+	}
+	/* Open Input Method */
+	set_prop(prop_restart, i++, term->misc.open_im ? "-xim" : "+xim");
+	/* Extra Dots Between Lines */
+	set_prop(prop_restart, i++, "-lsp");
+	set_prop(prop_restart, i++, lspstr);
+	/* Scroll Bar */
+	set_prop(prop_restart, i++, term->screen.scrollbar ? "-sb" : "+sb");
+	/* Jump Scroll */
+	set_prop(prop_restart, i++, term->screen.jumpscroll ? "-j" : "+j");
+	/* Reverse Video */
+#if 0
+	/* seems to be broken ?? */
+	set_prop(prop_restart, i++,
+		(term->flags & REVERSE_VIDEO) ? "-rv" : "+rv");
+#endif
+	/* Auto Wraparound */
+	set_prop(prop_restart, i++,
+		(term->flags & WRAPAROUND) ? "-aw" : "+aw");
+	/* Reverse Wraparound */
+	set_prop(prop_restart, i++,
+		(term->flags & REVERSEWRAP) ? "-rw" : "+rw");
+	/* Scroll to Bottom on Key Press */
+	set_prop(prop_restart, i++, term->screen.scrollkey ? "-sk" : "+sk");
+	/* Scroll to Bottom on Tty Output */
+	set_prop(prop_restart, i++,
+		term->screen.scrollttyoutput ? "-si" : "+si");
+	/* Visual Bell */
+	set_prop(prop_restart, i++, term->screen.visualbell ? "-vb" : "+vb");
+	/* Margin Bell */
+	set_prop(prop_restart, i++, term->screen.marginbell ? "-mb" : "+mb");
+	/* Status Line */
+	set_prop(prop_restart, i++, term->misc.statusline ? "-st" : "+st");
+	{
+		TScreen *screen = &term->screen;
+		Display* dpy = screen->display;
+		XColor tmp[3]; /* 0 for fg, 1 for bg, 2 for cursor */
+		tmp[0].pixel = screen->foreground;
+		tmp[1].pixel = term->core.background_pixel;
+		tmp[2].pixel = screen->cursorcolor;
+		XQueryColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)),
+		             tmp, 3);
+		xcolor_to_str(fg, &tmp[0]);
+		xcolor_to_str(bg, &tmp[1]);
+		xcolor_to_str(cr, &tmp[2]);
+		if (fg[0]) {
+			set_prop(prop_restart, i++, "-fg");
+			set_prop(prop_restart, i++, fg);
+		}
+		if (bg[0]) {
+			set_prop(prop_restart, i++, "-bg");
+			set_prop(prop_restart, i++, bg);
+		}
+		if (cr[0]) {
+			set_prop(prop_restart, i++, "-cr");
+			set_prop(prop_restart, i++, cr);
+		}
+	}
+#ifdef WALLPAPER
+	if (resource.wallpaper && strcmp(resource.wallpaper, "/")) {
+		set_prop(prop_restart, i++, "-wp");
+		set_prop(prop_restart, i++, resource.wallpaper);
+		if (resource.wp_position) {
+			set_prop(prop_restart, i++, "-wpp");
+			set_prop(prop_restart, i++, resource.wp_position);
+		}
+		if (resource.wp_bright) {
+			set_prop(prop_restart, i++, "-wpb");
+			set_prop(prop_restart, i++, resource.wp_bright);
+		}
+		if (resource.wp_fade) {
+			set_prop(prop_restart, i++, "-wpf");
+			set_prop(prop_restart, i++, resource.wp_fade);
+		}
+	} else {
+		set_prop(prop_restart, i++, "+wp");
+	}
+	if (resource.hide_wallpaper && strcmp(resource.hide_wallpaper, "/")) {
+		set_prop(prop_restart, i++, "-hwp");
+		set_prop(prop_restart, i++, resource.hide_wallpaper);
+		if (resource.hide_wp_position) {
+			set_prop(prop_restart, i++, "-hwpp");
+			set_prop(prop_restart, i++, resource.hide_wp_position);
+		}
+		if (resource.hide_wp_bright) {
+			set_prop(prop_restart, i++, "-hwpb");
+			set_prop(prop_restart, i++, resource.hide_wp_bright);
+		}
+		if (resource.hide_wp_fade) {
+			set_prop(prop_restart, i++, "-hwpf");
+			set_prop(prop_restart, i++, resource.hide_wp_fade);
+		}
+	} else {
+		set_prop(prop_restart, i++, "+hwp");
+	}
+	if (resource.inheriting) {
+		set_prop(prop_restart, i++, "-ip");
+		if (resource.ip_shade) {
+			set_prop(prop_restart, i++, "-ips");
+			set_prop(prop_restart, i++, resource.ip_shade);
+		}
+		if (resource.ip_fade) {
+			set_prop(prop_restart, i++, "-ipf");
+			set_prop(prop_restart, i++, resource.ip_fade);
+		}
+		if (resource.ip_hide) {
+			set_prop(prop_restart, i++, "-iph");
+			set_prop(prop_restart, i++, resource.ip_hide);
+		}
+		if (resource.ip_hide_fade) {
+			set_prop(prop_restart, i++, "-iphf");
+			set_prop(prop_restart, i++, resource.ip_hide_fade);
+		}
+	} else {
+		set_prop(prop_restart, i++, "+ip");
+	}
+#endif
+	/* Client ID */
+	set_prop(prop_restart, i++, "-sm-client-id");
+	set_prop(prop_restart, i++, sm_client_id);
+	
+	prop[2].num_vals = i - 2; /* Don't include -sm-client-id */
+	prop[2].vals = prop_restart;
+	prop[3].num_vals = i;
+	prop[3].vals = prop_restart;
+
+	DEBUG_SESSION(printf("SmcSetProperties\n"));
+	SmcSetProperties(sm_conn, sizeof(props)/sizeof(props[0]), props);
+}
+
+static void
+kterm_session_callback_save_yourself
+(SmcConn smc_conn, SmPointer client_data, int save_type,
+ Bool shutdown, int interact_style, Bool fast)
+{
+	DEBUG_SESSION(printf(
+		"save_yourself type=%d shut=%d interact=%d fast=%d\n",
+		save_type, shutdown, interact_style, fast));
+	kterm_session_set_properties();
+	DEBUG_SESSION(printf("SmcSaveYourself\n"));
+	SmcSaveYourselfDone(smc_conn, True);
+}
+
+static void 
+kterm_session_callback_shutdown_cancelled
+(SmcConn smc_conn, SmPointer client_data)
+{
+	DEBUG_SESSION(printf("shutdown_cancelled\n"));
+	session_state = kterm_session_state_normal;
+}
+
+
+static void 
+kterm_session_callback_save_complete
+(SmcConn smc_conn, SmPointer client_data)
+{
+	DEBUG_SESSION(printf("save_complete\n"));
+	session_state = kterm_session_state_normal;
+}
+
+static void
+kterm_session_ice_io_error_handler(IceConn conn)
+{
+	session_state = kterm_session_state_normal;
+	ice_fd   = -1;
+	ice_conn = NULL; 
+	sm_conn  = NULL;
+}
+
+void
+kterm_session_set_sm_client_id(void)
+{
+	Atom atom_sm_client_id;
+	atom_sm_client_id = XInternAtom(
+		XtDisplay(toplevel), "SM_CLIENT_ID", False);
+	if (sm_client_id && strlen(sm_client_id)) {
+		XChangeProperty(XtDisplay(toplevel), XtWindow(toplevel),
+				atom_sm_client_id, XA_STRING, 8,
+				PropModeReplace,
+				sm_client_id, strlen(sm_client_id));
+	} else {
+		XDeleteProperty(XtDisplay(toplevel), XtWindow(toplevel),
+				atom_sm_client_id);
+	}
+}
+
+void
+kterm_session_init(char *argv0, char *sm_client_id_old)
+{
+	SmcCallbacks callbacks;
+	char error_string[4097];
+	extern XtAppContext app_con;
+
+	kterm_session_argv0 = argv0 ? argv0 : "kterm";
+
+	IceSetIOErrorHandler(kterm_session_ice_io_error_handler);
+	callbacks.save_yourself.callback =
+		kterm_session_callback_save_yourself;
+	callbacks.die.callback =
+		kterm_session_callback_die;
+	callbacks.save_complete.callback =
+		kterm_session_callback_save_complete;
+	callbacks.shutdown_cancelled.callback =
+		kterm_session_callback_shutdown_cancelled;
+	error_string[4096] = '\0';
+	DEBUG_SESSION(printf("SmcOpenConnection\n"));
+	sm_conn = SmcOpenConnection(
+		NULL, NULL, SmProtoMajor, SmProtoMinor,
+		SmcSaveYourselfProcMask | SmcDieProcMask |
+		SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
+		&callbacks, sm_client_id_old, &sm_client_id,
+		4096, error_string);
+	if (error_string[0]) {
+		DEBUG_SESSION(printf("%s\n", error_string));
+	}
+	if (sm_conn) {
+		ice_conn = SmcGetIceConnection(sm_conn);
+		ice_fd = IceConnectionNumber(ice_conn);
+		DEBUG_SESSION(printf("ice_fd = %d\n", ice_fd));
+		XtAppAddInput(app_con, ice_fd, (XtPointer)XtInputReadMask,
+			      &kterm_session_ice_read, NULL);
+		DEBUG_SESSION(printf("connected\n"));
+	} else {
+		DEBUG_SESSION(printf("not connected\n"));
+	}
+}
+
diff -uNr kterm-6.2.0-wp-BGP-19990719-beta/session.h kterm-6.2.0-wp-BGP-19990719-beta-XSMP/session.h
--- kterm-6.2.0-wp-BGP-19990719-beta/session.h	Thu Jan  1 09:00:00 1970
+++ kterm-6.2.0-wp-BGP-19990719-beta-XSMP/session.h	Fri Sep 10 00:34:38 1999
@@ -0,0 +1,4 @@
+
+void kterm_session_init(char *argv0, char *sm_client_id);
+void kterm_session_set_sm_client_id(void);
+
