/* * Allocates and initializes a window stack. */ CoreWindowStack* dfb_windowstack_new( DisplayLayer *layer, int width, int height ) { CardCapabilities caps; CoreWindowStack *stack; DFB_ASSERT( layer != NULL ); DFB_ASSERT( width > 0 ); DFB_ASSERT( height > 0 ); /* Allocate window stack data (completely shared) */ stack = (CoreWindowStack*) shcalloc( 1, sizeof(CoreWindowStack) ); /* Remember layer id for access to it's local data later */ stack->layer_id = dfb_layer_id( layer ); /* Choose window surface policy */ if (dfb_config->window_policy != -1) { /* From configuration */ stack->wsp_opaque = stack->wsp_alpha = dfb_config->window_policy; } else { /* Examine hardware capabilities */ caps = dfb_gfxcard_capabilities(); /* If blitting is supported... */ if (caps.accel & DFXL_BLIT) { /* Auto video policy for opaque windows */ stack->wsp_opaque = CSP_VIDEOHIGH; /* If blending is supported, then use auto video policy for alpha windows */ if (caps.blitting & DSBLIT_BLEND_ALPHACHANNEL) stack->wsp_alpha = CSP_VIDEOHIGH; } } /* Create the pool of windows. */ stack->pool = fusion_object_pool_create( "Window Pool", sizeof(CoreWindow), sizeof(DFBWindowEvent), window_destructor ); /* Initialize the modify/update lock */ skirmish_init( &stack->lock ); /* Set default acceleration */ stack->cursor.numerator = 2; stack->cursor.denominator = 1; stack->cursor.threshold = 4; /* Setup size and cursor clipping region */ dfb_windowstack_resize( stack, width, height ); /* Attach to all input devices */ dfb_input_enumerate_devices( stack_attach_devices, stack ); return stack; }
void dfb_window_request_focus( CoreWindow *window ) { CoreWindowStack *stack = window->stack; DFB_ASSERT( !(window->options & DWOP_GHOST) ); stack_lock( stack ); switch_focus( stack, window ); stack_unlock( stack ); }
static void window_remove( CoreWindow *window ) { int i; CoreWindowStack *stack = window->stack; DFBRegion region = { window->x, window->y, window->x + window->width - 1, window->y + window->height - 1 }; DFB_ASSERT( window->stack != NULL ); window_withdraw( window ); for (i=0; i<stack->num_windows; i++) if (stack->windows[i] == window) break; if (i < stack->num_windows) { stack->num_windows--; for (; i<stack->num_windows; i++) stack->windows[i] = stack->windows[i+1]; if (stack->num_windows) { stack->windows = shrealloc( stack->windows, sizeof(CoreWindow*) * stack->num_windows ); } else { shfree( stack->windows ); stack->windows = NULL; } } window->initialized = false; /* If window was visible... */ if (window->opacity) { /* Update the affected region */ repaint_stack( stack, ®ion, 0 ); /* Possibly change focus to window now under the cursor */ handle_enter_leave_focus( stack ); /* Always try to have a focused window */ ensure_focus( stack ); } window->stack = NULL; }
void dfb_windowstack_destroy( CoreWindowStack *stack ) { DFB_ASSERT( stack != NULL ); dfb_input_enumerate_devices( stack_detach_devices, stack ); fusion_object_pool_destroy( stack->pool ); skirmish_destroy( &stack->lock ); if (stack->windows) shfree( stack->windows ); shfree( stack ); }
void dfb_windowstack_resize( CoreWindowStack *stack, int width, int height ) { DFB_ASSERT( stack != NULL ); /* Store the width and height of the stack */ stack->width = width; stack->height = height; /* Setup new cursor clipping region */ stack->cursor.region.x1 = 0; stack->cursor.region.y1 = 0; stack->cursor.region.x2 = width - 1; stack->cursor.region.y2 = height - 1; }
/* * Cede the property allowing others to lease or purchase it. */ FusionResult fusion_property_cede (FusionProperty *property) { pthread_mutex_lock (&property->lock); /* Simple error checking, maybe we should also check the owner. */ DFB_ASSERT( property->state != FUSION_PROPERTY_AVAILABLE ); /* Put back into 'available' state. */ property->state = FUSION_PROPERTY_AVAILABLE; /* Wake up one waiting party if there are any. */ pthread_cond_signal (&property->cond); pthread_mutex_unlock (&property->lock); return FUSION_SUCCESS; }
static void window_withdraw( CoreWindow *window ) { CoreWindowStack *stack = window->stack; DFB_ASSERT( window->stack != NULL ); if (stack->entered_window == window) stack->entered_window = NULL; if (stack->focused_window == window) stack->focused_window = NULL; if (stack->keyboard_window == window) stack->keyboard_window = NULL; if (stack->pointer_window == window) stack->pointer_window = NULL; }
static void window_insert( CoreWindow *window, int before ) { int i; DFBWindowEvent evt; CoreWindowStack *stack = window->stack; DFB_ASSERT( window->stack != NULL ); if (!window->initialized) { if (before < 0 || before > stack->num_windows) before = stack->num_windows; stack->windows = shrealloc( stack->windows, sizeof(CoreWindow*) * (stack->num_windows+1) ); for (i=stack->num_windows; i>before; i--) stack->windows[i] = stack->windows[i-1]; stack->windows[before] = window; stack->num_windows++; window->initialized = true; } /* Send configuration */ evt.type = DWET_POSITION_SIZE; evt.x = window->x; evt.y = window->y; evt.w = window->width; evt.h = window->height; dfb_window_dispatch( window, &evt ); if (window->opacity) handle_enter_leave_focus( stack ); }
bool wxDfbCheckReturn(DFBResult code) { switch ( code ) { case DFB_OK: return true; // these are programming errors, assert: #define DFB_ASSERT(code) \ case code: \ wxFAIL_MSG( "DirectFB error: " wxT(#code) ); \ return false \ DFB_ASSERT(DFB_DEAD); DFB_ASSERT(DFB_UNSUPPORTED); DFB_ASSERT(DFB_UNIMPLEMENTED); DFB_ASSERT(DFB_INVARG); DFB_ASSERT(DFB_NOIMPL); DFB_ASSERT(DFB_MISSINGFONT); DFB_ASSERT(DFB_THIZNULL); DFB_ASSERT(DFB_INVAREA); DFB_ASSERT(DFB_DESTROYED); DFB_ASSERT(DFB_NOSUCHMETHOD); DFB_ASSERT(DFB_NOSUCHINSTANCE); DFB_ASSERT(DFB_VERSIONMISMATCH); #undef DFB_ASSERT // these are not errors, but valid return codes: case DFB_INTERRUPTED: case DFB_BUFFEREMPTY: return true; default: // FIXME: should handle the errors individually wxLogError(_("DirectFB error %d occured."), (int)code); return false; } }
void dfb_windowstack_handle_motion( CoreWindowStack *stack, int dx, int dy ) { int new_cx, new_cy; DFBWindowEvent we; DFB_ASSERT( stack != NULL ); if (!stack->cursor.enabled) return; new_cx = MIN( stack->cursor.x + dx, stack->cursor.region.x2); new_cy = MIN( stack->cursor.y + dy, stack->cursor.region.y2); new_cx = MAX( new_cx, stack->cursor.region.x1 ); new_cy = MAX( new_cy, stack->cursor.region.y1 ); if (new_cx == stack->cursor.x && new_cy == stack->cursor.y) { stack_unlock( stack ); return; } dx = new_cx - stack->cursor.x; dy = new_cy - stack->cursor.y; stack->cursor.x = new_cx; stack->cursor.y = new_cy; DFB_ASSERT( stack->cursor.window != NULL ); dfb_window_move( stack->cursor.window, dx, dy ); switch (stack->wm_hack) { case 2: { CoreWindow *window = stack->entered_window; if (window && !(window->options & DWOP_KEEP_SIZE)) { int width = window->width + dx; int height = window->height + dy; if (width < 48) width = 48; if (height < 48) height = 48; if (width > 2048) width = 2048; if (height > 2048) height = 2048; if (width != window->width || height != window->height) dfb_window_resize( window, width, height ); } break; } case 1: { CoreWindow *window = stack->entered_window; if (window && !(window->options & DWOP_KEEP_POSITION)) dfb_window_move( window, dx, dy ); break; } case 0: stack_lock( stack ); we.cx = stack->cursor.x; we.cy = stack->cursor.y; if (stack->pointer_window) { we.type = DWET_MOTION; we.x = we.cx - stack->pointer_window->x; we.y = we.cy - stack->pointer_window->y; dfb_window_dispatch( stack->pointer_window, &we ); } else { if (!handle_enter_leave_focus( stack ) && stack->entered_window) { we.type = DWET_MOTION; we.x = we.cx - stack->entered_window->x; we.y = we.cy - stack->entered_window->y; dfb_window_dispatch( stack->entered_window, &we ); } } stack_unlock( stack ); break; default: ; } HEAVYDEBUGMSG("DirectFB/windows: mouse at %d, %d\n", stack->cursor.x, stack->cursor.y); }
static void update_region( CoreWindowStack *stack, CardState *state, int start, int x1, int y1, int x2, int y2 ) { int i = start; DFBRegion region = { x1, y1, x2, y2 }; /* check for empty region */ DFB_ASSERT (x1 <= x2 && y1 <= y2); while (i >= 0) { if (VISIBLE_WINDOW(stack->windows[i])) { int wx2 = stack->windows[i]->x + stack->windows[i]->width - 1; int wy2 = stack->windows[i]->y + stack->windows[i]->height - 1; if (dfb_region_intersect( ®ion, stack->windows[i]->x, stack->windows[i]->y, wx2, wy2 )) break; } i--; } if (i >= 0) { if (TRANSLUCENT_WINDOW(stack->windows[i])) update_region( stack, state, i-1, x1, y1, x2, y2 ); else { /* left */ if (region.x1 != x1) update_region( stack, state, i-1, x1, region.y1, region.x1-1, region.y2 ); /* upper */ if (region.y1 != y1) update_region( stack, state, i-1, x1, y1, x2, region.y1-1 ); /* right */ if (region.x2 != x2) update_region( stack, state, i-1, region.x2+1, region.y1, x2, region.y2 ); /* lower */ if (region.y2 != y2) update_region( stack, state, i-1, x1, region.y2+1, x2, y2 ); } { CoreWindow *window = stack->windows[i]; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; DFBRectangle srect = { region.x1 - window->x, region.y1 - window->y, region.x2 - region.x1 + 1, region.y2 - region.y1 + 1 }; if (window->options & DWOP_ALPHACHANNEL) flags |= DSBLIT_BLEND_ALPHACHANNEL; if (window->opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; if (state->color.a != window->opacity) { state->color.a = window->opacity; state->modified |= SMF_COLOR; } } if (window->options & DWOP_COLORKEYING) { flags |= DSBLIT_SRC_COLORKEY; if (state->src_colorkey != window->color_key) { state->src_colorkey = window->color_key; state->modified |= SMF_SRC_COLORKEY; } } if (state->blittingflags != flags) { state->blittingflags = flags; state->modified |= SMF_BLITTING_FLAGS; } state->source = window->surface; state->modified |= SMF_SOURCE; dfb_gfxcard_blit( &srect, region.x1, region.y1, state ); state->source = NULL; } } else { switch (stack->bg.mode) { case DLBM_COLOR: { DFBRectangle rect = { x1, y1, x2 - x1 + 1, y2 - y1 + 1 }; state->color = stack->bg.color; state->modified |= SMF_COLOR; dfb_gfxcard_fillrectangle( &rect, state ); break; } case DLBM_IMAGE: { DFBRectangle rect = { x1, y1, x2 - x1 + 1, y2 - y1 + 1 }; if (state->blittingflags != DSBLIT_NOFX) { state->blittingflags = DSBLIT_NOFX; state->modified |= SMF_BLITTING_FLAGS; } state->source = stack->bg.image; state->modified |= SMF_SOURCE; dfb_gfxcard_blit( &rect, x1, y1, state ); state->source = NULL; break; } case DLBM_TILE: { DFBRectangle rect = { 0, 0, stack->bg.image->width, stack->bg.image->height }; if (state->blittingflags != DSBLIT_NOFX) { state->blittingflags = DSBLIT_NOFX; state->modified |= SMF_BLITTING_FLAGS; } state->source = stack->bg.image; state->modified |= SMF_SOURCE; dfb_gfxcard_tileblit( &rect, (x1 / rect.w) * rect.w, (y1 / rect.h) * rect.h, (x2 / rect.w + 1) * rect.w, (y2 / rect.h + 1) * rect.h, state ); state->source = NULL; break; } default: ; } } }