static DFBResult
IDirectFBSurface_Layer_Flip( IDirectFBSurface    *thiz,
                             const DFBRegion     *region,
                             DFBSurfaceFlipFlags  flags )
{
     DFBRegion reg;

     DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer)

     D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags );

     if (!data->base.surface)
          return DFB_DESTROYED;

     if (data->base.locked)
          return DFB_LOCKED;

     if (!data->base.area.current.w || !data->base.area.current.h ||
         (region && (region->x1 > region->x2 || region->y1 > region->y2)))
          return DFB_INVAREA;


     IDirectFBSurface_StopAll( &data->base );

     if (data->base.parent) {
          IDirectFBSurface_data *parent_data;

          DIRECT_INTERFACE_GET_DATA_FROM( data->base.parent, parent_data, IDirectFBSurface );

          if (parent_data) {
               /* Signal end of sequence of operations. */
               dfb_state_lock( &parent_data->state );
               dfb_state_stop_drawing( &parent_data->state );
               dfb_state_unlock( &parent_data->state );
          }
     }

     dfb_region_from_rectangle( &reg, &data->base.area.current );

     if (region) {
          DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region,
                                                       data->base.area.wanted.x,
                                                       data->base.area.wanted.y );

          if (!dfb_region_region_intersect( &reg, &clip ))
               return DFB_INVAREA;
     }

     D_DEBUG_AT( Surface, "  -> FLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &reg ) );

     return CoreLayerRegion_FlipUpdate( data->region, &reg, flags );
}
Exemple #2
0
static void on_cbs_motion(int *y)
{
    pthread_mutex_lock(&ui_mutex);
    if (y == NULL) {
        /* back to the original position */
        pthread_mutex_unlock(&ui_mutex);
        return;
    }

    LiteBox *box = LITE_BOX(detailLabel);
    int cur_line, delta_line;
    int downX = getUiControlObj()->downX;
    int downY = getUiControlObj()->downY;
    int dy = downY - *y;
    DFBRegion reg_label;

    dfb_region_from_rectangle(&reg_label, &box->rect);
    if (!DFB_REGION_CONTAINS_POINT(&reg_label, downX, downY)) {
        pthread_mutex_unlock(&ui_mutex);
        return;
    }

    lite_get_label_cur_line(detailLabel, &cur_line);
    delta_line = dy / VERTICAL_SWIPE_THRESHOLD;
    LOG_DBG("[%s] total_line = %d, cur_line = %d, delta_line = %d\n", __func__, total_line, cur_line, delta_line);

    if (total_line <= MAX_CBS_DETAIL_LINES) {
        pthread_mutex_unlock(&ui_mutex);
        return;
    }

    cur_line += delta_line;
    if (cur_line < 0) {
        cur_line = 0;
    } else if (cur_line >= max_moved_lines) {
        cur_line = max_moved_lines;
    }
    LiteBox *scroll_box = LITE_BOX(scrollbarImg);
    scroll_box->rect.y = cur_line * scroll_step + SCROLLBAR_TOP;
    lite_reinit_box_and_children(scroll_box);
    lite_update_box(scroll_box->parent, NULL);

    LOG_DBG("[%s] scroll_step = %d, scroll_box->rect.y = %d, cur_line = %d\n", __func__, scroll_step, scroll_box->rect.y, cur_line);
    lite_set_label_cur_line(detailLabel, cur_line);

    pthread_mutex_unlock(&ui_mutex);
}
static DFBResult
IDirectFBImageProvider_GIF_RenderTo( IDirectFBImageProvider *thiz,
                                     IDirectFBSurface       *destination,
                                     const DFBRectangle     *dest_rect )
{
     DFBResult              ret;
     DFBRegion              clip;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     IDirectFBSurface_data *dst_data;
     CoreSurface           *dst_surface;

     DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF)

     dst_data = (IDirectFBSurface_data*) destination->priv;
     if (!dst_data)
          return DFB_DEAD;

     dst_surface = dst_data->surface;
     if (!dst_surface)
          return DFB_DESTROYED;

     dfb_region_from_rectangle( &clip, &dst_data->area.current );

     if (dest_rect) {
          if (dest_rect->w < 1 || dest_rect->h < 1)
               return DFB_INVARG;
          rect = *dest_rect;
          rect.x += dst_data->area.wanted.x;
          rect.y += dst_data->area.wanted.y;
     }
     else {
          rect = dst_data->area.wanted;
     }

     ret = destination->GetPixelFormat( destination, &format );
     if (ret)
          return ret;

     /* actual loading and rendering */
     if (dfb_rectangle_region_intersects( &rect, &clip )) {
          CoreSurfaceBufferLock lock;

          ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
          if (ret)
               return ret;

          dfb_scale_linear_32( data->image, data->image_width, data->image_height,
                               lock.addr, lock.pitch, &rect, dst_surface, &clip );

          dfb_surface_unlock_buffer( dst_surface, &lock );

          if (data->base.render_callback) {
               DIRenderCallbackResult r;

               rect.x = 0;
               rect.y = 0;
               rect.w = data->image_width;
               rect.h = data->image_height;

               r = data->base.render_callback( &rect,
                                               data->base.render_callback_context );

               if (r != DIRCR_OK)
                       return DFB_INTERRUPTED;
          }
     }

     return DFB_OK;
}
static DFBResult
IDirectFBImageProvider_JPEG2000_RenderTo( IDirectFBImageProvider *thiz,
                                          IDirectFBSurface       *destination,
                                          const DFBRectangle     *dest_rect )
{
     IDirectFBSurface_data  *dst_data;
     CoreSurface            *dst_surface;
     CoreSurfaceBufferLock   lock;
     DFBRectangle            rect;
     DFBRegion               clip;
     DIRenderCallbackResult  cb_result = DIRCR_OK;
     DFBResult               ret       = DFB_OK;
     
     DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_JPEG2000 )
     
     if (!destination)
          return DFB_INVARG;
          
     dst_data = destination->priv;
     if (!dst_data || !dst_data->surface)
          return DFB_DESTROYED;
          
     dst_surface = dst_data->surface;
     
     if (dest_rect) {
          if (dest_rect->w < 1 || dest_rect->h < 1)
               return DFB_INVARG;
          rect = *dest_rect;
          rect.x += dst_data->area.wanted.x;
          rect.y += dst_data->area.wanted.y;
     }
     else {
          rect = dst_data->area.wanted;
     }
     
     dfb_region_from_rectangle( &clip, &dst_data->area.current );
     if (!dfb_rectangle_region_intersects( &rect, &clip ))
          return DFB_OK;

     ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
     if (ret)
          return ret;
     
     if (!data->buf) {
          int  cmptlut[3];
          int  width, height;
          int  tlx, tly;
          int  hs, vs;
          int  i, j;
          bool direct, mono;
     
          if (jas_image_numcmpts(data->image) > 1) {
               cmptlut[0] = jas_image_getcmptbytype(data->image,
                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
               cmptlut[1] = jas_image_getcmptbytype(data->image,
                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
               cmptlut[2] = jas_image_getcmptbytype(data->image,
                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
               if (cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[2] < 0) {
                    dfb_surface_unlock_buffer( dst_surface, &lock );
                    return DFB_UNSUPPORTED;
               }
               mono = false;
          }
          else {
               cmptlut[0] = cmptlut[1] = cmptlut[2] = 0;
               mono = true;
          }
     
          width = jas_image_width(data->image);
          height = jas_image_height(data->image);
          tlx = jas_image_cmpttlx(data->image, 0);
          tly = jas_image_cmpttly(data->image, 0);
          hs = jas_image_cmpthstep(data->image, 0);
          vs = jas_image_cmptvstep(data->image, 0);
          
          data->buf = D_MALLOC( width*height*4 );
          if (!data->buf) {
               dfb_surface_unlock_buffer( dst_surface, &lock );
               return D_OOM();
          }
          
          direct = (rect.w == width && rect.h == height && data->render_callback);
          
#define GET_SAMPLE( n, x, y ) ({ \
     int _s; \
     _s = jas_image_readcmptsample(data->image, cmptlut[n], x, y); \
     _s >>= jas_image_cmptprec(data->image, cmptlut[n]) - 8; \
     if (_s > 255) \
          _s = 255; \
     else if (_s < 0) \
          _s = 0; \
     _s; \
})
            
          for (i = 0; i < height; i++) {
               u32 *dst = data->buf + i * width;
               int  x, y;
               
               y = (i - tly) / vs;
               if (y >= 0 && y < height) {     
                    for (j = 0; j < width; j++) {
                         x = (j - tlx) / hs;
                         if (x >= 0 && x < width) {
                              unsigned int r, g, b;
                              if (mono) {
                                   r = g = b = GET_SAMPLE(0, x, y);
                              }
                              else {
                                   r = GET_SAMPLE(0, x, y);
                                   g = GET_SAMPLE(1, x, y);
                                   b = GET_SAMPLE(2, x, y);
                              }
                              *dst++ = 0xff000000 | (r << 16) | (g << 8) | b;
                         }
                         else {
                              *dst++ = 0;
                         }
                    }
               }
               else {
                    memset( dst, 0, width*4 );
               }
               
               if (direct) {
                    DFBRectangle r = { rect.x, rect.y+i, width, 1 };
                    
                    dfb_copy_buffer_32( data->buf + i*width,
                                        lock.addr, lock.pitch, &r, dst_surface, &clip );
                    
                    if (data->render_callback) {                    
                         r = (DFBRectangle) { 0, i, width, 1 };
                         cb_result = data->render_callback( &r, data->render_callback_ctx );
                         if (cb_result != DIRCR_OK)
                              break;
                    }
               }
          }
          
          if (!direct) {
               dfb_scale_linear_32( data->buf, width, height,
                                    lock.addr, lock.pitch, &rect, dst_surface, &clip );

               if (data->render_callback) {
                    DFBRectangle r = { 0, 0, width, height };
                    data->render_callback( &r, data->render_callback_ctx );
               }
          }
          
          if (cb_result != DIRCR_OK) {
               D_FREE( data->buf );
               data->buf = NULL;
               ret = DFB_INTERRUPTED;
          }
     }
     else {
          int width  = jas_image_width(data->image);
          int height = jas_image_height(data->image);
          
          dfb_scale_linear_32( data->buf, width, height,
                               lock.addr, lock.pitch, &rect, dst_surface, &clip );
          
          if (data->render_callback) {
               DFBRectangle r = {0, 0, width, height};
               data->render_callback( &r, data->render_callback_ctx );
          }
     }
     
     dfb_surface_unlock_buffer( dst_surface, &lock );
     
     return ret;
}
static DFBResult
IDirectFBImageProvider_MPEG2_RenderTo( IDirectFBImageProvider *thiz,
                                       IDirectFBSurface       *destination,
                                       const DFBRectangle     *dest_rect )
{
     DFBResult              ret;
     IDirectFBSurface_data *dst_data;
     CoreSurface           *dst_surface;
     DFBRegion              clip;
     DFBRectangle           rect;

     DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_MPEG2)

     dst_data = (IDirectFBSurface_data*) destination->priv;
     if (!dst_data)
          return DFB_DEAD;

     dst_surface = dst_data->surface;
     if (!dst_surface)
          return DFB_DESTROYED;

     dfb_region_from_rectangle( &clip, &dst_data->area.current );

     if (dest_rect) {
          if (dest_rect->w < 1 || dest_rect->h < 1)
               return DFB_INVARG;
          rect = *dest_rect;
          rect.w += dst_data->area.wanted.w;
          rect.h += dst_data->area.wanted.h;
     }
     else {
          rect = dst_data->area.wanted;
     }

     switch (data->stage) {
          case STAGE_END:
               break;
          case STAGE_IMAGE:
               if (MPEG2_Decode( data->dec, mpeg2_write_func, data )) {
                    data->stage = STAGE_ERROR;
                    return DFB_FAILURE;
               }
               data->stage = STAGE_END;
               break;
          default:
               return DFB_FAILURE;
     }

     /* actual rendering */
     if (dfb_rectangle_region_intersects( &rect, &clip )) {
          CoreSurfaceBufferLock lock;

          ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
          if (ret)
               return ret;

          dfb_scale_linear_32( data->image, data->width, data->height,
                               lock.addr, lock.pitch, &rect, dst_surface, &clip );

          dfb_surface_unlock_buffer( dst_surface, &lock );
     }

     return DFB_OK;
}
static DFBResult
IDirectFBImageProvider_ANDROID_RenderTo( IDirectFBImageProvider *thiz,
                                         IDirectFBSurface       *destination,
                                         const DFBRectangle     *dest_rect )
{
     DFBResult              ret;
     bool                   direct = false;
     DFBRegion              clip;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     IDirectFBSurface_data *dst_data;
     CoreSurface           *dst_surface;
     CoreSurfaceBufferLock  lock;
     DIRenderCallbackResult cb_result = DIRCR_OK;

     DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_ANDROID)

     dst_data = (IDirectFBSurface_data*) destination->priv;
     if (!dst_data)
          return DFB_DEAD;

     dst_surface = dst_data->surface;
     if (!dst_surface)
          return DFB_DESTROYED;

     ret = decodeImage( data );
     if (ret)
          return ret;

     ret = destination->GetPixelFormat( destination, &format );
     if (ret)
          return ret;

     dfb_region_from_rectangle( &clip, &dst_data->area.current );

     if (dest_rect) {
          if (dest_rect->w < 1 || dest_rect->h < 1)
               return DFB_INVARG;

          rect = *dest_rect;
          rect.x += dst_data->area.wanted.x;
          rect.y += dst_data->area.wanted.y;

          if (!dfb_rectangle_region_intersects( &rect, &clip ))
               return DFB_OK;
     }
     else {
          rect = dst_data->area.wanted;
     }

     ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
     if (ret)
          return ret;

     dfb_scale_linear_32( (u32 *)data->image, data->width, data->height, lock.addr, lock.pitch, &rect, dst_surface, &clip );
     if (data->base.render_callback) {
          DFBRectangle r = { 0, 0, data->width, data->height };
          data->base.render_callback( &r, data->base.render_callback_context );
     }

     dfb_surface_unlock_buffer( dst_surface, &lock );

     return DFB_OK;
}
static DFBResult
IDirectFBImageProvider_WebP_RenderTo( IDirectFBImageProvider *thiz,
                                      IDirectFBSurface       *destination,
                                      const DFBRectangle     *dest_rect )
{
     DFBResult               ret;

     DFBRegion               clip;
     CoreSurface            *dst_surface;
     CardState               state;

     CoreSurfaceBufferLock   lock;

     IDirectFBSurface_data  *dst_data;
     DIRenderCallbackResult  cb_result = DIRCR_OK;

     DFBRectangle           src_rect;
     DFBRectangle           rect;

     DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_WebP )

     if (!destination)
          return DFB_INVARG;

     dst_data = destination->priv;
     if (!dst_data || !dst_data->surface)
          return DFB_DESTROYED;

     dst_surface = dst_data->surface;

     if (dest_rect) {
          if (dest_rect->w < 1 || dest_rect->h < 1)
               return DFB_INVARG;

          rect = *dest_rect;
          rect.x += dst_data->area.wanted.x;
          rect.y += dst_data->area.wanted.y;
     }
     else {
          rect = dst_data->area.wanted;
     }

     dfb_region_from_rectangle( &clip, &dst_data->area.current );
     if (!dfb_rectangle_region_intersects( &rect, &clip ))
          return DFB_OK;


     ret = dfb_surface_create_simple( data->base.core, data->width, data->height, data->pixelformat,
                                      DSCS_RGB, DSCAPS_NONE, CSTF_NONE,
                                      0, NULL, &data->decode_surface );
     if (ret) {
          D_ERROR( "Failed to create surface : '%s'\n", DirectResultString(ret) );
          goto error;
     }

     ret = dfb_surface_lock_buffer( data->decode_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
     if (ret) {
          D_ERROR( "Failed to lock the surface : '%s'\n", DirectResultString(ret) );
          goto error;
     }

     ret = WebP_decode_image( data, &lock );
     if (ret) {
          D_ERROR( "Failed to decode the image : '%s'\n", DirectResultString(ret) );
          goto error;
     }

     dfb_surface_unlock_buffer( data->decode_surface, &lock );

     dfb_state_init( &state, data->base.core );

     state.modified |= SMF_CLIP;

     state.clip =  DFB_REGION_INIT_FROM_RECTANGLE_VALS( rect.x, rect.y, rect.w, rect.h );
     src_rect = (DFBRectangle){0, 0, data->width, data->height};

     dfb_state_set_source( &state, data->decode_surface );
     dfb_state_set_destination( &state, dst_surface );

     dfb_gfxcard_batchstretchblit( &src_rect, &rect, 1, &state );

     data->serial = &state.serial;

     dfb_state_set_source(&state, NULL);
     dfb_state_set_destination(&state, NULL);

     dfb_state_destroy(&state);

     if (data->base.render_callback) {
          DFBRectangle r = { 0, 0, data->width, data->height };
          cb_result=data->base.render_callback( &r, data->base.render_callback_context );
     }

     if (cb_result == DIRCR_OK) {
          data->base.buffer->Release( data->base.buffer );
          data->base.buffer = NULL;
     }

     return DFB_OK;

error:
     if (data->decode_surface && lock.pitch)
          dfb_surface_unlock_buffer( data->decode_surface, &lock );

     dfb_surface_unref( data->decode_surface );

     data->base.buffer->Release( data->base.buffer );
     data->base.buffer = NULL;

     return ret;
}