3 * Rob Zimmermann. All rights reserved.
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
13 static const char sccsid
[] = "$Id: m_options.c,v 8.18 1997/08/02 16:50:10 bostic Exp $ (Berkeley) $Date: 1997/08/02 16:50:10 $";
16 #include <sys/types.h>
17 #include <sys/queue.h>
20 #include <X11/Intrinsic.h>
21 #include <Xm/DialogS.h>
24 #include <Xm/LabelG.h>
25 #include <Xm/PushBG.h>
27 #include <Xm/ToggleBG.h>
28 #include <Xm/RowColumn.h>
30 #include <bitstring.h>
35 #include "../common/common.h"
36 #include "../ipc/ip.h"
39 static void set_opt
__P((Widget
, XtPointer
, XtPointer
));
46 /* in production, get these from the resource list */
48 #define toggleColumns 6
57 static Widget preferences
= NULL
;
59 static optData display
[] = {
60 { optToggle
, "comment", },
61 { optToggle
, "flash", },
62 { optToggle
, "leftright", },
63 { optToggle
, "list", },
64 { optToggle
, "number", },
65 { optToggle
, "octal", },
66 { optToggle
, "ruler", },
67 { optToggle
, "showmode", },
68 { optToggle
, "slowopen", },
69 { optToggle
, "verbose", },
70 { optToggle
, "windowname", },
73 { optInteger
, "report", },
74 { optInteger
, "scroll", },
75 { optInteger
, "shiftwidth", },
76 { optInteger
, "sidescroll", },
77 { optInteger
, "tabstop", },
78 { optInteger
, "window", },
81 { optString
, "noprint", },
82 { optString
, "print", },
85 { optToggle
, "autowrite", },
86 { optToggle
, "lock", },
87 { optToggle
, "readonly", },
88 { optToggle
, "writeany", },
91 { optString
, "backup", },
92 { optString
, "path", },
95 { optToggle
, "exrc", },
96 { optToggle
, "lisp", },
97 { optToggle
, "modeline", },
98 { optToggle
, "sourceany", },
99 { optToggle
, "tildeop", },
102 { optInteger
, "taglength", },
105 { optString
, "cdpath", },
106 { optString
, "directory", },
107 { optString
, "msgcat", },
108 { optString
, "recdir", },
109 { optString
, "shell", },
110 { optString
, "shellmeta", },
111 { optString
, "tags", },
114 { optToggle
, "altwerase", },
115 { optToggle
, "autoindent", },
116 { optToggle
, "remap", },
117 { optToggle
, "showmatch", },
118 { optToggle
, "ttywerase", },
121 { optInteger
, "escapetime", },
122 { optInteger
, "keytime", },
123 { optInteger
, "matchtime", },
124 { optInteger
, "timeout", },
125 { optInteger
, "wraplen", },
126 { optInteger
, "wrapmargin", },
129 { optString
, "cedit", },
130 { optString
, "filec", },
133 { optToggle
, "extended", },
134 { optToggle
, "iclower", },
135 { optToggle
, "ignorecase", },
136 { optToggle
, "magic", },
137 { optToggle
, "searchincr", },
138 { optToggle
, "wrapscan", },
141 { optString
, "paragraphs", },
142 { optString
, "sections", },
146 /* ********* NOTE ***********
147 * Sheet 0 will always be shown first. It does not matter to the Xt code
148 * which sheet that is, so it ought to be the one users interact with most.
149 * Best guess is that's general editor options, but it might be Search/re.
150 * ********* NOTE ***********
152 static optSheet sheets
[] = {
154 "These options control how text is displayed on the screen",
161 "These options control how the editor handles files",
168 "These options control text input behavior",
175 "These options control searching and Regular Expression behavior",
182 "These options control general editor configuration",
193 #if defined(SelfTest)
194 void __vi_cancel_cb()
201 static void destroyed()
207 /* some window managers destroy us upon popdown */
208 for (i
=0; i
<XtNumber(sheets
); i
++) {
209 sheets
[i
].holder
= NULL
;
215 static void window_unmapped( w
, ptr
, ev
, cont
)
221 if ( ev
->type
== UnmapNotify
) {
222 #if defined(SelfTest)
225 XtPopdown( XtParent( preferences
) );
231 * Set an edit option based on a core message.
233 * PUBLIC: int __vi_editopt __P((IP_BUF *));
242 #define NSEARCH(list) { \
243 for (opt = list; opt->kind != optTerminator; ++opt) \
244 if (!strcmp(opt->name, ipbp->str1)) \
249 NSEARCH(display_int
);
250 NSEARCH(display_str
);
254 NSEARCH(general_int
);
255 NSEARCH(general_str
);
264 found
: switch (opt
->kind
) {
266 opt
->value
= (void *)ipbp
->val1
;
269 if (opt
->value
!= NULL
)
271 if ((opt
->value
= malloc(8)) != NULL
)
272 (void)snprintf(opt
->value
,
273 8, "%lu", (u_long
)ipbp
->val1
);
277 if (opt
->value
!= NULL
)
279 if ((opt
->value
= malloc(ipbp
->len2
)) != NULL
)
280 memcpy(opt
->value
, ipbp
->str2
, ipbp
->len2
);
290 * Send a set-edit-option message to core.
293 set_opt(w
, closure
, call_data
)
295 XtPointer closure
, call_data
;
304 ipb
.code
= VI_EDITOPT
;
305 ipb
.str1
= opt
->name
;
306 ipb
.len1
= strlen(opt
->name
);
310 XtVaGetValues(w
, XmNset
, &set
, 0);
314 vi_wsend("ab1", &ipb
);
316 opt
->value
= (void *)!set
;
319 * How do we turn off the button? We don't want to
320 * go recursive where we set it and it calls set_opt
321 * to tell the core. Is that possible?
323 XtVaSetValues(w
, XmNset
, &set
, 0);
327 if (strcmp(opt
->name
, "ruler") == 0)
329 __vi_show_text_ruler_dialog(
330 __vi_screen
->area
, "Ruler");
332 __vi_clear_text_ruler_dialog();
335 str
= XmTextFieldGetString(w
);
336 ipb
.val1
= atoi(str
);
338 vi_send("ab1", &ipb
);
342 ipb
.str2
= XmTextFieldGetString(w
);
343 ipb
.len2
= strlen(ipb
.str2
);
344 vi_send("ab1", &ipb
);
352 /* add toggles to the property sheet */
354 #if defined(__STDC__)
355 static void add_toggle( Widget parent
, optData
*option
)
357 static void add_toggle( parent
, option
)
364 w
= XtVaCreateManagedWidget( option
->name
,
365 xmToggleButtonGadgetClass
,
367 XmNset
, (Boolean
) option
->value
,
370 XtAddCallback( w
, XmNvalueChangedCallback
, set_opt
, option
);
374 static Widget
create_toggles( outer
, toggles
)
381 inner
= XtVaCreateWidget( "toggleOptions",
382 xmRowColumnWidgetClass
,
384 XmNpacking
, XmPACK_COLUMN
,
386 XmNtopAttachment
, XmATTACH_FORM
,
387 XmNrightAttachment
, XmATTACH_FORM
,
388 XmNleftAttachment
, XmATTACH_FORM
,
392 /* first the booleans */
393 for (i
=0; toggles
[i
].kind
!= optTerminator
; i
++) {
394 add_toggle( inner
, &toggles
[i
] );
396 XtManageChild( inner
);
402 /* draw text fields and their labels */
404 #if defined(__STDC__)
405 static void add_string_options( Widget parent
,
409 static void add_string_options( parent
, options
)
417 for ( i
=0; options
[i
].kind
!= optTerminator
; i
++ ) {
419 f
= XtVaCreateWidget( "form",
425 XtVaCreateManagedWidget( options
[i
].name
,
428 XmNtopAttachment
, XmATTACH_FORM
,
429 XmNbottomAttachment
, XmATTACH_FORM
,
430 XmNleftAttachment
, XmATTACH_FORM
,
431 XmNrightAttachment
, XmATTACH_POSITION
,
432 XmNrightPosition
, 20,
433 XmNalignment
, XmALIGNMENT_END
,
437 w
= XtVaCreateManagedWidget( "text",
438 xmTextFieldWidgetClass
,
440 XmNtopAttachment
, XmATTACH_FORM
,
441 XmNbottomAttachment
, XmATTACH_FORM
,
442 XmNrightAttachment
, XmATTACH_FORM
,
443 XmNleftAttachment
, XmATTACH_POSITION
,
448 XmTextFieldSetString( w
, (char *) options
[i
].value
);
449 XtAddCallback( w
, XmNactivateCallback
, set_opt
, &options
[i
] );
455 /* draw and display a single page of properties */
457 #if defined(__STDC__)
458 static Widget
create_sheet( Widget parent
, optSheet
*sheet
)
460 static Widget
create_sheet( parent
, sheet
)
465 Widget outer
, inner
, frame
;
469 outer
= XtVaCreateWidget( sheet
->name
,
472 XmNtopAttachment
, XmATTACH_FORM
,
473 XmNrightAttachment
, XmATTACH_FORM
,
474 XmNbottomAttachment
, XmATTACH_FORM
,
475 XmNleftAttachment
, XmATTACH_FORM
,
476 XmNshadowType
, XmSHADOW_ETCHED_IN
,
477 XmNshadowThickness
, 2,
478 XmNverticalSpacing
, 4,
479 XmNhorizontalSpacing
, 4,
483 /* add descriptive text */
484 frame
= XtVaCreateManagedWidget( "frame",
487 XmNtopAttachment
, XmATTACH_FORM
,
488 XmNrightAttachment
, XmATTACH_FORM
,
489 XmNleftAttachment
, XmATTACH_FORM
,
492 str
= XmStringCreateLtoR( sheet
->description
, XmSTRING_DEFAULT_CHARSET
);
493 XtVaCreateManagedWidget( "description",
501 /* Add the toggles. */
502 inner
= create_toggles( outer
, sheet
->toggles
);
503 XtVaSetValues( inner
,
504 XmNtopAttachment
, XmATTACH_WIDGET
,
509 /* the string options go here */
510 inner
= XtVaCreateWidget( "otherOptions",
511 xmRowColumnWidgetClass
,
513 XmNpacking
, XmPACK_COLUMN
,
514 XmNtopAttachment
, XmATTACH_WIDGET
,
516 XmNrightAttachment
, XmATTACH_FORM
,
517 XmNbottomAttachment
, XmATTACH_FORM
,
518 XmNleftAttachment
, XmATTACH_FORM
,
522 /* Optionally, the ints. */
523 if ( sheet
->ints
!= NULL
)
524 add_string_options( inner
, sheet
->ints
);
526 /* Optionally, the rest. */
527 if ( sheet
->others
!= NULL
)
528 add_string_options( inner
, sheet
->others
);
530 XtManageChild( inner
);
532 /* finally, force resize of the parent */
533 XtVaGetValues( outer
, XmNheight
, &height
, 0 );
534 XtVaSetValues( parent
, XmNheight
, height
, 0 );
540 /* change preferences to another sheet */
542 static void change_sheet( parent
, current
)
546 static int current_sheet
= -1;
548 /* create a new one? */
549 if ( sheets
[current
].holder
== NULL
)
550 sheets
[current
].holder
= create_sheet( parent
, &sheets
[current
] );
552 /* done with the old one? */
553 if ( current_sheet
!= -1 && sheets
[current_sheet
].holder
!= NULL
)
554 XtUnmanageChild( sheets
[current_sheet
].holder
);
556 current_sheet
= current
;
557 XtManageChild( sheets
[current
].holder
);
558 XtManageChild( parent
);
562 /* Draw and display a dialog the describes vi options */
564 #if defined(__STDC__)
565 static Widget
create_options_dialog( Widget parent
, String title
)
567 static Widget
create_options_dialog( parent
, title
)
572 Widget box
, form
, inner
;
577 if ( preferences
!= NULL
) return preferences
;
579 box
= XtVaCreatePopupShell( title
,
580 xmDialogShellWidgetClass
,
583 XmNallowShellResize
, False
,
586 XtAddCallback( box
, XmNpopdownCallback
, __vi_cancel_cb
, 0 );
587 XtAddCallback( box
, XmNdestroyCallback
, destroyed
, 0 );
588 XtAddEventHandler( box
,
589 SubstructureNotifyMask
,
595 form
= XtVaCreateWidget( "options",
601 /* copy the pointers to the sheet names */
603 for (i
=0; i
<XtNumber(sheets
); i
++) {
604 strcat( buffer
, "|" );
605 strcat( buffer
, sheets
[i
].name
);
608 inner
= __vi_CreateTabbedFolder( "tabs",
615 /* build the property sheets early */
616 for ( i
=0; i
<XtNumber(sheets
); i
++ )
617 change_sheet( inner
, i
);
619 /* manage all of the sheets right now */
620 for ( i
=0; i
<XtNumber(sheets
); i
++ )
621 XtManageChild( sheets
[i
].holder
);
622 XtManageChild( form
);
624 /* remove all but the first one */
625 for ( i
=0; i
<XtNumber(sheets
); i
++ )
626 XtUnmanageChild( sheets
[i
].holder
);
627 change_sheet( inner
, 0 ); /* show first sheet first */
629 /* keep this global, we might destroy it later */
641 * __vi_show_options_dialog --
644 * PUBLIC: void __vi_show_options_dialog __P((Widget, String));
647 __vi_show_options_dialog(parent
, title
)
651 Widget db
= create_options_dialog( parent
, title
);
652 #if defined(SelfTest)
653 Widget shell
= XtParent( db
);
658 #if defined(SelfTest)
659 /* wait until it goes away */
660 XtPopup( shell
, XtGrabNone
);
662 /* wait until it goes away */
663 __vi_modal_dialog( db
);
669 /* module entry point
670 * Utilities for the search dialog
673 * Returns the current value of a toggle.
675 * PUBLIC: int __vi_toggle __P((char *));
684 #define NSEARCH(list) { \
685 for (opt = list; opt->kind != optTerminator; ++opt) \
686 if (!strcmp(opt->name, name)) \
687 return ((int)opt->value); \
699 * __vi_create_search_toggles --
700 * Creates the search toggles. This is so the options and search widgets
701 * share their appearance.
703 * PUBLIC: Widget __vi_create_search_toggles __P((Widget, optData[]));
706 __vi_create_search_toggles(parent
, list
)
713 * Copy current options information into the search table.
716 * This is an O(M*N) loop, but I don't think it matters.
718 for (opt
= list
; opt
->kind
!= optTerminator
; ++opt
)
719 opt
->value
= (void *)__vi_toggle(opt
->name
);
721 return (create_toggles(parent
, list
));
725 #if defined(SelfTest)
727 #if defined(__STDC__)
728 static void show_options( Widget w
, XtPointer data
, XtPointer cbs
)
730 static void show_options( w
, data
, cbs
)
736 __vi_show_options_dialog( data
, "Preferences" );
739 main( int argc
, char *argv
[] )
742 Widget top_level
, rc
, button
;
745 /* create a top-level shell for the window manager */
746 top_level
= XtVaAppInitialize( &ctx
,
748 NULL
, 0, /* options */
750 argv
, /* might get modified */
755 rc
= XtVaCreateManagedWidget( "rc",
756 xmRowColumnWidgetClass
,
761 button
= XtVaCreateManagedWidget( "Pop up options dialog",
762 xmPushButtonGadgetClass
,
766 XtAddCallback( button
, XmNactivateCallback
, show_options
, rc
);
768 button
= XtVaCreateManagedWidget( "Quit",
769 xmPushButtonGadgetClass
,
773 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
775 XtRealizeWidget(top_level
);