mikew@maui.fx.com (Mike Wexler) (05/27/90)
Submitted-by: mikew@maui.fx.com (Mike Wexler) Posting-number: Volume 7, Issue 79 Archive-name: sm/part02 Here is the newest version of sm. It requires X11R4. If you were at my talk at Xhibition, this is the program I was talking about. #--------------------------Cut Here-------------------------- #! /bin/sh # This is a shell archive. Remove anything before the "#! /bin/sh" line, # then unpack it by saving it in a file and typing "sh file." # # Wrapped by Mike Wexler (mikew) at neptune on Thu May 24 09:05:00 1990 # # unpacks with default permissions # # Contents : StateSave.c Top.c Top.h Utils.c WinInfo.c Globals.c # StateExecute.c StateRead.c WinInfo.h Actions.c sm.man osdefs.h # smpro.tbl.ms State SM.ad Imakefile Makefile # if `test ! -s StateSave.c` then echo "x - StateSave.c" sed 's/^X//' > StateSave.c << '@EOF' X/*********************************************************** X X$Header: StateSave.c,v 3.1 90/04/16 17:20:04 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X#include "SM.h" X X#include <X11/Xlib.h> X#include "ICC.h" X#include <X11/Xutil.h> X#include <X11/Xatom.h> X X#include "xdefs.h" X#include "Top.h" X#include "PropUtils.h" X#include "ICCUtils.h" X#include "WinInfo.h" X#include "State.h" X#include "Atoms.h" X X/* X * Description: Save the current state of the window system. X * X * Side Effects: Can cause the clients to update WM_COMMAND and/or die. X * X */ X XStatus XStateSave(state) XStatePtr state; /* pointer to state */ X{ X Status cc; X char stateFile[256]; X FILE *stateFP; X char *getenv(); X int i; X WinInfoPtr wi; X X sprintf(stateFile, "%s/%s/State", getenv("HOME"), applData.smDir); X stateFP = fopen(stateFile, "w"); X if (stateFP == NULL) { X perror("rewrite window info"); X return (SM_FAILURE); X } X for (wi = state->topList; wi != NULL; wi = wi->next) X if ((cc = WIPrint(stateFP, wi)) < 0) X return(cc); X (void) fclose(stateFP); X sprintf(stateFile, "%s/%s/FontPath", getenv("HOME"), applData.smDir); X stateFP = fopen(stateFile, "w"); X if (stateFP == NULL) { X perror("rewrite window info"); X return (SM_FAILURE); X } X for (i = 0; i < state->numFontPaths; ++i) X fprintf(stateFP, "%s\n", state->fontPaths[i]); X (void) fclose(stateFP); X return (SM_SUCCESS); X} X X/* X * Description: Write the state to a file. X * X */ X XStatus XStatePrint(stateFP, state) XFILE *stateFP; /* stream to send output to */ XStatePtr state; /* state to output */ X{ X WinInfoPtr wi; X X for (wi = state->topList; wi != NULL; wi = wi->next) X (void) WIPrint(stateFP, wi); X return (SM_SUCCESS); X} X X/* X * Description: Apply proper quoting to an argument. For instance, X * an argument with a space in it should be quoted. X * X */ X XStatus XQuoteArg(arg, string, len) X unsigned char *arg; /* argument to quoted */ X char *string; /* result of quoting */ X int *len; /* length of string */ X{ X int special = False; X char *cp; X register int charsLeft = *len; X X string += strlen(string); X if (rindex(arg, ' ')) { X *string++ = '\"'; X if (--charsLeft <= 0) X return(SM_FAILURE); X special = True; X } X for (cp = (char *) arg; cp < (char *) arg + strlen(arg); ++cp) { X if (index(applData.metaChars, *cp) != NULL) { X *string++ = '\\'; X if (charsLeft-- <= 0) X return(SM_FAILURE); X } X *string++ = *cp; X if (charsLeft-- <= 0) X return(SM_FAILURE); X } X if (special == True) { X *string++ = '\"'; X charsLeft--; X } X *string = 0; X *len = charsLeft; X return(SM_SUCCESS); X} X X/* X * Description: Apply proper quoting to arguments. For instance, arguments with X * spaces should have quotes around them. X * X */ X Xstatic XStatus XArgvToString(argc, argv, string, len) Xint argc; /* number of arguments*/ Xunsigned char **argv; /* arguments */ Xchar *string; /* result string */ Xint len; /* length of result string */ X{ X int i; X X string[0] = 0; X for (i = 0; i < argc; ++i) { X if (i > 0) { X if (--len <= 0) X break; X strcat(string, " "); X } X if (QuoteArg(argv[i], string, &len) < 0) X return(SM_FAILURE); X } X return(SM_SUCCESS); X} X X X/* X * Description: Print the command neccessary to restart the client associated X * with a specific top-level window. X * X */ X Xstatic XStatus XWIPrint(stateFP, wi) X FILE *stateFP; /* output stream */ X WinInfo *wi; /* window information structure */ X{ X char command[500]; X unsigned char *host; X static unsigned char hostname[HOSTNAME_LEN] = "none"; X static unsigned char localhost[] = LOCAL_HOST; X X if (!strcmp(hostname, "none")) X if (gethostname(hostname, sizeof(hostname)) < 0) X return(SM_FAILURE); X X if (wi->argv == NULL) X return(SM_FAILURE); X ArgvToString(wi->argc, wi->argv, command, sizeof(command)); X if (strcmp(hostname, wi->wmClientMachine)) X host = wi->wmClientMachine; X else X host = localhost; X fprintf(stateFP, "%d %d %d %d %d %d %s %s %s %s\n", X wi->win_gravity, wi->wmState.state, wi->width, wi->height, X wi->x, wi->y, X host, wi->wmClass.res_class, wi->wmClass.res_name, X command); X return (SM_SUCCESS); X} X Xstatic int XputString(fp, s, len) XFILE *fp; Xunsigned char *s; Xint len; X{ X if (putw(htonl(len), fp)) X return(SM_FAILURE); X if (len > 0) X if (fwrite(s, len, 1, fp) == 0) X return(SM_FAILURE); X return(SM_SUCCESS); X} X X/* X * Description: Print the command neccessary to restart the client associated X * with a specific top-level window. X * X */ X Xstatic XStatus XWISave(stateFP, wi) XFILE *stateFP; /* output stream */ XWinInfo *wi; /* output */ X{ X XTextProperty textCommand; X static unsigned char hostname[HOSTNAME_LEN] = "none"; X static unsigned char localhost[] = LOCAL_HOST; X X if (!strcmp(hostname, "none")) X if (gethostname(hostname, sizeof(hostname)) < 0) X return(SM_FAILURE); X if (putw(htonl(wi->win_gravity), stateFP)) X return(SM_FAILURE);; X if (putw(htonl(wi->wmState.state), stateFP)) X return(SM_FAILURE); X if (putw(htonl(wi->width), stateFP)) X return(SM_FAILURE); X if (putw(htonl(wi->height), stateFP)) X return(SM_FAILURE); X if (putw(htonl(wi->x), stateFP)) X return(SM_FAILURE); X if (putw(htonl(wi->y), stateFP)) X return(SM_FAILURE); X if (strcmp(hostname, wi->wmClientMachine)) { X if (putString(stateFP, wi->wmClientMachine, X strlen(wi->wmClientMachine)) < 0) X return(SM_FAILURE); X } else { X if (putString(stateFP, localhost, strlen(localhost)) < 0) X return(SM_FAILURE); X } X if (putString(stateFP, (unsigned char *) wi->wmClass.res_class, X strlen(wi->wmClass.res_class)) < 0) X return(SM_FAILURE); X if (putString(stateFP, (unsigned char *) wi->wmClass.res_name, X strlen(wi->wmClass.res_name)) < 0) X return(SM_FAILURE); X if (XStringListToTextProperty(wi->argv, wi->argc, &textCommand) == 0) X return(SM_FAILURE); X if ((textCommand.format != 8) || (textCommand.encoding != XA_STRING)) X return(SM_FAILURE); X if (putString(stateFP, textCommand.value, (int) textCommand.nitems) < 0) X return(SM_FAILURE); X return (SM_SUCCESS); X} X X @EOF else echo "shar: Will not over write StateSave.c" fi if `test ! -s Top.c` then echo "x - Top.c" sed 's/^X//' > Top.c << '@EOF' X/*********************************************************** X X$Header: Top.c,v 3.1 90/04/16 17:20:44 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X#include "SM.h" X#include <X11/StringDefs.h> X#include <X11/Intrinsic.h> X#include <X11/Shell.h> X#include <X11/Xaw/Command.h> X#include <X11/Xaw/Form.h> X#include <X11/Vendor.h> X X#include "ICC.h" X#include "Top.h" X#include "WinInfo.h" X#include "State.h" X XWidget homeForm; XWidget confirmPopup; XWidget confirmForm; XWidget topShell; Xextern ApplicationData applData; X Xstatic XrmOptionDescRec options[] = { X {"-print", "print", XrmoptionNoArg, "True"}, X {"-ignore", "ignore", XrmoptionNoArg, "True"}, X}; X Xstatic XtResource tsResources[] = { X {"print", "print", XtRBoolean, sizeof (applData.print), X XtOffset(ApplicationDataPtr, print), XtRString, "False"}, X {"ignore", "ignore", XtRBoolean, sizeof (applData.ignore), X XtOffset(ApplicationDataPtr, ignore), XtRString, "False"}, X {"smDir", "smDir", XtRString, sizeof (applData.smDir), X XtOffset(ApplicationDataPtr, smDir), XtRString, "sm"}, X {"defaultDir", "defaultDir", XtRString, X sizeof (applData.defaultDir), X XtOffset(ApplicationDataPtr, defaultDir), XtRString, SM_DIR}, X {"shell", "shell", XtRString, sizeof (applData.shell), X XtOffset(ApplicationDataPtr, shell), XtRString, "/bin/sh"}, X {"defaultCommand", "defaultCommand", XtRString, X sizeof (applData.defaultCommand), X XtOffset(ApplicationDataPtr, defaultCommand), XtRString, "xterm -C &"}, X {"geometryString", "geometryString", XtRString, X sizeof (applData.geometry), X XtOffset(ApplicationDataPtr, geometry), XtRString, "-geometry"}, X {"iconicString", "iconic", XtRString, sizeof (applData.iconic), X XtOffset(ApplicationDataPtr, iconic), XtRString, "-iconic"}, X {"metaChars", "metaChars", XtRString, sizeof (applData.metaChars), X XtOffset(ApplicationDataPtr, metaChars), XtRString, "*#\"\\"}, X}; X X/* X * Description: Create the top-level widgets. X * X * Outputs: Widget - the Home form's widget. X * X */ X XWidget XCreateHome(parent) XWidget parent; /* the parent shell widget */ X{ X Widget quitButton; X Widget saveStateButton; X X homeForm = XtCreateWidget("homeForm", formWidgetClass, parent, NULL, 0); X quitButton = XtCreateManagedWidget("quitButton", commandWidgetClass, X homeForm, NULL, 0); X saveStateButton = XtCreateManagedWidget("saveStateButton", X commandWidgetClass, X homeForm, NULL, 0); X return (homeForm); X} X X/* X * Description: Create the confirm form's widgets X * X * Outputs: Widget - the confirm form's widget. X * X */ X XWidget XCreateConfirm(parent) XWidget parent; /* the parent shell widget */ X{ X Widget exitYesButton; X Widget exitNoButton; X Widget cancelButton; X X confirmPopup = XtCreatePopupShell("confirmPopup", vendorShellWidgetClass, X parent, NULL, 0); X X confirmForm = XtCreateManagedWidget("confirmForm", formWidgetClass, X confirmPopup, X NULL, 0); X X (void) XtCreateManagedWidget("confirmLabel", labelWidgetClass, X confirmForm, NULL, 0); X X exitYesButton = XtCreateManagedWidget("exitYesButton", X commandWidgetClass, X confirmForm, NULL, 0); X X exitNoButton = XtCreateManagedWidget("exitNoButton", X commandWidgetClass, X confirmForm, NULL, 0); X X cancelButton = XtCreateManagedWidget("cancelButton", commandWidgetClass, X confirmForm, NULL, 0); X X return (confirmForm); X} X X/* X * Description: Initialize X, Xt, and Xaw X * X * Outputs: Widget - top level widget X * X * Side Effects: Initializes the toolkit X */ X XWidget XInitializeX(argc, argv) Xint argc; /* argument count from command line */ Xchar **argv; /* argument list from command line */ X{ X Arg args[10]; X Cardinal n; X X n = 0; X topShell = XtAppInitialize(&myAppContext, "SM", X options, XtNumber(options), X &argc, argv, NULL, args, n); X if (argc != 1) X Usage(); X XtGetApplicationResources(topShell, (XtPointer) &applData, tsResources, X XtNumber(tsResources), NULL, 0); X return (topShell); X} X X/* X * Description: Set up top-level shellWidget and initialize the toolkit X * X * Outputs: Widget - top level widget X * X * Side Effects: Initializes the toolkit X */ X Xvoid XWidgetSetup() X{ X Arg args[10]; X Cardinal n; X static XtActionsRec actionsTable[] = { X {"quit", QuitAction}, X {"exit", ExitAction}, X {"saveState", SaveStateAction}, X {"cancel", CancelAction}, X }; X X /* Build the top-level widget. */ X XtAppAddActions(myAppContext, actionsTable, XtNumber(actionsTable)); X X homeForm = CreateHome(topShell); X confirmForm = CreateConfirm(topShell); X return; X} X X/* X * Description: Realize the top-level shell X * X * Side Effects: Realizes the top-level shell. X */ X X/* Realize the top-level shell. */ Xvoid XTopStart() X{ X XtManageChild(homeForm); X XtRealizeWidget(topShell); X} @EOF else echo "shar: Will not over write Top.c" fi if `test ! -s Top.h` then echo "x - Top.h" sed 's/^X//' > Top.h << '@EOF' X/*********************************************************** X X$Header: Top.h,v 3.1 90/04/16 17:21:30 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X Xextern Widget topShell; X Xextern Widget InitializeX(); Xextern void WidgetSetup(); Xextern void TopStart(); X Xextern Widget confirmPopup; Xextern Widget confirmForm; Xextern Widget homeForm; X @EOF else echo "shar: Will not over write Top.h" fi if `test ! -s Utils.c` then echo "x - Utils.c" sed 's/^X//' > Utils.c << '@EOF' X/*********************************************************** X X$Header: Utils.c,v 3.1 90/04/16 17:20:41 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X#include <stdio.h> X#include <errno.h> X X#include <X11/Xlib.h> X X#include "osdefs.h" X#include "SM.h" X#include "PatchLevel.h" X X/* X * Description: Print a fatal error message. X * X * Side Effects: Exits X * X */ X Xvoid XFatal(module, message) X char *module; /* the name of the module */ X char *message; /* the message to print */ X{ X fprintf(stderr, "sm v%f: %s(%s)\n", VERSION, message, module); X exit(1); X} X X/* X * Description: Print a warning message X * X */ X Xvoid XWarning(module, message) X char *module; /* the name of the module */ X char *message; /* the error message */ X{ X fprintf(stderr, "sm v%f: %s(%s)\n", VERSION, message, module); X return; X} X X/* X * Description: Print warning message caused by failed system library calls. X * X */ X Xvoid XPWarning(module) X char *module; /* module in which the error occurred */ X{ X char text[128]; X sprintf(text, "sm v%f: %s", VERSION, module); X perror(text); X return; X} X X/* X * Description: Safely concatenate two strings. X * X */ X XStatus Xsafestrcat(target, source, len) X char *target; X char *source; X int len; X{ X int targetLen; X int sourceLen; X X targetLen = strlen(target); X sourceLen = strlen(source); X if ((sourceLen + targetLen) >= len) X return(SM_FAILURE); X strcat(target, source); X return(SM_SUCCESS); X} X @EOF else echo "shar: Will not over write Utils.c" fi if `test ! -s WinInfo.c` then echo "x - WinInfo.c" sed 's/^X//' > WinInfo.c << '@EOF' X/*********************************************************** X X$Header: WinInfo.c,v 3.0 89/11/20 09:25:45 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X#include "SM.h" X#include "X11/Xlib.h" X#include "X11/Xutil.h" X#include "ICC.h" X#include "WinInfo.h" X X/* X * Description: Allocated a new WinInfo structure X * X * Outputs: WinInfo * - The newly allocated WinInfo structure. X * X */ X XWinInfo * XwiAlloc() X{ X WinInfo *winInfo; X X winInfo = (WinInfo *) XtMalloc(sizeof (*winInfo)); X if (winInfo == NULL) X return(NULL); X winInfo->saveYourselfState = DontSave; X winInfo->wmProtocols = NULL; X winInfo->numProtocols = 0; X winInfo->win_gravity = 0; X winInfo->prev = NULL; X winInfo->next = NULL; X return (winInfo); X} X X/* X * Description: Free an allocated WinInfo structure. X * X */ X XStatus XwiFree(winInfo) X WinInfoPtr winInfo; /* pointer to the WinInfo structure to free */ X{ X XtFree(winInfo); X return (SM_SUCCESS); X} X X X X @EOF else echo "shar: Will not over write WinInfo.c" fi if `test ! -s Globals.c` then echo "x - Globals.c" sed 's/^X//' > Globals.c << '@EOF' X/*********************************************************** X X$Header: Globals.c,v 3.1 90/04/16 16:14:04 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X#include <X11/Intrinsic.h> X#include "SM.h" X XApplicationData applData; XXtAppContext myAppContext; @EOF else echo "shar: Will not over write Globals.c" fi if `test ! -s StateExecute.c` then echo "x - StateExecute.c" sed 's/^X//' > StateExecute.c << '@EOF' X/*********************************************************** X X$Header: StateExecute.c,v 1.1 90/04/16 16:45:45 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X X#include "SM.h" X#include <pwd.h> X X#include <X11/Xatom.h> X#include <X11/StringDefs.h> X#include <X11/Shell.h> X#include "ICC.h" X#include "WinInfo.h" X#include "Top.h" X#include "State.h" X X X/* X * Description: Print the command neccessary to restart the client associated X * with a specific top-level window. X * X */ X X/*ARGSUSED*/ Xstatic XStatus XWIGenerateCommand(wi, command, len) X WinInfo *wi; /* window information structure */ X char *command; /* command line */ X{ X Status cc; X int i; X static char temp[TEMP_LEN]; X X command[0] = 0; X if (wi->argv == NULL) X return(SM_SUCCESS); X if ((cc = safestrcat(command, (char *) wi->argv[0], len)) < 0) X return(cc); X if ((cc = safestrcat(command, " ", len)) < 0) X return(cc); X /* Check if WM_COMMAND has -geometry, so we can override it. */ X for (i = 1; i < wi->argc; ++i) X if (!strcmp(wi->argv[i], applData.geometry)) X break; X/* X * No geometry was specified so put it at the beginning of the argument X * list. This is questionable. X */ X if (i == wi->argc) { X sprintf(temp, "%s %dx%d+%d+%d ", applData.geometry, X wi->width, wi->height, wi->x, wi->y); X if ((cc = safestrcat(command, temp, len)) < 0) X return(cc); X } X if (wi->wmState.state == IconicState) { X for (i = 1; i < wi->argc; ++i) X if (!strcmp(wi->argv[i], applData.iconic)) X break; X if (i == wi->argc) { X if ((cc = safestrcat(command, applData.iconic, len)) < 0) X return(cc); X if ((cc = safestrcat(command, " ", len)) < 0) X return(cc); X } X } X for (i = 1; i < wi->argc; ++i) { X/* Replace the -geometry with the current one. This is questionable. */ X if (!strcmp(wi->argv[i], applData.geometry)) { X i++; X sprintf(temp, "%s %dx%d+%d+%d ", applData.geometry, X wi->width, wi->height, wi->x, wi->y); X if ((cc = safestrcat(command, temp, len)) < 0) X return(cc); X continue; X } X/* Get rid of Iconic if it isn't iconic */ X if (wi->wmState.state != IconicState && !strcmp(wi->argv[i], X applData.iconic)) X continue; X if ((cc = QuoteArg(wi->argv[i], command, &len)) < 0) X return(cc); X if ((cc = safestrcat(command, " ", len)) < 0) X return(cc); X } X if ((cc = safestrcat(command, "< /dev/null > /dev/null 2> /dev/null &\n", len)) < 0) X return(cc); X return (SM_SUCCESS); X} X X/* X * Description: Start up all the programs specified by a state. X * X * Side Effects: Starts up a bunch of programs. X * X */ X XStatus XStateExecute(state) XState *state; /* state to execute */ X{ X FILE *shellInput; X char command[500]; X WinInfoPtr *winInfo; X HostInfoPtr hostInfo; X char setDisplay[100]; X char *displayString; X Display *display; X char *nonHostPart; X static unsigned char hostname[HOSTNAME_LEN] = "none"; X static char localhost[] = LOCAL_HOST; X X display = XtDisplay(topShell); X displayString = XDisplayString(display); X if (!strcmp(hostname, "none")) X if (gethostname(hostname, sizeof(hostname)) < 0) X return(SM_FAILURE); X X XSetFontPath(display, state->fontPaths, state->numFontPaths); X for (hostInfo = state->hostInfo; hostInfo != NULL; X hostInfo = hostInfo->next) { X if (strcmp(hostInfo->hostName, localhost) == 0) { X strcpy(command, "/bin/sh"); X } else { X sprintf(command, "/usr/ucb/rsh %s /bin/sh -fi", X hostInfo->hostName); X } X shellInput = popen(command, "w"); X if (shellInput == NULL) { X Warning("RestoreState", "can't create pipe to shell\n"); X return(SM_FAILURE); X } X if (strlen(displayString) < 1) X return(SM_FAILURE); X nonHostPart = rindex(displayString, ':'); X if (displayString[0] == ':' || strncmp(displayString, "unix:", 5) == 0) X sprintf(setDisplay, "DISPLAY=%s%s;export DISPLAY\n", hostname, X nonHostPart); X else X sprintf(setDisplay, "DISPLAY=%s;export DISPLAY\n", displayString); X fwrite(setDisplay, strlen(setDisplay), 1, shellInput); X fflush(shellInput); X for (winInfo = hostInfo->winInfos; X winInfo < hostInfo->winInfos + hostInfo->numWinInfos; ++winInfo) { X if (((*winInfo)->wmClass.res_class == NULL) || X strcmp((*winInfo)->wmClass.res_class, "SM")) { X WIGenerateCommand(*winInfo, command, sizeof(command)); X fwrite(command, strlen(command), 1, shellInput); X fflush(shellInput); X } X } X pclose(shellInput); X } X return (SM_SUCCESS); X} X @EOF else echo "shar: Will not over write StateExecute.c" fi if `test ! -s StateRead.c` then echo "x - StateRead.c" sed 's/^X//' > StateRead.c << '@EOF' X/*********************************************************** X X$Header: StateRead.c,v 1.1 90/04/16 17:20:22 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X X#include "SM.h" X#include <pwd.h> X X#include <X11/Xatom.h> X#include <X11/StringDefs.h> X#include <X11/Shell.h> X#include "ICC.h" X#include "WinInfo.h" X#include "Top.h" X#include "State.h" X Xstatic char *GetName(); X X/* X * number of characters in a machine word when expressed as an ascii string X */ X#define MAX_CHARS_PER_NUMBER 10 X#define MAX_CHARS_PER_STRING 512 X X/* X * Description: Return 1 word in host byte order X * X * X */ X Xstatic XStatus XgetWord(fp, num) XFILE *fp; /* stream file pointer */ Xint *num; X{ X char temp[MAX_CHARS_PER_NUMBER + 1]; /* NULL terminated string */ X char *p; X int c; X X for (p = temp; p < temp + MAX_CHARS_PER_NUMBER; ++p) { X c = getc(fp); X if (c == ' ') X break; X if (c == EOF) X return(SM_FAILURE); X *p = c; X } X *p = 0; X *num = atoi(temp); X return(0); X} X X/* X * Name: getString X * X * Description: Read a string from a file X * X * Side Effects: None. X * X*/ X Xstatic XStatus XgetString(fp, result) XFILE *fp; /* input stream pointer */ Xunsigned char **result ; X{ X unsigned char temp[MAX_CHARS_PER_STRING + 1]; X unsigned char *p; X int c; X Status cc; X Boolean quoteFlag = False; X X for (p = temp; p < temp + MAX_CHARS_PER_STRING; ) { X c = getc(fp); X switch (c) { X case '\"': X if (quoteFlag) X quoteFlag = False; X else X quoteFlag = True; X continue; /* process next char */ X case '\\': X c = getc(fp); /* get next char and store it */ X if (c == EOF) { X cc = 2; X goto done; X } X break; X case ' ': X if (quoteFlag) X break; X cc = 0; X goto done; /* end of string */ X case '\n': X cc = 1; X goto done; /* end of string */ X case EOF: X cc = 2; X goto done; /* end of string */ X } X *p++ = c; X } X done: X *p = 0; X *result = (unsigned char *) XtMalloc(p - temp + 1); X strcpy(*result, temp); X return(cc); X} X X/* X * Description: Read in a WinInfo from a saved state file. X * X * Outputs: int - -1 = error, 0 = ok, 1 = EOF X * X */ X Xint XWIRead(wi, fp) X WinInfo *wi; /* window info structure */ X FILE *fp; /* input stream pointer */ X{ X Status cc; X X if (getWord(fp, &wi->win_gravity) < 0) X return(1); X if (getWord(fp, &wi->wmState.state) < 0) X return(SM_FAILURE); X if (getWord(fp, &wi->width) < 0) X return(SM_FAILURE); X if (getWord(fp, &wi->height) < 0) X return(SM_FAILURE); X if (getWord(fp, &wi->x) < 0) X return(SM_FAILURE); X if (getWord(fp, &wi->y) < 0) X return(SM_FAILURE); X if (getString(fp, &wi->wmClientMachine) != 0) X return(SM_FAILURE); X if (getString(fp, &wi->wmClass.res_class) != 0) X return(SM_FAILURE); X if (getString(fp, &wi->wmClass.res_name) != 0) X return(SM_FAILURE); X wi->argv = NULL; X for (wi->argc = 1; ; ++wi->argc) { X wi->argv = (unsigned char **) X XtRealloc(wi->argv, (wi->argc) * sizeof(*wi->argv)); X cc = getString(fp, &wi->argv[wi->argc - 1]); X if (cc == 2) X return(1); X if (cc == 1) X break; X } X return(SM_SUCCESS); X} X X/* X * Description: Read the state from a saved state file. X * X */ X XStatus XStateRead(state) X State *state; /* pointer to the current state */ X{ X Status cc; X FILE *commandFile; X char *commandFileName; X WinInfo *wi; X int i; X X /* X * if GetName can't file a .SMState file then just start an xterm X * console. X */ X if ((commandFileName = GetName("State")) == NULL) { X return (SM_FAILURE); X } X commandFile = fopen(commandFileName, "r"); X if (commandFile == NULL) { X Warning("RestoreState", "can't open command file\n"); X return(SM_FAILURE); X } X for (;;) { X wi = wiAlloc(); X if (wi == NULL) X return(SM_FAILURE); X cc = WIRead(wi, commandFile); X if (cc != 0) X if (wiFree(wi) < 0) X return(SM_FAILURE); X if (cc < 0) X return(cc); X else if (cc == 1) X break; X if (wi->wmClass.res_class && strcmp(wi->wmClass.res_class, "SM") == 0) X SetMyOwnParameters(state, wi); X if ((cc = StateAddWinInfo(state, wi)) < 0) X return(cc); X if ((cc = StateAddToHostList(state, wi)) < 0) X return(cc); X } X fclose(commandFile); X /* X * if GetName can't file a .SMState file then just start an xterm X * console. X */ X if ((commandFileName = GetName("FontPath")) == NULL) { X return (SM_FAILURE); X } X commandFile = fopen(commandFileName, "r"); X if (commandFile == NULL) { X Warning("RestoreState", "can't open command file\n"); X return(SM_FAILURE); X } X for (i = 0; ;) { X static char fontPath[200]; X X if (fscanf(commandFile, "%s", fontPath) == EOF) { X state->numFontPaths = i; X break; X } X ++i; X if (state->fontPaths == NULL) X state->fontPaths = (char **) X XtMalloc(sizeof(*state->fontPaths) * i); X else X state->fontPaths = (char **) X XtRealloc(state->fontPaths, X sizeof(*state->fontPaths) * i); X state->fontPaths[i - 1] = strdup(fontPath); X } X fclose(commandFile); X return(SM_SUCCESS); X} X X/* X * Description: Set my own parameters based on a WinInfo with my name on X * it. X * X */ X XSetMyOwnParameters(state, wi) XStatePtr state; XWinInfoPtr wi; X{ X state->smState = wi; X return(0); X} X X/* X * Description: Finds the name of the SMState file to execute. It looks X * first in the user's home directory, and then in a X * system directory. X * X * Outputs: char * - the name of the file X * X */ X Xstatic Xchar * XGetName(file) Xchar *file; X{ X struct passwd *pw; X int endpwent(); X struct passwd *getpwuid(); X char *home; X static char path[256]; X X if ((home = getenv("HOME")) == NULL) { X if ((pw = getpwuid(getuid())) == NULL) { X PWarning("GetName"); X return (NULL); X } X home = pw->pw_dir; X endpwent(); X } X (void) sprintf(path, "%s/%s/%s", home, applData.smDir, file); X X if (access(path, F_OK) == 0) X return (path); X X (void) sprintf(path, "%s/%s", applData.defaultDir, file); X X if (access(path, F_OK) == 0) X return (path); X X return (NULL); X} X X @EOF else echo "shar: Will not over write StateRead.c" fi if `test ! -s WinInfo.h` then echo "x - WinInfo.h" sed 's/^X//' > WinInfo.h << '@EOF' X/*********************************************************** X X$Header: WinInfo.h,v 3.0 89/11/20 09:25:47 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X Xtypedef struct _winInfo { X XClassHint wmClass; X unsigned char *wmClientMachine; X int argc; X unsigned char **argv; X int x; X int y; X int width; X int height; X int win_gravity; X WM_STATE wmState; X Window rid; X Window parentRid; X Atom *wmProtocols; X unsigned long numProtocols; X int saveYourselfState; X struct _winInfo *next; X struct _winInfo *prev; X} WinInfo, *WinInfoPtr; X X#define DontSave 1 X#define Saving 2 X#define Saved 3 X Xextern WinInfo *wiAlloc(); Xextern Status wiFree(); Xextern WinInfo *wiGetByRid(); @EOF else echo "shar: Will not over write WinInfo.h" fi if `test ! -s Actions.c` then echo "x - Actions.c" sed 's/^X//' > Actions.c << '@EOF' X/*********************************************************** X X$Header: Actions.c,v 1.1 90/04/16 15:55:02 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X X#include "SM.h" X#include <X11/StringDefs.h> X#include <X11/Intrinsic.h> X#include <X11/Shell.h> X#include <X11/Vendor.h> X X#include "ICC.h" X#include "Top.h" X#include "WinInfo.h" X#include "State.h" X X/* X * Description: Handle the user pressing the shutdown button on the home form. X * X */ X X/* ARGSUSED */ Xvoid XQuitAction(w, event, params, numParams) XWidget w; /* the Quit Button Widget */ XXEvent *event; /* the event that caused the is action */ Xchar *params; /* params from the translation table */ XCardinal *numParams; /* number of params */ X{ X XtPopup(confirmPopup, XtGrabNonexclusive); X return; X} X X/* X * Description: Handle the user press the cancel button on the confirm screen. X * X * Side Effects: Causes the confirmForm to be Unmanaged and the quitButton to X */ X X/*ARGSUSED*/ Xvoid XCancelAction(w, event, params, numParams) XWidget w; /* the cancel button widget */ XXEvent *event; /* the event that caused the action */ Xchar *params; /* params from the translation table */ XCardinal *numParams; /* the number of params */ X{ X XtPopdown(confirmPopup); X return; X} X X/* X * Description: Handle the confirm button being pushed on the confirmation X * screen. X * X * Side Effects: Terminates program. X */ X X/* ARGSUSED */ Xvoid XSaveStateAction(w, event, params, numParams) XWidget w; /* The quit button widget */ XXEvent *event; /* the event that caused the action */ XString *params; /* params from the translation table */ XCardinal *numParams; /* the number of params */ X{ X State state; X X StateInit(&state); X if (StateGet(&state, XtDisplay(homeForm)) >= 0) X (void) StateSave(&state); X StateCleanup(&state); X} X X/* ARGSUSED */ Xvoid XExitAction(w, event, params, numParams) XWidget w; /* The quit button widget */ XXEvent *event; /* the event that caused the action */ XString *params; /* params from the translation table */ XCardinal *numParams; /* the number of params */ X{ X XtDestroyWidget((Widget) homeForm); X exit(0); X} X @EOF else echo "shar: Will not over write Actions.c" fi if `test ! -s sm.man` then echo "x - sm.man" sed 's/^X//' > sm.man << '@EOF' X.TH SM 1 X.SH NAME Xsm \- a session manager for x X.SH SYNOPSIS Xsm [-ignore] [-print] [-debug] [-display hostname:dpy] [normal Xaw options] X.SH DESCRIPTION X.I sm Xis a convenient way to save the state of your "desktop" and Xrestore it. X.PP XThe state is saved in a file called X.I sm/State Xwhich is located in your home directory. X.I Sm Xexecutes each of the commands in this file at startup time. XIf you don't have X.I sm/State Xin your home directory, X.I sm Xfirst tries to use the file X.I /usr/lib/X11/sm/DefaultState. XIf that file doesn't exist then, X.I sm Xexecutes "xterm -C". X.PP XThe state currently consists of the location, size, iconification and XWM_COMMAND of each of the windows. XIt also contains the current font path. X.PP X.I sm Xis normally started by X.I xinit Xor X.I xdm after running X.I xrdb Xand starting an ICCCM compliant window manager(such as X11R4's twm or Motif's Xmwm). X.PP XIf X.I sm Xwas started by X.I xinit Xor X.I xdm, Xquitting X.I sm Xshutdowns the X Window System server. X.SH OPTIONS X.TP X.B \-ignore XIgnore any existing sm/State file. X.TP X.B \-print XJust print out that current state. X.TP X.B \-debug XTurn on debugging. X.SH OPTIONS X.I sm Xtakes all of the standard toolkit options. In addition, you may Xignore the startup file with -ignore or you can write the current Xconfigure to stdout using -print. X.SH "X DEFAULTS" XThe available names and classes for the widgets used are: X.RS X.nf X.ta 4i XNAME CLASS Xprint Boolean Xignore Boolean XsmDir String XdefaultState String Xshell String Xdefaultcommand String XgeometryString String XiconicString String XgeometryString String XiconPixmap Pixmap Xgeometry Geometry XhomeForm Form XhomeForm.quitButton Form.CommandButton XconfirmForm.confirmLabel Form.Label XconfirmForm.yesButton Form.Label XconfirmForm.noButton.label: Form.label XconfirmForm.checkBoxLabel.label: Form.label X.fi X.RE X.PP XThese can be used to set fonts, colors, etc. tailored to the user's Xneeds. As a color example: X.PP X.RS X.ta 4i X.nf Xsm*quitButton.background: mauve Xsm*yesButton.background: peach Xsm*noButton.background: plum Xsm.geometry: -1-100 Xsm*homeForm.font: vbee-36 Xsm*confirmForm.font: vbee-36 X.fi X.RE X.SH FILES X/usr/lib/X11/sm/DefaultState X~/sm/State X.SH BUGS X.B Sm Xdoesn't iconic windows or window gravity. X.SH AUTHOR X.ta 1.2i XMike Wexler X.br X mikew@fx.com X X @EOF else echo "shar: Will not over write sm.man" fi if `test ! -s osdefs.h` then echo "x - osdefs.h" sed 's/^X//' > osdefs.h << '@EOF' X/*********************************************************** X X$Header: osdefs.h,v 3.0 89/11/20 09:25:48 mikew Exp $ X XCopyright 1989 by Mike Wexler, Santa Clara, Ca. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and its Xdocumentation for any purpose and without fee is hereby granted, Xprovided that the above copyright notice appear in all copies and that Xboth that copyright notice and this permission notice appear in Xsupporting documentation, and that the name of Mike Wexler or not be Xused in advertising or publicity pertaining to distribution of the Xsoftware without specific, written prior permission. X XMIKE WEXLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS XSOFTWARE. X X******************************************************************/ X Xextern int exit(); Xextern int fprintf(); Xextern char *sprintf(); Xextern int perror(); Xextern int gethostname(); Xextern int fclose(); Xextern int getuid(); Xextern char *getenv(); Xextern int access(); Xextern int system(); @EOF else echo "shar: Will not over write osdefs.h" fi if `test ! -s smpro.tbl.ms` then echo "x - smpro.tbl.ms" sed 's/^X//' > smpro.tbl.ms << '@EOF' X.\" Use tbl and -ms X.de Cp X.QP XConvention: X.I X.. X.de Ce X.R X.. X.de Pp X.QP XProblem: X.I X.. X.de Pe X.R X.. X.de Ip X.IP \(bu 3 X.. X.de Ls X.DS L X.. X.de Le X.DE X.. X.TL X_MIKEW_RESTORE_STATE proposal X.AU XMike Wexler X.AI XFXD/Telerate, Inc. X.AB X.LP XThis is a proposal for a new protocol which I'm sending to this list for Xdiscussion. It could be a part of a Window and Session Manager's document, Xa stand-alone protocol registered with the X Registry, or both. X.LP XIt intended to provide a reliable, efficient, and portable way for a SM to Xrestore client properties such as window geometry and state. It does this Xby introducing a new protocol for SMs and WMs to communicate about client Xstart-up. X.AE X.NH XProtocol X.LP XThis is a description of the protocol. Which consists of several ClientMessage Xevents with type _MIKEW_RESTORE_STATE. In each of them data[2] will Xrepresent a specific state in the progress of the protocol. The states Xare listed in Table 1. X.KF X.TS Xcenter, box; Xc s s Xc c c Xl l l. XTable 1 \- _MIKEW_RESTORE_STATE protcols states X_ XState Value Comments X_ XInitiating 0 SM about to start a client XAccepted 1 WM has accepted client startup XRejected 2 WM has rejected client startup XExecutionFailed 3 SM couldn't execute client XExecutionFailedAck 4 WM acknowledges execution failure XWindowMapped 5 WM has mapped the clients window X.TE X.KE X.NH 2 XWM's top-level window. X.LP XWhen a WM starts, it will create a top-level window with the class portion of the WM_CLASS property containing "WM" and a WM_PROTOCOLS property that Xcontains the atom _MIKEW_RESTORE_STATE. X.NH 2 XInitiation X.LP XThe SM generates a unique id for the transaction it is about Xto start. XThis id can't be reused until the WM replies with WindowMapped, Rejected, Xor ExecutionFailedAck, Xand is used in further communications to uniquely identify this window. XIt then attaches several properties to its top-level window. XThe first three are used to identify a client window when it is mapped: X_MIKEW_WM_CLASS_XXX, _MIKEW_WM_CLIENT_MACHINE_XXX, and _MIKEW_WM_COMMAND_XXX. XIn each of these properties XXX is replaced by the unique id. XThese properties should be filled in with the types and values of XWM_CLASS, WM_CLIENT_MACHINE, and WM_COMMAND Xwhen the client's state was saved. XIn addition there should be a property _MIKEW_WM_STATE of type _MIKEW_WM_STATE, Xsee Table 2. XThe x location, y location, width, height, state, and gravity are used by Xthe WM as if the user had specified them to the client program. X.KF X.TS Xcenter, box; Xc s s Xc c c Xl l l. XTable 1 \- _MIKEW_WM_STATE type property contents X_ XField Type Comments X_ Xstate CARD32 see WM_STATE in ICCCM Xx INT32 Location of outer corner of window as specified by win_gravity Xy INT32 Xwidth INT32 size of window Xheight INT32 Xwin_gravity INT32 see WM_NORNAL_HINTS is ICCCM X.TE X.KE X.KS X.LP XThen the SM sends a ClientMessage event to the WM's top-level window Xwith: X.Ip X``window'' == SM's top level window X.Ip X``type'' == WM_PROTOCOLS X.Ip X``format'' == 32 X.Ip X``data[0]'' == _MIKEW_RESTORE_STATE X.Ip X``data[1]`` == timestamp X.Ip X``data[2]'' == Initiating X.Ip X``data[3]`` == id X.KE X.NH 2 XWM response X.KS X.LP XThe WM responds with a ClientMessage event with: X.Ip X``type'' == WM_PROTOCOLS X.Ip X``format'' == 32 X.Ip X``data[0]'' == _MIKEW_RESTORE_STATE X.Ip X``data[1]`` == timestamp X.Ip X``data[2]'' == Accepted | Rejected X.Ip X``data[3]`` == id X.KE X.LP XIf the window manager replies with Rejected it means that the request made Xwill never succeed and should not be tried again. X.NH 2 XClient startup X.LP XThe SM starts the client on the host specified by client machine and Xwith the command specified by command. Note that the client program is Xsupposed to ensure that both WM_CLIENT_MACHINE, WM_COMMAND remain as Xspecified at start-up until it receives a map notify from the WM. It is Xalso expected to create a WM_CLASS property with the same contents as its Xprior invocation. The client should also create a WM_PROTOCOLS property Xcontaining _MIKEW_RESTORE_STATE to indicate that it follows these rules. X.KS X.LP XIf execution fails the SM sends a ClientMessageEvent with: X.Ip X``type'' == WM_PROTOCOLS X.Ip X``format'' == 32 X.Ip X``data[0]'' == _MIKEW_RESTORE_STATE X.Ip X``data[1]`` == timestamp X.Ip X``data[2]'' == ExecutionFailed X.Ip X``data[3]`` == id X.KE X.NH 2 XAcknowledgement of execution failure X.KS X.LP XIf the WM receives a execution failure message it respinds with a XClientMessage event with: X.Ip X``type'' == WM_PROTOCOLS X.Ip X``format'' == 32 X.Ip X``data[0]'' == _MIKEW_RESTORE_STATE X.Ip X``data[1]`` == timestamp X.Ip X``data[2]'' == ExecutionFailedAck X.Ip X``data[3]`` == id X.KE X.NH 2 XWindow mapping X.KS X.LP XWhen the WM receives a map request for a window with the appropriate XWM_CLIENT_MACHINE, WM_COMMAND, and WM_CLASS, it maps it as if the user Xrequested the x location, y location, width, height, state, and window Xgravity specified in the initial _MIKEW_RESTORE_STATE event. It then Xsends a ClientMessage of type _MIKEW_RESTORE_STATE with: X.Ip X``type'' == WM_PROTOCOLS X.Ip X``format'' == 32 X.Ip X``data[0]'' == _MIKEW_RESTORE_STATE X.Ip X``data[1]`` == timestamp X.Ip X``data[2]'' == WindowMapped X.Ip X``data[3]`` == id X.KE X.NH XNotes X.LP XOnly one request can be pending with a particular host, class, command Xtriple. X.LP XThe clients can't change the WM_COMMAND, WM_CLASS, or WM_CLIENT_MACHINE Xuntil after they've received a map notify. X.LP XIt is unclear whether this will support clients with multiple top-level Xwindows. @EOF else echo "shar: Will not over write smpro.tbl.ms" fi if `test ! -s State` then echo "x - State" sed 's/^X//' > State << '@EOF' X0 1 80 24 571 3 localhost XTerm xterm xterm -geometry 80x24+571+3 -C X0 3 80 24 536 175 localhost XTerm xterm xterm -title "abc\\\\ def" X0 1 80 24 3 3 localhost XTerm xterm xterm -geometry 80x24+3+3 -C -n neptune X0 1 80 24 571 343 localhost XTerm xterm xterm -geometry 80x24+571+343 -n neptune X0 1 218 161 656 736 localhost XNetload xnetload xnetload -geometry 218x161+656+736 -configuration 2x2 -nolocal neptune pond troll fxgrp X0 1 80 41 3 344 localhost emacs emacs -geometry 80x41+3+344 X0 1 261 103 888 794 localhost DClock dclock dclock -geometry 261x103+888+794 X0 1 81 75 572 739 localhost XBiff xbiff xbiff -geometry 81x75+572+739 @EOF else echo "shar: Will not over write State" fi if `test ! -s SM.ad` then echo "x - SM.ad" sed 's/^X//' > SM.ad << '@EOF' X# Default for all widgets X*bitmapFilePath: /usr/share/X11.4/lib/X11/sm X X# Application specific information XSM.print: False XSM.debug: False XSM.ignore: False XSM.smDir: sm XSM.defaultState: DefaultState XSM.shell: /bin/sh XSM.defaultCommand: xterm -C & XSM.metaChars: "#\* XSM.geometryString: -geometry XSM.iconicString: -iconic X X# Defaults for various widgets X SM.iconic: True XSM.iconPixmap: SM.xbm X XSM.homeform.background: black XSM.homeForm.borderWidth: 0 X XSM.homeForm.quitButton.resize: True XSM.homeForm.quitButton.label: Quit XSM.homeForm.quitButton.translations: #override \ X <Btn1Up>: notify()unset()quit()\n XSM.homeForm.saveStateButton.label: Save State XSM.homeForm.saveStateButton.translations: #override \ X <Btn1Up>: notify()unset()saveState()\n XSM.homeForm.saveStateButton.fromHoriz: quitButton X XSM.confirmPopup.geometry: 174x80+500+400 X XSM.confirmPopup.confirmForm.borderWidth: 0 X XSM.confirmPopup.confirmForm.confirmLabel.label: Save State? XSM.confirmPopup.confirmForm.confirmLabel.borderWidth: 0 X XSM.confirmPopup.confirmForm.exitYesButton.fromVert: confirmLabel XSM.confirmPopup.confirmForm.exitYesButton.label: Yes XSM.confirmPopup.confirmForm.exitYesButton.translations:#override \ X <Btn1Up>: notify()unset()saveState()exit()\n X XSM.confirmPopup.confirmForm.exitNoButton.fromHoriz: exitYesButton XSM.confirmPopup.confirmForm.exitNoButton.fromVert: confirmLabel XSM.confirmPopup.confirmForm.exitNoButton.label: No XSM.confirmPopup.confirmForm.exitNoButton.translations:#override \ X <Btn1Up>: notify()unset()exit()\n X XSM.confirmPopup.confirmForm.cancelButton.fromHoriz: exitNoButton XSM.confirmPopup.confirmForm.cancelButton.fromVert: confirmLabel XSM.confirmPopup.confirmForm.cancelButton.label: Cancel XSM.confirmPopup.confirmForm.cancelButton.translations:#override \ X <Btn1Up>: notify()unset()cancel()\n @EOF else echo "shar: Will not over write SM.ad" fi if `test ! -s Imakefile` then echo "x - Imakefile" sed 's/^X//' > Imakefile << '@EOF' X PROGRAMS = sm X SM_DIR = $(LIBDIR)/sm X DEFINES = -DSM_DIR=\"${SM_DIR}\" X SYS_LIBRARIES = -lXaw -lXt -lXmu -lX11 X SRCS = Actions.c Atoms.c Globals.c \ X ICCUtils.c PropUtils.c SM.c \ X StateMisc.c StateGet.c StateExecute.c StateRead.c \ X StateSave.c Top.c Utils.c WinInfo.c X X OBJS = Actions.o Atoms.o Globals.o \ X ICCUtils.o PropUtils.o SM.o \ X StateMisc.o StateGet.o StateExecute.o StateRead.o \ X StateSave.o Top.o Utils.o WinInfo.o X X XComplexProgramTarget(sm) XInstallAppDefaults(SM) XInstallNonExec(State, $(SM_DIR)) XInstallNonExec(FontPath, $(SM_DIR)) XInstallNonExec(SM.xbm, $(SM_DIR)) X XSABERFLAGS = $(CFLAGS) X Xinstall.ln: @EOF else echo "shar: Will not over write Imakefile" fi if `test ! -s Makefile` then echo "x - Makefile" sed 's/^X//' > Makefile << '@EOF' X# Makefile generated by imake - do not edit! X# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $ X# X# The cpp used on this machine replaces all newlines and multiple tabs and X# spaces in a macro expansion with a single space. Imake tries to compensate X# for this, but is not always successful. X# X X########################################################################### X# Makefile generated from "Imake.tmpl" and <Imakefile> X# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $ X# X# Platform-specific parameters may be set in the appropriate .cf X# configuration files. Site-wide parameters may be set in the file X# site.def. Full rebuilds are recommended if any parameters are changed. X# X# If your C preprocessor doesn't define any unique symbols, you'll need X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing X# "make Makefile", "make Makefiles", or "make World"). X# X# If you absolutely can't get imake to work, you'll need to set the X# variables at the top of each Makefile as well as the dependencies at the X# bottom (makedepend will do this automatically). X# X X########################################################################### X# platform-specific configuration parameters - edit sun.cf to change X X# platform: $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $ X# operating system: SunOS 4.0.3 X X########################################################################### X# site-specific configuration parameters - edit site.def to change X X# site: $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $ X X SHELL = /bin/sh X X TOP = . X CURRENT_DIR = . X X AR = ar cq X BOOTSTRAPCFLAGS = X CC = cc X X COMPRESS = compress X CPP = /lib/cpp $(STD_CPP_DEFINES) X PREPROCESSCMD = cc -E $(STD_CPP_DEFINES) X INSTALL = install X LD = ld X LINT = lint X LINTLIBFLAG = -C X LINTOPTS = -axz X LN = ln -s X MAKE = make X MV = mv X CP = cp X RANLIB = ranlib X RANLIBINSTFLAGS = X RM = rm -f X STD_INCLUDES = X STD_CPP_DEFINES = X STD_DEFINES = X EXTRA_LOAD_FLAGS = X EXTRA_LIBRARIES = X TAGS = ctags X X SHAREDCODEDEF = -DSHAREDCODE X SHLIBDEF = -DSUNSHLIB X X PROTO_DEFINES = X X INSTPGMFLAGS = X X INSTBINFLAGS = -m 0755 X INSTUIDFLAGS = -m 4755 X INSTLIBFLAGS = -m 0664 X INSTINCFLAGS = -m 0444 X INSTMANFLAGS = -m 0444 X INSTDATFLAGS = -m 0444 X INSTKMEMFLAGS = -m 4755 X X DESTDIR = /usr/share/X11.4 X X TOP_INCLUDES = -I$(INCROOT) X X CDEBUGFLAGS = -O X CCOPTIONS = X COMPATFLAGS = X X ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES) X ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS) X CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) X LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) X LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) X LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) X LDCOMBINEFLAGS = -X -r X X MACROFILE = sun.cf X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut X X IMAKE_DEFINES = X X IRULESRC = $(CONFIGDIR) X IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) X X ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \ X $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \ X $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) X X########################################################################### X# X Window System Build Parameters X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $ X X########################################################################### X# X Window System make variables; this need to be coordinated with rules X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $ X X PATHSEP = / X USRLIBDIR = $(DESTDIR)/lib X BINDIR = $(DESTDIR)/bin X INCROOT = $(DESTDIR)/include X BUILDINCROOT = $(TOP) X BUILDINCDIR = $(BUILDINCROOT)/X11 X BUILDINCTOP = .. X INCDIR = $(INCROOT)/X11 X ADMDIR = $(DESTDIR)/adm X LIBDIR = $(USRLIBDIR)/X11 X CONFIGDIR = $(LIBDIR)/config X LINTLIBDIR = $(USRLIBDIR)/lint X X FONTDIR = $(LIBDIR)/fonts X XINITDIR = $(LIBDIR)/xinit X XDMDIR = $(LIBDIR)/xdm X AWMDIR = $(LIBDIR)/awm X TWMDIR = $(LIBDIR)/twm X GWMDIR = $(LIBDIR)/gwm X MANPATH = $(DESTDIR)/man X MANSOURCEPATH = $(MANPATH)/man X MANDIR = $(MANSOURCEPATH)n X LIBMANDIR = $(MANSOURCEPATH)3 X XAPPLOADDIR = $(LIBDIR)/app-defaults X X SOXLIBREV = 4.2 X SOXTREV = 4.0 X SOXAWREV = 4.0 X SOOLDXREV = 4.0 X SOXMUREV = 4.0 X SOXEXTREV = 4.0 X X FONTCFLAGS = -t X X INSTAPPFLAGS = $(INSTDATFLAGS) X X IMAKE = imake X DEPEND = makedepend X RGB = rgb X FONTC = bdftosnf X MKFONTDIR = mkfontdir X MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier.sh X X CONFIGSRC = $(TOP)/config X CLIENTSRC = $(TOP)/clients X DEMOSRC = $(TOP)/demos X LIBSRC = $(TOP)/lib X FONTSRC = $(TOP)/fonts X INCLUDESRC = $(TOP)/X11 X SERVERSRC = $(TOP)/server X UTILSRC = $(TOP)/util X SCRIPTSRC = $(UTILSRC)/scripts X EXAMPLESRC = $(TOP)/examples X CONTRIBSRC = $(TOP)/../contrib X DOCSRC = $(TOP)/doc X RGBSRC = $(TOP)/rgb X DEPENDSRC = $(UTILSRC)/makedepend X IMAKESRC = $(CONFIGSRC) X XAUTHSRC = $(LIBSRC)/Xau X XLIBSRC = $(LIBSRC)/X X XMUSRC = $(LIBSRC)/Xmu X TOOLKITSRC = $(LIBSRC)/Xt X AWIDGETSRC = $(LIBSRC)/Xaw X OLDXLIBSRC = $(LIBSRC)/oldX X XDMCPLIBSRC = $(LIBSRC)/Xdmcp X BDFTOSNFSRC = $(FONTSRC)/bdftosnf X MKFONTDIRSRC = $(FONTSRC)/mkfontdir X EXTENSIONSRC = $(TOP)/extensions X X DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a X EXTENSIONLIB = -lXext X X DEPXLIB = $(DEPEXTENSIONLIB) X XLIB = $(EXTENSIONLIB) -lX11 X X DEPXAUTHLIB = $(USRLIBDIR)/libXau.a X XAUTHLIB = -lXau X X DEPXMULIB = X XMULIB = -lXmu X X DEPOLDXLIB = X OLDXLIB = -loldX X X DEPXTOOLLIB = X XTOOLLIB = -lXt X X DEPXAWLIB = X XAWLIB = -lXaw X X LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln X LINTXLIB = $(USRLIBDIR)/llib-lX11.ln X LINTXMU = $(USRLIBDIR)/llib-lXmu.ln X LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln X LINTXAW = $(USRLIBDIR)/llib-lXaw.ln X X DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) X X DEPLIBS1 = $(DEPLIBS) X DEPLIBS2 = $(DEPLIBS) X DEPLIBS3 = $(DEPLIBS) X X########################################################################### X# Imake rules for building libraries, programs, scripts, and data files X# rules: $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $ X X########################################################################### X# start of Imakefile X X PROGRAMS = sm X SM_DIR = $(LIBDIR)/sm X DEFINES = -DSM_DIR=\"${SM_DIR}\" X SYS_LIBRARIES = -lXaw -lXt -lXmu -lX11 X SRCS = Actions.c Atoms.c Globals.c \ X ICCUtils.c PropUtils.c SM.c \ X StateMisc.c StateGet.c StateExecute.c StateRead.c \ X StateSave.c Top.c Utils.c WinInfo.c X X OBJS = Actions.o Atoms.o Globals.o \ X ICCUtils.o PropUtils.o SM.o \ X StateMisc.o StateGet.o StateExecute.o StateRead.o \ X StateSave.o Top.o Utils.o WinInfo.o X X PROGRAM = sm X Xall:: sm X Xsm: $(OBJS) $(DEPLIBS) X $(RM) $@ X $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS) X Xsaber_sm: X #load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) X Xosaber_sm: X #load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) X Xinstall:: sm X $(INSTALL) -c $(INSTPGMFLAGS) sm $(BINDIR) X Xinstall.man:: sm.man X $(INSTALL) -c $(INSTMANFLAGS) sm.man $(MANDIR)/sm.n X Xdepend:: X $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS) X Xlint: X $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS) Xlint1: X $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS) X Xclean:: X $(RM) $(PROGRAM) X Xinstall:: SM.ad X $(INSTALL) -c $(INSTAPPFLAGS) SM.ad $(XAPPLOADDIR)/SM X Xinstall:: State X $(INSTALL) -c $(INSTDATFLAGS) State $(SM_DIR) X Xinstall:: FontPath X $(INSTALL) -c $(INSTDATFLAGS) FontPath $(SM_DIR) X Xinstall:: SM.xbm X $(INSTALL) -c $(INSTDATFLAGS) SM.xbm $(SM_DIR) X XSABERFLAGS = $(CFLAGS) X Xinstall.ln: X X########################################################################### X# common rules for all Makefiles - do not edit X Xemptyrule:: X Xclean:: X $(RM_CMD) \#* X XMakefile:: X -@if [ -f Makefile ]; then \ X echo " $(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \ X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ X else exit 0; fi X $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) X Xtags:: X $(TAGS) -w *.[ch] X $(TAGS) -xw *.[ch] > TAGS X Xsaber: X #load $(ALLDEFINES) $(SRCS) X Xosaber: X #load $(ALLDEFINES) $(OBJS) X X########################################################################### X# empty rules for directories that do not have SUBDIRS - do not edit X Xinstall:: X @echo "install in $(CURRENT_DIR) done" X Xinstall.man:: X @echo "install.man in $(CURRENT_DIR) done" X XMakefiles:: X Xincludes:: X X########################################################################### X# dependencies generated by makedepend X @EOF else echo "shar: Will not over write Makefile" fi echo "Finished archive 2 of 2" # to concatenate archives, remove anything after this line exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.