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.16 1996/12/20 10:29:10 bostic Exp $ (Berkeley) $Date: 1996/12/20 10:29: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
, "window", },
71 { optToggle
, "windowname", },
74 { optInteger
, "report", },
75 { optInteger
, "scroll", },
76 { optInteger
, "shiftwidth", },
77 { optInteger
, "sidescroll", },
78 { optInteger
, "tabstop", },
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 the general configuration\n\
155 and the editor as a whole",
162 "These options control the way things are displayed on the screen",
169 "These options globally modify how the editor handles files",
176 "These options modify how text input behaves",
183 "These options modify searches and regular expression",
194 #if defined(SelfTest)
195 void __vi_cancel_cb()
202 static void destroyed()
208 /* some window managers destroy us upon popdown */
209 for (i
=0; i
<XtNumber(sheets
); i
++) {
210 sheets
[i
].holder
= NULL
;
216 static void window_unmapped( w
, ptr
, ev
, cont
)
222 if ( ev
->type
== UnmapNotify
) {
223 #if defined(SelfTest)
226 XtPopdown( XtParent( preferences
) );
232 * Set an edit option based on a core message.
234 * PUBLIC: int __vi_editopt __P((IP_BUF *));
243 #define NSEARCH(list) { \
244 for (opt = list; opt->kind != optTerminator; ++opt) \
245 if (!strcmp(opt->name, ipbp->str1)) \
250 NSEARCH(display_int
);
251 NSEARCH(display_str
);
255 NSEARCH(general_int
);
256 NSEARCH(general_str
);
265 found
: switch (opt
->kind
) {
267 opt
->value
= (void *)ipbp
->val1
;
270 if (opt
->value
!= NULL
)
272 if ((opt
->value
= malloc(8)) != NULL
)
273 (void)snprintf(opt
->value
,
274 8, "%lu", (u_long
)ipbp
->val1
);
278 if (opt
->value
!= NULL
)
280 if ((opt
->value
= malloc(ipbp
->len2
)) != NULL
)
281 memcpy(opt
->value
, ipbp
->str2
, ipbp
->len2
);
291 * Send a set-edit-option message to core.
294 set_opt(w
, closure
, call_data
)
296 XtPointer closure
, call_data
;
305 ipb
.code
= VI_EDITOPT
;
306 ipb
.str1
= opt
->name
;
307 ipb
.len1
= strlen(opt
->name
);
311 XtVaGetValues(w
, XmNset
, &set
, 0);
315 if (strcmp(opt
->name
, "ruler") == 0)
317 __vi_show_text_ruler_dialog(
318 __vi_screen
->area
, "Ruler");
320 __vi_clear_text_ruler_dialog();
323 str
= XmTextFieldGetString(w
);
324 ipb
.val1
= atoi(str
);
329 ipb
.str2
= XmTextFieldGetString(w
);
330 ipb
.len2
= strlen(ipb
.str2
);
335 vi_send("ab1", &ipb
);
339 /* add toggles to the property sheet */
341 #if defined(__STDC__)
342 static void add_toggle( Widget parent
, optData
*option
)
344 static void add_toggle( parent
, option
)
351 w
= XtVaCreateManagedWidget( option
->name
,
352 xmToggleButtonGadgetClass
,
354 XmNset
, (Boolean
) option
->value
,
357 XtAddCallback( w
, XmNvalueChangedCallback
, set_opt
, option
);
361 static Widget
create_toggles( outer
, toggles
)
368 inner
= XtVaCreateWidget( "toggleOptions",
369 xmRowColumnWidgetClass
,
371 XmNpacking
, XmPACK_COLUMN
,
373 XmNtopAttachment
, XmATTACH_FORM
,
374 XmNrightAttachment
, XmATTACH_FORM
,
375 XmNleftAttachment
, XmATTACH_FORM
,
379 /* first the booleans */
380 for (i
=0; toggles
[i
].kind
!= optTerminator
; i
++) {
381 add_toggle( inner
, &toggles
[i
] );
383 XtManageChild( inner
);
389 /* draw text fields and their labels */
391 #if defined(__STDC__)
392 static void add_string_options( Widget parent
,
396 static void add_string_options( parent
, options
)
404 for ( i
=0; options
[i
].kind
!= optTerminator
; i
++ ) {
406 f
= XtVaCreateWidget( "form",
412 XtVaCreateManagedWidget( options
[i
].name
,
415 XmNtopAttachment
, XmATTACH_FORM
,
416 XmNbottomAttachment
, XmATTACH_FORM
,
417 XmNleftAttachment
, XmATTACH_FORM
,
418 XmNrightAttachment
, XmATTACH_POSITION
,
419 XmNrightPosition
, 20,
420 XmNalignment
, XmALIGNMENT_END
,
424 w
= XtVaCreateManagedWidget( "text",
425 xmTextFieldWidgetClass
,
427 XmNtopAttachment
, XmATTACH_FORM
,
428 XmNbottomAttachment
, XmATTACH_FORM
,
429 XmNrightAttachment
, XmATTACH_FORM
,
430 XmNleftAttachment
, XmATTACH_POSITION
,
435 XmTextFieldSetString( w
, (char *) options
[i
].value
);
436 XtAddCallback( w
, XmNactivateCallback
, set_opt
, &options
[i
] );
442 /* draw and display a single page of properties */
444 #if defined(__STDC__)
445 static Widget
create_sheet( Widget parent
, optSheet
*sheet
)
447 static Widget
create_sheet( parent
, sheet
)
452 Widget outer
, inner
, frame
;
456 outer
= XtVaCreateWidget( sheet
->name
,
459 XmNtopAttachment
, XmATTACH_FORM
,
460 XmNrightAttachment
, XmATTACH_FORM
,
461 XmNbottomAttachment
, XmATTACH_FORM
,
462 XmNleftAttachment
, XmATTACH_FORM
,
463 XmNshadowType
, XmSHADOW_ETCHED_IN
,
464 XmNshadowThickness
, 2,
465 XmNverticalSpacing
, 4,
466 XmNhorizontalSpacing
, 4,
470 /* add descriptive text */
471 frame
= XtVaCreateManagedWidget( "frame",
474 XmNtopAttachment
, XmATTACH_FORM
,
475 XmNrightAttachment
, XmATTACH_FORM
,
476 XmNleftAttachment
, XmATTACH_FORM
,
479 str
= XmStringCreateLtoR( sheet
->description
, XmSTRING_DEFAULT_CHARSET
);
480 XtVaCreateManagedWidget( "description",
488 /* Add the toggles. */
489 inner
= create_toggles( outer
, sheet
->toggles
);
490 XtVaSetValues( inner
,
491 XmNtopAttachment
, XmATTACH_WIDGET
,
496 /* the string options go here */
497 inner
= XtVaCreateWidget( "otherOptions",
498 xmRowColumnWidgetClass
,
500 XmNpacking
, XmPACK_COLUMN
,
501 XmNtopAttachment
, XmATTACH_WIDGET
,
503 XmNrightAttachment
, XmATTACH_FORM
,
504 XmNbottomAttachment
, XmATTACH_FORM
,
505 XmNleftAttachment
, XmATTACH_FORM
,
509 /* Optionally, the ints. */
510 if ( sheet
->ints
!= NULL
)
511 add_string_options( inner
, sheet
->ints
);
513 /* Optionally, the rest. */
514 if ( sheet
->others
!= NULL
)
515 add_string_options( inner
, sheet
->others
);
517 XtManageChild( inner
);
519 /* finally, force resize of the parent */
520 XtVaGetValues( outer
, XmNheight
, &height
, 0 );
521 XtVaSetValues( parent
, XmNheight
, height
, 0 );
527 /* change preferences to another sheet */
529 static void change_sheet( parent
, current
)
533 static int current_sheet
= -1;
535 /* create a new one? */
536 if ( sheets
[current
].holder
== NULL
)
537 sheets
[current
].holder
= create_sheet( parent
, &sheets
[current
] );
539 /* done with the old one? */
540 if ( current_sheet
!= -1 && sheets
[current_sheet
].holder
!= NULL
)
541 XtUnmanageChild( sheets
[current_sheet
].holder
);
543 current_sheet
= current
;
544 XtManageChild( sheets
[current
].holder
);
545 XtManageChild( parent
);
549 /* Draw and display a dialog the describes vi options */
551 #if defined(__STDC__)
552 static Widget
create_options_dialog( Widget parent
, String title
)
554 static Widget
create_options_dialog( parent
, title
)
559 Widget box
, form
, inner
;
564 if ( preferences
!= NULL
) return preferences
;
566 box
= XtVaCreatePopupShell( title
,
567 xmDialogShellWidgetClass
,
570 XmNallowShellResize
, False
,
573 XtAddCallback( box
, XmNpopdownCallback
, __vi_cancel_cb
, 0 );
574 XtAddCallback( box
, XmNdestroyCallback
, destroyed
, 0 );
575 XtAddEventHandler( box
,
576 SubstructureNotifyMask
,
582 form
= XtVaCreateWidget( "options",
588 /* copy the pointers to the sheet names */
590 for (i
=0; i
<XtNumber(sheets
); i
++) {
591 strcat( buffer
, "|" );
592 strcat( buffer
, sheets
[i
].name
);
595 inner
= __vi_CreateTabbedFolder( "tabs",
602 /* build the property sheets early */
603 for ( i
=0; i
<XtNumber(sheets
); i
++ )
604 change_sheet( inner
, i
);
606 /* manage all of the sheets right now */
607 for ( i
=0; i
<XtNumber(sheets
); i
++ )
608 XtManageChild( sheets
[i
].holder
);
609 XtManageChild( form
);
611 /* remove all but the first one */
612 for ( i
=0; i
<XtNumber(sheets
); i
++ )
613 XtUnmanageChild( sheets
[i
].holder
);
614 change_sheet( inner
, 0 ); /* show first sheet first */
616 /* keep this global, we might destroy it later */
628 * __vi_show_options_dialog --
631 * PUBLIC: void __vi_show_options_dialog __P((Widget, String));
634 __vi_show_options_dialog(parent
, title
)
638 Widget db
= create_options_dialog( parent
, title
);
639 #if defined(SelfTest)
640 Widget shell
= XtParent( db
);
645 #if defined(SelfTest)
646 /* wait until it goes away */
647 XtPopup( shell
, XtGrabNone
);
649 /* wait until it goes away */
650 __vi_modal_dialog( db
);
656 /* module entry point
657 * Utilities for the search dialog
660 * Returns the current value of a toggle.
662 * PUBLIC: int __vi_toggle __P((char *));
671 #define NSEARCH(list) { \
672 for (opt = list; opt->kind != optTerminator; ++opt) \
673 if (!strcmp(opt->name, name)) \
674 return ((int)opt->value); \
686 * __vi_create_search_toggles --
687 * Creates the search toggles. This is so the options and search widgets
688 * share their appearance.
690 * PUBLIC: Widget __vi_create_search_toggles __P((Widget, optData[]));
693 __vi_create_search_toggles(parent
, list
)
700 * Copy current options information into the search table.
703 * This is an O(M*N) loop, but I don't think it matters.
705 for (opt
= list
; opt
->kind
!= optTerminator
; ++opt
)
706 opt
->value
= (void *)__vi_toggle(opt
->name
);
708 return (create_toggles(parent
, list
));
712 #if defined(SelfTest)
714 #if defined(__STDC__)
715 static void show_options( Widget w
, XtPointer data
, XtPointer cbs
)
717 static void show_options( w
, data
, cbs
)
723 __vi_show_options_dialog( data
, "Preferences" );
726 main( int argc
, char *argv
[] )
729 Widget top_level
, rc
, button
;
732 /* create a top-level shell for the window manager */
733 top_level
= XtVaAppInitialize( &ctx
,
735 NULL
, 0, /* options */
737 argv
, /* might get modified */
742 rc
= XtVaCreateManagedWidget( "rc",
743 xmRowColumnWidgetClass
,
748 button
= XtVaCreateManagedWidget( "Pop up options dialog",
749 xmPushButtonGadgetClass
,
753 XtAddCallback( button
, XmNactivateCallback
, show_options
, rc
);
755 button
= XtVaCreateManagedWidget( "Quit",
756 xmPushButtonGadgetClass
,
760 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
762 XtRealizeWidget(top_level
);