/* * Input thread reading from device. * Generates events on incoming data. */ static void* x11EventThread( DirectThread *thread, void *driver_data ) { X11InputData *data = driver_data; DFBX11 *x11 = data->x11; DFBX11Shared *shared = x11->shared; while (!data->stop) { unsigned int pull = 23; XEvent xEvent; DFBInputEvent dfbEvent; static int nextKeyIsRepeat = false; /* FIXME: Detect key repeats, we're receiving KeyPress, KeyRelease, KeyPress, KeyRelease... !!?? */ if (shared->window == 0) { /* no window, so no event */ usleep( 50000 ); continue; } usleep( 10000 ); XLockDisplay( x11->display ); while (!data->stop && pull-- && XPending( x11->display )) { XNextEvent( x11->display, &xEvent ); /* is this key repeat? idea from GII */ if ( (xEvent.type == KeyRelease) && (XPending( x11->display )) ) { XEvent peekEvent; XPeekEvent( x11->display, &peekEvent ); if ( (peekEvent.type == KeyPress) && (peekEvent.xkey.keycode == xEvent.xkey.keycode) && (peekEvent.xkey.time - xEvent.xkey.time < 2) ) { nextKeyIsRepeat = true; } } XUnlockDisplay( x11->display ); D_DEBUG_AT( X11_Input, "Event received: %d\n", xEvent.type ); switch (xEvent.type) { case ButtonPress: case ButtonRelease: motion_realize( data ); case MotionNotify: handleMouseEvent( &xEvent, data ); // crash ??? break; case KeyPress: case KeyRelease: { motion_realize( data ); dfbEvent.type = (xEvent.type == KeyPress) ? DIET_KEYPRESS : DIET_KEYRELEASE; dfbEvent.flags = DIEF_KEYCODE | DIEF_TIMESTAMP; dfbEvent.key_code = xEvent.xkey.keycode; dfbEvent.timestamp.tv_sec = xEvent.xkey.time / 1000; dfbEvent.timestamp.tv_usec = (xEvent.xkey.time % 1000) * 1000; if ( (xEvent.type == KeyPress) && nextKeyIsRepeat ) { nextKeyIsRepeat = false; dfbEvent.flags |= DIEF_REPEAT; } dfb_input_dispatch( data->device, &dfbEvent ); break; } case Expose: //handle_expose( &xEvent.xexpose ); break; case DestroyNotify: /* this event is mainly to unblock XNextEvent. */ break; default: break; } XLockDisplay( x11->display ); } XUnlockDisplay( x11->display ); if (!data->stop) motion_realize( data ); } return NULL; }
/* * Input thread reading from device. * Generates events on incoming data. */ static void* sdlEventThread( DirectThread *thread, void *driver_data ) { SDLInputData *data = (SDLInputData*) driver_data; DFBSDL *dfb_sdl = data->dfb_sdl; while (!data->stop) { DFBInputEvent evt; SDL_Event event; fusion_skirmish_prevail( &dfb_sdl->lock ); /* Check for events */ while ( SDL_PollEvent(&event) ) { fusion_skirmish_dismiss( &dfb_sdl->lock ); switch (event.type) { case SDL_MOUSEMOTION: motion_compress( event.motion.x, event.motion.y ); break; case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: motion_realize( data ); if (event.type == SDL_MOUSEBUTTONDOWN) evt.type = DIET_BUTTONPRESS; else evt.type = DIET_BUTTONRELEASE; evt.flags = DIEF_NONE; switch (event.button.button) { case SDL_BUTTON_LEFT: evt.button = DIBI_LEFT; break; case SDL_BUTTON_MIDDLE: evt.button = DIBI_MIDDLE; break; case SDL_BUTTON_RIGHT: evt.button = DIBI_RIGHT; break; case SDL_BUTTON_WHEELUP: case SDL_BUTTON_WHEELDOWN: if (event.type != SDL_MOUSEBUTTONDOWN) { fusion_skirmish_prevail( &dfb_sdl->lock ); continue; } evt.type = DIET_AXISMOTION; evt.flags = DIEF_AXISREL; evt.axis = DIAI_Z; if (event.button.button == SDL_BUTTON_WHEELUP) evt.axisrel = -1; else evt.axisrel = 1; break; default: fusion_skirmish_prevail( &dfb_sdl->lock ); continue; } dfb_input_dispatch( data->device, &evt ); break; case SDL_KEYUP: case SDL_KEYDOWN: if (event.type == SDL_KEYDOWN) evt.type = DIET_KEYPRESS; else evt.type = DIET_KEYRELEASE; /* Get a key id first */ translate_key( event.key.keysym.sym, &evt ); /* If SDL provided a symbol, use it */ if (event.key.keysym.unicode) { evt.flags |= DIEF_KEYSYMBOL; evt.key_symbol = event.key.keysym.unicode; /** * Hack to translate the Control+[letter] * combination to * Modifier: CONTROL, Key Symbol: [letter] * A side effect here is that Control+Backspace * produces Control+h */ if (evt.modifiers == DIMM_CONTROL && evt.key_symbol >= 1 && evt.key_symbol <= ('z'-'a'+1)) { evt.key_symbol += 'a'-1; } } dfb_input_dispatch( data->device, &evt ); break; case SDL_QUIT: evt.type = DIET_KEYPRESS; evt.flags = DIEF_KEYSYMBOL; evt.key_symbol = DIKS_ESCAPE; dfb_input_dispatch( data->device, &evt ); evt.type = DIET_KEYRELEASE; evt.flags = DIEF_KEYSYMBOL; evt.key_symbol = DIKS_ESCAPE; dfb_input_dispatch( data->device, &evt ); break; default: break; } fusion_skirmish_prevail( &dfb_sdl->lock ); } fusion_skirmish_dismiss( &dfb_sdl->lock ); motion_realize( data ); usleep(10000); direct_thread_testcancel( thread ); } return NULL; }
/* * Input thread reading from device. * Generates events on incoming data. */ static void* x11EventThread( DirectThread *thread, void *driver_data ) { X11InputData *data = driver_data; DFBX11 *x11 = data->x11; int x11_fd = ConnectionNumber(x11->display); XExposeEvent expose_event = { 0 }; fd_set in_fds; struct timeval tv; while (!data->stop) { unsigned int pull = 2000; XEvent xEvent; DFBInputEvent dfbEvent; static int nextKeyIsRepeat = false; /* FIXME: Detect key repeats, we're receiving KeyPress, KeyRelease, KeyPress, KeyRelease... !!?? */ if (expose_event.type) { // handle_expose_Async( x11, &expose_event ); expose_event.type = 0; } // Create a File Description Set containing x11_fd FD_ZERO(&in_fds); FD_SET(x11_fd, &in_fds); // Set our timer. tv.tv_sec = 0; tv.tv_usec = 20000; // Wait for X Event or a Timer if (select(x11_fd+1, &in_fds, 0, 0, &tv)) { XLockDisplay( x11->display ); while (!data->stop && pull-- && XPending( x11->display )) { XNextEvent( x11->display, &xEvent ); //D_INFO_LINE_MSG("x11 event %d",xEvent.type); /* is this key repeat? idea from GII */ if ( (xEvent.type == KeyRelease) && (XPending( x11->display )) ) { XEvent peekEvent; XPeekEvent( x11->display, &peekEvent ); if ( (peekEvent.type == KeyPress) && (peekEvent.xkey.keycode == xEvent.xkey.keycode) && (peekEvent.xkey.time - xEvent.xkey.time < 2) ) { nextKeyIsRepeat = true; } } XUnlockDisplay( x11->display ); D_DEBUG_AT( X11_Input, "Event received: %d\n", xEvent.type ); switch (xEvent.type) { case ButtonPress: case ButtonRelease: motion_realize( data ); case MotionNotify: handleMouseEvent( &xEvent, data, x11 ); // crash ??? break; case KeyPress: case KeyRelease: motion_realize( data ); dfbEvent.type = (xEvent.type == KeyPress) ? DIET_KEYPRESS : DIET_KEYRELEASE; dfbEvent.flags = DIEF_KEYCODE | DIEF_TIMESTAMP; dfbEvent.key_code = xEvent.xkey.keycode; dfbEvent.timestamp.tv_sec = xEvent.xkey.time / 1000; dfbEvent.timestamp.tv_usec = (xEvent.xkey.time % 1000) * 1000; if ( (xEvent.type == KeyPress) && nextKeyIsRepeat ) { nextKeyIsRepeat = false; dfbEvent.flags |= DIEF_REPEAT; } dfb_input_dispatch( data->device, &dfbEvent ); break; case Expose: //D_INFO_LINE_MSG("<- expose %d,%d-%dx%d", // xEvent.xexpose.x, xEvent.xexpose.y, xEvent.xexpose.width, xEvent.xexpose.height); if (expose_event.type != 0) { DFBRegion e1 = { expose_event.x, expose_event.y, expose_event.x + expose_event.width - 1, expose_event.y + expose_event.height - 1 }; DFBRegion e2 = { xEvent.xexpose.x, xEvent.xexpose.y, xEvent.xexpose.x + xEvent.xexpose.width - 1, xEvent.xexpose.y + xEvent.xexpose.height - 1 }; dfb_region_region_union( &e1, &e2 ); expose_event.x = e1.x1; expose_event.y = e1.y1; expose_event.width = e1.x2 - e1.x1 + 1; expose_event.height = e1.y2 - e1.y1 + 1; } else expose_event = xEvent.xexpose; //D_INFO_LINE_MSG("-> expose %d,%d-%dx%d", // expose_event.x, expose_event.y, expose_event.width, expose_event.height); break; case DestroyNotify: /* this event is mainly to unblock XNextEvent. */ break; default: break; } XLockDisplay( x11->display ); } XUnlockDisplay( x11->display ); if (!data->stop) motion_realize( data ); } } return NULL; }