chuck@Morgan.COM (Chuck Ocheret) (11/08/89)
All I want to do is have a Text widget which inverts upper/lower case keystrokes. That is, when you type a lower case 'm', an upper case 'M' should appear in the widget and vice versa. Other keys should be unaffected. Section 10.5, "KeyCode-to-KeySym Conversions" of the X Intrinsics manual (X11, Release 3, Oct. 1988) specifies how to provide your own key translator with XtSetKeyTranslator(). After lifting code for the default key translator, the following translator was produced: void myTranslateKey(dpy, keycode, modifiers, modifiers_return, keysym_return) Display *dpy; KeyCode keycode; Modifiers modifiers; Modifiers *modifiers_return; KeySym *keysym_return; { KeySym ks; XtPerDisplay perDisplay; perDisplay = _XtGetPerDisplay(dpy); *modifiers_return = 0; if ((modifiers & StandardMask) == 0) ks =_XtKeyCodeToKeySym(dpy,perDisplay,keycode,0); else if ((modifiers & (ShiftMask | LockMask)) != 0) ks =_XtKeyCodeToKeySym(dpy,perDisplay,keycode,1); else ks = NoSymbol; if (ks >= XK_a && ks <= XK_z) ks = ks-0x20; else if (ks >= XK_A && ks <= XK_Z) ks = ks+0x20; *keysym_return = ks; } Dbx shows that this function does indeed get called and it does the translation. However, the Text widget still shows untranslated keystrokes. What am I doing wrong? Is there some other mechanism I should be using? Do I really have to provide a big table for the translation manager? -- +------------------+ Chuck Ocheret, Sr. Staff Engineer +------------------+ | chuck@morgan.com | Morgan Stanley & Co., Inc. | (212)703-4474 | | Duty now ... |19th Floor, 1251 Avenue of the Americas| for the future. | +------------------+ New York, N.Y. 10020 USA +------------------+
swick@ATHENA.MIT.EDU (Ralph R. Swick) (11/08/89)
> Dbx shows that this function does indeed get called and it does the > translation. However, the Text widget still shows untranslated > keystrokes. What am I doing wrong? Probably nothing. I can't speak authoritatively for Motif, but I suspect that they're doing the same thing that the R3 Xaw Text widget does; i.e. re-interpreting the XEvent in the action proc using straight Xlib functions. In R3 there was no support for a client of Xt discovering the resulting KeySym that the Xt translation manager produced when it called an action proc. This addition is a part of the R4 proposed changes.
ries@venice.SEDD.TRW.COM (Marc Ries) (11/09/89)
In article <CHUCK.89Nov7121348@s6.Morgan.COM> chuck@Morgan.COM (Chuck Ocheret) writes: >All I want to do is have a Text widget which inverts upper/lower >case keystrokes. That is, when you type a lower case 'm', an upper >case 'M' should appear in the widget and vice versa. Other keys >should be unaffected. While the following example (highlight the text, then "U" or "L" keystroke will translate the highlighted text to upper or lower) does not solve your problem, it >might< give you something to go on [I haven't run this through a compiler so there may be some typos]: /* * RESOURCES * toplevel*text.editMode: MULTI_LINE_EDIT * toplevel*text.rows: 20 * toplevel*text.columns: 70 * toplevel*text.insertionPointVisible: TRUE * toplevel*text.autoShowCursorPosition: TRUE */ #include <Xm/MainW.h> #include <Xm/Text.h> void myTextAction (); XtActionsRex myTextActions[] = {"changeCase", (XtActionProc) myTextAction) }; String myTransUpper = "Ctrl<Key>U: changeCase(U)"; String myTransLower = "Ctrl<Key>L: changeCase(L)"; void main(argc, argv) unsigned int argc; char **argv; { Widget toplevel, main, text; Arg myArgs[10]; int i; toplevel = XtInitialize (argv[0], "toplevel", NULL, 0, &argc, argv); main = XmCreateMainWindow(toplevel, "main", (Arglist)NULL, (Cardinal)0); XtManageChild(main); text = XmCreateScrolledText(main, "text", (Arglist)NULL, (Cardinal)0); XtManageChild(text); XtAddActions(myNewActions, XtNumber (myNewActions); XtOverrideTranlations(text, XtParseTranslationTable(myTransUpper)); XtOverrideTranlations(text, XtParseTranslationTable(myTransLower)); XtRealizeWidget(toplevel); XtMainLoop(); } /ARGSUSED*/ void myTextAction(w, ev, params) Widget w; XEvent *ev; String *params; { int i=0; char *myStr = XmTextGetSelection(w); XmTextPosition tpos; Arg al[2]; int ac; if(myStr != NULL) { DeletePrimarySelection(w); switch(params[0][0]) { case 'L': i = 0; while(myStr[i] != '\0' { myStr[i] = tolower(myStr[i]); i++ } break; case 'U': i = 0; while(myStr[i] != '\0' { myStr[i] = toupper(myStr[i]); i++ } default: break; } ac = 0; XtSetArg(al[ac], XmNcursorPosition, &tpos); a++; XtGetValues(w, al, ac); XmTextReplace(w, tpos, tpos, myStr); XtFree(myStr); } } void DeletePrimarySelection(w) Widget w; { XClientMessageEvent cm; cm.type = ClientMessage; cm.display = XtDisplay(w); cm.message_type = XmInternAtom(XtDisplay(w), "KILL_SELECTION", FALSE); cm.window = XtWindow(w); cm.format = 32; cm.data[0] = XA_PRIMARY; XSendEvent(XtDisplay(w), cm.window, TRUE, NoEventMask, &cm); } -- Marc Ries ries@venice.sedd.trw.com (ARPA) somewhere!trwind!venice!ries (UUCP) #include <std.disclaimer>