示例#1
0
void
dfb_updates_add( DFBUpdates      *updates,
                 const DFBRegion *region )
{
     int i;

     D_MAGIC_ASSERT( updates, DFBUpdates );
     DFB_REGION_ASSERT( region );
     D_ASSERT( updates->regions != NULL );
     D_ASSERT( updates->num_regions >= 0 );
     D_ASSERT( updates->num_regions <= updates->max_regions );

     D_DEBUG_AT( DFB_Updates, "%s( %p, %4d,%4d-%4dx%4d )\n", __FUNCTION__, (void*)updates,
                 DFB_RECTANGLE_VALS_FROM_REGION(region) );

     if (updates->num_regions == 0) {
          D_DEBUG_AT( DFB_Updates, "  -> added as first\n" );

          updates->regions[0]  = updates->bounding = *region;
          updates->num_regions = 1;

          return;
     }

     for (i=0; i<updates->num_regions; i++) {
          if (dfb_region_region_extends( &updates->regions[i], region ) ||
              dfb_region_region_intersects( &updates->regions[i], region ))
          {
               D_DEBUG_AT( DFB_Updates, "  -> combined with [%d] %4d,%4d-%4dx%4d\n", i,
                           DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[i]) );

               dfb_region_region_union( &updates->regions[i], region );

               dfb_region_region_union( &updates->bounding, region );

               D_DEBUG_AT( DFB_Updates, "  -> resulting in  [%d] %4d,%4d-%4dx%4d\n", i,
                           DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[i]) );

               return;
          }
     }

     if (updates->num_regions == updates->max_regions) {
          dfb_region_region_union( &updates->bounding, region );

          updates->regions[0]  = updates->bounding;
          updates->num_regions = 1;

          D_DEBUG_AT( DFB_Updates, "  -> collapsing to [0] %4d,%4d-%4dx%4d\n",
                      DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[0]) );
     }
     else {
          updates->regions[updates->num_regions++] = *region;

          dfb_region_region_union( &updates->bounding, region );

          D_DEBUG_AT( DFB_Updates, "  -> added as      [%d] %4d,%4d-%4dx%4d\n", updates->num_regions - 1,
                      DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[updates->num_regions - 1]) );
     }
}
示例#2
0
文件: util.c 项目: maxupunk/DIR685
void
dfb_updates_add( DFBUpdates      *updates,
                 const DFBRegion *region )
{
     int i;

     D_MAGIC_ASSERT( updates, DFBUpdates );
     DFB_REGION_ASSERT( region );
     D_ASSERT( updates->regions != NULL );
     D_ASSERT( updates->num_regions >= 0 );
     D_ASSERT( updates->num_regions <= updates->max_regions );

     if (updates->num_regions == 0) {
          updates->regions[0]  = updates->bounding = *region;
          updates->num_regions = 1;

          return;
     }

     for (i=0; i<updates->num_regions; i++) {
          DFBRegion inter = updates->regions[i];

          if (dfb_region_region_intersect( &inter, region )) {
               DFBRegion uni = updates->regions[i];

               dfb_region_region_union( &uni, region );

               updates->regions[i] = uni;

               dfb_region_region_union( &updates->bounding, &uni );

               return;
          }
     }

     if (updates->num_regions == updates->max_regions) {
          dfb_region_region_union( &updates->bounding, region );

          updates->regions[0]  = updates->bounding;
          updates->num_regions = 1;
     }
     else {
          updates->regions[updates->num_regions++] = *region;

          dfb_region_region_union( &updates->bounding, region );
     }
}
示例#3
0
static DFBResult
dfb_sdl_update_screen_handler( const DFBRegion *region )
{
     DFBRegion    update;
     CoreSurface *surface = dfb_sdl->primary;

     DFB_REGION_ASSERT_IF( region );

     if (region)
          update = *region;
     else {
          update.x1 = 0;
          update.y1 = 0;
          update.x2 = surface->config.size.w - 1;
          update.y2 = surface->config.size.h - 1;
     }

#if 0
     pthread_mutex_lock( &dfb_sdl->update.lock );

     if (dfb_sdl->update.pending)
          dfb_region_region_union( &dfb_sdl->update.region, &update );
     else {
          dfb_sdl->update.region  = update;
          dfb_sdl->update.pending = true;
     }

     pthread_cond_signal( &dfb_sdl->update.cond );

     pthread_mutex_unlock( &dfb_sdl->update.lock );
#else
     if (surface->config.caps & DSCAPS_FLIPPING)
          SDL_Flip( dfb_sdl->screen );
     else
          SDL_UpdateRect( dfb_sdl->screen, DFB_RECTANGLE_VALS_FROM_REGION(&update) );
#endif

     return DFB_OK;
}
示例#4
0
/* HACK: implementation dumped in here for now, will move into context */
static DFBResult
wm_update_cursor( CoreWindowStack       *stack,
                  void                  *wm_data,
                  void                  *stack_data,
                  CoreCursorUpdateFlags  flags )
{
     DFBResult         ret;
     DFBRegion         old_region;
     WMData           *wmdata   = wm_data;
     StackData        *data     = stack_data;
     bool              restored = false;
     CoreLayer        *layer;
     CoreLayerRegion  *region;
     CardState        *state;
     CoreSurface      *surface;
     UniqueContext    *context;

     D_ASSERT( stack != NULL );
     D_ASSERT( stack->context != NULL );
     D_ASSERT( wm_data != NULL );
     D_ASSERT( stack_data != NULL );

     D_MAGIC_ASSERT( data, StackData );

     context = data->context;

     D_MAGIC_ASSERT( context, UniqueContext );

     /* Optimize case of invisible cursor moving. */
     if (!(flags & ~(CCUF_POSITION | CCUF_SHAPE)) && (!stack->cursor.opacity || !stack->cursor.enabled)) {
          context->cursor_bs_valid = false;
          return DFB_OK;
     }

     layer   = dfb_layer_at( context->layer_id );
     state   = &layer->state;
     region  = context->region;
     surface = context->surface;

     D_ASSERT( region != NULL );
     D_ASSERT( surface != NULL );

     if (flags & CCUF_ENABLE) {
          CoreSurface            *cursor_bs;
          DFBSurfaceCapabilities  caps = DSCAPS_NONE;

          dfb_surface_caps_apply_policy( stack->cursor.policy, &caps );

          D_ASSERT( context->cursor_bs == NULL );

          /* Create the cursor backing store surface. */
          ret = dfb_surface_create_simple( wmdata->core, stack->cursor.size.w, stack->cursor.size.h,
                                           region->config.format, region->config.colorspace, 
                                           caps, CSTF_SHARED | CSTF_CURSOR,
                                           0, /* FIXME: no shared cursor objects, no cursor id */
                                           NULL, &cursor_bs );
          if (ret) {
               D_ERROR( "WM/Default: Failed creating backing store for cursor!\n" );
               return ret;
          }

          ret = dfb_surface_globalize( cursor_bs );
          D_ASSERT( ret == DFB_OK );

          /* Ensure valid back buffer for now.
           * FIXME: Keep a flag to know when back/front have been swapped and need a sync.
           */
          switch (region->config.buffermode) {
               case DLBM_BACKVIDEO:
               case DLBM_TRIPLE:
                    dfb_gfx_copy( surface, surface, NULL );
                    break;

               default:
                    break;
          }

          context->cursor_bs = cursor_bs;
     }
     else {
          D_ASSERT( context->cursor_bs != NULL );

          /* restore region under cursor */
          if (context->cursor_drawn) {
               DFBRectangle rect = { 0, 0,
                                     context->cursor_region.x2 - context->cursor_region.x1 + 1,
                                     context->cursor_region.y2 - context->cursor_region.y1 + 1 };

               D_ASSERT( stack->cursor.opacity || (flags & CCUF_OPACITY) );
               D_ASSERT( context->cursor_bs_valid );

               dfb_gfx_copy_to( context->cursor_bs, surface, &rect,
                                context->cursor_region.x1, context->cursor_region.y1, false );

               context->cursor_drawn = false;

               old_region = context->cursor_region;
               restored   = true;
          }

          if (flags & CCUF_SIZE) {
               ret = dfb_surface_reformat( context->cursor_bs,
                                           stack->cursor.size.w, stack->cursor.size.h,
                                           context->cursor_bs->config.format );
               if (ret) {
                    D_ERROR( "WM/Default: Failed resizing backing store for cursor!\n" );
                    return ret;
               }
          }
     }

     if (flags & (CCUF_ENABLE | CCUF_POSITION | CCUF_SIZE | CCUF_OPACITY)) {
          context->cursor_bs_valid  = false;

          context->cursor_region.x1 = stack->cursor.x - stack->cursor.hot.x;
          context->cursor_region.y1 = stack->cursor.y - stack->cursor.hot.y;
          context->cursor_region.x2 = context->cursor_region.x1 + stack->cursor.size.w - 1;
          context->cursor_region.y2 = context->cursor_region.y1 + stack->cursor.size.h - 1;

          if (!dfb_region_intersect( &context->cursor_region, 0, 0, stack->width - 1, stack->height - 1 )) {
               D_BUG( "invalid cursor region" );
               return DFB_BUG;
          }
     }

     D_ASSERT( context->cursor_bs != NULL );

     if (flags & CCUF_DISABLE) {
          dfb_surface_unlink( &context->cursor_bs );
     }
     else if (stack->cursor.opacity) {
          /* backup region under cursor */
          if (!context->cursor_bs_valid) {
               DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &context->cursor_region );

               D_ASSERT( !context->cursor_drawn );

               /* FIXME: this requires using blitted flipping all the time,
                  but fixing it seems impossible, for now DSFLIP_BLIT is forced
                  in repaint_stack() when the cursor is enabled. */
               dfb_gfx_copy_to( surface, context->cursor_bs, &rect, 0, 0, true );

               context->cursor_bs_valid = true;
          }

          /* Set destination. */
          state->destination  = surface;
          state->modified    |= SMF_DESTINATION;

          /* Set clipping region. */
          dfb_state_set_clip( state, &context->cursor_region );

          /* draw cursor */
          unique_draw_cursor( stack, context, state, &context->cursor_region );

          /* Reset destination. */
          state->destination  = NULL;
          state->modified    |= SMF_DESTINATION;

          context->cursor_drawn = true;

          if (restored) {
               if (dfb_region_region_intersects( &old_region, &context->cursor_region ))
                    dfb_region_region_union( &old_region, &context->cursor_region );
               else
                    dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );

               dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );
          }
          else
               dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );
     }
     else if (restored)
          dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );

     return DFB_OK;
}
示例#5
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;
}