cdesktopenv/cde/programs/dtksh/dtkcmds.c

9489 lines
230 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $TOG: dtkcmds.c /main/13 1997/07/14 18:16:01 samborn $ */
/* Copyright (c) 1991, 1992 UNIX System Laboratories, Inc. */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* UNIX System Laboratories, Inc. */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* X includes */
#include "name.h"
#include "shell.h"
#include <signal.h>
#include <fcntl.h>
#include <X11/X.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/CoreP.h>
#include <X11/StringDefs.h>
#include <Xm/XmStrDefs.h>
#include <setjmp.h>
#include <string.h>
#include <ctype.h>
#include <Xm/Xm.h>
#include <Xm/Protocols.h>
#include <Dt/Service.h>
#include <Dt/Wsm.h>
#include <Dt/HourGlass.h>
#include <Dt/Help.h>
#include <Dt/Action.h>
#include <Dt/Dts.h>
#include <Dt/Print.h>
#include <Tt/tttk.h>
#include <Tt/tt_c.h>
#include "hash.h"
#include "stdio.h"
#define NO_AST
#include "dtksh.h"
#undef NO_AST
#include "xmksh.h"
#include "dtkcmds.h"
#include "xmcvt.h"
#include "widget.h"
#include "extra.h"
#include "xmwidgets.h"
#include "msgs.h"
#include <locale.h>
extern Namval_t *sh_assignok(register Namval_t *np,int add);
static void PendingDestroy(
Widget w,
wtab_t *wtab,
caddr_t callData) ;
static Boolean WtabDestroy(
caddr_t callData) ;
static int _CreateWidget(
Widget (*func)(),
int argc,
char *argv[]) ;
static int _DTKSH_XtDestroyWidget(
Widget w) ;
static int do_single_widget_arg_func(
int (*func)(),
int argc,
char **argv) ;
static void mainloopsighandler(
int sig) ;
static int XtCallCallbacks_usage(
char *arg0) ;
static void RegisterCmdStr(
char type,
long id,
char *cmd) ;
static void RemoveCmdStr(
char type,
long id) ;
static int do_RootWindowCmd(
int (*func)(),
int argc,
char *argv[]) ;
static int cvtfontstruct(
char *name,
XFontStruct **fn) ;
static int CatchNonFatalFontError(
Display *display,
XErrorEvent *event) ;
static int cvtfont(
Display *display,
char *name,
Font *fn) ;
static int cvtcolor(
char *name,
Pixel *pix) ;
static int invokeXDrawFunction(
int function,
int argc,
char *argv[]) ;
static int XtAddInputUsage(
char *arg0) ;
static void DestroyInputRecord(
XtInputId id) ;
static int FindInputRecord(
XtInputId id) ;
static Boolean ProcessInput(
inputrec_t * inp,
int source,
XtInputId id,
Boolean eofFound) ;
static int VerifyString_usage(
char *arg0) ;
static int XtSetSensitive_usage(
char *arg0) ;
static int GetDisplayHandle(
int argc,
char **argv,
Widget (*func)());
static int RegisterTranslations(
void (*func)(),
int argc,
char *argv[]) ;
static int LocateEHRecord(
wtab_t *w,
char *ksh_cmd) ;
static int GetWorkspaceList(
char *usageMsg,
Boolean getOccupied,
int argc,
char *argv[]) ;
static int DtTurnOnOrOffHourGlass(
void (*func)(),
int argc,
char *argv[]) ;
static int WsmCommonProc(
int argc,
char *argv[],
void (*func)());
static int ttdt_SaveOrRevert(
Tt_status (*func)(),
int argc,
char *argv[] ) ;
static int message_DestroyOrReply(
Tt_status (*func)(),
int argc,
char *argv[] );
static int message_FailOrReject(
Tt_status (*func)(),
int argc,
char *argv[] );
static Tt_message TtFileCB(
Tt_message msg,
Tttk_op op,
char * pathName,
void * clientData,
int sameEuidEgid,
int sameProcId ) ;
static int tt_netfile_handler(
int paramCount,
char * (*func)(),
char * usageMsg,
int argc,
char *argv[] ) ;
static Namval_t * CreateEmptyNameValuePair(
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessIntValue(
int value,
Namval_t *np,
char *name,
Namfun_t *fp,
char *format,
Namfun_t *fp_new) ;
static Namval_t * ProcessStringValue(
char *value,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessBooleanIntValue(
int value,
Namval_t *np,
char *name,
Namfun_t *fp,
Namfun_t *fp_new) ;
static Namval_t * ProcessTraversalDirection(
XmTraversalDirection dir,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessSelectionType(
char selType,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessIntTable(
int *table,
int count,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessXmStringTable(
XmString *table,
int count,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessWidgetHandle(
Widget handle,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessXmStringValue(
XmString xmstring,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessHyperType(
int hyperType,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static void InitEventTables( void ) ;
static Namval_t * ProcessCallbackEvent(
XEvent *event,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * _IntProcessCallbackReason(
struct named_integer *table,
XmAnyCallbackStruct *cbData,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessCallbackReason(
XmAnyCallbackStruct *cbData,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static Namval_t * ProcessHelpCallbackReason(
XmAnyCallbackStruct *cbData,
Namval_t *np,
char *name,
Namfun_t *fp) ;
static void _DtActionInvokeUsage( void ) ;
static void DtkReloadHandler(
XtPointer clientData ) ;
static Namfun_t * CloneDiscipline(
Namdisc_t * discipline );
static void FreeDiscipline(
Namfun_t * discipline );
static Namdisc_t * CheckClassDisciplines(
WidgetClass class,
char *cbname) ;
void SetTextDoit(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextStartPos(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextEndPos(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextPtr(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextLen(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextFormat(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextWCSptr(
Namval_t *np,
char *name,
Namfun_t *fp);
void SetTextWCSlen(
Namval_t *np,
char *name,
Namfun_t *fp);
#define CLEAR_AREA 0
#define CLEAR_WINDOW 1
#define DRAW_ARC 2
#define DRAW_IMAGE_STRING 3
#define DRAW_LINE 4
#define DRAW_LINES 5
#define DRAW_POINT 6
#define DRAW_POINTS 7
#define DRAW_RECTANGLE 8
#define DRAW_SEGMENTS 9
#define DRAW_STRING 10
#define FILL_ARC 11
#define FILL_POLYGON 12
#define FILL_RECTANGLE 13
#define COPY_AREA 14
#define WORKPROC_CMDS 0
#define TIMEOUT_CMDS 1
#define MAXARGS 4096
#define SLISTITEMSIZE 16
Widget Toplevel;
Boolean invalidFont;
/* List of all name/value pairs created during handling of a callback */
Namval_t *** npTable = NULL;
int npTableSize = 0;
int * npListSizes = NULL;
int nestingLevel = -1;
static Namdisc_t transDiscipline ={0, NULL, NULL, NULL, NULL,
(Namval_t *(*)())transCreateDisc, NULL, NULL};
static Namdisc_t ehDiscipline = {0, NULL, NULL, NULL, NULL,
(Namval_t *(*)())ehCreateDisc, NULL, NULL};
static Namdisc_t dftDiscipline = {0, NULL, NULL, NULL, NULL,
(Namval_t *(*)())dftCreateDisc, NULL, NULL};
static Namdisc_t nopDiscipline = {0, NULL, NULL, NULL, NULL,
(Namval_t *(*)())nopCreateDisc, NULL, NULL};
static Namdisc_t text_doit_disc = {0, (void (*)())SetTextDoit, NULL, NULL, NULL,
NULL, NULL, NULL};
static Namdisc_t text_startpos_disc = {0, (void (*)())SetTextStartPos, NULL,
NULL, NULL,NULL, NULL, NULL};
static Namdisc_t text_endpos_disc = {0, (void (*)())SetTextEndPos, NULL, NULL,
NULL, NULL, NULL, NULL};
static Namdisc_t text_ptr_disc = {0, (void (*)())SetTextPtr, NULL, NULL, NULL,
NULL, NULL, NULL};
static Namdisc_t text_len_disc = {0, (void (*)())SetTextLen, NULL, NULL, NULL,
NULL, NULL, NULL};
static Namdisc_t text_format_disc = {0, (void (*)())SetTextFormat, NULL, NULL,
NULL, NULL, NULL, NULL};
static Namdisc_t text_wcsptr_disc = {0, (void (*)())SetTextWCSptr, NULL, NULL,
NULL, NULL, NULL, NULL};
static Namdisc_t text_wcslen_disc = {0, (void (*)())SetTextWCSlen, NULL, NULL,
NULL, NULL, NULL, NULL};
static const XtActionsRec Ksh_actions[] = {
{ "ksh_eval", Translation_ksh_eval }
};
static dtksh_client_data_t ** cbDataTable = NULL;
static int cbDataTableSize = 0;
static dtksh_event_handler_data_t ** ehDataTable = NULL;
static int ehDataTableSize = 0;
static char * str_XtRString = XtRString;
char str_s_eq_s[] = "%s=%s";
char str_s_eq[] = "%s=";
char str_nill[] = "";
typedef struct
{
int state;
Window icon;
} WmStateData;
typedef struct
{
long id;
char * cmd;
} CommandString;
CommandString * workProcCmds = NULL;
int workProcCmdsSize = 0;
CommandString * timeOutCmds = NULL;
int timeOutCmdsSize = 0;
typedef struct {
char * ksh_cmd;
Tt_pattern * patterns;
} Ttdt_file_cb_data;
Ttdt_file_cb_data ** fileCBList = 0;
int sizeFileCBList = 0;
typedef struct {
char * fieldName;
char * representation;
Cardinal valueOffset;
Cardinal valueSize;
} EventEntryTable;
typedef struct {
char * eventType;
EventEntryTable * table;
} XEventTable;
/* Keeps track of file input generated by XtAddInput() */
typedef struct {
Boolean inUse;
XtInputId id;
inputrec_t * inp;
} InputRecord;
InputRecord * activeInputs = NULL;
int numActiveInputs = 0;
/*
* When we are notified that a widget is being destroyed (through the
* widget's destroy callback, it is not yet safe for us to remove all
* internal knowledge of that widget, because the shell script may have
* also added a destroy callback, which gets call AFTER ours. Therefore,
* all we can do is mark the widget as 'pending destroy', and add a
* workproc; the workproc will then take care of removing the widget.
*/
static Boolean workProcAdded = False;
static void
PendingDestroy(
Widget w,
wtab_t *wtab,
caddr_t callData )
{
wtab->mask |= DT_PENDING_DESTROY;
if (!workProcAdded)
{
workProcAdded = True;
XtAddWorkProc((XtWorkProc)WtabDestroy, NULL);
}
}
static Boolean
WtabDestroy(
caddr_t callData )
{
int i;
for (i = 0; i < NumW; i++)
{
if ((W[i]->type == TAB_WIDGET) && (W[i]->mask & DT_PENDING_DESTROY))
{
XtFree(W[i]->wname);
XtFree(W[i]->widid);
if (W[i]->envar) {
char *val = env_get(W[i]->envar);
/*
* Blank out the environment variable holding the
* widget handle, but only if it still holds the
* handle! This guards against the possibility that
* the user has re-used the same variable for another
* widget later.
*/
if (val && W[i]->widid && strcmp(val, W[i]->widid) == 0) {
env_blank(W[i]->envar);
}
XtFree(W[i]->envar);
}
W[i]->type = TAB_EMPTY;
Wtab_free++;
}
}
workProcAdded = False;
return(True);
}
wtab_t *
set_up_w(
Widget wid,
wtab_t *parent,
char *var,
char *name,
classtab_t *class )
{
char widid[8];
static wtab_t *w;
get_new_wtab(&w, widid);
if (var) {
env_set_var(var, widid);
w->envar = strdup(var);
} else {
w->envar = strdup("none");
}
w->type = TAB_WIDGET;
w->wname = name ? strdup(name) : strdup(XtName(wid));
w->wclass = class;
w->parent = parent;
w->widid = strdup(widid);
w->w = wid;
w->mask = 0;
XtAddCallback(wid, XtNdestroyCallback, (XtCallbackProc)PendingDestroy,
(caddr_t)w);
return(w);
}
static short Needfree[MAXARGS];
void
parse_args(
char *arg0,
int argc,
char **argv,
wtab_t *w,
wtab_t *parent,
classtab_t *class,
int *n,
Arg *args,
int * pargc,
char ** pargv ,
Boolean postponePixmaps )
{
register int i;
register char *colon, *resource, *val, *p;
XtArgVal argval;
int freeflag, len;
char * errmsg;
int conversionResult;
if (pargc)
(*pargc) = 0;
*n = 0;
for (i = 0; i < argc; i++) {
if (i >= MAXARGS) {
errmsg = strdup(GETMESSAGE(5,1,
"Too many resource parameters have been specified; skipping '%s'"));
printerrf(arg0, errmsg,
argv[*n], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
continue;
}
if ((colon = strchr(argv[i], ':')) == NULL)
{
errmsg = strdup(GETMESSAGE(5,2,
"Bad resource specification; should be of the form 'name:value' : %s"));
printerrf(arg0, errmsg,
argv[i], NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
continue;
}
val = &colon[1];
len = colon - argv[i];
resource = XtMalloc(len + 1);
strncpy(resource, argv[i], len);
resource[len] = '\0';
/*
* The following special check fixes a bug in Xt, where the
* string defined for the XmNwaitForWm resource does not
* follow the naming conventions, and is set to "waitforwm".
* In dtksh, users expect the naming conventions to be
* followed, and this breaks for this one resource.
*/
if (strcmp(resource, "waitForWm") == 0)
strcpy(resource, XmNwaitForWm);
if ((conversionResult = ConvertStringToType(arg0, w, parent,
class, resource, val, &argval, &freeflag,
postponePixmaps)) == CONVERT_SUCCEEDED)
{
XtSetArg(args[*n], resource, argval);
/*
* The following is a memory leak, but it allows us to
* comply with what Xt has spec'ed as the required
* behavior of the geometry string (It is a bogus
* requirement!). The Xt Shell widget does not make
* a copy of the incoming 'geometry' string, but
* instead, simply keeps a pointer to the string
* passed-in by the application. For dtksh, this is
* a problem, because we would typically free up the
* string right away. This hack causes us to not free
* up the string.
*/
if (strcmp(resource, XmNgeometry) == 0)
Needfree[*n] = False;
else
Needfree[*n] = freeflag;
(*n)++;
}
else if (conversionResult == CONVERT_POSTPONED)
{
/*
* Postpone processing this resource until after the
* the widget has been created, or, in the case of a
* pixmap resource, until any new colors have been set.
*/
if (pargc)
{
pargv[*pargc] = argv[i];
(*pargc)++;
}
XtFree(resource);
}
else
{
XtFree(resource);
}
}
}
void
free_args(
int n,
Arg *args )
{
register int i;
/*
* Free up argument pointers
*/
for (i = 0; i < n; i++) {
XtFree(args[i].name);
if (Needfree[i]) {
XtFree((String)args[i].value);
}
}
}
int
do_XtInitialize(
int argc,
char *argv[] )
{
int ret;
char *dtkdb_hook;
char * errmsg;
int * lockedFds;
if (Toplevel != NULL)
{
errmsg = strdup(GETMESSAGE(5,4,
"The toolkit has already been initialized"));
printerr(argv[0], errmsg, NULL);
free(errmsg);
return(1);
}
if (argc < 4) {
errmsg =strdup(GETMESSAGE(5,5,
"Usage: XtInitialize variable applicationName applicationClass [args ...]"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
lockedFds = LockKshFileDescriptors();
ret = toolkit_initialize(argc, argv);
UnlockKshFileDescriptors(lockedFds);
XtAddActions((XtActionList)Ksh_actions, XtNumber(Ksh_actions));
if ((dtkdb_hook = env_get("DTKDB_HOOK")) != NULL) {
ksh_eval(dtkdb_hook);
}
return(ret);
}
static int
_CreateWidget(
Widget (*func)(),
int argc,
char *argv[] )
{
Widget widget;
classtab_t *class;
char *arg0 = argv[0];
wtab_t *w, *pw, *wtab;
char *wname, *wclass, *parentid, *var;
Arg args[MAXARGS];
register int i;
int n;
char * errmsg;
int pargc;
char ** pargv;
if (argc < 5) {
errmsg = strdup(GETMESSAGE(5,6,
"Usage: %s variable name class parent [arg:val ...]"));
printerrf(str_nill, errmsg,
argv[0], NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
var = argv[1];
wname = argv[2];
wclass = argv[3];
parentid = argv[4];
pw = str_to_wtab(argv[0], parentid);
if (pw == NULL) {
errmsg = strdup(GetSharedMsg(DT_NO_PARENT));
printerr(argv[0], errmsg, NULL);
free(errmsg);
return(1);
}
argv += 5;
argc -= 5;
if ((class = str_to_class(arg0, wclass)) == NULL) {
return(1);
}
pargc = 0;
if (argc > 0) {
pargv = (char **)XtMalloc(sizeof(char *) * argc);
}
else {
pargv = NULL;
}
n = 0;
parse_args(arg0, argc, argv, NULL, pw, class, &n, args, &pargc, pargv,
True);
widget = func(wname, class->class, pw->w, args, n);
if (widget != NULL) {
wtab = set_up_w(widget, pw, var, wname, class);
/* Process any postponed resources */
if (pargc > 0)
{
free_args(n, args);
n = 0;
parse_args(arg0, pargc, pargv, wtab, pw, class, &n,
args, NULL, NULL, False);
XtSetValues(widget, args, n);
}
} else {
errmsg = strdup(GetSharedMsg(DT_WIDGET_CREATE_FAILED));
printerrf(argv[0], errmsg, wname,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
env_blank(argv[1]);
}
free_args(n, args);
XtFree((char *)pargv);
return(0);
}
int
do_XtCreateApplicationShell(
int argc,
char *argv[] )
{
Widget widget;
classtab_t *class;
char *arg0 = argv[0];
wtab_t *w, *wtab;
char *wname, *wclass, *var;
Arg args[MAXARGS];
register int i;
int n;
char * errmsg;
int pargc;
char ** pargv;
if (argc < 4) {
errmsg=strdup(GETMESSAGE(5,7,
"Usage: XtCreateApplicationShell variable name class [arg:val ...]"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
var = argv[1];
wname = argv[2];
wclass = argv[3];
argv += 4;
argc -= 4;
if ((class = str_to_class(arg0, wclass)) == NULL) {
return(1);
}
pargc = 0;
if (argc > 0) {
pargv = (char **)XtMalloc(sizeof(char *) * argc);
}
else {
pargv = NULL;
}
n = 0;
parse_args(arg0, argc, argv, NULL, NULL, class, &n, args, &pargc,
pargv, True);
widget = XtCreateApplicationShell(wname, class->class, args, n);
if (widget != NULL) {
wtab = set_up_w(widget, NULL, var, wname, class);
/* Process any postponed resources */
if (pargc > 0)
{
free_args(n, args);
n = 0;
parse_args(arg0, pargc, pargv, wtab, NULL, class,
&n, args, NULL, NULL, False);
XtSetValues(widget, args, n);
}
} else {
errmsg = strdup(GetSharedMsg(DT_WIDGET_CREATE_FAILED));
printerrf(argv[0], errmsg, wname,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
env_blank(argv[1]);
}
free_args(n, args);
XtFree((char *)pargv);
return(0);
}
int
do_XtCreatePopupShell(
int argc,
char *argv[] )
{
return(_CreateWidget(XtCreatePopupShell, argc, argv));
}
int
do_XtCreateManagedWidget(
int argc,
char *argv[] )
{
return(_CreateWidget(XtCreateManagedWidget, argc, argv));
}
int
do_XtCreateWidget(
int argc,
char *argv[] )
{
return(_CreateWidget(XtCreateWidget, argc, argv));
}
int
do_XtPopup(
int argc,
char *argv[] )
{
wtab_t *w;
XtGrabKind grab;
char * errmsg;
if (argc != 3)
{
errmsg=strdup(GETMESSAGE(5,8,
"Usage: XtPopup widget GrabNone|GrabNonexclusive|GrabExclusive"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
else
{
grab = XtGrabNone;
if (argc < 3 || strcmp(argv[2], "GrabNone") == 0)
grab = XtGrabNone;
else if (strcmp(argv[2], "GrabNonexclusive") == 0)
grab = XtGrabNonexclusive;
else if (strcmp(argv[2], "GrabExclusive") == 0)
grab = XtGrabExclusive;
else
{
errmsg=strdup(GETMESSAGE(5,9,
"The grab type '%s' is not recognized; using 'GrabNone'"));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
}
XtPopup(w->w, grab);
}
return(0);
}
static int
_DTKSH_XtDestroyWidget(
Widget w )
{
XtDestroyWidget(w);
return(1);
}
static int
do_single_widget_arg_func(
int (*func)(),
int argc,
char **argv )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc < 2) {
errmsg = strdup(GetSharedMsg(DT_USAGE_WIDGET));
printerrf(str_nill, errmsg, argv[0], NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
for (i = 1; i < argc; i++) {
w = str_to_wtab(argv[0], argv[i]);
if (w != NULL) {
func(w->w);
}
}
return(0);
}
int
do_XtDestroyWidget(
int argc,
char *argv[] )
{
return(do_single_widget_arg_func(_DTKSH_XtDestroyWidget, argc, argv));
}
int
do_single_widget_test_func(
int (*func)(),
int argc,
char **argv )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc != 2) {
errmsg=strdup(GetSharedMsg(DT_USAGE_WIDGET));
printerrf(str_nill, errmsg, argv[0], NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w != NULL) {
return(!func(w->w));
}
return(255);
}
int
do_XtIsSensitive(
int argc,
char *argv[] )
{
return(do_single_widget_test_func((int(*)())XtIsSensitive, argc, argv));
}
/*
* XtIsShell() is a macro, so we can't use do_single_widget_test_func().
*/
int
do_XtIsShell(
int argc,
char *argv[] )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,10, "Usage: XtIsShell widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w != NULL)
return(!XtIsShell(w->w));
return(255);
}
int
do_XtIsManaged(
int argc,
char *argv[] )
{
return(do_single_widget_test_func((int(*)())XtIsManaged, argc, argv));
}
int
do_XtIsRealized(
int argc,
char *argv[] )
{
return(do_single_widget_test_func((int(*)())XtIsRealized, argc, argv));
}
int
do_XtRealizeWidget(
int argc,
char *argv[] )
{
return(do_single_widget_arg_func((int(*)())XtRealizeWidget, argc, argv));
}
int
do_XtUnrealizeWidget(
int argc,
char *argv[] )
{
return(do_single_widget_arg_func((int(*)())XtUnrealizeWidget, argc, argv));
}
/*
* XtMapWidget() is a macro, so can't use do_single_widget_arg_func()
*/
int
do_XtMapWidget(
int argc,
char *argv[] )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc < 2) {
errmsg = strdup(GETMESSAGE(5,11, "Usage: XtMapWidget widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
for (i = 1; i < argc; i++) {
w = str_to_wtab(argv[0], argv[i]);
if (w != NULL) {
XtMapWidget(w->w);
}
}
return(0);
}
int
do_XtUnmapWidget(
int argc,
char **argv )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc < 2) {
errmsg = strdup(GETMESSAGE(5,12, "Usage: XtUnmapWidget widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
for (i = 1; i < argc; i++) {
w = str_to_wtab(argv[0], argv[i]);
if (w != NULL) {
XtUnmapWidget(w->w);
}
}
return(0);
}
int
do_XtPopdown(
int argc,
char **argv )
{
return(do_single_widget_arg_func((int(*)())XtPopdown, argc, argv));
}
int
do_XtMainLoop(
int argc,
char **argv )
{
/*
* Required to guarantee that all of the shell script's "echo"
* requests have been taken care of, before we drop into the
* the black hole called XtMainLoop.
*/
fflush(stdout);
XtMainLoop();
return(1);
}
int
do_XtDisplay(
int argc,
char **argv )
{
return(GetDisplayHandle(argc, argv, (Widget (*)())XtDisplay));
}
int
do_XtDisplayOfObject(
int argc,
char **argv )
{
return(GetDisplayHandle(argc, argv, (Widget (*)())XtDisplayOfObject));
}
static int
GetDisplayHandle(
int argc,
char **argv,
Widget (*func)())
{
wtab_t *w;
char *arg0 = argv[0];
char * variable = argv[1];
char buf[128];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,13, "Usage: %s variable widget"));
printerrf(str_nill, errmsg, arg0, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(arg0, argv[2]);
if (w == NULL)
return(1);
sprintf(buf, "0x%lx", (long)(*func)(w->w));
alt_env_set_var(variable, buf);
return(0);
}
int
do_XtNameToWidget(
int argc,
char *argv[] )
{
char *arg0 = argv[0];
wtab_t * w;
char * variable = argv[1];
Widget child;
classtab_t *ctab;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,82,
"Usage: XtNameToWidget variable referenceWidget names"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(arg0, argv[2]);
if (w == NULL) {
alt_env_set_var(variable, str_nill);
return(1);
}
child = XtNameToWidget(w->w, argv[3]);
if (child == NULL)
{
alt_env_set_var(variable, str_nill);
return(1);
}
w = widget_to_wtab(child);
if (w == NULL) {
alt_env_set_var(variable, str_nill);
return(1);
}
/*
* If the widget class has no resources registered, then this is
* the first known instance of this widget class, so we need to
* force the resource list to be loaded. This can frequently
* occur if a Motif convenience function is used, which creates
* a 'hidden' parent.
*/
ctab = w->wclass;
if (ctab->res == NULL)
(void)str_to_class(arg0, ctab->cname);
alt_env_set_var(variable, w->widid);
return(0);
}
int
do_XtScreen(
int argc,
char **argv )
{
wtab_t *w;
char *arg0 = argv[0];
char * variable = argv[1];
char buf[128];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,14, "Usage: XtScreen variable widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(arg0, argv[2]);
if (w == NULL)
return(1);
sprintf(buf, "0x%lx", (long)XtScreen(w->w));
alt_env_set_var(variable, buf);
return(0);
}
int
do_XtWindow(
int argc,
char **argv )
{
wtab_t *w;
char *arg0 = argv[0];
char * variable = argv[1];
char buf[128];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,15, "Usage: XtWindow variable widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(arg0, argv[2]);
if (w == NULL)
return(1);
sprintf(buf, "0x%lx", (long)XtWindow(w->w));
alt_env_set_var(variable, buf);
return(0);
}
static int
XtCallCallbacks_usage(
char *arg0 )
{
char * errmsg;
errmsg = strdup(GETMESSAGE(5,16,
"Usage: XtCallCallbacks widget callbackName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
int
do_XtCallCallbacks(
int argc,
char **argv )
{
wtab_t *w;
char *arg0 = argv[0];
if (argc != 3)
return(XtCallCallbacks_usage(arg0));
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
else
XtCallCallbacks(w->w, argv[2], NULL);
return(0);
}
int
do_XtHasCallbacks(
int argc,
char **argv )
{
wtab_t *w;
char *arg0 = argv[0];
char * msg;
char * variable = argv[1];
XtCallbackStatus callbackStatus;
XrmValue fval, tval;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,17,
"Usage: XtHasCallbacks variable widget callbackName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[2]);
if (w == NULL)
return(1);
else
callbackStatus = XtHasCallbacks(w->w, argv[3]);
switch (callbackStatus)
{
case XtCallbackNoList:
{
msg = "CallbackNoList";
break;
}
case XtCallbackHasNone:
{
msg = "CallbackHasNone";
break;
}
case XtCallbackHasSome:
{
msg = "CallbackHasSome";
break;
}
}
alt_env_set_var(variable, msg);
return(0);
}
int
do_XtAddCallback(
int argc,
char **argv )
{
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,18,
"Usage: XtAddCallback widget callbackName ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
return(AddOneCallback(argv[0], argv[1], argv[2], argv[3], NULL));
}
/*
* This function is used to add both regular Xt Callbacks, and
* Motif WMProtocol callback.
*/
int
AddOneCallback(
char *cmd,
char *widget,
char *cbName,
char *kshcmd,
char *propAtomStr )
{
wtab_t *w;
dtksh_client_data_t *cdata;
char * p;
Atom propAtom;
char * errmsg;
w = str_to_wtab(cmd, widget);
if (w == NULL)
return(1);
if (propAtomStr)
{
propAtom = (Atom)strtoul(propAtomStr, &p, 0);
if (p == propAtomStr)
{
errmsg = strdup(GetSharedMsg(DT_BAD_ATOM));
printerrf(cmd, errmsg, propAtomStr, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
}
else
propAtom = None;
cdata = GetNewCBData(kshcmd, w, cbName, propAtom);
if (strcmp(cmd, "XtAddCallback") == 0)
XtAddCallback(w->w, cbName, (XtCallbackProc)stdCB, (XtPointer)cdata);
else
{
XmAddWMProtocolCallback(w->w, propAtom, (XtCallbackProc)stdCB,
(XtPointer)cdata);
}
return(0);
}
int
do_XtRemoveCallback(
int argc,
char **argv )
{
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,19,
"Usage: XtRemoveCallback widget callbackName ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
return(RemoveOneCallback (argv[0], argv[1], argv[2], argv[3], NULL, NULL));
}
/*
* This function is used to delete both regular Xt Callbacks, and
* Motif WMProtocol callback.
*/
int
RemoveOneCallback(
char *cmd,
char *widget,
char *cbName,
char *kshcmd,
char *propAtomStr,
char *handleStr )
{
wtab_t *w;
dtksh_client_data_t *cdata;
int i;
Atom propAtom;
char * p;
DtWsmCBContext handle;
char * errmsg;
w = str_to_wtab(cmd, widget);
if (w == NULL)
return(1);
if (propAtomStr)
{
propAtom = (Atom)strtoul(propAtomStr, &p, 0);
if (p == propAtomStr)
{
errmsg = strdup(GetSharedMsg(DT_BAD_ATOM));
printerrf(cmd, errmsg, propAtomStr, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
}
else
propAtom = None;
if (handleStr)
{
handle = (DtWsmCBContext)strtoul(handleStr, &p, 0);
if (p == handleStr)
{
errmsg = strdup(GETMESSAGE(5,20,
"The following is an invalid callback handle: %s"));
printerrf(cmd, errmsg, handleStr, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
}
else
handle = NULL;
/* Locate the matching table entry */
if ((i = LocateCBRecord (w, cbName, kshcmd, propAtom, handle)) >= 0)
{
cdata = cbDataTable[i];
if (strcmp(cmd, "XtRemoveCallback") == 0)
XtRemoveCallback(w->w, cbName, (XtCallbackProc)stdCB,(XtPointer)cdata);
else if (strcmp(cmd, "XmRemoveWMProtocolCallback") == 0)
{
XmRemoveWMProtocolCallback(w->w, propAtom, (XtCallbackProc)stdCB,
(XtPointer)cdata);
}
else
{
DtWsmRemoveWorkspaceCallback(handle);
}
if (--(cdata->refCount) <= 0)
{
XtFree(cdata->ksh_cmd);
XtFree(cdata->cbname);
XtFree((XtPointer)cdata);
cbDataTable[i] = NULL;
return(0);
}
return(0);
}
errmsg = strdup(GETMESSAGE(5,21,
"The specified callback is not registered"));
printerr(cmd, errmsg, NULL);
free(errmsg);
return(1);
}
int
do_XtAddEventHandler(
int argc,
char **argv )
{
wtab_t *w;
char *arg0 = argv[0];
dtksh_event_handler_data_t *ehdata;
Boolean nonMaskable;
EventMask eventMask;
XrmValue fval, tval;
char * errmsg;
if (argc != 5)
{
errmsg=strdup(GETMESSAGE(5,22,
"Usage: XtAddEventHandler widget mask nonMaskable ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(arg0, argv[1]);
if (w == NULL)
return(1);
fval.addr = argv[3];
fval.size = strlen(argv[3]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
nonMaskable = *((Boolean *)(tval.addr));
else
return(1);
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, "EventMask", &tval);
if (tval.size != 0)
eventMask = *((EventMask *)(tval.addr));
else
return(1);
if ((eventMask == 0) && (nonMaskable == False))
return(1);
ehdata = GetNewEHData(argv[4], w, eventMask, nonMaskable);
XtAddEventHandler(w->w, eventMask, nonMaskable, (XtEventHandler)stdEH,
(XtPointer)ehdata);
return(0);
}
int
do_XtRemoveEventHandler(
int argc,
char **argv )
{
wtab_t *w;
char *arg0 = argv[0];
dtksh_event_handler_data_t *ehdata;
int i;
Boolean nonMaskable;
EventMask eventMask;
XrmValue fval, tval;
char * errmsg;
if (argc != 5)
{
errmsg =strdup(GETMESSAGE(5,23,
"Usage: XtRemoveEventHandler widget mask nonMaskable ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(arg0, argv[1]);
if (w == NULL)
return(1);
/* Locate the matching table entry */
if ((i = LocateEHRecord (w, argv[4])) >= 0)
{
ehdata = ehDataTable[i];
fval.addr = argv[3];
fval.size = strlen(argv[3]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
{
nonMaskable = *((Boolean *)(tval.addr));
/* See if non-maskable event processing has been turned off */
if (nonMaskable)
ehdata->nonMaskable = False;
}
else
return(1);
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, "EventMask", &tval);
if (tval.size != 0)
{
eventMask = *((EventMask *)(tval.addr));
/* Disable the specified set of events */
ehdata->eventMask &= ~eventMask;
}
else
return(1);
XtRemoveEventHandler (w->w, eventMask, nonMaskable, (XtEventHandler)stdEH,
(XtPointer)ehdata);
if ((ehdata->eventMask == 0) && (ehdata->nonMaskable == False))
{
/* It is now safe to remove this entry */
XtFree(ehdata->ksh_cmd);
XtFree((XtPointer)ehdata);
ehDataTable[i] = NULL;
return(0);
}
return(0);
}
errmsg = strdup(GETMESSAGE(5,24,
"The specified event handler is not registered"));
printerr(arg0, errmsg, NULL);
free(errmsg);
return(1);
}
int
do_XtGetValues(
int argc,
char **argv )
{
register int i, j;
int n;
char *arg0 = argv[0];
char *val, *p, *str;
Arg args[MAXARGS];
char *envar[MAXARGS];
wtab_t *w;
char * errmsg;
if (argc < 3) {
errmsg = strdup(GETMESSAGE(5,25,
"Usage: XtGetValues widget resource:variable ..."));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
argv += 2;
argc -= 2;
if (w == NULL) {
return(1);
}
/*
* Arguments are of the form:
*
* resource:envar
*/
for (i = 0, n = 0; i < argc; i++) {
if ((p = strchr(argv[i], ':')) == NULL) {
errmsg=strdup(GETMESSAGE(5,26,
"The following resource parameter is incorrectly formed: %s"));
printerrf(arg0, errmsg, argv[i],
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
continue;
}
*p = '\0';
/*
* The following special check fixes a bug in Xt, where the
* string defined for the XmNwaitForWm resource does not
* follow the naming conventions, and is set to "waitforwm".
* In dtksh, users expect the naming conventions to be
* followed, and this breaks for this one resource.
*/
if (strcmp(argv[n], "waitForWm") == 0)
args[n].name = strdup(XmNwaitForWm);
else
args[n].name = strdup(argv[n]);
envar[n] = &p[1];
*p = ':';
args[n].value = (XtArgVal)stakalloc(256);
n++;
}
XtGetValues(w->w, args, n);
for (i = 0; i < n; i++) {
if (ConvertTypeToString(arg0, w->wclass, w, w->parent, args[i].name, args[i].value, &str) != FAIL) {
env_set_var(envar[i], str);
}
else
env_blank(envar[i]);
XtFree(args[i].name);
}
return(0);
}
int
do_XtSetValues(
int argc,
char **argv )
{
int n;
char *arg0 = argv[0];
Arg args[MAXARGS];
wtab_t *w;
char * errmsg;
int pargc;
char ** pargv;
if (argc < 3) {
errmsg = strdup(GETMESSAGE(5,27,
"Usage: XtSetValues widget arg:val ..."));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
argv += 2;
argc -= 2;
if (w == NULL) {
return(1);
} else {
pargc = 0;
pargv = (char **)XtMalloc(sizeof(char *) * argc);
n = 0;
parse_args(arg0, argc, argv, w, w->parent, w->wclass, &n, args,
&pargc, pargv, True);
if (n > 0)
XtSetValues(w->w, args, n);
/* Process any postponed resources */
if (pargc > 0)
{
free_args(n, args);
n = 0;
parse_args(arg0, pargc, pargv, w, w->parent,
w->wclass, &n, args, NULL, NULL, False);
XtSetValues(w->w, args, n);
}
free_args(n, args);
XtFree((char *)pargv);
}
return(0);
}
/*
* When a timeout or work proc is added, the memory allocated for the
* clientData (i.e. the command string) will be lost, unless we provide
* a means of associating the string with the workproc/timeout id, and
* then free up the memory when the workproc/timeout is removed. The
* following two functions implement such a mechanism. This prevents
* a memory leak from occurring.
*/
static void
RegisterCmdStr(
char type,
long id,
char *cmd )
{
CommandString **table;
int * tableSize;
if (type == WORKPROC_CMDS)
{
table = &workProcCmds;
tableSize = &workProcCmdsSize;
}
else
{
table = &timeOutCmds;
tableSize = &timeOutCmdsSize;
}
(*tableSize)++;
*table = (CommandString *)XtRealloc((char *)*table,
sizeof(CommandString) * (*tableSize));
(*table)[(*tableSize)-1].id = id;
(*table)[(*tableSize)-1].cmd = cmd;
}
static void
RemoveCmdStr(
char type,
long id )
{
CommandString **table;
int * tableSize;
int i, j;
if (type == WORKPROC_CMDS)
{
table = &workProcCmds;
tableSize = &workProcCmdsSize;
}
else
{
table = &timeOutCmds;
tableSize = &timeOutCmdsSize;
}
for (i = 0; i < (*tableSize); i++)
{
if (id == (*table)[i].id)
{
XtFree((*table)[i].cmd);
(*tableSize)--;
for (j = i; j < (*tableSize); j++)
(*table)[j] = (*table)[j+1];
*table = (CommandString *)XtRealloc((char *) (*table),
sizeof(CommandString) * (*tableSize));
break;
}
}
}
int
do_XtAddWorkProc(
int argc,
char *argv[] )
{
char *variable;
char *cmd;
char buf[256];
XtWorkProcId id;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,28,
"Usage: XtAddWorkProc variable command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
variable = argv[1];
cmd = strdup((char *)argv[2]);
id = XtAddWorkProc((XtWorkProc)stdWorkProcCB, (XtPointer)cmd);
RegisterCmdStr(WORKPROC_CMDS, (long)id, cmd);
sprintf(buf, "0x%lx", (long)id);
alt_env_set_var(variable, buf);
return(0);
}
int
do_XtRemoveWorkProc(
int argc,
char *argv[] )
{
XtWorkProcId id;
char *p;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,29, "Usage: XtRemoveWorkProc workProcId"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
id = strtoul(argv[1], &p, 16);
if (p == argv[1])
{
errmsg=strdup(GETMESSAGE(5,30,
"The workProcId parameter must be a hex number: %s"));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
XtRemoveWorkProc(id);
RemoveCmdStr(WORKPROC_CMDS, (long)id);
return(0);
}
int
do_XtAddTimeOut(
int argc,
char *argv[] )
{
unsigned long milliseconds = 0;
wtab_t *w;
char *variable;
char *cmd;
char buf[256];
XtIntervalId id;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,31,
"Usage: XtAddTimeOut variable milliseconds command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
variable = argv[1];
if ((milliseconds = atol(argv[2])) <= 0)
{
errmsg = strdup(GETMESSAGE(5,32,
"The milliseconds parameter must be greater than zero"));
printerr(argv[0], errmsg, NULL);
free(errmsg);
alt_env_set_var(variable, str_nill);
return(1);
}
cmd = strdup((char *)argv[3]);
id = XtAddTimeOut(milliseconds, (XtTimerCallbackProc)stdTimerCB,
(XtPointer)cmd);
RegisterCmdStr(TIMEOUT_CMDS, (long)id, cmd);
sprintf(buf, "0x%lx", (long)id);
alt_env_set_var(variable, buf);
return(0);
}
int
do_XtRemoveTimeOut(
int argc,
char *argv[] )
{
XtIntervalId id;
char *p;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,33, "Usage: XtRemoveTimeOut intervalId"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
id = strtoul(argv[1], &p, 16);
if (p == argv[1]) {
errmsg = strdup(GETMESSAGE(5,34,
"The intervalId parameter must be a hex number: %s"));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
XtRemoveTimeOut(id);
RemoveCmdStr(TIMEOUT_CMDS, (long)id);
return(0);
}
int
do_XtUnmanageChildren(
int argc,
char *argv[] )
{
return(do_managelist_func(argc, argv, (int (*)())XtUnmanageChildren));
}
int
do_XtManageChildren(
int argc,
char *argv[] )
{
return(do_managelist_func(argc, argv, (int (*)())XtManageChildren));
}
int
do_managelist_func(
int argc,
char *argv[],
int (*func)() )
{
wtab_t *w;
register int i;
Widget widgets[MAXARGS];
Cardinal nwidgets;
char * errmsg;
if (argc < 2) {
errmsg = strdup(GETMESSAGE(5,35, "Usage: %s widget ..."));
printerrf(str_nill, errmsg, argv[0], NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
for (nwidgets = 0, i = 1; i < argc && nwidgets < MAXARGS; i++) {
w = str_to_wtab(argv[0], argv[i]);
if (w != NULL) {
widgets[nwidgets++] = w->w;
}
}
func(widgets, nwidgets);
return(0);
}
int
do_XtIsSubclass(
int argc,
char *argv[] )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,120,
"Usage: XtIsSubclass widget class"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w != NULL)
{
for (i = 0; C[i].cname; i++)
{
if (strcmp(argv[2], C[i].cname) == 0)
return(!XtIsSubclass(w->w, C[i].class));
}
}
errmsg = strdup(GETMESSAGE(5,121,
"%s is not a valid widget class name"));
printerrf(str_nill, errmsg, argv[2], NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(255);
}
int
do_XtClass(
int argc,
char *argv[] )
{
wtab_t *w;
register int i;
char * errmsg;
WidgetClass class;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,122,
"Usage: XtClass variable widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[2]);
if (w != NULL)
{
class = XtClass(w->w);
for (i = 0; C[i].cname; i++)
{
if (C[i].class == class)
{
alt_env_set_var(argv[1], C[i].cname);
return(0);
}
}
}
alt_env_set_var(argv[1], str_nill);
return(255);
}
#define PARSE_POINTLIST (-1)
#define PARSE_SEGMENTLIST (-2)
#define PARSE_AREA (-3)
GC Standard_GC;
int
create_standard_gc(
Display *display,
Window drawable )
{
Standard_GC = XCreateGC(display, drawable, 0, NULL);
return(0);
}
int
do_XBell(
int argc,
char *argv[] )
{
int volume;
Display * display;
char * p;
char * errmsg;
if (argc != 3)
{
errmsg=strdup(GETMESSAGE(5,36, "Usage: XBell display volume"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
else
volume = atoi(argv[2]);
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
if (volume < -100)
volume = -100;
else if (volume > 100)
volume = 100;
XBell(display, volume);
return(0);
}
static int
do_RootWindowCmd(
int (*func)(),
int argc,
char *argv[] )
{
Screen * screen;
char * p;
char buf[128];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,37, "Usage: %s variable screen"));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
screen = (Screen *)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GETMESSAGE(5,38, "The screen parameter is invalid: %s"));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
sprintf(buf, "%ld", (long)(*func)(screen));
alt_env_set_var(argv[1], buf);
return(0);
}
int
do_XRootWindowOfScreen(
int argc,
char *argv[] )
{
return(do_RootWindowCmd((int (*)())XRootWindowOfScreen, argc, argv));
}
int
do_XWidthOfScreen(
int argc,
char *argv[] )
{
return(do_RootWindowCmd(XWidthOfScreen, argc, argv));
}
int
do_XHeightOfScreen(
int argc,
char *argv[] )
{
return(do_RootWindowCmd(XHeightOfScreen, argc, argv));
}
int
do_XDefineCursor(
int argc,
char *argv[] )
{
Cursor cursor;
Display * display;
Window window;
char * p;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,39,
"Usage: XDefineCursor display window cursorId"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
window = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
cursor = (Cursor)strtoul(argv[3], &p, 0);
if (p == argv[3])
{
errmsg = strdup(GETMESSAGE(5,40,
"The cursorId parameter is invalid: %s"));
printerrf(argv[0], errmsg, argv[3], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
XDefineCursor(display, window, cursor);
return(0);
}
int
do_XUndefineCursor(
int argc,
char *argv[] )
{
Display * display;
Window window;
char * p;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,41,
"Usage: XUndefineCursor display window"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
window = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
XUndefineCursor(display, window);
return(0);
}
int
do_XtRemoveAllCallbacks(
int argc,
char *argv[] )
{
wtab_t *w;
register int i;
char * errmsg;
if (argc != 3) {
errmsg = strdup(GETMESSAGE(5,42,
"Usage: XtRemoveAllCallbacks widget callbackName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w != NULL) {
XtRemoveAllCallbacks(w->w, argv[2]);
return(0);
} else
return(1);
}
static int
cvtfontstruct(
char *name,
XFontStruct **fn )
{
XrmValue fval, tval;
fval.addr = name;
fval.size = strlen(name);
XtConvert(Toplevel, XtRString, &fval, XtRFontStruct, &tval);
if (tval.size != 0) {
*fn = ((XFontStruct **)(tval.addr))[0];
return(SUCCESS);
} else
return(FAIL);
}
static int
CatchNonFatalFontError(
Display *display,
XErrorEvent *event )
{
invalidFont = True;
}
static int
cvtfont(
Display *display,
char *name,
Font *fn )
{
int (*oldHandler)();
invalidFont = False;
oldHandler = XSetErrorHandler(CatchNonFatalFontError);
*fn = XLoadFont(display, name);
XSync(display, False);
XSetErrorHandler(oldHandler);
if (!invalidFont)
return(SUCCESS);
else
return(FAIL);
}
static int
cvtcolor(
char *name,
Pixel *pix )
{
XrmValue fval, tval;
fval.addr = name;
fval.size = strlen(name);
XtConvert(Toplevel, XtRString, &fval, XtRPixel, &tval);
if (tval.size != 0) {
*pix = ((Pixel *)(tval.addr))[0];
return(SUCCESS);
} else
return(FAIL);
}
int
do_XTextWidth(
int argc,
char *argv[] )
{
XFontStruct *fn;
char *s;
char buf[128];
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,43,
"Usage: XTextWidth variable fontName string"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (cvtfontstruct(argv[2], &fn) != SUCCESS)
{
errmsg = strdup(GetSharedMsg(DT_BAD_FONT));
printerrf(argv[0], errmsg, argv[2], NULL,
NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
s = argv[3];
sprintf(buf, "%ld", (long)XTextWidth(fn, s, strlen(s)));
alt_env_set_var(argv[1], buf);
return(0);
}
#define MAXDRAWARGS 6
#define LINE_ARGS 1
#define POLYGON_ARGS 2
static int
invokeXDrawFunction(
int function,
int argc,
char *argv[] )
{
char * functionName = argv[0];
Display * display;
Window drawable;
Window destination;
int srcX, srcY;
int destX, destY;
unsigned int width, height;
char *s;
char *sp;
register int i;
int mode, parse;
int text = FALSE;
int (*func)();
int argtype = 0;
int polymode;
int coordmode;
GC gc = NULL;
int p[MAXDRAWARGS];
int returnVal = 0;
Boolean unknownOption;
Boolean userSpecifiedGC = False;
char * errmsg;
if (argc < 3)
{
errmsg = strdup(GETMESSAGE(5,44,
"Usage: %s display drawable [args ...]"));
printerrf(str_nill, errmsg, functionName, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &sp, 0);
if (sp == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
drawable = (Window)strtoul(argv[2], &sp, 0);
if (sp == argv[2])
{
errmsg = strdup(GETMESSAGE(5,45,
"The drawable parameter is invalid: %s"));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
if (function == COPY_AREA)
{
parse = 0;
func = XCopyArea;
destination = (Window)strtoul(argv[3], &sp, 0);
if (sp == argv[3])
{
errmsg = strdup(GETMESSAGE(5,46,
"The destination parameter is invalid: %s"));
printerrf(argv[0], errmsg, argv[3], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
srcX = atoi(argv[4]);
srcY = atoi(argv[5]);
width = atoi(argv[6]);
height = atoi(argv[7]);
destX = atoi(argv[8]);
destY = atoi(argv[9]);
argc -= 7;
argv += 7;
}
else if (function == DRAW_RECTANGLE)
{
parse = 4;
func = XDrawRectangle;
}
else if (function == FILL_RECTANGLE)
{
parse = 4;
func = XFillRectangle;
}
else if (function == FILL_POLYGON)
{
parse = PARSE_POINTLIST;
func = XFillPolygon;
argtype = POLYGON_ARGS;
polymode = Complex;
coordmode = CoordModeOrigin;
if (argc > 3)
{
while (argv[3][0] == '-')
{
if (strcmp(argv[3], "-Complex") == 0)
polymode = Complex;
else if (strcmp(argv[3], "-Convex") == 0)
polymode = Convex;
else if (strcmp(argv[3], "-Nonconvex") == 0)
polymode = Nonconvex;
else if (strcmp(argv[3], "-CoordModeOrigin") == 0)
coordmode = CoordModeOrigin;
else if (strcmp(argv[3], "-CoordModePrevious") == 0)
coordmode = CoordModePrevious;
else
break;
argc--;
argv++;
}
}
}
else if (function == DRAW_LINE)
{
parse = 4;
func = XDrawLine;
}
else if (function == DRAW_SEGMENTS)
{
parse = PARSE_SEGMENTLIST;
func = XDrawSegments;
}
else if (function == DRAW_LINES)
{
parse = PARSE_POINTLIST;
func = XDrawLines;
argtype = LINE_ARGS;
coordmode = CoordModeOrigin;
if (argc > 3)
{
while (argv[3][0] == '-')
{
if (strcmp(argv[3], "-CoordModeOrigin") == 0)
coordmode = CoordModeOrigin;
else if (strcmp(argv[3], "-CoordModePrevious") == 0)
coordmode = CoordModePrevious;
else
break;
argc--;
argv++;
}
}
}
else if (function == DRAW_STRING)
{
parse = 2;
text = TRUE;
func = XDrawString;
}
else if (function == DRAW_IMAGE_STRING)
{
parse = 2;
text = TRUE;
func = XDrawImageString;
}
else if (function == DRAW_ARC)
{
parse = 6;
func = XDrawArc;
}
else if (function == FILL_ARC)
{
parse = 6;
func = XFillArc;
}
else if (function == DRAW_POINT)
{
parse = 2;
func = XDrawPoint;
}
else if (function == DRAW_POINTS)
{
parse = PARSE_POINTLIST;
func = XDrawPoints;
argtype = LINE_ARGS;
coordmode = CoordModeOrigin;
if (argc > 3)
{
while (argv[3][0] == '-')
{
if (strcmp(argv[3], "-CoordModeOrigin") == 0)
coordmode = CoordModeOrigin;
else if (strcmp(argv[3], "-CoordModePrevious") == 0)
coordmode = CoordModePrevious;
else
break;
argc--;
argv++;
}
}
}
else if (function == CLEAR_WINDOW)
{
parse = 0;
func = XClearWindow;
}
else if (function == CLEAR_AREA)
{
parse = PARSE_AREA;
func = XClearArea;
}
if (Standard_GC == NULL)
create_standard_gc(display, drawable);
while (argc > 4 && argv[3][0] == '-')
{
if (gc == NULL)
gc = XCreateGC(display, drawable, 0, NULL);
if (strcmp(argv[3], "-gc") == 0)
{
XFreeGC(display, gc);
gc = (GC) atol(argv[4]);
userSpecifiedGC = True;
}
else if (strcmp(argv[3], "-foreground") == 0)
{
Pixel pix;
if (cvtcolor(argv[4], &pix) == SUCCESS)
XSetForeground(display, gc, pix);
}
else if (strcmp(argv[3], "-background") == 0)
{
Pixel pix;
if (cvtcolor(argv[4], &pix) == SUCCESS)
XSetBackground(display, gc, pix);
}
else if (strcmp(argv[3], "-font") == 0)
{
Font fn;
if (cvtfont(display, argv[4], &fn) == SUCCESS)
XSetFont(display, gc, fn);
else
{
errmsg = strdup(GetSharedMsg(DT_BAD_FONT));
printerrf(functionName, errmsg, argv[4], NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
free(errmsg);
returnVal = 1;
}
}
else if (strcmp(argv[3], "-line_width") == 0)
{
XGCValues v;
v.line_width = atoi(argv[4]);
XChangeGC(display, gc, GCLineWidth, &v);
}
else if (strcmp(argv[3], "-function") == 0)
{
XGCValues v;
long f;
unknownOption = False;
if (strcmp(argv[4], "xor") == 0)
f = GXxor;
else if (strcmp(argv[4], "or") == 0)
f = GXor;
else if (strcmp(argv[4], "clear") == 0)
f = GXclear;
else if (strcmp(argv[4], "and") == 0)
f = GXand;
else if (strcmp(argv[4], "copy") == 0)
f = GXcopy;
else if (strcmp(argv[4], "noop") == 0)
f = GXnoop;
else if (strcmp(argv[4], "nor") == 0)
f = GXnor;
else if (strcmp(argv[4], "nand") == 0)
f = GXnand;
else if (strcmp(argv[4], "set") == 0)
f = GXset;
else if (strcmp(argv[4], "invert") == 0)
f = GXinvert;
else if (strcmp(argv[4], "equiv") == 0)
f = GXequiv;
else if (strcmp(argv[4], "andReverse") == 0)
f = GXandReverse;
else if (strcmp(argv[4], "orReverse") == 0)
f = GXorReverse;
else if (strcmp(argv[4], "copyInverted") == 0)
f = GXcopyInverted;
else
{
errmsg = strdup(GETMESSAGE(5,47,
"Unrecognized graphics function name: %s"));
printerrf(functionName, errmsg, argv[4],
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
returnVal = 1;
unknownOption = True;
}
if (!unknownOption)
{
v.function = f;
XChangeGC(display, gc, GCFunction, &v);
}
}
else if (strcmp(argv[3], "-line_style") == 0)
{
XGCValues v;
long f;
unknownOption = False;
if (strcmp(argv[4], "LineSolid") == 0)
f = LineSolid;
else if (strcmp(argv[4], "LineDoubleDash") == 0)
f = LineDoubleDash;
else if (strcmp(argv[4], "LineOnOffDash") == 0)
f = LineOnOffDash;
else {
errmsg = strdup(GETMESSAGE(5,48, "Unrecognized line style: %s"));
printerrf(functionName, errmsg,
argv[4], NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
returnVal = 1;
unknownOption = True;
}
if (!unknownOption)
{
v.line_style = f;
XChangeGC(display, gc, GCLineStyle, &v);
}
}
else
{
errmsg = strdup(GETMESSAGE(5,49, "Unrecognized drawing option: %s"));
printerrf(functionName, errmsg, argv[3], NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
returnVal = 1;
}
argv += 2;
argc -= 2;
}
if (gc == NULL)
gc = Standard_GC;
argc -= 3;
argv += 3;
if (parse == PARSE_POINTLIST)
{
XPoint *points = (XPoint *)malloc(sizeof(XPoint )*(argc/2+1));
int npoints = 0;
for (i = 0; i < argc-1; i += 2, npoints++)
{
points[npoints].x = atoi(argv[i]);
points[npoints].y = atoi(argv[i+1]);
}
switch (argtype)
{
case POLYGON_ARGS:
{
(*func)(display, drawable, gc, points, argc/2, polymode, coordmode);
break;
}
case LINE_ARGS:
{
(*func)(display, drawable, gc, points, argc/2, coordmode);
break;
}
}
free(points);
argc -= 2*npoints;
argv += 2*npoints;
}
else if (parse == PARSE_SEGMENTLIST)
{
XSegment *segments;
int nsegments = 0;
segments = (XSegment *)malloc(sizeof(XSegment )*(argc/4+1));
for (i = 0; i < argc-1; i += 4, nsegments++)
{
segments[nsegments].x1 = atoi(argv[i]);
segments[nsegments].y1 = atoi(argv[i+1]);
segments[nsegments].x2 = atoi(argv[i+2]);
segments[nsegments].y2 = atoi(argv[i+3]);
}
(*func)(display, drawable, gc, segments, argc/4);
free(segments);
argc -= 4*nsegments;
argv += 4*nsegments;
}
else if (parse == PARSE_AREA)
{
Boolean exposures = False;
XrmValue fval, tval;
for (i = 0; i < 4 && argc > 0; i++)
{
p[i] = atoi(argv[0]);
argc --;
argv ++;
}
if (argc > 0)
{
fval.addr = argv[0];
fval.size = strlen(argv[0]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
exposures = *((Boolean *)(tval.addr));
argc --;
argv ++;
}
(*func)(display, drawable, p[0], p[1], p[2], p[3], exposures);
}
else
{
while (argc >= parse)
{
for (i = 0; i < parse && i < argc; i++)
p[i] = atoi(argv[i]);
if (text)
{
(*func)(display, drawable, gc,
p[0], p[1], argv[i], strlen(argv[i]));
argc--;
argv++;
}
else if (func == XClearWindow)
(*func)(display, drawable);
else if (func == XCopyArea)
{
(*func)(display, drawable, destination, gc,
srcX, srcY, width, height, destX, destY);
}
else
{
(*func)(display, drawable, gc,
p[0], p[1], p[2], p[3], p[4], p[5]);
}
argc -= parse;
argv += parse;
if (parse == 0)
break;
}
}
if ((gc != Standard_GC) && !userSpecifiedGC)
XFreeGC(display, gc);
if (argc != 0)
{
errmsg = strdup(GETMESSAGE(5,50,
"There were left over points which were ignored"));
printerr(functionName, errmsg, NULL);
free(errmsg);
returnVal = 1;
}
return(returnVal);
}
#undef LINE_ARGS
#undef POLYGON_ARGS
int
do_XDrawArc(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_ARC, argc, argv);
}
int
do_XDrawImageString(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_IMAGE_STRING, argc, argv);
}
int
do_XDrawLine(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_LINE, argc, argv);
}
int
do_XDrawLines(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_LINES, argc, argv);
}
int
do_XDrawPoint(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_POINT, argc, argv);
}
int
do_XDrawPoints(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_POINTS, argc, argv);
}
int
do_XDrawRectangle(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_RECTANGLE, argc, argv);
}
int
do_XCopyArea(
int argc,
char *argv[] )
{
char * errmsg;
if (argc < 10)
{
errmsg = strdup(GETMESSAGE(5,51,
"Usage: XCopyArea display source dest sourceX sourceY width height destX destY [args ...]"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
invokeXDrawFunction(COPY_AREA, argc, argv);
}
int
do_XDrawSegments(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_SEGMENTS, argc, argv);
}
int
do_XDrawString(
int argc,
char *argv[] )
{
invokeXDrawFunction(DRAW_STRING, argc, argv);
}
int
do_XFillArc(
int argc,
char *argv[] )
{
invokeXDrawFunction(FILL_ARC, argc, argv);
}
int
do_XFillPolygon(
int argc,
char *argv[] )
{
invokeXDrawFunction(FILL_POLYGON, argc, argv);
}
int
do_XFillRectangle(
int argc,
char *argv[] )
{
invokeXDrawFunction(FILL_RECTANGLE, argc, argv);
}
int
do_XClearArea(
int argc,
char *argv[] )
{
invokeXDrawFunction(CLEAR_AREA, argc, argv);
}
int
do_XClearWindow(
int argc,
char *argv[] )
{
invokeXDrawFunction(CLEAR_WINDOW, argc, argv);
}
int
ConvertTypeToString(
char *arg0,
classtab_t *class,
wtab_t *w,
wtab_t *parent,
char *resource,
XtArgVal val,
char **ret )
{
char *from_type;
XtResourceList res;
XrmValue fr_val, to_val;
char *nam;
char * errmsg;
if ((nam = hashget((Hash_table_t*)class->res, resource)) == NULL) {
/* If we didn't find it in this widget's class record,
* see if the parent is a constraint widget class, and
* if so then see if we can find the class there.
*/
if (parent == NULL || parent->wclass == NULL ||
parent->wclass->con == NULL ||
(nam = hashget((Hash_table_t*)parent->wclass->con, resource))
== NULL)
{
errmsg = strdup(GetSharedMsg(DT_UNDEF_RESOURCE));
printerrf(arg0, errmsg,
(char *)(class->cname), resource, NULL, NULL,
NULL, NULL, NULL, NULL);
free(errmsg);
return(FAIL);
}
}
res = (XtResourceList)nam;
/*
* unfortunately, we have to have a special case for String
* type resources, since their size may vary.
*/
if (strcmp(res->resource_type, str_XtRString) == 0) {
*ret = ((String *)val)[0];
return(0);
}
fr_val.size = res->resource_size;
fr_val.addr = (caddr_t)val;
to_val.size = 0;
to_val.addr = NULL;
XtConvert(
w ? w->w : Toplevel,
res->resource_type, /* from type */
&fr_val, /* from value */
str_XtRString, /* to type */
&to_val /* the converted value */
);
if ((to_val.addr) || (strcmp(res->resource_type, XmRXmString) == 0)) {
*ret = to_val.addr;
} else {
errmsg=strdup(GETMESSAGE(5,52,
"Unable to convert resource type '%s' to 'String'"));
printerrf(arg0, errmsg,
res->resource_type, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(FAIL);
}
return(SUCCESS);
}
wtab_t *DTKSHConversionWidget;
classtab_t *DTKSHConversionClass;
char *DTKSHConversionResource;
int
ConvertStringToType(
char *arg0,
wtab_t *w,
wtab_t *parent,
classtab_t *class,
char *resource,
char *val,
XtArgVal *ret,
int *freeit,
Boolean postponePixmaps )
{
char *to_type;
XtResourceList res;
XrmValue fr_val, to_val;
char *nam;
char * errmsg;
DTKSHConversionClass = class; /* needed by callback converter */
DTKSHConversionResource = resource; /* needed by callback converter */
DTKSHConversionWidget = w; /* needed by callback converter */
if ((nam = hashget((Hash_table_t*)class->res, resource)) == NULL) {
/* If we didn't find it in this widget's class record,
* see if the parent is a constraint widget class, and
* if so then see if we can find the class there.
*/
if (parent == NULL || parent->wclass == NULL ||
parent->wclass->con == NULL ||
(nam = hashget((Hash_table_t*)parent->wclass->con,
resource)) == NULL)
{
errmsg = strdup(GetSharedMsg(DT_UNDEF_RESOURCE));
printerrf(arg0, errmsg,
(char *)(class->cname), resource, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(CONVERT_FAILED);
}
}
res = (XtResourceList)nam;
/*
* Unfortunately, because String types can be variable in size,
* we have to handle this as a special case.
*/
if (strcmp(res->resource_type, str_XtRString) == 0) {
*ret = (XtArgVal)strdup(val);
*freeit = TRUE;
return(CONVERT_SUCCEEDED);
}
fr_val.size = strlen(val) + 1;
fr_val.addr = (caddr_t)val;
to_val.size = 0;
to_val.addr = NULL;
/*
* Hook to allow us to postpone processing of certain classes of
* resources. In particular, Dimension based resources can't be
* converted until the widget exists, nor can gadget pixmap resources.
* Any other pixmap resource needs to be postponed until after any
* color changes have taken effect, otherwise the string to pixmap
* converter uses the existing colors, instead of the new colors.
*/
if (toolkit_special_resource(arg0, res, w, parent,
class, resource, val, ret,
freeit, postponePixmaps)) {
return(CONVERT_POSTPONED);
}
XtConvert(
w ? w->w : Toplevel,
str_XtRString, /* from type */
&fr_val, /* from value */
res->resource_type, /* to type */
&to_val /* the converted value */
);
if (to_val.size && to_val.addr) {
switch(to_val.size) {
case sizeof(char):
*ret = ((char *)to_val.addr)[0];
*freeit = FALSE;
break;
case sizeof(short):
*ret = (XtArgVal)((short *)to_val.addr)[0];
*freeit = FALSE;
break;
case sizeof(int):
*ret = (XtArgVal)((int *)to_val.addr)[0];
*freeit = FALSE;
break;
default:
/*
* Deal with sizeof(long) != sizeof(int) here.
* Bit of a cheat but it's a simple change.
*/
if (to_val.size == sizeof(long)) {
*ret = (XtArgVal)((long *)to_val.addr)[0];
*freeit = FALSE;
break;
}
/*
* There is a possibility that some
* coverters will return malloc'ed space and this
* is really unnecessary and will leak memory. About
* the only way to handle this is to handle such types as
* special cases. Maybe we need a hash table that
* contains the names of types that need the malloc?
* The X specs should really have some mechanism for
* knowing when to free the results of a conversion.
*/
*ret = (XtArgVal)XtMalloc(to_val.size);
memcpy((char *)ret, to_val.addr, to_val.size);
*freeit = TRUE;
}
} else {
errmsg=strdup(GETMESSAGE(5,53,
"Unable to convert resource type 'String' to type '%s'"));
printerrf(arg0, errmsg,
res->resource_type, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(CONVERT_FAILED);
}
return(CONVERT_SUCCEEDED);
}
static int
XtAddInputUsage(
char *arg0 )
{
char * errmsg;
errmsg=strdup(GETMESSAGE(5,54,
"Usage: XtAddInput variable [-r] fileDescriptor kshCommand"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
int
do_XtAddInput(
int argc,
char *argv[] )
{
register int i, j;
int fd;
char *arg0 = argv[0];
char *variable;
char *cmd;
inputrec_t *inp;
XtInputId id;
char buf[256];
char * errmsg;
unsigned char modeFlags = LINE_INPUT_MODE;
if (argc < 4)
return(XtAddInputUsage(arg0));
variable = argv[1];
argv+=2;
argc-=2;
if (strcmp(argv[0], "-r") == 0)
{
/* Raw mode; the registered handler will take care of reading input */
modeFlags = RAW_INPUT_MODE;
argv++;
argc--;
}
if (argc != 2)
return(XtAddInputUsage(arg0));
fd = atoi(argv[0]);
argv++;
argc--;
inp = (inputrec_t *)XtMalloc(sizeof(inputrec_t));
if (modeFlags & RAW_INPUT_MODE)
{
/* Raw mode; the registered handler will do all buffering */
inp->lnbufsize = 0;
inp->lnbuf = NULL;
}
else
{
inp->lnbufsize = LINESIZE;
inp->lnbuf = XtMalloc(inp->lnbufsize);
}
inp->fd = fd;
inp->flags = modeFlags;
inp->lnend = 0;
inp->cmd = strdup(argv[0]);
inp->lastCharIsBackslash = False;
inp->lineWasTouched = False;
id = XtAddInput(fd, (XtPointer)XtInputReadMask,
(XtInputCallbackProc)stdInputCB, (caddr_t)inp);
/*
* Save a record of this input, so that we can destroy the buffer
* information when the input handler is unregistered.
*/
for (i = 0; i < numActiveInputs; i++)
{
if (activeInputs[i].inUse == False)
break;
}
if ( i >= numActiveInputs)
{
/* Grow the array */
numActiveInputs += 5;
activeInputs = (InputRecord *)XtRealloc((char *)activeInputs,
sizeof(InputRecord) * numActiveInputs);
for (j = i; j < numActiveInputs; j++)
{
activeInputs[j].inUse = False;
activeInputs[j].inp = NULL;
activeInputs[j].id = 0;
}
}
activeInputs[i].inUse = True;
activeInputs[i].id = id;
activeInputs[i].inp = inp;
sprintf(buf, "0x%lx", (long)id);
alt_env_set_var(variable, buf);
return(0);
}
int
do_XtRemoveInput(
int argc,
char *argv[] )
{
XtInputId id;
char *p;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,56, "Usage: XtRemoveInput inputId"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
id = strtoul(argv[1], &p, 16);
if (p == argv[1])
{
errmsg = strdup(GETMESSAGE(5,57,
"The inputId parameter must be a hex number: %s"));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
free(errmsg);
return(1);
}
DestroyInputRecord(id);
return(0);
}
/*
* This function will attempt to remove the indicated input source. If,
* however, the source is busy (i.e. the XtRemoveInput() request came
* from within the input handler), then we will simply mark the input
* source as 'pending destroy', and will allow stdInputCB to do the
* actual removing when it is safe.
*/
static void
DestroyInputRecord(
XtInputId id )
{
inputrec_t * inp;
int entryIndex;
if ((entryIndex = FindInputRecord(id)) >= 0)
{
inp = activeInputs[entryIndex].inp;
if (inp->flags & INPUT_SOURCE_BUSY)
inp->flags |= INPUT_SOURCE_PENDING_DELETE;
else
{
/* It's ok to delete the source now */
XtRemoveInput(id);
activeInputs[entryIndex].inUse = False;
activeInputs[entryIndex].id = 0;
activeInputs[entryIndex].inp = NULL;
XtFree(inp->lnbuf);
XtFree((char *)inp);
}
}
}
static int
FindInputRecord(
XtInputId id )
{
int i;
for (i = 0; i < numActiveInputs; i++)
{
if ((activeInputs[i].inUse) && (activeInputs[i].id == id))
return(i);
}
return(-1);
}
/*
* This function will initialize some environment variables, and then
* invoke the handler registered for this input source. If will return
* 'True' if the handler called XtRemoveInput on this source; if this
* has happened, then the 'inp' structure MUST NOT be touched again,
* since it will have been freed up.
*/
static Boolean
ProcessInput(
inputrec_t * inp,
int source,
XtInputId id,
Boolean eofFound )
{
Namval_t * sourceVar = nv_search("INPUT_SOURCE", sh.var_tree, NV_ADD);
Namval_t * idVar = nv_search("INPUT_ID", sh.var_tree, NV_ADD);
Namval_t * eofVar = nv_search("INPUT_EOF", sh.var_tree, NV_ADD);
Namval_t * lineVar = nv_search("INPUT_LINE", sh.var_tree, NV_ADD);
char strBuf[25];
/* Initialize the environment variables */
sprintf(strBuf, "%d", source);
nv_putval(sourceVar, strBuf, NV_RDONLY);
sprintf(strBuf, "0x%lx", (long)id);
nv_putval(idVar, strBuf, NV_RDONLY);
sprintf(strBuf, "%s", (eofFound ? "true" : "false"));
nv_putval(eofVar, strBuf, NV_RDONLY);
if ((inp->flags & RAW_INPUT_MODE) || (inp->lnend == 0))
{
strBuf[0] = '\0';
nv_putval(lineVar, strBuf, NV_RDONLY);
}
else
nv_putval(lineVar, inp->lnbuf, NV_RDONLY);
/* Invoke the registered handler */
inp->flags |= INPUT_SOURCE_BUSY;
ksh_eval(inp->cmd);
inp->flags &= ~INPUT_SOURCE_BUSY;
/* Clean up the environment variables */
nv_newattr(sourceVar, 0, 0);
nv_close(sourceVar);
nv_newattr(idVar, 0, 0);
nv_close(idVar);
nv_newattr(eofVar, 0, 0);
nv_close(eofVar);
nv_newattr(lineVar, 0, 0);
nv_close(lineVar);
/* If the handler removed the input source, then process it now */
if (inp->flags & INPUT_SOURCE_PENDING_DELETE)
{
DestroyInputRecord(id);
return(True);
}
return(False);
}
void
Translation_ksh_eval(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params )
{
char buf[128];
int i;
Namval_t * np;
Namval_t * np2;
wtab_t *wtab = NULL;
Namfun_t * clonedDisc;
if (w != NULL)
wtab = widget_to_wtab(w);
nestingLevel++;
np2 = GetNameValuePair("TRANSLATION_WIDGET");
nv_newattr(np2, 0, 0);
nv_putval(np2, (wtab ? wtab->widid : "Unknown"), NV_RDONLY);
nv_newattr(np2, NV_RDONLY, 0);
np = GetNameValuePair("TRANSLATION_EVENT");
nv_newattr(np, 0, 0);
sprintf(buf, "0x%lx", (long)event);
nv_putval(np, buf, NV_RDONLY);
nv_newattr(np, NV_RDONLY, 0);
clonedDisc = CloneDiscipline(&transDiscipline);
nv_stack(np, clonedDisc);
for (i = 0; i < *num_params; i++)
ksh_eval(params[i]);
/* Remove the discipline for the hierarchical variables */
nv_stack(np, NULL);
FreeDiscipline(clonedDisc);
/* Free up all of the name/value pairs we created */
FreeNestedVariables();
nestingLevel--;
}
void
RestorePriorEnvVarValues(
Namval_t *np1,
char *value1,
Namval_t *np2,
char *value2 )
{
if (value1 && np1)
{
nv_newattr(np1, 0, 0);
nv_putval(np1, value1, NV_RDONLY);
nv_newattr(np1, NV_RDONLY, 0);
}
if (value2 && np2)
{
nv_newattr(np2, 0, 0);
nv_putval(np2, value2, NV_RDONLY);
nv_newattr(np2, NV_RDONLY, 0);
}
}
/*
* stdCB() is the central routine from which all callback
* functions are dispatched (specified by clientData). The
* variables "CB_WIDGET" and "CB_CALL_DATA" will be placed in
* the environment to represent the CallBackWidget handle.
*/
void
stdCB(
void *widget,
caddr_t clientData,
caddr_t callData )
{
char buf[128];
dtksh_client_data_t *cdata = (dtksh_client_data_t *)clientData;
Namval_t * np;
Namval_t * np2;
WidgetClass class;
Namdisc_t * discipline = NULL;
int i;
char * oldCB_WIDGET_value = NULL;
char * oldCB_CALL_DATA_value = NULL;
char * ptr;
Namfun_t * clonedDisc;
/*
* The wtab_t entry of the cdata need not be filled in since
* it could have been set via direct resource setting at widget
* creation time, and the converter for string to callback would
* not have had access to this information (since the widget
* was not created yet.
* Thus, we set it here. Note that this will happen at most
* one time, since we are modifying the cdata structure.
*/
if (cdata->w == NULL)
cdata->w = widget_to_wtab(widget);
nestingLevel++;
np2 = GetNameValuePair("CB_WIDGET");
nv_newattr(np2, 0, 0);
if (ptr = nv_getval(np2))
oldCB_WIDGET_value = strdup(ptr);
nv_putval(np2, (cdata->w ? cdata->w->widid : "Unknown"), NV_RDONLY);
nv_newattr(np2, NV_RDONLY, 0);
/* Certain callbacks don't pass structures as the calldata */
if ((cdata->cbname) &&
((strcmp(cdata->cbname, XmNpopupCallback) == 0) ||
(strcmp(cdata->cbname, XmNpopdownCallback) == 0)))
{
/* The calldata indicates the grab type */
XtGrabKind * grabKind = (XtGrabKind *)callData;
switch (*grabKind)
{
case XtGrabNonexclusive:
{
strcpy(buf, "GrabNonexclusive");
break;
}
case XtGrabExclusive:
{
strcpy(buf, "GrabExclusive");
break;
}
default:
{
strcpy(buf, "GrabNone");
break;
}
}
}
else
sprintf(buf, "0x%lx", (long)callData);
np = GetNameValuePair("CB_CALL_DATA");
nv_newattr(np, 0, 0);
if (ptr = nv_getval(np))
oldCB_CALL_DATA_value = strdup(ptr);
nv_putval(np, buf, NV_RDONLY);
nv_newattr(np, NV_RDONLY, 0);
/*
* Add a discipline for hierarchical variables.
* Need to add a different discipline, based on the callback type,
* since the fields within the callback structure differ depending
* upon the type of callback and the widget. NOTE: the WMProtocol
* callback will use the default discipline.
*/
if (cdata->cbname)
{
if ((strcmp(cdata->cbname, XmNpopupCallback) == 0) ||
(strcmp(cdata->cbname, XmNpopdownCallback) == 0) ||
(strcmp(cdata->cbname, XmNdestroyCallback) == 0))
{
discipline = &nopDiscipline;
}
else if (strcmp(cdata->cbname, XmNhelpCallback) == 0)
discipline = &dftDiscipline;
else
{
class = XtClass(cdata->w->w);
while (class)
{
if (discipline = CheckClassDisciplines(class, cdata->cbname))
break;
class = class->core_class.superclass;
}
}
}
/*
* If a discipline was found, then use it; otherwise, we MUST set up
* a default discipline; otherwise, any hierarchical variables
* referenced by the user are not under our control, thus never getting
* freed up, and then also preventing future disciplines from getting
* called when they should have.
*/
if (discipline)
clonedDisc = CloneDiscipline(discipline);
else
clonedDisc = CloneDiscipline(&dftDiscipline);
nv_stack(np, clonedDisc);
ksh_eval((char *)cdata->ksh_cmd);
/* We may be nested, so restore old CB_WIDGET & CB_CALL_DATA values */
RestorePriorEnvVarValues(np2, oldCB_WIDGET_value, np, oldCB_CALL_DATA_value);
XtFree(oldCB_WIDGET_value);
XtFree(oldCB_CALL_DATA_value);
/* Remove the discipline for the hierarchical variables */
nv_stack(np, NULL);
FreeDiscipline(clonedDisc);
/* Free up all of the name/value pairs we created */
FreeNestedVariables();
nestingLevel--;
return;
}
/*
* This is the callback handler for the 'workspace changed' callback.
*/
void
stdWSCB(
void *widget,
Atom atom,
caddr_t clientData )
{
char buf[128];
dtksh_client_data_t *cdata = (dtksh_client_data_t *)clientData;
Namval_t * np;
Namval_t * np2;
int i;
char * oldCB_WIDGET_value = NULL;
char * oldCB_CALL_DATA_value = NULL;
char * ptr;
Namfun_t * clonedDisc;
nestingLevel++;
np2 = GetNameValuePair("CB_WIDGET");
nv_newattr(np2, 0, 0);
if (ptr = nv_getval(np2))
oldCB_WIDGET_value = strdup(ptr);
nv_putval(np2, cdata->w->widid, NV_RDONLY);
nv_newattr(np2, NV_RDONLY, 0);
np = GetNameValuePair("CB_CALL_DATA");
nv_newattr(np, 0, 0);
sprintf(buf, "0x%lx", (long)atom);
if (ptr = nv_getval(np))
oldCB_CALL_DATA_value = strdup(ptr);
nv_putval(np, buf, NV_RDONLY);
nv_newattr(np, NV_RDONLY, 0);
clonedDisc = CloneDiscipline(&nopDiscipline);
nv_stack(np, clonedDisc);
ksh_eval((char *)cdata->ksh_cmd);
/* We may be nested, so restore old CB_WIDGET & CB_CALL_DATA values */
RestorePriorEnvVarValues(np2, oldCB_WIDGET_value, np, oldCB_CALL_DATA_value);
XtFree(oldCB_WIDGET_value);
XtFree(oldCB_CALL_DATA_value);
/* Remove the discipline for the hierarchical variables */
nv_stack(np, NULL);
FreeDiscipline(clonedDisc);
/* Free up all of the name/value pairs we created */
FreeNestedVariables();
nestingLevel--;
}
void
stdInputCB(
inputrec_t *inp,
int *source,
XtInputId *id )
{
char buf[LINESIZE];
char cmdbuf[LINESIZE];
int cmd;
char *p;
register int i, n, j;
char * errmsg;
int len;
/* If in 'raw' mode, then simply let the handler do all the work */
if (inp->flags & RAW_INPUT_MODE)
{
ProcessInput(inp, *source, *id, False);
return;
}
/* try to read some input from the fd */
if ((n = read(inp->fd, buf, sizeof(buf)-1)) <= 0)
{
/* EOF; notify handler, passing in any remaining buffered data */
if ((inp->lnend > 0) || (inp->lineWasTouched))
{
/* Force one call with the data, and a 2nd with the EOF */
inp->lnbuf[inp->lnend] = '\0';
ProcessInput(inp, *source, *id, False);
}
inp->lastCharIsBackslash = False;
inp->lineWasTouched = False;
inp->lnbuf[0] = '\0';
inp->lnend = 0;
ProcessInput(inp, *source, *id, True);
return;
}
/*
* Go through appending to current line, execute line if you
* get an unquoted newline. Strip off the newline, so that
* we are consistent with the ksh 'read' command, remove
* escaped newlines, and do backslash processing.
*/
for (i = 0; i < n; )
{
#ifdef NLS16
len = mblen(buf+i, MB_CUR_MAX);
#else
len = 1;
#endif
inp->lineWasTouched = True;
if ((inp->lnend + len) >= (inp->lnbufsize-1))
{
/* Grow the input buffer */
inp->lnbufsize += (n + LINESIZE + 5);
inp->lnbuf = XtRealloc(inp->lnbuf, inp->lnbufsize);
}
/* Perform backslash processing */
if ((len == 1) && (buf[i] == '\\') && (!inp->lastCharIsBackslash))
{
/* Skip this character; the next character will be treated specially */
inp->lastCharIsBackslash = True;
i++;
continue;
}
/*
* If the previous character has been a backslash, then the current
* character gets placed into the buffer without any special
* processing; the exception is the newline character, which gets
* dumped.
*/
if ((len == 1) && (buf[i] == '\n'))
{
/*
* If the newline is escaped, then drop it, and continue.
* Otherwise, process the line.
*/
i++;
if (inp->lastCharIsBackslash)
{
inp->lastCharIsBackslash = False;
continue;
}
inp->lnbuf[inp->lnend] = '\0';
if (ProcessInput(inp, *source, *id, False))
{
/* The handler called XtRemoveInput() on this source; abort */
return;
}
inp->lnend = 0;
inp->lineWasTouched = False;
}
else
{
/* Simply copy the next character into the buffer */
inp->lastCharIsBackslash = False;
for (j = 0; j < len; j++)
inp->lnbuf[inp->lnend++] = buf[i++];
}
}
}
int
stdWorkProcCB(
char *clientData )
{
int retcode;
int i;
retcode = ksh_eval((char *)clientData);
if (retcode != 0)
{
/* This is tricky, because we do not have the workproc id */
for (i = 0; i < workProcCmdsSize; i++)
{
if (clientData == workProcCmds[i].cmd)
{
RemoveCmdStr(WORKPROC_CMDS, (long)workProcCmds[i].id);
break;
}
}
}
return(retcode);
}
void
stdTimerCB(
char *clientData,
long *id )
{
ksh_eval((char *)clientData);
RemoveCmdStr(TIMEOUT_CMDS, (long)*id);
return;
}
int
do_XFlush(
int argc,
char *argv[] )
{
char *p;
Display * display;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,59, "Usage: XFlush display"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
XFlush(display);
return(0);
}
int
do_XSync(
int argc,
char *argv[] )
{
Boolean discard;
XrmValue fval, tval;
char *p;
Display * display;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,60, "Usage: XSync display discard"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
discard = *((Boolean *)(tval.addr));
else
return(1);
XSync(display, discard);
return(0);
}
int
do_XRaiseWindow(
int argc,
char *argv[] )
{
Boolean discard;
XrmValue fval, tval;
wtab_t *w;
char *p;
Display * display;
Window window;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,61, "Usage: XRaiseWindow display window"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
window = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
XRaiseWindow(display, window);
return(0);
}
static int
XtSetSensitive_usage(
char *arg0 )
{
char * errmsg;
errmsg = strdup(GETMESSAGE(5,62, "Usage: %s widget [True|False]"));
printerrf(str_nill, errmsg, arg0, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
int
do_XtSetSensitive(
int argc,
char *argv[] )
{
wtab_t *w;
Boolean bool;
XrmValue fval, tval;
if (argc != 3)
return(XtSetSensitive_usage(argv[0]));
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
bool = *((Boolean *)(tval.addr));
else
return(1);
w = str_to_wtab(argv[0], argv[1]);
if (w != NULL)
XtSetSensitive(w->w, bool);
else
return(1);
return(0);
}
static int
RegisterTranslations(
void (*func)(),
int argc,
char *argv[] )
{
wtab_t *w;
XtTranslations translationTable;
XrmValue fval, tval;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,63, "Usage: %s widget translations"));
printerrf(str_nill, errmsg, argv[0], NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, XtRTranslationTable, &tval);
if (tval.size != 0)
translationTable = *((XtTranslations *)(tval.addr));
else
return(1);
(*func)(w->w, translationTable);
return(0);
}
int
do_XtOverrideTranslations(
int argc,
char **argv )
{
return(RegisterTranslations(XtOverrideTranslations, argc, argv));
}
int
do_XtAugmentTranslations(
int argc,
char **argv )
{
return(RegisterTranslations(XtAugmentTranslations, argc, argv));
}
int
do_XtUninstallTranslations(
int argc,
char *argv[] )
{
wtab_t *w;
XtTranslations * translationTable;
XrmValue fval, tval;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,64,
"Usage: XtUninstallTranslations widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
XtUninstallTranslations(w->w);
return(0);
}
int
do_XtParent(
int argc,
char **argv )
{
char *arg0 = argv[0];
char * wname;
wtab_t *wtab;
classtab_t *ctab;
char buf[128];
char * errmsg;
if (argc != 3 ) {
errmsg = strdup(GETMESSAGE(5,65, "Usage: XtParent variable widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
wname = argv[2];
wtab = str_to_wtab(arg0, wname);
if (wtab == NULL) {
return(1);
}
if (wtab->parent == NULL) {
wtab = widget_to_wtab(XtParent(wtab->w));
if (wtab == NULL)
return(1);
/*
* If the widget class has no resources registered, then this is
* the first known instance of this widget class, so we need to
* force the resource list to be loaded. This can frequently
* occur if a Motif convenience function is used, which creates
* a 'hidden' parent.
*/
ctab = wtab->wclass;
if (ctab->res == NULL)
(void)str_to_class(arg0, ctab->cname);
} else
wtab = wtab->parent;
sprintf(buf, "%s", wtab->widid);
alt_env_set_var(argv[1], buf);
return(0);
}
int
do_XtLastTimestampProcessed(
int argc,
char **argv )
{
char *arg0 = argv[0];
Display * display;
char * p;
char buf[128];
char * errmsg;
if (argc != 3 ) {
errmsg = strdup(GETMESSAGE(5,66,
"Usage: XtLastTimestampProcessed variable display"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
sprintf(buf, "%ld", (long)XtLastTimestampProcessed(display));
alt_env_set_var(argv[1], buf);
return(0);
}
/**********************************************/
/*
* The following two functions work for both standard Xt callbacks
* (which are identified by a callback name) and WM protocol callbacks
* (which are identified by a property atom). That is why both of
* these parameters are passed in. It is usually the case that only
* one of the 'cbname' and 'propAtom' parameters are used; the unused
* one should be set to NULL (cbname) or None (propAtom).
*/
dtksh_client_data_t *
GetNewCBData(
char *ksh_cmd,
wtab_t *w,
char *cbname,
Atom propAtom )
{
dtksh_client_data_t * cdata;
int i;
int j;
/* Can we reuse an existing entry? */
if ((i = LocateCBRecord (w, cbname, ksh_cmd, propAtom, NULL)) >= 0)
{
cdata = cbDataTable[i];
cdata->refCount++;
return(cdata);
}
/* Look for an open slot */
for (i = 0; i < cbDataTableSize; i++)
{
if (cbDataTable[i] == NULL)
break;
}
if (i >= cbDataTableSize)
{
/* Need to enlarge the table */
cbDataTableSize += 10;
cbDataTable = (dtksh_client_data_t **)
XtRealloc((XtPointer)cbDataTable,
sizeof(dtksh_client_data_t *) * cbDataTableSize);
for (j = i; j < cbDataTableSize; j++)
cbDataTable[j] = NULL;
}
cdata = (dtksh_client_data_t *)XtMalloc(sizeof(dtksh_client_data_t));
if (ksh_cmd)
cdata->ksh_cmd = strdup(ksh_cmd);
else
cdata->ksh_cmd = NULL;
cdata->w = w;
if (cbname)
cdata->cbname = strdup(cbname);
else
cdata->cbname = NULL;
cdata->propAtom = propAtom;
cdata->handle = NULL;
cdata->refCount = 1;
cbDataTable[i] = cdata;
return(cdata);
}
int
LocateCBRecord(
wtab_t *w,
char *cbname,
char *ksh_cmd,
Atom propAtom,
DtWsmCBContext handle )
{
int i;
/* Locate the matching table entry */
for (i = 0; i < cbDataTableSize; i++)
{
if (cbDataTable[i])
{
if ((((cbname == NULL) && (cbDataTable[i]->cbname == NULL)) ||
(((cbname != NULL) && (cbDataTable[i]->cbname != NULL)) &&
(strcmp(cbDataTable[i]->cbname, cbname) == 0))) &&
(cbDataTable[i]->w == w) &&
(strcmp(cbDataTable[i]->ksh_cmd, ksh_cmd) == 0) &&
(cbDataTable[i]->propAtom == propAtom) &&
(cbDataTable[i]->handle == (XtPointer)handle))
{
return(i);
}
}
}
return(-1);
}
/**********************************************/
void
stdEH(
void *widget,
caddr_t clientData,
XEvent *event,
Boolean *continueToDispatch )
{
char buf[128];
dtksh_event_handler_data_t *ehdata;
int i;
Namval_t * np;
Namval_t * np2;
Namfun_t * clonedDisc;
ehdata = (dtksh_event_handler_data_t *)clientData;
nestingLevel++;
np2 = GetNameValuePair("EH_WIDGET");
nv_newattr(np2, 0, 0);
nv_putval(np2, ehdata->w->widid, NV_RDONLY);
nv_newattr(np2, NV_RDONLY, 0);
np = GetNameValuePair("EH_EVENT");
nv_newattr(np, 0, 0);
sprintf(buf, "0x%lx", (long)event);
nv_putval(np, buf, NV_RDONLY);
clonedDisc = CloneDiscipline(&ehDiscipline);
nv_stack(np, clonedDisc);
ksh_eval((char *)ehdata->ksh_cmd);
/* Remove the discipline for the hierarchical variables */
nv_stack(np, NULL);
FreeDiscipline(clonedDisc);
/* Free up all of the name/value pairs we created */
FreeNestedVariables();
nestingLevel--;
}
/*
* For a given widget, if the ksh-cmd is the same as one already
* registered for this widget, then we will merge them into a
* single event handler (by merging the event masks), as is done
* by Xt anyways.
*/
dtksh_event_handler_data_t *
GetNewEHData(
char *ksh_cmd,
wtab_t *w,
EventMask eventMask,
Boolean nonMaskable )
{
dtksh_event_handler_data_t * ehdata;
int i;
int j;
/* Can we merge with an existing entry? */
if ((i = LocateEHRecord (w, ksh_cmd)) >= 0)
{
ehdata = ehDataTable[i];
if (nonMaskable)
ehdata->nonMaskable = True;
ehdata->eventMask |= eventMask;
return(ehdata);
}
/* Look for an open slot */
for (i = 0; i < ehDataTableSize; i++)
{
if (ehDataTable[i] == NULL)
break;
}
if (i >= ehDataTableSize)
{
/* Need to enlarge the table */
ehDataTableSize += 10;
ehDataTable = (dtksh_event_handler_data_t **)
XtRealloc((XtPointer)ehDataTable,
sizeof(dtksh_event_handler_data_t *) * ehDataTableSize);
for (j = i; j < ehDataTableSize; j++)
ehDataTable[j] = NULL;
}
ehdata = (dtksh_event_handler_data_t *)
XtMalloc(sizeof(dtksh_event_handler_data_t));
if (ksh_cmd)
ehdata->ksh_cmd = strdup(ksh_cmd);
else
ehdata->ksh_cmd = NULL;
ehdata->w = w;
ehdata->eventMask = eventMask;
ehdata->nonMaskable = nonMaskable;
ehDataTable[i] = ehdata;
return(ehdata);
}
static int
LocateEHRecord(
wtab_t *w,
char *ksh_cmd )
{
int i;
/* Locate the matching event handler table entry */
for (i = 0; i < ehDataTableSize; i++)
{
if (ehDataTable[i])
{
if ((ehDataTable[i]->w == w) &&
(strcmp(ehDataTable[i]->ksh_cmd, ksh_cmd) == 0))
{
return(i);
}
}
}
return(-1);
}
int
do_DtSessionRestorePath(
int argc,
char *argv[] )
{
wtab_t *w;
char * path;
Boolean status;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,67,
"Usage: DtSessionRestorePath widget pathVariable saveFile"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
status = DtSessionRestorePath(w->w, &path, argv[3]);
if (status)
alt_env_set_var(argv[2], path);
else
alt_env_set_var(argv[2], str_nill);
return (!status);
}
int
do_DtSessionSavePath(
int argc,
char *argv[] )
{
wtab_t *w;
char * path;
char * file;
Boolean status;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,68,
"Usage: DtSessionSavePath widget pathVariable fileVariable"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
status = DtSessionSavePath(w->w, &path, &file);
if (status)
{
env_set_var(argv[2], path);
env_set_var(argv[3], file);
}
else
{
env_blank(argv[2]);
env_blank(argv[3]);
}
return (!status);
}
int
do_DtShellIsIconified(
int argc,
char *argv[] )
{
wtab_t *w;
Boolean status;
Atom actual_type;
int actual_format;
unsigned long nitems;
unsigned long leftover;
WmStateData * wm_state;
Atom wmStateAtom;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,69, "Usage: DtShellIsIconified widget"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
wmStateAtom = XmInternAtom (XtDisplay(w->w), "WM_STATE", False);
/* Getting the WM_STATE property to see if iconified or not */
XGetWindowProperty(XtDisplay(w->w), XtWindow (w->w),
wmStateAtom, 0L, (long) LINESIZE, False,
wmStateAtom, &actual_type, &actual_format,
&nitems, &leftover, (unsigned char **) &wm_state);
return (wm_state->state != IconicState);
}
int
do_DtSetStartupCommand(
int argc,
char *argv[] )
{
wtab_t *w;
Atom commandAtom;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,70,
"Usage: DtSetStartupCommand widget command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
commandAtom = XA_WM_COMMAND;
XChangeProperty(XtDisplay(w->w), XtWindow(w->w), commandAtom,
XA_STRING, 8, PropModeReplace,
(unsigned char *)argv[2], strlen(argv[2])+1);
XSync(XtDisplay(w->w), False);
return(0);
}
/* This only works if the widget is not yet realized */
int
do_DtSetIconifyHint(
int argc,
char *argv[] )
{
wtab_t *w;
Boolean state;
XrmValue fval, tval;
XWMHints *wmhints;
Arg args[5];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,71,
"Usage: DtSetIconifyHint widget boolean"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
state = *((Boolean *)(tval.addr));
else
return(1);
if (state)
{
/* add the iconify hint to the current shell */
XtSetArg(args[0], XmNinitialState, IconicState);
XtSetValues(w->w, args, 1);
}
else
{
/* Remove the iconify hint from the current shell */
wmhints = XGetWMHints(XtDisplay(w->w), XtWindow(w->w));
wmhints->flags |= IconWindowHint;
wmhints->initial_state = NormalState;
XSetWMHints(XtDisplay(w->w), XtWindow(w->w), wmhints);
}
return(0);
}
int
do_DtWsmAddWorkspaceFunctions(
int argc,
char *argv[] )
{
return(WsmCommonProc(argc, argv, (void (*)())DtWsmAddWorkspaceFunctions));
}
int
do_DtWsmRemoveWorkspaceFunctions(
int argc,
char *argv[] )
{
return(WsmCommonProc(argc, argv, (void (*)())DtWsmRemoveWorkspaceFunctions));
}
static int
WsmCommonProc(
int argc,
char *argv[],
void (*func)())
{
wtab_t *w;
Display * display;
Window window;
char * p;
char buf[256];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GetSharedMsg(DT_USAGE_DISPLAY_WINDOW));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
window = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
(*func)(display, window);
return (0);
}
int
do_DtWsmGetCurrentWorkspace(
int argc,
char *argv[] )
{
wtab_t *w;
Display * display;
Window rootWindow;
char * p;
Atom atom;
char buf[256];
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GetSharedMsg(DT_USAGE_DISPLAY_ROOT_VAR));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
env_blank(argv[3]);
return(1);
}
rootWindow = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GETMESSAGE(5,73,
"The rootWindow parameter is invalid: %s"));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
env_blank(argv[3]);
return(1);
}
DtWsmGetCurrentWorkspace(display, rootWindow, &atom);
sprintf(buf, "%ld", (long)atom);
env_set_var(argv[3], buf);
return (0);
}
int
do_DtWsmSetCurrentWorkspace(
int argc,
char *argv[] )
{
wtab_t *w;
char * p;
Atom atom;
Status result;
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,74,
"Usage: DtWsmSetCurrentWorkspace widget atom"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
atom = (Atom)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GETMESSAGE(5,75, "The workspace atom is invalid: %s"));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
result = DtWsmSetCurrentWorkspace(w->w, atom);
if (result == DT_SVC_SUCCESS)
return (0);
else
return (1);
}
static int
GetWorkspaceList(
char *usageMsg,
Boolean getOccupied,
int argc,
char *argv[] )
{
wtab_t *w;
char * p;
Display * display;
Window root;
unsigned long numWS;
Atom * wsList;
char * buf;
char atom[128];
int result;
int i;
char * errmsg;
if (argc != 4)
{
printerrf(str_nill, usageMsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
env_blank(argv[3]);
return(1);
}
root = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
env_blank(argv[3]);
return(1);
}
if (getOccupied)
result = DtWsmGetWorkspacesOccupied(display, root, &wsList, &numWS);
else
result = DtWsmGetWorkspaceList(display, root, &wsList, (int *)&numWS);
if (result == Success)
{
buf = XtMalloc(1);
buf[0] = '\0';
for (i = 0; i < numWS; i++)
{
sprintf(atom, "%ld", (long)wsList[i]);
buf = XtRealloc(buf, strlen(buf) + strlen(atom) + 2);
if (i != 0)
strcat(buf, ",");
strcat(buf, atom);
}
env_set_var(argv[3], buf);
XtFree(buf);
XFree (wsList);
return (0);
}
else
{
env_blank(argv[3]);
return (1);
}
}
int
do_DtWsmGetWorkspaceList(
int argc,
char *argv[] )
{
char * errmsg;
int retVal;
errmsg = strdup(GetSharedMsg(DT_USAGE_DISPLAY_ROOT_VAR));
retVal = GetWorkspaceList(errmsg, False, argc, argv);
free(errmsg);
return(retVal);
}
int
do_DtWsmGetWorkspacesOccupied(
int argc,
char *argv[] )
{
char * errmsg;
int retVal;
errmsg = strdup(GetSharedMsg(DT_USAGE_DISPLAY_WINDOW_VAR));
retVal = GetWorkspaceList(errmsg, True, argc, argv);
free(errmsg);
return(retVal);
}
int
do_DtWsmSetWorkspacesOccupied(
int argc,
char *argv[] )
{
char * p;
Display * display;
Window window;
unsigned long numWS;
Atom * wsList;
char * buf;
int i;
char * nextAtom;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,78,
"Usage: DtWsmSetWorkspacesOccupied display window workspaceList"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
window = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
numWS = 0;
p = argv[3];
/* Strip leading spaces */
while (*p == ' ')
p++;
nextAtom = strtok(p, ",");
wsList = (Atom *)XtMalloc(1);
wsList[0] = '\0';
while (nextAtom)
{
if (strlen(nextAtom) > 0)
{
wsList = (Atom *)XtRealloc((char *)wsList, sizeof(Atom) * (numWS + 1));
wsList[numWS] = atol(nextAtom);
numWS++;
nextAtom = strtok(NULL, ",");
}
}
DtWsmSetWorkspacesOccupied(display, window, wsList, numWS);
XtFree ((char *)wsList);
return (0);
}
int
do_DtWsmGetCurrentBackdropWindow(
int argc,
char *argv[] )
{
char * p;
Display * display;
Window rootWindow, returnedWin;
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GetSharedMsg(DT_USAGE_DISPLAY_ROOT_VAR));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[1], &p, 0);
if (p == argv[1])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
env_blank(argv[3]);
return(1);
}
rootWindow = (Window)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_WINDOW));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
env_blank(argv[3]);
return(1);
}
returnedWin = DtWsmGetCurrentBackdropWindow(display, rootWindow);
if (returnedWin != None)
{
char buf[128];
sprintf(buf, "%d", (int)returnedWin);
env_set_var(argv[3], buf);
return (0);
}
else
{
env_blank(argv[3]);
return (1);
}
}
int
do_DtWsmOccupyAllWorkspaces(
int argc,
char *argv[] )
{
return(WsmCommonProc(argc, argv, (void (*)())DtWsmOccupyAllWorkspaces));
}
int
do__DtGetHourGlassCursor(
int argc,
char *argv[] )
{
char * p;
Display * display;
Cursor cursor;
char buf[128];
char * errmsg;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,79,
"Usage: _DtGetHourGlassCursor variable display"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
display = (Display *)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_DISPLAY));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
alt_env_set_var(argv[1], str_nill);
return(1);
}
cursor = _DtGetHourGlassCursor(display);
sprintf(buf, "%d", cursor);
alt_env_set_var(argv[1], buf);
return (0);
}
static int
DtTurnOnOrOffHourGlass(
void (*func)(),
int argc,
char *argv[] )
{
char * p;
Cursor cursor;
char buf[128];
wtab_t *w;
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GetSharedMsg(DT_USAGE_WIDGET));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == NULL)
return(1);
(*func)(w->w);
return (0);
}
int
do__DtTurnOnHourGlass(
int argc,
char *argv[] )
{
return(DtTurnOnOrOffHourGlass(_DtTurnOnHourGlass, argc, argv));
}
int
do__DtTurnOffHourGlass(
int argc,
char *argv[] )
{
return(DtTurnOnOrOffHourGlass(_DtTurnOffHourGlass, argc, argv));
}
int
do_DtWsmAddCurrentWorkspaceCallback(
int argc,
char **argv )
{
wtab_t *w;
dtksh_client_data_t *cdata;
char * p;
Atom propAtom;
DtWsmCBContext handle;
char buf[128];
char * errmsg;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,80,
"Usage: DtWsmAddCurrentWorkspaceCallback variable widget ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
w = str_to_wtab(argv[0], argv[2]);
if (w == NULL)
{
alt_env_set_var(argv[1], str_nill);
return(1);
}
/* Always force a new entry */
cdata = GetNewCBData(NULL, NULL, NULL, None);
cdata->w = w;
cdata->ksh_cmd = strdup(argv[3]);
handle = DtWsmAddCurrentWorkspaceCallback(w->w,
(DtWsmWsChangeProc)stdWSCB, (XtPointer)cdata);
cdata->handle = (XtPointer)handle;
sprintf(buf, "%ld", (long)handle);
alt_env_set_var(argv[1], buf);
return(0);
}
int
do_DtWsmRemoveWorkspaceCallback(
int argc,
char **argv )
{
char * errmsg, *p;
dtksh_client_data_t *cdata = (dtksh_client_data_t *)NULL;
DtWsmCBContext handle;
int i;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,81,
"Usage: DtWsmRemoveWorkspaceCallback handle"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
handle = (DtWsmCBContext)strtoul(argv[1], &p, 0);
if (p != argv[1])
{
for(i = 0; i < cbDataTableSize; i++)
{
if(cbDataTable[i] != (dtksh_client_data_t *)NULL)
{
if(cbDataTable[i]->handle == handle)
{
cdata = cbDataTable[i];
break;
}
}
}
}
if(cdata == (dtksh_client_data_t *)NULL)
{
errmsg = strdup(GETMESSAGE(5,20,
"The following is an invalid callback handle: %s"));
printerrf(argv[0], errmsg, argv[1], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
return(RemoveOneCallback (argv[0], cdata->w->widid, NULL, cdata->ksh_cmd,
NULL, argv[1]));
}
/*****************************************************************************/
/*****************************************************************************/
int
do_DtDbLoad(
int argc,
char *argv[] )
{
char * errmsg;
if (argc != 1)
{
errmsg = strdup(GETMESSAGE(5,83, "Usage: DtDbLoad"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
DtDbLoad();
return (0);
}
/* Only a single handler is allowed */
static char * reloadNotifyCommand = NULL;
/*
* This is our internal 'ReloadNotify' callback; it simply interprets
* the ksh command specified by the shell script.
*/
static void
DtkReloadHandler(
XtPointer clientData )
{
ksh_eval((char *)reloadNotifyCommand);
}
/*
* This command registers a ksh-command string, which will be executed
* whenever a 'ReloadNotify' message is received. Subsequent calls to
* this command will simply replace the previous ksh-command witht the
* new one.
*/
int
do_DtDbReloadNotify(
int argc,
char *argv[] )
{
char * errmsg;
static Boolean firstTime = True;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,84, "Usage: DtDbReloadNotify ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (firstTime)
{
firstTime = False;
DtDbReloadNotify((DtDbReloadCallbackProc)DtkReloadHandler, NULL);
}
XtFree(reloadNotifyCommand);
reloadNotifyCommand = strdup(argv[1]);
return (0);
}
/*
* This command is a boolean command, which returns 'True' if the
* specified name correlates to a defined action.
*/
int
do_DtActionExists(
int argc,
char *argv[] )
{
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,85, "Usage: DtActionExists actionName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (DtActionExists(argv[1]))
return(0);
return(255);
}
/*
* This command returns the label associated with an action. If the
* action is not defined, or if there is no label, then an empty string
* is returned.
*/
int
do_DtActionLabel(
int argc,
char *argv[] )
{
char * errmsg;
char * label;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,86,
"Usage: DtActionLabel variable actionName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (label = DtActionLabel(argv[2]))
{
alt_env_set_var(argv[1], label);
XtFree(label);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
/*
* This command returns the description associated with an action. If the
* action is not defined, or if there is no description, then an empty string
* is returned.
*/
int
do_DtActionDescription(
int argc,
char *argv[] )
{
char * errmsg;
char * description;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,87,
"Usage: DtActionDescription variable actionName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (description = DtActionDescription(argv[2]))
{
alt_env_set_var(argv[1], description);
XtFree(description);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
static void
_DtActionInvokeUsage( void )
{
char * errmsg;
errmsg = strdup(GETMESSAGE(5,88,
"Usage: DtActionInvoke widget actionName termParms execHost contextDir useIndicator ksh-command [\"FILE\" fileName] ..."));
printerr(str_nill, errmsg, NULL);
free(errmsg);
}
/*
* This command provides the shell script with the mechanism for requesting
* that an action be invoked. It accepts a variable list of arguments,
* which can currently only be of type 'ARG_FILE'.
*/
int
do_DtActionInvoke(
int argc,
char *argv[] )
{
wtab_t *w;
char * termParms = (char *)NULL;
char * execHost = (char *)NULL;
char * contextDir = (char *)NULL;
Boolean useIndicator;
int aac;
DtActionArg *aap = (DtActionArg *)NULL;
XrmValue fval, tval;
int i;
int idx;
int * lockedFds;
/*
* Either there must be no file args (so argc == 8), or if there are
* file args, then there must be 2 components for each argument.
* This check must change when/if we support arguments other than files.
*/
if ((argc < 8) || (((argc - 8) % 2) != 0))
{
_DtActionInvokeUsage();
return(1);
}
w = str_to_wtab(argv[0], argv[1]);
if (w == (wtab_t *)NULL)
return(1);
/* Get true/false value for useIndicator */
fval.addr = argv[6];
fval.size = strlen(argv[6]);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
useIndicator = *((Boolean *)(tval.addr));
else
return(1);
if (argv[3] && (strlen(argv[3]) > 0))
termParms = argv[3];
if (argv[4] && (strlen(argv[4]) > 0))
execHost = argv[4];
if (argv[5] && (strlen(argv[5]) > 0))
contextDir = argv[5];
/*
* Parse the optional file arguments
* This will have to change when/if we support arguments other than files.
*/
if ((aac = (argc - 8) / 2) > 0)
{
aap = (DtActionArg *)XtMalloc(sizeof(DtActionArg) * aac);
for (i = 8; i < argc; i+=2 )
{
if(strcmp(argv[i], "FILE") != 0)
{
_DtActionInvokeUsage();
XtFree((char *)aap);
return(1);
}
idx = (i - 8) / 2;
aap[idx].argClass = DtACTION_FILE;
aap[idx].u.file.name = argv[i + 1];
}
}
/* Force fd above the range reserved by ksh for the user (0 - 9) */
lockedFds = LockKshFileDescriptors();
/*
* Force callback to NULL until we have code in place to support it.
*/
DtActionInvoke(w->w, argv[2], aap, aac, termParms, execHost,
contextDir, useIndicator, NULL,
(XtPointer)NULL);
UnlockKshFileDescriptors(lockedFds);
XtFree((char *)aap);
return (0);
}
/*****************************************************************************/
/*****************************************************************************/
int
do_DtDtsLoadDataTypes(
int argc,
char *argv[] )
{
char * errmsg;
if (argc != 1)
{
errmsg = strdup(GETMESSAGE(5,89, "Usage: DtDtsLoadDataTypes"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
DtDtsLoadDataTypes();
return (0);
}
int
do_DtDtsFileToDataType(
int argc,
char *argv[] )
{
char * errmsg;
char * datatype;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,90,
"Usage: DtDtsFileToDataType variable fileName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (datatype = DtDtsFileToDataType(argv[2]))
{
alt_env_set_var(argv[1], datatype);
DtDtsFreeDataType(datatype);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsFileToAttributeValue(
int argc,
char *argv[] )
{
char * errmsg;
char * attribute;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,91,
"Usage: DtDtsFileToAttributeValue variable fileName attrName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (attribute = DtDtsFileToAttributeValue(argv[2], argv[3]))
{
alt_env_set_var(argv[1], attribute);
DtDtsFreeAttributeValue(attribute);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsFileToAttributeList(
int argc,
char *argv[] )
{
char * errmsg;
char * attributeList;
DtDtsAttribute ** attributes;
int i;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,92,
"Usage: DtDtsFileToAttributeList variable fileName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (attributes = DtDtsFileToAttributeList(argv[2]))
{
attributeList = XtMalloc(1);
attributeList[0] = '\0';
for (i = 0; attributes[i]; i++)
{
attributeList = XtRealloc(attributeList,
strlen(attributeList) +
strlen(attributes[i]->name) + 3);
if (i != 0)
strcat(attributeList, " ");
strcat(attributeList, attributes[i]->name);
}
alt_env_set_var(argv[1], attributeList);
DtDtsFreeAttributeList(attributes);
XtFree(attributeList);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsDataTypeToAttributeValue(
int argc,
char *argv[] )
{
char * errmsg;
char * attribute;
char * optName;
if ((argc != 4) && (argc != 5))
{
errmsg = strdup(GETMESSAGE(5,93,
"Usage: DtDtsDataTypeToAttributeValue variable dataType attrName optName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if ((argc == 4) || (strlen(argv[4]) == 0))
optName = NULL;
else
optName = argv[4];
if (attribute = DtDtsDataTypeToAttributeValue(argv[2], argv[3], optName))
{
alt_env_set_var(argv[1], attribute);
DtDtsFreeAttributeValue(attribute);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsDataTypeToAttributeList(
int argc,
char *argv[] )
{
char * errmsg;
char * attributeList;
DtDtsAttribute ** attributes;
int i;
char * optName;
if ((argc != 3) && (argc != 4))
{
errmsg = strdup(GETMESSAGE(5,94,
"Usage: DtDtsDataTypeToAttributeList variable dataType optName"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if ((argc == 3) || (strlen(argv[3]) == 0))
optName = NULL;
else
optName = argv[3];
if (attributes = DtDtsDataTypeToAttributeList(argv[2], optName))
{
attributeList = XtMalloc(1);
attributeList[0] = '\0';
for (i = 0; attributes[i]; i++)
{
attributeList = XtRealloc(attributeList,
strlen(attributeList) +
strlen(attributes[i]->name) + 3);
if (i != 0)
strcat(attributeList, " ");
strcat(attributeList, attributes[i]->name);
}
alt_env_set_var(argv[1], attributeList);
DtDtsFreeAttributeList(attributes);
XtFree(attributeList);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsFindAttribute(
int argc,
char *argv[] )
{
char * errmsg;
char * dataTypeList;
char ** dataTypes;
int i;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,95,
"Usage: DtDtsFindAttribute variable name value"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (dataTypes = DtDtsFindAttribute(argv[2], argv[3]))
{
dataTypeList = XtMalloc(1);
dataTypeList[0] = '\0';
for (i = 0; dataTypes[i]; i++)
{
dataTypeList = XtRealloc(dataTypeList,
strlen(dataTypeList) +
strlen(dataTypes[i]) + 3);
if (i != 0)
strcat(dataTypeList, " ");
strcat(dataTypeList, dataTypes[i]);
}
alt_env_set_var(argv[1], dataTypeList);
DtDtsFreeDataTypeNames(dataTypes);
XtFree(dataTypeList);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsDataTypeNames(
int argc,
char *argv[] )
{
char * errmsg;
char * dataTypeList;
char ** dataTypes;
int i;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,96, "Usage: DtDtsDataTypeNames variable"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (dataTypes = DtDtsDataTypeNames())
{
dataTypeList = XtMalloc(1);
dataTypeList[0] = '\0';
for (i = 0; dataTypes[i]; i++)
{
dataTypeList = XtRealloc(dataTypeList,
strlen(dataTypeList) +
strlen(dataTypes[i]) + 3);
if (i != 0)
strcat(dataTypeList, " ");
strcat(dataTypeList, dataTypes[i]);
}
alt_env_set_var(argv[1], dataTypeList);
DtDtsFreeDataTypeNames(dataTypes);
XtFree(dataTypeList);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsSetDataType(
int argc,
char *argv[] )
{
char * errmsg;
char * savedDataType;
Boolean override;
if (argc != 5)
{
errmsg = strdup(GETMESSAGE(5,97,
"Usage: DtDtsSetDataType variable fileName dataType override"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
/* Since XtInitialize may not have been called, can't use XtConvert */
if (DtCompareISOLatin1(argv[4], "true"))
override = True;
else if (DtCompareISOLatin1(argv[4], "false"))
override = False;
else
return(1);
if (savedDataType = DtDtsSetDataType(argv[2], argv[3], override))
{
alt_env_set_var(argv[1], savedDataType);
DtDtsFreeDataType(savedDataType);
}
else
alt_env_set_var(argv[1], str_nill);
return (0);
}
int
do_DtDtsDataTypeIsAction(
int argc,
char *argv[] )
{
char * errmsg;
if (argc != 2)
{
errmsg = strdup(GETMESSAGE(5,98,
"Usage: DtDtsDataTypeIsAction dataType"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
if (DtDtsDataTypeIsAction(argv[1]))
return(0);
return(255);
}
/*****************************************************************************/
/*****************************************************************************/
/*
* This command will attempt to open a ToolTalk communications channel.
*/
int
do_ttdt_open(
int argc,
char *argv[] )
{
char * errmsg;
char * procId;
Boolean sendStarted;
XrmValue toVal;
Cardinal nargs;
char * statusString;
char buf[25];
int ttfd;
int * lockedFds;
Tt_status ttStatus;
if (argc != 8)
{
errmsg = strdup(GETMESSAGE(5,99,
"Usage: ttdt_open variable status variable2 toolname vendor version sendStarted"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
/* Convert "true" or "false" to 1 or 0 */
DtkshCvtStringToBool(argv[7], &toVal);
if (toVal.size != 0)
sendStarted = *((Boolean *)(toVal.addr));
else
return(1);
/* Force fd above the range reserved by ksh for the user (0 - 9) */
lockedFds = LockKshFileDescriptors();
procId = ttdt_open(&ttfd, argv[4], argv[5], argv[6], (int)sendStarted);
UnlockKshFileDescriptors(lockedFds);
/* Get the ttStatus and the asssociated string */
ttStatus = tt_ptr_error(procId);
DtkshCvtTtStatusToString(ttStatus, &toVal);
if (toVal.size && toVal.addr)
statusString = toVal.addr;
else
statusString = str_nill;
env_set_var(argv[2], statusString);
if (ttStatus == TT_OK)
env_set_var(argv[1], procId);
else
{
env_set_var(argv[1], str_nill);
ttfd = -1;
}
sprintf(buf, "%d", ttfd);
env_set_var(argv[3], buf);
tt_free(procId);
return (0);
}
/*
* This command is used to close a ToolTalk connection.
*/
int
do_ttdt_close(
int argc,
char *argv[] )
{
char * errmsg;
Boolean sendStopped;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
char * procId;
char * newProcId;
if (argc != 5)
{
errmsg = strdup(GETMESSAGE(5,103,
"Usage: ttdt_close status procId newProcId sendStopped"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[2]) == 0)
procId = NULL;
else
procId = argv[2];
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[3]) == 0)
newProcId = NULL;
else
newProcId = argv[3];
DtkshCvtStringToBool(argv[4], &tval);
if (tval.size != 0)
sendStopped = *((Boolean *)(tval.addr));
else
return(1);
ttStatus = ttdt_close(procId, newProcId, (int)sendStopped);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return (0);
}
/*
* This is the alternate input handler command for ToolTalk. Shell scripts
* will invoke it from their alternate input handlers, passing in all of
* the required parameters. This input handler will cause ToolTalk events
* to be received and dispatched.
*/
int
do_tttk_Xt_input_handler(
int argc,
char *argv[] )
{
char * errmsg;
int source;
XtInputId fid;
char * p;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,100,
"Usage: tttk_Xt_input_handler procId source id"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
source = strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg=strdup(GETMESSAGE(5,101,
"The source parameter must be an integer: %s"));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
fid = strtoul(argv[3], &p, 0);
if (p == argv[3])
{
errmsg = strdup(GETMESSAGE(5,102,
"The id parameter must be a hex number: %s"));
printerrf(argv[0], errmsg, argv[3], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
tttk_Xt_input_handler(argv[1], &source, &fid);
return (0);
}
int
do_ttdt_session_join(
int argc,
char *argv[] )
{
char * errmsg;
Boolean join;
char * sessId;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
char buf[25];
Widget widget;
wtab_t *w;
Tt_pattern * patterns;
if (argc != 6)
{
errmsg = strdup(GETMESSAGE(5,104,
"Usage: ttdt_session_join variable status sessId shellWidgetHandle join"
));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
DtkshCvtStringToBool(argv[5], &tval);
if (tval.size != 0)
join = *((Boolean *)(tval.addr));
else
return(1);
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[3]) == 0)
sessId = NULL;
else
sessId = argv[3];
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[4]) == 0)
widget = NULL;
else
{
w = str_to_wtab(argv[0], argv[4]);
if (w == NULL)
return(1);
widget = w->w;
}
patterns = ttdt_session_join(sessId, NULL, widget, NULL, (int)join);
ttStatus = tt_ptr_error(patterns);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[2], statusString);
if (ttStatus == TT_OK)
{
sprintf(buf, "%ld", (long)patterns);
env_set_var(argv[1], buf);
}
else
env_set_var(argv[1], str_nill);
return (0);
}
int
do_ttdt_session_quit(
int argc,
char *argv[] )
{
char * errmsg;
Boolean quit;
char * sessId;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
Tt_pattern * patterns;
char * p;
if (argc != 5)
{
errmsg = strdup(GETMESSAGE(5,105,
"Usage: ttdt_session_quit status sessId sessPatterns quit"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
DtkshCvtStringToBool(argv[4], &tval);
if (tval.size != 0)
quit = *((Boolean *)(tval.addr));
else
return(1);
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[2]) == 0)
sessId = NULL;
else
sessId = argv[2];
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[3]) == 0)
patterns = NULL;
else
{
patterns = (Tt_pattern *)strtoul(argv[3], &p, 0);
if (p == argv[3])
{
errmsg=strdup(GETMESSAGE(5,106,
"The sessPatterns parameter is invalid: %s"));
printerrf(argv[0], errmsg, argv[3], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
}
ttStatus = ttdt_session_quit(sessId, patterns, (int)quit);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return (0);
}
int
do_ttdt_file_event(
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
Boolean send;
Tt_pattern * patterns;
Tttk_op op;
char * p;
if (argc != 5)
{
errmsg = strdup(GETMESSAGE(5,107,
"Usage: ttdt_file_event status op patterns send"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, "TtOp", &tval); /* XXX */
if (tval.size != 0)
op = *((Tttk_op *)(tval.addr));
else
return(1);
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[3]) == 0)
patterns = NULL;
else
{
patterns = (Tt_pattern *)strtoul(argv[3], &p, 0);
if (p == argv[3])
{
errmsg = strdup(GetSharedMsg(DT_BAD_PATTERN));
printerrf(argv[0], errmsg, argv[3], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
}
DtkshCvtStringToBool(argv[4], &tval);
if (tval.size != 0)
send = *((Boolean *)(tval.addr));
else
return(1);
ttStatus = ttdt_file_event(NULL, op, patterns, (int)send);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return (0);
}
/*
* This is the internal callback invoked by tooltalk, whenever a message
* is received for a file the user joined (using ttdt_file_join). We
* need to set up some environment variables, and then interpret the
* ksh-cmd supplied by the shell script.
*/
static Tt_message
TtFileCB(
Tt_message msg,
Tttk_op op,
char * pathName,
void * clientData,
int sameEuidEgid,
int sameProcId )
{
Ttdt_file_cb_data *cdata = (Ttdt_file_cb_data *)clientData;
int results;
char strBuf[25];
Namval_t * msgVar;
Namval_t * opVar;
Namval_t * pathVar;
Namval_t * sameProcVar;
Namval_t * sameEuidVar;
XrmValue fval, tval;
int ttmark = tt_mark();;
/* Initialize the environment variables */
msgVar = nv_search("DT_TT_MSG", sh.var_tree, NV_ADD);
sprintf(strBuf, "%ld", (long)msg);
nv_putval(msgVar, strBuf, NV_RDONLY);
opVar = nv_search("DT_TT_OP", sh.var_tree, NV_ADD);
fval.addr = (caddr_t)&op;
fval.size = sizeof(op);
XtConvert(Toplevel, "TtOp", &fval, XtRString, &tval); /* XXX?? */
if (tval.size && tval.addr)
nv_putval(opVar, (char *)tval.addr, NV_RDONLY);
else
nv_putval(opVar, str_nill, NV_RDONLY);
pathVar = nv_search("DT_TT_PATHNAME", sh.var_tree, NV_ADD);
nv_putval(pathVar, pathName, NV_RDONLY);
sameProcVar = nv_search("DT_TT_SAME_PROCID", sh.var_tree, NV_ADD);
if (sameProcId)
nv_putval(sameProcVar, "True", NV_RDONLY);
else
nv_putval(sameProcVar, "False", NV_RDONLY);
sameEuidVar = nv_search("DT_TT_SAME_EUID_EGID", sh.var_tree, NV_ADD);
if (sameProcId)
nv_putval(sameEuidVar, "True", NV_RDONLY);
else
nv_putval(sameEuidVar, "False", NV_RDONLY);
/* Interpret the registered command */
results = ksh_eval((char *)cdata->ksh_cmd);
/* Clean up the environment variables */
nv_newattr(msgVar, 0, 0);
nv_close(msgVar);
nv_newattr(opVar, 0, 0);
nv_close(opVar);
nv_newattr(pathVar, 0, 0);
nv_close(pathVar);
nv_newattr(sameProcVar, 0, 0);
nv_close(sameProcVar);
nv_newattr(sameEuidVar, 0, 0);
nv_close(sameEuidVar);
tt_release(ttmark);
return((Tt_message)results);
}
int
do_ttdt_file_join(
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
Boolean join;
Tt_scope scope;
Tt_pattern * patterns;
Ttdt_file_cb_data * cData;
char buf[30];
int i, j;
if (argc != 7)
{
errmsg = strdup(GETMESSAGE(5,115,
"Usage: ttdt_file_join variable status pathName scope join ksh-command"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
DtkshCvtStringToBool(argv[5], &tval);
if (tval.size != 0)
join = *((Boolean *)(tval.addr));
else
return(1);
fval.addr = argv[4];
fval.size = strlen(argv[4]);
XtConvert(Toplevel, XtRString, &fval, "TtScope", &tval); /* XXX ??? */
if (tval.size != 0)
scope = *((Tt_scope *)(tval.addr));
else
return(1);
cData = (Ttdt_file_cb_data *)XtMalloc(sizeof(Ttdt_file_cb_data));
patterns = ttdt_file_join(argv[3], scope, (int)join, TtFileCB, cData);
ttStatus = tt_ptr_error(patterns);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[2], statusString);
/*
* If the request failed, then no callback was added, so we can free
* up the client data; otherwise, we need to finish filling in the
* client data, and then saving it in our storage array, so that we
* can later free it when ttdt_file_quit() is called.
*/
if (ttStatus == TT_OK)
{
sprintf(buf, "%ld", (long)patterns);
env_set_var(argv[1], buf);
cData->ksh_cmd = strdup(argv[6]);
cData->patterns = patterns;
/* Add clientData to our storage array */
for (i = 0; i < sizeFileCBList; i++)
{
if (fileCBList[i] == NULL)
break;
}
if (i >= sizeFileCBList)
{
/* Grow the array */
sizeFileCBList += 10;
fileCBList = (Ttdt_file_cb_data **)XtRealloc((char *)fileCBList,
sizeof(Ttdt_file_cb_data *) * sizeFileCBList);
for (j = i; j < sizeFileCBList; j++)
fileCBList[j] = NULL;
}
fileCBList[i] = cData;
}
else
{
XtFree((char *)cData);
env_set_var(argv[1], str_nill);
}
return (0);
}
int
do_ttdt_file_quit(
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
Boolean quit;
Tt_pattern * patterns;
char * p;
int i;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,108,
"Usage: ttdt_file_quit status patterns quit"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[2]) == 0)
patterns = NULL;
else
{
patterns = (Tt_pattern *)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_PATTERN));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
}
DtkshCvtStringToBool(argv[3], &tval);
if (tval.size != 0)
quit = *((Boolean *)(tval.addr));
else
return(1);
ttStatus = ttdt_file_quit(patterns, (int)quit);
/* Remove this entry from our list of file callbacks */
for (i = 0; i < sizeFileCBList; i++)
{
if (fileCBList[i] && (fileCBList[i]->patterns == patterns))
{
XtFree(fileCBList[i]->ksh_cmd);
XtFree((char *)fileCBList[i]);
fileCBList[i] = NULL;
break;
}
}
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return (0);
}
int
do_ttdt_Get_Modified(
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_scope scope;
int timeout;
char * p;
if (argc != 4)
{
errmsg = strdup(GETMESSAGE(5,109,
"Usage: ttdt_Get_Modified pathName scope timeout"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
fval.addr = argv[2];
fval.size = strlen(argv[2]);
XtConvert(Toplevel, XtRString, &fval, "TtScope", &tval); /* XXX ?? */
if (tval.size != 0)
scope = *((Tt_scope *)(tval.addr));
else
return(1);
timeout = strtoul(argv[3], &p, 0);
if (p == argv[3])
{
errmsg = strdup(GetSharedMsg(DT_BAD_TIMEOUT));
printerrf(argv[0], errmsg, argv[3], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
if (ttdt_Get_Modified(NULL, argv[1], scope,
XtWidgetToApplicationContext(Toplevel), timeout))
{
return(0);
}
return(255);
}
/*
* Common function for ttdt_Save and ttdt_Revert commands.
*/
static int
ttdt_SaveOrRevert(
Tt_status (*func)(),
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_scope scope;
int timeout;
char * p;
Tt_status ttStatus;
char * statusString;
if (argc != 5)
{
errmsg = strdup(GETMESSAGE(5,110,
"Usage: %s status pathName scope timeout"));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
fval.addr = argv[3];
fval.size = strlen(argv[3]);
XtConvert(Toplevel, XtRString, &fval, "TtScope", &tval); /* XXX ?? */
if (tval.size != 0)
scope = *((Tt_scope *)(tval.addr));
else
return(1);
timeout = strtoul(argv[4], &p, 0);
if (p == argv[4])
{
errmsg = strdup(GetSharedMsg(DT_BAD_TIMEOUT));
printerrf(argv[0], errmsg, argv[4], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
ttStatus = (*func)(NULL, argv[2], scope,
XtWidgetToApplicationContext(Toplevel), timeout);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return(0);
}
int
do_ttdt_Save(
int argc,
char *argv[] )
{
return(ttdt_SaveOrRevert(ttdt_Save, argc, argv ));
}
int
do_ttdt_Revert(
int argc,
char *argv[] )
{
return(ttdt_SaveOrRevert(ttdt_Revert, argc, argv ));
}
int
do_tt_error_pointer(
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_status ttStatus;
void * errPtr;
char buf[25];
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,112,
"Usage: tt_error_pointer variable ttStatus"));
printerr(str_nill, errmsg, NULL);
free(errmsg);
return(1);
}
/* Map the string into a ttStatus */
DtkshCvtStringToTtStatus(argv[2], &tval);
if (tval.size != 0)
ttStatus = *((Tt_status *)(tval.addr));
else
return(1);
errPtr = tt_error_pointer(ttStatus);
sprintf(buf, "%ld", (long)errPtr);
alt_env_set_var(argv[1], buf);
return (0);
}
static int
message_DestroyOrReply(
Tt_status (*func)(),
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
Tt_message message;
char * p;
if (argc != 3)
{
errmsg = strdup(GETMESSAGE(5,113, "Usage: %s status msg"));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
message = (Tt_message)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_MESSAGE));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
ttStatus = (*func)(message);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return (0);
}
int
do_tttk_message_destroy(
int argc,
char *argv[] )
{
return(message_DestroyOrReply(tttk_message_destroy, argc, argv));
}
int
do_tt_message_reply(
int argc,
char *argv[] )
{
return(message_DestroyOrReply(tt_message_reply, argc, argv));
}
static int
message_FailOrReject(
Tt_status (*func)(),
int argc,
char *argv[] )
{
char * errmsg;
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
Tt_message message;
char * msgStatusString;
Boolean destroy;
char * p;
if (argc != 6)
{
errmsg = strdup(GETMESSAGE(5,114,
"Usage: %s status msg msgStatus msgStatusString destroy"));
printerrf(str_nill, errmsg, argv[0], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
message = (Tt_message)strtoul(argv[2], &p, 0);
if (p == argv[2])
{
errmsg = strdup(GetSharedMsg(DT_BAD_MESSAGE));
printerrf(argv[0], errmsg, argv[2], NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
free(errmsg);
return(1);
}
/* Map the string into a ttStatus */
DtkshCvtStringToTtStatus(argv[3], &tval);
if (tval.size != 0)
ttStatus = *((Tt_status *)(tval.addr));
else
return(1);
/* Need to treat "" equal to a NULL pointer here */
if (strlen(argv[4]) == 0)
msgStatusString = NULL;
else
msgStatusString = argv[4];
/* Convert the boolean value */
DtkshCvtStringToBool(argv[5], &tval);
if (tval.size != 0)
destroy = *((Boolean *)(tval.addr));
else
return(1);
ttStatus = (*func)(message, ttStatus, msgStatusString, destroy);
/* Map the ttStatus into a string */
DtkshCvtTtStatusToString(ttStatus, &tval);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[1], statusString);
return (0);
}
int
do_tttk_message_reject(
int argc,
char *argv[] )
{
return(message_FailOrReject(tttk_message_reject, argc, argv));
}
int
do_tttk_message_fail(
int argc,
char *argv[] )
{
return(message_FailOrReject(tttk_message_fail, argc, argv));
}
static int
tt_netfile_handler(
int paramCount,
char * (*func)(),
char * usageMsg,
int argc,
char *argv[] )
{
XrmValue fval, tval;
Tt_status ttStatus;
char * statusString;
char * convertedName;
Cardinal cargc;
XrmValue cargv[1];
if (argc != paramCount)
{
printerr(str_nill, usageMsg, NULL);
return(1);
}
if (paramCount == 4)
convertedName = (char *)(*func)(argv[3]);
else
convertedName = (char *)(*func)(argv[3], argv[4]);
/*
* Map the ttStatus into a string. Note that we can't call the XtConvert
* function, since a shell script may not have called XtInitialize.
*/
ttStatus = tt_ptr_error(convertedName);
DtkshCvtTtStatusToString(ttStatus, &tval);
if (ttStatus == TT_OK)
env_set_var(argv[1], convertedName);
else
env_set_var(argv[1], str_nill);
if (tval.size && tval.addr)
statusString = tval.addr;
else
statusString = str_nill;
env_set_var(argv[2], statusString);
tt_free(convertedName);
return (0);
}
int
do_tt_file_netfile(
int argc,
char *argv[] )
{
char * usageMsg;
int results;
usageMsg = strdup(GETMESSAGE(5,116,
"Usage: tt_file_netfile variable status filename"));
results = tt_netfile_handler(4, tt_file_netfile, usageMsg, argc, argv);
XtFree(usageMsg);
return(results);
}
int
do_tt_netfile_file(
int argc,
char *argv[] )
{
char * usageMsg;
int results;
usageMsg = strdup(GETMESSAGE(5,117,
"Usage: tt_netfile_file variable status netfilename"));
results = tt_netfile_handler(4, tt_netfile_file, usageMsg, argc, argv);
XtFree(usageMsg);
return(results);
}
int
do_tt_host_file_netfile(
int argc,
char *argv[] )
{
char * usageMsg;
int results;
usageMsg = strdup(GETMESSAGE(5,118,
"Usage: tt_host_file_netfile variable status host filename"));
results = tt_netfile_handler(5, tt_host_file_netfile, usageMsg, argc, argv);
XtFree(usageMsg);
return(results);
}
int
do_tt_host_netfile_file(
int argc,
char *argv[] )
{
char * usageMsg;
int results;
usageMsg = strdup(GETMESSAGE(5,119,
"Usage: tt_host_netfile_file variable status host netfilename"));
results = tt_netfile_handler(5, tt_host_netfile_file, usageMsg, argc, argv);
XtFree(usageMsg);
return(results);
}
/*****************************************************************************/
/*****************************************************************************/
/*
* Starting with the class of the widget, check to see if it defines the
* indicated callback; if not, then keep checking its superclasses.
*/
static Namdisc_t *
CheckClassDisciplines(
WidgetClass class,
char *cbname )
{
int i = 0;
int j = 0;
while (C[i].cname)
{
if (C[i].class == class)
{
if (C[i].disciplines)
{
while(C[i].disciplines[j].callbackName)
{
if (strcmp(cbname, C[i].disciplines[j].callbackName) == 0)
return(C[i].disciplines[j].discipline);
j++;
}
}
}
i++;
}
return(NULL);
}
/*****************************************************************************/
/*****************************************************************************/
/*
* The following collection of functions deal with handling the dynamic
* setting of an environment variable, when referenced by the shell script.
* All of the environment variables are based off of the CB_CALL_DATA
* environment variable, which is set before the shell script's callback
* is invoked. After the shell script's callback returns, any dynamically
* created environment variable are removed; thus, the scope is only
* within the context of the callback.
*
* If the shell script attempts to reference a subfield of the CB_CALL_DATA,
* and if the parent has not yet been reference, then the 'name' passed to
* the discipline function will contain all of the previously unreferenced
* portions of the environment variable name. As an example, if the shell
* script referenced ${CB_CALL_DATA.EVENT.TYPE} , and the "EVENT" portion
* has not yet been referenced, then the incoming name will be "EVENT.TYPE".
* This is why all of the discipline functions below use "strtok()"; this
* allows us to break up the name into each token, and to then initialize
* the token. Any unrecognized tokens are set to the string "". In the
* above example, a new name/value pair will be created for both the
* "EVENT" and the "TYPE" portions, and the returned name/value pair will
* be for the "TYPE" portion, since it was the terminal portion of the
* reference.
*/
static struct named_integer CallbackReasons[] = {
{ "CR_NONE", XmCR_NONE },
{ "CR_HELP", XmCR_HELP },
{ "CR_VALUE_CHANGED", XmCR_VALUE_CHANGED },
{ "CR_INCREMENT", XmCR_INCREMENT },
{ "CR_DECREMENT", XmCR_DECREMENT },
{ "CR_PAGE_INCREMENT", XmCR_PAGE_INCREMENT },
{ "CR_PAGE_DECREMENT", XmCR_PAGE_DECREMENT },
{ "CR_TO_TOP", XmCR_TO_TOP },
{ "CR_TO_BOTTOM", XmCR_TO_BOTTOM },
{ "CR_DRAG", XmCR_DRAG },
{ "CR_ACTIVATE", XmCR_ACTIVATE },
{ "CR_ARM", XmCR_ARM },
{ "CR_DISARM", XmCR_DISARM },
{ "CR_MAP", XmCR_MAP },
{ "CR_UNMAP", XmCR_UNMAP },
{ "CR_FOCUS", XmCR_FOCUS },
{ "CR_LOSING_FOCUS", XmCR_LOSING_FOCUS },
{ "CR_MODIFYING_TEXT_VALUE", XmCR_MODIFYING_TEXT_VALUE },
{ "CR_MOVING_INSERT_CURSOR", XmCR_MOVING_INSERT_CURSOR },
{ "CR_EXECUTE", XmCR_EXECUTE },
{ "CR_SINGLE_SELECT", XmCR_SINGLE_SELECT },
{ "CR_MULTIPLE_SELECT", XmCR_MULTIPLE_SELECT },
{ "CR_EXTENDED_SELECT", XmCR_EXTENDED_SELECT },
{ "CR_BROWSE_SELECT", XmCR_BROWSE_SELECT },
{ "CR_DEFAULT_ACTION", XmCR_DEFAULT_ACTION },
{ "CR_CLIPBOARD_DATA_REQUEST", XmCR_CLIPBOARD_DATA_REQUEST },
{ "CR_CLIPBOARD_DATA_DELETE", XmCR_CLIPBOARD_DATA_DELETE },
{ "CR_CASCADING", XmCR_CASCADING },
{ "CR_OK", XmCR_OK },
{ "CR_CANCEL", XmCR_CANCEL },
{ "CR_APPLY", XmCR_APPLY },
{ "CR_NO_MATCH", XmCR_NO_MATCH },
{ "CR_COMMAND_ENTERED", XmCR_COMMAND_ENTERED },
{ "CR_COMMAND_CHANGED", XmCR_COMMAND_CHANGED },
{ "CR_EXPOSE", XmCR_EXPOSE },
{ "CR_RESIZE", XmCR_RESIZE },
{ "CR_INPUT", XmCR_INPUT },
{ "CR_GAIN_PRIMARY", XmCR_GAIN_PRIMARY },
{ "CR_LOSE_PRIMARY", XmCR_LOSE_PRIMARY },
{ "CR_CREATE", XmCR_CREATE },
{ "CR_TEAR_OFF_ACTIVATE", XmCR_TEAR_OFF_ACTIVATE },
{ "CR_TEAR_OFF_DEACTIVATE", XmCR_TEAR_OFF_DEACTIVATE },
{ "CR_OBSCURED_TRAVERSAL", XmCR_OBSCURED_TRAVERSAL },
{ "CR_PROTOCOLS", 6666 },
{ NULL, NULL },
};
static struct named_integer HelpCallbackReasons[] = {
{ "HELP_CR_CLOSE", DtCR_HELP_CLOSE },
{ "HELP_CR_LINK_ACTIVATE", DtCR_HELP_LINK_ACTIVATE },
{ NULL, NULL },
};
/*
* Create a new name/value pair (if necessary), and add it to the list of
* name/value pairs which must be cleaned up when we are done.
*/
Namval_t *
GetNameValuePair(
char *name )
{
Namval_t * np2;
Namval_t** list;
int i;
if (((np2 = nv_search(name, sh.var_tree, 0)) == NULL) ||
(nestingLevel == 0))
{
/* Add to the list only the first time referenced */
if (nestingLevel + 1 > npTableSize)
{
npTable = (Namval_t ***)XtRealloc((char *)npTable,
sizeof(Namval_t **) * (nestingLevel+1));
npListSizes = (int *)XtRealloc((char *)npListSizes,
sizeof(int) * (nestingLevel+1));
for (i = npTableSize; i < (nestingLevel + 1); i++)
{
npTable[i] = NULL;
npListSizes[i] = 0;
}
npTableSize = nestingLevel + 1;
}
np2 = nv_search(name, sh.var_tree, NV_ADD);
(npListSizes[nestingLevel])++;
list = npTable[nestingLevel] = (Namval_t **)XtRealloc(
(char *)npTable[nestingLevel],
sizeof(Namval_t *) * npListSizes[nestingLevel]);
list[npListSizes[nestingLevel] - 1] = np2;
/*
* I _think_ this works OK, because I _think_ the subshell code will
* automatically clean up the "extra" Namval_t it might create here.
* As long as we clean up the original, I don't think we leak here.
*/
if(sh.subshell)
np2 = sh_assignok(np2, 1);
}
return(np2);
}
/*
* Free only those environment variables created at this nesting level.
*/
void
FreeNestedVariables( void )
{
Namval_t** list;
int i;
if ((nestingLevel < 0) || (nestingLevel >= npTableSize))
return;
list = npTable[nestingLevel];
for (i = 0; i < npListSizes[nestingLevel]; i++)
{
nv_newattr(list[i], 0, 0);
nv_stack(list[i], NULL);
nv_close(list[i]);
}
XtFree((char *)list);
npTable[nestingLevel] = NULL;
npListSizes[nestingLevel] = 0;
}
/*
* Create an empty name/value pair.
* THIS FUNCTION ASSUMES THAT THE CALLER HAS DONE THE INITIAL strtok()
* CALL, SO THAT WE CAN DO THE REMAINING ONES, TO INITIALIZE ALL REMAINING
* TOKENS.
*/
static Namval_t *
CreateEmptyNameValuePair(
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
np2 = GetNameValuePair(name);
buf[0] = '\0';
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
return(CreateEmptyNameValuePair(np, name, fp));
else
return(np2);
}
static Namval_t *
ProcessIntValue(
int value,
Namval_t *np,
char *name,
Namfun_t *fp,
char *format,
Namfun_t *fp_new)
{
Namval_t * np2;
char buf[128];
np2 = GetNameValuePair(name);
sprintf(buf, format, value);
nv_stack(np2, NULL);
nv_putval(np2, buf, NV_RDONLY);
if (fp_new)
nv_stack(np2, fp_new);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessStringValue(
char *value,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
np2 = GetNameValuePair(name);
if (value)
nv_putval(np2, value, NV_RDONLY);
else
nv_putval(np2, str_nill, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessBooleanIntValue(
int value,
Namval_t *np,
char *name,
Namfun_t *fp,
Namfun_t *fp_new )
{
Namval_t * np2;
char buf[128];
np2 = GetNameValuePair(name);
if (value)
strcpy(buf, "true");
else
strcpy(buf, "false");
/*
* Any old disciplies MUST be cleared, before setting value. If this
* is not done, then excessive looping occurs, and the value will not
* be correct, the next time you retrieve it.
*/
nv_stack(np2, NULL);
nv_putval(np2, buf, NV_RDONLY);
if (fp_new)
nv_stack(np2, fp_new);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessTraversalDirection(
XmTraversalDirection dir,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
XrmValue f, t;
char * value;
np2 = GetNameValuePair(name);
f.addr = (caddr_t)&dir;
f.size = sizeof(XmTraversalDirection);
t.addr = NULL;
t.size = 0;
XtConvert(Toplevel, "TraversalDirection", &f, XtRString, &t);
if (t.size && t.addr)
value = t.addr;
else
value = str_nill;
strcpy(buf, value);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessSelectionType(
char selType,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
XrmValue f, t;
char * value;
int tmpSelType = (int)selType;
np2 = GetNameValuePair(name);
f.addr = (caddr_t)&tmpSelType;
f.size = sizeof(int);
t.addr = NULL;
t.size = 0;
XtConvert(Toplevel, "ListSelectionType", &f, XtRString, &t);
if (t.size && t.addr)
value = t.addr;
else
value = str_nill;
strcpy(buf, value);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessIntTable(
int *table,
int count,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char * buf;
char buf2[25];
int i;
buf = XtMalloc(1);
buf[0] = '\0';
np2 = GetNameValuePair(name);
if (count > 0)
{
for (i = 0; i < count; i++)
{
sprintf(buf2, "%d", table[i]);
buf = XtRealloc(buf, strlen(buf) + strlen(buf2) + (i == 0 ? 1 : 2));
if (i != 0)
strcat(buf, ",");
strcat(buf, buf2);
}
}
nv_putval(np2, buf, NV_RDONLY);
XtFree (buf);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessXmStringTable(
XmString *table,
int count,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char * buf;
int i;
np2 = GetNameValuePair(name);
buf = _CvtXmStringTableToString(table, count);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessWidgetHandle(
Widget handle,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
wtab_t * w;
np2 = GetNameValuePair(name);
w = widget_to_wtab(handle);
strcpy(buf, w ? w->widid : "Unknown");
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessXmStringValue(
XmString xmstring,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
wtab_t * w;
char * value;
np2 = GetNameValuePair(name);
if ((value = XmStringToString(xmstring)) == NULL)
value = str_nill;
nv_putval(np2, value, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessHyperType(
int hyperType,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
wtab_t * w;
XrmValue f, t;
char * value;
np2 = GetNameValuePair(name);
f.addr = (caddr_t)&hyperType;
f.size = sizeof(long);
t.addr = NULL;
t.size = 0;
XtConvert(Toplevel, "HelpHyperType", &f, XtRString, &t);
if (t.addr)
value = t.addr;
else
value = str_nill;
strcpy(buf, value);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static XEventTable eventTable[] = {
{"XANY", NULL},
{"XBUTTON", NULL},
{"XEXPOSE", NULL},
{"XNOEXPOSE", NULL},
{"XGRAPHICSEXPOSE", NULL},
{"XKEY", NULL},
{"XMOTION", NULL},
{NULL, NULL},
};
static EventEntryTable xanyTable[] = {
{"TYPE", "XE_EventType", XtOffsetOf(XEvent, xany.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xany.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xany.send_event),
sizeof(Boolean)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xany.display),
sizeof(Display *)},
{"WINDOW", "XE_Window", XtOffsetOf(XEvent, xany.window),
sizeof(Window)},
{NULL, NULL, 0, 0},
};
static EventEntryTable xbuttonTable[] = {
{"TYPE", "XE_EventType", XtOffsetOf(XEvent, xbutton.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xbutton.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xbutton.send_event),
sizeof(Bool)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xbutton.display),
sizeof(Display *)},
{"WINDOW", "XE_Window", XtOffsetOf(XEvent, xbutton.window),
sizeof(Window)},
{"ROOT", "XE_Window", XtOffsetOf(XEvent, xbutton.root),
sizeof(Window)},
{"SUBWINDOW", "XE_Window", XtOffsetOf(XEvent, xbutton.subwindow),
sizeof(Window)},
{"TIME", "XE_IntValue", XtOffsetOf(XEvent, xbutton.time),
sizeof(unsigned int)},
{"X", "XE_IntValue", XtOffsetOf(XEvent, xbutton.x),
sizeof(int)},
{"Y", "XE_IntValue", XtOffsetOf(XEvent, xbutton.y),
sizeof(int)},
{"X_ROOT", "XE_IntValue", XtOffsetOf(XEvent, xbutton.x_root),
sizeof(int)},
{"Y_ROOT", "XE_IntValue", XtOffsetOf(XEvent, xbutton.y_root),
sizeof(int)},
{"STATE", "XE_ModifierState", XtOffsetOf(XEvent, xbutton.state),
sizeof(unsigned int)},
{"BUTTON", "XE_Button", XtOffsetOf(XEvent, xbutton.button),
sizeof(unsigned int)},
{"SAME_SCREEN", "X_Bool", XtOffsetOf(XEvent, xbutton.same_screen),
sizeof(Bool)},
{NULL, NULL, 0, 0},
};
static EventEntryTable xexposeTable[] = {
{"TYPE", "XE_EventType", XtOffsetOf(XEvent, xexpose.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xexpose.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xexpose.send_event),
sizeof(Bool)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xexpose.display),
sizeof(Display *)},
{"WINDOW", "XE_Window", XtOffsetOf(XEvent, xexpose.window),
sizeof(Window)},
{"X", "XE_IntValue", XtOffsetOf(XEvent, xexpose.x),
sizeof(int)},
{"Y", "XE_IntValue", XtOffsetOf(XEvent, xexpose.y),
sizeof(int)},
{"WIDTH", "XE_IntValue", XtOffsetOf(XEvent, xexpose.width),
sizeof(int)},
{"HEIGHT", "XE_IntValue", XtOffsetOf(XEvent, xexpose.height),
sizeof(int)},
{"COUNT", "XE_IntValue", XtOffsetOf(XEvent, xexpose.count),
sizeof(int)},
{NULL, NULL, 0, 0},
};
static EventEntryTable xnoExposeTable[] = {
{"TYPE", "XE_EventType", XtOffsetOf(XEvent, xnoexpose.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xnoexpose.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xnoexpose.send_event),
sizeof(Bool)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xnoexpose.display),
sizeof(Display *)},
{"DRAWABLE", "XE_Window", XtOffsetOf(XEvent, xnoexpose.drawable),
sizeof(Window)},
{"MAJOR_CODE", "XE_IntValue", XtOffsetOf(XEvent, xnoexpose.major_code),
sizeof(int)},
{"MINOR_CODE", "XE_IntValue", XtOffsetOf(XEvent, xnoexpose.minor_code),
sizeof(int)},
{NULL, NULL, 0, 0},
};
static EventEntryTable xgraphicsExposeTable[] = {
{"TYPE", "XE_EventType",
XtOffsetOf(XEvent, xgraphicsexpose.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xgraphicsexpose.send_event),
sizeof(Bool)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xgraphicsexpose.display),
sizeof(Display *)},
{"DRAWABLE", "XE_Window", XtOffsetOf(XEvent, xgraphicsexpose.drawable),
sizeof(Window)},
{"X", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.x),
sizeof(int)},
{"Y", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.y),
sizeof(int)},
{"WIDTH", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.width),
sizeof(int)},
{"HEIGHT", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.height),
sizeof(int)},
{"COUNT", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.count),
sizeof(int)},
{"MAJOR_CODE", "XE_IntValue",
XtOffsetOf(XEvent, xgraphicsexpose.major_code),
sizeof(int)},
{"MINOR_CODE", "XE_IntValue", XtOffsetOf(XEvent, xgraphicsexpose.minor_code),
sizeof(int)},
{NULL, NULL, 0, 0},
};
static EventEntryTable xkeyTable[] = {
{"TYPE", "XE_EventType", XtOffsetOf(XEvent, xkey.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xkey.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xkey.send_event),
sizeof(Bool)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xkey.display),
sizeof(Display *)},
{"WINDOW", "XE_Window", XtOffsetOf(XEvent, xkey.window),
sizeof(Window)},
{"ROOT", "XE_Window", XtOffsetOf(XEvent, xkey.root),
sizeof(Window)},
{"SUBWINDOW", "XE_Window", XtOffsetOf(XEvent, xkey.subwindow),
sizeof(Window)},
{"TIME", "XE_IntValue", XtOffsetOf(XEvent, xkey.time),
sizeof(unsigned int)},
{"X", "XE_IntValue", XtOffsetOf(XEvent, xkey.x),
sizeof(int)},
{"Y", "XE_IntValue", XtOffsetOf(XEvent, xkey.y),
sizeof(int)},
{"X_ROOT", "XE_IntValue", XtOffsetOf(XEvent, xkey.x_root),
sizeof(int)},
{"Y_ROOT", "XE_IntValue", XtOffsetOf(XEvent, xkey.y_root),
sizeof(int)},
{"STATE", "XE_ModifierState", XtOffsetOf(XEvent, xkey.state),
sizeof(unsigned int)},
{"KEYCODE", "XE_IntValue", XtOffsetOf(XEvent, xkey.keycode),
sizeof(unsigned int)},
{"SAME_SCREEN", "X_Bool", XtOffsetOf(XEvent, xkey.same_screen),
sizeof(Bool)},
{NULL, NULL, 0, 0},
};
static EventEntryTable xmotionTable[] = {
{"TYPE", "XE_EventType", XtOffsetOf(XEvent, xmotion.type), sizeof(int)},
{"SERIAL", "XE_IntValue", XtOffsetOf(XEvent, xmotion.serial),
sizeof(unsigned long)},
{"SEND_EVENT", "X_Bool", XtOffsetOf(XEvent, xmotion.send_event),
sizeof(Bool)},
{"DISPLAY", "XE_HexValue", XtOffsetOf(XEvent, xmotion.display),
sizeof(Display *)},
{"WINDOW", "XE_Window", XtOffsetOf(XEvent, xmotion.window),
sizeof(Window)},
{"ROOT", "XE_Window", XtOffsetOf(XEvent, xmotion.root),
sizeof(Window)},
{"SUBWINDOW", "XE_Window", XtOffsetOf(XEvent, xmotion.subwindow),
sizeof(Window)},
{"TIME", "XE_IntValue", XtOffsetOf(XEvent, xmotion.time),
sizeof(unsigned int)},
{"X", "XE_IntValue", XtOffsetOf(XEvent, xmotion.x),
sizeof(int)},
{"Y", "XE_IntValue", XtOffsetOf(XEvent, xmotion.y),
sizeof(int)},
{"X_ROOT", "XE_IntValue", XtOffsetOf(XEvent, xmotion.x_root),
sizeof(int)},
{"Y_ROOT", "XE_IntValue", XtOffsetOf(XEvent, xmotion.y_root),
sizeof(int)},
{"STATE", "XE_ModifierState", XtOffsetOf(XEvent, xmotion.state),
sizeof(unsigned int)},
{"IS_HINT", "XE_MotionHint", XtOffsetOf(XEvent, xmotion.is_hint),
sizeof(char)},
{"SAME_SCREEN", "X_Bool", XtOffsetOf(XEvent, xmotion.same_screen),
sizeof(Bool)},
{NULL, NULL, 0, 0},
};
/*
* The order in which the structures are initialized IS important; they
* must be done in the same order as they are defined in the eventTable
* structure.
*/
static void
InitEventTables( void )
{
int i = 0;
eventTable[i++].table = xanyTable;
eventTable[i++].table = xbuttonTable;
eventTable[i++].table = xexposeTable;
eventTable[i++].table = xnoExposeTable;
eventTable[i++].table = xgraphicsExposeTable;
eventTable[i++].table = xkeyTable;
eventTable[i++].table = xmotionTable;
}
static Namval_t *
ProcessCallbackEvent(
XEvent *event,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
static Boolean initialized = False;
int i = 0;
int j = 0;
EventEntryTable * table;
XrmValue fval, tval;
char * ptr;
if (!initialized)
{
InitEventTables();
initialized = True;
}
np2 = GetNameValuePair(name);
sprintf(buf, "0x%lx", (long)event);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
{
if (event == NULL)
np2 = CreateEmptyNameValuePair(np, name, fp);
else
{
np2 = GetNameValuePair(name);
if (strcmp(name, "TYPE") == 0)
{
fval.addr = (caddr_t)&(event->type);
fval.size = sizeof(long);
XtConvert(Toplevel, "XE_EventType", &fval, XtRString, &tval);
if (tval.size != 0)
ptr = (char *)(tval.addr);
else
ptr = str_nill;
nv_putval(np2, ptr, NV_RDONLY);
}
else
{
while (eventTable[i].eventType)
{
if (strcmp(eventTable[i].eventType, name) == 0)
{
sprintf(buf, "0x%lx", (long)event);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
{
np2 = GetNameValuePair(name);
table = eventTable[i].table;
while (table[j].fieldName)
{
if (strcmp(table[j].fieldName, name) == 0)
{
if (table[j].valueSize == sizeof(char))
{
fval.addr = (caddr_t) ((char *)
((char *)event+table[j].valueOffset));
fval.size = sizeof(char);
}
else if (table[j].valueSize == sizeof(short))
{
fval.addr = (caddr_t) ((short *)
((char *)event+table[j].valueOffset));
fval.size = sizeof(short);
}
else if (table[j].valueSize == sizeof(int))
{
fval.addr = (caddr_t) ((int *)
((char *)event+table[j].valueOffset));
fval.size = sizeof(int);
}
else if (table[j].valueSize == sizeof(long))
{
fval.addr = (caddr_t) ((long *)
((char *)event+table[j].valueOffset));
fval.size = sizeof(long);
}
XtConvert(Toplevel, table[j].representation,
&fval, XtRString, &tval);
if (tval.size != 0)
ptr = (char *)(tval.addr);
else
ptr = str_nill;
nv_putval(np2, ptr, NV_RDONLY);
break;
}
j++;
}
if (table[j].fieldName == NULL)
nv_putval(np2, str_nill, NV_RDONLY);
break;
}
}
i++;
}
if (eventTable[i].eventType == NULL)
nv_putval(np2, str_nill, NV_RDONLY);
}
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
}
}
return(np2);
}
static Namval_t *
_IntProcessCallbackReason(
struct named_integer *table,
XmAnyCallbackStruct *cbData,
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
/*
* We won't use an Xt converter here (even though we could), because
* we want to be able to handle the case where the callback reason
* is one we don't know about.
*/
np2 = GetNameValuePair(name);
while (table->name)
{
if (table->value == cbData->reason)
{
nv_putval(np2, table->name, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
table++;
}
/*
* fdt: someday, allow for an expandable table, which can be
* added to by the shell script; useful when loading new widgets.
*/
/* Unknown callback reason; simply return the integer value */
sprintf(buf, "%d", cbData->reason);
nv_putval(np2, buf, NV_RDONLY);
if (name = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, name, fp);
return(np2);
}
static Namval_t *
ProcessCallbackReason(
XmAnyCallbackStruct *cbData,
Namval_t *np,
char *name,
Namfun_t *fp )
{
return(_IntProcessCallbackReason(CallbackReasons, cbData, np, name, fp));
}
/*
* This requires a separate handler, due to the fact that the help
* callback reasons overlap the standard Motif callback reasons!!
*/
static Namval_t *
ProcessHelpCallbackReason(
XmAnyCallbackStruct *cbData,
Namval_t *np,
char *name,
Namfun_t *fp )
{
return(_IntProcessCallbackReason(HelpCallbackReasons, cbData, np, name, fp));
}
/*
* Certain classes of callbacks do not return a structure as the calldata.
* Examples are the destroyCallback, popupCallback, popdownCallback and
* the workspace changed callback. Since the calldata is a value, and not
* a structure, any references to subfields are invalid.
*/
Namval_t *
nopCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char * token;
char * dupName = strdup(name);
token = strtok(dupName, ".");
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This function creates a new name/value pair (representing an environment
* variable) when it is referenced. If the name/value pair already exists,
* then it is simply reused. We keep track of all the name/value pairs
* we create, so that they can be destroyed when callback processing has
* completed. This handles the XmAnyCallbackStruct.
*/
Namval_t *
dftCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
XmAnyCallbackStruct * cbData;
char * cbDataAddrStr;
char * p;
char * token;
char * dupName = strdup(name);
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmAnyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the discipline handler for an event handler.
* It only knows how to reference the event structure.
*/
Namval_t *
ehCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
XEvent * event;
char * eventAddrStr;
char * p;
char * token;
char * tmpBuf;
eventAddrStr = nv_getv(np, fp);
event = (XEvent *)strtoul(eventAddrStr, &p, 0);
tmpBuf = XtMalloc(strlen(name) + strlen("EH_EVENT") + 2);
sprintf(tmpBuf, "%s.%s", "EH_EVENT", name);
token = strtok(tmpBuf, ".");
np2 = ProcessCallbackEvent(event, np, token, fp);
XtFree(tmpBuf);
return(np2);
}
/*
* This is the discipline handler for the translation handler.
* It only knows how to reference the event structure.
*/
Namval_t *
transCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
Namval_t * np2;
char buf[128];
XEvent * event;
char * eventAddrStr;
char * p;
char * token;
char * tmpBuf;
eventAddrStr = nv_getv(np, fp);
event = (XEvent *)strtoul(eventAddrStr, &p, 0);
tmpBuf = XtMalloc(strlen(name) + strlen("TRANSLATION_EVENT") + 2);
sprintf(tmpBuf, "%s.%s", "TRANSLATION_EVENT", name);
token = strtok(tmpBuf, ".");
np2 = ProcessCallbackEvent(event, np, token, fp);
XtFree(tmpBuf);
return(np2);
}
/*
* This is the 'create' discipline function for the scale widget.
* This handles the XmScaleCallbackStruct.
*/
Namval_t *
scaleCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmScaleCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmScaleCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "VALUE") == 0)
np2 = ProcessIntValue((int)cbData->value, np, token, fp, "%d", NULL);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the arrow widget.
* This handles the XmArrowButtonCallbackStruct.
*/
Namval_t *
arrowCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmArrowButtonCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmArrowButtonCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "CLICK_COUNT") == 0)
{
if (cbData->reason == XmCR_ACTIVATE)
{
np2 = ProcessIntValue((int)cbData->click_count, np, token, fp, "%d",
NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the comboBox widget.
* This handles the XmComboBoxCallbackStruct.
*/
Namval_t *
comboCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmComboBoxCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmComboBoxCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData,
np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "ITEM_OR_TEXT") == 0)
np2 = ProcessXmStringValue(cbData->item_or_text, np, token, fp);
else if (strcmp(token, "ITEM_POSITION") == 0)
{
np2 = ProcessIntValue((int)cbData->item_position, np, token, fp, "%d",
NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the command widget.
* This handles the XmCommandCallbackStruct.
*/
Namval_t *
cmdCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmCommandCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
int len;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmCommandCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "VALUE") == 0)
np2 = ProcessXmStringValue(cbData->value, np, token, fp);
else if (strcmp(token, "LENGTH") == 0)
{
if ((p = XmStringToString(cbData->value)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue((int)len, np, token, fp, "%d", NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the drawingArea widget.
* This handles the XmDrawingAreaCallbackStruct.
*/
Namval_t *
dAreaCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmDrawingAreaCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmDrawingAreaCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "WINDOW") == 0)
np2 = ProcessIntValue((int)cbData->window, np, token, fp, "0x%x", NULL);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the drawnButton widget.
* This handles the XmDrawnButtonCallbackStruct.
*/
Namval_t *
dbtnCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmDrawnButtonCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmDrawnButtonCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "WINDOW") == 0)
np2 = ProcessIntValue((int)cbData->window, np, token, fp, "0x%x", NULL);
else if (strcmp(token, "CLICK_COUNT") == 0)
{
if (cbData->reason == XmCR_ACTIVATE)
{
np2 = ProcessIntValue((int)cbData->click_count, np, token, fp, "%d",
NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the file selection widget.
* This handles the XmFileSelectionBoxCallbackStruct.
*/
Namval_t *
fselCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmFileSelectionBoxCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
int len;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmFileSelectionBoxCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "VALUE") == 0)
np2 = ProcessXmStringValue(cbData->value, np, token, fp);
else if (strcmp(token, "LENGTH") == 0)
{
if ((p = XmStringToString(cbData->value)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue(len, np, token, fp, "%d", NULL);
}
else if (strcmp(token, "MASK") == 0)
np2 = ProcessXmStringValue(cbData->mask, np, token, fp);
else if (strcmp(token, "MASK_LENGTH") == 0)
{
if ((p = XmStringToString(cbData->mask)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue(len, np, token, fp, "%d", NULL);
}
else if (strcmp(token, "DIR") == 0)
np2 = ProcessXmStringValue(cbData->dir, np, token, fp);
else if (strcmp(token, "DIR_LENGTH") == 0)
{
if ((p = XmStringToString(cbData->dir)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue(len, np, token, fp, "%d", NULL);
}
else if (strcmp(token, "PATTERN") == 0)
np2 = ProcessXmStringValue(cbData->pattern, np, token, fp);
else if (strcmp(token, "PATTERN_LENGTH") == 0)
{
if ((p = XmStringToString(cbData->pattern)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue(len, np, token, fp, "%d", NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the list widget.
* This handles the XmListCallbackStruct.
*/
Namval_t *
listCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmListCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
int len;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmListCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "ITEM") == 0)
np2 = ProcessXmStringValue(cbData->item, np, token, fp);
else if (strcmp(token, "ITEM_LENGTH") == 0)
{
if ((p = XmStringToString(cbData->item)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue(len, np, token, fp, "%d", NULL);
}
else if (strcmp(token, "ITEM_POSITION") == 0)
{
np2 = ProcessIntValue((int)cbData->item_position, np, token, fp, "%d",
NULL);
}
else if (strcmp(token, "SELECTED_ITEMS") == 0)
{
if ((cbData->reason == XmCR_DEFAULT_ACTION) ||
(cbData->reason == XmCR_MULTIPLE_SELECT) ||
(cbData->reason == XmCR_EXTENDED_SELECT))
{
np2 = ProcessXmStringTable(cbData->selected_items,
cbData->selected_item_count,
np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "SELECTED_ITEM_COUNT") == 0)
{
if ((cbData->reason == XmCR_DEFAULT_ACTION) ||
(cbData->reason == XmCR_MULTIPLE_SELECT) ||
(cbData->reason == XmCR_EXTENDED_SELECT))
{
np2 = ProcessIntValue((int)cbData->selected_item_count, np, token,
fp, "%d", NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "SELECTED_ITEM_POSITIONS") == 0)
{
if ((cbData->reason == XmCR_DEFAULT_ACTION) ||
(cbData->reason == XmCR_MULTIPLE_SELECT) ||
(cbData->reason == XmCR_EXTENDED_SELECT))
{
np2 = ProcessIntTable(cbData->selected_item_positions,
cbData->selected_item_count,
np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "SELECTION_TYPE") == 0)
{
if (cbData->reason == XmCR_EXTENDED_SELECT)
np2 = ProcessSelectionType(cbData->selection_type, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the pushbutton widget.
* This handles the XmPushButtonCallbackStruct.
*/
Namval_t *
pbtnCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmPushButtonCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmPushButtonCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "CLICK_COUNT") == 0)
{
if (cbData->reason == XmCR_ACTIVATE)
{
np2 = ProcessIntValue((int)cbData->click_count, np, token, fp, "%d",
NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the rowcolumn widget.
* This handles the XmRowColumnCallbackStruct.
*/
Namval_t *
rcCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmRowColumnCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmRowColumnCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
{
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token,
fp);
}
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if ((strcmp(token, "WIDGET") == 0) &&
(cbData->reason == XmCR_ACTIVATE))
{
np2 = ProcessWidgetHandle(cbData->widget, np, token, fp);
}
else if ((strcmp(token, "DATA") == 0) && (cbData->reason == XmCR_ACTIVATE))
np2 = ProcessIntValue((int)cbData->data, np, token, fp, "0x%x", NULL);
else if ((strcmp(token, "CALLBACKSTRUCT") == 0) &&
(cbData->reason == XmCR_ACTIVATE))
{
np2 = ProcessIntValue((int)cbData->callbackstruct, np, token,fp,"0x%x",
NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the scrollbar widget.
* This handles the XmScrollBarCallbackStruct.
*/
Namval_t *
sbarCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmScrollBarCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmScrollBarCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "VALUE") == 0)
np2 = ProcessIntValue((int)cbData->value, np, token, fp, "%d", NULL);
else if (strcmp(token, "PIXEL") == 0)
{
if ((cbData->reason == XmCR_TO_BOTTOM) || (cbData->reason == XmCR_TO_TOP))
np2 = ProcessIntValue((int)cbData->pixel, np, token,fp,"%d", NULL);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the scrolledwindow widget.
* This handles the XmTraverseObsuredCallbackStruct.
*/
Namval_t *
swinCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTraverseObscuredCallbackStruct * cbData;
char * token;
char * p;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmTraverseObscuredCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "TRAVERSAL_DESTINATION") == 0)
np2 = ProcessWidgetHandle(cbData->traversal_destination, np, token, fp);
else if (strcmp(token, "DIRECTION") == 0)
np2 = ProcessTraversalDirection(cbData->direction, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the selection box widget.
* This handles the XmSelectionBoxCallbackStruct.
*/
Namval_t *
sboxCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmSelectionBoxCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
int len;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmSelectionBoxCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "VALUE") == 0)
np2 = ProcessXmStringValue(cbData->value, np, token, fp);
else if (strcmp(token, "LENGTH") == 0)
{
if ((p = XmStringToString(cbData->value)) == NULL)
len = 0;
else
len = strlen(p);
np2 = ProcessIntValue(len, np, token, fp, "%d", NULL);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the toggle widget.
* This handles the XmToggleButtonCallbackStruct.
*/
Namval_t *
tbtnCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmToggleButtonCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmToggleButtonCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "SET") == 0)
np2 = ProcessBooleanIntValue((int)cbData->set, np, token, fp, NULL);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is one ofthe 'create' discipline function for the text widget.
* This handles the XmTextVerifyCallbackStruct. If a subfield can
* be altered by a shell script (i.e. CB_CALL_DATA.TEXT.PTR), then
* we must assign a discipline to the 'PTR' environment variable,
* so that we will be notified when the assignment occurs, and thus
* can update the real callback structure.
*/
Namval_t *
textCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
char * token;
XrmValue f, t;
char * value;
char buf[25];
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
np2 = ProcessCallbackReason((XmAnyCallbackStruct *)cbData, np, token, fp);
else if (strcmp(token, "EVENT") == 0)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else if (strcmp(token, "DOIT") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_doit_disc);
np2 = ProcessBooleanIntValue((int)cbData->doit, np, token, fp, disc);
}
else if (strcmp(token, "CURRINSERT") == 0)
np2 = ProcessIntValue((int)cbData->currInsert, np, token, fp, "%d", NULL);
else if (strcmp(token, "NEWINSERT") == 0)
np2 = ProcessIntValue((int)cbData->newInsert, np, token, fp, "%d", NULL);
else if (strcmp(token, "STARTPOS") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_startpos_disc);
if ((cbData->reason == XmCR_LOSING_FOCUS) ||
(cbData->reason == XmCR_MODIFYING_TEXT_VALUE))
{
np2 = ProcessIntValue((int)cbData->startPos, np, token, fp,"%d", disc);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "ENDPOS") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_endpos_disc);
if ((cbData->reason == XmCR_LOSING_FOCUS) ||
(cbData->reason == XmCR_MODIFYING_TEXT_VALUE))
{
np2 = ProcessIntValue((int)cbData->endPos, np, token, fp, "%d", disc);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "TEXT") == 0)
{
if (cbData->reason == XmCR_MODIFYING_TEXT_VALUE)
{
np2 = GetNameValuePair(token);
sprintf(buf, "0x%lx", (long)cbData->text);
nv_putval(np2, buf, NV_RDONLY);
/* Need to handle the substructure fields */
if (token = strtok(NULL, "."))
{
np2 = GetNameValuePair(token);
if (strcmp(token, "PTR") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_ptr_disc);
/* Any old disciplies MUST be cleared, before setting value */
nv_stack(np2, NULL);
if (cbData->text->ptr)
nv_putval(np2, cbData->text->ptr, NV_RDONLY);
else
nv_putval(np2, str_nill, NV_RDONLY);
nv_stack(np2, disc);
}
else if (strcmp(token, "LENGTH") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_len_disc);
/* Any old disciplies MUST be cleared, before setting value */
sprintf(buf, "%d", cbData->text->length);
nv_stack(np2, NULL);
nv_putval(np2, buf, NV_RDONLY);
nv_stack(np2, disc);
}
else if (strcmp(token, "FORMAT") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_format_disc);
f.addr = (caddr_t)&(cbData->text->format);
f.size = sizeof(XmTextFormat);
t.addr = NULL;
t.size = 0;
XtConvert(Toplevel, "TextFormat", &f, XtRString, &t);
/* Any old disciplies MUST be cleared, before setting value */
if (t.size && t.addr)
value = t.addr;
else
value = str_nill;
nv_stack(np2, NULL);
nv_putval(np2, value, NV_RDONLY);
nv_stack(np2, disc);
}
else
nv_putval(np2, str_nill, NV_RDONLY);
/* No deeper nesting is supported */
if (token = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, token, fp);
}
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is one ofthe 'create' discipline function for the text widget.
* This handles the XmTextVerifyCallbackStructWcs.
*/
Namval_t *
textCreateDisc2(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStructWcs * cbData;
char * p;
char * token;
Namval_t * np2;
char * nameCopy = strdup(name);
char * dupName = strdup(name);
char buf[25];
cbDataAddrStr = nv_getv(np, fp);
cbData = (XmTextVerifyCallbackStructWcs *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "TEXT") == 0)
{
np2 = GetNameValuePair(token);
sprintf(buf, "0x%lx", (long)cbData->text);
nv_putval(np2, buf, NV_RDONLY);
/* Need to handle the substructure fields */
if (token = strtok(NULL, "."))
{
np2 = GetNameValuePair(token);
if (strcmp(token, "WCSPTR") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_wcsptr_disc);
/* Any old disciplies MUST be cleared, before setting value */
nv_stack(np2, NULL);
if (cbData->text->wcsptr)
{
wchar_t * wcBuf;
char * mbBuf;
int mbBufSize;
int count, i;
/*
* It appears that the wchar string coming in is NOT NULL
* terminated; we must make our own copy, before calling
* wcstombs().
*/
wcBuf = (wchar_t *)XtMalloc((cbData->text->length + 1) *
sizeof(wchar_t));
for ( i = 0; i < cbData->text->length; i++)
wcBuf[i] = cbData->text->wcsptr[i];
wcBuf[i] = 0;
mbBufSize = ((cbData->text->length + 1) * sizeof(wchar_t));
mbBuf = XtMalloc(mbBufSize);
count = wcstombs(mbBuf, wcBuf, mbBufSize - sizeof(wchar_t));
if (count >= 0)
{
mbBuf[count] = '\0';
nv_putval(np2, mbBuf, NV_RDONLY);
}
else
nv_putval(np2, str_nill, NV_RDONLY);
XtFree(mbBuf);
XtFree((char *)wcBuf);
}
else
nv_putval(np2, str_nill, NV_RDONLY);
nv_stack(np2, disc);
}
else if (strcmp(token, "LENGTH") == 0)
{
static Namfun_t * disc = NULL;
if (disc == NULL)
disc = CloneDiscipline(&text_wcslen_disc);
/* Any old disciplies MUST be cleared, before setting value */
sprintf(buf, "%d", cbData->text->length);
nv_stack(np2, NULL);
nv_putval(np2, buf, NV_RDONLY);
nv_stack(np2, disc);
}
else
nv_putval(np2, str_nill, NV_RDONLY);
/* No deeper nesting is supported */
if (token = strtok(NULL, "."))
np2 = CreateEmptyNameValuePair(np, token, fp);
}
}
else
np2 = textCreateDisc(np, nameCopy, fp);
XtFree(nameCopy);
XtFree(dupName);
return(np2);
}
/*
* This is the 'create' discipline function for the help widget.
* This handles the DtHelpDialogCallbackStruct.
*/
Namval_t *
helpCreateDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
DtHelpDialogCallbackStruct * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (DtHelpDialogCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
/* cbData can be NULL if invoked from XtCallCallbacks */
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "REASON") == 0)
{
/*
* Can't use the normal callback reason function, since the help
* callback reasons are not unique! They overlap with the normal
* callback reasons.
*/
np2 = ProcessHelpCallbackReason((XmAnyCallbackStruct *)cbData, np,
token, fp);
}
else if (strcmp(token, "EVENT") == 0)
{
if (cbData->event)
np2 = ProcessCallbackEvent(cbData->event, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "LOCATIONID") == 0)
{
if (cbData->reason == DtCR_HELP_LINK_ACTIVATE)
np2 = ProcessStringValue(cbData->locationId, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "HELPVOLUME") == 0)
{
if (cbData->reason == DtCR_HELP_LINK_ACTIVATE)
np2 = ProcessStringValue(cbData->helpVolume, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "SPECIFICATION") == 0)
{
if (cbData->reason == DtCR_HELP_LINK_ACTIVATE)
np2 = ProcessStringValue(cbData->specification, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else if (strcmp(token, "HYPERTYPE") == 0)
{
if (cbData->reason == DtCR_HELP_LINK_ACTIVATE)
np2 = ProcessHyperType(cbData->hyperType, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
}
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/*
* This is the 'DtPrintSetupProc' discipline function for the DtPrintSetupBox
* widget. It handles the DtPrintSetupData struct with the exception of the
* print_display and print_screen members.
*/
Namval_t *
dtPrintSetupProcDisc(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
DtPrintSetupData * cbData;
char * p;
char * token;
char * dupName = strdup(name);
Namval_t * np2;
cbDataAddrStr = nv_getv(np, fp);
cbData = (DtPrintSetupData *)strtoul(cbDataAddrStr, &p, 0);
token = strtok(dupName, ".");
if (cbData == NULL)
np2 = CreateEmptyNameValuePair(np, token, fp);
else if (strcmp(token, "PRINTER_NAME") == 0)
np2 = ProcessStringValue(cbData->printer_name, np, token, fp);
else if (strcmp(token, "DESTINATION") == 0)
np2 = ProcessIntValue(cbData->destination, np, token, fp, "%d", NULL);
else if (strcmp(token, "DEST_INFO") == 0)
np2 = ProcessStringValue(cbData->dest_info, np, token, fp);
else
np2 = CreateEmptyNameValuePair(np, token, fp);
XtFree(dupName);
return(np2);
}
/****************************************************************************
*
* The following functions are used to create and free a copy of a
* discipline structure. We register a discipline when we want to
* be notified that the shell script has referenced one of our special
* environment variables. This gives us the ability to dynamically
* assign the value they will receive. This is used during callback,
* translation and event handling (i.e. CB_CALL_DATA, etc). We need
* to duplicate the discipline structure due to how ksh handles these
* structures; it stores each successive one in a linked list. Typically,
* this is not a problem. However, because callbacks can become nested
* (From within one callback, the script does something which causes another
* callback to fire), if the same discipline structure gets passed in twice,
* when it gets added to the linked list, the original 'next' pointer gets
* trashed; the typical result is that the next time one of the special
* environment variables is referenced, dtksh goes into an infinite loop.
* The solution appears to be to 'clone' the discipline, thus creating
* a unique structure each time, and preventing the 'next' pointer from
* getting trashed.
*
**************************************************************************/
static Namfun_t *
CloneDiscipline(
Namdisc_t * discipline )
{
Namfun_t * clonedDisc;
clonedDisc = (Namfun_t *)XtMalloc(sizeof(Namfun_t));
clonedDisc->disc = discipline;
clonedDisc->next = NULL;
return(clonedDisc);
}
static void
FreeDiscipline(
Namfun_t * discipline )
{
XtFree((char *)discipline);
}
void
SetTextDoit(
Namval_t *np,
char *name,
Namfun_t *fp )
{
XrmValue fval, tval;
Boolean doit = True;
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
Namval_t *cbDataNp;
/* Convert from string to a boolean */
fval.addr = name;
fval.size = strlen(name);
XtConvert(Toplevel, XtRString, &fval, XtRBoolean, &tval);
if (tval.size != 0)
doit = *((Boolean *)(tval.addr));
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
cbData->doit = doit;
}
}
void
SetTextStartPos(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
Namval_t *cbDataNp;
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
cbData->startPos = strtoul(name, &p, 0);
}
}
void
SetTextEndPos(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
Namval_t *cbDataNp;
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
cbData->endPos = strtoul(name, &p, 0);
}
}
void
SetTextPtr(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
Namval_t *cbDataNp;
static char * staticBuf = NULL;
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
/* fdt
* MOTIF BUG ALERT!!
* Motif will not currently free the original buffer,
* but will instead free our buffer.
*
* XtFree(staticBuf);
*/
staticBuf = strdup(name);
cbData->text->ptr = staticBuf;
}
}
void
SetTextLen(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
Namval_t *cbDataNp;
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
cbData->text->length = strtoul(name, &p, 0);
}
}
void
SetTextFormat(
Namval_t *np,
char *name,
Namfun_t *fp )
{
XrmValue fval, tval;
Boolean doit = True;
char * cbDataAddrStr;
XmTextVerifyCallbackStruct * cbData;
char * p;
Namval_t *cbDataNp;
/* Convert from string to format type */
fval.addr = name;
fval.size = strlen(name);
XtConvert(Toplevel, XtRString, &fval, "TextFormat", &tval);
if (tval.size && tval.addr &&
(cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0)))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStruct *)strtoul(cbDataAddrStr, &p, 0);
cbData->text->format = *((int *)(tval.addr));
}
}
void
SetTextWCSptr(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStructWcs * cbData;
char * p;
Namval_t *cbDataNp;
static wchar_t * wcBuf = NULL;
int count;
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStructWcs *)strtoul(cbDataAddrStr, &p, 0);
/* fdt
* MOTIF BUG ALERT!!
* Motif will not currently free the original buffer,
* but will instead free our buffer.
*
* XtFree(wcBuf);
*/
wcBuf = (wchar_t *)XtMalloc((strlen(name) + 1) * sizeof(wchar_t));
count = mbstowcs(wcBuf, name, strlen(name)+1);
cbData->text->wcsptr = wcBuf;
}
}
void
SetTextWCSlen(
Namval_t *np,
char *name,
Namfun_t *fp )
{
char * cbDataAddrStr;
XmTextVerifyCallbackStructWcs * cbData;
char * p;
Namval_t *cbDataNp;
if (cbDataNp = nv_open("CB_CALL_DATA", sh.var_tree, 0))
{
cbDataAddrStr = nv_getv(cbDataNp, NULL);
cbData=(XmTextVerifyCallbackStructWcs *)strtoul(cbDataAddrStr, &p, 0);
cbData->text->length = strtoul(name, &p, 0);
}
}
/*
* stdPrintSetupProc() is the central routine from which the DtPrintSetupBox
* widget's DtPrintSetupProc resources are dispatched.
* The variable "CB_WIDGET" will be placed in the environment to represent
* the CallBackWidget handle. Because DtPrintSetupProc doesn't work the
* same way as a callback, we had to fudge this to work by storing the command
* string inside the widget's wtab_t->info field. This is pretty nasty and
* non-generic, but there does not appear to be a good solution.
*
* The call_data is made available through the CD_CALL_DATA variable.
*
* If a new DtPrintSetupProc resource needs to be supported, the list of
* hardcoded procs and associated information have to be updated, as follows:
* - add a #define of the resource in dtksh.h
* - add a new member in the ProcInfo_t to store that command in dtksh.h.
* - add a new function called std<resource_name> which calls
* stdPrintSetupProc().
* - add a new case to set the command to the above function for the new
* resource in DtkshCvtStringToPrintSetupProc().
* - add a new case in the switch statement this function to account for
* the new resource.
*
*/
void
stdPrintSetupProc(
int proctype,
void *widget,
DtPrintSetupData *callData)
{
wtab_t *w;
ProcInfo_t *pinfo;
char buf[128];
Namval_t *np;
Namval_t *np2;
WidgetClass class;
Namdisc_t *discipline = NULL;
char *oldCB_WIDGET_value = NULL;
char *oldCB_CALL_DATA_value = NULL;
char *ptr;
Namfun_t *clonedDisc;
w = widget_to_wtab((Widget)widget);
if (w == NULL)
return;
pinfo = (ProcInfo_t *) w->info;
if (pinfo == NULL)
return;
nestingLevel++;
np2 = GetNameValuePair("CB_WIDGET");
nv_newattr(np2, 0, 0);
if (ptr = nv_getval(np2))
oldCB_WIDGET_value = strdup(ptr);
nv_putval(np2, w->widid, NV_RDONLY);
nv_newattr(np2, NV_RDONLY, 0);
sprintf(buf, "0x%lx", (long)callData);
np = GetNameValuePair("CB_CALL_DATA");
nv_newattr(np, 0, 0);
if (ptr = nv_getval(np))
oldCB_CALL_DATA_value = strdup(ptr);
nv_putval(np, buf, NV_RDONLY);
nv_newattr(np, NV_RDONLY, 0);
/* look up the discipline for DtPrintSetupProc */
class = XtClass(w->w);
while (class) {
if (discipline = CheckClassDisciplines(class, DtRPrintSetupProc))
break;
class = class->core_class.superclass;
}
/*
* If a discipline was found, then use it; otherwise, we MUST set up
* a default discipline; otherwise, any hierarchical variables
* referenced by the user are not under our control, thus never getting
* freed up, and then also preventing future disciplines from getting
* called when they should have.
*/
if (discipline)
clonedDisc = CloneDiscipline(discipline);
else
clonedDisc = CloneDiscipline(&dftDiscipline);
nv_stack(np, clonedDisc);
switch (proctype) {
case PRINTER_INFO_PROC:
ksh_eval(pinfo->printerInfoProcCommand);
break;
case SELECT_FILE_PROC:
ksh_eval(pinfo->selectFileProcCommand);
break;
case SELECT_PRINTER_PROC:
ksh_eval(pinfo->selectPrinterProcCommand);
break;
case SETUP_PROC:
ksh_eval(pinfo->setupProcCommand);
break;
case VERIFY_PRINTER_PROC:
ksh_eval(pinfo->verifyPrinterProcCommand);
break;
}
/* We may be nested, so restore old CB_WIDGET & CB_CALL_DATA values */
RestorePriorEnvVarValues(np2, oldCB_WIDGET_value, np, oldCB_CALL_DATA_value);
XtFree(oldCB_WIDGET_value);
XtFree(oldCB_CALL_DATA_value);
/* Remove the discipline for the hierarchical variables */
nv_stack(np, NULL);
FreeDiscipline(clonedDisc);
/* Free up all of the name/value pairs we created */
FreeNestedVariables();
nestingLevel--;
return;
}
void
stdPrinterInfoProc(
void *widget,
DtPrintSetupData *callData)
{
stdPrintSetupProc(PRINTER_INFO_PROC, widget, callData);
return;
}
void
stdSelectFileProc(
void *widget,
DtPrintSetupData *callData)
{
stdPrintSetupProc(SELECT_FILE_PROC, widget, callData);
return;
}
void
stdSelectPrinterProc(
void *widget,
DtPrintSetupData *psd)
{
stdPrintSetupProc(SELECT_PRINTER_PROC, widget, psd);
return;
}
void
stdSetupProc(
void *widget,
DtPrintSetupData *callData)
{
stdPrintSetupProc(SETUP_PROC, widget, callData);
return;
}
void
stdVerifyPrinterProc(
void *widget,
DtPrintSetupData *callData)
{
stdPrintSetupProc(VERIFY_PRINTER_PROC, widget, callData);
return;
}