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>