/* ** Temporary event handlers for keys pressed after the mark or goto-mark ** commands, If the key is valid, grab the key event and call the action ** procedure to mark (or go to) the selection, otherwise, remove the handler ** and give up. */ static void processMarkEvent(Widget w, XtPointer clientData, XEvent *event, Boolean *continueDispatch, char *action, int extend) { XKeyEvent *e = (XKeyEvent *)event; WindowInfo *window = WidgetToWindow(w); Modifiers modifiers; KeySym keysym; char *params[2], string[2]; XtTranslateKeycode(TheDisplay, e->keycode, e->state, &modifiers, &keysym); if ((keysym >= 'A' && keysym <= 'Z') || (keysym >= 'a' && keysym <= 'z')) { string[0] = toupper(keysym); string[1] = '\0'; params[0] = string; params[1] = "extend"; XtCallActionProc(window->lastFocus, action, event, params, extend ? 2 : 1); *continueDispatch = False; } XtRemoveEventHandler(w, KeyPressMask, False, markKeyCB, window); XtRemoveEventHandler(w, KeyPressMask, False, gotoMarkKeyCB, window); XtRemoveEventHandler(w, KeyPressMask, False, gotoMarkExtendKeyCB, window); XtRemoveTimeOut(window->markTimeoutID); }
KeySym XtGetActionKeysym( XEvent *event, Modifiers *modifiers_return) { TMKeyContext tm_context; Modifiers modifiers; KeySym keysym, retval; LOCK_PROCESS; tm_context= _XtGetPerDisplay(event->xany.display)->tm_context; if (event->xany.type != KeyPress && event->xany.type != KeyRelease) { UNLOCK_PROCESS; return NoSymbol; } if (tm_context != NULL && event == tm_context->event && event->xany.serial == tm_context->serial ) { if (modifiers_return != NULL) *modifiers_return = tm_context->modifiers; retval = tm_context->keysym; UNLOCK_PROCESS; return retval; } XtTranslateKeycode( event->xany.display, (KeyCode)event->xkey.keycode, event->xkey.state, &modifiers, &keysym ); if (modifiers_return != NULL) *modifiers_return = event->xkey.state & modifiers; UNLOCK_PROCESS; return keysym; }
/* * Event handler used by both TextField/TextArea to correctly process * cut/copy/paste keys such that interaction with our own * clipboard mechanism will work properly. * * client_data is MTextFieldPeer instance */ void Text_handlePaste(Widget w, XtPointer client_data, XEvent * event, Boolean * cont) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); KeySym keysym; Modifiers mods; /* Any event handlers which take peer instance pointers as * client_data should check to ensure the widget has not been * marked as destroyed as a result of a dispose() call on the peer * (which can result in the peer instance pointer already haven * been gc'd by the time this event is processed) */ if (event->type != KeyPress || w->core.being_destroyed) { return; } XtTranslateKeycode(event->xkey.display, (KeyCode) event->xkey.keycode, event->xkey.state, &mods, &keysym); /* Should be a temporary fix for 4052132 if a cleaner fix is found later */ if ((event->xkey.state & ControlMask) && (keysym == 'v' || keysym == 'V')) keysym = osfXK_Paste; if ((event->xkey.state & ShiftMask) && (keysym == osfXK_Insert)) keysym = osfXK_Paste; switch (keysym) { case osfXK_Paste: /* If we own the selection, then paste the data directly */ if (awtJNI_isSelectionOwner(env, "CLIPBOARD")) { JNU_CallMethodByName(env, NULL, (jobject) client_data, "pasteFromClipboard", "()V"); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } *cont = FALSE; } break; case osfXK_Cut: case osfXK_Copy: /* For some reason if we own the selection, our loseSelection * callback is not automatically called on cut/paste from * text widgets. */ if (awtJNI_isSelectionOwner(env, "CLIPBOARD")) { awtJNI_notifySelectionLost(env, "CLIPBOARD"); } break; default: break; } }
void kb_event(Display *display, XEvent *event) { KeySym keysym; Modifiers dummy; u8 key_index; int modifiers; if ((event->type != KeyPress) && (event->type != KeyRelease)) { return; } modifiers = event->xkey.state & ShiftMask; modifiers |= (event->xkey.state & ControlMask) >> 1; XtTranslateKeycode(display, event->xkey.keycode, 0, &dummy, &keysym); key_index = 0; if ((keysym & 0xff00) == 0x0000) { /* Latin1 charset */ if (!(keysym < 0x80)) { return; } key_index = keysym_translate[keysym & 0xff]; } if ((keysym & 0xff00) == 0xff00) { /* miscellaneous keys */ if (keysym == XK_Escape) { key_index = 14; } else if (keysym == XK_Return) { key_index = 26; } else if ((keysym == XK_Left) || (keysym == XK_KP_Left)) { key_index = 39; } else if ((keysym == XK_Right) || (keysym == XK_KP_Right)) { key_index = 40; } } if (key_index) { /* * NOTE: We can get away with calling both handler functions because * they both operate on static data. We really should be using a * registered callback, but that would require more work than I feel * like doing at the present time. */ if (event->type == KeyPress) { apple2_press_keyboard(apple2, decode_key[key_index][modifiers]); } sc3k_keyboard_event(key_index | ((event->type != KeyPress) << 7)); msx_keyboard_event(key_index | ((event->type != KeyPress) << 7)); } }
static void GrabAllCorrectKeys( Widget widget, TMTypeMatch typeMatch, TMModifierMatch modMatch, GrabActionRec* grabP) { Display *dpy = XtDisplay(widget); KeyCode *keycodes, *keycodeP; Cardinal keycount; Modifiers careOn = 0; Modifiers careMask = 0; if (modMatch->lateModifiers) { Boolean resolved; resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers, &careOn, &careMask); if (!resolved) return; } careOn |= modMatch->modifiers; careMask |= modMatch->modifierMask; XtKeysymToKeycodeList( dpy, (KeySym)typeMatch->eventCode, &keycodes, &keycount ); if (keycount == 0) return; for (keycodeP = keycodes; keycount--; keycodeP++) { if (modMatch->standard) { /* find standard modifiers that produce this keysym */ KeySym keysym; int std_mods, least_mod; Modifiers modifiers_return; XtTranslateKeycode( dpy, *keycodeP, (Modifiers)0, &modifiers_return, &keysym ); if (careOn & modifiers_return) return; if (keysym == typeMatch->eventCode) { XtGrabKey(widget, *keycodeP, careOn, grabP->owner_events, grabP->pointer_mode, grabP->keyboard_mode ); /* continue; */ /* grab all modifier combinations */ } least_mod = modifiers_return & (~modifiers_return + 1); for (std_mods = modifiers_return; std_mods >= least_mod; std_mods--) { Modifiers dummy; /* check all useful combinations of modifier bits */ if (modifiers_return & std_mods && !(~modifiers_return & std_mods)) { XtTranslateKeycode( dpy, *keycodeP, (Modifiers)std_mods, &dummy, &keysym ); if (keysym == typeMatch->eventCode) { XtGrabKey(widget, *keycodeP, careOn | (Modifiers) std_mods, grabP->owner_events, grabP->pointer_mode, grabP->keyboard_mode ); /* break; */ /* grab all modifier combinations */ } } } } else /* !event->standard */ { XtGrabKey(widget, *keycodeP, careOn, grabP->owner_events, grabP->pointer_mode, grabP->keyboard_mode ); } } XtFree((char *)keycodes); }
/* * Event handler used by both TextField/TextArea to correctly process * cut/copy/paste keys such that interaction with our own clipboard mechanism * will work properly. */ void Text_handlePaste(Widget w, XtPointer client_data, XEvent * event, Boolean * cont) { KeySym keysym; long mods; JNIEnv *env; jobject this = (jobject) client_data; if ((*JVM)->AttachCurrentThread(JVM, (void **) &env, NULL) != 0) return; /* * Any event handlers which take peer instance pointers as * client_data should check to ensure the widget has not been marked * as destroyed as a result of a dispose() call on the peer (which * can result in the peer instance pointer already haven been gc'd by * the time this event is processed) */ if (w->core.being_destroyed) return; if (event->type == KeyPress) { XtTranslateKeycode(event->xkey.display, (KeyCode) event->xkey.keycode, event->xkey.state, (Modifiers *) & mods, &keysym); /* * allow Ctrl-V and Shift-Insert to function as Paste when VM * has clipboard, otherwise the applicatin hangs *//* Bug#unknown */ if ((event->xkey.state & ControlMask) && (keysym == 'v' || keysym == 'V')) { /* Bug#unknown */ keysym = osfXK_Paste; /* Bug#unknown */ } /* Bug#unknown */ if ((event->xkey.state & ShiftMask) && (keysym == (osfXK_Insert & 0xffff))) { /* Bug#unknown */ keysym = osfXK_Paste; /* Bug#unknown */ } /* Bug#unknown */ switch (keysym) { case osfXK_Paste: /* * If we own the selection, then paste the data * directly */ if (awt_isSelectionOwner(env, "CLIPBOARD")) { (*env)->CallVoidMethod(env, this, MCachedIDs.MTextPeer_pasteFromClipboardMID); *cont = FALSE; } break; case osfXK_Cut: case osfXK_Copy: /* * For some reason if we own the selection, our * loseSelection callback is not automatically called * on cut/paste from text widgets. */ if (awt_isSelectionOwner(env, "CLIPBOARD")) { awt_notifySelectionLost(env, "CLIPBOARD"); } break; } } }
// // Input from motif text-widget with recall // Returns 1 if return i pressed, else 0. // int mrm_TextInput( Widget w, XEvent *event, char *recall, int line_size, int recall_size, int *current_recall_line) { KeySym keysym; Modifiers mod; int pos; char *text; char newtext[160]; int i; XmTextPosition left, right; char *s, *t; text = XmTextGetString( w); XtTranslateKeycode( flow_Display(w), event->xkey.keycode, event->xkey.state, &mod, &keysym); keysym &= 0xFFFF; switch ( keysym) { case XK_Return: case XK_Linefeed: // Insert in recall buffer if ( strcmp( text, "") != 0) { for ( i = recall_size - 2; i >= 0; i--) strcpy( recall + (i+1) * line_size, recall + i * line_size); strncpy( recall, text, line_size); recall[line_size-1] = 0; } *current_recall_line = 0; return 1; case XK_Up: (*current_recall_line)++; if ( *current_recall_line > recall_size - 1) *current_recall_line = recall_size - 1; XmTextSetString( w, recall + (*current_recall_line - 1) * line_size); XmTextSetCursorPosition( w, strlen(recall + (*current_recall_line - 1) * line_size)); break; case XK_Down: if ( *current_recall_line == 0) XmTextSetString( w, ""); else if ( *current_recall_line == 1) { XmTextSetString( w, ""); (*current_recall_line)--; } else { (*current_recall_line)--; XmTextSetString( w, recall + (*current_recall_line - 1) * line_size); XmTextSetCursorPosition( w, strlen(recall + (*current_recall_line - 1) * line_size)); } break; case XK_Left: XmTextClearSelection( w, CurrentTime); pos = XmTextGetCursorPosition( w); if ( pos == 0) break; pos--; XmTextSetCursorPosition( w, pos); break; case XK_Right: XmTextClearSelection( w, CurrentTime); pos = XmTextGetCursorPosition( w); if ( pos >= line_size - 1) break; pos++; if ( pos > strlen(text)) break; XmTextSetCursorPosition( w, pos); break; case XK_BackSpace: case 65535: if ( XmTextGetSelectionPosition( w, &left, &right)) { for ( s = text + left, t = text + right; *t; s++,t++) *s = *t; *s = 0; XmTextSetString( w, text); XmTextSetCursorPosition( w, left); } else { pos = XmTextGetCursorPosition( w); if ( pos == 0) break; if ( pos == 1) strcpy( newtext, ""); else strncpy( newtext, text, pos-1); newtext[pos-1] = 0; strncat( newtext, &text[pos], sizeof( newtext)); XmTextSetString( w, newtext); XmTextSetCursorPosition( w, pos-1); } break; default: if ( event->xkey.state & ControlMask) return 0; if ( keysym > 256) return 0; if ( XmTextGetSelectionPosition( w, &left, &right)) { for ( s = text + left, t = text + right; *t; s++,t++) *s = *t; *s = 0; XmTextSetCursorPosition( w, left); } pos = XmTextGetCursorPosition( w); if ( pos >= line_size - 1) break; if ( pos == 0) strcpy( newtext, ""); else strncpy( newtext, text, pos); newtext[pos] = keysym; newtext[pos+1] = 0; strncat( newtext, &text[pos], sizeof( newtext)); XmTextSetString( w, newtext); XmTextSetCursorPosition( w, pos+1); } return 0; }
static void Keyaction(Widget w, XEvent *e, String *p, Cardinal *np) { static unsigned char compose[5]; static int composing = -2; int kind = Kraw; int c, len, minmod; KeySym k, mk; Charfunc f; Modifiers md; char buf[100] = {0}; c = 0; len = 0; /* Translate the keycode into a key symbol. */ if(e->xany.type != KeyPress) return; XkbTranslateKeyCode(xkb, (KeyCode)e->xkey.keycode, e->xkey.state, &md, &k); XkbTranslateKeySym(e->xany.display, &k, e->xkey.state, buf, sizeof(buf) - 1, &len); /* Check to see if it's a specially-handled key first. */ for (Keymapping *m = keymappings; m; m = m->next){ KeySym u = NoSymbol; KeySym l = NoSymbol; XConvertCase(k, &l, &u); /* Note that magic bit manipulation here - we want to check that the * modifiers that are specified for the binding are all pressed, but * we allow other modifiers to be as well. This is because when NumLock * is on, it's always added to the modifier mask. */ if (l == m->s || m->s == XK_VoidSymbol){ if (m->m == 0 || (m->m & ~e->xkey.state) == 0){ switch (m->c){ case Cnone: return; case Cdefault: continue; default: f = ((GwinWidget)w)->gwin.gotchar; if (f) (*f)(m->c, m->k, Tcurrent, 0, 0, m->a); return; } } } } /* * The following song and dance is so we can have our chosen * modifier key behave like a compose key, i.e, press and release * and then type the compose sequence, like Plan 9. We have * to find out which key is the compose key first though. */ if (IsModifierKey(k) && ((GwinWidget)w)->gwin.compose && composing == -2 && modmap) { minmod = (((GwinWidget)w)->gwin.compose+2)*keypermod; for (c = minmod; c < minmod+keypermod; c++) { XtTranslateKeycode(e->xany.display, modmap->modifiermap[c], e->xkey.state, &md, &mk); if (k == mk) { composing = -1; break; } } return; } /* Handle Multi_key separately, since it isn't a modifier */ if(k == XK_Multi_key) { composing = -1; return; } if(k == NoSymbol || k > 0xff00) return; /* Check to see if we are in a composition sequence */ if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask) && composing == -2) composing = -1; if (composing > -2) { compose[++composing] = k; if ((*compose == 'X') && (composing > 0)) { if ((k < '0') || (k > 'f') || ((k > '9') && (k < 'a'))) { STUFFCOMPOSE(); c = (uint16_t)k; composing = -2; } else if (composing == 4) { c = unicode(compose); if (c == -1) { STUFFCOMPOSE(); c = (uint16_t)compose[4]; } composing = -2; } } else if (composing == 1) { c = (int)latin1(compose); if (c == -1) { STUFFCOMPOSE(); c = (uint16_t)compose[1]; } composing = -2; } } else { if (composing >= 0) { composing++; STUFFCOMPOSE(); } c = keysymtoshort(k); composing = -2; } if (composing >= -1) return; f = ((GwinWidget)w)->gwin.gotchar; if(f) (*f)(c, kind, Tcurrent, 0, 0, NULL); }
/* ** Button1 press: evaluate at curpos ** Button2 press: clear marks. start mark at curpos. ** Button2 motion: clear old stop mark. stop mark at curpos ** Button2 release: same as motion. */ static void video_event_handler(Widget w, XtPointer clientData, XEvent *event, Boolean *b) { PLOT *plot = (PLOT *)clientData; XButtonEvent *butevent; XMotionEvent *motevent; XKeyEvent *keyevent; char *keybuf; KeySym key_sym; Modifiers mod_return; Widget ew; switch (event->type) { case KeyRelease: keyevent = (XKeyEvent *)event; ew = XtWindowToWidget(XtDisplay(w), keyevent->window); if (ew != plot->plot_widget) panel_event_handler(ew, (XtPointer)plot->panel, event, b); else { XtTranslateKeycode(XtDisplay(w), keyevent->keycode, 0, &mod_return, &key_sym); if ((keybuf = XKeysymToString(key_sym)) != NULL) { if (KEY_IS_UP(keybuf)) { panel_unzoom(plot->panel); } else { panel_handle_keyrelease(w, plot, keyevent, keybuf); } } } break; case ButtonPress: butevent = (XButtonEvent *) event; switch (butevent->button) { case Button1: break; case Button2: break; case Button3: XmMenuPosition(plot->plot_popupmenu_widget, butevent); XtManageChild(plot->plot_popupmenu_widget); break; default: break; } break; case ButtonRelease: butevent = (XButtonEvent *) event; switch (butevent->button) { case Button1: break; case Button2: break; case Button3: break; default: break; } break; case MotionNotify: motevent = (XMotionEvent *)event; if (motevent->state & Button1Mask) { } else if (motevent->state & Button2Mask) { } else if (motevent->state & Button2Mask) { } break; default: break; } }
static void Keyaction(Widget w, XEvent *e, String *p, Cardinal *np) { static unsigned char compose[5]; static int composing = -2; int composed = 0; int c, minmod; KeySym k, mk; Charfunc f; Modifiers md; /* * I tried using XtGetActionKeysym, but it didn't seem to * do case conversion properly * (at least, with Xterminal servers and R4 intrinsics) */ if(e->xany.type != KeyPress) return; XtTranslateKeycode(e->xany.display, (KeyCode)e->xkey.keycode, e->xkey.state, &md, &k); /* * The following song and dance is so we can have our chosen * modifier key behave like a compose key, i.e, press and release * and then type the compose sequence, like Plan 9. We have * to find out which key is the compose key first 'though. */ if (IsModifierKey(k) && ((GwinWidget)w)->gwin.compose && composing == -2 && modmap) { minmod = (((GwinWidget)w)->gwin.compose+2)*keypermod; for (c = minmod; c < minmod+keypermod; c++) { XtTranslateKeycode(e->xany.display, modmap->modifiermap[c], e->xkey.state, &md, &mk); if (k == mk) { composing = -1; break; } } return; } /* Handle Multi_key separately, since it isn't a modifier */ if(k == XK_Multi_key) { composing = -1; return; } if(k == NoSymbol) return; if(k&0xFF00){ switch(k){ case XK_BackSpace: case XK_Tab: case XK_Escape: case XK_Delete: case XK_KP_0: case XK_KP_1: case XK_KP_2: case XK_KP_3: case XK_KP_4: case XK_KP_5: case XK_KP_6: case XK_KP_7: case XK_KP_8: case XK_KP_9: case XK_KP_Divide: case XK_KP_Multiply: case XK_KP_Subtract: case XK_KP_Add: case XK_KP_Decimal: k &= 0x7F; break; case XK_Linefeed: k = '\r'; break; case XK_KP_Enter: case XK_Return: k = '\n'; break; case XK_Left: case XK_Down: case XK_Right: case XK_Next: k = 0x80; /* VIEW -- "Scroll" */ break; case XK_Up: case XK_Prior: k = 0x81; /* PREVIEW -- "Scroll back" */ break; default: return; /* not ISO-1 or tty control */ } } /* Compensate for servers that call a minus a hyphen */ if(k == XK_hyphen) k = XK_minus; /* Do control mapping ourselves if translator doesn't */ if((e->xkey.state&ControlMask) && !(md&ControlMask)) k &= 0x9f; if(k == NoSymbol) return; /* Check to see if we are in a composition sequence */ if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask) && composing == -2) composing = -1; if (composing > -2) { compose[++composing] = k; if ((*compose == 'X') && (composing > 0)) { if ((k < '0') || (k > 'f') || ((k > '9') && (k < 'a'))) { STUFFCOMPOSE(); c = (unsigned short)k; composing = -2; } else if (composing == 4) { c = unicode(compose); if (c == -1) { STUFFCOMPOSE(); c = (unsigned short)compose[4]; } else composed = 1; composing = -2; } } else if (composing == 1) { c = (int)latin1(compose); if (c == -1) { STUFFCOMPOSE(); c = (unsigned short)compose[1]; } else composed = 1; composing = -2; } } else { if (composing >= 0) { composing++; STUFFCOMPOSE(); } c = (unsigned short)k; composing = -2; } if (composing >= -1) return; f = ((GwinWidget)w)->gwin.gotchar; if(f) (*f)(c, composed); }