예제 #1
0
/*
 * 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;
}
예제 #2
0
/*
 * 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;
}
예제 #3
0
/*
 * 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;
}