DFBResult dfb_state_set_source_mask( CardState *state, CoreSurface *source_mask ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source_mask != source_mask) { if (source_mask && dfb_surface_ref( source_mask )) { D_WARN( "could not ref() source mask" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source_mask) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE_MASK ) ); dfb_surface_unref( state->source_mask ); } state->source_mask = source_mask; state->modified |= SMF_SOURCE_MASK; if (source_mask) { direct_serial_copy( &state->src_mask_serial, &source_mask->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE_MASK ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE_MASK ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult dfb_state_set_source2( CardState *state, CoreSurface *source2 ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source2 != source2) { if (source2 && dfb_surface_ref( source2 )) { D_WARN( "could not ref() source2" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source2) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE2 ) ); dfb_surface_unref( state->source2 ); } state->source2 = source2; state->modified |= SMF_SOURCE2; if (source2) { direct_serial_copy( &state->src2_serial, &source2->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE2 ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE2 ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult dfb_layer_region_activate( CoreLayerRegion *region ) { DFBResult ret; D_ASSERT( region != NULL ); /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; D_ASSUME( ! D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE ) ); if (D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE )) { dfb_layer_region_unlock( region ); return DFB_OK; } /* Realize the region if it's enabled. */ if (D_FLAGS_IS_SET( region->state, CLRSF_ENABLED )) { ret = realize_region( region ); if (ret) { dfb_layer_region_unlock( region ); return ret; } } /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_ACTIVE ); /* Unlock the region. */ dfb_layer_region_unlock( region ); return DFB_OK; }
void dfb_gfx_clear( CoreSurface *surface, CoreSurfaceBufferRole role ) { DFBRectangle rect = { 0, 0, surface->config.size.w, surface->config.size.h }; StateClient *client = state_client_tls.Get(); D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_COLOR | SMF_DESTINATION | SMF_TO ); client->state.clip.x2 = surface->config.size.w - 1; client->state.clip.y2 = surface->config.size.h - 1; client->state.destination = surface; client->state.to = role; client->state.to_eye = DSSE_LEFT; client->state.color.a = 0; client->state.color.r = 0; client->state.color.g = 0; client->state.color.b = 0; client->state.color_index = 0; CoreGraphicsStateClient_FillRectangles( &client->client, &rect, 1 ); CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE ); /* Signal end of sequence. */ dfb_state_stop_drawing( &client->state ); client->state.destination = NULL; }
static DFBResult unrealize_region( CoreLayerRegion *region ) { DFBResult ret; int index; CoreLayer *layer; CoreLayerShared *shared; const DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( fusion_vector_contains( &shared->added_regions, region ) ); index = fusion_vector_index_of( &shared->added_regions, region ); D_DEBUG_AT( Core_Layers, "Removing region (%d, %d - %dx%d) from '%s'.\n", DFB_RECTANGLE_VALS( ®ion->config.dest ), shared->description.name ); /* Remove the region from hardware and driver. */ if (funcs->RemoveRegion) { ret = funcs->RemoveRegion( layer, layer->driver_data, layer->layer_data, region->region_data ); if (ret) { D_DERROR( ret, "Core/Layers: Could not remove region!\n" ); return ret; } } /* Remove the region from the 'added' list. */ fusion_vector_remove( &shared->added_regions, index ); /* Deallocate the driver's region data. */ if (region->region_data) { SHFREE( shared->shmpool, region->region_data ); region->region_data = NULL; } /* Update the region's state. */ D_FLAGS_CLEAR( region->state, CLRSF_REALIZED ); D_FLAGS_SET( region->state, CLRSF_FROZEN ); if (region->surface && region->surface_lock.buffer) { dfb_surface_unlock_buffer( region->surface, ®ion->surface_lock ); dfb_surface_destroy_buffers( region->surface ); } return DFB_OK; }
DFBResult dfb_state_get_acceleration_mask( CardState *state, DFBAccelerationMask *ret_accel ) { DFBAccelerationMask mask = DFXL_NONE; D_MAGIC_ASSERT( state, CardState ); D_ASSERT( ret_accel != NULL ); dfb_state_lock( state ); /* Check drawing functions */ if (dfb_gfxcard_state_check( state, DFXL_FILLRECTANGLE )) D_FLAGS_SET( mask, DFXL_FILLRECTANGLE ); if (dfb_gfxcard_state_check( state, DFXL_DRAWRECTANGLE )) D_FLAGS_SET( mask, DFXL_DRAWRECTANGLE ); if (dfb_gfxcard_state_check( state, DFXL_DRAWLINE )) D_FLAGS_SET( mask, DFXL_DRAWLINE ); if (dfb_gfxcard_state_check( state, DFXL_FILLTRIANGLE )) D_FLAGS_SET( mask, DFXL_FILLTRIANGLE ); if (dfb_gfxcard_state_check( state, DFXL_FILLTRAPEZOID )) D_FLAGS_SET( mask, DFXL_FILLTRAPEZOID ); /* Check blitting functions */ if (state->source) { if (dfb_gfxcard_state_check( state, DFXL_BLIT )) D_FLAGS_SET( mask, DFXL_BLIT ); if (dfb_gfxcard_state_check( state, DFXL_STRETCHBLIT )) D_FLAGS_SET( mask, DFXL_STRETCHBLIT ); if (dfb_gfxcard_state_check( state, DFXL_TEXTRIANGLES )) D_FLAGS_SET( mask, DFXL_TEXTRIANGLES ); } /* Check blitting functions */ if (state->source2) { if (dfb_gfxcard_state_check( state, DFXL_BLIT2 )) D_FLAGS_SET( mask, DFXL_BLIT2 ); } dfb_state_unlock( state ); *ret_accel = mask; return DFB_OK; }
void dfb_gfx_copy_regions_stereo( CoreSurface *source, CoreSurfaceBufferRole from, DFBSurfaceStereoEye source_eye, CoreSurface *destination, CoreSurfaceBufferRole to, DFBSurfaceStereoEye destination_eye, const DFBRegion *regions, unsigned int num, int x, int y ) { unsigned int i, n = 0; DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h }; DFBRectangle rects[num]; DFBPoint points[num]; D_ASSERT( !dfb_config->task_manager ); for (i=0; i<num; i++) { DFB_REGION_ASSERT( ®ions[i] ); rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( ®ions[i] ); if (dfb_rectangle_intersect( &rects[n], &rect )) { points[n].x = x + rects[n].x - rect.x; points[n].y = y + rects[n].y - rect.y; n++; } } if (n > 0) { StateClient *client = state_client_tls.Get(); D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO ); client->state.clip.x2 = destination->config.size.w - 1; client->state.clip.y2 = destination->config.size.h - 1; client->state.source = source; client->state.destination = destination; client->state.from = from; client->state.from_eye = source_eye; client->state.to = to; client->state.to_eye = destination_eye; CoreGraphicsStateClient_Blit( &client->client, rects, points, n ); CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE ); /* Signal end of sequence. */ dfb_state_stop_drawing( &client->state ); client->state.destination = NULL; client->state.source = NULL; } }
DFBResult unique_decoration_destroy( UniqueDecoration *decoration ) { D_MAGIC_ASSERT( decoration, UniqueDecoration ); D_FLAGS_SET( decoration->flags, UDF_DESTROYED ); unique_decoration_notify( decoration, UDNF_DESTROYED ); return DFB_OK; }
static void i830_init_ringbuffer( I830DriverData *idrv, I830DeviceData *idev ) { u32 ring_enabled; D_DEBUG_AT( I830_Ring, "Previous lp ring config: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", i830_readl(idrv->mmio_base, LP_RING), i830_readl(idrv->mmio_base, LP_RING + RING_HEAD), i830_readl(idrv->mmio_base, LP_RING + RING_START), i830_readl(idrv->mmio_base, LP_RING + RING_LEN) ); ring_enabled = i830_readl(idrv->mmio_base, LP_RING + RING_LEN) & 1; if (ring_enabled) i830_wait_for_blit_idle(idrv, idev); i830_lring_enable(idrv, 0); idev->lring1 = i830_readl(idrv->mmio_base, LP_RING); idev->lring2 = i830_readl(idrv->mmio_base, LP_RING + RING_HEAD); idev->lring3 = i830_readl(idrv->mmio_base, LP_RING + RING_START); idev->lring4 = i830_readl(idrv->mmio_base, LP_RING + RING_LEN); D_FLAGS_SET( idrv->flags, I830RES_STATE_SAVE ); i830_writel(idrv->mmio_base, LP_RING + RING_LEN, 0); i830_writel(idrv->mmio_base, LP_RING + RING_HEAD, 0); i830_writel(idrv->mmio_base, LP_RING + RING_TAIL, 0); i830_writel(idrv->mmio_base, LP_RING + RING_START, 0); D_DEBUG_AT( I830_Ring, "INST_DONE: 0x%04x\n", i830_readw(idrv->mmio_base, INST_DONE) ); idev->lp_ring.size = RINGBUFFER_SIZE; idev->lp_ring.tail_mask = idev->lp_ring.size - 1; i830_writel( idrv->mmio_base, LP_RING + RING_START, (idev->lring_bind.pg_start * 4096) & I830_RING_START_MASK ); i830_writel( idrv->mmio_base, LP_RING + RING_LEN, (idev->lp_ring.size - 4096) & I830_RING_NR_PAGES ); i830_lring_enable(idrv, 1); D_DEBUG_AT( I830_Ring, "Wrote lp ring config: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", i830_readl(idrv->mmio_base, LP_RING), i830_readl(idrv->mmio_base, LP_RING + RING_HEAD), i830_readl(idrv->mmio_base, LP_RING + RING_START), i830_readl(idrv->mmio_base, LP_RING + RING_LEN) ); }
void dfb_gfx_copy_stereo( CoreSurface *source, DFBSurfaceStereoEye source_eye, CoreSurface *destination, DFBSurfaceStereoEye destination_eye, const DFBRectangle *rect, int x, int y, bool from_back ) { DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h }; StateClient *client = state_client_tls.Get(); D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO ); client->state.clip.x2 = destination->config.size.w - 1; client->state.clip.y2 = destination->config.size.h - 1; client->state.source = source; client->state.destination = destination; client->state.from = from_back ? CSBR_BACK : CSBR_FRONT; client->state.from_eye = source_eye; client->state.to = CSBR_BACK; client->state.to_eye = destination_eye; if (rect) { if (dfb_rectangle_intersect( &sourcerect, rect )) { DFBPoint point = { x + sourcerect.x - rect->x, y + sourcerect.y - rect->y }; CoreGraphicsStateClient_Blit( &client->client, &sourcerect, &point, 1 ); } } else { DFBPoint point = { x, y }; CoreGraphicsStateClient_Blit( &client->client, &sourcerect, &point, 1 ); } CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE ); /* Signal end of sequence. */ dfb_state_stop_drawing( &client->state ); client->state.destination = NULL; client->state.source = NULL; }
void dfb_gfx_stretch_stereo( CoreSurface *source, DFBSurfaceStereoEye source_eye, CoreSurface *destination, DFBSurfaceStereoEye destination_eye, const DFBRectangle *srect, const DFBRectangle *drect, bool from_back ) { DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h }; DFBRectangle destrect = { 0, 0, destination->config.size.w, destination->config.size.h }; D_ASSERT( !dfb_config->task_manager ); if (srect) { if (!dfb_rectangle_intersect( &sourcerect, srect )) return; } if (drect) { if (!dfb_rectangle_intersect( &destrect, drect )) return; } StateClient *client = state_client_tls.Get(); D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO ); client->state.clip.x2 = destination->config.size.w - 1; client->state.clip.y2 = destination->config.size.h - 1; client->state.source = source; client->state.destination = destination; client->state.from = from_back ? CSBR_BACK : CSBR_FRONT; client->state.from_eye = source_eye; client->state.to = CSBR_BACK; client->state.to_eye = destination_eye; CoreGraphicsStateClient_StretchBlit( &client->client, &sourcerect, &destrect, 1 ); CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE ); /* Signal end of sequence. */ dfb_state_stop_drawing( &client->state ); client->state.destination = NULL; client->state.source = NULL; }
DFBResult dfb_state_set_source_2( CardState *state, CoreSurface *source, u32 flip_count ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source != source || state->source_flip_count != flip_count || !state->source_flip_count_used) { bool ref = true;//!fusion_config->secure_fusion || dfb_core_is_master( core_dfb ); if (source && ref && dfb_surface_ref( source )) { D_WARN( "could not ref() source" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE ) ); if (ref) dfb_surface_unref( state->source ); } state->source = source; state->modified |= SMF_SOURCE; state->source_flip_count = flip_count; state->source_flip_count_used = true; if (source) { direct_serial_copy( &state->src_serial, &source->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult dfb_state_set_destination( CardState *state, CoreSurface *destination ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); D_ASSUME( !(state->flags & CSF_DRAWING) ); if (state->destination != destination) { if (destination) { if (dfb_surface_ref( destination )) { D_WARN( "could not ref() destination" ); dfb_state_unlock( state ); return DFB_DEAD; } validate_clip( state, destination->config.size.w - 1, destination->config.size.h - 1, false ); } if (state->destination) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_DESTINATION ) ); dfb_surface_unref( state->destination ); } state->destination = destination; state->modified |= SMF_DESTINATION; if (destination) { direct_serial_copy( &state->dst_serial, &destination->serial ); D_FLAGS_SET( state->flags, CSF_DESTINATION ); } else D_FLAGS_CLEAR( state->flags, CSF_DESTINATION ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult dfb_state_set_source2( CardState *state, CoreSurface *source2 ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source2 != source2) { bool ref = true;//!fusion_config->secure_fusion || dfb_core_is_master( core_dfb ); if (source2 && ref && dfb_surface_ref( source2 )) { D_WARN( "could not ref() source2" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source2) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE2 ) ); if (ref) dfb_surface_unref( state->source2 ); } state->source2 = source2; state->modified |= SMF_SOURCE2; if (source2) { direct_serial_copy( &state->src2_serial, &source2->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE2 ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE2 ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult EGLDisplayX11::Surface_Initialise( SurfaceXWindow &surface ) { D_DEBUG_AT( DFBX11_EGLDisplay, "EGL::SurfaceXWindow::%s( %p ) <- window 0x%08lx, handle 0x%08lx (class %d)\n", __FUNCTION__, this, surface.window, surface.parent.native_handle.value, surface.parent.native_handle.clazz ); DFBResult ret; ::Window window = surface.window; bool is_pixmap = false; DFBSurfaceDescription desc; XWindowAttributes attrs; // xcb_generic_error_t *err = NULL; // // D_DEBUG_AT( DFBX11_EGLDisplay, " -> calling xcb_get_window_attributes...\n" ); // xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes( (xcb_connection_t*)display->x11_display, window ); // // D_DEBUG_AT( DFBX11_EGLDisplay, " -> calling xcb_get_window_attributes_reply...\n" ); // xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply( (xcb_connection_t*)display->x11_display, cookie, &err ); // // if (!reply) { // D_ERROR( "DFBEGL/SurfaceXWindow: xcb_get_window_attributes() failed (error code %d)!\n", err ? err->error_code : 0 ); // return DFB_FAILURE; // } // XMapWindow( x11_display, window ); XSync( x11_display, False ); XGetWindowAttributes( x11_display, window, &attrs ); desc.width = attrs.width; desc.height = attrs.height; D_DEBUG_AT( DFBX11_EGLDisplay, " -> size %dx%d\n", desc.width, desc.height ); desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_RESOURCE_ID | DSDESC_HINTS); desc.pixelformat = (attrs.depth == 24) ? DSPF_RGB32 : DSPF_ARGB; desc.caps = DSCAPS_SHARED; desc.resource_id = window; desc.hints = DSHF_NONE; if (surface.parent.native_handle.clazz == DirectFB::EGL::NativeHandle::CLASS_WINDOW) { D_FLAGS_SET( desc.caps, DSCAPS_PRIMARY ); // D_FLAGS_SET( desc.caps, DSCAPS_DOUBLE ); D_FLAGS_SET( desc.hints, DSHF_WINDOW ); } else { is_pixmap = true; } D_DEBUG_AT( DFBX11_EGLDisplay, " -> caps %s\n", *ToString<DFBSurfaceCapabilities>( desc.caps ) ); IDirectFB *dfb = parent.GetDFB(); // dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN ); ret = dfb->CreateSurface( dfb, &desc, &surface.parent.surface ); if (ret) { D_DERROR( ret, "DFBEGL/SurfaceXWindow: IDirectFB::CreateSurface() failed!\n" ); goto error; } ret = surface.parent.surface->Allocate( surface.parent.surface, DSBR_FRONT, DSSE_LEFT, is_pixmap ? "Pixmap/X11" : "Window/X11", window, &surface.allocation ); if (ret) { D_DERROR( ret, "DFBEGL/SurfaceXWindow: IDirectFBSurface::Allocate() failed!\n" ); goto error; } surface.parent.surface->AllowAccess( surface.parent.surface, "*" ); return DFB_OK; error: if (surface.parent.surface) { surface.parent.surface->Release( surface.parent.surface ); surface.parent.surface = NULL; } return ret; }
DirectResult direct_config_set( const char *name, const char *value ) { if (direct_strcmp (name, "disable-module" ) == 0) { if (value) { int n = 0; while (direct_config->disable_module && direct_config->disable_module[n]) n++; direct_config->disable_module = (char**) D_REALLOC( direct_config->disable_module, sizeof(char*) * (n + 2) ); direct_config->disable_module[n] = D_STRDUP( value ); direct_config->disable_module[n+1] = NULL; } else { D_ERROR("Direct/Config '%s': No module name specified!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "module-dir" ) == 0) { if (value) { if (direct_config->module_dir) D_FREE( direct_config->module_dir ); direct_config->module_dir = D_STRDUP( value ); } else { D_ERROR("Direct/Config 'module-dir': No directory name specified!\n"); return DR_INVARG; } } else if (direct_strcmp (name, "memcpy" ) == 0) { if (value) { if (direct_config->memcpy) D_FREE( direct_config->memcpy ); direct_config->memcpy = D_STRDUP( value ); } else { D_ERROR("Direct/Config '%s': No method specified!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "quiet" ) == 0 || strcmp (name, "no-quiet" ) == 0) { /* Enable/disable all at once by default. */ DirectMessageType type = DMT_ALL; /* Find out the specific message type being configured. */ if (value) { if (!strcmp( value, "info" )) type = DMT_INFO; else if (!strcmp( value, "warning" )) type = DMT_WARNING; else if (!strcmp( value, "error" )) type = DMT_ERROR; else if (!strcmp( value, "once" )) type = DMT_ONCE; else if (!strcmp( value, "untested" )) type = DMT_UNTESTED; else if (!strcmp( value, "unimplemented" )) type = DMT_UNIMPLEMENTED; else { D_ERROR( "DirectFB/Config '%s': Unknown message type '%s'!\n", name, value ); return DR_INVARG; } } /* Set/clear the corresponding flag in the configuration. */ if (name[0] == 'q') D_FLAGS_SET( direct_config->quiet, type ); else D_FLAGS_CLEAR( direct_config->quiet, type ); } else if (direct_strcmp (name, "no-quiet" ) == 0) { direct_config->quiet = DMT_NONE; } else if (direct_strcmp (name, "debug" ) == 0) { if (value) { DirectLogDomainConfig config = {0}; if (value[0] && value[1] == ':') { config.level = value[0] - '0' + DIRECT_LOG_DEBUG_0; value += 2; } else config.level = DIRECT_LOG_DEBUG; direct_log_domain_configure( value, &config ); } else if (direct_config->log_level < DIRECT_LOG_DEBUG) direct_config->log_level = DIRECT_LOG_DEBUG; } else if (direct_strcmp (name, "no-debug" ) == 0) { if (value) { DirectLogDomainConfig config = {0}; config.level = DIRECT_LOG_DEBUG_0; direct_log_domain_configure( value, &config ); } else if (direct_config->log_level > DIRECT_LOG_DEBUG_0) direct_config->log_level = DIRECT_LOG_DEBUG_0; } else if (direct_strcmp (name, "log-all" ) == 0) { direct_config->log_all = true; } else if (direct_strcmp (name, "log-none" ) == 0) { direct_config->log_none = true; } else if (direct_strcmp (name, "debugmem" ) == 0) { direct_config->debugmem = true; } else if (direct_strcmp (name, "no-debugmem" ) == 0) { direct_config->debugmem = false; } else if (direct_strcmp (name, "trace" ) == 0) { direct_config->trace = true; } else if (direct_strcmp (name, "no-trace" ) == 0) { direct_config->trace = false; } else if (direct_strcmp (name, "log-file" ) == 0 || strcmp (name, "log-udp" ) == 0) { if (value) { DirectResult ret; DirectLog *log; ret = direct_log_create( strcmp(name,"log-udp") ? DLT_FILE : DLT_UDP, value, &log ); if (ret) return ret; if (direct_config->log) direct_log_destroy( direct_config->log ); direct_config->log = log; direct_log_set_default( log ); } else { if (direct_strcmp(name,"log-udp")) D_ERROR("Direct/Config '%s': No file name specified!\n", name); else D_ERROR("Direct/Config '%s': No host and port specified!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "fatal-level" ) == 0) { if (direct_strcasecmp (value, "none" ) == 0) { direct_config->fatal = DCFL_NONE; } else if (direct_strcasecmp (value, "assert" ) == 0) { direct_config->fatal = DCFL_ASSERT; } else if (direct_strcasecmp (value, "assume" ) == 0) { direct_config->fatal = DCFL_ASSUME; } else { D_ERROR("Direct/Config '%s': Unknown level specified (use 'none', 'assert', 'assume')!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "fatal-break" ) == 0) { direct_config->fatal_break = true; } else if (direct_strcmp (name, "no-fatal-break" ) == 0) { direct_config->fatal_break = false; } else if (direct_strcmp (name, "sighandler" ) == 0) { direct_config->sighandler = true; } else if (direct_strcmp (name, "no-sighandler" ) == 0) { direct_config->sighandler = false; } else if (direct_strcmp (name, "dont-catch" ) == 0) { if (value) { char *signals = D_STRDUP( value ); char *p = NULL, *r, *s = signals; while ((r = direct_strtok_r( s, ",", &p ))) { char *error; unsigned long signum; direct_trim( &r ); signum = direct_strtoul( r, &error, 10 ); if (*error) { D_ERROR( "Direct/Config '%s': Error in number at '%s'!\n", name, error ); D_FREE( signals ); return DR_INVARG; } sigaddset( &direct_config->dont_catch, signum ); s = NULL; } D_FREE( signals ); } else { D_ERROR("Direct/Config '%s': No signals specified!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "thread_block_signals") == 0) { direct_config->thread_block_signals = true; } else if (direct_strcmp (name, "no-thread_block_signals") == 0) { direct_config->thread_block_signals = false; } else if (direct_strcmp (name, "thread-priority-scale" ) == 0) { if (value) { int scale; if (direct_sscanf( value, "%d", &scale ) < 1) { D_ERROR("Direct/Config '%s': Could not parse value!\n", name); return DR_INVARG; } direct_config->thread_priority_scale = scale; } else { D_ERROR("Direct/Config '%s': No value specified!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "thread-priority" ) == 0) { /* Must be moved to lib/direct/conf.c in trunk! */ if (value) { int priority; if (direct_sscanf( value, "%d", &priority ) < 1) { D_ERROR("Direct/Config '%s': Could not parse value!\n", name); return DR_INVARG; } direct_config->thread_priority = priority; } else { D_ERROR("Direct/Config '%s': No value specified!\n", name); return DR_INVARG; } } else if (direct_strcmp (name, "thread-scheduler" ) == 0) { /* Must be moved to lib/direct/conf.c in trunk! */ if (value) { if (direct_strcmp( value, "other" ) == 0) { direct_config->thread_scheduler = DCTS_OTHER; } else if (direct_strcmp( value, "fifo" ) == 0) { direct_config->thread_scheduler = DCTS_FIFO; } else if (direct_strcmp( value, "rr" ) == 0) { direct_config->thread_scheduler = DCTS_RR; } else { D_ERROR( "Direct/Config '%s': Unknown scheduler '%s'!\n", name, value ); return DR_INVARG; } } else { D_ERROR( "Direct/Config '%s': No value specified!\n", name ); return DR_INVARG; } } else if (direct_strcmp (name, "thread-stacksize" ) == 0) { /* Must be moved to lib/direct/conf.c in trunk! */ if (value) { int size; if (direct_sscanf( value, "%d", &size ) < 1) { D_ERROR( "Direct/Config '%s': Could not parse value!\n", name ); return DR_INVARG; } direct_config->thread_stack_size = size; } else { D_ERROR( "Direct/Config '%s': No value specified!\n", name ); return DR_INVARG; } } else return DR_UNSUPPORTED; return DR_OK; }
static DFBResult realize_region( CoreLayerRegion *region ) { DFBResult ret; CoreLayer *layer; CoreLayerShared *shared; DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) ); D_ASSERT( ! D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( ! fusion_vector_contains( &shared->added_regions, region ) ); /* Allocate the driver's region data. */ if (funcs->RegionDataSize) { int size = funcs->RegionDataSize(); if (size > 0) { region->region_data = SHCALLOC( 1, size ); if (!region->region_data) return D_OOSHM(); } } D_DEBUG_AT( Core_Layers, "Adding region (%d, %d - %dx%d) to '%s'.\n", DFB_RECTANGLE_VALS( ®ion->config.dest ), shared->description.name ); /* Add the region to the driver. */ if (funcs->AddRegion) { ret = funcs->AddRegion( layer, layer->driver_data, layer->layer_data, region->region_data, ®ion->config ); if (ret) { D_DERROR( ret, "Core/Layers: Could not add region!\n" ); if (region->region_data) { SHFREE( region->region_data ); region->region_data = NULL; } return ret; } } /* Add the region to the 'added' list. */ fusion_vector_add( &shared->added_regions, region ); /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_REALIZED ); /* Initially setup hardware. */ ret = set_region( region, ®ion->config, CLRCF_ALL, region->surface ); if (ret) { unrealize_region( region ); return ret; } return DFB_OK; }
DFBResult dfb_layer_region_set_configuration( CoreLayerRegion *region, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags flags ) { DFBResult ret; CoreLayer *layer; DisplayLayerFuncs *funcs; CoreLayerRegionConfig new_config; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( config != NULL ); D_ASSERT( config->buffermode != DLBM_WINDOWS ); D_ASSERT( (flags == CLRCF_ALL) || (region->state & CLRSF_CONFIGURED) ); D_ASSUME( flags != CLRCF_NONE ); D_ASSUME( ! (flags & ~CLRCF_ALL) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->funcs != NULL ); D_ASSERT( layer->funcs->TestRegion != NULL ); funcs = layer->funcs; /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; /* Full configuration supplied? */ if (flags == CLRCF_ALL) { new_config = *config; } else { /* Use the current configuration. */ new_config = region->config; /* Update each modified entry. */ if (flags & CLRCF_WIDTH) new_config.width = config->width; if (flags & CLRCF_HEIGHT) new_config.height = config->height; if (flags & CLRCF_FORMAT) new_config.format = config->format; if (flags & CLRCF_SURFACE_CAPS) new_config.surface_caps = config->surface_caps; if (flags & CLRCF_BUFFERMODE) new_config.buffermode = config->buffermode; if (flags & CLRCF_OPTIONS) new_config.options = config->options; if (flags & CLRCF_SOURCE_ID) new_config.source_id = config->source_id; if (flags & CLRCF_SOURCE) new_config.source = config->source; if (flags & CLRCF_DEST) new_config.dest = config->dest; if (flags & CLRCF_OPACITY) new_config.opacity = config->opacity; if (flags & CLRCF_ALPHA_RAMP) { new_config.alpha_ramp[0] = config->alpha_ramp[0]; new_config.alpha_ramp[1] = config->alpha_ramp[1]; new_config.alpha_ramp[2] = config->alpha_ramp[2]; new_config.alpha_ramp[3] = config->alpha_ramp[3]; } if (flags & CLRCF_SRCKEY) new_config.src_key = config->src_key; if (flags & CLRCF_DSTKEY) new_config.dst_key = config->dst_key; if (flags & CLRCF_PARITY) new_config.parity = config->parity; } /* Check if the new configuration is supported. */ ret = funcs->TestRegion( layer, layer->driver_data, layer->layer_data, &new_config, NULL ); if (ret) { dfb_layer_region_unlock( region ); return ret; } /* Propagate new configuration to the driver if the region is realized. */ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { ret = set_region( region, &new_config, flags, region->surface ); if (ret) { dfb_layer_region_unlock( region ); return ret; } } /* Update the region's current configuration. */ region->config = new_config; /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_CONFIGURED ); /* Unlock the region. */ dfb_layer_region_unlock( region ); return DFB_OK; }
static DFBResult i830_agp_setup( CoreGraphicsDevice *device, I830DriverData *idrv, I830DeviceData *idev ) { idrv->agpgart = open("/dev/agpgart", O_RDWR); if (idrv->agpgart == -1) return DFB_IO; D_FLAGS_SET( idrv->flags, I830RES_GART ); if (ioctl(idrv->agpgart, AGPIOC_ACQUIRE)) { D_PERROR( "I830/AGP: AGPIOC_ACQUIRE failed!\n" ); return DFB_IO; } D_FLAGS_SET( idrv->flags, I830RES_GART_ACQ ); if (!idev->initialized) { agp_setup setup; setup.agp_mode = 0; if (ioctl(idrv->agpgart, AGPIOC_SETUP, &setup)) { D_PERROR( "I830/AGP: AGPIOC_SETUP failed!\n" ); return DFB_IO; } if (ioctl(idrv->agpgart, AGPIOC_INFO, &idev->info)) { D_PERROR( "I830/AGP: AGPIOC_INFO failed!\n" ); return DFB_IO; } } idrv->aper_base = mmap( NULL, idev->info.aper_size * 1024 * 1024, PROT_WRITE, MAP_SHARED, idrv->agpgart, 0 ); if (idrv->aper_base == MAP_FAILED) { D_PERROR( "I830/AGP: mmap() failed!\n" ); i830_release_resource( idrv, idev ); return DFB_IO; } D_FLAGS_SET( idrv->flags, I830RES_MMAP ); if (!idev->initialized) { u32 base; /* We'll attempt to bind at fb_base + fb_len + 1 MB, to be safe */ base = dfb_gfxcard_memory_physical(device, 0) - idev->info.aper_base; base += dfb_gfxcard_memory_length(); base += (1024 * 1024); idev->lring_mem.pg_count = RINGBUFFER_SIZE/4096; idev->lring_mem.type = AGP_NORMAL_MEMORY; if (ioctl(idrv->agpgart, AGPIOC_ALLOCATE, &idev->lring_mem)) { D_PERROR( "I830/AGP: AGPIOC_ALLOCATE failed!\n" ); i830_release_resource( idrv, idev ); return DFB_IO; } D_FLAGS_SET( idrv->flags, I830RES_LRING_ACQ ); idev->lring_bind.key = idev->lring_mem.key; idev->lring_bind.pg_start = base/4096; if (ioctl(idrv->agpgart, AGPIOC_BIND, &idev->lring_bind)) { D_PERROR( "I830/AGP: AGPIOC_BIND failed!\n" ); i830_release_resource( idrv, idev ); return DFB_IO; } D_FLAGS_SET( idrv->flags, I830RES_LRING_BIND ); idev->ovl_mem.pg_count = 1; idev->ovl_mem.type = AGP_PHYSICAL_MEMORY; if (ioctl(idrv->agpgart, AGPIOC_ALLOCATE, &idev->ovl_mem)) { D_PERROR( "I830/AGP: AGPIOC_ALLOCATE failed!\n" ); i830_release_resource( idrv, idev ); return DFB_IO; } D_FLAGS_SET( idrv->flags, I830RES_OVL_ACQ ); idev->ovl_bind.key = idev->ovl_mem.key; idev->ovl_bind.pg_start = (base + RINGBUFFER_SIZE)/4096; if (ioctl(idrv->agpgart, AGPIOC_BIND, &idev->ovl_bind)) { D_PERROR( "I830/AGP: AGPIOC_BIND failed!\n" ); i830_release_resource( idrv, idev ); return DFB_IO; } D_FLAGS_SET( idrv->flags, I830RES_OVL_BIND ); } if (idrv->flags & I830RES_GART_ACQ) { ioctl(idrv->agpgart, AGPIOC_RELEASE); idrv->flags &= ~I830RES_GART_ACQ; } idrv->lring_base = idrv->aper_base + idev->lring_bind.pg_start * 4096; idrv->ovl_base = idrv->aper_base + idev->ovl_bind.pg_start * 4096; idrv->pattern_base = idrv->ovl_base + 1024; if (!idev->initialized) { memset((void *) idrv->lring_base, 0x00, RINGBUFFER_SIZE); memset((void *) idrv->ovl_base, 0xff, 1024); memset((void *) idrv->pattern_base, 0xff, 4096 - 1024); idev->lring1 = 0;//i830_readl(idrv->mmio_base, LP_RING); idev->lring2 = 0;//i830_readl(idrv->mmio_base, LP_RING + RING_HEAD); idev->lring3 = 0;//i830_readl(idrv->mmio_base, LP_RING + RING_START); idev->lring4 = 0;//i830_readl(idrv->mmio_base, LP_RING + RING_LEN); } idev->initialized = true; return DFB_OK; }
static DFBResult sh_du_set_region( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags updated, CoreSurface *surface, CorePalette *palette, CoreSurfaceBufferLock *left_lock, CoreSurfaceBufferLock *right_lock ) { DFBResult ret; SHGfxDriverData *drv; SHDuLayerData *lyr; u32 *pal, dirty; D_DEBUG_AT( SH_DU_LAYER, "%s( %u, 0x%x, 0x%lx )\n", __FUNCTION__, dfb_layer_id( layer ), updated, D_FLAGS_IS_SET( updated, CLRCF_SURFACE ) ? left_lock->phys : 0 ); D_UNUSED_P( region_data ); D_UNUSED_P( surface ); D_UNUSED_P( right_lock ); drv = (SHGfxDriverData *)driver_data; lyr = (SHDuLayerData *)layer_data; pal = NULL; dirty = 0u; /* color palette */ if (D_FLAGS_IS_SET( updated, CLRCF_PALETTE ) && palette) { unsigned int i; if (palette->num_entries > 256) return DFB_UNSUPPORTED; pal = malloc(256 * sizeof(u32)); if (!pal) return DFB_NOSYSTEMMEMORY; for (i = 0; i < palette->num_entries; i++) pal[i] = SH_DU_COLOR_TO_PALETTE(palette->entries[i]); while (i < 256) pal[i++] = 0u; } /* buffer address and stride */ if (D_FLAGS_IS_SET( updated, CLRCF_SURFACE )) { u32 stride; stride = (u32)(left_lock->pitch * 8); stride /= DFB_BITS_PER_PIXEL( left_lock->buffer->format ); if (lyr->plane.stride != stride) { lyr->plane.stride = stride; SH_DU_PLANE_SET_DIRTY( dirty, STRIDE ); } if (lyr->plane.pa0 != left_lock->phys) { lyr->plane.pa0 = left_lock->phys; SH_DU_PLANE_SET_DIRTY( dirty, PA0 ); } } /* area */ if (D_FLAGS_IS_SET( updated, CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_SOURCE | CLRCF_DEST )) { u32 sx, sy, dx, dy, w, h; if (D_FLAGS_IS_SET( updated, CLRCF_WIDTH )) { D_ASSERT( config->width > 0 ); lyr->width = config->width; } if (D_FLAGS_IS_SET( updated, CLRCF_HEIGHT )) { D_ASSERT( config->height > 0 ); lyr->height = config->height; } if (D_FLAGS_IS_SET( updated, CLRCF_SOURCE )) { D_ASSERT( config->source.x >= 0 ); D_ASSERT( config->source.y >= 0 ); lyr->sx = config->source.x; lyr->sy = config->source.y; } if (D_FLAGS_IS_SET( updated, CLRCF_DEST )) { lyr->dx = config->dest.x; lyr->dy = config->dest.y; } if (lyr->dx >= 0) { w = (u32)lyr->width; sx = (u32)lyr->sx; dx = (u32)lyr->dx; } else { w = (lyr->width + lyr->dx) <= 0 ? 0u : (u32)(lyr->width + lyr->dx); sx = (u32)(lyr->sx - lyr->dx); dx = 0u; } if (lyr->dy >= 0) { h = (u32)lyr->height; sy = (u32)lyr->sy; dy = (u32)lyr->dy; } else { h = (lyr->height + lyr->dy) <= 0 ? 0u : (u32)(lyr->height + lyr->dy); sy = (u32)(lyr->sy - lyr->dy); dy = 0u; } if (lyr->plane.width != w) { lyr->plane.width = w; SH_DU_PLANE_SET_DIRTY( dirty, WIDTH ); } if (lyr->plane.height != h) { lyr->plane.height = h; SH_DU_PLANE_SET_DIRTY( dirty, HEIGHT ); } if (lyr->plane.sx != sx) { lyr->plane.sx = sx; SH_DU_PLANE_SET_DIRTY( dirty, SX ); } if (lyr->plane.sy != sy) { lyr->plane.sy = sy; SH_DU_PLANE_SET_DIRTY( dirty, SY ); } if (lyr->plane.dx != dx) { lyr->plane.dx = dx; SH_DU_PLANE_SET_DIRTY( dirty, DX ); } if (lyr->plane.dy != dy) { lyr->plane.dy = dy; SH_DU_PLANE_SET_DIRTY( dirty, DY ); } } /* mode and opacity */ if (D_FLAGS_IS_SET( updated, CLRCF_FORMAT | CLRCF_OPTIONS | CLRCF_OPACITY )) { u32 mode, opacity; mode = lyr->plane.mode; opacity = lyr->plane.opacity; if (D_FLAGS_IS_SET( updated, CLRCF_OPACITY )) lyr->opacity = config->opacity; if (D_FLAGS_IS_SET( updated, CLRCF_OPTIONS )) { if (D_FLAGS_IS_SET( config->options, DLOP_ALPHACHANNEL )) { D_FLAGS_SET( mode, SH_DU_PMR_BLEND ); D_FLAGS_CLEAR( opacity, SH_DU_PALPHAR_ABIT_IGNORE ); D_FLAGS_SET( opacity, SH_DU_PALPHAR_PALETTE ); } else if (D_FLAGS_IS_SET( config->options, DLOP_OPACITY )) { D_FLAGS_SET( mode, SH_DU_PMR_BLEND ); D_FLAGS_SET( opacity, SH_DU_PALPHAR_ABIT_IGNORE ); D_FLAGS_CLEAR( opacity, SH_DU_PALPHAR_PALETTE ); } else { D_FLAGS_CLEAR( mode, SH_DU_PMR_BLEND ); } if (D_FLAGS_IS_SET( config->options, DLOP_SRC_COLORKEY )) D_FLAGS_CLEAR( mode, SH_DU_PMR_NOSRCKEY ); else D_FLAGS_SET( mode, SH_DU_PMR_NOSRCKEY ); } if (D_FLAGS_IS_SET( updated, CLRCF_FORMAT )) { mode &= ~SH_DU_PMR_DDF_MASK; switch (config->format) { case DSPF_RGB16: mode |= SH_DU_PMR_DDF565; break; case DSPF_ARGB1555: mode |= SH_DU_PMR_DDF1555; break; default: D_ASSERT( config->format == DSPF_LUT8 ); mode |= SH_DU_PMR_DDF8; break; } } if (D_FLAGS_IS_SET( mode, SH_DU_PMR_BLEND )) { if (D_FLAGS_IS_SET( opacity, SH_DU_PALPHAR_PALETTE )) /* pixel alpha blending */ opacity |= SH_DU_PALPHAR_ALPHA_MASK; else /* const alpha blending */ opacity = (opacity & ~SH_DU_PALPHAR_ALPHA_MASK) | (u32)lyr->opacity; } if (lyr->plane.opacity != opacity) { lyr->plane.opacity = opacity; SH_DU_PLANE_SET_DIRTY( dirty, OPACITY ); } if (lyr->plane.mode != mode) { lyr->plane.mode = mode; SH_DU_PLANE_SET_DIRTY( dirty, MODE ); } } /* src color key */ if (D_FLAGS_IS_SET( updated, CLRCF_SRCKEY )) lyr->ckey = config->src_key; if (D_FLAGS_IS_SET( updated, CLRCF_SRCKEY | CLRCF_FORMAT )) { u32 ddf, ckey; ddf = lyr->plane.mode & SH_DU_PMR_DDF_MASK; if (ddf == SH_DU_PMR_DDF8) { ckey = (u32)lyr->ckey.index; if (lyr->plane.ckey8 != ckey) { lyr->plane.ckey8 = ckey; SH_DU_PLANE_SET_DIRTY( dirty, CKEY8 ); } } else { ckey = (ddf == SH_DU_PMR_DDF565) ? SH_DU_COLORKEY_TO_RGB565( lyr->ckey ) : SH_DU_COLORKEY_TO_ARGB1555( lyr->ckey ); if (lyr->plane.ckey16 != ckey) { lyr->plane.ckey16 = ckey; SH_DU_PLANE_SET_DIRTY( dirty, CKEY16 ); } } } ret = (dirty || pal) ? update_layer( drv, lyr, dirty, pal ) : DFB_OK; if (pal) free( pal ); return ret; }
static void back_to_front_copy( CoreSurface *surface, DFBSurfaceStereoEye eye, const DFBRegion *region, DFBSurfaceBlittingFlags flags, int rotation) { DFBRectangle rect; DFBPoint point; StateClient *client = state_client_tls.Get(); if (region) { rect.x = region->x1; rect.y = region->y1; rect.w = region->x2 - region->x1 + 1; rect.h = region->y2 - region->y1 + 1; } else { rect.x = 0; rect.y = 0; rect.w = surface->config.size.w; rect.h = surface->config.size.h; } point.x = rect.x; point.y = rect.y; if (rotation == 90) { point.x = rect.y; point.y = surface->config.size.w - rect.w - rect.x; D_FLAGS_SET( flags, DSBLIT_ROTATE90 ); } else if (rotation == 180) { point.x = surface->config.size.w - rect.w - rect.x; point.y = surface->config.size.h - rect.h - rect.y; D_FLAGS_SET( flags, DSBLIT_ROTATE180 ); } else if (rotation == 270) { point.x = surface->config.size.h - rect.h - rect.y; point.y = rect.x; D_FLAGS_SET( flags, DSBLIT_ROTATE270 ); } D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO ); client->state.clip.x2 = surface->config.size.w - 1; client->state.clip.y2 = surface->config.size.h - 1; client->state.source = surface; client->state.destination = surface; client->state.from = CSBR_BACK; client->state.from_eye = eye; client->state.to = CSBR_FRONT; client->state.to_eye = eye; client->state.blittingflags = flags; CoreGraphicsStateClient_Blit( &client->client, &rect, &point, 1 ); CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_FOLLOW_READER ); /* Signal end of sequence. */ dfb_state_stop_drawing( &client->state ); client->state.destination = NULL; client->state.source = NULL; }
void dfb_gfx_copy_regions_client( CoreSurface *source, CoreSurfaceBufferRole from, DFBSurfaceStereoEye source_eye, CoreSurface *destination, CoreSurfaceBufferRole to, DFBSurfaceStereoEye destination_eye, const DFBRegion *regions, unsigned int num, int x, int y, CoreGraphicsStateClient *_client ) { unsigned int i, n = 0; DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h }; DFBRectangle rects[num]; DFBPoint points[num]; CoreGraphicsStateClient *client = _client ? _client : &state_client_tls.Get()->client; CardState *state = client->state; CardState backup; for (i=0; i<num; i++) { DFB_REGION_ASSERT( ®ions[i] ); rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( ®ions[i] ); if (dfb_rectangle_intersect( &rects[n], &rect )) { points[n].x = x + rects[n].x; points[n].y = y + rects[n].y; n++; } } if (n > 0) { backup.clip = state->clip; backup.source = state->source; backup.destination = state->destination; backup.from = state->from; backup.from_eye = state->from_eye; backup.to = state->to; backup.to_eye = state->to_eye; backup.blittingflags = state->blittingflags; D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS ); state->clip.x1 = 0; state->clip.y1 = 0; state->clip.x2 = destination->config.size.w - 1; state->clip.y2 = destination->config.size.h - 1; state->source = source; state->destination = destination; state->from = from; state->from_eye = source_eye; state->to = to; state->to_eye = destination_eye; state->blittingflags = DSBLIT_NOFX; CoreGraphicsStateClient_Blit( client, rects, points, n ); if (!_client) CoreGraphicsStateClient_Flush( client, 0, CGSCFF_NONE ); D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS ); state->clip = backup.clip; state->source = backup.source; state->destination = backup.destination; state->from = backup.from; state->from_eye = backup.from_eye; state->to = backup.to; state->to_eye = backup.to_eye; state->blittingflags = backup.blittingflags; } }