v12i071: olvwm - Open Look Virtual Window Manager, Part15/16

Scott Oaks - Sun Consulting NYC sdo at soliado.East.Sun.COM
Mon Apr 29 03:31:39 AEST 1991


Submitted-by: sdo at soliado.East.Sun.COM (Scott Oaks - Sun Consulting NYC)
Posting-number: Volume 12, Issue 71
Archive-name: olvwm/part15

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 15 (of 16)."
# Contents:  resources.c
# Wrapped by sdo at piccolo on Fri Apr 26 17:31:11 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'resources.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'resources.c'\"
else
echo shar: Extracting \"'resources.c'\" \(40786 characters\)
sed "s/^X//" >'resources.c' <<'END_OF_FILE'
X/*
X *      (c) Copyright 1990 Sun Microsystems, Inc. Sun design patents
X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
X *      file for terms of the license.
X *
X *	Written for Sun Microsystems by Crucible, Santa Cruz, CA.
X */
X
static char     sccsid[] = "@(#)resources.c	1.5 olvwm version 4/26/91";
X
X/*
X * Based on
static	char	sccsid[] = "@(#) resources.c 25.34 90/06/05 Crucible";
X *
X */
X
X#include <ctype.h>
X#include <errno.h>
X#include <stdio.h>
X#include <string.h>
X#include <sys/file.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Xresource.h>
X#include <X11/keysym.h>
X#include <X11/cursorfont.h>
X
X#include <olgx/olgx.h>
X
X#include "mem.h"
X#include "olwm.h"
X#include "win.h"
X#include "defaults.h"
X#include "globals.h"
X#include "resources.h"
X#include "olcursor.h"
X
extern	char		*AppName;
extern	Bool 		ColorDisplay;
extern	List		*ActiveClientList;
X
extern 	Graphics_info	*olgx_gisbutton;
extern 	Graphics_info	*olgx_gistext;
extern 	Graphics_info	*olgx_gisnormal;
extern 	Graphics_info	*olgx_gisreverse;
extern 	Graphics_info	*olgx_gisrevpin;
X
extern	GC		DrawNormalGC, DrawReverseGC;
extern	GC		DrawLinesGC, DrawRevLinesGC;
extern	GC		DrawBackgroundGC, DrawSelectedGC;
extern	GC		DrawBusyGC;
extern	GC		IconUnselectedGC, IconBorderGC;
extern	GC		IconNormalGC, IconSelectedGC;
X
extern Pixmap Gray50;
extern int Gray50width;
extern int Gray50height;
X
XXrmDatabase		OlwmDB = NULL;
GlobalResourceVariables	GRV;
X
Bool WorkspaceColorUsed = False;
unsigned long WorkspaceColorPixel;
X
static Bool windowColorsAllocated = False;
X
extern void FrameSetupGrabs();
X
X/* forward function definitions */
static Bool setMinimalDecor();
static Bool setBeepResource();
static Bool updIconLocation();
static Bool updBorderColor();
X
Bool UpdInputFocusStyle();
X
X/* NOTICE that the optionTable for command line entries is mostly 
X * independent of this table.  BOTH need to be modified in case of
X * changes or additions.
X */
X/* quantity of/indices into the RMTable are #define'd in resources.h */
ResourceInfo	RMTable[] = {
X	{ ".display",			".Display",		NULL,	
X	    &(GRV.DisplayName),		(BFuncPtr)0,		(BFuncPtr)0 },
X	{ ".name",			".Name",		"olwm", 
X	    &(GRV.NameTag),		SetNameTag,		(BFuncPtr)0 },
X	{ ".workspaceColor",		".WorkspaceColor",	NULL, 
X	    &(GRV.WorkspaceColor),	setCharResource,	UpdWorkspace },
X	{ ".use3D",			".Use3D",		"True", 
X	    &(GRV.F3dUsed),		setDimension,		(BFuncPtr)0 },
X	{ ".WindowColor", 		".Background",		NULL, 
X	    &(GRV.Bg1Color),		setBg1Color,		UpdBg1Color },
X	{ ".foreground",		".Foreground",		NULL, 
X	    &(GRV.Fg1Color),		setFg1Color,		UpdFg1Color },
X	{ ".borderColor",		".Foreground",		NULL, 
X	    &(GRV.BorderColor),		setColor,		updBorderColor },
X	{ ".cursorColor",		".Foreground",		NULL, 
X	    &(GRV.CursorColor),		setColor,		UpdCursorColor },
X/* NOTICE that font defaults are names, although variables are font infos */
X#ifdef LATER	/* ideal name/class setup */
X	{ ".title.font",		".Title.Font",	
X	    "-b&h-lucida-bold-r-normal-sans-*-120-*-*-*-*-*-*", 
X	    &(GRV.TitleFontInfo),	setFontResource,	UpdTitleFont },
X	{ ".text.font",			".Text.Font",	
X	    "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*", 
X	    &(GRV.TextFontInfo),	setFontResource, 	UpdTextFont },
X	{ ".button.font",		".Button.Font",	
X	     "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*",
X	    &(GRV.ButtonFontInfo),	setFontResource, 	UpdButtonFont },
X	{ ".icon.font",			".Icon.Font",	
X	     "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*",
X	    &(GRV.IconFontInfo),	setFontResource,	UpdIconFont },
X#else
X	{ ".titleFont",			".TitleFont",	
X	    "-b&h-lucida-bold-r-normal-sans-*-120-*-*-*-*-*-*", 
X	    &(GRV.TitleFontInfo),	setFontResource,	UpdTitleFont },
X	{ ".textFont",			".TextFont",	
X	    "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*", 
X	    &(GRV.TextFontInfo),	setFontResource, 	UpdTextFont },
X	{ ".buttonFont",		".MenuButtonFont",	
X	     "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*",
X	    &(GRV.ButtonFontInfo),	setFontResource, 	UpdButtonFont },
X	{ ".iconFont",			".IconFont",	
X	     "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*",
X	    &(GRV.IconFontInfo),	setFontResource,	UpdIconFont },
X#endif /* LATER */
X	{ ".glyphFont",			".GlyphFont",	
X	     "-sun-open look glyph-*-*-*-*-*-120-*-*-*-*-*-*",
X	    &(GRV.GlyphFontInfo),	setGlyphFont,		UpdGlyphFont },
X	{ ".cursorFont",		".CursorFont",	
X	     "-sun-open look cursor-*-*-*-*-*-120-*-*-*-*-*-*",
X	    &(GRV.BasicPointer),	setCursors,		(BFuncPtr)0 },
X	{ ".inputFocusStyle",		".SetInput",		"Select",
X	    &(GRV.FocusFollowsMouse),	setInputFocusStyle,	UpdInputFocusStyle },
X	{ ".reparentOK",		".ReparentOK",		"True", 
X	    &(GRV.ReparentFlag),	setBoolResource,	(BFuncPtr)0 },
X	{ ".defaultTitle",		".DefaultTitle",	"No Name", 
X	    &(GRV.DefaultWinName),	setCharResource,	 (BFuncPtr)0 },
X	{ ".flashFrequency",		".FlashFrequency",	"100000", 
X	    &(GRV.FlashTime),		setIntResource,		(BFuncPtr)0 },
X	{ ".menu.popup.outlineButton",	".Menu.Popup.OutlineButton", "False",
X	    &(GRV.FShowMenuButtons),	setBoolResource,	 (BFuncPtr)0 },
X	{ ".menu.pinned.outlineButton",	".Menu.Pinned.OutlineButton", "False",
X	    &(GRV.FShowPinnedMenuButtons), setBoolResource,	(BFuncPtr)0 },
X	{ ".iconLocation",		".IconLocation", 	"Top",
X	    &(GRV.IconPlacement),	setIconLocation,	updIconLocation },
X	{ ".focusLenience",		".FocusLenience", 	"False",
X	    &(GRV.FocusLenience),	setBoolResource,	(BFuncPtr)0 },
X	{ ".dragWindow",		".DragWindow", 		"False",
X	    &(GRV.DragWindow),		setBoolResource,	(BFuncPtr)0 },
X	{ ".autoRaise",			".AutoRaise",		"False",
X	    &(GRV.AutoRaise),		setBoolResource,	(BFuncPtr)0 },
X	{ ".dragRightDistance",		".DragRightDistance",	"100",
X	    &(GRV.DragRightDistance),	setIntResource,		(BFuncPtr)0 },
X	{ ".moveThreshold",		".MoveThreshold",	"5",
X	    &(GRV.MoveThreshold),	setIntResource,		(BFuncPtr)0 },
X	{ ".clickMoveThreshold",	".ClickMoveThreshold",	"5",
X	    &(GRV.ClickMoveThreshold),	setIntResource,		(BFuncPtr)0 },
X	{ ".mouseClickTimeout",		".MultiClickTimeout",	"500",
X	    &(GRV.DoubleClickTime),	setClickTimeout,	(BFuncPtr)0 },
X/* NOTICE that key defaults are string reps of syms, but vars are keycodes */
X	{ ".frontKey",			".FrontKey",		"Any L5",
X	    &(GRV.FrontKey),		setKey,			(BFuncPtr)0 },
X	{ ".helpKey",			".HelpKey",		"Help",
X	    &(GRV.HelpKey),		setKey,			(BFuncPtr)0 },
X	{ ".openKey",			".OpenKey",		"Any L7",
X	    &(GRV.OpenKey),		setKey,			(BFuncPtr)0 },
X	{ ".confirmKey",		".ConfirmKey",		"Return",
X	    &(GRV.ConfirmKey),		setKey,			(BFuncPtr)0 },
X	{ ".print.orphans",		".Print.Debug",		"False", 
X	    &(GRV.PrintOrphans),	setBoolResource,	(BFuncPtr)0 },
X	{ ".print.all",			".Print.Debug",		"False", 
X	    &(GRV.PrintAll),		setBoolResource,	(BFuncPtr)0 },
X	{ ".synchronize",		".Debug",		"False", 
X	    &(GRV.Synchronize),		setBoolResource,	UpdSync },
X	{ ".snapToGrid",		".SnapToGrid",		"False",
X	    &(GRV.FSnapToGrid),		setBoolResource,	(BFuncPtr)0 },
X	{ ".saveWorkspaceTimeout",	".SaveWorkspaceTimeout", "10",
X	    &(GRV.SaveWorkspaceTimeout), setIntResource,	(BFuncPtr)0 },
X	{ ".popupJumpCursor",		".PopupJumpCursor",	"True",
X	    &(GRV.PopupJumpCursor),	setBoolResource,	(BFuncPtr)0 },
X	{ ".cancelKey",			".CancelKey",		"Escape",
X	    &(GRV.CancelKey),		setKey,			(BFuncPtr)0 },
X	{ ".colorLockKey",		".ColorLockKey",	"Control L2",
X	    &(GRV.ColorLockKey),	setKey,			(BFuncPtr)0 },
X	{ ".colorUnlockKey",		".ColorUnlockKey",	"Control L4",
X	    &(GRV.ColorUnlockKey),	setKey,			(BFuncPtr)0 },
X	{ ".colorFocusLocked",		".ColorFocusLocked",	"False",
X	    &(GRV.ColorFocusLocked),	setBoolResource,	(BFuncPtr)0 },
X	{ ".edgeMoveThreshold",		".EdgeMoveThreshold", 	"10",
X	    &(GRV.EdgeThreshold),	setIntResource,		(BFuncPtr)0 },
X	{ ".rubberBandThickness",	".RubberBandThickness",	"2",
X	    &(GRV.RubberBandThickness),	setIntResource,		(BFuncPtr)0 },
X	{ ".beep",			".Beep",		"always",
X	    &(GRV.Beep),		setBeepResource,	(BFuncPtr)0 },
X	{ ".pPositionCompat",		".PPositionCompat",	"false",
X	    &(GRV.PPositionCompat),	setBoolResource,	(BFuncPtr)0 },
X	{ ".minimalDecor",		".MinimalDecor",	"",
X	    &(GRV.Minimals),		setMinimalDecor,	(BFuncPtr)0 },
X	{ ".use3DFrames",		".Use3DFrames",		"False", 
X	    &(GRV.F3dFrames),		setBoolResource,	(BFuncPtr)0 },
X	{ ".refreshRecursively",	".RefreshRecursively",	"True",
X	    &(GRV.RefreshRecursively),	setBoolResource,	(BFuncPtr)0 },
X	{ ".virtualDesktop",		".VirtualDesktop",	"3x2",
X	    GRV.VirtualDesktop,		setStringResource,	UpdVirtualDesktop },
X	{ ".allowMoveIntoDesktop",	".AllowMoveIntoDesktop","true",
X	    &(GRV.AllowMoveIntoDesktop),	setBoolResource,	(BFuncPtr)0 },
X	{ ".vdmScale",		".PannerScale",		"15",
X	    &(GRV.VDMScale),		setIntResource,		UpdVDMScale },
X	{ ".virtualGeometry",		".VirtualGeometry",	"0x0",
X	    GRV.VirtualGeometry,	setStringResource,	UpdVirtualGeometry},
X	{ ".virtualFont",		".VirtualFont",	
X	     "-b&h-lucida-medium-r-normal-sans-*-120-*-*-*-*-*-*",
X	    &(GRV.VirtualFont),		setFontResource,	UpdVirtualFont },
X	{ ".allowArrowInRoot",		".AllowArrowInRoot",	"True",
X	    &(GRV.ArrowInRoot),		setBoolResource,	(BFuncPtr) 0 },
X	{ ".virtualBackgroundColor",	".VirtualBackgroundColor",	"-1",
X	    &(GRV.VirtualBackgroundColor),	VirtualSetColor,	UpdVirtualBgColor },
X	{ ".virtualBackgroundMap",	".VirtualBackgroundMap", NULL,
X	    &(GRV.VirtualBackgroundMap),		setCharResource,	UpdVirtualMap },
X	{ ".virtualIconGeometry",	".VirtualIconGeometry",	"0x0",
X	    GRV.VirtualIconGeometry,	setStringResource,	UpdVirtualIconGeometry},
X	{ ".virtualForegroundColor",	".VirtualForegroundColor",	"-1",
X	    &(GRV.VirtualForegroundColor),	VirtualSetColor,	UpdVirtualFgColor },
X	{ ".virtualFontColor",		".VirtualFontColor",	"-1",
X	    &(GRV.VirtualFontColor),	VirtualSetColor,	UpdVirtualFontColor },
X	{ ".autoShowRootMenu",		".AutoShowRootMenu",	"False",
X	    &(GRV.AutoShowRootMenu),	setBoolResource,	(BFuncPtr) 0 },
X	{ ".autoRootMenuX",		".AutoRootMenuX",	"0",
X	    &(GRV.AutoRootMenuX),	setIntResource,		(BFuncPtr) 0 },
X	{ ".autoRootMenuY",		".AutoRootMenuY",	"0",
X	    &(GRV.AutoRootMenuY),	setIntResource,		(BFuncPtr) 0 },
X	{ ".virtualIconic",		".VirtualIconic",	"False",
X	    &(GRV.VirtualIconic),	setBoolResource,	(BFuncPtr) 0 },
X	{ ".virtualSticky",		".VirtualSticky",	"",
X	    &(GRV.StickyList),		setMinimalDecor,	(BFuncPtr)0 },
X};
X
X/* private data */
X
static Bool matchString();
static Bool matchBool();
static Bool matchFocusType();
static Bool matchIconPlace();
static Bool matchBeepKeyword();
X#ifdef NOTDEF
static Bool checkClass();
X#endif
static void setWorkspaceColor();
X
X
X#define BSIZE 100
X
X/*
X * Determine whether value matches pattern, irrespective of case.
X * This routine is necessary because not all systems have strcasecmp().
X */
static Bool
matchString( value, pattern )
char *value;
char *pattern;
X{
X    char buf[BSIZE];
X    char *p;
X
X    strncpy(buf,value,BSIZE);
X    buf[BSIZE-1] = '\0'; /* force null termination */
X
X    for ( p=buf; *p; ++p )
X	if (isupper(*p))
X	    *p = tolower(*p);
X
X    return 0 == strcmp(buf,pattern);
X}
X
X
X/*
X * Match any of the following booleans: yes, no, 1, 0, on, off, t, nil, 
X * true, false.  Pass back the boolean matched in ret, and return True.  
X * Otherwise, return False.
X *
X * matchString is case independent.
X */
static Bool
matchBool( value, ret )
char *value;
Bool *ret;
X{
X    if (matchString(value,"yes") ||
X	matchString(value,"on") ||
X	matchString(value,"t") ||
X	matchString(value,"true") ||
X	(0 == strcmp(value,"1"))) {
X	*ret = True;
X	return True;
X    }
X
X    if (matchString(value,"no") ||
X	matchString(value,"off") ||
X	matchString(value,"nil") ||
X	matchString(value,"false") ||
X	(0 == strcmp(value,"0"))) {
X	*ret = False;
X	return True;
X    }
X
X    return False;
X}
X
X/*
X * Match any of the following input focus types: followmouse, follow, f, 
X * select, s, click, clicktotype, c.  Pass back True for focusfollows or 
X * False for clicktotype in ret (since FocusFollowsMouse is the global
X * corresponding to this resource), and return True.  
X * Otherwise, return False.
X *
X * matchString is case independent.
X */
static Bool
matchFocusType( value, ret )
char *value;
Bool *ret;
X{
X	if ( matchString(value, "followmouse")
X	     || matchString(value, "follow") 
X	     || matchString(value,"f") )
X	{
X		*ret = True;
X		return True;
X	}
X
X	if ( matchString(value, "select")
X	     || matchString(value, "click") 
X	     || matchString(value,"clicktotype")
X	     || matchString(value,"c")
X	     || matchString(value,"s") )
X	{
X		*ret = False;
X		return True;
X	}
X
X	return False;
X}
X
X/*
X * Match any of the three possible beep keywords:  always, never, or notices.
X * Pass back the BeepStatus value by reference, and return True, if
X * a match was found; otherwise return False and do not disturb the
X * passed value.
X */
static Bool
matchBeepKeyword(value,ret)
char *value;
BeepStatus *ret;
X{
X	if (matchString(value,"always"))
X	{
X	    *ret = BeepAlways;
X	    return True;
X	}
X	if (matchString(value,"never"))
X	{
X	    *ret = BeepNever;
X	    return True;
X	}
X	if (matchString(value,"notices"))
X	{
X	    *ret = BeepNotices;
X	    return True;
X	}
X	return False;
X}
X
X/*
X * Match any of the following icon placement locations: top, bottom, right, 
X * left, s, click, clicktotype, c.  Pass back the IconPreference 
X * in ret, and return True.  
X * Otherwise, return False.
X *
X * matchString is case independent.
X */
static Bool
matchIconPlace( value, ret )
char		*value;
IconPreference	*ret;
X{
X	if (matchString(value, "top"))
X	{
X		*ret = AlongTop;
X		return True;
X	}
X	if (matchString(value, "bottom"))
X	{
X		*ret = AlongBottom;
X		return True;
X	}
X	if (matchString(value, "right"))
X	{
X		*ret = AlongRight;
X		return True;
X	}
X	if (matchString(value, "left"))
X	{
X		*ret = AlongLeft;
X		return True;
X	}
X	if (matchString(value, "top-lr"))
X	{
X		*ret = AlongTop;
X		return True;
X	}
X	if (matchString(value, "top-rl"))
X	{
X		*ret = AlongTopRL;
X		return True;
X	}
X	if (matchString(value, "bottom-lr"))
X	{
X		*ret = AlongBottom;
X		return True;
X	}
X	if (matchString(value, "bottom-rl"))
X	{
X		*ret = AlongBottomRL;
X		return True;
X	}
X	if (matchString(value, "right-tb"))
X	{
X		*ret = AlongRight;
X		return True;
X	}
X	if (matchString(value, "right-bt"))
X	{
X		*ret = AlongRightBT;
X		return True;
X	}
X	if (matchString(value, "left-tb"))
X	{
X		*ret = AlongLeft;
X		return True;
X	}
X	if (matchString(value, "left-bt"))
X	{
X		*ret = AlongLeftBT;
X		return True;
X	}
X
X	return False;
X}
X
X#ifdef NOTDEF
X/*
X * checkClass - Check to see if the named class is the same as (or a subset of)
X * 	the compareClass specified.
X *
X *	Note that the fullClassname must be consistently bound!
X *	(If combine loose and tight bindings, need to convert to using 
X *	XrmStringToBindingQuarkList().)
X */
static Bool
checkClass( fullClassname, compareClass )
char	*fullClassname;
char	*compareClass;
X{
X#define	MAX_QUARKS	20
X	XrmQuark	classQuarks[MAX_QUARKS];
X	XrmQuark	compareQuark;
X	int		ii;
X
X	compareQuark = XrmStringToQuark( compareClass );
X	XrmStringToQuarkList( fullClassname, classQuarks );
X	for ( ii = 0 ;  (ii < MAX_QUARKS) && (classQuarks[ii] != NULL) ; ii++ )
X		if ( compareQuark == classQuarks[ii] )
X			return True;
X
X	return False;
X}
X#endif
X
X
X/*
X *	The Resource Set Functions
X */
X
X/*
X * setBoolResource - set value of a bool resource
X *
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setBoolResource( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool	newBoolValue;
X	Bool	updateNeeded = False;
X#define RM_BOOLVAR     *((Bool *)(RMTable[rmIndex].varAddr))
X
X	if ( (newValue == NULL) || !matchBool( newValue, &newBoolValue ) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X			matchBool( RMTable[rmIndex].defaultVal, &newBoolValue );
X	}
X	else if ( varSet )	/* a valid newValue and an old value */
X	{
X		if ( newBoolValue == RM_BOOLVAR )
X			return( updateNeeded );
X		else
X			updateNeeded = True;
X	}
X
X	RM_BOOLVAR = newBoolValue;
X	return( updateNeeded );
X}
X
X/*
X * setFontResource - set font info variable from db resource value 
X *
X *	Notice that since comparing XFontStructs would be rather messy,
X *	we cheat and simply compare the font names in the database.
X */
static Bool
setFontResource( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	XFontStruct		*tmpFontInfo;
X	Bool			updateNeeded = False;
X	char			name[MAX_NAME];
X	char			class[MAX_CLASS];
X	XrmRepresentation	rmType;
X	XrmValue		rmValue;
X
X#define RM_FONTVAR     *((XFontStruct **)(RMTable[rmIndex].varAddr))
X
X	if ( ( newValue == NULL ) ||
X	     ( (tmpFontInfo = XLoadQueryFont(dpy, newValue)) == NULL ) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else if ( ( tmpFontInfo = 
X			    XLoadQueryFont(dpy, RMTable[rmIndex].defaultVal) )
X			  == NULL )
X                	tmpFontInfo = XLoadQueryFont(dpy, DEFAULTFONT);
X	}
X	else if ( varSet )
X	{
X		MakeRMName( name, rmIndex );
X		MakeRMClass( class, rmIndex );
X		/* compare newValue with old value - REMIND if default was used
X		 * last time, and newValue was now set to it vi xrdb, then we 
X		 * may do an update unnecessarily (since value will not be in 
X		 * OlwmDB, so XrmGetResource will return False and updateNeeded
X		 * will be set to True, since we can't strcmp the value)
X		 */
X		if ( XrmGetResource( OlwmDB, name, class, &rmType, &rmValue ) 
X		     && !strcmp( newValue, rmValue.addr ) )
X			return( updateNeeded );
X		else
X			updateNeeded = True;
X	}
X
X	RM_FONTVAR = tmpFontInfo;
X	return( updateNeeded );
X}
X
X/*
X * setGlyphFont - set glyph font info variable from db resource value 
X *
X *	Notice that since comparing XFontStructs would be rather messy,
X *	we cheat and simply compare the font names in the database.
X *
X *	This is essentially the same as SetFontResource, except that
X *	the absence of a valid glyph font is a fatal error.
X */
static Bool
setGlyphFont( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	XFontStruct		*tmpFontInfo;
X	Bool			updateNeeded = False;
X	char			name[MAX_NAME];
X	char			class[MAX_CLASS];
X	XrmRepresentation	rmType;
X	XrmValue		rmValue;
X
X#ifndef RM_FONTVAR
X#define RM_FONTVAR     *((XFontStruct **)(RMTable[rmIndex].varAddr))
X#endif
X
X	if ( ( newValue == NULL ) ||
X	     ( (tmpFontInfo = XLoadQueryFont(dpy, newValue)) == NULL ) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else if ( ( tmpFontInfo = 
X			    XLoadQueryFont(dpy, RMTable[rmIndex].defaultVal) )
X			  == NULL )
X		{
X			fprintf(stderr, 
X				"OLWM fatal error:  can't load glyph font \"%s\"; exiting\n",
X				RMTable[rmIndex].defaultVal);
X			exit(1);
X		}
X	}
X	else if ( varSet )
X	{
X		MakeRMName( name, rmIndex );
X		MakeRMClass( class, rmIndex );
X		/* compare newValue with old value - REMIND if default was used
X		 * last time, and newValue was now set to it vi xrdb, then we 
X		 * may do an update unnecessarily (since value will not be in 
X		 * OlwmDB, so XrmGetResource will return False and updateNeeded
X		 * will be set to True, since we can't strcmp the value)
X		 */
X		if ( XrmGetResource( OlwmDB, name, class, &rmType, &rmValue ) 
X		     && !strcmp( newValue, rmValue.addr ) )
X			return( updateNeeded );
X		else
X			updateNeeded = True;
X	}
X
X	RM_FONTVAR = tmpFontInfo;
X	return( updateNeeded );
X}
X
X/*
X * setCursors - set up ALL cursors from cursor font specified
X *
X *	NOTE that CursorColor and Bg1Color must be set before the cursors!
X *
X *	Notice that six cursors are set up (and stored in six separate
X *	GRV elements) from this single resource.
X *
X *	Also, since we don't save the actual cursor font name,
X *	checking to see if the font has been changed must be done by
X *	comparing the font names in the database.
X *
X */
static Bool
setCursors( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Font			cursorFont = 0; 	/* init for compare */
X	Bool			updateNeeded = False;
X	char			name[MAX_NAME];
X	char			class[MAX_CLASS];
X	XrmRepresentation	rmType;
X	XrmValue		rmValue;
X	int			ii;
X	XColor			foreColor, backColor;
X
X	if ( ( newValue == NULL )
X	     || ( (cursorFont = XLoadFont( dpy, newValue )) == 0 ) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* use built-in default if possible */
X			cursorFont = XLoadFont( dpy, 
X						RMTable[rmIndex].defaultVal );
X	}
X	else if ( varSet )
X	{
X		/* check to see if cursor font in resource actually changed */
X		MakeRMName( name, rmIndex );
X		MakeRMClass( class, rmIndex );
X		/* compare newValue with old value - REMIND doesn't detect
X		 * when built-in default values are used 
X		 */
X		if ( XrmGetResource( OlwmDB, name, class, &rmType, &rmValue ) 
X		     && !strcmp( newValue, rmValue.addr ) )
X			return( updateNeeded );
X		else
X			updateNeeded = True;
X	}
X	
X	/* set up cursor rgb values in color structure */
X	foreColor.pixel = GRV.CursorColor;
X	XQueryColor( dpy, CMAP, &foreColor );
X	/* REMIND - should backColor be background (GRV.Bg1Color)? */
X	backColor.pixel = WhitePixel( dpy, DefaultScreen(dpy) );
X	XQueryColor( dpy, CMAP, &backColor );
X
X	/* loop through and set all six pointers */
X	for ( ii = 0 ; ii < NUM_CURSORS ; ii++ )
X	{
X	    Cursor		*tmpVariable;
X	    unsigned int	tmpFontIndex;
X	    unsigned int	defaultIndex;
X
X	    switch( ii )
X	    {
X	    /* REMIND - we might need to change these absolute indices to
X	     * #defines of some sort
X	     */
X	    case BASICPTR:	tmpVariable = &GRV.BasicPointer;
X				tmpFontIndex = OLC_basic;
X				defaultIndex = XC_left_ptr;
X				break;
X	    case MOVEPTR:	tmpVariable = &GRV.MovePointer;
X				tmpFontIndex = OLC_basic;
X				defaultIndex = XC_left_ptr;
X				break;
X	    case BUSYPTR:	tmpVariable = &GRV.BusyPointer;
X				tmpFontIndex = OLC_busy;
X				defaultIndex = XC_watch;
X				break;
X	    case ICONPTR:	tmpVariable = &GRV.IconPointer;
X				tmpFontIndex = OLC_basic;
X				defaultIndex = XC_left_ptr;
X				break;
X	    case RESIZEPTR:	tmpVariable = &GRV.ResizePointer;
X				tmpFontIndex = OLC_beye;
X				defaultIndex = XC_tcross;
X				break;
X	    case MENUPTR:	tmpVariable = &GRV.MenuPointer;
X				tmpFontIndex = OLC_basic;
X				defaultIndex = XC_sb_right_arrow;
X				break;
X	    case QUESTIONPTR:	tmpVariable = &GRV.QuestionPointer;
X				tmpFontIndex = OLC_basic;
X				defaultIndex = XC_question_arrow;
X				break;
X	    case TARGETPTR:	tmpVariable = &GRV.TargetPointer;
X				tmpFontIndex = OLC_basic;
X				defaultIndex = XC_circle;
X				break;
X	    case PANPTR:	tmpVariable = &GRV.PanPointer;
X				tmpFontIndex = OLC_panning;
X				defaultIndex = XC_sb_v_double_arrow;
X				break;
X	    }
X
X	    if ( ( cursorFont == 0 )
X	         || ( (*tmpVariable = XCreateGlyphCursor( dpy, cursorFont,
X				cursorFont, tmpFontIndex, tmpFontIndex+1, 
X				&foreColor, &backColor )) == 0 ) )
X	    {
X	    	/* use default */
X	    	*tmpVariable = XCreateFontCursor( dpy, defaultIndex );
X#ifdef LATER
X		/* seems to be a bug in XRecolorCursor() right now */
X		XRecolorCursor( dpy, tmpVariable, &foreColor, &backColor );
X#endif
X	    }
X	}
X
X	return( updateNeeded );
X}
X
X/*
X * setCharResource - set character resource value from db 
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setCharResource( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	char	*setValue;
X	Bool	updateNeeded = False;
X#define RM_CHARVAR     (*((char **)(RMTable[rmIndex].varAddr)))
X
X	if ( newValue == NULL )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default - we're assuming varSet is a
X			 * reliable indicator that the value was not set
X			 * previously (else it would need to be MemFree'd
X			 */
X			setValue = RMTable[rmIndex].defaultVal;
X	}
X	else 
X	{
X		if (varSet && RM_CHARVAR != NULL &&
X		    strcmp(RM_CHARVAR, newValue) == 0) {
X			return( updateNeeded );
X		} else {
X			updateNeeded = True;
X			/* REMIND: if not previously set, what will happen?
X			 * Does our global array initialization guarantee a
X			 * NULL ptr there?
X			 */
X			MemFree( RM_CHARVAR );
X			setValue = newValue;
X		}
X	}
X
X	/* REMIND: this is slightly inefficient, since the defaultVal may 
X	 * copied, but it makes the MemFree unconditional when updating 
X	 * the value
X	 */
X	if ( setValue != NULL )
X		RM_CHARVAR = MemNewString( setValue );
X	else
X		RM_CHARVAR = NULL;
X
X	return( updateNeeded );
X}
X
X#ifdef NOTDEF
X/*
X * setFloatResource - retrieve float resource from OlwmDB
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setFloatResource( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool	updateNeeded = False;
X	float	newFloat;
X#define RM_FLOATVAR     *((float *)(RMTable[rmIndex].varAddr))
X
X	if ( newValue == NULL )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X			sscanf( RMTable[rmIndex].defaultVal, "%f", &newFloat);
X	}
X	else 
X	{
X		sscanf( newValue, "%f", &newFloat);
X		if ( varSet )
X		{
X			if ( newFloat == RM_FLOATVAR )
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X	RM_FLOATVAR = newFloat;
X	return( updateNeeded );
X}
X#endif
X
X/*
X * setIntResource - retrieve integer value from resource db
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setIntResource( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool	updateNeeded = False;
X	int	newInt;
X#define RM_INTVAR     *((int *)(RMTable[rmIndex].varAddr))
X
X	if ( newValue == NULL )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X			newInt = atoi( RMTable[rmIndex].defaultVal );
X	}
X	else 
X	{
X		newInt = atoi( newValue );
X		if ( varSet )
X		{
X			if ( newInt == RM_INTVAR )
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X	RM_INTVAR = newInt;
X	return( updateNeeded );
X}
X
X/*
X * setStringResource - retrieve string value from resource db
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setStringResource( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool	updateNeeded = False;
X	char	*NewS;
X
X	if ( newValue == NULL )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X			NewS = RMTable[rmIndex].defaultVal;
X	}
X	else 
X	{
X		NewS = newValue;
X		if ( varSet )
X		{
X			if ( NewS == RMTable[rmIndex].varAddr )
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X	strcpy(RMTable[rmIndex].varAddr, NewS);
X	return( updateNeeded );
X}
X
X/*
X * setClickTimeout - retrieve value for clickTimeout resource
X *	(Not simply a SetIntResource since must be converted to millisec.)
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setClickTimeout( dpy, rmIndex, newValue, varSet)
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool	updateNeeded = False;
X	int	newInt;
X#ifndef RM_INTVAR
X#define RM_INTVAR     *((int *)(RMTable[rmIndex].varAddr))
X#endif
X
X	if ( newValue == NULL )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default REMIND - need convert to milli? */
X			newInt = atoi( RMTable[rmIndex].defaultVal );
X	}
X	else 
X	{
X		newInt = atoi( newValue ) * 100;    /* convert to millisec*/
X		if ( varSet )
X		{
X			if ( newInt == RM_INTVAR )
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X	/*
X	 * It's nearly impossible for the hardware to actually generate two
X	 * clicks in less than 100ms.  We make a special case for this and
X	 * make the minimum timeout value be 150ms.
X	 */
X	if (newInt < 150)
X	    newInt = 150;
X
X	RM_INTVAR = newInt;
X	return( updateNeeded );
X}
X
X
X/*
X * setFg1Color - retrieve color name resource from OlwmDB 
X *	and convert to pixel value
X */
static Bool
setFg1Color( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	XColor		exact;
X	unsigned long	newColor;
X	Bool		updateNeeded = False;
X#define RM_COLORVAR     *((unsigned long *)(RMTable[rmIndex].varAddr))
X
X#ifndef COLOR2D
X	if ( !GRV.F3dUsed )
X		newColor = BlackPixel( dpy, DefaultScreen(dpy) );
X	else
X	{
X#endif /* COLOR2D */
X	if ( (newValue == NULL)
X	      || (!XParseColor( dpy, CMAP, newValue, &exact ))
X	      || (!XAllocColor( dpy, CMAP, &exact )) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else 
X		{
X			exact.pixel = BlackPixel( dpy, DefaultScreen(dpy) );
X			XQueryColor( dpy, CMAP, &exact );
X			exact.red = (exact.red*8)/10;
X			exact.green = (exact.green*8)/10;
X			exact.blue = (exact.blue*8)/10;
X			if ( XAllocColor( dpy, CMAP, &exact ) )
X				newColor = exact.pixel;
X			else	/* REMIND should OlwmDB value change? */
X				newColor = BlackPixel(dpy, DefaultScreen(dpy));
X		}
X	}
X	else 
X	{
X		newColor = exact.pixel;
X		if ( varSet )
X		{
X			if ( newColor == RM_COLORVAR )
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X#ifndef COLOR2D
X	}	/* end GRV.F3dUsed */
X#endif /* COLOR2D */
X
X	RM_COLORVAR = newColor;
X	return( updateNeeded );
X}
X
X
X/*
X * setBg1Color - retrieve color name resource from OlwmDB 
X *	and convert to pixel value
X *
X *	NOTE that Bg1Color must be set before any other color can be set!!!
X */
static Bool
setBg1Color( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	XColor		exact;
X	XColor		fgc, bg2c, bg3c, whitec;
X	unsigned long	newColor;
X	unsigned long	oldcells[4];
X	int		oldcellcount = 0;
X#ifndef RM_COLORVAR
X#define RM_COLORVAR     *((unsigned long *)(RMTable[rmIndex].varAddr))
X#endif
X
X	if (windowColorsAllocated) {
X	    /*
X	     * REMIND: this code helps prevent us from freeing the same cell 
X	     * twice.  We should be able to do this according to the protocol, 
X	     * but some servers have bugs where allocating a cell twice and 
X	     * then freeing it once will actually free the cell.
X	     */
X	    if (GRV.Bg0Color != WorkspaceColorPixel)
X		oldcells[oldcellcount++] = GRV.Bg0Color;
X	    if (GRV.Bg1Color != WorkspaceColorPixel)
X		oldcells[oldcellcount++] = GRV.Bg1Color;
X	    if (GRV.Bg2Color != WorkspaceColorPixel)
X		oldcells[oldcellcount++] = GRV.Bg2Color;
X	    if (GRV.Bg3Color != WorkspaceColorPixel)
X		oldcells[oldcellcount++] = GRV.Bg3Color;
X	    XFreeColors(dpy, CMAP, oldcells, oldcellcount, 0);
X	    windowColorsAllocated = False;
X	}
X
X	if ((newValue != NULL) &&
X	    (XParseColor(dpy, CMAP, newValue, &exact) == 1) &&
X	    (XAllocColor(dpy, CMAP, &exact) == 1))
X	{
X		newColor = exact.pixel;
X		windowColorsAllocated = True;
X	} else {
X		/*
X		 * No valid value was found in the resource, so we use 
X		 * 20% gray as the default.
X		 */
X		exact.pixel = WhitePixel( dpy, DefaultScreen(dpy) );
X		XQueryColor( dpy, CMAP, &exact );
X		exact.red = (exact.red*8)/10;
X		exact.green = (exact.green*8)/10;
X		exact.blue = (exact.blue*8)/10;
X		if (XAllocColor(dpy, CMAP, &exact) == 1) {
X			newColor = exact.pixel;
X			windowColorsAllocated = True;
X		} else {
X			/* REMIND should OlwmDB value change? */
X			GRV.F3dUsed = False;
X			newColor = WhitePixel(dpy, DefaultScreen(dpy));
X			windowColorsAllocated = False;
X		}
X	}
X
X	RM_COLORVAR = newColor;
X
X	/* these colors aren't currently settable directly using resources */
X#ifndef COLOR2D
X	if ( GRV.F3dUsed )
X	{
X#endif /* COLOR2D */
X	    fgc.pixel = GRV.Fg1Color;
X	    XQueryColor(dpy,CMAP,&fgc);
X	    olgx_calculate_3Dcolors(&fgc,&exact,&bg2c,&bg3c,&whitec);
X	    XAllocColor(dpy,CMAP,&bg2c);
X	    GRV.Bg2Color = bg2c.pixel;
X	    XAllocColor(dpy,CMAP,&bg3c);
X	    GRV.Bg3Color = bg3c.pixel;
X	    XAllocColor(dpy,CMAP,&whitec);
X	    GRV.Bg0Color = whitec.pixel;
X#ifndef COLOR2D
X	}
X	else
X	{
X		/* in 2d these are not used by olgx, but olwm may */
X		GRV.Bg0Color = WhitePixel( dpy, DefaultScreen(dpy) );
X		GRV.Bg1Color = WhitePixel( dpy, DefaultScreen(dpy) );
X		GRV.Bg2Color = BlackPixel( dpy, DefaultScreen(dpy) );
X		GRV.Bg3Color = BlackPixel( dpy, DefaultScreen(dpy) );
X	}
X#endif /* COLOR2D */
X
X	return True;
X}
X
X/*
X * setColor - retrieve color name resource from OlwmDB 
X *	and convert to pixel value
X *
X *	REMIND - the default (BlackPixel) is built-in to this function.
X */
Bool
setColor( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	XColor		exact;
X	unsigned long	newColor;
X	Bool		updateNeeded = False;
X#ifndef RM_COLORVAR
X#define RM_COLORVAR     *((unsigned long *)(RMTable[rmIndex].varAddr))
X#endif
X
X	if ( (newValue == NULL)
X	      || (!XParseColor( dpy, CMAP, newValue, &exact ))
X	      || (!XAllocColor( dpy, CMAP, &exact )) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else 
X			newColor = BlackPixel(dpy, DefaultScreen(dpy));
X	}
X	else 
X	{
X		newColor = exact.pixel;
X		if ( varSet )
X		{
X			if ( newColor == RM_COLORVAR )
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X	RM_COLORVAR = newColor;
X	return( updateNeeded );
X}
X
X
X/*
X * setInputFocusStyle - retrieve value of inputFocusStyle resource and
X *	return True is it's "followmouse" and False if it's "select" or
X *	"clicktotype"
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setInputFocusStyle( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool	focusFollows;
X	Bool	updateNeeded = False;
X#ifndef RM_BOOLVAR
X#define RM_BOOLVAR     *((Bool *)(RMTable[rmIndex].varAddr))
X#endif
X
X	if ( (newValue == NULL) || !matchFocusType( newValue, &focusFollows ) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X			matchFocusType( RMTable[rmIndex].defaultVal, 
X					&focusFollows );
X	}
X	else if ( varSet )
X	{
X		if ( focusFollows == RM_BOOLVAR )
X			return( updateNeeded );
X		else
X			updateNeeded = True;
X	}
X
X	RM_BOOLVAR = focusFollows;
X	return( updateNeeded );
X}
X
X/*
X * setBeepResource - retrieve value of Beep resource
X */
static Bool
setBeepResource( dpy, rmIndex, newValue, varSet )
Display *dpy;
int rmIndex;
char *newValue;
Bool varSet;
X{
X	BeepStatus newBeep;
X	Bool updateNeeded = False;
X
X#ifndef RM_BEEPVAR
X#define RM_BEEPVAR *((BeepStatus *)(RMTable[rmIndex].varAddr))
X#endif
X
X	if ((newValue == NULL) || !matchBeepKeyword(newValue, &newBeep))
X	{
X	    if (varSet)
X		return(updateNeeded);
X	    else
X		matchBeepKeyword(RMTable[rmIndex].defaultVal,&newBeep);
X	}
X	else if (varSet)
X	{
X	    if (newBeep == RM_BEEPVAR)
X		return(updateNeeded);
X	    else
X		updateNeeded = True;
X	}
X
X	RM_BEEPVAR = newBeep;
X	return(updateNeeded);
X}
X
X
X/*
X * setIconLocation - return value of iconLocation resource
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setIconLocation( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool		updateNeeded = False;
X	IconPreference	newIconPlace;
X#define RM_ICONVAR     *((IconPreference *)(RMTable[rmIndex].varAddr))
X
X	if ( (newValue == NULL) || !matchIconPlace( newValue, &newIconPlace ) )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X			matchIconPlace( RMTable[rmIndex].defaultVal, 
X					&newIconPlace );
X	}
X	else if ( varSet )	/* a valid newValue and an old value */
X	{
X		if ( newIconPlace == RM_ICONVAR )
X			return( updateNeeded );
X		else
X			updateNeeded = True;
X	}
X
X	RM_ICONVAR = newIconPlace;
X	return( updateNeeded );
X}
X
X
static Bool
parseKeySpec(dpy, str, modmask, keycode)
X    Display *dpy;
X    char *str;
X    int *modmask;
X    KeyCode *keycode;
X{
X    char line[100];
X    char *word;
X    extern unsigned int FindModiferMask();
X    int kc, m;
X    int mask = 0;
X    int code = 0;
X    KeySym ks;
X
X    strcpy(line, str);
X    word = strtok(line, " \t");
X    if (word == NULL)
X	return False;
X
X    while (word != NULL) {
X	ks = XStringToKeysym(word);
X	if (ks == NoSymbol) {
X	    if (strcmp(word, "Any") == 0) {
X		mask = AnyModifier;
X		word = strtok(NULL, " \t");
X		continue;
X	    } else if (strcmp(word, "Shift") == 0)
X		ks = XK_Shift_L;
X	    else if (strcmp(word, "Control") == 0)
X		ks = XK_Control_L;
X	    else if (strcmp(word, "Meta") == 0)
X		ks = XK_Meta_L;
X	    else if (strcmp(word, "Alt") == 0)
X		ks = XK_Alt_L;
X	    else if (strcmp(word, "Super") == 0)
X		ks = XK_Super_L;
X	    else if (strcmp(word, "Hyper") == 0)
X		ks = XK_Hyper_L;
X	    else
X		return False;
X	}
X	    
X	kc = XKeysymToKeycode(dpy, ks);
X	if (kc == 0)
X	    return False;
X
X	m = FindModifierMask(kc);
X	if (m == 0) {
X	    code = kc;
X	    break;
X	}
X	mask |= m;
X	word = strtok(NULL, " \t");
X    }
X
X    if (code == 0)
X	return False;
X
X    *keycode = code;
X    *modmask = mask;
X    return True;
X}
X
X
X/*
X * setKey - retrieve value for named KeySym and convert it to a KeyCode
X *	Then grab the key so we'll deal with it as a special command.
X */
static Bool
setKey( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	unsigned int	modMask;
X	KeyCode		newKeyCode = 0;
X	Bool		updateNeeded = False;
X#define RM_KEYVAR     ((KeySpec *)(RMTable[rmIndex].varAddr))
X
X	if ( newValue == NULL )
X	{
X		if ( varSet )
X			return( updateNeeded );
X		else	/* builtin default */
X		{
X		    (void) parseKeySpec(dpy, RMTable[rmIndex].defaultVal,
X					&modMask, &newKeyCode);
X		}
X	}
X	else 
X	{
X		(void) parseKeySpec(dpy, newValue, &modMask, &newKeyCode);
X		if ( varSet )
X		{
X			if ((newKeyCode == RM_KEYVAR->keycode) &&
X			    (modMask == RM_KEYVAR->modmask))
X				return( updateNeeded );
X			else
X				updateNeeded = True;
X		}
X	}
X
X	/* REMIND perhaps we should have separate functions to deal with
X	 * keys that want grab and don't want grab
X	 * Also, perhaps this activity should be in the updFunc
X	 */
X	if (rmIndex != RM_CONFIRMKEY && rmIndex != RM_CANCELKEY &&
X	    newKeyCode != 0) {
X		XGrabKey( dpy, newKeyCode, modMask, 
X			  DefaultRootWindow(dpy), False, 
X			  GrabModeAsync, GrabModeAsync );
X#ifdef notdef
X		xkbc.auto_repeat_mode = AutoRepeatModeOff;
X		xkbc.key = newKeyCode;
X		XChangeKeyboardControl(dpy, KBKey|KBAutoRepeatMode, &xkbc);
X#endif /* notdef */
X	}
X
X	RM_KEYVAR->keycode = newKeyCode;
X	RM_KEYVAR->modmask = modMask;
X	return( updateNeeded );
X}
X
X
X/*
X * setDimension
X * 
X * Look at the default screen and determine whether to use 3D.
X */
static Bool
setDimension( dpy, rmIndex, newValue, varSet )
X    Display	*dpy;
X    int		rmIndex;
X    char	*newValue;
X    Bool	varSet;
X{
X	Bool	newDimension;
X	Bool	updateNeeded = False;
X	int	depth = DisplayPlanes(dpy,DefaultScreen(dpy));
X	int	visclass = (DefaultVisual(dpy,DefaultScreen(dpy)))->class;
X
X	if ((newValue == NULL) || !matchBool(newValue, &newDimension)) {
X	    if (varSet)
X		return(updateNeeded);
X	    else
X		matchBool(RMTable[rmIndex].defaultVal, &newDimension);
X	} else if (varSet) {
X	    if (newDimension == RM_BOOLVAR)
X		return(updateNeeded);
X	    else
X		updateNeeded = True;
X	}
X
X	switch (visclass) {
X	case StaticGray:
X	case GrayScale:
X	    if (depth < 2)
X		newDimension = False;
X	    break;
X	case DirectColor:
X	case PseudoColor:
X	    if (depth < 4)
X		newDimension = False;
X	    break;
X	case StaticColor:
X	    if (depth < 8)
X		newDimension = False;
X	    break;
X	case TrueColor:
X	    if (depth < 6)
X		newDimension = False;
X	    break;
X	}
X
X	RM_BOOLVAR = newDimension;
X	return(updateNeeded);
X}
X
X
X/*
X * SetNameTag - retrieve value of name resource.  If not set, use
X *	AppName.   Not likely to be valuable as a dynamically
X *	modified resource.
X *
X *	REMIND: currently not called in any resource parsing loop
X */
X/*ARGSUSED*/	/* dpy, newValue, varSet are std args for Set fns */
Bool
SetNameTag( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	Bool			updateNeeded = False;
X	char			name[MAX_NAME];
X	char			class[MAX_CLASS];
X	XrmRepresentation	repType;
X	XrmValue		value;
X#define RM_NAMEVAR     *((char **)(RMTable[rmIndex].varAddr))
X
X	(void) strcpy( name, AppName );
X	(void) strcat( name, RMTable[rmIndex].instance );
X	MakeRMClass( class, rmIndex );
X
X	/* REMIND NameTag will need to be MemFree'd, if 
X	 * updating the NameTag is allowed and != AppName
X	 */
X	if ( XrmGetResource( OlwmDB, name, class, &repType, &value )
X		== True && (value.addr != NULL) )
X	{
X		RM_NAMEVAR = MemNewString( value.addr );
X		updateNeeded = True;
X	}
X	else
X		RM_NAMEVAR = AppName;
X	
X	return( updateNeeded );
X}
X
X/* buildMinimalList -- build the list of classes/instances to be 
X * but minimally decorated; return True if the list was successfully parsed.
X *
X * Works for sticky windows too
X */
static Bool 
buildMinimalList(str, pplist)
char *str;
List **pplist;
X{
X    char *swork, *swork2;
X    List *l = NULL_LIST;
X
X    if (str == NULL)
X	return False;
X
X    swork2 = swork = MemNewString(str);
X
X    while ((swork2 = strtok(swork2, " \t")) != NULL)
X    {
X	l = ListCons(MemNewString(swork2),l);
X	swork2 = NULL;
X    }
X    MemFree(swork);
X    *pplist = l;
X    return True;
X}
X
static void *
freeMinimalStrings(str,junk)
char *str;
void *junk;
X{
X	MemFree(str);
X	return NULL;
X}
X
X/*
X * setMinimalDecor - set list of windows to be minimally decorated
X *
X * works for sticky windows too
X *
X */
X/*ARGSUSED*/	/* dpy is std arg for Set fns */
static Bool
setMinimalDecor( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X	List	*newl = NULL_LIST;
X#define RM_LISTVAR     *((List **)(RMTable[rmIndex].varAddr))
X
X	if (newValue == NULL)
X	{
X	    if (!buildMinimalList( RMTable[rmIndex].defaultVal, &newl ))
X	        return False;
X	}
X	else if (!buildMinimalList( newValue, &newl ) )
X	    return False;
X
X	if (RM_LISTVAR != NULL)
X	{
X	    ListApply(RM_LISTVAR,freeMinimalStrings,NULL);
X	    ListDestroy(RM_LISTVAR);
X	}
X	RM_LISTVAR = newl;
X
X	return( True );
X}
END_OF_FILE
if test 40786 -ne `wc -c <'resources.c'`; then
    echo shar: \"'resources.c'\" unpacked with wrong size!
fi
# end of 'resources.c'
fi
echo shar: End of archive 15 \(of 16\).
cp /dev/null ark15isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources.x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list