Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / nvi / motif_l / m_options.c
blob96921c6d68bcdaa32140863eec10b002ca58aa3c
1 /* $NetBSD$ */
3 /*-
4 * Copyright (c) 1996
5 * Rob Zimmermann. All rights reserved.
6 * Copyright (c) 1996
7 * Keith Bostic. All rights reserved.
9 * See the LICENSE file for redistribution information.
12 #include "config.h"
14 #ifndef lint
15 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";
16 #endif /* not lint */
18 #include <sys/types.h>
19 #include <sys/queue.h>
21 #include <X11/X.h>
22 #include <X11/Intrinsic.h>
23 #include <Xm/DialogS.h>
24 #include <Xm/Form.h>
25 #include <Xm/Frame.h>
26 #include <Xm/LabelG.h>
27 #include <Xm/PushBG.h>
28 #include <Xm/TextF.h>
29 #include <Xm/ToggleBG.h>
30 #include <Xm/RowColumn.h>
32 #include <bitstring.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
37 #undef LOCK_SUCCESS
38 #include "../common/common.h"
39 #include "../ipc/ip.h"
40 #include "m_motif.h"
42 extern int vi_ofd;
44 static void set_opt __P((Widget, XtPointer, XtPointer));
47 /* constants */
49 #if defined(SelfTest)
51 /* in production, get these from the resource list */
53 #define toggleColumns 6
55 #endif
59 * global data
62 static Widget preferences = NULL;
64 static optData display[] = {
65 { optToggle, "comment", },
66 { optToggle, "flash", },
67 { optToggle, "leftright", },
68 { optToggle, "list", },
69 { optToggle, "number", },
70 { optToggle, "octal", },
71 { optToggle, "ruler", },
72 { optToggle, "showmode", },
73 { optToggle, "slowopen", },
74 { optToggle, "verbose", },
75 { optToggle, "windowname", },
76 { optTerminator, },
77 }, display_int[] = {
78 { optInteger, "report", },
79 { optInteger, "scroll", },
80 { optInteger, "shiftwidth", },
81 { optInteger, "sidescroll", },
82 { optInteger, "tabstop", },
83 { optInteger, "window", },
84 { optTerminator, },
85 }, display_str[] = {
86 { optString, "noprint", },
87 { optString, "print", },
88 { optTerminator, },
89 }, files[] = {
90 { optToggle, "autowrite", },
91 { optToggle, "lock", },
92 { optToggle, "readonly", },
93 { optToggle, "writeany", },
94 { optTerminator, },
95 }, files_str[] = {
96 { optString, "backup", },
97 { optString, "path", },
98 { optTerminator, },
99 }, general[] = {
100 { optToggle, "exrc", },
101 { optToggle, "lisp", },
102 { optToggle, "modeline", },
103 { optToggle, "sourceany", },
104 { optToggle, "tildeop", },
105 { optTerminator, },
106 }, general_int[] = {
107 { optInteger, "taglength", },
108 { optTerminator, },
109 }, general_str[] = {
110 { optString, "cdpath", },
111 { optString, "directory", },
112 { optString, "msgcat", },
113 { optString, "recdir", },
114 { optString, "shell", },
115 { optString, "shellmeta", },
116 { optString, "tags", },
117 { optTerminator, },
118 }, input[] = {
119 { optToggle, "altwerase", },
120 { optToggle, "autoindent", },
121 { optToggle, "remap", },
122 { optToggle, "showmatch", },
123 { optToggle, "ttywerase", },
124 { optTerminator, },
125 }, input_int[] = {
126 { optInteger, "escapetime", },
127 { optInteger, "keytime", },
128 { optInteger, "matchtime", },
129 { optInteger, "timeout", },
130 { optInteger, "wraplen", },
131 { optInteger, "wrapmargin", },
132 { optTerminator, },
133 }, input_str[] = {
134 { optString, "cedit", },
135 { optString, "filec", },
136 { optTerminator, },
137 }, search[] = {
138 { optToggle, "extended", },
139 { optToggle, "iclower", },
140 { optToggle, "ignorecase", },
141 { optToggle, "magic", },
142 { optToggle, "searchincr", },
143 { optToggle, "wrapscan", },
144 { optTerminator, },
145 }, search_str[] = {
146 { optString, "paragraphs", },
147 { optString, "sections", },
148 { optTerminator, },
151 /* ********* NOTE ***********
152 * Sheet 0 will always be shown first. It does not matter to the Xt code
153 * which sheet that is, so it ought to be the one users interact with most.
154 * Best guess is that's general editor options, but it might be Search/re.
155 * ********* NOTE ***********
157 static optSheet sheets[] = {
158 { "Display",
159 "These options control how text is displayed on the screen",
160 NULL,
161 display,
162 display_int,
163 display_str,
165 { "Files",
166 "These options control how the editor handles files",
167 NULL,
168 files,
169 NULL,
170 files_str,
172 { "Input",
173 "These options control text input behavior",
174 NULL,
175 input,
176 input_int,
177 input_str,
179 { "Search/RE",
180 "These options control searching and Regular Expression behavior",
181 NULL,
182 search,
183 NULL,
184 search_str,
186 { "Editor",
187 "These options control general editor configuration",
188 NULL,
189 general,
190 general_int,
191 general_str,
196 /* callbacks */
198 #if defined(SelfTest)
199 void __vi_cancel_cb()
201 puts( "cancelled" );
203 #endif
206 static void destroyed(void)
208 int i;
210 puts( "destroyed" );
212 /* some window managers destroy us upon popdown */
213 for (i=0; i<XtNumber(sheets); i++) {
214 sheets[i].holder = NULL;
216 preferences = NULL;
220 static void window_unmapped(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont)
222 if ( ev->type == UnmapNotify ) {
223 #if defined(SelfTest)
224 puts( "unmapped" );
225 #endif
226 XtPopdown( XtParent( preferences ) );
231 * __vi_editopt --
232 * Set an edit option based on a core message.
234 * PUBLIC: int __vi_editopt __P((IPVI *, const char *, u_int32_t, const char *, u_int32_t, u_int32_t));
237 __vi_editopt(IPVI *ipvi, const char *str1, u_int32_t len1, const char *str2, u_int32_t len2, u_int32_t val1)
239 optData *opt;
241 #undef NSEARCH
242 #define NSEARCH(list) { \
243 for (opt = list; opt->kind != optTerminator; ++opt) \
244 if (!strcmp(opt->name, str1)) \
245 goto found; \
248 NSEARCH(display);
249 NSEARCH(display_int);
250 NSEARCH(display_str);
251 NSEARCH(files);
252 NSEARCH(files_str);
253 NSEARCH(general);
254 NSEARCH(general_int);
255 NSEARCH(general_str);
256 NSEARCH(input);
257 NSEARCH(input_int);
258 NSEARCH(input_str);
259 NSEARCH(search);
260 NSEARCH(search_str);
262 return (0);
264 found: switch (opt->kind) {
265 case optToggle:
266 opt->value = (void *)val1;
267 break;
268 case optInteger:
269 if (opt->value != NULL)
270 free(opt->value);
271 if ((opt->value = malloc(8)) != NULL)
272 (void)snprintf(opt->value,
273 8, "%lu", (u_long)val1);
274 break;
275 case optString:
276 case optFile:
277 if (opt->value != NULL)
278 free(opt->value);
279 if ((opt->value = malloc(len2)) != NULL)
280 memcpy(opt->value, str2, len2);
281 break;
282 case optTerminator:
283 abort();
285 return (0);
289 * set_opt --
290 * Send a set-edit-option message to core.
292 static void
293 set_opt(Widget w, XtPointer closure, XtPointer call_data)
295 optData *opt;
296 Boolean set;
297 IP_BUF ipb;
298 String str;
299 extern IPVI ipvi_motif;
301 opt = closure;
303 ipb.code = VI_EDITOPT;
304 ipb.str1 = opt->name;
305 ipb.len1 = strlen(opt->name);
307 switch (opt->kind) {
308 case optToggle:
309 XtVaGetValues(w, XmNset, &set, 0);
310 ipb.val1 = set;
311 ipb.len2 = 0;
313 vi_wsend(&ipvi_motif, "ab1", &ipb);
314 if (ipb.val1) {
315 opt->value = (void *)!set;
317 * RAZ:
318 * How do we turn off the button? We don't want to
319 * go recursive where we set it and it calls set_opt
320 * to tell the core. Is that possible?
322 XtVaSetValues(w, XmNset, &set, 0);
323 break;
326 if (strcmp(opt->name, "ruler") == 0)
327 if (set)
328 __vi_show_text_ruler_dialog(
329 __vi_screen->area, "Ruler");
330 else
331 __vi_clear_text_ruler_dialog();
332 break;
333 case optInteger:
334 str = XmTextFieldGetString(w);
335 ipb.val1 = atoi(str);
336 ipb.len2 = 0;
337 vi_send(vi_ofd, "ab1", &ipb);
338 break;
339 case optFile:
340 case optString:
341 ipb.str2 = XmTextFieldGetString(w);
342 ipb.len2 = strlen(ipb.str2);
343 vi_send(vi_ofd, "ab1", &ipb);
344 break;
345 case optTerminator:
346 abort();
351 /* add toggles to the property sheet */
353 #if defined(__STDC__)
354 static void add_toggle( Widget parent, optData *option )
355 #else
356 static void add_toggle( parent, option )
357 Widget parent;
358 optData *option;
359 #endif
361 Widget w;
363 w = XtVaCreateManagedWidget( option->name,
364 xmToggleButtonGadgetClass,
365 parent,
366 XmNset, (Boolean) option->value,
369 XtAddCallback( w, XmNvalueChangedCallback, set_opt, option );
373 static Widget create_toggles(Widget outer, optData *toggles)
375 Widget inner;
376 int i;
378 inner = XtVaCreateWidget( "toggleOptions",
379 xmRowColumnWidgetClass,
380 outer,
381 XmNpacking, XmPACK_COLUMN,
382 XmNnumColumns, 4,
383 XmNtopAttachment, XmATTACH_FORM,
384 XmNrightAttachment, XmATTACH_FORM,
385 XmNleftAttachment, XmATTACH_FORM,
389 /* first the booleans */
390 for (i=0; toggles[i].kind != optTerminator; i++) {
391 add_toggle( inner, &toggles[i] );
393 XtManageChild( inner );
395 return inner;
399 /* draw text fields and their labels */
401 #if defined(__STDC__)
402 static void add_string_options( Widget parent,
403 optData *options
405 #else
406 static void add_string_options( parent, options )
407 Widget parent;
408 optData *options;
409 #endif
411 int i;
412 Widget f, w;
414 for ( i=0; options[i].kind != optTerminator; i++ ) {
416 f = XtVaCreateWidget( "form",
417 xmFormWidgetClass,
418 parent,
422 XtVaCreateManagedWidget( options[i].name,
423 xmLabelGadgetClass,
425 XmNtopAttachment, XmATTACH_FORM,
426 XmNbottomAttachment, XmATTACH_FORM,
427 XmNleftAttachment, XmATTACH_FORM,
428 XmNrightAttachment, XmATTACH_POSITION,
429 XmNrightPosition, 20,
430 XmNalignment, XmALIGNMENT_END,
434 w = XtVaCreateManagedWidget( "text",
435 xmTextFieldWidgetClass,
437 XmNtopAttachment, XmATTACH_FORM,
438 XmNbottomAttachment, XmATTACH_FORM,
439 XmNrightAttachment, XmATTACH_FORM,
440 XmNleftAttachment, XmATTACH_POSITION,
441 XmNleftPosition, 20,
445 XmTextFieldSetString( w, (char *) options[i].value );
446 XtAddCallback( w, XmNactivateCallback, set_opt, &options[i] );
447 XtManageChild( f );
452 /* draw and display a single page of properties */
454 #if defined(__STDC__)
455 static Widget create_sheet( Widget parent, optSheet *sheet )
456 #else
457 static Widget create_sheet( parent, sheet )
458 Widget parent;
459 optSheet *sheet;
460 #endif
462 Widget outer, inner, frame;
463 Dimension height;
464 XmString str;
466 outer = XtVaCreateWidget( sheet->name,
467 xmFormWidgetClass,
468 parent,
469 XmNtopAttachment, XmATTACH_FORM,
470 XmNrightAttachment, XmATTACH_FORM,
471 XmNbottomAttachment, XmATTACH_FORM,
472 XmNleftAttachment, XmATTACH_FORM,
473 XmNshadowType, XmSHADOW_ETCHED_IN,
474 XmNshadowThickness, 2,
475 XmNverticalSpacing, 4,
476 XmNhorizontalSpacing, 4,
480 /* add descriptive text */
481 frame = XtVaCreateManagedWidget( "frame",
482 xmFrameWidgetClass,
483 outer,
484 XmNtopAttachment, XmATTACH_FORM,
485 XmNrightAttachment, XmATTACH_FORM,
486 XmNleftAttachment, XmATTACH_FORM,
489 str = XmStringCreateLtoR( sheet->description, XmSTRING_DEFAULT_CHARSET );
490 XtVaCreateManagedWidget( "description",
491 xmLabelGadgetClass,
492 frame,
493 XmNlabelString, str,
496 XmStringFree( str );
498 /* Add the toggles. */
499 inner = create_toggles( outer, sheet->toggles );
500 XtVaSetValues( inner,
501 XmNtopAttachment, XmATTACH_WIDGET,
502 XmNtopWidget, frame,
506 /* the string options go here */
507 inner = XtVaCreateWidget( "otherOptions",
508 xmRowColumnWidgetClass,
509 outer,
510 XmNpacking, XmPACK_COLUMN,
511 XmNtopAttachment, XmATTACH_WIDGET,
512 XmNtopWidget, inner,
513 XmNrightAttachment, XmATTACH_FORM,
514 XmNbottomAttachment, XmATTACH_FORM,
515 XmNleftAttachment, XmATTACH_FORM,
519 /* Optionally, the ints. */
520 if ( sheet->ints != NULL )
521 add_string_options( inner, sheet->ints );
523 /* Optionally, the rest. */
524 if ( sheet->others != NULL )
525 add_string_options( inner, sheet->others );
527 XtManageChild( inner );
529 /* finally, force resize of the parent */
530 XtVaGetValues( outer, XmNheight, &height, 0 );
531 XtVaSetValues( parent, XmNheight, height, 0 );
533 return outer;
537 /* change preferences to another sheet */
539 static void change_sheet(Widget parent, int current)
541 static int current_sheet = -1;
543 /* create a new one? */
544 if ( sheets[current].holder == NULL )
545 sheets[current].holder = create_sheet( parent, &sheets[current] );
547 /* done with the old one? */
548 if ( current_sheet != -1 && sheets[current_sheet].holder != NULL )
549 XtUnmanageChild( sheets[current_sheet].holder );
551 current_sheet = current;
552 XtManageChild( sheets[current].holder );
553 XtManageChild( parent );
557 /* Draw and display a dialog the describes vi options */
559 #if defined(__STDC__)
560 static Widget create_options_dialog( Widget parent, String title )
561 #else
562 static Widget create_options_dialog( parent, title )
563 Widget parent;
564 String title;
565 #endif
567 Widget box, form, inner;
568 int i;
569 char buffer[1024];
571 /* already built? */
572 if ( preferences != NULL ) return preferences;
574 box = XtVaCreatePopupShell( title,
575 xmDialogShellWidgetClass,
576 parent,
577 XmNtitle, title,
578 XmNallowShellResize, False,
581 XtAddCallback( box, XmNpopdownCallback, __vi_cancel_cb, 0 );
582 XtAddCallback( box, XmNdestroyCallback, destroyed, 0 );
583 XtAddEventHandler( box,
584 SubstructureNotifyMask,
585 False,
586 window_unmapped,
587 NULL
590 form = XtVaCreateWidget( "options",
591 xmFormWidgetClass,
592 box,
596 /* copy the pointers to the sheet names */
597 *buffer = '\0';
598 for (i=0; i<XtNumber(sheets); i++) {
599 strcat( buffer, "|" );
600 strcat( buffer, sheets[i].name );
603 inner = __vi_CreateTabbedFolder( "tabs",
604 form,
605 buffer,
606 XtNumber(sheets),
607 change_sheet
610 /* build the property sheets early */
611 for ( i=0; i<XtNumber(sheets); i++ )
612 change_sheet( inner, i );
614 /* manage all of the sheets right now */
615 for ( i=0; i<XtNumber(sheets); i++ )
616 XtManageChild( sheets[i].holder );
617 XtManageChild( form );
619 /* remove all but the first one */
620 for ( i=0; i<XtNumber(sheets); i++ )
621 XtUnmanageChild( sheets[i].holder );
622 change_sheet( inner, 0 ); /* show first sheet first */
624 /* keep this global, we might destroy it later */
625 preferences = form;
627 /* done */
628 return form;
634 * module entry point
636 * __vi_show_options_dialog --
639 * PUBLIC: void __vi_show_options_dialog __P((Widget, String));
641 void
642 __vi_show_options_dialog(Widget parent, String title)
644 Widget db = create_options_dialog( parent, title );
645 #if defined(SelfTest)
646 Widget shell = XtParent( db );
647 #endif
649 XtManageChild( db );
651 #if defined(SelfTest)
652 /* wait until it goes away */
653 XtPopup( shell, XtGrabNone );
654 #else
655 /* wait until it goes away */
656 __vi_modal_dialog( db );
657 #endif
662 /* module entry point
663 * Utilities for the search dialog
665 * __vi_toggle --
666 * Returns the current value of a toggle.
668 * PUBLIC: int __vi_toggle __P((char *));
671 __vi_toggle(char *name)
673 optData *opt;
675 #undef NSEARCH
676 #define NSEARCH(list) { \
677 for (opt = list; opt->kind != optTerminator; ++opt) \
678 if (!strcmp(opt->name, name)) \
679 return ((int)opt->value); \
681 NSEARCH(display);
682 NSEARCH(files);
683 NSEARCH(general);
684 NSEARCH(input);
685 NSEARCH(search);
687 return (0);
691 * __vi_create_search_toggles --
692 * Creates the search toggles. This is so the options and search widgets
693 * share their appearance.
695 * PUBLIC: Widget __vi_create_search_toggles __P((Widget, optData[]));
697 Widget
698 __vi_create_search_toggles(Widget parent, optData *list)
700 optData *opt;
703 * Copy current options information into the search table.
705 * XXX
706 * This is an O(M*N) loop, but I don't think it matters.
708 for (opt = list; opt->kind != optTerminator; ++opt)
709 opt->value = (void *)__vi_toggle(opt->name);
711 return (create_toggles(parent, list));
715 #if defined(SelfTest)
717 #if defined(__STDC__)
718 static void show_options( Widget w, XtPointer data, XtPointer cbs )
719 #else
720 static void show_options( w, data, cbs )
721 Widget w;
722 XtPointer data;
723 XtPointer cbs;
724 #endif
726 __vi_show_options_dialog( data, "Preferences" );
729 main( int argc, char *argv[] )
731 XtAppContext ctx;
732 Widget top_level, rc, button;
733 extern exit();
735 /* create a top-level shell for the window manager */
736 top_level = XtVaAppInitialize( &ctx,
737 argv[0],
738 NULL, 0, /* options */
739 (ArgcType) &argc,
740 argv, /* might get modified */
741 NULL,
742 NULL
745 rc = XtVaCreateManagedWidget( "rc",
746 xmRowColumnWidgetClass,
747 top_level,
751 button = XtVaCreateManagedWidget( "Pop up options dialog",
752 xmPushButtonGadgetClass,
756 XtAddCallback( button, XmNactivateCallback, show_options, rc );
758 button = XtVaCreateManagedWidget( "Quit",
759 xmPushButtonGadgetClass,
763 XtAddCallback( button, XmNactivateCallback, exit, 0 );
765 XtRealizeWidget(top_level);
766 XtAppMainLoop(ctx);
768 #endif