/* ** xgc ** ** text.c ** ** How to make a text widget that returns a string when the cursor ** leaves its window. */ #include #include #include #include #include #include #include #include "xgc.h" static void WriteText(Widget, XEvent *, String *, Cardinal *); /* the strings which are displayed on the screen, edited, and sent to interpret() */ static char textstrings[NUMTEXTWIDGETS][80]; static char oldtextstrings[NUMTEXTWIDGETS][80]; static const char *defaultstrings[NUMTEXTWIDGETS] = {"0","6x10","0","1"}; /* The labels displayed next to them */ static const char *labels[NUMTEXTWIDGETS] = {"Line Width","Font","Foreground", "Background"}; /* the first half of what gets sent to interpret() */ static const char *names[NUMTEXTWIDGETS] = {"linewidth ","font ","foreground ", "background "}; /* create_text_choice(w,type,length,width) ** --------------------------------------- ** Inside w (a form), creates an editable text widget of width width. The ** user can enter a string of up to length characters. type is one of ** the constants defined in xgc.h; it decides things like the label, ** what string will be displayed and edited, etc. When the pointer leaves ** the widget, the widget does the appropriate thing with the text ** inside it; the user doesn't have to press an "enter" button or anything. ** Returns the text widget which the user will edit. */ Widget create_text_choice(Widget w, int type, int length, int width) { char translationtable[600]; /* for adding the new action (calling WriteText() when the pointer leaves) */ static XtActionsRec actionTable[] = { /* likewise */ {"WriteText", WriteText}, {"Nothing", NULL} }; static Arg labelargs[] = { {XtNborderWidth, (XtArgVal) 0}, {XtNjustify, (XtArgVal) XtJustifyRight} }; static Arg textargs[] = { {XtNeditType, (XtArgVal) XawtextEdit}, {XtNstring, (XtArgVal) NULL}, {XtNlength, (XtArgVal) NULL}, {XtNhorizDistance, (XtArgVal) 10}, {XtNfromHoriz, (XtArgVal) NULL}, {XtNinsertPosition, (XtArgVal) NULL}, {XtNuseStringInPlace, (XtArgVal) True} }; static Widget text; /* the text widget */ static Widget label; /* the label widget */ /* Disable keys which would cause the cursor to go off the single ** line that we want to display. If the pointer leaves the window, ** update the GC accordingly. The integer passed to WriteText is ** so it knows what type of widget was just updated. */ snprintf(translationtable,sizeof translationtable, ": WriteText(%d)\n\ : set-keyboard-focus() select-start()\n\ CtrlJ: Nothing()\n\ CtrlM: Nothing()\n\ Linefeed: Nothing()\n\ Return: Nothing()\n\ CtrlO: Nothing()\n\ MetaI: Nothing()\n\ CtrlN: Nothing()\n\ CtrlP: Nothing()\n\ CtrlZ: Nothing()\n\ MetaZ: Nothing()\n\ CtrlV: Nothing()\n\ MetaV: Nothing()",type); /* label uses type to find out what its title is */ label = XtCreateManagedWidget(labels[type],labelWidgetClass,w, labelargs,XtNumber(labelargs)); /* text uses type to find out what its string is */ switch (type) { case TForeground: snprintf(textstrings[type],sizeof textstrings[type], "%d",(int) X.gcv.foreground); snprintf(oldtextstrings[type],sizeof oldtextstrings[type], "%d",(int) X.gcv.foreground); break; case TBackground: snprintf(textstrings[type],sizeof textstrings[type], "%d",(int) X.gcv.background); snprintf(oldtextstrings[type],sizeof oldtextstrings[type], "%d",(int) X.gcv.background); break; default: strcpy(textstrings[type],defaultstrings[type]); strcpy(oldtextstrings[type],defaultstrings[type]); } textargs[1].value = (XtArgVal) textstrings[type]; textargs[2].value = (XtArgVal) length; textargs[4].value = (XtArgVal) label; textargs[5].value = (XtArgVal) strlen(textstrings[type]); text = XtCreateManagedWidget("text", asciiTextWidgetClass,w, textargs,XtNumber(textargs)); /* Register the actions and translations */ XtAppAddActions(appcontext,actionTable,XtNumber(actionTable)); XtOverrideTranslations(text,XtParseTranslationTable(translationtable)); return(text); } /* WriteText(w,event,params,num_params) ** ------------------------------------ ** Makes an appropriate string and sends it off to interpret(). ** It's an ActionProc, thus the funny arguments. */ /*ARGSUSED*/ static void WriteText(Widget w, XEvent *event, String *params, Cardinal *num_params) { char mbuf[80]; int type; /* which string # to send */ type = atoi(params[0]); if (type < 0 || type >= NUMTEXTWIDGETS) { fprintf(stderr, "Invalid value %s in WriteText()\n", params[0]); return; } if (strcmp(textstrings[type],oldtextstrings[type])) { strcpy(oldtextstrings[type],textstrings[type]); snprintf(mbuf,sizeof mbuf,"%s%s\n", names[type], /* the right first half */ textstrings[type]); /* the right second half */ interpret(mbuf); /* send it off */ } } /* change_text(w,type,newtext) ** ------------------------ ** Changes the text in the text widget w of type type to newtext. */ void change_text(Widget w, String newtext) { XawTextBlock text; /* the new text */ XawTextPosition first, last; /* boundaries of the old text */ String oldtext; /* the old text */ static Arg textargs[] = { {XtNstring, (XtArgVal) 0} }; /* Initialize the XawTextBlock. */ if (!newtext) newtext = ""; text.firstPos = 0; text.length = strlen(newtext); text.ptr = newtext; text.format = FMT8BIT; /* Find the old text, so we can get its length, so we know how ** much of it to update. */ textargs[0].value = (XtArgVal) &oldtext; XtGetValues(w,textargs,XtNumber(textargs)); first = XawTextTopPosition(w); if (!oldtext) oldtext = ""; last = (XawTextPosition) strlen(oldtext)+1; /* Replace it with the new text. */ XawTextReplace(w, first, last, &text); }