3 * Rob Zimmermann. All rights reserved.
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
12 #include <sys/cdefs.h>
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 ";
18 __RCSID("$NetBSD: m_options.c,v 1.2 2014/01/26 21:43:45 christos Exp $");
21 #include <sys/types.h>
22 #include <sys/queue.h>
25 #include <X11/Intrinsic.h>
26 #include <Xm/DialogS.h>
29 #include <Xm/LabelG.h>
30 #include <Xm/PushBG.h>
32 #include <Xm/ToggleBG.h>
33 #include <Xm/RowColumn.h>
35 #include <bitstring.h>
41 #include "../common/common.h"
42 #include "../ipc/ip.h"
47 static void set_opt
__P((Widget
, XtPointer
, XtPointer
));
54 /* in production, get these from the resource list */
56 #define toggleColumns 6
65 static Widget preferences
= NULL
;
67 static optData display
[] = {
68 { optToggle
, "comment", },
69 { optToggle
, "flash", },
70 { optToggle
, "leftright", },
71 { optToggle
, "list", },
72 { optToggle
, "number", },
73 { optToggle
, "octal", },
74 { optToggle
, "ruler", },
75 { optToggle
, "showmode", },
76 { optToggle
, "slowopen", },
77 { optToggle
, "verbose", },
78 { optToggle
, "windowname", },
81 { optInteger
, "report", },
82 { optInteger
, "scroll", },
83 { optInteger
, "shiftwidth", },
84 { optInteger
, "sidescroll", },
85 { optInteger
, "tabstop", },
86 { optInteger
, "window", },
89 { optString
, "noprint", },
90 { optString
, "print", },
93 { optToggle
, "autowrite", },
94 { optToggle
, "lock", },
95 { optToggle
, "readonly", },
96 { optToggle
, "writeany", },
99 { optString
, "backup", },
100 { optString
, "path", },
103 { optToggle
, "exrc", },
104 { optToggle
, "lisp", },
105 { optToggle
, "modeline", },
106 { optToggle
, "sourceany", },
107 { optToggle
, "tildeop", },
110 { optInteger
, "taglength", },
113 { optString
, "cdpath", },
114 { optString
, "directory", },
115 { optString
, "msgcat", },
116 { optString
, "recdir", },
117 { optString
, "shell", },
118 { optString
, "shellmeta", },
119 { optString
, "tags", },
122 { optToggle
, "altwerase", },
123 { optToggle
, "autoindent", },
124 { optToggle
, "remap", },
125 { optToggle
, "showmatch", },
126 { optToggle
, "ttywerase", },
129 { optInteger
, "escapetime", },
130 { optInteger
, "keytime", },
131 { optInteger
, "matchtime", },
132 { optInteger
, "timeout", },
133 { optInteger
, "wraplen", },
134 { optInteger
, "wrapmargin", },
137 { optString
, "cedit", },
138 { optString
, "filec", },
141 { optToggle
, "extended", },
142 { optToggle
, "iclower", },
143 { optToggle
, "ignorecase", },
144 { optToggle
, "magic", },
145 { optToggle
, "searchincr", },
146 { optToggle
, "wrapscan", },
149 { optString
, "paragraphs", },
150 { optString
, "sections", },
154 /* ********* NOTE ***********
155 * Sheet 0 will always be shown first. It does not matter to the Xt code
156 * which sheet that is, so it ought to be the one users interact with most.
157 * Best guess is that's general editor options, but it might be Search/re.
158 * ********* NOTE ***********
160 static optSheet sheets
[] = {
162 "These options control how text is displayed on the screen",
169 "These options control how the editor handles files",
176 "These options control text input behavior",
183 "These options control searching and Regular Expression behavior",
190 "These options control general editor configuration",
201 #if defined(SelfTest)
202 void __vi_cancel_cb()
209 static void destroyed(void)
215 /* some window managers destroy us upon popdown */
216 for (i
=0; i
<XtNumber(sheets
); i
++) {
217 sheets
[i
].holder
= NULL
;
223 static void window_unmapped(Widget w
, XtPointer ptr
, XEvent
*ev
, Boolean
*cont
)
225 if ( ev
->type
== UnmapNotify
) {
226 #if defined(SelfTest)
229 XtPopdown( XtParent( preferences
) );
235 * Set an edit option based on a core message.
237 * PUBLIC: int __vi_editopt __P((IPVI *, const char *, u_int32_t, const char *, u_int32_t, u_int32_t));
240 __vi_editopt(IPVI
*ipvi
, const char *str1
, u_int32_t len1
, const char *str2
, u_int32_t len2
, u_int32_t val1
)
245 #define NSEARCH(list) { \
246 for (opt = list; opt->kind != optTerminator; ++opt) \
247 if (!strcmp(opt->name, str1)) \
252 NSEARCH(display_int
);
253 NSEARCH(display_str
);
257 NSEARCH(general_int
);
258 NSEARCH(general_str
);
267 found
: switch (opt
->kind
) {
269 opt
->value
= (void *)val1
;
272 if (opt
->value
!= NULL
)
274 if ((opt
->value
= malloc(8)) != NULL
)
275 (void)snprintf(opt
->value
,
276 8, "%lu", (u_long
)val1
);
280 if (opt
->value
!= NULL
)
282 if ((opt
->value
= malloc(len2
)) != NULL
)
283 memcpy(opt
->value
, str2
, len2
);
293 * Send a set-edit-option message to core.
296 set_opt(Widget w
, XtPointer closure
, XtPointer call_data
)
302 extern IPVI ipvi_motif
;
306 ipb
.code
= VI_EDITOPT
;
307 ipb
.str1
= opt
->name
;
308 ipb
.len1
= strlen(opt
->name
);
312 XtVaGetValues(w
, XmNset
, &set
, 0);
316 vi_wsend(&ipvi_motif
, "ab1", &ipb
);
318 opt
->value
= (void *)!set
;
321 * How do we turn off the button? We don't want to
322 * go recursive where we set it and it calls set_opt
323 * to tell the core. Is that possible?
325 XtVaSetValues(w
, XmNset
, &set
, 0);
329 if (strcmp(opt
->name
, "ruler") == 0)
331 __vi_show_text_ruler_dialog(
332 __vi_screen
->area
, "Ruler");
334 __vi_clear_text_ruler_dialog();
337 str
= XmTextFieldGetString(w
);
338 ipb
.val1
= atoi(str
);
340 vi_send(vi_ofd
, "ab1", &ipb
);
344 ipb
.str2
= XmTextFieldGetString(w
);
345 ipb
.len2
= strlen(ipb
.str2
);
346 vi_send(vi_ofd
, "ab1", &ipb
);
354 /* add toggles to the property sheet */
356 #if defined(__STDC__)
357 static void add_toggle( Widget parent
, optData
*option
)
359 static void add_toggle( parent
, option
)
366 w
= XtVaCreateManagedWidget( option
->name
,
367 xmToggleButtonGadgetClass
,
369 XmNset
, (Boolean
) option
->value
,
372 XtAddCallback( w
, XmNvalueChangedCallback
, set_opt
, option
);
376 static Widget
create_toggles(Widget outer
, optData
*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(Widget parent
, int current
)
544 static int current_sheet
= -1;
546 /* create a new one? */
547 if ( sheets
[current
].holder
== NULL
)
548 sheets
[current
].holder
= create_sheet( parent
, &sheets
[current
] );
550 /* done with the old one? */
551 if ( current_sheet
!= -1 && sheets
[current_sheet
].holder
!= NULL
)
552 XtUnmanageChild( sheets
[current_sheet
].holder
);
554 current_sheet
= current
;
555 XtManageChild( sheets
[current
].holder
);
556 XtManageChild( parent
);
560 /* Draw and display a dialog the describes vi options */
562 #if defined(__STDC__)
563 static Widget
create_options_dialog( Widget parent
, String title
)
565 static Widget
create_options_dialog( parent
, title
)
570 Widget box
, form
, inner
;
575 if ( preferences
!= NULL
) return preferences
;
577 box
= XtVaCreatePopupShell( title
,
578 xmDialogShellWidgetClass
,
581 XmNallowShellResize
, False
,
584 XtAddCallback( box
, XmNpopdownCallback
, __vi_cancel_cb
, 0 );
585 XtAddCallback( box
, XmNdestroyCallback
, destroyed
, 0 );
586 XtAddEventHandler( box
,
587 SubstructureNotifyMask
,
593 form
= XtVaCreateWidget( "options",
599 /* copy the pointers to the sheet names */
601 for (i
=0; i
<XtNumber(sheets
); i
++) {
602 strcat( buffer
, "|" );
603 strcat( buffer
, sheets
[i
].name
);
606 inner
= __vi_CreateTabbedFolder( "tabs",
613 /* build the property sheets early */
614 for ( i
=0; i
<XtNumber(sheets
); i
++ )
615 change_sheet( inner
, i
);
617 /* manage all of the sheets right now */
618 for ( i
=0; i
<XtNumber(sheets
); i
++ )
619 XtManageChild( sheets
[i
].holder
);
620 XtManageChild( form
);
622 /* remove all but the first one */
623 for ( i
=0; i
<XtNumber(sheets
); i
++ )
624 XtUnmanageChild( sheets
[i
].holder
);
625 change_sheet( inner
, 0 ); /* show first sheet first */
627 /* keep this global, we might destroy it later */
639 * __vi_show_options_dialog --
642 * PUBLIC: void __vi_show_options_dialog __P((Widget, String));
645 __vi_show_options_dialog(Widget parent
, String title
)
647 Widget db
= create_options_dialog( parent
, title
);
648 #if defined(SelfTest)
649 Widget shell
= XtParent( db
);
654 #if defined(SelfTest)
655 /* wait until it goes away */
656 XtPopup( shell
, XtGrabNone
);
658 /* wait until it goes away */
659 __vi_modal_dialog( db
);
665 /* module entry point
666 * Utilities for the search dialog
669 * Returns the current value of a toggle.
671 * PUBLIC: int __vi_toggle __P((char *));
674 __vi_toggle(char *name
)
679 #define NSEARCH(list) { \
680 for (opt = list; opt->kind != optTerminator; ++opt) \
681 if (!strcmp(opt->name, name)) \
682 return ((int)opt->value); \
694 * __vi_create_search_toggles --
695 * Creates the search toggles. This is so the options and search widgets
696 * share their appearance.
698 * PUBLIC: Widget __vi_create_search_toggles __P((Widget, optData[]));
701 __vi_create_search_toggles(Widget parent
, optData
*list
)
706 * Copy current options information into the search table.
709 * This is an O(M*N) loop, but I don't think it matters.
711 for (opt
= list
; opt
->kind
!= optTerminator
; ++opt
)
712 opt
->value
= (void *)__vi_toggle(opt
->name
);
714 return (create_toggles(parent
, list
));
718 #if defined(SelfTest)
720 #if defined(__STDC__)
721 static void show_options( Widget w
, XtPointer data
, XtPointer cbs
)
723 static void show_options( w
, data
, cbs
)
729 __vi_show_options_dialog( data
, "Preferences" );
732 main( int argc
, char *argv
[] )
735 Widget top_level
, rc
, button
;
738 /* create a top-level shell for the window manager */
739 top_level
= XtVaAppInitialize( &ctx
,
741 NULL
, 0, /* options */
743 argv
, /* might get modified */
748 rc
= XtVaCreateManagedWidget( "rc",
749 xmRowColumnWidgetClass
,
754 button
= XtVaCreateManagedWidget( "Pop up options dialog",
755 xmPushButtonGadgetClass
,
759 XtAddCallback( button
, XmNactivateCallback
, show_options
, rc
);
761 button
= XtVaCreateManagedWidget( "Quit",
762 xmPushButtonGadgetClass
,
766 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
768 XtRealizeWidget(top_level
);