TextPop.c revision 5b16253f
17a84e134Smrg/*
27a84e134Smrg
37a84e134SmrgCopyright 1989, 1994, 1998  The Open Group
47a84e134Smrg
57a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its
67a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that
77a84e134Smrgthe above copyright notice appear in all copies and that both that
87a84e134Smrgcopyright notice and this permission notice appear in supporting
97a84e134Smrgdocumentation.
107a84e134Smrg
117a84e134SmrgThe above copyright notice and this permission notice shall be included in
127a84e134Smrgall copies or substantial portions of the Software.
137a84e134Smrg
147a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
177a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
187a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
197a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
207a84e134Smrg
217a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be
227a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings
237a84e134Smrgin this Software without prior written authorization from The Open Group.
247a84e134Smrg
257a84e134Smrg*/
267a84e134Smrg
277a84e134Smrg/*
287a84e134Smrg * This file is broken up into three sections one dealing with
297a84e134Smrg * each of the three popups created here:
307a84e134Smrg *
317a84e134Smrg * FileInsert, Search, and Replace.
327a84e134Smrg *
33421c997bSmrg * There is also a section at the end for utility functions
347a84e134Smrg * used by all more than one of these dialogs.
357a84e134Smrg *
367a84e134Smrg * The following functions are the only non-static ones defined
375b16253fSmrg * in this module.  They are located at the beginning of the
387a84e134Smrg * section that contains this dialog box that uses them.
39421c997bSmrg *
407a84e134Smrg * void _XawTextInsertFileAction(w, event, params, num_params);
417a84e134Smrg * void _XawTextDoSearchAction(w, event, params, num_params);
427a84e134Smrg * void _XawTextDoReplaceAction(w, event, params, num_params);
437a84e134Smrg * void _XawTextInsertFile(w, event, params, num_params);
447a84e134Smrg */
457a84e134Smrg
467a84e134Smrg#ifdef HAVE_CONFIG_H
477a84e134Smrg#include <config.h>
487a84e134Smrg#endif
497a84e134Smrg#include <stdio.h>
507a84e134Smrg#include <errno.h>
517a84e134Smrg#include <X11/IntrinsicP.h>
527a84e134Smrg#include <X11/StringDefs.h>
53421c997bSmrg#include <X11/Shell.h>
547a84e134Smrg#include <X11/Xos.h>
557a84e134Smrg#include <X11/Xmu/CharSet.h>
567a84e134Smrg#include <X11/Xaw/TextP.h>
577a84e134Smrg#include <X11/Xaw/AsciiText.h>
587a84e134Smrg#include <X11/Xaw/Cardinals.h>
597a84e134Smrg#include <X11/Xaw/Command.h>
607a84e134Smrg#include <X11/Xaw/Form.h>
617a84e134Smrg#include <X11/Xaw/Toggle.h>
627a84e134Smrg#include "XawI18n.h"
637a84e134Smrg
645ec34c4cSmrgstatic _Xconst char* INSERT_FILE = "Enter Filename:";
655ec34c4cSmrgstatic _Xconst char* SEARCH_LABEL_1 = "Use <Tab> to change fields.";
665ec34c4cSmrgstatic _Xconst char* SEARCH_LABEL_2 = "Use ^q<Tab> for <Tab>.";
675ec34c4cSmrgstatic _Xconst char* DISMISS_NAME = "cancel";
687a84e134Smrg#define DISMISS_NAME_LEN 6
695ec34c4cSmrgstatic _Xconst char* FORM_NAME = "form";
705ec34c4cSmrgstatic _Xconst char* LABEL_NAME = "label";
715ec34c4cSmrgstatic _Xconst char* TEXT_NAME = "text";
727a84e134Smrg
737a84e134Smrg#define R_OFFSET      1
747a84e134Smrg
755ec34c4cSmrgtypedef void (*AddFunc)(Widget, String, Widget);
767a84e134Smrg
777a84e134Smrg/*
787a84e134Smrg * Prototypes
797a84e134Smrg */
807a84e134Smrgstatic void _SetField(Widget, Widget);
815ec34c4cSmrgstatic void AddSearchChildren(Widget, String, Widget);
825ec34c4cSmrgstatic void AddInsertFileChildren(Widget, String, Widget);
837a84e134Smrgstatic void CenterWidgetOnPoint(Widget, XEvent*);
847a84e134Smrgstatic Widget CreateDialog(Widget, String, String, AddFunc);
857a84e134Smrgstatic void DoInsert(Widget, XtPointer, XtPointer);
867a84e134Smrgstatic void DoReplaceAll(Widget, XtPointer, XtPointer);
877a84e134Smrgstatic void DoReplaceOne(Widget, XtPointer, XtPointer);
887a84e134Smrgstatic Bool DoSearch(struct SearchAndReplace*);
897a84e134Smrgstatic Widget GetShell(Widget);
907a84e134Smrgstatic String GetString(Widget);
915ec34c4cSmrgstatic _XtString GetStringRaw(Widget);
927a84e134Smrgstatic void InitializeSearchWidget(struct SearchAndReplace*,
937a84e134Smrg				   XawTextScanDirection, Bool);
947a84e134Smrgstatic Bool InParams(String, String*, unsigned int);
955ec34c4cSmrgstatic Bool InsertFileNamed(Widget, String);
967a84e134Smrgstatic void PopdownFileInsert(Widget, XtPointer, XtPointer);
977a84e134Smrgstatic void PopdownSearch(Widget, XtPointer, XtPointer);
987a84e134Smrgstatic Bool Replace(struct SearchAndReplace*, Bool, Bool);
997a84e134Smrgstatic void SearchButton(Widget, XtPointer, XtPointer);
1005ec34c4cSmrgstatic void SetResource(Widget, String, XtArgVal);
1015ec34c4cSmrgstatic Bool SetResourceByName(Widget, String, String, XtArgVal);
1027a84e134Smrgstatic void SetSearchLabels(struct SearchAndReplace*, String, String, Bool);
1037a84e134Smrgstatic void SetWMProtocolTranslations(Widget);
1047a84e134Smrg
1057a84e134Smrg/*
1067a84e134Smrg * Actions
1077a84e134Smrg */
1087a84e134Smrgstatic void WMProtocols(Widget, XEvent*, String*, Cardinal*);
1097a84e134Smrg
1107a84e134Smrg/*
1117a84e134Smrg * External Actions
1127a84e134Smrg */
1137a84e134Smrgvoid _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*);
1147a84e134Smrgvoid _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*);
1157a84e134Smrgvoid _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*);
1167a84e134Smrgvoid _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*);
1177a84e134Smrgvoid _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*);
1187a84e134Smrgvoid _XawTextSearch(Widget, XEvent*, String*, Cardinal*);
1197a84e134Smrgvoid _XawTextSetField(Widget, XEvent*, String*, Cardinal*);
1207a84e134Smrg
1217a84e134Smrg/*
1227a84e134Smrg * From Text.c
1237a84e134Smrg */
1247a84e134Smrgchar *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
1257a84e134Smrgvoid _XawTextShowPosition(TextWidget);
1267a84e134Smrg
1277a84e134Smrg/*
1287a84e134Smrg * Initialization
1297a84e134Smrg */
1307a84e134Smrgstatic char radio_trans_string[] =
1317a84e134Smrg"<Btn1Down>,<Btn1Up>:"	"set() notify()\n"
1327a84e134Smrg;
1337a84e134Smrg
134421c997bSmrgstatic char search_text_trans[] =
1357a84e134Smrg"~s<Key>Return:"	"DoSearchAction(Popdown)\n"
1367a84e134Smrg"s<Key>Return:"		"DoSearchAction() SetField(Replace)\n"
1377a84e134Smrg"c<Key>c:"		"PopdownSearchAction()\n"
1387a84e134Smrg"<Btn1Down>:"		"select-start() SetField(Search)\n"
1397a84e134Smrg"<Key>Tab:"		"DoSearchAction() SetField(Replace)\n"
1407a84e134Smrg;
1417a84e134Smrg
142421c997bSmrgstatic char rep_text_trans[] =
1437a84e134Smrg"~s<Key>Return:"	"DoReplaceAction(Popdown)\n"
1447a84e134Smrg"s<Key>Return:"		"SetField(Search)\n"
1457a84e134Smrg"c<Key>c:"		"PopdownSearchAction()\n"
1467a84e134Smrg"<Btn1Down>:"		"select-start() DoSearchAction() SetField(Replace)\n"
1477a84e134Smrg"<Key>Tab:"		"SetField(Search)\n"
1487a84e134Smrg;
1497a84e134Smrg
1507a84e134Smrg/*
1517a84e134Smrg * Implementation
1527a84e134Smrg */
1537a84e134Smrg/*
154421c997bSmrg * This section of the file contains all the functions that
1557a84e134Smrg * the file insert dialog box uses
1567a84e134Smrg */
1577a84e134Smrg
1587a84e134Smrg/*
1597a84e134Smrg * Function:
1607a84e134Smrg *	_XawTextInsertFileAction
1617a84e134Smrg *
1627a84e134Smrg * Description:
1637a84e134Smrg *	  Action routine that can be bound to dialog box's Text Widget
1647a84e134Smrg *	that will insert a file into the main Text Widget.
1657a84e134Smrg */
1667a84e134Smrg/*ARGSUSED*/
167421c997bSmrgvoid
1685ec34c4cSmrg_XawTextInsertFileAction(Widget w, XEvent *event _X_UNUSED,
1695ec34c4cSmrg			 String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
1707a84e134Smrg{
1717a84e134Smrg    DoInsert(w, (XtPointer)XtParent(XtParent(XtParent(w))), NULL);
1727a84e134Smrg}
1737a84e134Smrg
1747a84e134Smrg/*
1757a84e134Smrg * Function:
1767a84e134Smrg *	_XawTextInsertFile
1777a84e134Smrg *
1787a84e134Smrg * Parameters:
1797a84e134Smrg *	w	   - text widget
1807a84e134Smrg *	event	   - X Event (used to get x and y location)
1817a84e134Smrg *	params	   - parameter list
1827a84e134Smrg *	num_params - ""
1837a84e134Smrg *
1847a84e134Smrg * Description:
1857a84e134Smrg *	  Action routine that can be bound to the text widget
1867a84e134Smrg *	it will popup the insert file dialog box.
1877a84e134Smrg *
1887a84e134Smrg * Note:
1897a84e134Smrg *	The parameter list may contain one entry
1907a84e134Smrg *
1917a84e134Smrg *  Entry:
1927a84e134Smrg *	  This entry is optional and contains the value of the default
1937a84e134Smrg *	file to insert
1947a84e134Smrg */
195421c997bSmrgvoid
1967a84e134Smrg_XawTextInsertFile(Widget w, XEvent *event,
1977a84e134Smrg		   String *params, Cardinal *num_params)
1987a84e134Smrg{
1997a84e134Smrg    TextWidget ctx = (TextWidget)w;
2005ec34c4cSmrg    String ptr;
2017a84e134Smrg    XawTextEditType edit_mode;
2027a84e134Smrg    Arg args[1];
2037a84e134Smrg
2047a84e134Smrg    XtSetArg(args[0], XtNeditType, &edit_mode);
2057a84e134Smrg    XtGetValues(ctx->text.source, args, 1);
206421c997bSmrg
2077a84e134Smrg    if (edit_mode != XawtextEdit) {
2087a84e134Smrg	XBell(XtDisplay(w), 0);
2097a84e134Smrg	return;
2107a84e134Smrg    }
2117a84e134Smrg
212421c997bSmrg    if (*num_params == 0)
2137a84e134Smrg	ptr = "";
214421c997bSmrg    else
2157a84e134Smrg	ptr = params[0];
216421c997bSmrg
2177a84e134Smrg    if (!ctx->text.file_insert) {
2187a84e134Smrg	ctx->text.file_insert = CreateDialog(w, ptr, "insertFile",
2197a84e134Smrg					     AddInsertFileChildren);
2207a84e134Smrg	XtRealizeWidget(ctx->text.file_insert);
2217a84e134Smrg	SetWMProtocolTranslations(ctx->text.file_insert);
2227a84e134Smrg    }
2237a84e134Smrg
2247a84e134Smrg    CenterWidgetOnPoint(ctx->text.file_insert, event);
2257a84e134Smrg    XtPopup(ctx->text.file_insert, XtGrabNone);
2267a84e134Smrg}
2277a84e134Smrg
2287a84e134Smrg/*
2297a84e134Smrg * Function:
2307a84e134Smrg *	PopdownFileInsert
2317a84e134Smrg *
2327a84e134Smrg * Parameters:
2337a84e134Smrg *	w	  - widget that caused this action
2347a84e134Smrg *	closure	  - pointer to the main text widget that popped up this dialog
2357a84e134Smrg *	call_data - (not used)
2367a84e134Smrg *
2377a84e134Smrg * Description:
2387a84e134Smrg *	Pops down the file insert button
2397a84e134Smrg */
2407a84e134Smrg/*ARGSUSED*/
241421c997bSmrgstatic void
2425ec34c4cSmrgPopdownFileInsert(Widget w _X_UNUSED, XtPointer closure, XtPointer call_data _X_UNUSED)
2437a84e134Smrg{
2447a84e134Smrg    TextWidget ctx = (TextWidget)closure;
2457a84e134Smrg
2467a84e134Smrg    XtPopdown(ctx->text.file_insert);
2477a84e134Smrg    (void)SetResourceByName(ctx->text.file_insert, LABEL_NAME,
2487a84e134Smrg			    XtNlabel, (XtArgVal)INSERT_FILE);
2497a84e134Smrg}
2507a84e134Smrg
2517a84e134Smrg/*
2527a84e134Smrg * Function:
2537a84e134Smrg *	DoInsert
2547a84e134Smrg *
2557a84e134Smrg * Parameters:
2567a84e134Smrg *	w	- widget that activated this callback
2577a84e134Smrg *	closure - pointer to the text widget to insert the file into
2587a84e134Smrg *
2597a84e134Smrg * Description:
2607a84e134Smrg *	Actually insert the file named in the text widget of the file dialog
2617a84e134Smrg */
2627a84e134Smrg/*ARGSUSED*/
263421c997bSmrgstatic void
2647a84e134SmrgDoInsert(Widget w, XtPointer closure, XtPointer call_data)
2657a84e134Smrg{
2667a84e134Smrg    TextWidget ctx = (TextWidget)closure;
2677a84e134Smrg    char buf[BUFSIZ], msg[BUFSIZ];
2687a84e134Smrg    Widget temp_widget;
2697a84e134Smrg
270421c997bSmrg    snprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, TEXT_NAME);
2717a84e134Smrg    if ((temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL) {
2727a84e134Smrg	(void)strcpy(msg,
2737a84e134Smrg		     "Error: Could not get text widget from file insert popup");
2747a84e134Smrg    }
2757a84e134Smrg    else if (InsertFileNamed((Widget)ctx, GetString(temp_widget))) {
2767a84e134Smrg	PopdownFileInsert(w, closure, call_data);
2777a84e134Smrg	return;
2787a84e134Smrg    }
2797a84e134Smrg    else
280421c997bSmrg	snprintf(msg, sizeof(msg), "Error: %s", strerror(errno));
2817a84e134Smrg
282421c997bSmrg    (void)SetResourceByName(ctx->text.file_insert,
2837a84e134Smrg			    LABEL_NAME, XtNlabel, (XtArgVal)msg);
2847a84e134Smrg    XBell(XtDisplay(w), 0);
2857a84e134Smrg}
2867a84e134Smrg
2877a84e134Smrg/*
2887a84e134Smrg * Function:
2897a84e134Smrg *	InsertFileNamed
2907a84e134Smrg *
2917a84e134Smrg * Parameters:
2927a84e134Smrg *	tw  - text widget to insert this file into
2937a84e134Smrg *	str - name of the file to insert
2947a84e134Smrg *
2957a84e134Smrg * Description:
2967a84e134Smrg *	Inserts a file into the text widget.
2977a84e134Smrg *
2987a84e134Smrg * Returns:
2995b16253fSmrg *	True if the insert was successful, False otherwise.
3007a84e134Smrg */
3017a84e134Smrgstatic Bool
3025ec34c4cSmrgInsertFileNamed(Widget tw, String str)
3037a84e134Smrg{
3047a84e134Smrg    FILE *file;
3057a84e134Smrg    XawTextBlock text;
3067a84e134Smrg    XawTextPosition pos;
3077a84e134Smrg
3087a84e134Smrg    if (str == NULL || strlen(str) == 0 || (file = fopen(str, "r")) == NULL)
3097a84e134Smrg	return (False);
3107a84e134Smrg
3117a84e134Smrg    pos = XawTextGetInsertionPoint(tw);
3127a84e134Smrg
313c8571806Smrg    fseek(file, 0L, SEEK_END);
3147a84e134Smrg
3157a84e134Smrg    text.firstPos = 0;
3165ec34c4cSmrg    text.length = (int)ftell(file);
3175ec34c4cSmrg    text.ptr = XtMalloc((Cardinal)(text.length + 1));
3187a84e134Smrg    text.format = XawFmt8Bit;
3197a84e134Smrg
320c8571806Smrg    fseek(file, 0L, SEEK_SET);
3215ec34c4cSmrg    if (fread(text.ptr, 1, (size_t)text.length, file) != (size_t)text.length)
3227a84e134Smrg	XtErrorMsg("readError", "insertFileNamed", "XawError",
3237a84e134Smrg		   "fread returned error", NULL, NULL);
3247a84e134Smrg
3257a84e134Smrg    if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) {
3267a84e134Smrg	XtFree(text.ptr);
3277a84e134Smrg	fclose(file);
3287a84e134Smrg	return (False);
3297a84e134Smrg    }
3307a84e134Smrg    pos += text.length;
3317a84e134Smrg    XtFree(text.ptr);
3327a84e134Smrg    fclose(file);
3337a84e134Smrg    XawTextSetInsertionPoint(tw, pos);
3347a84e134Smrg    _XawTextShowPosition((TextWidget)tw);
3357a84e134Smrg
3367a84e134Smrg    return (True);
3377a84e134Smrg}
3387a84e134Smrg
3397a84e134Smrg/*
3407a84e134Smrg * Function:
3417a84e134Smrg *	AddInsertFileChildren
3427a84e134Smrg *
3437a84e134Smrg * Parameters:
3447a84e134Smrg *	form - form widget for the insert dialog widget
3457a84e134Smrg *	ptr  - pointer to the initial string for the Text Widget
3467a84e134Smrg *	tw   - main text widget
3477a84e134Smrg *
3487a84e134Smrg * Description:
3497a84e134Smrg *	Adds all children to the InsertFile dialog widget.
3507a84e134Smrg */
3517a84e134Smrgstatic void
3525ec34c4cSmrgAddInsertFileChildren(Widget form, String ptr, Widget tw)
3537a84e134Smrg{
3547a84e134Smrg    Arg args[10];
3557a84e134Smrg    Cardinal num_args;
3567a84e134Smrg    Widget label, text, cancel, insert;
3577a84e134Smrg    XtTranslations trans;
3587a84e134Smrg
3597a84e134Smrg    num_args = 0;
3607a84e134Smrg    XtSetArg(args[num_args], XtNlabel, INSERT_FILE);	num_args++;
3617a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3627a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
3637a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	num_args++;
3647a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);	num_args++;
3657a84e134Smrg    label = XtCreateManagedWidget(LABEL_NAME, labelWidgetClass, form,
3667a84e134Smrg				  args, num_args);
367421c997bSmrg
3687a84e134Smrg    num_args = 0;
3697a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, label);	num_args++;
3707a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3717a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainRight);	num_args++;
3727a84e134Smrg    XtSetArg(args[num_args], XtNeditType, XawtextEdit);	num_args++;
3737a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	num_args++;
3747a84e134Smrg    XtSetArg(args[num_args], XtNstring, ptr);		num_args++;
3757a84e134Smrg    text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form,
3767a84e134Smrg				 args, num_args);
3777a84e134Smrg
3787a84e134Smrg    num_args = 0;
3797a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Insert File");	num_args++;
3807a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, text);	num_args++;
3817a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3827a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
3837a84e134Smrg    insert = XtCreateManagedWidget("insert", commandWidgetClass, form,
3847a84e134Smrg				   args, num_args);
3857a84e134Smrg
3867a84e134Smrg    num_args = 0;
3877a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Cancel");	num_args++;
3887a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, text);	num_args++;
3897a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, insert);	num_args++;
3907a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3917a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
3927a84e134Smrg    cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
3937a84e134Smrg				   args, num_args);
3947a84e134Smrg
3957a84e134Smrg    XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer)tw);
3967a84e134Smrg    XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer)tw);
3977a84e134Smrg
3987a84e134Smrg    XtSetKeyboardFocus(form, text);
3997a84e134Smrg
4007a84e134Smrg    /*
4017a84e134Smrg     * Bind <CR> to insert file
4027a84e134Smrg     */
4037a84e134Smrg    trans = XtParseTranslationTable("<Key>Return:InsertFileAction()");
4047a84e134Smrg    XtOverrideTranslations(text, trans);
4057a84e134Smrg}
4067a84e134Smrg
4077a84e134Smrg/*
408421c997bSmrg * This section of the file contains all the functions that
4097a84e134Smrg * the search dialog box uses
4107a84e134Smrg */
4117a84e134Smrg/*
4127a84e134Smrg * Function:
4137a84e134Smrg *	_XawTextDoSearchAction
4147a84e134Smrg *
4157a84e134Smrg * Description:
4167a84e134Smrg *	  Action routine that can be bound to dialog box's Text Widget that
4177a84e134Smrg *	will search for a string in the main Text Widget.
4187a84e134Smrg *
4197a84e134Smrg * Note:
4205b16253fSmrg * If the search was successful and the argument popdown is passed to
421421c997bSmrg * this action routine then the widget will automatically popdown the
4227a84e134Smrg *	search widget
4237a84e134Smrg */
4247a84e134Smrg/*ARGSUSED*/
425421c997bSmrgvoid
4265ec34c4cSmrg_XawTextDoSearchAction(Widget w, XEvent *event _X_UNUSED,
4277a84e134Smrg		       String *params, Cardinal *num_params)
4287a84e134Smrg{
4297a84e134Smrg    TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
4307a84e134Smrg    Bool popdown = False;
4317a84e134Smrg
4327a84e134Smrg    if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
4337a84e134Smrg	popdown = True;
434421c997bSmrg
4357a84e134Smrg    if (DoSearch(tw->text.search) && popdown)
4367a84e134Smrg	PopdownSearch(w, (XtPointer)tw->text.search, NULL);
4377a84e134Smrg}
4387a84e134Smrg
4397a84e134Smrg/*
4407a84e134Smrg * Function:
4417a84e134Smrg *	_XawTextPopdownSearchAction
4427a84e134Smrg *
4437a84e134Smrg * Description:
4447a84e134Smrg *	  Action routine that can be bound to dialog box's Text Widget that
4457a84e134Smrg *	will popdown the search widget.
4467a84e134Smrg */
4477a84e134Smrg/*ARGSUSED*/
448421c997bSmrgvoid
4495ec34c4cSmrg_XawTextPopdownSearchAction(Widget w, XEvent *event _X_UNUSED,
4505ec34c4cSmrg			    String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
4517a84e134Smrg{
4527a84e134Smrg    TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
4537a84e134Smrg
4547a84e134Smrg    PopdownSearch(w, (XtPointer)tw->text.search, NULL);
4557a84e134Smrg}
4567a84e134Smrg
4577a84e134Smrg/*
4587a84e134Smrg * Function:
4597a84e134Smrg *	PopdownSearch
4607a84e134Smrg *
4617a84e134Smrg * Parameters:
4627a84e134Smrg *	w	  - (not used)
4637a84e134Smrg *	closure	  - pointer to the search structure
4647a84e134Smrg *	call_data - (not used)
4657a84e134Smrg *
4667a84e134Smrg * Description:
4677a84e134Smrg *	Pops down the search widget and resets it
4687a84e134Smrg */
4697a84e134Smrg/*ARGSUSED*/
470421c997bSmrgstatic void
4715ec34c4cSmrgPopdownSearch(Widget w _X_UNUSED, XtPointer closure, XtPointer call_data _X_UNUSED)
4727a84e134Smrg{
4737a84e134Smrg    struct SearchAndReplace *search = (struct SearchAndReplace *)closure;
4747a84e134Smrg
4757a84e134Smrg    XtPopdown(search->search_popup);
4767a84e134Smrg    SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
4777a84e134Smrg}
4787a84e134Smrg
4797a84e134Smrg/*
4807a84e134Smrg * Function:
4817a84e134Smrg *	SearchButton
4827a84e134Smrg *
4837a84e134Smrg * Arguments:
4847a84e134Smrg *	w	  - (not used)
4857a84e134Smrg *	closure	  - pointer to the search info
4867a84e134Smrg *	call_data - (not used)
4877a84e134Smrg *
4887a84e134Smrg * Description:
4897a84e134Smrg *	Performs a search when the button is clicked.
4907a84e134Smrg */
4917a84e134Smrg/*ARGSUSED*/
492421c997bSmrgstatic void
4935ec34c4cSmrgSearchButton(Widget w _X_UNUSED, XtPointer closure, XtPointer call_data _X_UNUSED)
4947a84e134Smrg{
4957a84e134Smrg    (void)DoSearch((struct SearchAndReplace *)closure);
4967a84e134Smrg}
4977a84e134Smrg
4987a84e134Smrg/*
4997a84e134Smrg * Function:
5007a84e134Smrg *	_XawTextSearch
5017a84e134Smrg *
5027a84e134Smrg * Parameters:
5037a84e134Smrg *	w	   - text widget
5047a84e134Smrg *	event	   - X Event (used to get x and y location)
5057a84e134Smrg *	params	   - parameter list
5067a84e134Smrg *	num_params - ""
5077a84e134Smrg *
5087a84e134Smrg * Description:
5097a84e134Smrg *	  Action routine that can be bound to the text widget
5107a84e134Smrg *	it will popup the search dialog box.
5117a84e134Smrg *
5127a84e134Smrg * Note:
5137a84e134Smrg *	  The parameter list contains one or two entries that may be
5147a84e134Smrg *	the following.
5157a84e134Smrg *
5167a84e134Smrg * First Entry:
5177a84e134Smrg *	  The first entry is the direction to search by default.
5185b16253fSmrg *	This argument must be specified and may have a value of
5197a84e134Smrg *	"left" or "right".
5207a84e134Smrg *
5217a84e134Smrg * Second Entry:
5227a84e134Smrg *	  This entry is optional and contains the value of the default
5237a84e134Smrg *	string to search for.
5247a84e134Smrg */
5257a84e134Smrg
5267a84e134Smrg#define SEARCH_HEADER	"Text Widget - Search():"
527421c997bSmrgvoid
5287a84e134Smrg_XawTextSearch(Widget w, XEvent *event, String *params, Cardinal *num_params)
5297a84e134Smrg{
5307a84e134Smrg    TextWidget ctx = (TextWidget)w;
5317a84e134Smrg    XawTextScanDirection dir;
5325ec34c4cSmrg    String ptr;
5335ec34c4cSmrg    char buf[BUFSIZ];
5347a84e134Smrg    XawTextEditType edit_mode;
5357a84e134Smrg    Arg args[1];
5367a84e134Smrg    wchar_t wcs[1];
5377a84e134Smrg
5387a84e134Smrg    if (*num_params < 1 || *num_params > 2) {
539421c997bSmrg	snprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
540421c997bSmrg		 "This action must have only",
541421c997bSmrg		 "one or two parameters");
5427a84e134Smrg	XtAppWarning(XtWidgetToApplicationContext(w), buf);
5437a84e134Smrg	return;
5447a84e134Smrg    }
5457a84e134Smrg
5467a84e134Smrg    if (*num_params == 2)
5477a84e134Smrg	ptr = params[1];
5487a84e134Smrg    else if (XawTextFormat(ctx, XawFmtWide)) {
5497a84e134Smrg	/* This just does the equivalent of
5505b16253fSmrg	   ptr = ""L, a waste because params[1] isn't W aligned */
5517a84e134Smrg	ptr = (char *)wcs;
5527a84e134Smrg	wcs[0] = 0;
5537a84e134Smrg    }
5547a84e134Smrg    else
5557a84e134Smrg	ptr = "";
5567a84e134Smrg
5577a84e134Smrg    switch(params[0][0]) {
558421c997bSmrg	case 'b':		  /* Left */
5597a84e134Smrg	case 'B':
5607a84e134Smrg	    dir = XawsdLeft;
5617a84e134Smrg	    break;
562421c997bSmrg	case 'f':		  /* Right */
5637a84e134Smrg	case 'F':
5647a84e134Smrg	    dir = XawsdRight;
5657a84e134Smrg	    break;
5667a84e134Smrg	default:
567421c997bSmrg	    snprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
568421c997bSmrg		     "The first parameter must be",
569421c997bSmrg		     "Either 'backward' or 'forward'");
5707a84e134Smrg	    XtAppWarning(XtWidgetToApplicationContext(w), buf);
5717a84e134Smrg	    return;
5727a84e134Smrg    }
5737a84e134Smrg
5747a84e134Smrg    if (ctx->text.search== NULL) {
5757a84e134Smrg	ctx->text.search = XtNew(struct SearchAndReplace);
5767a84e134Smrg	ctx->text.search->search_popup = CreateDialog(w, ptr, "search",
5777a84e134Smrg						      AddSearchChildren);
5787a84e134Smrg	XtRealizeWidget(ctx->text.search->search_popup);
5797a84e134Smrg	SetWMProtocolTranslations(ctx->text.search->search_popup);
5807a84e134Smrg    }
5817a84e134Smrg    else if (*num_params > 1)
5827a84e134Smrg	XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL);
5837a84e134Smrg
5847a84e134Smrg    XtSetArg(args[0], XtNeditType,&edit_mode);
5857a84e134Smrg    XtGetValues(ctx->text.source, args, 1);
5867a84e134Smrg
5877a84e134Smrg    InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit));
5887a84e134Smrg
5897a84e134Smrg    CenterWidgetOnPoint(ctx->text.search->search_popup, event);
5907a84e134Smrg    XtPopup(ctx->text.search->search_popup, XtGrabNone);
5917a84e134Smrg}
5927a84e134Smrg
5937a84e134Smrg/*
5947a84e134Smrg * Function:
5957a84e134Smrg *	InitializeSearchWidget
5967a84e134Smrg *
5977a84e134Smrg * Parameters:
5987a84e134Smrg *	search	       - search widget structure
5997a84e134Smrg *	dir	       - direction to search
6007a84e134Smrg *	replace_active - state of the sensitivity for the replace button
6017a84e134Smrg *
6027a84e134Smrg * Description:
6037a84e134Smrg *	  This function initializes the search widget and
6045b16253fSmrg *		   is called each time the search widget is popped up.
6057a84e134Smrg */
6067a84e134Smrgstatic void
6077a84e134SmrgInitializeSearchWidget(struct SearchAndReplace *search,
6087a84e134Smrg		       XawTextScanDirection dir, Bool replace_active)
6097a84e134Smrg{
6107a84e134Smrg    SetResource(search->rep_one, XtNsensitive, (XtArgVal)replace_active);
6117a84e134Smrg    SetResource(search->rep_all, XtNsensitive, (XtArgVal)replace_active);
6127a84e134Smrg    SetResource(search->rep_label, XtNsensitive, (XtArgVal)replace_active);
6137a84e134Smrg    SetResource(search->rep_text, XtNsensitive, (XtArgVal)replace_active);
6147a84e134Smrg
6157a84e134Smrg    switch (dir) {
6167a84e134Smrg	case XawsdLeft:
6177a84e134Smrg	    SetResource(search->left_toggle, XtNstate, (XtArgVal)True);
6187a84e134Smrg	    break;
6197a84e134Smrg	case XawsdRight:
6207a84e134Smrg	    SetResource(search->right_toggle, XtNstate, (XtArgVal)True);
6217a84e134Smrg	    break;
6227a84e134Smrg    }
623421c997bSmrg}
6247a84e134Smrg
6257a84e134Smrg/*
6267a84e134Smrg * Function:
6277a84e134Smrg *	AddSearchChildren
6287a84e134Smrg *
6297a84e134Smrg * Parameters:
6307a84e134Smrg *	form - form widget for the search widget
6317a84e134Smrg *	ptr  - pointer to the initial string for the Text Widget
6327a84e134Smrg *	tw   - main text widget
6337a84e134Smrg *
6347a84e134Smrg * Description:
6357a84e134Smrg *	Adds all children to the Search Dialog Widget.
6367a84e134Smrg */
6377a84e134Smrgstatic void
6385ec34c4cSmrgAddSearchChildren(Widget form, String ptr, Widget tw)
6397a84e134Smrg{
6407a84e134Smrg    Arg args[10];
6417a84e134Smrg    Cardinal num_args;
6427a84e134Smrg    Widget cancel, search_button, s_label, s_text, r_text;
6437a84e134Smrg    XtTranslations trans;
6447a84e134Smrg    struct SearchAndReplace *search = ((TextWidget)tw)->text.search;
6457a84e134Smrg
6467a84e134Smrg    num_args = 0;
6477a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
6487a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
6497a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	num_args++;
6507a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);	num_args++;
6517a84e134Smrg    search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form,
6527a84e134Smrg					   args, num_args);
6537a84e134Smrg
6547a84e134Smrg    num_args = 0;
6557a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++;
6567a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	   num_args++;
6577a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	   num_args++;
6587a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	   num_args++;
6597a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);	   num_args++;
6607a84e134Smrg    search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form,
6617a84e134Smrg					   args, num_args);
662421c997bSmrg
6637a84e134Smrg    /*
6647a84e134Smrg     * We need to add R_OFFSET to the radio_data, because the value zero (0)
6657a84e134Smrg     * has special meaning
6667a84e134Smrg     */
6677a84e134Smrg    num_args = 0;
6687a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Backward");	   num_args++;
6697a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
6707a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	   num_args++;
6717a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	   num_args++;
6727a84e134Smrg    XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdLeft + R_OFFSET);
6737a84e134Smrg    num_args++;
6747a84e134Smrg    search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass,
6757a84e134Smrg						form, args, num_args);
6767a84e134Smrg
6777a84e134Smrg    num_args = 0;
6787a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Forward");	   num_args++;
6797a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
6807a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++;
6817a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	   num_args++;
6827a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	   num_args++;
6837a84e134Smrg    XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++;
6847a84e134Smrg    XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdRight + R_OFFSET);
6857a84e134Smrg    num_args++;
6867a84e134Smrg    search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass,
6877a84e134Smrg						 form, args, num_args);
6887a84e134Smrg
6897a84e134Smrg    {
6907a84e134Smrg	XtTranslations radio_translations;
6917a84e134Smrg
6927a84e134Smrg	radio_translations = XtParseTranslationTable(radio_trans_string);
6937a84e134Smrg	XtOverrideTranslations(search->left_toggle, radio_translations);
6947a84e134Smrg	XtOverrideTranslations(search->right_toggle, radio_translations);
6957a84e134Smrg    }
6967a84e134Smrg
6977a84e134Smrg#ifndef OLDXAW
6987a84e134Smrg    if (XawTextFormat((TextWidget)tw, XawFmt8Bit)) {
6997a84e134Smrg	num_args = 0;
7007a84e134Smrg	XtSetArg(args[num_args], XtNlabel, "Case Sensitive");	num_args++;
7017a84e134Smrg	XtSetArg(args[num_args], XtNfromVert, search->label2);	num_args++;
7027a84e134Smrg	XtSetArg(args[num_args], XtNfromHoriz, search->right_toggle); num_args++;
7037a84e134Smrg	XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7047a84e134Smrg	XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
7057a84e134Smrg	XtSetArg(args[num_args], XtNstate, True);		num_args++;
7067a84e134Smrg	search->case_sensitive = XtCreateManagedWidget("case", toggleWidgetClass,
7077a84e134Smrg						       form, args, num_args);
7087a84e134Smrg    }
7097a84e134Smrg    else
7107a84e134Smrg	search->case_sensitive = NULL;
7117a84e134Smrg#endif
7127a84e134Smrg
7137a84e134Smrg    num_args = 0;
7147a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->left_toggle);	num_args++;
7157a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Search for:  ");	num_args++;
7167a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7177a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7187a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0 );		num_args++;
7197a84e134Smrg    s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form,
7207a84e134Smrg				    args, num_args);
7217a84e134Smrg
7227a84e134Smrg    num_args = 0;
7237a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
7247a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, s_label);		num_args++;
7257a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7267a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainRight);		num_args++;
7277a84e134Smrg    XtSetArg(args[num_args], XtNeditType, XawtextEdit);		num_args++;
7287a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);		num_args++;
7297a84e134Smrg    XtSetArg(args[num_args], XtNstring, ptr);			num_args++;
7307a84e134Smrg    s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form,
7317a84e134Smrg				   args, num_args);
7327a84e134Smrg    search->search_text = s_text;
7337a84e134Smrg
7347a84e134Smrg    num_args = 0;
7357a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, s_text);		num_args++;
7367a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Replace with:");	num_args++;
7377a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7387a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7397a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);		num_args++;
7407a84e134Smrg    search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass,
7417a84e134Smrg					      form, args, num_args);
7427a84e134Smrg
7437a84e134Smrg    num_args = 0;
7447a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, s_label);		num_args++;
7457a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, s_text);		num_args++;
7467a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7477a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainRight);		num_args++;
7487a84e134Smrg    XtSetArg(args[num_args], XtNeditType, XawtextEdit);		num_args++;
7497a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);		num_args++;
7507a84e134Smrg    XtSetArg(args[num_args], XtNstring, ""); num_args++;
7517a84e134Smrg    r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass,
7527a84e134Smrg				   form, args, num_args);
7537a84e134Smrg    search->rep_text = r_text;
754421c997bSmrg
7557a84e134Smrg    num_args = 0;
7567a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Search");		num_args++;
7577a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7587a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7597a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7607a84e134Smrg    search_button = XtCreateManagedWidget("search", commandWidgetClass, form,
7617a84e134Smrg					  args, num_args);
7627a84e134Smrg
7637a84e134Smrg    num_args = 0;
7647a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Replace");		num_args++;
7657a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7667a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search_button);	num_args++;
7677a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7687a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7697a84e134Smrg    search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass,
7707a84e134Smrg					    form, args, num_args);
7717a84e134Smrg
7727a84e134Smrg    num_args = 0;
7737a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Replace All");		num_args++;
7747a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7757a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search->rep_one);	num_args++;
7767a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7777a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7787a84e134Smrg    search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass,
7797a84e134Smrg					    form, args, num_args);
7807a84e134Smrg
7817a84e134Smrg    num_args = 0;
7827a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Cancel");		num_args++;
7837a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7847a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search->rep_all);	num_args++;
7857a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7867a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7877a84e134Smrg    cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
7887a84e134Smrg				   args, num_args);
7897a84e134Smrg
7907a84e134Smrg    XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer)search);
7917a84e134Smrg    XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer)search);
7927a84e134Smrg    XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer)search);
7937a84e134Smrg    XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer)search);
7947a84e134Smrg
7957a84e134Smrg    /*
7967a84e134Smrg     * Initialize the text entry fields
7977a84e134Smrg     */
7987a84e134Smrg    {
7997a84e134Smrg	Pixel color;
8007a84e134Smrg
8017a84e134Smrg	num_args = 0;
8027a84e134Smrg	XtSetArg(args[num_args], XtNbackground, &color); num_args++;
8037a84e134Smrg	XtGetValues(search->rep_text, args, num_args);
8047a84e134Smrg	num_args = 0;
8057a84e134Smrg	XtSetArg(args[num_args], XtNborderColor, color); num_args++;
8067a84e134Smrg	XtSetValues(search->rep_text, args, num_args);
8077a84e134Smrg	XtSetKeyboardFocus(form, search->search_text);
8087a84e134Smrg    }
8097a84e134Smrg
8107a84e134Smrg    SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
8117a84e134Smrg
8127a84e134Smrg    /*
8137a84e134Smrg     * Bind Extra translations
8147a84e134Smrg     */
8157a84e134Smrg    trans = XtParseTranslationTable(search_text_trans);
8167a84e134Smrg    XtOverrideTranslations(search->search_text, trans);
8177a84e134Smrg
8187a84e134Smrg    trans = XtParseTranslationTable(rep_text_trans);
8197a84e134Smrg    XtOverrideTranslations(search->rep_text, trans);
8207a84e134Smrg}
8217a84e134Smrg
8227a84e134Smrg/*
8237a84e134Smrg * Function:
8247a84e134Smrg *	DoSearch
8257a84e134Smrg *
8267a84e134Smrg * Parameters:
8277a84e134Smrg *	search - search structure
8287a84e134Smrg *
8297a84e134Smrg * Description:
8307a84e134Smrg *	Performs a search
8317a84e134Smrg *
8327a84e134Smrg * Returns:
8335b16253fSmrg *	True if successful
8347a84e134Smrg */
8357a84e134Smrg/*ARGSUSED*/
8367a84e134Smrgstatic Bool
8377a84e134SmrgDoSearch(struct SearchAndReplace *search)
8387a84e134Smrg{
8397a84e134Smrg    char msg[37];
8407a84e134Smrg    Widget tw = XtParent(search->search_popup);
8417a84e134Smrg    XawTextPosition pos;
8427a84e134Smrg    XawTextScanDirection dir;
8437a84e134Smrg    XawTextBlock text;
8447a84e134Smrg    TextWidget ctx = (TextWidget)tw;
8457a84e134Smrg
8467a84e134Smrg    text.firstPos = 0;
8477a84e134Smrg    text.ptr = GetStringRaw(search->search_text);
8485ec34c4cSmrg    if ((text.format = (unsigned long)_XawTextFormat(ctx)) == XawFmtWide)
8495ec34c4cSmrg	text.length = (int)wcslen((wchar_t*)text.ptr);
8507a84e134Smrg    else {
8515ec34c4cSmrg	text.length = (int)strlen(text.ptr);
8527a84e134Smrg
8537a84e134Smrg#ifndef OLDXAW
8547a84e134Smrg	if (search->case_sensitive) {
8557a84e134Smrg	  /* text.firstPos isn't useful here, so I'll use it as an
8567a84e134Smrg	   * options flag.
8577a84e134Smrg	   */
8587a84e134Smrg	    Arg args[1];
8597a84e134Smrg	    Boolean case_sensitive;
8607a84e134Smrg
8617a84e134Smrg	    XtSetArg(args[0], XtNstate, &case_sensitive);
8627a84e134Smrg	    XtGetValues(search->case_sensitive, args, 1);
8637a84e134Smrg	    text.firstPos = !case_sensitive;
8647a84e134Smrg	}
8657a84e134Smrg#endif /* OLDXAW */
8667a84e134Smrg    }
867421c997bSmrg
8687a84e134Smrg    dir = (XawTextScanDirection)(unsigned long)
8697a84e134Smrg      ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
8707a84e134Smrg
8717a84e134Smrg    pos = XawTextSearch(tw, dir, &text);
8727a84e134Smrg
873421c997bSmrg   /* The Raw string in find.ptr may be WC I can't use here, so I re - call
8747a84e134Smrg     GetString to get a tame version */
8757a84e134Smrg
8767a84e134Smrg    if (pos == XawTextSearchError) {
8775ec34c4cSmrg	String ptr;
8787a84e134Smrg	int len;
8797a84e134Smrg
8807a84e134Smrg	ptr = GetString(search->search_text);
8815ec34c4cSmrg	len = (int)strlen(ptr);
882421c997bSmrg	snprintf(msg, sizeof(msg), "%s", ptr);
8837a84e134Smrg
8847a84e134Smrg	ptr = strchr(msg, '\n');
8855ec34c4cSmrg	if (ptr != NULL || sizeof(msg) - 1 < (size_t)len) {
8867a84e134Smrg	    if (ptr != NULL)
8875ec34c4cSmrg		len = (int)(ptr - msg + 4);
8887a84e134Smrg	    else
8895ec34c4cSmrg		len = (int)strlen(msg);
8907a84e134Smrg
8917a84e134Smrg	    if (len < 4)
8927a84e134Smrg		strcpy(msg, "...");
8937a84e134Smrg	    else
8947a84e134Smrg		strcpy(msg + len - 4, "...");
8957a84e134Smrg	}
8967a84e134Smrg	XawTextUnsetSelection(tw);
8977a84e134Smrg	SetSearchLabels(search, "Could not find string", msg, True);
8987a84e134Smrg
8997a84e134Smrg	return (False);
9007a84e134Smrg    }
9017a84e134Smrg    XawTextDisableRedisplay(tw);
9027a84e134Smrg    XawTextSetSelection(tw, pos, pos + text.length);
9037a84e134Smrg    search->selection_changed = False;	/* selection is good */
9047a84e134Smrg
9057a84e134Smrg    if (dir == XawsdRight)
9067a84e134Smrg	XawTextSetInsertionPoint(tw, pos + text.length);
9077a84e134Smrg    else
9087a84e134Smrg	XawTextSetInsertionPoint(tw, pos);
9097a84e134Smrg    _XawTextShowPosition(ctx);
9107a84e134Smrg    XawTextEnableRedisplay(tw);
9117a84e134Smrg
9127a84e134Smrg    return (True);
9137a84e134Smrg}
9147a84e134Smrg
9157a84e134Smrg/*
916421c997bSmrg * This section of the file contains all the functions that
9177a84e134Smrg * the replace dialog box uses
9187a84e134Smrg */
9197a84e134Smrg/*
9207a84e134Smrg * Function:
9217a84e134Smrg *	_XawTextDoReplaceAction
9227a84e134Smrg *
9237a84e134Smrg * Description:
9247a84e134Smrg *	Action routine that can be bound to dialog box's
9257a84e134Smrg *	Text Widget that will replace a string in the main Text Widget.
9267a84e134Smrg */
9277a84e134Smrg/*ARGSUSED*/
928421c997bSmrgvoid
9295ec34c4cSmrg_XawTextDoReplaceAction(Widget w, XEvent *event _X_UNUSED,
9307a84e134Smrg			String *params, Cardinal *num_params)
9317a84e134Smrg{
9327a84e134Smrg    TextWidget ctx = (TextWidget)XtParent(XtParent(XtParent(w)));
9337a84e134Smrg    Bool popdown = False;
9347a84e134Smrg
9357a84e134Smrg    if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
9367a84e134Smrg	popdown = True;
9377a84e134Smrg
9387a84e134Smrg    if (Replace( ctx->text.search, True, popdown) && popdown)
9397a84e134Smrg	PopdownSearch(w, (XtPointer)ctx->text.search, NULL);
9407a84e134Smrg}
9417a84e134Smrg
9427a84e134Smrg/*
9437a84e134Smrg * Function:
9447a84e134Smrg *	DoReplaceOne
9457a84e134Smrg *
9467a84e134Smrg * Arguments:
9477a84e134Smrg *	w	  - *** Not Used ***
9487a84e134Smrg *	closure   - a pointer to the search structure
9497a84e134Smrg *	call_data - *** Not Used ***
9507a84e134Smrg *
9517a84e134Smrg * Description:
9527a84e134Smrg *	  Replaces the first instance of the string in the search
9537a84e134Smrg *	dialog's text widget with the one in the replace dialog's text widget.
9547a84e134Smrg */
9557a84e134Smrg/*ARGSUSED*/
9567a84e134Smrgstatic void
9575ec34c4cSmrgDoReplaceOne(Widget w _X_UNUSED, XtPointer closure, XtPointer call_data _X_UNUSED)
9587a84e134Smrg{
9597a84e134Smrg    Replace((struct SearchAndReplace *)closure, True, False);
9607a84e134Smrg}
9617a84e134Smrg
9627a84e134Smrg/*
9637a84e134Smrg * Function:
9647a84e134Smrg *	DoReplaceAll
9657a84e134Smrg *
9667a84e134Smrg * Parameters:
9677a84e134Smrg *	w	  - (not used)
9687a84e134Smrg *	closure	  - pointer to the search structure
9697a84e134Smrg *	call_data - (not used)
9707a84e134Smrg *
971421c997bSmrg * Description:
9727a84e134Smrg *	  Replaces every instance of the string in the search dialog's
9737a84e134Smrg *	text widget with the one in the replace dialog's text widget.
9747a84e134Smrg */
9757a84e134Smrg/*ARGSUSED*/
976421c997bSmrgstatic void
9775ec34c4cSmrgDoReplaceAll(Widget w _X_UNUSED, XtPointer closure, XtPointer call_data _X_UNUSED)
9787a84e134Smrg{
9797a84e134Smrg    Replace((struct SearchAndReplace *)closure, False, False);
9807a84e134Smrg}
9817a84e134Smrg
9827a84e134Smrg/*
9837a84e134Smrg * Function:
9847a84e134Smrg *	Replace
9857a84e134Smrg *
9867a84e134Smrg * Parameters:
9877a84e134Smrg *	tw	      - Text Widget to replce the string in
9887a84e134Smrg *	once_only     - if True then only replace the first one found,
9897a84e134Smrg *			else replace all of them
9907a84e134Smrg *	show_current  - if true then leave the selection on the
9917a84e134Smrg *		        string that was just replaced, otherwise
9927a84e134Smrg *		        move it onto the next one
9937a84e134Smrg *
9947a84e134Smrg * Description:
9957a84e134Smrg *	  This is the function that does the real work of
9967a84e134Smrg *	replacing strings in the main text widget.
9977a84e134Smrg */
9987a84e134Smrgstatic Bool
9997a84e134SmrgReplace(struct SearchAndReplace *search, Bool once_only, Bool show_current)
10007a84e134Smrg{
10017a84e134Smrg    XawTextPosition pos, new_pos, end_pos, ipos;
10027a84e134Smrg    XawTextScanDirection dir;
10037a84e134Smrg    XawTextBlock find, replace;
10047a84e134Smrg    Widget tw = XtParent(search->search_popup);
10057a84e134Smrg    int count = 0;
10067a84e134Smrg    TextWidget ctx = (TextWidget)tw;
10077a84e134Smrg    Bool redisplay;
10087a84e134Smrg
10097a84e134Smrg    find.ptr = GetStringRaw(search->search_text);
10105ec34c4cSmrg    if ((find.format = (unsigned long)_XawTextFormat(ctx)) == XawFmtWide)
10115ec34c4cSmrg	find.length = (int)(XawTextPosition)wcslen((wchar_t*)find.ptr);
10127a84e134Smrg    else
10135ec34c4cSmrg	find.length = (int)(XawTextPosition)strlen(find.ptr);
10147a84e134Smrg    find.firstPos = 0;
10157a84e134Smrg
10167a84e134Smrg    replace.ptr = GetStringRaw(search->rep_text);
10177a84e134Smrg    replace.firstPos = 0;
10185ec34c4cSmrg    if ((replace.format = (unsigned long)_XawTextFormat(ctx)) == XawFmtWide)
10195ec34c4cSmrg	replace.length = (int)wcslen((wchar_t*)replace.ptr);
10207a84e134Smrg    else
10215ec34c4cSmrg	replace.length = (int)strlen(replace.ptr);
1022421c997bSmrg
10237a84e134Smrg    dir = (XawTextScanDirection)(unsigned long)
10247a84e134Smrg      ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
10257a84e134Smrg
10267a84e134Smrg    redisplay = !once_only || (once_only && !show_current);
10277a84e134Smrg    ipos = XawTextGetInsertionPoint(tw);
10287a84e134Smrg    if (redisplay)
10297a84e134Smrg	XawTextDisableRedisplay(tw);
10307a84e134Smrg    /*CONSTCOND*/
10317a84e134Smrg    while (True) {
10327a84e134Smrg	if (count != 0)	{
10337a84e134Smrg	    new_pos = XawTextSearch(tw, dir, &find);
10347a84e134Smrg
10357a84e134Smrg	    if (new_pos == XawTextSearchError) {
10367a84e134Smrg		if (count == 0) {
10377a84e134Smrg		    char msg[37];
10385ec34c4cSmrg		    String ptr;
10397a84e134Smrg		    int len;
10407a84e134Smrg
10417a84e134Smrg		    ptr = GetString(search->search_text);
10425ec34c4cSmrg		    len = (int)strlen(ptr);
1043421c997bSmrg		    snprintf(msg, sizeof(msg), "%s", ptr);
10447a84e134Smrg		    ptr = strchr(msg, '\n');
10455ec34c4cSmrg		    if (ptr != NULL || sizeof(msg) - 1 < (size_t)len) {
10467a84e134Smrg			if (ptr != NULL)
10475ec34c4cSmrg			    len = (int)(ptr - msg + 4);
10487a84e134Smrg			else
10495ec34c4cSmrg			    len = (int)strlen(msg);
10507a84e134Smrg
10517a84e134Smrg			if (len < 4)
10527a84e134Smrg			    strcpy(msg, "...");
10537a84e134Smrg			else
10547a84e134Smrg			    strcpy(msg + len - 4, "...");
10557a84e134Smrg		    }
10567a84e134Smrg		    SetSearchLabels(search, "Could not find string", msg, True);
10577a84e134Smrg
10587a84e134Smrg		    if (redisplay) {
10597a84e134Smrg			XawTextSetInsertionPoint(tw, ipos);
10607a84e134Smrg			_XawTextShowPosition(ctx);
10617a84e134Smrg			XawTextEnableRedisplay(tw);
10627a84e134Smrg		    }
10637a84e134Smrg
10647a84e134Smrg		    return (False);
10657a84e134Smrg		}
10667a84e134Smrg		else
10677a84e134Smrg		    break;
10687a84e134Smrg	    }
10697a84e134Smrg	    pos = new_pos;
10707a84e134Smrg	    end_pos = pos + find.length;
10717a84e134Smrg	}
10727a84e134Smrg	else {
10737a84e134Smrg	    XawTextGetSelectionPos(tw, &pos, &end_pos);
10747a84e134Smrg
10757a84e134Smrg	    if (search->selection_changed) {
10767a84e134Smrg		SetSearchLabels(search, "Selection modified, aborting.",
10777a84e134Smrg				"", True);
10787a84e134Smrg		if (redisplay) {
10797a84e134Smrg		    XawTextSetInsertionPoint(tw, ipos);
10807a84e134Smrg		    XawTextEnableRedisplay(tw);
10817a84e134Smrg		}
10827a84e134Smrg
10837a84e134Smrg		return (False);
10847a84e134Smrg	    }
10857a84e134Smrg	    if (pos == end_pos) {
10867a84e134Smrg		if (redisplay) {
10877a84e134Smrg		    XawTextSetInsertionPoint(tw, ipos);
10887a84e134Smrg		    XawTextEnableRedisplay(tw);
10897a84e134Smrg		}
10907a84e134Smrg
10917a84e134Smrg		return (False);
10927a84e134Smrg	    }
10937a84e134Smrg	}
10947a84e134Smrg
10957a84e134Smrg	if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) {
10967a84e134Smrg	    SetSearchLabels(search, "Error while replacing.", "", True);
10977a84e134Smrg	    if (redisplay) {
10987a84e134Smrg		XawTextSetInsertionPoint(tw, ipos);
10997a84e134Smrg		XawTextEnableRedisplay(tw);
11007a84e134Smrg	    }
11017a84e134Smrg
11027a84e134Smrg	    return (False);
11037a84e134Smrg	}
11047a84e134Smrg
11057a84e134Smrg	if (dir == XawsdRight)
11067a84e134Smrg	    ipos = pos + replace.length;
11077a84e134Smrg	else
11087a84e134Smrg	    ipos = pos;
11097a84e134Smrg
11107a84e134Smrg	if (once_only) {
11117a84e134Smrg	    if (show_current)
11127a84e134Smrg		break;
11137a84e134Smrg	    else {
11147a84e134Smrg		DoSearch(search);
11157a84e134Smrg		XawTextEnableRedisplay(tw);
11167a84e134Smrg
11177a84e134Smrg		return (True);
11187a84e134Smrg	    }
11197a84e134Smrg	}
11207a84e134Smrg	else
11217a84e134Smrg	    ctx->text.insertPos = ipos;
11227a84e134Smrg	count++;
11237a84e134Smrg    }
11247a84e134Smrg
11257a84e134Smrg    if (replace.length == 0)
11267a84e134Smrg	XawTextUnsetSelection(tw);
11277a84e134Smrg    else
11287a84e134Smrg	XawTextSetSelection(tw, pos, pos + replace.length);
11297a84e134Smrg
11307a84e134Smrg    XawTextSetInsertionPoint(tw, ipos);
11317a84e134Smrg    _XawTextShowPosition(ctx);
11327a84e134Smrg    XawTextEnableRedisplay(tw);
11337a84e134Smrg
11347a84e134Smrg    return (True);
11357a84e134Smrg}
11367a84e134Smrg
11377a84e134Smrg/*
11387a84e134Smrg * Function:
11397a84e134Smrg *	SetSearchLabels
11407a84e134Smrg *
11417a84e134Smrg * Parameters:
11427a84e134Smrg *	search - search structure
11437a84e134Smrg *	msg1   - message to put in each search label
11447a84e134Smrg *	msg2   - ""
11457a84e134Smrg *	bell   - if True then ring bell
11467a84e134Smrg *
11477a84e134Smrg * Description:
11487a84e134Smrg *	Sets both the search labels, and also rings the bell.
11497a84e134Smrg */
11507a84e134Smrgstatic void
11517a84e134SmrgSetSearchLabels(struct SearchAndReplace *search, String msg1, String msg2,
11527a84e134Smrg		Bool bell)
11537a84e134Smrg{
11547a84e134Smrg    (void)SetResource(search->label1, XtNlabel, (XtArgVal)msg1);
11557a84e134Smrg    (void)SetResource(search->label2, XtNlabel, (XtArgVal)msg2);
1156421c997bSmrg    if (bell)
11577a84e134Smrg	XBell(XtDisplay(search->search_popup), 0);
11587a84e134Smrg}
11597a84e134Smrg
11607a84e134Smrg/*
11617a84e134Smrg * This section of the file contains utility routines used by
11627a84e134Smrg * other functions in this file
11637a84e134Smrg */
11647a84e134Smrg/*
11657a84e134Smrg * Function:
11667a84e134Smrg *	_XawTextSetField
11677a84e134Smrg *
11687a84e134Smrg * Description:
11697a84e134Smrg *	  Action routine that can be bound to dialog box's
11707a84e134Smrg *		   Text Widget that will send input to the field specified.
11717a84e134Smrg */
11727a84e134Smrg/*ARGSUSED*/
1173421c997bSmrgvoid
11745ec34c4cSmrg_XawTextSetField(Widget w, XEvent *event _X_UNUSED, String *params, Cardinal *num_params)
11757a84e134Smrg{
11767a84e134Smrg    struct SearchAndReplace *search;
11777a84e134Smrg    Widget cnew, old;
11787a84e134Smrg
11797a84e134Smrg    search = ((TextWidget)XtParent(XtParent(XtParent(w))))->text.search;
11807a84e134Smrg
11817a84e134Smrg    if (*num_params != 1) {
11827a84e134Smrg	SetSearchLabels(search, "Error: SetField Action must have",
11837a84e134Smrg			"exactly one argument", True);
11847a84e134Smrg	return;
11857a84e134Smrg    }
11867a84e134Smrg    switch (params[0][0])  {
11877a84e134Smrg	case 's':
11887a84e134Smrg	case 'S':
11897a84e134Smrg	    cnew = search->search_text;
11907a84e134Smrg	    old = search->rep_text;
11917a84e134Smrg	    break;
11927a84e134Smrg	case 'r':
11937a84e134Smrg	case 'R':
11947a84e134Smrg	    old = search->search_text;
11957a84e134Smrg	    cnew = search->rep_text;
11967a84e134Smrg	    break;
11977a84e134Smrg	default:
11987a84e134Smrg	    SetSearchLabels(search,
11997a84e134Smrg			    "Error: SetField Action's first Argument must",
12007a84e134Smrg			    "be either 'Search' or 'Replace'", True);
12017a84e134Smrg	    return;
12027a84e134Smrg    }
12037a84e134Smrg    _SetField(cnew, old);
12047a84e134Smrg}
12057a84e134Smrg
12067a84e134Smrg/*
12077a84e134Smrg * Function:
12087a84e134Smrg *	_SetField
12097a84e134Smrg *
12107a84e134Smrg * Parameters:
12117a84e134Smrg *	cnew - new and old text fields
12127a84e134Smrg *	old  - ""
12137a84e134Smrg *
12147a84e134Smrg * Description:
12157a84e134Smrg *	Sets the current text field.
12167a84e134Smrg */
12177a84e134Smrgstatic void
12187a84e134Smrg_SetField(Widget cnew, Widget old)
12197a84e134Smrg{
12207a84e134Smrg    Arg args[2];
12217a84e134Smrg    Pixel new_border, old_border, old_bg;
12227a84e134Smrg
12237a84e134Smrg    if (!XtIsSensitive(cnew)) {
12247a84e134Smrg	XBell(XtDisplay(old), 0);	/* Don't set field to an inactive Widget */
12257a84e134Smrg	return;
12267a84e134Smrg    }
12277a84e134Smrg
12287a84e134Smrg    XtSetKeyboardFocus(XtParent(cnew), cnew);
1229421c997bSmrg
12307a84e134Smrg    XtSetArg(args[0], XtNborderColor, &old_border);
12317a84e134Smrg    XtSetArg(args[1], XtNbackground, &old_bg);
12327a84e134Smrg    XtGetValues(cnew, args, 2);
12337a84e134Smrg
12347a84e134Smrg    XtSetArg(args[0], XtNborderColor, &new_border);
12357a84e134Smrg    XtGetValues(old, args, 1);
12367a84e134Smrg
12377a84e134Smrg    if (old_border != old_bg)	/* Colors are already correct, return */
12387a84e134Smrg	return;
12397a84e134Smrg
12407a84e134Smrg    SetResource(old, XtNborderColor, (XtArgVal)old_border);
12417a84e134Smrg    SetResource(cnew, XtNborderColor, (XtArgVal)new_border);
12427a84e134Smrg}
12437a84e134Smrg
12447a84e134Smrg/*
12457a84e134Smrg * Function:
12467a84e134Smrg *	SetResourceByName
12477a84e134Smrg *
12487a84e134Smrg * Parameters:
12497a84e134Smrg *	shell	 - shell widget of the popup
12507a84e134Smrg *	name	 - name of the child
12517a84e134Smrg *	res_name - name of the resource
12527a84e134Smrg *	value	 - value of the resource
12537a84e134Smrg *
12547a84e134Smrg * Description:
12557a84e134Smrg *	  Sets a resource in any of the dialog children given
12567a84e134Smrg *	name of the child and the shell widget of the dialog.
12577a84e134Smrg *
12587a84e134Smrg * Returns:
12595b16253fSmrg *	True if successful
12607a84e134Smrg */
12617a84e134Smrgstatic Bool
12625ec34c4cSmrgSetResourceByName(Widget shell, String name, String res_name, XtArgVal value)
12637a84e134Smrg{
12647a84e134Smrg    Widget temp_widget;
12657a84e134Smrg    char buf[BUFSIZ];
12667a84e134Smrg
1267421c997bSmrg    snprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, name);
12687a84e134Smrg
12697a84e134Smrg    if ((temp_widget = XtNameToWidget(shell, buf)) != NULL) {
12707a84e134Smrg	SetResource(temp_widget, res_name, value);
12717a84e134Smrg	return (True);
12727a84e134Smrg    }
12737a84e134Smrg    return (False);
12747a84e134Smrg}
12757a84e134Smrg
12767a84e134Smrg/*
12777a84e134Smrg * Function:
12787a84e134Smrg *	SetResource
12797a84e134Smrg *
12807a84e134Smrg * Parameters:
12817a84e134Smrg *	w	 - widget
12827a84e134Smrg *	res_name - name of the resource
12837a84e134Smrg *	value	 - value of the resource
12847a84e134Smrg *
12857a84e134Smrg * Description:
12867a84e134Smrg *	Sets a resource in a widget
12877a84e134Smrg */
12887a84e134Smrgstatic void
12895ec34c4cSmrgSetResource(Widget w, String res_name, XtArgVal value)
12907a84e134Smrg{
12917a84e134Smrg    Arg args[1];
1292421c997bSmrg
12937a84e134Smrg    XtSetArg(args[0], res_name, value);
12947a84e134Smrg    XtSetValues( w, args, 1);
12957a84e134Smrg}
12967a84e134Smrg
12977a84e134Smrg/*
12987a84e134Smrg * Function:
12997a84e134Smrg *	GetString{Raw}
13007a84e134Smrg *
13017a84e134Smrg * Parameters:
13027a84e134Smrg *	text - text widget whose string we will get
1303421c997bSmrg *
13047a84e134Smrg * Description:
13057a84e134Smrg *	Gets the value for the string in the popup.
13067a84e134Smrg *
13077a84e134Smrg * Returns:
13087a84e134Smrg *	GetString:	the string as a MB
13097a84e134Smrg *	GetStringRaw:	the exact buffer contents suitable for a search
13107a84e134Smrg */
13117a84e134Smrgstatic String
13127a84e134SmrgGetString(Widget text)
13137a84e134Smrg{
13147a84e134Smrg    String string;
13157a84e134Smrg    Arg args[1];
13167a84e134Smrg
13177a84e134Smrg    XtSetArg(args[0], XtNstring, &string);
13187a84e134Smrg    XtGetValues(text, args, 1);
13197a84e134Smrg
13207a84e134Smrg    return (string);
13217a84e134Smrg}
13227a84e134Smrg
13235ec34c4cSmrgstatic _XtString
13247a84e134SmrgGetStringRaw(Widget tw)
13257a84e134Smrg{
13267a84e134Smrg    TextWidget ctx = (TextWidget)tw;
13277a84e134Smrg    XawTextPosition last;
13287a84e134Smrg
13297a84e134Smrg    last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight,
13307a84e134Smrg			     ctx->text.mult, True);
13317a84e134Smrg    return (_XawTextGetText(ctx, 0, last));
13327a84e134Smrg}
13337a84e134Smrg
13347a84e134Smrg/*
13357a84e134Smrg * Function:
13367a84e134Smrg *	CenterWidgetOnPoint
13377a84e134Smrg *
13387a84e134Smrg * Parameters:
13397a84e134Smrg *	w     - shell widget
13407a84e134Smrg *		 event - event containing the location of the point
13417a84e134Smrg *
13427a84e134Smrg * Description:
13437a84e134Smrg *	Centers a shell widget on a point relative to the root window.
13447a84e134Smrg *
13457a84e134Smrg * Note:
13467a84e134Smrg *	The widget is not allowed to go off the screen
13477a84e134Smrg */
13487a84e134Smrgstatic void
13497a84e134SmrgCenterWidgetOnPoint(Widget w, XEvent *event)
13507a84e134Smrg{
13517a84e134Smrg    Arg args[3];
13527a84e134Smrg    Cardinal num_args;
13537a84e134Smrg    Dimension width, height, b_width;
13547a84e134Smrg    Position x, y, max_x, max_y;
1355421c997bSmrg
13567a84e134Smrg    if (event != NULL) {
13577a84e134Smrg	switch (event->type) {
13587a84e134Smrg	    case ButtonPress:
13597a84e134Smrg	    case ButtonRelease:
13605ec34c4cSmrg		x = (Position)event->xbutton.x_root;
13615ec34c4cSmrg		y = (Position)event->xbutton.y_root;
13627a84e134Smrg		break;
13637a84e134Smrg	    case KeyPress:
13647a84e134Smrg	    case KeyRelease:
13655ec34c4cSmrg		x = (Position)event->xkey.x_root;
13665ec34c4cSmrg		y = (Position)event->xkey.y_root;
13677a84e134Smrg		break;
13687a84e134Smrg	    default:
13697a84e134Smrg		return;
13707a84e134Smrg	}
13717a84e134Smrg    }
13727a84e134Smrg    else
13737a84e134Smrg	return;
13747a84e134Smrg
13757a84e134Smrg    num_args = 0;
13767a84e134Smrg    XtSetArg(args[num_args], XtNwidth, &width); num_args++;
13777a84e134Smrg    XtSetArg(args[num_args], XtNheight, &height); num_args++;
13787a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
13797a84e134Smrg    XtGetValues(w, args, num_args);
13807a84e134Smrg
13815ec34c4cSmrg    width = (Dimension)(width + (b_width << 1));
13825ec34c4cSmrg    height = (Dimension)(height + (b_width << 1));
13837a84e134Smrg
13845ec34c4cSmrg    x = (Position)(x - (width >> 1));
13857a84e134Smrg    if (x < 0)
13867a84e134Smrg	x = 0;
13877a84e134Smrg    if (x > (max_x = (Position)(XtScreen(w)->width - width)))
13887a84e134Smrg	x = max_x;
13897a84e134Smrg
13905ec34c4cSmrg    y = (Position)(y - (height >> 1));
13917a84e134Smrg    if (y < 0)
13927a84e134Smrg	y = 0;
13937a84e134Smrg    if (y > (max_y = (Position)(XtScreen(w)->height - height)))
13947a84e134Smrg	y = max_y;
1395421c997bSmrg
13967a84e134Smrg    num_args = 0;
13977a84e134Smrg    XtSetArg(args[num_args], XtNx, x); num_args++;
13987a84e134Smrg    XtSetArg(args[num_args], XtNy, y); num_args++;
13997a84e134Smrg    XtSetValues(w, args, num_args);
14007a84e134Smrg}
14017a84e134Smrg
14027a84e134Smrg/*
14037a84e134Smrg * Function:
14047a84e134Smrg *	CreateDialog
14057a84e134Smrg *
14067a84e134Smrg * Parameters:
14077a84e134Smrg *	parent - parent of the dialog - the main text widget
14087a84e134Smrg *	ptr    - initial_string for the dialog
14097a84e134Smrg *	name   - name of the dialog
14107a84e134Smrg *	func   - function to create the children of the dialog
14117a84e134Smrg *
14127a84e134Smrg * Returns:
14137a84e134Smrg *	Popup shell of the dialog
14147a84e134Smrg *
14157a84e134Smrg * Note:
14167a84e134Smrg *	The function argument is passed the following arguments:
14177a84e134Smrg *	form   - from widget that is the dialog
14187a84e134Smrg *	ptr    - initial string for the dialog's text widget
14197a84e134Smrg *	parent - parent of the dialog - the main text widget
14207a84e134Smrg */
14217a84e134Smrgstatic Widget
14227a84e134SmrgCreateDialog(Widget parent, String ptr, String name, AddFunc func)
14237a84e134Smrg{
14247a84e134Smrg    Widget popup, form;
14257a84e134Smrg    Arg args[5];
14267a84e134Smrg    Cardinal num_args;
14277a84e134Smrg
14287a84e134Smrg    num_args = 0;
14297a84e134Smrg    XtSetArg(args[num_args], XtNiconName, name);		num_args++;
14307a84e134Smrg    XtSetArg(args[num_args], XtNgeometry, NULL);		num_args++;
14317a84e134Smrg    XtSetArg(args[num_args], XtNallowShellResize, True);	num_args++;
14327a84e134Smrg    XtSetArg(args[num_args], XtNtransientFor, GetShell(parent));num_args++;
1433421c997bSmrg    popup = XtCreatePopupShell(name, transientShellWidgetClass,
14347a84e134Smrg			       parent, args, num_args);
14357a84e134Smrg
14367a84e134Smrg    form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup, NULL, 0);
14377a84e134Smrg    XtManageChild (form);
14387a84e134Smrg
14397a84e134Smrg    (*func)(form, ptr, parent);
14407a84e134Smrg
14417a84e134Smrg    return (popup);
14427a84e134Smrg}
14437a84e134Smrg
14447a84e134Smrg/*
14457a84e134Smrg * Function
14467a84e134Smrg *	GetShell
14477a84e134Smrg *	nearest shell widget.
14487a84e134Smrg *
14497a84e134Smrg * Parameters:
14507a84e134Smrg *	w - widget whose parent shell should be returned
14517a84e134Smrg *
14527a84e134Smrg * Returns:
14537a84e134Smrg *	  The shell widget among the ancestors of w that is the
1454421c997bSmrg *	fewest levels up in the widget hierarchy.
14557a84e134Smrg *
14567a84e134Smrg * Description:
14577a84e134Smrg *	Walks up the widget hierarchy to find the topmost shell widget.
14587a84e134Smrg */
14597a84e134Smrgstatic Widget
14607a84e134SmrgGetShell(Widget w)
14617a84e134Smrg{
14627a84e134Smrg    while (w != NULL && !XtIsShell(w))
14637a84e134Smrg	w = XtParent(w);
1464421c997bSmrg
14657a84e134Smrg    return (w);
14667a84e134Smrg}
14677a84e134Smrg
14687a84e134Smrgstatic Bool
14697a84e134SmrgInParams(String str, String *p, unsigned int n)
14707a84e134Smrg{
14717a84e134Smrg    unsigned int i;
14727a84e134Smrg
14737a84e134Smrg    for (i = 0; i < n; p++, i++)
14747a84e134Smrg	if (!XmuCompareISOLatin1(*p, str))
14757a84e134Smrg	    return (True);
14767a84e134Smrg    return (False);
14777a84e134Smrg}
14787a84e134Smrg
14795ec34c4cSmrgstatic const char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW";
14807a84e134Smrg
14817a84e134Smrgstatic void
14827a84e134SmrgWMProtocols(Widget w, XEvent *event, String *params, Cardinal *num_params)
14837a84e134Smrg{
14847a84e134Smrg    Atom wm_delete_window;
14857a84e134Smrg    Atom wm_protocols;
14867a84e134Smrg
14877a84e134Smrg    wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True);
14887a84e134Smrg    wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True);
14897a84e134Smrg
14907a84e134Smrg    /* Respond to a recognized WM protocol request if
14917a84e134Smrg     * event type is ClientMessage and no parameters are passed, or
14927a84e134Smrg     * event type is ClientMessage and event data is matched to parameters, or
14937a84e134Smrg     * event type isn't ClientMessage and parameters make a request
14947a84e134Smrg     */
14957a84e134Smrg#define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params)
14967a84e134Smrg
14977a84e134Smrg    if ((event->type == ClientMessage
14987a84e134Smrg	 && event->xclient.message_type == wm_protocols
14995ec34c4cSmrg	 && (Atom)event->xclient.data.l[0] == wm_delete_window
15007a84e134Smrg	 && (*num_params == 0 || DO_DELETE_WINDOW))
15017a84e134Smrg	|| (event->type != ClientMessage && DO_DELETE_WINDOW)) {
15027a84e134Smrg#undef DO_DELETE_WINDOW
15037a84e134Smrg	Widget cancel;
15047a84e134Smrg	char descendant[DISMISS_NAME_LEN + 2];
15057a84e134Smrg
1506421c997bSmrg	snprintf(descendant, sizeof(descendant), "*%s", DISMISS_NAME);
15077a84e134Smrg	cancel = XtNameToWidget(w, descendant);
15087a84e134Smrg	if (cancel)
15097a84e134Smrg	    XtCallCallbacks(cancel, XtNcallback, NULL);
15107a84e134Smrg    }
15117a84e134Smrg}
15127a84e134Smrg
15137a84e134Smrgstatic void
15147a84e134SmrgSetWMProtocolTranslations(Widget w)
15157a84e134Smrg{
15167a84e134Smrg    static XtTranslations compiled_table;
15177a84e134Smrg    static XtAppContext *app_context_list;
15187a84e134Smrg    static Cardinal list_size;
15197a84e134Smrg
15207a84e134Smrg    unsigned int i;
15217a84e134Smrg    XtAppContext app_context;
15227a84e134Smrg    Atom wm_delete_window;
15237a84e134Smrg
15247a84e134Smrg    app_context = XtWidgetToApplicationContext(w);
15257a84e134Smrg
15267a84e134Smrg    /* parse translation table once */
15277a84e134Smrg    if (!compiled_table)
15287a84e134Smrg	compiled_table =
15297a84e134Smrg	    XtParseTranslationTable("<Message>WM_PROTOCOLS:XawWMProtocols()\n");
15307a84e134Smrg
15317a84e134Smrg    /* add actions once per application context */
15327a84e134Smrg    for (i = 0; i < list_size && app_context_list[i] != app_context; i++)
15337a84e134Smrg	;
15347a84e134Smrg    if (i == list_size) {
15357a84e134Smrg	XtActionsRec actions[1];
15367a84e134Smrg
15377a84e134Smrg	actions[0].string = "XawWMProtocols";
15387a84e134Smrg	actions[0].proc = WMProtocols;
15397a84e134Smrg	list_size++;
15407a84e134Smrg	app_context_list = (XtAppContext *)XtRealloc
15415ec34c4cSmrg	    ((char *)app_context_list, (Cardinal)(list_size * sizeof(XtAppContext)));
15427a84e134Smrg	XtAppAddActions(app_context, actions, 1);
15437a84e134Smrg	app_context_list[i] = app_context;
15447a84e134Smrg    }
15457a84e134Smrg
15467a84e134Smrg    /* establish communication between the window manager and each shell */
15477a84e134Smrg    XtAugmentTranslations(w, compiled_table);
15487a84e134Smrg    wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False);
15497a84e134Smrg    (void)XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1);
15507a84e134Smrg}
1551