static int x11_event(XEvent *ev) { switch (ev->type) { /* Graphics related events */ case ConfigureNotify: x11_window_xpos=ev->xconfigure.x; x11_window_ypos=ev->xconfigure.y; x11_window_width=ev->xconfigure.width; x11_window_height=ev->xconfigure.height; handle_resize_event(ev->xconfigure.width, ev->xconfigure.height); break; case NoExpose: break; case GraphicsExpose: expose_rect(ev->xgraphicsexpose.x, ev->xgraphicsexpose.y, ev->xgraphicsexpose.width, ev->xgraphicsexpose.height); break; case Expose: expose_rect(ev->xexpose.x, ev->xexpose.y, ev->xexpose.width, ev->xexpose.height); break; /* Copy/Paste events */ case SelectionClear: { XSelectionClearEvent *req; req=&(ev->xselectionclear); pthread_mutex_lock(©buf_mutex); if(req->selection==CONSOLE_CLIPBOARD) FREE_AND_NULL(copybuf); pthread_mutex_unlock(©buf_mutex); } break; case SelectionNotify: { int format; unsigned long len, bytes_left, dummy; Atom type; if(ev->xselection.selection != CONSOLE_CLIPBOARD) break; if(ev->xselection.requestor!=win) break; if(ev->xselection.property) { x11.XGetWindowProperty(dpy, win, ev->xselection.property, 0, 0, 0, AnyPropertyType, &type, &format, &len, &bytes_left, (unsigned char **)(&pastebuf)); if(bytes_left > 0 && format==8) x11.XGetWindowProperty(dpy, win, ev->xselection.property,0,bytes_left,0,AnyPropertyType,&type,&format,&len,&dummy,(unsigned char **)&pastebuf); else pastebuf=NULL; } else pastebuf=NULL; /* Set paste buffer */ sem_post(&pastebuf_set); sem_wait(&pastebuf_used); x11.XFree(pastebuf); pastebuf=NULL; } break; case SelectionRequest: { XSelectionRequestEvent *req; XEvent respond; req=&(ev->xselectionrequest); pthread_mutex_lock(©buf_mutex); if(copybuf==NULL) { respond.xselection.property=None; } else { if(req->target==XA_STRING) { x11.XChangeProperty(dpy, req->requestor, req->property, XA_STRING, 8, PropModeReplace, (unsigned char *)copybuf, strlen(copybuf)); respond.xselection.property=req->property; } else respond.xselection.property=None; } respond.xselection.type=SelectionNotify; respond.xselection.display=req->display; respond.xselection.requestor=req->requestor; respond.xselection.selection=req->selection; respond.xselection.target=req->target; respond.xselection.time=req->time; x11.XSendEvent(dpy,req->requestor,0,0,&respond); pthread_mutex_unlock(©buf_mutex); } break; /* Mouse Events */ case MotionNotify: { XMotionEvent *me = (XMotionEvent *)ev; me->x/=vstat.scaling; me->x/=vstat.charwidth; me->y/=vstat.scaling; me->y/=vstat.charheight; me->x++; me->y++; if(me->x<1) me->x=1; if(me->y<1) me->y=1; if(me->x>vstat.cols) me->x=vstat.cols; if(me->y>vstat.rows+1) me->y=vstat.rows+1; ciomouse_gotevent(CIOLIB_MOUSE_MOVE,me->x,me->y); } break; case ButtonRelease: { XButtonEvent *be = (XButtonEvent *)ev; be->x/=vstat.scaling; be->x/=vstat.charwidth; be->y/=vstat.scaling; be->y/=vstat.charheight; be->x++; be->y++; if(be->x<1) be->x=1; if(be->y<1) be->y=1; if(be->x>vstat.cols) be->x=vstat.cols; if(be->y>vstat.rows+1) be->y=vstat.rows+1; if (be->button <= 3) { ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(be->button),be->x,be->y); } } break; case ButtonPress: { XButtonEvent *be = (XButtonEvent *)ev; be->x/=vstat.scaling; be->x/=vstat.charwidth; be->y/=vstat.scaling; be->y/=vstat.charheight; be->x++; be->y++; if(be->x<1) be->x=1; if(be->y<1) be->y=1; if(be->x>vstat.cols) be->x=vstat.cols; if(be->y>vstat.rows+1) be->y=vstat.rows+1; if (be->button <= 3) { ciomouse_gotevent(CIOLIB_BUTTON_PRESS(be->button),be->x,be->y); } } break; /* Keyboard Events */ case KeyPress: { static char buf[128]; KeySym ks; int n; int nlock = 0; WORD scan = 0xffff; n = x11.XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0); switch (ks) { case XK_Escape: scan = 1; goto docode; case XK_Tab: case XK_ISO_Left_Tab: scan = 15; goto docode; case XK_Return: case XK_KP_Enter: scan = 28; goto docode; case XK_Print: scan = 55; goto docode; case XK_F1: case XK_F2: case XK_F3: case XK_F4: case XK_F5: case XK_F6: case XK_F7: case XK_F8: case XK_F9: case XK_F10: scan = ks - XK_F1 + 59; goto docode; case XK_KP_7: nlock = 1; case XK_Home: case XK_KP_Home: scan = 71; goto docode; case XK_KP_8: nlock = 1; case XK_Up: case XK_KP_Up: scan = 72; goto docode; case XK_KP_9: nlock = 1; case XK_Prior: case XK_KP_Prior: scan = 73; goto docode; case XK_KP_Subtract: scan = 74; goto docode; case XK_KP_4: nlock = 1; case XK_Left: case XK_KP_Left: scan = 75; goto docode; case XK_KP_5: nlock = 1; case XK_Begin: case XK_KP_Begin: scan = 76; goto docode; case XK_KP_6: nlock = 1; case XK_Right: case XK_KP_Right: scan = 77; goto docode; case XK_KP_Add: scan = 78; goto docode; case XK_KP_1: nlock = 1; case XK_End: case XK_KP_End: scan = 79; goto docode; case XK_KP_2: nlock = 1; case XK_Down: case XK_KP_Down: scan = 80; goto docode; case XK_KP_3: nlock = 1; case XK_Next: case XK_KP_Next: scan = 81; goto docode; case XK_KP_0: nlock = 1; case XK_Insert: case XK_KP_Insert: scan = 82; goto docode; case XK_KP_Decimal: nlock = 1; scan = 83; goto docode; case XK_Delete: case XK_KP_Delete: /* scan = flipdelete ? 14 : 83; */ scan = 83; goto docode; case XK_BackSpace: /* scan = flipdelete ? 83 : 14; */ scan = 14; goto docode; case XK_F11: scan = 87; goto docode; case XK_F12: scan = 88; goto docode; case XK_KP_Divide: scan = Ascii2Scan['/']; goto docode; case XK_KP_Multiply: scan = Ascii2Scan['*']; goto docode; default: if (ks < ' ' || ks > '~') break; scan = Ascii2Scan[ks]; docode: if (nlock) scan |= 0x100; if ((scan & ~0x100) > 88) { scan = 0xffff; break; } if (ev->xkey.state & Mod1Mask) { scan = ScanCodes[scan & 0xff].alt; } else if ((ev->xkey.state & ShiftMask) || (scan & 0x100)) { scan = ScanCodes[scan & 0xff].shift; } else if (ev->xkey.state & ControlMask) { scan = ScanCodes[scan & 0xff].ctrl; } else scan = ScanCodes[scan & 0xff].base; break; } if (scan != 0xffff) { uint16_t key=scan; write(key_pipe[1], &key, (scan&0xff)?1:2); } return(1); } default: break; } return(0); }
static int win32_keyboardio(int isgetch) { INPUT_RECORD input; DWORD num=0; HANDLE h; static WORD lastch; if((h=GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) return(0); while(1) { if(lastch) { if(isgetch) { BYTE ch; ch=lastch&0xff; lastch>>=8; return(ch); } else return(TRUE); } while(1) { GetNumberOfConsoleInputEvents(h, &num); if(num) break; if(mouse_trywait()) { lastch=CIO_KEY_MOUSE; break; } if(isgetch) SLEEP(1); else return(FALSE); } if(lastch) continue; if(!ReadConsoleInput(h, &input, 1, &num) || !num || (input.EventType!=KEY_EVENT && input.EventType!=MOUSE_EVENT)) continue; switch(input.EventType) { case KEY_EVENT: #ifdef DEBUG_KEY_EVENTS dprintf("KEY_EVENT: KeyDown=%u" ,input.Event.KeyEvent.bKeyDown); dprintf(" RepeatCount=%u" ,input.Event.KeyEvent.wRepeatCount); dprintf(" VirtualKeyCode=0x%04hX" ,input.Event.KeyEvent.wVirtualKeyCode); dprintf(" VirtualScanCode=0x%04hX" ,input.Event.KeyEvent.wVirtualScanCode); dprintf(" uChar.AsciiChar=0x%02X (%u)" ,(BYTE)input.Event.KeyEvent.uChar.AsciiChar ,(BYTE)input.Event.KeyEvent.uChar.AsciiChar); dprintf(" ControlKeyState=0x%08lX" ,input.Event.KeyEvent.dwControlKeyState); #endif if(input.Event.KeyEvent.bKeyDown) { /* Is this an AltGr key? */ if(((input.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_CTRL_PRESSED)) == (RIGHT_ALT_PRESSED|LEFT_CTRL_PRESSED)) && (BYTE)input.Event.KeyEvent.uChar.AsciiChar) { lastch=(BYTE)input.Event.KeyEvent.uChar.AsciiChar; } /* Is this a modified char? */ else if((input.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED|RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED|ENHANCED_KEY)) || (input.Event.KeyEvent.wVirtualKeyCode >= VK_F1 && input.Event.KeyEvent.wVirtualKeyCode <= VK_F24) || !input.Event.KeyEvent.uChar.AsciiChar) { lastch=win32_getchcode(input.Event.KeyEvent.wVirtualKeyCode, input.Event.KeyEvent.dwControlKeyState); } /* Must be a normal char then! */ else { lastch=(BYTE)input.Event.KeyEvent.uChar.AsciiChar; } } else if(input.Event.KeyEvent.wVirtualKeyCode == VK_MENU) lastch=(BYTE)input.Event.KeyEvent.uChar.AsciiChar; break; case MOUSE_EVENT: if(domouse) { if(input.Event.MouseEvent.dwMousePosition.X+1 != LastX || input.Event.MouseEvent.dwMousePosition.Y+1 != LastY) { LastX=input.Event.MouseEvent.dwMousePosition.X+1; LastY=input.Event.MouseEvent.dwMousePosition.Y+1; ciomouse_gotevent(CIOLIB_MOUSE_MOVE,LastX,LastY); } if(last_state != input.Event.MouseEvent.dwButtonState) { switch(input.Event.MouseEvent.dwButtonState ^ last_state) { case FROM_LEFT_1ST_BUTTON_PRESSED: if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) ciomouse_gotevent(CIOLIB_BUTTON_1_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); else ciomouse_gotevent(CIOLIB_BUTTON_1_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); break; case FROM_LEFT_2ND_BUTTON_PRESSED: if(input.Event.MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) ciomouse_gotevent(CIOLIB_BUTTON_2_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); else ciomouse_gotevent(CIOLIB_BUTTON_2_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); break; case RIGHTMOST_BUTTON_PRESSED: if(input.Event.MouseEvent.dwButtonState & RIGHTMOST_BUTTON_PRESSED) ciomouse_gotevent(CIOLIB_BUTTON_3_PRESS,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); else ciomouse_gotevent(CIOLIB_BUTTON_3_RELEASE,input.Event.MouseEvent.dwMousePosition.X+1,input.Event.MouseEvent.dwMousePosition.Y+1); break; } last_state=input.Event.MouseEvent.dwButtonState; } } } }
int curs_getch(void) { int ch; #ifdef NCURSES_VERSION_MAJOR MEVENT mevnt; #endif if(curs_nextgetch) { ch=curs_nextgetch; curs_nextgetch=0; } else { while((ch=getch())==ERR) { if(mouse_trywait()) { curs_nextgetch=CIO_KEY_MOUSE>>8; return(CIO_KEY_MOUSE & 0xff); } } if(ch > 255) { switch(ch) { case KEY_DOWN: /* Down-arrow */ curs_nextgetch=0x50; ch=0; break; case KEY_UP: /* Up-arrow */ curs_nextgetch=0x48; ch=0; break; case KEY_LEFT: /* Left-arrow */ curs_nextgetch=0x4b; ch=0; break; case KEY_RIGHT: /* Right-arrow */ curs_nextgetch=0x4d; ch=0; break; case KEY_HOME: /* Home key (upward+left arrow) */ curs_nextgetch=0x47; ch=0; break; case KEY_BACKSPACE: /* Backspace (unreliable) */ ch=8; break; case KEY_F(1): /* Function Key */ curs_nextgetch=0x3b; ch=0; break; case KEY_F(2): /* Function Key */ curs_nextgetch=0x3c; ch=0; break; case KEY_F(3): /* Function Key */ curs_nextgetch=0x3d; ch=0; break; case KEY_F(4): /* Function Key */ curs_nextgetch=0x3e; ch=0; break; case KEY_F(5): /* Function Key */ curs_nextgetch=0x3f; ch=0; break; case KEY_F(6): /* Function Key */ curs_nextgetch=0x40; ch=0; break; case KEY_F(7): /* Function Key */ curs_nextgetch=0x41; ch=0; break; case KEY_F(8): /* Function Key */ curs_nextgetch=0x42; ch=0; break; case KEY_F(9): /* Function Key */ curs_nextgetch=0x43; ch=0; break; case KEY_F(10): /* Function Key */ curs_nextgetch=0x44; ch=0; break; case KEY_F(11): /* Function Key */ curs_nextgetch=0x57; ch=0; break; case KEY_F(12): /* Function Key */ curs_nextgetch=0x58; ch=0; break; case KEY_DC: /* Delete character */ curs_nextgetch=0x53; ch=0; break; case KEY_IC: /* Insert char or enter insert mode */ curs_nextgetch=0x52; ch=0; break; case KEY_EIC: /* Exit insert char mode */ curs_nextgetch=0x52; ch=0; break; case KEY_NPAGE: /* Next page */ curs_nextgetch=0x51; ch=0; break; case KEY_PPAGE: /* Previous page */ curs_nextgetch=0x49; ch=0; break; case KEY_ENTER: /* Enter or send (unreliable) */ curs_nextgetch=0x0d; ch=0; break; case KEY_A1: /* Upper left of keypad */ curs_nextgetch=0x47; ch=0; break; case KEY_A3: /* Upper right of keypad */ curs_nextgetch=0x49; ch=0; break; case KEY_B2: /* Center of keypad */ curs_nextgetch=0x4c; ch=0; break; case KEY_C1: /* Lower left of keypad */ curs_nextgetch=0x4f; ch=0; break; case KEY_C3: /* Lower right of keypad */ curs_nextgetch=0x51; ch=0; break; case KEY_BEG: /* Beg (beginning) */ curs_nextgetch=0x47; ch=0; break; case KEY_CANCEL: /* Cancel */ curs_nextgetch=0x03; ch=0; break; case KEY_END: /* End */ curs_nextgetch=0x4f; ch=0; break; case KEY_SELECT: /* Select - Is "End" in X */ curs_nextgetch=0x4f; ch=0; break; #ifdef NCURSES_VERSION_MAJOR case KEY_MOUSE: /* Mouse stuff */ if(getmouse(&mevnt)==OK) { int evnt=0; switch(mevnt.bstate) { case BUTTON1_PRESSED: evnt=CIOLIB_BUTTON_1_PRESS; break; case BUTTON1_RELEASED: evnt=CIOLIB_BUTTON_1_RELEASE; break; case BUTTON2_PRESSED: evnt=CIOLIB_BUTTON_2_PRESS; break; case BUTTON2_RELEASED: evnt=CIOLIB_BUTTON_2_RELEASE; break; case BUTTON3_PRESSED: evnt=CIOLIB_BUTTON_3_PRESS; break; case BUTTON3_RELEASED: evnt=CIOLIB_BUTTON_3_RELEASE; break; case REPORT_MOUSE_POSITION: evnt=CIOLIB_MOUSE_MOVE; break; } ciomouse_gotevent(evnt, mevnt.x+1, mevnt.y+1); } break; #endif default: curs_nextgetch=0xff; ch=0; break; } } } return(ch); }