xref: /netbsd/external/bsd/nvi/dist/motif_l/m_options.c (revision cc73507a)
13a571abcSchristos /*-
23a571abcSchristos  * Copyright (c) 1996
33a571abcSchristos  *	Rob Zimmermann.  All rights reserved.
43a571abcSchristos  * Copyright (c) 1996
53a571abcSchristos  *	Keith Bostic.  All rights reserved.
63a571abcSchristos  *
73a571abcSchristos  * See the LICENSE file for redistribution information.
83a571abcSchristos  */
93a571abcSchristos 
103a571abcSchristos #include "config.h"
113a571abcSchristos 
12*cc73507aSchristos #include <sys/cdefs.h>
13*cc73507aSchristos #if 0
143a571abcSchristos #ifndef lint
153a571abcSchristos static const char sccsid[] = "Id: m_options.c,v 8.22 2003/11/05 17:09:59 skimo Exp  (Berkeley) Date: 2003/11/05 17:09:59 ";
163a571abcSchristos #endif /* not lint */
17*cc73507aSchristos #else
18*cc73507aSchristos __RCSID("$NetBSD: m_options.c,v 1.2 2014/01/26 21:43:45 christos Exp $");
19*cc73507aSchristos #endif
203a571abcSchristos 
213a571abcSchristos #include <sys/types.h>
223a571abcSchristos #include <sys/queue.h>
233a571abcSchristos 
243a571abcSchristos #include <X11/X.h>
253a571abcSchristos #include <X11/Intrinsic.h>
263a571abcSchristos #include <Xm/DialogS.h>
273a571abcSchristos #include <Xm/Form.h>
283a571abcSchristos #include <Xm/Frame.h>
293a571abcSchristos #include <Xm/LabelG.h>
303a571abcSchristos #include <Xm/PushBG.h>
313a571abcSchristos #include <Xm/TextF.h>
323a571abcSchristos #include <Xm/ToggleBG.h>
333a571abcSchristos #include <Xm/RowColumn.h>
343a571abcSchristos 
353a571abcSchristos #include <bitstring.h>
363a571abcSchristos #include <stdio.h>
373a571abcSchristos #include <stdlib.h>
383a571abcSchristos #include <string.h>
393a571abcSchristos 
403a571abcSchristos #undef LOCK_SUCCESS
413a571abcSchristos #include "../common/common.h"
423a571abcSchristos #include "../ipc/ip.h"
433a571abcSchristos #include "m_motif.h"
443a571abcSchristos 
453a571abcSchristos extern int vi_ofd;
463a571abcSchristos 
473a571abcSchristos static void set_opt __P((Widget, XtPointer, XtPointer));
483a571abcSchristos 
493a571abcSchristos 
503a571abcSchristos /* constants */
513a571abcSchristos 
523a571abcSchristos #if defined(SelfTest)
533a571abcSchristos 
543a571abcSchristos /* in production, get these from the resource list */
553a571abcSchristos 
563a571abcSchristos #define	toggleColumns	6
573a571abcSchristos 
583a571abcSchristos #endif
593a571abcSchristos 
603a571abcSchristos 
613a571abcSchristos /*
623a571abcSchristos  * global data
633a571abcSchristos  */
643a571abcSchristos 
653a571abcSchristos static Widget	preferences = NULL;
663a571abcSchristos 
673a571abcSchristos static optData display[] = {
683a571abcSchristos 	{ optToggle,	"comment",	},
693a571abcSchristos 	{ optToggle,	"flash",	},
703a571abcSchristos 	{ optToggle,	"leftright",	},
713a571abcSchristos 	{ optToggle,	"list",		},
723a571abcSchristos 	{ optToggle,	"number",	},
733a571abcSchristos 	{ optToggle,	"octal",	},
743a571abcSchristos 	{ optToggle,	"ruler",	},
753a571abcSchristos 	{ optToggle,	"showmode",	},
763a571abcSchristos 	{ optToggle,	"slowopen",	},
773a571abcSchristos 	{ optToggle,	"verbose",	},
783a571abcSchristos 	{ optToggle,	"windowname",	},
793a571abcSchristos 	{ optTerminator,		},
803a571abcSchristos }, display_int[] = {
813a571abcSchristos 	{ optInteger,	"report",	},
823a571abcSchristos 	{ optInteger,	"scroll",	},
833a571abcSchristos 	{ optInteger,	"shiftwidth",	},
843a571abcSchristos 	{ optInteger,	"sidescroll",	},
853a571abcSchristos 	{ optInteger,	"tabstop",	},
863a571abcSchristos 	{ optInteger,	"window",	},
873a571abcSchristos 	{ optTerminator,		},
883a571abcSchristos }, display_str[] = {
893a571abcSchristos 	{ optString,	"noprint",	},
903a571abcSchristos 	{ optString,	"print",	},
913a571abcSchristos 	{ optTerminator,		},
923a571abcSchristos }, files[] = {
933a571abcSchristos 	{ optToggle,	"autowrite",	},
943a571abcSchristos 	{ optToggle,	"lock",		},
953a571abcSchristos 	{ optToggle,	"readonly",	},
963a571abcSchristos 	{ optToggle,	"writeany",	},
973a571abcSchristos 	{ optTerminator,		},
983a571abcSchristos }, files_str[] = {
993a571abcSchristos 	{ optString,	"backup",	},
1003a571abcSchristos 	{ optString,	"path",		},
1013a571abcSchristos 	{ optTerminator,		},
1023a571abcSchristos }, general[] = {
1033a571abcSchristos 	{ optToggle,	"exrc",		},
1043a571abcSchristos 	{ optToggle,	"lisp",		},
1053a571abcSchristos 	{ optToggle,	"modeline",	},
1063a571abcSchristos 	{ optToggle,	"sourceany",	},
1073a571abcSchristos 	{ optToggle,	"tildeop",	},
1083a571abcSchristos 	{ optTerminator,		},
1093a571abcSchristos }, general_int[] = {
1103a571abcSchristos 	{ optInteger,	"taglength",	},
1113a571abcSchristos 	{ optTerminator,		},
1123a571abcSchristos }, general_str[] = {
1133a571abcSchristos 	{ optString,	"cdpath",	},
1143a571abcSchristos 	{ optString,	"directory",	},
1153a571abcSchristos 	{ optString,	"msgcat",	},
1163a571abcSchristos 	{ optString,	"recdir",	},
1173a571abcSchristos 	{ optString,	"shell",	},
1183a571abcSchristos 	{ optString,	"shellmeta",	},
1193a571abcSchristos 	{ optString,	"tags",		},
1203a571abcSchristos 	{ optTerminator,		},
1213a571abcSchristos }, input[] = {
1223a571abcSchristos 	{ optToggle,	"altwerase",	},
1233a571abcSchristos 	{ optToggle,	"autoindent",	},
1243a571abcSchristos 	{ optToggle,	"remap",	},
1253a571abcSchristos 	{ optToggle,	"showmatch",	},
1263a571abcSchristos 	{ optToggle,	"ttywerase",	},
1273a571abcSchristos 	{ optTerminator,		},
1283a571abcSchristos }, input_int[] = {
1293a571abcSchristos 	{ optInteger,	"escapetime",	},
1303a571abcSchristos 	{ optInteger,	"keytime",	},
1313a571abcSchristos 	{ optInteger,	"matchtime",	},
1323a571abcSchristos 	{ optInteger,	"timeout",	},
1333a571abcSchristos 	{ optInteger,	"wraplen",	},
1343a571abcSchristos 	{ optInteger,	"wrapmargin",	},
1353a571abcSchristos 	{ optTerminator,		},
1363a571abcSchristos }, input_str[] = {
1373a571abcSchristos 	{ optString,	"cedit",	},
1383a571abcSchristos 	{ optString,	"filec",	},
1393a571abcSchristos 	{ optTerminator,		},
1403a571abcSchristos }, search[] = {
1413a571abcSchristos 	{ optToggle,	"extended",	},
1423a571abcSchristos 	{ optToggle,	"iclower",	},
1433a571abcSchristos 	{ optToggle,	"ignorecase",	},
1443a571abcSchristos 	{ optToggle,	"magic",	},
1453a571abcSchristos 	{ optToggle,	"searchincr",	},
1463a571abcSchristos 	{ optToggle,	"wrapscan",	},
1473a571abcSchristos 	{ optTerminator,		},
1483a571abcSchristos }, search_str[] = {
1493a571abcSchristos 	{ optString,	"paragraphs",	},
1503a571abcSchristos 	{ optString,	"sections",	},
1513a571abcSchristos 	{ optTerminator,		},
1523a571abcSchristos };
1533a571abcSchristos 
1543a571abcSchristos /* ********* NOTE ***********
1553a571abcSchristos  * Sheet 0 will always be shown first.  It does not matter to the Xt code
1563a571abcSchristos  * which sheet that is, so it ought to be the one users interact with most.
1573a571abcSchristos  * Best guess is that's general editor options, but it might be Search/re.
1583a571abcSchristos  * ********* NOTE ***********
1593a571abcSchristos  */
1603a571abcSchristos static	optSheet sheets[] = {
1613a571abcSchristos 	{	"Display",
1623a571abcSchristos 		"These options control how text is displayed on the screen",
1633a571abcSchristos 		NULL,
1643a571abcSchristos 		display,
1653a571abcSchristos 		display_int,
1663a571abcSchristos 		display_str,
1673a571abcSchristos 	},
1683a571abcSchristos 	{	"Files",
1693a571abcSchristos 		"These options control how the editor handles files",
1703a571abcSchristos 		NULL,
1713a571abcSchristos 		files,
1723a571abcSchristos 		NULL,
1733a571abcSchristos 		files_str,
1743a571abcSchristos 	},
1753a571abcSchristos 	{	"Input",
1763a571abcSchristos 		"These options control text input behavior",
1773a571abcSchristos 		NULL,
1783a571abcSchristos 		input,
1793a571abcSchristos 		input_int,
1803a571abcSchristos 		input_str,
1813a571abcSchristos 	},
1823a571abcSchristos 	{	"Search/RE",
1833a571abcSchristos 	"These options control searching and Regular Expression behavior",
1843a571abcSchristos 		NULL,
1853a571abcSchristos 		search,
1863a571abcSchristos 		NULL,
1873a571abcSchristos 		search_str,
1883a571abcSchristos 	},
1893a571abcSchristos 	{	"Editor",
1903a571abcSchristos 		"These options control general editor configuration",
1913a571abcSchristos 		NULL,
1923a571abcSchristos 		general,
1933a571abcSchristos 		general_int,
1943a571abcSchristos 		general_str,
1953a571abcSchristos 	},
1963a571abcSchristos };
1973a571abcSchristos 
1983a571abcSchristos 
1993a571abcSchristos /* callbacks */
2003a571abcSchristos 
2013a571abcSchristos #if defined(SelfTest)
__vi_cancel_cb()2023a571abcSchristos void __vi_cancel_cb()
2033a571abcSchristos {
2043a571abcSchristos     puts( "cancelled" );
2053a571abcSchristos }
2063a571abcSchristos #endif
2073a571abcSchristos 
2083a571abcSchristos 
destroyed(void)2093a571abcSchristos static	void destroyed(void)
2103a571abcSchristos {
2113a571abcSchristos     int i;
2123a571abcSchristos 
2133a571abcSchristos     puts( "destroyed" );
2143a571abcSchristos 
2153a571abcSchristos     /* some window managers destroy us upon popdown */
2163a571abcSchristos     for (i=0; i<XtNumber(sheets); i++) {
2173a571abcSchristos 	sheets[i].holder = NULL;
2183a571abcSchristos     }
2193a571abcSchristos     preferences = NULL;
2203a571abcSchristos }
2213a571abcSchristos 
2223a571abcSchristos 
window_unmapped(Widget w,XtPointer ptr,XEvent * ev,Boolean * cont)2233a571abcSchristos static	void	window_unmapped(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont)
2243a571abcSchristos {
2253a571abcSchristos     if ( ev->type == UnmapNotify ) {
2263a571abcSchristos #if defined(SelfTest)
2273a571abcSchristos 	puts( "unmapped" );
2283a571abcSchristos #endif
2293a571abcSchristos 	XtPopdown( XtParent( preferences ) );
2303a571abcSchristos     }
2313a571abcSchristos }
2323a571abcSchristos 
2333a571abcSchristos /*
2343a571abcSchristos  * __vi_editopt --
2353a571abcSchristos  *	Set an edit option based on a core message.
2363a571abcSchristos  *
2373a571abcSchristos  * PUBLIC: int __vi_editopt __P((IPVI *, const char *, u_int32_t, const char *, u_int32_t, u_int32_t));
2383a571abcSchristos  */
2393a571abcSchristos int
__vi_editopt(IPVI * ipvi,const char * str1,u_int32_t len1,const char * str2,u_int32_t len2,u_int32_t val1)2403a571abcSchristos __vi_editopt(IPVI *ipvi, const char *str1, u_int32_t len1, const char *str2, u_int32_t len2, u_int32_t val1)
2413a571abcSchristos {
2423a571abcSchristos 	optData *opt;
2433a571abcSchristos 
2443a571abcSchristos #undef	NSEARCH
2453a571abcSchristos #define	NSEARCH(list) {							\
2463a571abcSchristos 	for (opt = list; opt->kind != optTerminator; ++opt)		\
2473a571abcSchristos 		if (!strcmp(opt->name, str1))			\
2483a571abcSchristos 			goto found;					\
2493a571abcSchristos }
2503a571abcSchristos 
2513a571abcSchristos 	NSEARCH(display);
2523a571abcSchristos 	NSEARCH(display_int);
2533a571abcSchristos 	NSEARCH(display_str);
2543a571abcSchristos 	NSEARCH(files);
2553a571abcSchristos 	NSEARCH(files_str);
2563a571abcSchristos 	NSEARCH(general);
2573a571abcSchristos 	NSEARCH(general_int);
2583a571abcSchristos 	NSEARCH(general_str);
2593a571abcSchristos 	NSEARCH(input);
2603a571abcSchristos 	NSEARCH(input_int);
2613a571abcSchristos 	NSEARCH(input_str);
2623a571abcSchristos 	NSEARCH(search);
2633a571abcSchristos 	NSEARCH(search_str);
2643a571abcSchristos 
2653a571abcSchristos 	return (0);
2663a571abcSchristos 
2673a571abcSchristos found:	switch (opt->kind) {
2683a571abcSchristos 	case optToggle:
2693a571abcSchristos 		opt->value = (void *)val1;
2703a571abcSchristos 		break;
2713a571abcSchristos 	case optInteger:
2723a571abcSchristos 		if (opt->value != NULL)
2733a571abcSchristos 			free(opt->value);
2743a571abcSchristos 		if ((opt->value = malloc(8)) != NULL)
2753a571abcSchristos 			(void)snprintf(opt->value,
2763a571abcSchristos 			    8, "%lu", (u_long)val1);
2773a571abcSchristos 		break;
2783a571abcSchristos 	case optString:
2793a571abcSchristos 	case optFile:
2803a571abcSchristos 		if (opt->value != NULL)
2813a571abcSchristos 			free(opt->value);
2823a571abcSchristos 		if ((opt->value = malloc(len2)) != NULL)
2833a571abcSchristos 			memcpy(opt->value, str2, len2);
2843a571abcSchristos 		break;
2853a571abcSchristos 	case optTerminator:
2863a571abcSchristos 		abort();
2873a571abcSchristos 	}
2883a571abcSchristos 	return (0);
2893a571abcSchristos }
2903a571abcSchristos 
2913a571abcSchristos /*
2923a571abcSchristos  * set_opt --
2933a571abcSchristos  *	Send a set-edit-option message to core.
2943a571abcSchristos  */
2953a571abcSchristos static void
set_opt(Widget w,XtPointer closure,XtPointer call_data)2963a571abcSchristos set_opt(Widget w, XtPointer closure, XtPointer call_data)
2973a571abcSchristos {
2983a571abcSchristos 	optData *opt;
2993a571abcSchristos 	Boolean set;
3003a571abcSchristos 	IP_BUF ipb;
3013a571abcSchristos 	String str;
3023a571abcSchristos 	extern IPVI ipvi_motif;
3033a571abcSchristos 
3043a571abcSchristos 	opt = closure;
3053a571abcSchristos 
3063a571abcSchristos 	ipb.code = VI_EDITOPT;
3073a571abcSchristos 	ipb.str1 = opt->name;
3083a571abcSchristos 	ipb.len1 = strlen(opt->name);
3093a571abcSchristos 
3103a571abcSchristos 	switch (opt->kind) {
3113a571abcSchristos 	case optToggle:
3123a571abcSchristos 		XtVaGetValues(w, XmNset, &set, 0);
3133a571abcSchristos 		ipb.val1 = set;
3143a571abcSchristos 		ipb.len2 = 0;
3153a571abcSchristos 
3163a571abcSchristos 		vi_wsend(&ipvi_motif, "ab1", &ipb);
3173a571abcSchristos 		if (ipb.val1) {
3183a571abcSchristos 			opt->value = (void *)!set;
3193a571abcSchristos 			/*
3203a571abcSchristos 			 * RAZ:
3213a571abcSchristos 			 * How do we turn off the button?  We don't want to
3223a571abcSchristos 			 * go recursive where we set it and it calls set_opt
3233a571abcSchristos 			 * to tell the core.  Is that possible?
3243a571abcSchristos 			 */
3253a571abcSchristos 			XtVaSetValues(w, XmNset, &set, 0);
3263a571abcSchristos 			break;
3273a571abcSchristos 		}
3283a571abcSchristos 
3293a571abcSchristos 		if (strcmp(opt->name, "ruler") == 0)
3303a571abcSchristos 			if (set)
3313a571abcSchristos 				__vi_show_text_ruler_dialog(
3323a571abcSchristos 				    __vi_screen->area, "Ruler");
3333a571abcSchristos 			else
3343a571abcSchristos 				__vi_clear_text_ruler_dialog();
3353a571abcSchristos 		break;
3363a571abcSchristos 	case optInteger:
3373a571abcSchristos 		str = XmTextFieldGetString(w);
3383a571abcSchristos 		ipb.val1 = atoi(str);
3393a571abcSchristos 		ipb.len2 = 0;
3403a571abcSchristos 		vi_send(vi_ofd, "ab1", &ipb);
3413a571abcSchristos 		break;
3423a571abcSchristos 	case optFile:
3433a571abcSchristos 	case optString:
3443a571abcSchristos 		ipb.str2 = XmTextFieldGetString(w);
3453a571abcSchristos 		ipb.len2 = strlen(ipb.str2);
3463a571abcSchristos 		vi_send(vi_ofd, "ab1", &ipb);
3473a571abcSchristos 		break;
3483a571abcSchristos 	case optTerminator:
3493a571abcSchristos 		abort();
3503a571abcSchristos 	}
3513a571abcSchristos }
3523a571abcSchristos 
3533a571abcSchristos 
3543a571abcSchristos /* add toggles to the property sheet */
3553a571abcSchristos 
3563a571abcSchristos #if defined(__STDC__)
add_toggle(Widget parent,optData * option)3573a571abcSchristos static	void	add_toggle( Widget parent, optData *option )
3583a571abcSchristos #else
3593a571abcSchristos static	void	add_toggle( parent, option )
3603a571abcSchristos 	Widget	parent;
3613a571abcSchristos 	optData	*option;
3623a571abcSchristos #endif
3633a571abcSchristos {
3643a571abcSchristos     Widget	w;
3653a571abcSchristos 
3663a571abcSchristos     w = XtVaCreateManagedWidget( option->name,
3673a571abcSchristos 				 xmToggleButtonGadgetClass,
3683a571abcSchristos 				 parent,
3693a571abcSchristos 				 XmNset,	(Boolean) option->value,
3703a571abcSchristos 				 0
3713a571abcSchristos 				 );
3723a571abcSchristos     XtAddCallback( w, XmNvalueChangedCallback, set_opt, option );
3733a571abcSchristos }
3743a571abcSchristos 
3753a571abcSchristos 
create_toggles(Widget outer,optData * toggles)3763a571abcSchristos static	Widget	create_toggles(Widget outer, optData *toggles)
3773a571abcSchristos {
3783a571abcSchristos     Widget	inner;
3793a571abcSchristos     int		i;
3803a571abcSchristos 
3813a571abcSchristos     inner = XtVaCreateWidget( "toggleOptions",
3823a571abcSchristos 			      xmRowColumnWidgetClass,
3833a571abcSchristos 			      outer,
3843a571abcSchristos 			      XmNpacking,		XmPACK_COLUMN,
3853a571abcSchristos 			      XmNnumColumns,		4,
3863a571abcSchristos 			      XmNtopAttachment,		XmATTACH_FORM,
3873a571abcSchristos 			      XmNrightAttachment,	XmATTACH_FORM,
3883a571abcSchristos 			      XmNleftAttachment,	XmATTACH_FORM,
3893a571abcSchristos 			      0
3903a571abcSchristos 			      );
3913a571abcSchristos 
3923a571abcSchristos     /* first the booleans */
3933a571abcSchristos     for (i=0; toggles[i].kind != optTerminator; i++) {
3943a571abcSchristos 	add_toggle( inner, &toggles[i] );
3953a571abcSchristos     }
3963a571abcSchristos     XtManageChild( inner );
3973a571abcSchristos 
3983a571abcSchristos     return inner;
3993a571abcSchristos }
4003a571abcSchristos 
4013a571abcSchristos 
4023a571abcSchristos /* draw text fields and their labels */
4033a571abcSchristos 
4043a571abcSchristos #if defined(__STDC__)
add_string_options(Widget parent,optData * options)4053a571abcSchristos static	void	add_string_options( Widget parent,
4063a571abcSchristos 				    optData *options
4073a571abcSchristos 				    )
4083a571abcSchristos #else
4093a571abcSchristos static	void	add_string_options( parent, options )
4103a571abcSchristos 	Widget	parent;
4113a571abcSchristos 	optData	*options;
4123a571abcSchristos #endif
4133a571abcSchristos {
4143a571abcSchristos     int		i;
4153a571abcSchristos     Widget	f, w;
4163a571abcSchristos 
4173a571abcSchristos     for ( i=0; options[i].kind != optTerminator; i++ ) {
4183a571abcSchristos 
4193a571abcSchristos 	f = XtVaCreateWidget( "form",
4203a571abcSchristos 			      xmFormWidgetClass,
4213a571abcSchristos 			      parent,
4223a571abcSchristos 			      0
4233a571abcSchristos 			      );
4243a571abcSchristos 
4253a571abcSchristos 	XtVaCreateManagedWidget( options[i].name,
4263a571abcSchristos 				 xmLabelGadgetClass,
4273a571abcSchristos 				 f,
4283a571abcSchristos 				 XmNtopAttachment,	XmATTACH_FORM,
4293a571abcSchristos 				 XmNbottomAttachment,	XmATTACH_FORM,
4303a571abcSchristos 				 XmNleftAttachment,	XmATTACH_FORM,
4313a571abcSchristos 				 XmNrightAttachment,	XmATTACH_POSITION,
4323a571abcSchristos 				 XmNrightPosition,	20,
4333a571abcSchristos 				 XmNalignment,		XmALIGNMENT_END,
4343a571abcSchristos 				 0
4353a571abcSchristos 				 );
4363a571abcSchristos 
4373a571abcSchristos 	w = XtVaCreateManagedWidget( "text",
4383a571abcSchristos 				     xmTextFieldWidgetClass,
4393a571abcSchristos 				     f,
4403a571abcSchristos 				     XmNtopAttachment,		XmATTACH_FORM,
4413a571abcSchristos 				     XmNbottomAttachment,	XmATTACH_FORM,
4423a571abcSchristos 				     XmNrightAttachment,	XmATTACH_FORM,
4433a571abcSchristos 				     XmNleftAttachment,		XmATTACH_POSITION,
4443a571abcSchristos 				     XmNleftPosition,		20,
4453a571abcSchristos 				     0
4463a571abcSchristos 				     );
4473a571abcSchristos 
4483a571abcSchristos 	XmTextFieldSetString( w, (char *) options[i].value );
4493a571abcSchristos 	XtAddCallback( w, XmNactivateCallback, set_opt, &options[i] );
4503a571abcSchristos 	XtManageChild( f );
4513a571abcSchristos     }
4523a571abcSchristos }
4533a571abcSchristos 
4543a571abcSchristos 
4553a571abcSchristos /* draw and display a single page of properties */
4563a571abcSchristos 
4573a571abcSchristos #if defined(__STDC__)
create_sheet(Widget parent,optSheet * sheet)4583a571abcSchristos static	Widget		create_sheet( Widget parent, optSheet *sheet )
4593a571abcSchristos #else
4603a571abcSchristos static	Widget		create_sheet( parent, sheet )
4613a571abcSchristos 	Widget		parent;
4623a571abcSchristos 	optSheet	*sheet;
4633a571abcSchristos #endif
4643a571abcSchristos {
4653a571abcSchristos     Widget	outer, inner, frame;
4663a571abcSchristos     Dimension	height;
4673a571abcSchristos     XmString	str;
4683a571abcSchristos 
4693a571abcSchristos     outer = XtVaCreateWidget( sheet->name,
4703a571abcSchristos 			      xmFormWidgetClass,
4713a571abcSchristos 			      parent,
4723a571abcSchristos 			      XmNtopAttachment,		XmATTACH_FORM,
4733a571abcSchristos 			      XmNrightAttachment,	XmATTACH_FORM,
4743a571abcSchristos 			      XmNbottomAttachment,	XmATTACH_FORM,
4753a571abcSchristos 			      XmNleftAttachment,	XmATTACH_FORM,
4763a571abcSchristos 			      XmNshadowType,		XmSHADOW_ETCHED_IN,
4773a571abcSchristos 			      XmNshadowThickness,	2,
4783a571abcSchristos 			      XmNverticalSpacing,	4,
4793a571abcSchristos 			      XmNhorizontalSpacing,	4,
4803a571abcSchristos 			      0
4813a571abcSchristos 			      );
4823a571abcSchristos 
4833a571abcSchristos     /* add descriptive text */
4843a571abcSchristos     frame = XtVaCreateManagedWidget( "frame",
4853a571abcSchristos 				    xmFrameWidgetClass,
4863a571abcSchristos 				    outer,
4873a571abcSchristos 				    XmNtopAttachment,		XmATTACH_FORM,
4883a571abcSchristos 				    XmNrightAttachment,		XmATTACH_FORM,
4893a571abcSchristos 				    XmNleftAttachment,		XmATTACH_FORM,
4903a571abcSchristos 				    0
4913a571abcSchristos 				    );
4923a571abcSchristos     str = XmStringCreateLtoR( sheet->description, XmSTRING_DEFAULT_CHARSET );
4933a571abcSchristos     XtVaCreateManagedWidget( "description",
4943a571abcSchristos 			     xmLabelGadgetClass,
4953a571abcSchristos 			     frame,
4963a571abcSchristos 			     XmNlabelString,		str,
4973a571abcSchristos 			     0
4983a571abcSchristos 			     );
4993a571abcSchristos     XmStringFree( str );
5003a571abcSchristos 
5013a571abcSchristos     /* Add the toggles. */
5023a571abcSchristos     inner = create_toggles( outer, sheet->toggles );
5033a571abcSchristos     XtVaSetValues( inner,
5043a571abcSchristos 		   XmNtopAttachment,	XmATTACH_WIDGET,
5053a571abcSchristos 		   XmNtopWidget,	frame,
5063a571abcSchristos 		   0
5073a571abcSchristos 		   );
5083a571abcSchristos 
5093a571abcSchristos     /* the string options go here */
5103a571abcSchristos     inner = XtVaCreateWidget( "otherOptions",
5113a571abcSchristos 			      xmRowColumnWidgetClass,
5123a571abcSchristos 			      outer,
5133a571abcSchristos 			      XmNpacking,		XmPACK_COLUMN,
5143a571abcSchristos 			      XmNtopAttachment,		XmATTACH_WIDGET,
5153a571abcSchristos 			      XmNtopWidget,		inner,
5163a571abcSchristos 			      XmNrightAttachment,	XmATTACH_FORM,
5173a571abcSchristos 			      XmNbottomAttachment,	XmATTACH_FORM,
5183a571abcSchristos 			      XmNleftAttachment,	XmATTACH_FORM,
5193a571abcSchristos 			      0
5203a571abcSchristos 			      );
5213a571abcSchristos 
5223a571abcSchristos     /* Optionally, the ints. */
5233a571abcSchristos     if ( sheet->ints != NULL )
5243a571abcSchristos 	add_string_options( inner, sheet->ints );
5253a571abcSchristos 
5263a571abcSchristos      /* Optionally, the rest. */
5273a571abcSchristos     if ( sheet->others != NULL )
5283a571abcSchristos 	add_string_options( inner, sheet->others );
5293a571abcSchristos 
5303a571abcSchristos     XtManageChild( inner );
5313a571abcSchristos 
5323a571abcSchristos     /* finally, force resize of the parent */
5333a571abcSchristos     XtVaGetValues( outer, XmNheight, &height, 0 );
5343a571abcSchristos     XtVaSetValues( parent, XmNheight, height, 0 );
5353a571abcSchristos 
5363a571abcSchristos     return outer;
5373a571abcSchristos }
5383a571abcSchristos 
5393a571abcSchristos 
5403a571abcSchristos /* change preferences to another sheet */
5413a571abcSchristos 
change_sheet(Widget parent,int current)5423a571abcSchristos static	void	change_sheet(Widget parent, int current)
5433a571abcSchristos {
5443a571abcSchristos     static int		current_sheet = -1;
5453a571abcSchristos 
5463a571abcSchristos     /* create a new one? */
5473a571abcSchristos     if ( sheets[current].holder == NULL )
5483a571abcSchristos 	sheets[current].holder = create_sheet( parent, &sheets[current] );
5493a571abcSchristos 
5503a571abcSchristos     /* done with the old one? */
5513a571abcSchristos     if ( current_sheet != -1 && sheets[current_sheet].holder != NULL )
5523a571abcSchristos 	XtUnmanageChild( sheets[current_sheet].holder );
5533a571abcSchristos 
5543a571abcSchristos     current_sheet = current;
5553a571abcSchristos     XtManageChild( sheets[current].holder );
5563a571abcSchristos     XtManageChild( parent );
5573a571abcSchristos }
5583a571abcSchristos 
5593a571abcSchristos 
5603a571abcSchristos /* Draw and display a dialog the describes vi options */
5613a571abcSchristos 
5623a571abcSchristos #if defined(__STDC__)
create_options_dialog(Widget parent,String title)5633a571abcSchristos static	Widget	create_options_dialog( Widget parent, String title )
5643a571abcSchristos #else
5653a571abcSchristos static	Widget	create_options_dialog( parent, title )
5663a571abcSchristos 	Widget	parent;
5673a571abcSchristos 	String	title;
5683a571abcSchristos #endif
5693a571abcSchristos {
5703a571abcSchristos     Widget	box, form, inner;
5713a571abcSchristos     int		i;
5723a571abcSchristos     char	buffer[1024];
5733a571abcSchristos 
5743a571abcSchristos     /* already built? */
5753a571abcSchristos     if ( preferences != NULL ) return preferences;
5763a571abcSchristos 
5773a571abcSchristos     box = XtVaCreatePopupShell( title,
5783a571abcSchristos 				xmDialogShellWidgetClass,
5793a571abcSchristos 				parent,
5803a571abcSchristos 				XmNtitle,		title,
5813a571abcSchristos 				XmNallowShellResize,	False,
5823a571abcSchristos 				0
5833a571abcSchristos 				);
5843a571abcSchristos     XtAddCallback( box, XmNpopdownCallback, __vi_cancel_cb, 0 );
5853a571abcSchristos     XtAddCallback( box, XmNdestroyCallback, destroyed, 0 );
5863a571abcSchristos     XtAddEventHandler( box,
5873a571abcSchristos 		       SubstructureNotifyMask,
5883a571abcSchristos 		       False,
5893a571abcSchristos 		       window_unmapped,
5903a571abcSchristos 		       NULL
5913a571abcSchristos 		       );
5923a571abcSchristos 
5933a571abcSchristos     form = XtVaCreateWidget( "options",
5943a571abcSchristos 			     xmFormWidgetClass,
5953a571abcSchristos 			     box,
5963a571abcSchristos 			     0
5973a571abcSchristos 			     );
5983a571abcSchristos 
5993a571abcSchristos     /* copy the pointers to the sheet names */
6003a571abcSchristos     *buffer = '\0';
6013a571abcSchristos     for (i=0; i<XtNumber(sheets); i++) {
6023a571abcSchristos 	strcat( buffer, "|" );
6033a571abcSchristos 	strcat( buffer, sheets[i].name );
6043a571abcSchristos     }
6053a571abcSchristos 
6063a571abcSchristos     inner = __vi_CreateTabbedFolder( "tabs",
6073a571abcSchristos 				    form,
6083a571abcSchristos 				    buffer,
6093a571abcSchristos 				    XtNumber(sheets),
6103a571abcSchristos 				    change_sheet
6113a571abcSchristos 				    );
6123a571abcSchristos 
6133a571abcSchristos     /* build the property sheets early */
6143a571abcSchristos     for ( i=0; i<XtNumber(sheets); i++ )
6153a571abcSchristos 	change_sheet( inner, i );
6163a571abcSchristos 
6173a571abcSchristos     /* manage all of the sheets right now */
6183a571abcSchristos     for ( i=0; i<XtNumber(sheets); i++ )
6193a571abcSchristos 	XtManageChild( sheets[i].holder );
6203a571abcSchristos     XtManageChild( form );
6213a571abcSchristos 
6223a571abcSchristos     /* remove all but the first one */
6233a571abcSchristos     for ( i=0; i<XtNumber(sheets); i++ )
6243a571abcSchristos 	XtUnmanageChild( sheets[i].holder );
6253a571abcSchristos     change_sheet( inner, 0 );	/* show first sheet first */
6263a571abcSchristos 
6273a571abcSchristos     /* keep this global, we might destroy it later */
6283a571abcSchristos     preferences = form;
6293a571abcSchristos 
6303a571abcSchristos     /* done */
6313a571abcSchristos     return form;
6323a571abcSchristos }
6333a571abcSchristos 
6343a571abcSchristos 
6353a571abcSchristos 
6363a571abcSchristos /*
6373a571abcSchristos  * module entry point
6383a571abcSchristos  *
6393a571abcSchristos  * __vi_show_options_dialog --
6403a571abcSchristos  *
6413a571abcSchristos  *
6423a571abcSchristos  * PUBLIC: void __vi_show_options_dialog __P((Widget, String));
6433a571abcSchristos  */
6443a571abcSchristos void
__vi_show_options_dialog(Widget parent,String title)6453a571abcSchristos __vi_show_options_dialog(Widget parent, String title)
6463a571abcSchristos {
6473a571abcSchristos     Widget 	db = create_options_dialog( parent, title );
6483a571abcSchristos #if defined(SelfTest)
6493a571abcSchristos     Widget	shell = XtParent( db );
6503a571abcSchristos #endif
6513a571abcSchristos 
6523a571abcSchristos     XtManageChild( db );
6533a571abcSchristos 
6543a571abcSchristos #if defined(SelfTest)
6553a571abcSchristos     /* wait until it goes away */
6563a571abcSchristos     XtPopup( shell, XtGrabNone );
6573a571abcSchristos #else
6583a571abcSchristos     /* wait until it goes away */
6593a571abcSchristos     __vi_modal_dialog( db );
6603a571abcSchristos #endif
6613a571abcSchristos }
6623a571abcSchristos 
6633a571abcSchristos 
6643a571abcSchristos 
6653a571abcSchristos /* module entry point
6663a571abcSchristos  * Utilities for the search dialog
6673a571abcSchristos  *
6683a571abcSchristos  * __vi_toggle --
6693a571abcSchristos  *	Returns the current value of a toggle.
6703a571abcSchristos  *
6713a571abcSchristos  * PUBLIC: int __vi_toggle __P((char *));
6723a571abcSchristos  */
6733a571abcSchristos int
__vi_toggle(char * name)6743a571abcSchristos __vi_toggle(char *name)
6753a571abcSchristos {
6763a571abcSchristos 	optData *opt;
6773a571abcSchristos 
6783a571abcSchristos #undef	NSEARCH
6793a571abcSchristos #define	NSEARCH(list) {							\
6803a571abcSchristos 	for (opt = list; opt->kind != optTerminator; ++opt)		\
6813a571abcSchristos 		if (!strcmp(opt->name, name))				\
6823a571abcSchristos 			return ((int)opt->value);			\
6833a571abcSchristos }
6843a571abcSchristos 	NSEARCH(display);
6853a571abcSchristos 	NSEARCH(files);
6863a571abcSchristos 	NSEARCH(general);
6873a571abcSchristos 	NSEARCH(input);
6883a571abcSchristos 	NSEARCH(search);
6893a571abcSchristos 
6903a571abcSchristos 	return (0);
6913a571abcSchristos }
6923a571abcSchristos 
6933a571abcSchristos /*
6943a571abcSchristos  * __vi_create_search_toggles --
6953a571abcSchristos  *	Creates the search toggles.  This is so the options and search widgets
6963a571abcSchristos  *	share their appearance.
6973a571abcSchristos  *
6983a571abcSchristos  * PUBLIC: Widget __vi_create_search_toggles __P((Widget, optData[]));
6993a571abcSchristos  */
7003a571abcSchristos Widget
__vi_create_search_toggles(Widget parent,optData * list)7013a571abcSchristos __vi_create_search_toggles(Widget parent, optData *list)
7023a571abcSchristos {
7033a571abcSchristos 	optData *opt;
7043a571abcSchristos 
7053a571abcSchristos 	/*
7063a571abcSchristos 	 * Copy current options information into the search table.
7073a571abcSchristos 	 *
7083a571abcSchristos 	 * XXX
7093a571abcSchristos 	 * This is an O(M*N) loop, but I don't think it matters.
7103a571abcSchristos 	 */
7113a571abcSchristos 	for (opt = list; opt->kind != optTerminator; ++opt)
7123a571abcSchristos 		opt->value = (void *)__vi_toggle(opt->name);
7133a571abcSchristos 
7143a571abcSchristos 	return (create_toggles(parent, list));
7153a571abcSchristos }
7163a571abcSchristos 
7173a571abcSchristos 
7183a571abcSchristos #if defined(SelfTest)
7193a571abcSchristos 
7203a571abcSchristos #if defined(__STDC__)
show_options(Widget w,XtPointer data,XtPointer cbs)7213a571abcSchristos static void show_options( Widget w, XtPointer data, XtPointer cbs )
7223a571abcSchristos #else
7233a571abcSchristos static void show_options( w, data, cbs )
7243a571abcSchristos Widget w;
7253a571abcSchristos XtPointer	data;
7263a571abcSchristos XtPointer	cbs;
7273a571abcSchristos #endif
7283a571abcSchristos {
7293a571abcSchristos     __vi_show_options_dialog( data, "Preferences" );
7303a571abcSchristos }
7313a571abcSchristos 
main(int argc,char * argv[])7323a571abcSchristos main( int argc, char *argv[] )
7333a571abcSchristos {
7343a571abcSchristos     XtAppContext	ctx;
7353a571abcSchristos     Widget		top_level, rc, button;
7363a571abcSchristos     extern		exit();
7373a571abcSchristos 
7383a571abcSchristos     /* create a top-level shell for the window manager */
7393a571abcSchristos     top_level = XtVaAppInitialize( &ctx,
7403a571abcSchristos 				   argv[0],
7413a571abcSchristos 				   NULL, 0,	/* options */
7423a571abcSchristos 				   (ArgcType) &argc,
7433a571abcSchristos 				   argv,	/* might get modified */
7443a571abcSchristos 				   NULL,
7453a571abcSchristos 				   NULL
7463a571abcSchristos 				   );
7473a571abcSchristos 
7483a571abcSchristos     rc = XtVaCreateManagedWidget( "rc",
7493a571abcSchristos 				  xmRowColumnWidgetClass,
7503a571abcSchristos 				  top_level,
7513a571abcSchristos 				  0
7523a571abcSchristos 				  );
7533a571abcSchristos 
7543a571abcSchristos     button = XtVaCreateManagedWidget( "Pop up options dialog",
7553a571abcSchristos 				      xmPushButtonGadgetClass,
7563a571abcSchristos 				      rc,
7573a571abcSchristos 				      0
7583a571abcSchristos 				      );
7593a571abcSchristos     XtAddCallback( button, XmNactivateCallback, show_options, rc );
7603a571abcSchristos 
7613a571abcSchristos     button = XtVaCreateManagedWidget( "Quit",
7623a571abcSchristos 				      xmPushButtonGadgetClass,
7633a571abcSchristos 				      rc,
7643a571abcSchristos 				      0
7653a571abcSchristos 				      );
7663a571abcSchristos     XtAddCallback( button, XmNactivateCallback, exit, 0 );
7673a571abcSchristos 
7683a571abcSchristos     XtRealizeWidget(top_level);
7693a571abcSchristos     XtAppMainLoop(ctx);
7703a571abcSchristos }
7713a571abcSchristos #endif
772