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.22 2003/11/05 17:09:59 skimo Exp (Berkeley) Date: 2003/11/05 17:09:59 ";
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>
36 #include "../common/common.h"
37 #include "../ipc/ip.h"
42 static void set_opt
__P((Widget
, XtPointer
, XtPointer
));
49 /* in production, get these from the resource list */
51 #define toggleColumns 6
60 static Widget preferences
= NULL
;
62 static optData display
[] = {
63 { optToggle
, "comment", },
64 { optToggle
, "flash", },
65 { optToggle
, "leftright", },
66 { optToggle
, "list", },
67 { optToggle
, "number", },
68 { optToggle
, "octal", },
69 { optToggle
, "ruler", },
70 { optToggle
, "showmode", },
71 { optToggle
, "slowopen", },
72 { optToggle
, "verbose", },
73 { optToggle
, "windowname", },
76 { optInteger
, "report", },
77 { optInteger
, "scroll", },
78 { optInteger
, "shiftwidth", },
79 { optInteger
, "sidescroll", },
80 { optInteger
, "tabstop", },
81 { optInteger
, "window", },
84 { optString
, "noprint", },
85 { optString
, "print", },
88 { optToggle
, "autowrite", },
89 { optToggle
, "lock", },
90 { optToggle
, "readonly", },
91 { optToggle
, "writeany", },
94 { optString
, "backup", },
95 { optString
, "path", },
98 { optToggle
, "exrc", },
99 { optToggle
, "lisp", },
100 { optToggle
, "modeline", },
101 { optToggle
, "sourceany", },
102 { optToggle
, "tildeop", },
105 { optInteger
, "taglength", },
108 { optString
, "cdpath", },
109 { optString
, "directory", },
110 { optString
, "msgcat", },
111 { optString
, "recdir", },
112 { optString
, "shell", },
113 { optString
, "shellmeta", },
114 { optString
, "tags", },
117 { optToggle
, "altwerase", },
118 { optToggle
, "autoindent", },
119 { optToggle
, "remap", },
120 { optToggle
, "showmatch", },
121 { optToggle
, "ttywerase", },
124 { optInteger
, "escapetime", },
125 { optInteger
, "keytime", },
126 { optInteger
, "matchtime", },
127 { optInteger
, "timeout", },
128 { optInteger
, "wraplen", },
129 { optInteger
, "wrapmargin", },
132 { optString
, "cedit", },
133 { optString
, "filec", },
136 { optToggle
, "extended", },
137 { optToggle
, "iclower", },
138 { optToggle
, "ignorecase", },
139 { optToggle
, "magic", },
140 { optToggle
, "searchincr", },
141 { optToggle
, "wrapscan", },
144 { optString
, "paragraphs", },
145 { optString
, "sections", },
149 /* ********* NOTE ***********
150 * Sheet 0 will always be shown first. It does not matter to the Xt code
151 * which sheet that is, so it ought to be the one users interact with most.
152 * Best guess is that's general editor options, but it might be Search/re.
153 * ********* NOTE ***********
155 static optSheet sheets
[] = {
157 "These options control how text is displayed on the screen",
164 "These options control how the editor handles files",
171 "These options control text input behavior",
178 "These options control searching and Regular Expression behavior",
185 "These options control general editor configuration",
196 #if defined(SelfTest)
197 void __vi_cancel_cb()
204 static void destroyed(void)
210 /* some window managers destroy us upon popdown */
211 for (i
=0; i
<XtNumber(sheets
); i
++) {
212 sheets
[i
].holder
= NULL
;
218 static void window_unmapped(Widget w
, XtPointer ptr
, XEvent
*ev
, Boolean
*cont
)
220 if ( ev
->type
== UnmapNotify
) {
221 #if defined(SelfTest)
224 XtPopdown( XtParent( preferences
) );
230 * Set an edit option based on a core message.
232 * PUBLIC: int __vi_editopt __P((IPVI *, const char *, u_int32_t, const char *, u_int32_t, u_int32_t));
235 __vi_editopt(IPVI
*ipvi
, const char *str1
, u_int32_t len1
, const char *str2
, u_int32_t len2
, u_int32_t val1
)
240 #define NSEARCH(list) { \
241 for (opt = list; opt->kind != optTerminator; ++opt) \
242 if (!strcmp(opt->name, str1)) \
247 NSEARCH(display_int
);
248 NSEARCH(display_str
);
252 NSEARCH(general_int
);
253 NSEARCH(general_str
);
262 found
: switch (opt
->kind
) {
264 opt
->value
= (void *)val1
;
267 if (opt
->value
!= NULL
)
269 if ((opt
->value
= malloc(8)) != NULL
)
270 (void)snprintf(opt
->value
,
271 8, "%lu", (u_long
)val1
);
275 if (opt
->value
!= NULL
)
277 if ((opt
->value
= malloc(len2
)) != NULL
)
278 memcpy(opt
->value
, str2
, len2
);
288 * Send a set-edit-option message to core.
291 set_opt(Widget w
, XtPointer closure
, XtPointer call_data
)
297 extern IPVI ipvi_motif
;
301 ipb
.code
= VI_EDITOPT
;
302 ipb
.str1
= opt
->name
;
303 ipb
.len1
= strlen(opt
->name
);
307 XtVaGetValues(w
, XmNset
, &set
, 0);
311 vi_wsend(&ipvi_motif
, "ab1", &ipb
);
313 opt
->value
= (void *)!set
;
316 * How do we turn off the button? We don't want to
317 * go recursive where we set it and it calls set_opt
318 * to tell the core. Is that possible?
320 XtVaSetValues(w
, XmNset
, &set
, 0);
324 if (strcmp(opt
->name
, "ruler") == 0)
326 __vi_show_text_ruler_dialog(
327 __vi_screen
->area
, "Ruler");
329 __vi_clear_text_ruler_dialog();
332 str
= XmTextFieldGetString(w
);
333 ipb
.val1
= atoi(str
);
335 vi_send(vi_ofd
, "ab1", &ipb
);
339 ipb
.str2
= XmTextFieldGetString(w
);
340 ipb
.len2
= strlen(ipb
.str2
);
341 vi_send(vi_ofd
, "ab1", &ipb
);
349 /* add toggles to the property sheet */
351 #if defined(__STDC__)
352 static void add_toggle( Widget parent
, optData
*option
)
354 static void add_toggle( parent
, option
)
361 w
= XtVaCreateManagedWidget( option
->name
,
362 xmToggleButtonGadgetClass
,
364 XmNset
, (Boolean
) option
->value
,
367 XtAddCallback( w
, XmNvalueChangedCallback
, set_opt
, option
);
371 static Widget
create_toggles(Widget outer
, optData
*toggles
)
376 inner
= XtVaCreateWidget( "toggleOptions",
377 xmRowColumnWidgetClass
,
379 XmNpacking
, XmPACK_COLUMN
,
381 XmNtopAttachment
, XmATTACH_FORM
,
382 XmNrightAttachment
, XmATTACH_FORM
,
383 XmNleftAttachment
, XmATTACH_FORM
,
387 /* first the booleans */
388 for (i
=0; toggles
[i
].kind
!= optTerminator
; i
++) {
389 add_toggle( inner
, &toggles
[i
] );
391 XtManageChild( inner
);
397 /* draw text fields and their labels */
399 #if defined(__STDC__)
400 static void add_string_options( Widget parent
,
404 static void add_string_options( parent
, options
)
412 for ( i
=0; options
[i
].kind
!= optTerminator
; i
++ ) {
414 f
= XtVaCreateWidget( "form",
420 XtVaCreateManagedWidget( options
[i
].name
,
423 XmNtopAttachment
, XmATTACH_FORM
,
424 XmNbottomAttachment
, XmATTACH_FORM
,
425 XmNleftAttachment
, XmATTACH_FORM
,
426 XmNrightAttachment
, XmATTACH_POSITION
,
427 XmNrightPosition
, 20,
428 XmNalignment
, XmALIGNMENT_END
,
432 w
= XtVaCreateManagedWidget( "text",
433 xmTextFieldWidgetClass
,
435 XmNtopAttachment
, XmATTACH_FORM
,
436 XmNbottomAttachment
, XmATTACH_FORM
,
437 XmNrightAttachment
, XmATTACH_FORM
,
438 XmNleftAttachment
, XmATTACH_POSITION
,
443 XmTextFieldSetString( w
, (char *) options
[i
].value
);
444 XtAddCallback( w
, XmNactivateCallback
, set_opt
, &options
[i
] );
450 /* draw and display a single page of properties */
452 #if defined(__STDC__)
453 static Widget
create_sheet( Widget parent
, optSheet
*sheet
)
455 static Widget
create_sheet( parent
, sheet
)
460 Widget outer
, inner
, frame
;
464 outer
= XtVaCreateWidget( sheet
->name
,
467 XmNtopAttachment
, XmATTACH_FORM
,
468 XmNrightAttachment
, XmATTACH_FORM
,
469 XmNbottomAttachment
, XmATTACH_FORM
,
470 XmNleftAttachment
, XmATTACH_FORM
,
471 XmNshadowType
, XmSHADOW_ETCHED_IN
,
472 XmNshadowThickness
, 2,
473 XmNverticalSpacing
, 4,
474 XmNhorizontalSpacing
, 4,
478 /* add descriptive text */
479 frame
= XtVaCreateManagedWidget( "frame",
482 XmNtopAttachment
, XmATTACH_FORM
,
483 XmNrightAttachment
, XmATTACH_FORM
,
484 XmNleftAttachment
, XmATTACH_FORM
,
487 str
= XmStringCreateLtoR( sheet
->description
, XmSTRING_DEFAULT_CHARSET
);
488 XtVaCreateManagedWidget( "description",
496 /* Add the toggles. */
497 inner
= create_toggles( outer
, sheet
->toggles
);
498 XtVaSetValues( inner
,
499 XmNtopAttachment
, XmATTACH_WIDGET
,
504 /* the string options go here */
505 inner
= XtVaCreateWidget( "otherOptions",
506 xmRowColumnWidgetClass
,
508 XmNpacking
, XmPACK_COLUMN
,
509 XmNtopAttachment
, XmATTACH_WIDGET
,
511 XmNrightAttachment
, XmATTACH_FORM
,
512 XmNbottomAttachment
, XmATTACH_FORM
,
513 XmNleftAttachment
, XmATTACH_FORM
,
517 /* Optionally, the ints. */
518 if ( sheet
->ints
!= NULL
)
519 add_string_options( inner
, sheet
->ints
);
521 /* Optionally, the rest. */
522 if ( sheet
->others
!= NULL
)
523 add_string_options( inner
, sheet
->others
);
525 XtManageChild( inner
);
527 /* finally, force resize of the parent */
528 XtVaGetValues( outer
, XmNheight
, &height
, 0 );
529 XtVaSetValues( parent
, XmNheight
, height
, 0 );
535 /* change preferences to another sheet */
537 static void change_sheet(Widget parent
, int current
)
539 static int current_sheet
= -1;
541 /* create a new one? */
542 if ( sheets
[current
].holder
== NULL
)
543 sheets
[current
].holder
= create_sheet( parent
, &sheets
[current
] );
545 /* done with the old one? */
546 if ( current_sheet
!= -1 && sheets
[current_sheet
].holder
!= NULL
)
547 XtUnmanageChild( sheets
[current_sheet
].holder
);
549 current_sheet
= current
;
550 XtManageChild( sheets
[current
].holder
);
551 XtManageChild( parent
);
555 /* Draw and display a dialog the describes vi options */
557 #if defined(__STDC__)
558 static Widget
create_options_dialog( Widget parent
, String title
)
560 static Widget
create_options_dialog( parent
, title
)
565 Widget box
, form
, inner
;
570 if ( preferences
!= NULL
) return preferences
;
572 box
= XtVaCreatePopupShell( title
,
573 xmDialogShellWidgetClass
,
576 XmNallowShellResize
, False
,
579 XtAddCallback( box
, XmNpopdownCallback
, __vi_cancel_cb
, 0 );
580 XtAddCallback( box
, XmNdestroyCallback
, destroyed
, 0 );
581 XtAddEventHandler( box
,
582 SubstructureNotifyMask
,
588 form
= XtVaCreateWidget( "options",
594 /* copy the pointers to the sheet names */
596 for (i
=0; i
<XtNumber(sheets
); i
++) {
597 strcat( buffer
, "|" );
598 strcat( buffer
, sheets
[i
].name
);
601 inner
= __vi_CreateTabbedFolder( "tabs",
608 /* build the property sheets early */
609 for ( i
=0; i
<XtNumber(sheets
); i
++ )
610 change_sheet( inner
, i
);
612 /* manage all of the sheets right now */
613 for ( i
=0; i
<XtNumber(sheets
); i
++ )
614 XtManageChild( sheets
[i
].holder
);
615 XtManageChild( form
);
617 /* remove all but the first one */
618 for ( i
=0; i
<XtNumber(sheets
); i
++ )
619 XtUnmanageChild( sheets
[i
].holder
);
620 change_sheet( inner
, 0 ); /* show first sheet first */
622 /* keep this global, we might destroy it later */
634 * __vi_show_options_dialog --
637 * PUBLIC: void __vi_show_options_dialog __P((Widget, String));
640 __vi_show_options_dialog(Widget parent
, String title
)
642 Widget db
= create_options_dialog( parent
, title
);
643 #if defined(SelfTest)
644 Widget shell
= XtParent( db
);
649 #if defined(SelfTest)
650 /* wait until it goes away */
651 XtPopup( shell
, XtGrabNone
);
653 /* wait until it goes away */
654 __vi_modal_dialog( db
);
660 /* module entry point
661 * Utilities for the search dialog
664 * Returns the current value of a toggle.
666 * PUBLIC: int __vi_toggle __P((char *));
669 __vi_toggle(char *name
)
674 #define NSEARCH(list) { \
675 for (opt = list; opt->kind != optTerminator; ++opt) \
676 if (!strcmp(opt->name, name)) \
677 return ((int)opt->value); \
689 * __vi_create_search_toggles --
690 * Creates the search toggles. This is so the options and search widgets
691 * share their appearance.
693 * PUBLIC: Widget __vi_create_search_toggles __P((Widget, optData[]));
696 __vi_create_search_toggles(Widget parent
, optData
*list
)
701 * Copy current options information into the search table.
704 * This is an O(M*N) loop, but I don't think it matters.
706 for (opt
= list
; opt
->kind
!= optTerminator
; ++opt
)
707 opt
->value
= (void *)__vi_toggle(opt
->name
);
709 return (create_toggles(parent
, list
));
713 #if defined(SelfTest)
715 #if defined(__STDC__)
716 static void show_options( Widget w
, XtPointer data
, XtPointer cbs
)
718 static void show_options( w
, data
, cbs
)
724 __vi_show_options_dialog( data
, "Preferences" );
727 main( int argc
, char *argv
[] )
730 Widget top_level
, rc
, button
;
733 /* create a top-level shell for the window manager */
734 top_level
= XtVaAppInitialize( &ctx
,
736 NULL
, 0, /* options */
738 argv
, /* might get modified */
743 rc
= XtVaCreateManagedWidget( "rc",
744 xmRowColumnWidgetClass
,
749 button
= XtVaCreateManagedWidget( "Pop up options dialog",
750 xmPushButtonGadgetClass
,
754 XtAddCallback( button
, XmNactivateCallback
, show_options
, rc
);
756 button
= XtVaCreateManagedWidget( "Quit",
757 xmPushButtonGadgetClass
,
761 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
763 XtRealizeWidget(top_level
);