Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / nvi / motif_l / m_search.c
blob97cc18a7e0e0d586469dfa1de351f36d2944220a
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_search.c,v 8.14 2003/11/05 17:10:00 skimo Exp (Berkeley) Date: 2003/11/05 17:10:00";
16 #endif /* not lint */
18 #include <sys/queue.h>
20 /* context */
21 #include <X11/X.h>
22 #include <X11/Intrinsic.h>
23 #include <Xm/DialogS.h>
24 #include <Xm/Form.h>
25 #include <Xm/Label.h>
26 #include <Xm/PushBG.h>
27 #include <Xm/TextF.h>
28 #include <Xm/ToggleB.h>
29 #include <Xm/RowColumn.h>
31 #include <bitstring.h>
32 #include <stdio.h>
33 #include <stdlib.h>
35 #undef LOCK_SUCCESS
36 #include "../common/common.h"
37 #include "../ipc/ip.h"
38 #include "m_motif.h"
40 extern int vi_ofd;
43 /* types */
45 typedef struct sds {
46 struct sds *next;
47 Widget shell;
48 } save_dialog;
50 static save_dialog *dialogs = NULL;
52 typedef struct {
53 String name;
54 void (*cb)();
55 } ButtonData;
58 /* globals and constants */
60 static String PatternWidget = "text";
61 static String pattern = NULL;
63 static optData search_toggles[] = {
64 { optToggle, "extended", NULL, VI_SEARCH_EXT },
65 { optToggle, "iclower", NULL, VI_SEARCH_ICL },
66 { optToggle, "ignorecase", NULL, VI_SEARCH_IC },
67 { optToggle, "literal", NULL, VI_SEARCH_LIT },
68 { optToggle, "searchincr", NULL, VI_SEARCH_INCR },
69 { optToggle, "wrapscan", NULL, VI_SEARCH_WR },
70 { optTerminator, },
73 static void done_func __P((Widget));
74 static void next_func __P((Widget));
75 static void prev_func __P((Widget));
76 static void search __P((Widget, int));
78 static ButtonData button_data[] = {
79 { "Next", next_func },
80 { "Previous", prev_func },
81 { "Cancel", done_func } /* always last */
85 /* Xt utilities */
87 #if defined(__STDC__)
88 static Widget get_child_widget( Widget parent, String name )
89 #else
90 static Widget get_child_widget( parent, name )
91 Widget parent;
92 String name;
93 #endif
95 char buffer[1024];
97 strcpy( buffer, "*" );
98 strcat( buffer, name );
99 return XtNameToWidget( parent, buffer );
103 /* sync the global state */
105 #if defined(__STDC__)
106 static void get_state( Widget w )
107 #else
108 static void get_state( w )
109 Widget w;
110 #endif
112 #if defined(SelfTest)
113 int i;
114 #endif
115 Widget shell = w;
117 /* get all the data from the root of the widget tree */
118 while ( ! XtIsShell(shell) ) shell = XtParent(shell);
120 #if defined(SelfTest)
121 /* which flags? */
122 for (i=0; i<XtNumber(toggle_data); i++) {
123 if (( w = get_child_widget( shell, toggle_data[i].name )) != NULL ) {
124 XtVaGetValues( w, XmNset, &toggle_data[i].value, 0 );
127 #endif
129 /* what's the pattern? */
130 if (( w = get_child_widget( shell, PatternWidget )) != NULL ) {
131 if ( pattern != NULL ) XtFree( pattern );
132 pattern = XmTextFieldGetString( w );
137 /* Translate the user's actions into nvi commands */
139 * next_func --
140 * Action for next button.
142 static void
143 next_func(Widget w)
145 search(w, 0);
149 * prev_func --
150 * Action for previous button.
152 static void
153 prev_func(Widget w)
155 search(w, VI_SEARCH_REV);
159 * search --
160 * Perform the search.
162 static void
163 search(Widget w, int flags)
165 IP_BUF ipb;
166 optData *opt;
167 Widget shell;
169 shell = w;
170 while ( ! XtIsShell(shell) ) shell = XtParent(shell);
172 /* Get current data from the root of the widget tree?
173 * Do it if we are a child of a dialog shell (assume we
174 * are a 'Find' dialog). Otherwise don't (we are the child
175 * of a menu and being invoked via accelerator)
177 if (XmIsDialogShell(shell))
178 get_state(w);
180 /* no pattern? probably, we haven't posted a search dialog yet.
181 * there ought to be a better thing to do here.
183 if ( pattern == NULL ) {
184 vi_info_message( w, "No previous string specified" );
185 return;
188 ipb.str1 = pattern;
189 ipb.len1 = strlen(pattern);
191 /* Initialize the search flags based on the buttons. */
192 ipb.val1 = flags;
193 for (opt = search_toggles; opt->kind != optTerminator; ++opt)
194 if (opt->value != NULL)
195 ipb.val1 |= opt->flags;
197 ipb.code = VI_C_SEARCH;
198 vi_send(vi_ofd, "a1", &ipb);
201 #if defined(__STDC__)
202 static void done_func( Widget w )
203 #else
204 static void done_func( w )
205 Widget w;
206 #endif
208 save_dialog *ptr;
210 #if defined(SelfTest)
211 puts( XtName(w) );
212 #endif
214 while ( ! XtIsShell(w) ) w = XtParent(w);
215 XtPopdown( w );
217 /* save it for later */
218 ptr = (save_dialog *) malloc( sizeof(save_dialog) );
219 ptr->next = dialogs;
220 ptr->shell = w;
221 dialogs = ptr;
225 /* create a set of push buttons */
227 #define SpacingRatio 4 /* 3:1 button to spaces */
229 #if defined(__STDC__)
230 static Widget create_push_buttons( Widget parent,
231 ButtonData *data,
232 int count
234 #else
235 static Widget create_push_buttons( parent, data, count )
236 Widget parent;
237 ButtonData *data;
238 int count;
239 #endif
241 Widget w, form;
242 int pos = 1, base;
244 base = SpacingRatio*count + 1;
245 form = XtVaCreateManagedWidget( "buttons",
246 xmFormWidgetClass,
247 parent,
248 XmNleftAttachment, XmATTACH_FORM,
249 XmNrightAttachment, XmATTACH_FORM,
250 XmNfractionBase, base,
251 XmNshadowType, XmSHADOW_ETCHED_IN,
252 XmNshadowThickness, 2,
253 XmNverticalSpacing, 4,
257 while ( count-- > 0 ) {
258 w = XtVaCreateManagedWidget(data->name,
259 xmPushButtonGadgetClass,
260 form,
261 XmNtopAttachment, XmATTACH_FORM,
262 XmNbottomAttachment,XmATTACH_FORM,
263 XmNleftAttachment, XmATTACH_POSITION,
264 XmNleftPosition, pos,
265 XmNshowAsDefault, False,
266 XmNrightAttachment, XmATTACH_POSITION,
267 XmNrightPosition, pos+SpacingRatio-1,
270 XtAddCallback( w, XmNactivateCallback, data->cb, 0 );
271 pos += SpacingRatio;
272 data++;
275 /* last button is 'cancel' */
276 XtVaSetValues( XtParent(form), XmNcancelButton, w, 0 );
278 return form;
282 /* create a set of check boxes */
284 #if defined(SelfTest)
286 #if defined(__STDC__)
287 static Widget create_check_boxes( Widget parent,
288 ToggleData *toggles,
289 int count
291 #else
292 static Widget create_check_boxes( parent, toggles, count )
293 Widget parent;
294 ToggleData *toggles;
295 int count;
296 #endif
298 Widget form;
299 int pos = 1, base;
301 base = SpacingRatio*count +1;
302 form = XtVaCreateManagedWidget( "toggles",
303 xmFormWidgetClass,
304 parent,
305 XmNleftAttachment, XmATTACH_FORM,
306 XmNrightAttachment, XmATTACH_FORM,
307 XmNfractionBase, base,
308 XmNverticalSpacing, 4,
312 while ( count-- > 0 ) {
313 XtVaCreateManagedWidget(toggles->name,
314 xmToggleButtonWidgetClass,
315 form,
316 XmNtopAttachment, XmATTACH_FORM,
317 XmNbottomAttachment, XmATTACH_FORM,
318 XmNleftAttachment, XmATTACH_POSITION,
319 XmNleftPosition, pos,
320 XmNrightAttachment, XmATTACH_POSITION,
321 XmNrightPosition, pos+SpacingRatio-1,
324 pos += SpacingRatio;
325 ++toggles;
328 return form;
331 #endif
334 /* Routines to handle the text field widget */
336 /* when the user hits 'CR' in a text widget, fire the default pushbutton */
337 #if defined(__STDC__)
338 static void text_cr( Widget w, void *ptr, void *ptr2 )
339 #else
340 static void text_cr( w, ptr, ptr2 )
341 Widget w;
342 void *ptr;
343 void *ptr2;
344 #endif
346 next_func( w );
350 #ifdef notdef
352 * when the user hits any other character, if we are doing incremental
353 * search, send the updated string to nvi
355 * XXX
356 * I don't currently see any way to make this work -- incremental search
357 * is going to be really nasty. What makes it worse is that the dialog
358 * box almost certainly obscured a chunk of the text file, so there's no
359 * way to use it even if it works.
361 #if defined(__STDC__)
362 static void value_changed( Widget w, void *ptr, void *ptr2 )
363 #else
364 static void value_changed( w, ptr, ptr2 )
365 Widget w;
366 void *ptr;
367 void *ptr2;
368 #endif
370 /* get all the data from the root of the widget tree */
371 get_state( w );
373 /* send it along? */
374 #if defined(SelfTest)
375 if ( incremental_search ) send_command( w );
376 #else
377 if ( __vi_incremental_search() ) send_command( w );
378 #endif
380 #endif /* notdef */
383 /* Draw and display a dialog the describes nvi search capability */
385 #if defined(__STDC__)
386 static Widget create_search_dialog( Widget parent, String title )
387 #else
388 static Widget create_search_dialog( parent, title )
389 Widget parent;
390 String title;
391 #endif
393 Widget box, form, label, text, checks, buttons, form2;
394 save_dialog *ptr;
396 /* use an existing one? */
397 if ( dialogs != NULL ) {
398 box = dialogs->shell;
399 ptr = dialogs->next;
400 free( dialogs );
401 dialogs = ptr;
402 return box;
405 box = XtVaCreatePopupShell( title,
406 xmDialogShellWidgetClass,
407 parent,
408 XmNtitle, title,
409 XmNallowShellResize, False,
413 form = XtVaCreateWidget( "form",
414 xmFormWidgetClass,
415 box,
416 XmNverticalSpacing, 4,
417 XmNhorizontalSpacing, 4,
421 form2 = XtVaCreateManagedWidget( "form",
422 xmFormWidgetClass,
423 form,
424 XmNtopAttachment, XmATTACH_FORM,
425 XmNleftAttachment, XmATTACH_FORM,
426 XmNrightAttachment, XmATTACH_FORM,
430 label = XtVaCreateManagedWidget( "Pattern:",
431 xmLabelWidgetClass,
432 form2,
433 XmNtopAttachment, XmATTACH_FORM,
434 XmNbottomAttachment,XmATTACH_FORM,
435 XmNleftAttachment, XmATTACH_FORM,
439 text = XtVaCreateManagedWidget( PatternWidget,
440 xmTextFieldWidgetClass,
441 form2,
442 XmNtopAttachment, XmATTACH_FORM,
443 XmNbottomAttachment,XmATTACH_FORM,
444 XmNleftAttachment, XmATTACH_WIDGET,
445 XmNleftWidget, label,
446 XmNrightAttachment, XmATTACH_FORM,
449 #ifdef notdef
450 XtAddCallback( text, XmNvalueChangedCallback, value_changed, 0 );
451 #endif
452 XtAddCallback( text, XmNactivateCallback, text_cr, 0 );
454 buttons = create_push_buttons( form, button_data, XtNumber(button_data) );
455 XtVaSetValues( buttons,
456 XmNbottomAttachment, XmATTACH_FORM,
460 #if defined(SelfTest)
461 checks = create_check_boxes( form, toggle_data, XtNumber(toggle_data) );
462 #else
463 checks = (Widget) __vi_create_search_toggles( form, search_toggles );
464 #endif
465 XtVaSetValues( checks,
466 XmNtopAttachment, XmATTACH_WIDGET,
467 XmNtopWidget, form2,
468 XmNbottomAttachment, XmATTACH_WIDGET,
469 XmNbottomWidget, buttons,
473 XtManageChild( form );
474 return box;
478 /* Module interface to the outside world
480 * xip_show_search_dialog( parent, title )
481 * pops up a search dialog
483 * xip_next_search()
484 * simulates a 'next' assuming that a search has been done
487 #if defined(__STDC__)
488 void __vi_show_search_dialog( Widget parent, String title )
489 #else
490 void __vi_show_search_dialog( parent, data, cbs )
491 Widget parent;
492 String title;
493 #endif
495 Widget db = create_search_dialog( parent, title );
496 Dimension height;
498 /* we can handle getting taller and wider or narrower, but not shorter */
499 XtVaGetValues( db, XmNheight, &height, 0 );
500 XtVaSetValues( db, XmNmaxHeight, height, XmNminHeight, height, 0 );
502 /* post the dialog */
503 XtPopup( db, XtGrabNone );
505 /* request initial focus to the text widget */
506 XmProcessTraversal( get_child_widget( db, PatternWidget ),
507 XmTRAVERSE_CURRENT
513 * __vi_search --
515 * PUBLIC: void __vi_search __P((Widget));
517 void
518 __vi_search(Widget w)
520 next_func( w );
524 #if defined(SelfTest)
526 #if defined(__STDC__)
527 static void show_search( Widget w, XtPointer data, XtPointer cbs )
528 #else
529 static void show_search( w, data, cbs )
530 Widget w;
531 XtPointer data;
532 XtPointer cbs;
533 #endif
535 __vi_show_search_dialog( data, "Search" );
538 main( int argc, char *argv[] )
540 XtAppContext ctx;
541 Widget top_level, rc, button;
542 extern exit();
544 /* create a top-level shell for the window manager */
545 top_level = XtVaAppInitialize( &ctx,
546 argv[0],
547 NULL, 0, /* options */
548 (ArgcType) &argc,
549 argv, /* might get modified */
550 NULL,
551 NULL
554 rc = XtVaCreateManagedWidget( "rc",
555 xmRowColumnWidgetClass,
556 top_level,
560 button = XtVaCreateManagedWidget( "Pop up search dialog",
561 xmPushButtonGadgetClass,
565 XtAddCallback( button, XmNactivateCallback, show_search, rc );
567 button = XtVaCreateManagedWidget( "Quit",
568 xmPushButtonGadgetClass,
572 XtAddCallback( button, XmNactivateCallback, exit, 0 );
574 XtRealizeWidget(top_level);
575 XtAppMainLoop(ctx);
577 #endif