mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 21:34:09 +00:00
onscreen: Adds support for resizable windows
This adds api to be able to request that the window system allows a given onscreen framebuffer to be resizable, and api to add and remove resize handlers to be called whenever the framebuffer does actually change size. The new functions are: cogl_onscreen_{get,set}_resizable() cogl_onscreen_{add,remove}_resize_handler() The examples cogl-hello and cogl-x11-foreign have been updated to use the new api. To smoke test how Cogl updates the viewport automatically in response to window resizes the cogl-hello test doesn't explicitly respond to resize events by setting the viewport and cogl-x11-foreign responds by setting a viewport that is offset by a quarter of the window's width/height and half the width and height of the window. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit a1a8cc00bfa2cecaf1007aec5f3dd95dc07b1786)
This commit is contained in:
parent
72f992effe
commit
df51574116
@ -51,6 +51,7 @@ typedef struct _CoglGLXDisplay
|
|||||||
GLXWindow dummy_glxwin;
|
GLXWindow dummy_glxwin;
|
||||||
Window dummy_xwin;
|
Window dummy_xwin;
|
||||||
CoglBool pending_swap_notify;
|
CoglBool pending_swap_notify;
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
} CoglGLXDisplay;
|
} CoglGLXDisplay;
|
||||||
|
|
||||||
#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */
|
#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */
|
||||||
|
@ -46,6 +46,19 @@ struct _CoglSwapBuffersNotifyEntry
|
|||||||
unsigned int id;
|
unsigned int id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _CoglResizeNotifyEntry CoglResizeNotifyEntry;
|
||||||
|
|
||||||
|
COGL_TAILQ_HEAD (CoglResizeNotifyList, CoglResizeNotifyEntry);
|
||||||
|
|
||||||
|
struct _CoglResizeNotifyEntry
|
||||||
|
{
|
||||||
|
COGL_TAILQ_ENTRY (CoglResizeNotifyEntry) list_node;
|
||||||
|
|
||||||
|
CoglOnscreenResizeCallback callback;
|
||||||
|
void *user_data;
|
||||||
|
unsigned int id;
|
||||||
|
};
|
||||||
|
|
||||||
struct _CoglOnscreen
|
struct _CoglOnscreen
|
||||||
{
|
{
|
||||||
CoglFramebuffer _parent;
|
CoglFramebuffer _parent;
|
||||||
@ -64,6 +77,9 @@ struct _CoglOnscreen
|
|||||||
|
|
||||||
CoglSwapBuffersNotifyList swap_callbacks;
|
CoglSwapBuffersNotifyList swap_callbacks;
|
||||||
|
|
||||||
|
CoglBool resizable;
|
||||||
|
CoglResizeNotifyList resize_callbacks;
|
||||||
|
|
||||||
void *winsys;
|
void *winsys;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,4 +93,7 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
|
|||||||
void
|
void
|
||||||
_cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen);
|
_cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_onscreen_notify_resize (CoglOnscreen *onscreen);
|
||||||
|
|
||||||
#endif /* __COGL_ONSCREEN_PRIVATE_H */
|
#endif /* __COGL_ONSCREEN_PRIVATE_H */
|
||||||
|
@ -46,6 +46,7 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
|
|||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
COGL_TAILQ_INIT (&onscreen->swap_callbacks);
|
COGL_TAILQ_INIT (&onscreen->swap_callbacks);
|
||||||
|
COGL_TAILQ_INIT (&onscreen->resize_callbacks);
|
||||||
|
|
||||||
framebuffer->config = onscreen_template->config;
|
framebuffer->config = onscreen_template->config;
|
||||||
cogl_object_ref (framebuffer->config.swap_chain);
|
cogl_object_ref (framebuffer->config.swap_chain);
|
||||||
@ -113,6 +114,13 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
|
|||||||
{
|
{
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
||||||
|
CoglResizeNotifyEntry *resize_entry;
|
||||||
|
|
||||||
|
while ((resize_entry = COGL_TAILQ_FIRST (&onscreen->resize_callbacks)))
|
||||||
|
{
|
||||||
|
COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, resize_entry, list_node);
|
||||||
|
g_slice_free (CoglResizeNotifyEntry, resize_entry);
|
||||||
|
}
|
||||||
|
|
||||||
if (framebuffer->context->window_buffer == COGL_FRAMEBUFFER (onscreen))
|
if (framebuffer->context->window_buffer == COGL_FRAMEBUFFER (onscreen))
|
||||||
framebuffer->context->window_buffer = NULL;
|
framebuffer->context->window_buffer = NULL;
|
||||||
@ -346,6 +354,22 @@ _cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen)
|
|||||||
entry->callback (COGL_FRAMEBUFFER (onscreen), entry->user_data);
|
entry->callback (COGL_FRAMEBUFFER (onscreen), entry->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_onscreen_notify_resize (CoglOnscreen *onscreen)
|
||||||
|
{
|
||||||
|
CoglResizeNotifyEntry *entry, *tmp;
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
|
COGL_TAILQ_FOREACH_SAFE (entry,
|
||||||
|
&onscreen->resize_callbacks,
|
||||||
|
list_node,
|
||||||
|
tmp)
|
||||||
|
entry->callback (onscreen,
|
||||||
|
framebuffer->width,
|
||||||
|
framebuffer->height,
|
||||||
|
entry->user_data);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
|
_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
@ -356,11 +380,78 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
|
|||||||
framebuffer->width = width;
|
framebuffer->width = width;
|
||||||
framebuffer->height = height;
|
framebuffer->height = height;
|
||||||
|
|
||||||
/* The framebuffer geometry can affect the GL viewport so if the
|
framebuffer->viewport_x = 0;
|
||||||
* framebuffer being updated is the current framebuffer we mark the
|
framebuffer->viewport_y = 0;
|
||||||
* viewport state as changed so it will be updated the next time
|
framebuffer->viewport_width = width;
|
||||||
* _cogl_framebuffer_flush_state() is called. */
|
framebuffer->viewport_height = height;
|
||||||
|
|
||||||
|
/* If the framebuffer being updated is the current framebuffer we
|
||||||
|
* mark the viewport state as changed so it will be updated the next
|
||||||
|
* time _cogl_framebuffer_flush_state() is called. */
|
||||||
if (framebuffer->context->current_draw_buffer == framebuffer)
|
if (framebuffer->context->current_draw_buffer == framebuffer)
|
||||||
framebuffer->context->current_draw_buffer_changes |=
|
framebuffer->context->current_draw_buffer_changes |=
|
||||||
COGL_FRAMEBUFFER_STATE_VIEWPORT;
|
COGL_FRAMEBUFFER_STATE_VIEWPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_onscreen_set_resizable (CoglOnscreen *onscreen,
|
||||||
|
CoglBool resizable)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer;
|
||||||
|
const CoglWinsysVtable *winsys;
|
||||||
|
|
||||||
|
if (onscreen->resizable == resizable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
onscreen->resizable = resizable;
|
||||||
|
|
||||||
|
framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
if (framebuffer->allocated)
|
||||||
|
{
|
||||||
|
winsys = _cogl_framebuffer_get_winsys (COGL_FRAMEBUFFER (onscreen));
|
||||||
|
|
||||||
|
if (winsys->onscreen_set_resizable)
|
||||||
|
winsys->onscreen_set_resizable (onscreen, resizable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglBool
|
||||||
|
cogl_onscreen_get_resizable (CoglOnscreen *onscreen)
|
||||||
|
{
|
||||||
|
return onscreen->resizable;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
|
||||||
|
CoglOnscreenResizeCallback callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
CoglResizeNotifyEntry *entry = g_slice_new (CoglResizeNotifyEntry);
|
||||||
|
static int next_resize_callback_id = 0;
|
||||||
|
|
||||||
|
entry->callback = callback;
|
||||||
|
entry->user_data = user_data;
|
||||||
|
entry->id = next_resize_callback_id++;
|
||||||
|
|
||||||
|
COGL_TAILQ_INSERT_TAIL (&onscreen->resize_callbacks, entry, list_node);
|
||||||
|
|
||||||
|
return entry->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
|
||||||
|
unsigned int id)
|
||||||
|
{
|
||||||
|
CoglResizeNotifyEntry *entry;
|
||||||
|
|
||||||
|
COGL_TAILQ_FOREACH (entry, &onscreen->resize_callbacks, list_node)
|
||||||
|
{
|
||||||
|
if (entry->id == id)
|
||||||
|
{
|
||||||
|
COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, entry, list_node);
|
||||||
|
g_slice_free (CoglResizeNotifyEntry, entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -380,6 +380,144 @@ void
|
|||||||
cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
|
cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
|
||||||
unsigned int id);
|
unsigned int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_set_resizable:
|
||||||
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
|
*
|
||||||
|
* Lets you request Cogl to mark an @onscreen framebuffer as
|
||||||
|
* resizable or not.
|
||||||
|
*
|
||||||
|
* By default, if possible, a @onscreen will be created by Cogl
|
||||||
|
* as non resizable, but it is not guaranteed that this is always
|
||||||
|
* possible for all window systems.
|
||||||
|
*
|
||||||
|
* <note>Cogl does not know whether marking the @onscreen framebuffer
|
||||||
|
* is truly meaningful for your current window system (consider
|
||||||
|
* applications being run fullscreen on a phone or TV) so this
|
||||||
|
* function may not have any useful effect. If you are running on a
|
||||||
|
* multi windowing system such as X11 or Win32 or OSX then Cogl will
|
||||||
|
* request to the window system that users be allowed to resize the
|
||||||
|
* @onscreen, although it's still possible that some other window
|
||||||
|
* management policy will block this possibility.</note>
|
||||||
|
*
|
||||||
|
* <note>Whenever an @onscreen framebuffer is resized the viewport
|
||||||
|
* will be automatically updated to match the new size of the
|
||||||
|
* framebuffer with an origin of (0,0). If your application needs more
|
||||||
|
* specialized control of the viewport it will need to register a
|
||||||
|
* resize handler using cogl_onscreen_add_resize_handler() so that it
|
||||||
|
* can track when the viewport has been changed automatically.</note>
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_onscreen_set_resizable (CoglOnscreen *onscreen,
|
||||||
|
CoglBool resizable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_get_resizable:
|
||||||
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
|
*
|
||||||
|
* Lets you query whether @onscreen has been marked as resizable via
|
||||||
|
* the cogl_onscreen_set_resizable() api.
|
||||||
|
*
|
||||||
|
* By default, if possible, a @onscreen will be created by Cogl
|
||||||
|
* as non resizable, but it is not guaranteed that this is always
|
||||||
|
* possible for all window systems.
|
||||||
|
*
|
||||||
|
* <note>If cogl_onscreen_set_resizable(@onscreen, %TRUE) has been
|
||||||
|
* previously called then this function will return %TRUE, but it's
|
||||||
|
* possible that the current windowing system being used does not
|
||||||
|
* support window resizing (consider fullscreen windows on a phone or
|
||||||
|
* a TV). This function is not aware of whether resizing is truly
|
||||||
|
* meaningful with your window system, only whether the @onscreen has
|
||||||
|
* been marked as resizable.</note>
|
||||||
|
*
|
||||||
|
* Return value: Returns whether @onscreen has been marked as
|
||||||
|
* resizable or not.
|
||||||
|
* Since: 2.0
|
||||||
|
*/
|
||||||
|
CoglBool
|
||||||
|
cogl_onscreen_get_resizable (CoglOnscreen *onscreen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CoglOnscreenResizeCallback:
|
||||||
|
* @onscreen: A #CoglOnscreen framebuffer that was resized
|
||||||
|
* @width: The new width of @onscreen
|
||||||
|
* @height: The new height of @onscreen
|
||||||
|
* @user_data: The private passed to
|
||||||
|
* cogl_onscreen_add_resize_handler()
|
||||||
|
*
|
||||||
|
* Is a callback type used with the
|
||||||
|
* cogl_onscreen_add_resize_handler() allowing applications to be
|
||||||
|
* notified whenever an @onscreen framebuffer is resized.
|
||||||
|
*
|
||||||
|
* <note>Cogl automatically updates the viewport of an @onscreen
|
||||||
|
* framebuffer that is resized so this callback is also an indication
|
||||||
|
* that the viewport has been modified too</note>
|
||||||
|
*
|
||||||
|
* <note>A resize callback will only ever be called while dispatching
|
||||||
|
* Cogl events from the system mainloop; so for example during
|
||||||
|
* cogl_poll_dispatch(). This is so that callbacks shouldn't occur
|
||||||
|
* while an application might have arbitrary locks held for
|
||||||
|
* example.</note>
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
*/
|
||||||
|
typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_add_resize_handler:
|
||||||
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
|
* @callback: A #CoglOnscreenResizeCallback to call when the @onscreen
|
||||||
|
* changes size.
|
||||||
|
* @user_data: Private data to be passed to @callback.
|
||||||
|
*
|
||||||
|
* Registers a @callback with @onscreen that will be called whenever
|
||||||
|
* the @onscreen framebuffer changes size.
|
||||||
|
*
|
||||||
|
* The @callback can be removed using
|
||||||
|
* cogl_onscreen_remove_resize_handler() passing the same @callback
|
||||||
|
* and @user_data pair.
|
||||||
|
*
|
||||||
|
* <note>Since Cogl automatically updates the viewport of an @onscreen
|
||||||
|
* framebuffer that is resized, a resize callback can also be used to
|
||||||
|
* track when the viewport has been changed automatically by Cogl in
|
||||||
|
* case your application needs more specialized control over the
|
||||||
|
* viewport.</note>
|
||||||
|
*
|
||||||
|
* <note>A resize callback will only ever be called while dispatching
|
||||||
|
* Cogl events from the system mainloop; so for example during
|
||||||
|
* cogl_poll_dispatch(). This is so that callbacks shouldn't occur
|
||||||
|
* while an application might have arbitrary locks held for
|
||||||
|
* example.</note>
|
||||||
|
*
|
||||||
|
* Return value: a unique identifier that can be used to remove to remove
|
||||||
|
* the callback later.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
|
||||||
|
CoglOnscreenResizeCallback callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_remove_resize_handler:
|
||||||
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
|
* @id: An identifier returned from cogl_onscreen_add_resize_handler()
|
||||||
|
*
|
||||||
|
* Removes a resize @callback and @user_data pair that were previously
|
||||||
|
* associated with @onscreen via cogl_onscreen_add_resize_handler().
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
|
||||||
|
unsigned int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_is_onscreen:
|
* cogl_is_onscreen:
|
||||||
* @object: A #CoglObject pointer
|
* @object: A #CoglObject pointer
|
||||||
|
@ -74,6 +74,8 @@ cogl_sdl_handle_event (CoglContext *context, SDL_Event *event)
|
|||||||
|
|
||||||
winsys = _cogl_context_get_winsys (context);
|
winsys = _cogl_context_get_winsys (context);
|
||||||
|
|
||||||
|
_cogl_renderer_handle_native_event (context->display->renderer, event);
|
||||||
|
|
||||||
if (winsys->poll_dispatch)
|
if (winsys->poll_dispatch)
|
||||||
winsys->poll_dispatch (context, NULL, 0);
|
winsys->poll_dispatch (context, NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,8 @@ typedef struct _CoglDisplayEGL
|
|||||||
EGLSurface current_draw_surface;
|
EGLSurface current_draw_surface;
|
||||||
EGLContext current_context;
|
EGLContext current_context;
|
||||||
|
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
|
|
||||||
/* Platform specific display data */
|
/* Platform specific display data */
|
||||||
void *platform;
|
void *platform;
|
||||||
} CoglDisplayEGL;
|
} CoglDisplayEGL;
|
||||||
@ -131,6 +133,8 @@ typedef struct _CoglOnscreenEGL
|
|||||||
{
|
{
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
|
|
||||||
/* Platform specific data */
|
/* Platform specific data */
|
||||||
void *platform;
|
void *platform;
|
||||||
} CoglOnscreenEGL;
|
} CoglOnscreenEGL;
|
||||||
|
@ -89,6 +89,32 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_resize (CoglContext *context,
|
||||||
|
GLXDrawable drawable,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
CoglOnscreen *onscreen = find_onscreen_for_xid (context, drawable);
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplayEGL *egl_display = display->winsys;
|
||||||
|
CoglOnscreenEGL *egl_onscreen;
|
||||||
|
|
||||||
|
if (!onscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
egl_onscreen = onscreen->winsys;
|
||||||
|
|
||||||
|
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
||||||
|
|
||||||
|
/* We only want to notify that a resize happened when the
|
||||||
|
application calls cogl_context_dispatch so instead of immediately
|
||||||
|
notifying we'll set a flag to remember to notify later */
|
||||||
|
egl_display->pending_resize_notify = TRUE;
|
||||||
|
egl_onscreen->pending_resize_notify = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static CoglFilterReturn
|
static CoglFilterReturn
|
||||||
event_filter_cb (XEvent *xevent, void *data)
|
event_filter_cb (XEvent *xevent, void *data)
|
||||||
{
|
{
|
||||||
@ -96,17 +122,10 @@ event_filter_cb (XEvent *xevent, void *data)
|
|||||||
|
|
||||||
if (xevent->type == ConfigureNotify)
|
if (xevent->type == ConfigureNotify)
|
||||||
{
|
{
|
||||||
CoglOnscreen *onscreen =
|
notify_resize (context,
|
||||||
find_onscreen_for_xid (context, xevent->xconfigure.window);
|
xevent->xconfigure.window,
|
||||||
|
xevent->xconfigure.width,
|
||||||
if (onscreen)
|
xevent->xconfigure.height);
|
||||||
{
|
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
|
||||||
|
|
||||||
_cogl_framebuffer_winsys_update_size (framebuffer,
|
|
||||||
xevent->xconfigure.width,
|
|
||||||
xevent->xconfigure.height);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return COGL_FILTER_CONTINUE;
|
return COGL_FILTER_CONTINUE;
|
||||||
@ -441,6 +460,45 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
|
|||||||
XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
|
XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
|
||||||
|
CoglBool resizable)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
CoglContext *context = framebuffer->context;
|
||||||
|
CoglXlibRenderer *xlib_renderer =
|
||||||
|
_cogl_xlib_renderer_get_data (context->display->renderer);
|
||||||
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
|
CoglOnscreenXlib *xlib_onscreen = egl_onscreen->platform;
|
||||||
|
|
||||||
|
XSizeHints *size_hints = XAllocSizeHints ();
|
||||||
|
|
||||||
|
if (resizable)
|
||||||
|
{
|
||||||
|
/* TODO: Add cogl_onscreen_request_minimum_size () */
|
||||||
|
size_hints->min_width = 1;
|
||||||
|
size_hints->min_height = 1;
|
||||||
|
|
||||||
|
size_hints->max_width = INT_MAX;
|
||||||
|
size_hints->max_height = INT_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int width = cogl_framebuffer_get_width (framebuffer);
|
||||||
|
int height = cogl_framebuffer_get_height (framebuffer);
|
||||||
|
|
||||||
|
size_hints->min_width = width;
|
||||||
|
size_hints->min_height = height;
|
||||||
|
|
||||||
|
size_hints->max_width = width;
|
||||||
|
size_hints->max_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetWMNormalHints (xlib_renderer->xdpy, xlib_onscreen->xwin, size_hints);
|
||||||
|
|
||||||
|
XFree (size_hints);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
|
_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
|
||||||
{
|
{
|
||||||
@ -570,10 +628,35 @@ _cogl_winsys_poll_get_info (CoglContext *context,
|
|||||||
int *n_poll_fds,
|
int *n_poll_fds,
|
||||||
int64_t *timeout)
|
int64_t *timeout)
|
||||||
{
|
{
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplayEGL *egl_display = display->winsys;
|
||||||
|
|
||||||
_cogl_xlib_renderer_poll_get_info (context->display->renderer,
|
_cogl_xlib_renderer_poll_get_info (context->display->renderer,
|
||||||
poll_fds,
|
poll_fds,
|
||||||
n_poll_fds,
|
n_poll_fds,
|
||||||
timeout);
|
timeout);
|
||||||
|
|
||||||
|
if (egl_display->pending_resize_notify)
|
||||||
|
*timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flush_pending_notifications_cb (void *data,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer = data;
|
||||||
|
|
||||||
|
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
|
||||||
|
{
|
||||||
|
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
|
|
||||||
|
if (egl_onscreen->pending_resize_notify)
|
||||||
|
{
|
||||||
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
|
egl_onscreen->pending_resize_notify = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -581,9 +664,20 @@ _cogl_winsys_poll_dispatch (CoglContext *context,
|
|||||||
const CoglPollFD *poll_fds,
|
const CoglPollFD *poll_fds,
|
||||||
int n_poll_fds)
|
int n_poll_fds)
|
||||||
{
|
{
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplayEGL *egl_display = display->winsys;
|
||||||
|
|
||||||
_cogl_xlib_renderer_poll_dispatch (context->display->renderer,
|
_cogl_xlib_renderer_poll_dispatch (context->display->renderer,
|
||||||
poll_fds,
|
poll_fds,
|
||||||
n_poll_fds);
|
n_poll_fds);
|
||||||
|
|
||||||
|
if (egl_display->pending_resize_notify)
|
||||||
|
{
|
||||||
|
g_list_foreach (context->framebuffers,
|
||||||
|
flush_pending_notifications_cb,
|
||||||
|
NULL);
|
||||||
|
egl_display->pending_resize_notify = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EGL_KHR_image_pixmap
|
#ifdef EGL_KHR_image_pixmap
|
||||||
@ -726,6 +820,8 @@ _cogl_winsys_egl_xlib_get_vtable (void)
|
|||||||
|
|
||||||
vtable.onscreen_set_visibility =
|
vtable.onscreen_set_visibility =
|
||||||
_cogl_winsys_onscreen_set_visibility;
|
_cogl_winsys_onscreen_set_visibility;
|
||||||
|
vtable.onscreen_set_resizable =
|
||||||
|
_cogl_winsys_onscreen_set_resizable;
|
||||||
|
|
||||||
vtable.onscreen_x11_get_window_xid =
|
vtable.onscreen_x11_get_window_xid =
|
||||||
_cogl_winsys_onscreen_x11_get_window_xid;
|
_cogl_winsys_onscreen_x11_get_window_xid;
|
||||||
|
@ -80,6 +80,7 @@ typedef struct _CoglOnscreenGLX
|
|||||||
GLXDrawable glxwin;
|
GLXDrawable glxwin;
|
||||||
uint32_t last_swap_vsync_counter;
|
uint32_t last_swap_vsync_counter;
|
||||||
CoglBool pending_swap_notify;
|
CoglBool pending_swap_notify;
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
} CoglOnscreenGLX;
|
} CoglOnscreenGLX;
|
||||||
|
|
||||||
typedef struct _CoglTexturePixmapGLX
|
typedef struct _CoglTexturePixmapGLX
|
||||||
@ -183,6 +184,32 @@ notify_swap_buffers (CoglContext *context, GLXDrawable drawable)
|
|||||||
glx_onscreen->pending_swap_notify = TRUE;
|
glx_onscreen->pending_swap_notify = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_resize (CoglContext *context,
|
||||||
|
GLXDrawable drawable,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
CoglOnscreen *onscreen = find_onscreen_for_xid (context, drawable);
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglGLXDisplay *glx_display = display->winsys;
|
||||||
|
CoglOnscreenGLX *glx_onscreen;
|
||||||
|
|
||||||
|
if (!onscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glx_onscreen = onscreen->winsys;
|
||||||
|
|
||||||
|
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
||||||
|
|
||||||
|
/* We only want to notify that a resize happened when the
|
||||||
|
application calls cogl_context_dispatch so instead of immediately
|
||||||
|
notifying we'll set a flag to remember to notify later */
|
||||||
|
glx_display->pending_resize_notify = TRUE;
|
||||||
|
glx_onscreen->pending_resize_notify = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static CoglFilterReturn
|
static CoglFilterReturn
|
||||||
glx_event_filter_cb (XEvent *xevent, void *data)
|
glx_event_filter_cb (XEvent *xevent, void *data)
|
||||||
{
|
{
|
||||||
@ -193,17 +220,10 @@ glx_event_filter_cb (XEvent *xevent, void *data)
|
|||||||
|
|
||||||
if (xevent->type == ConfigureNotify)
|
if (xevent->type == ConfigureNotify)
|
||||||
{
|
{
|
||||||
CoglOnscreen *onscreen =
|
notify_resize (context,
|
||||||
find_onscreen_for_xid (context, xevent->xconfigure.window);
|
xevent->xconfigure.window,
|
||||||
|
xevent->xconfigure.width,
|
||||||
if (onscreen)
|
xevent->xconfigure.height);
|
||||||
{
|
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
|
||||||
|
|
||||||
_cogl_framebuffer_winsys_update_size (framebuffer,
|
|
||||||
xevent->xconfigure.width,
|
|
||||||
xevent->xconfigure.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we let ConfigureNotify pass through */
|
/* we let ConfigureNotify pass through */
|
||||||
return COGL_FILTER_CONTINUE;
|
return COGL_FILTER_CONTINUE;
|
||||||
@ -1412,6 +1432,44 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
|
|||||||
XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
|
XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
|
||||||
|
CoglBool resizable)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
CoglContext *context = framebuffer->context;
|
||||||
|
CoglXlibRenderer *xlib_renderer =
|
||||||
|
_cogl_xlib_renderer_get_data (context->display->renderer);
|
||||||
|
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
|
||||||
|
|
||||||
|
XSizeHints *size_hints = XAllocSizeHints ();
|
||||||
|
|
||||||
|
if (resizable)
|
||||||
|
{
|
||||||
|
/* TODO: Add cogl_onscreen_request_minimum_size () */
|
||||||
|
size_hints->min_width = 1;
|
||||||
|
size_hints->min_height = 1;
|
||||||
|
|
||||||
|
size_hints->max_width = INT_MAX;
|
||||||
|
size_hints->max_height = INT_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int width = cogl_framebuffer_get_width (framebuffer);
|
||||||
|
int height = cogl_framebuffer_get_height (framebuffer);
|
||||||
|
|
||||||
|
size_hints->min_width = width;
|
||||||
|
size_hints->min_height = height;
|
||||||
|
|
||||||
|
size_hints->max_width = width;
|
||||||
|
size_hints->max_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetWMNormalHints (xlib_renderer->xdpy, xlib_onscreen->xwin, size_hints);
|
||||||
|
|
||||||
|
XFree (size_hints);
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: This is a particularly hacky _cogl_winsys interface... */
|
/* XXX: This is a particularly hacky _cogl_winsys interface... */
|
||||||
static XVisualInfo *
|
static XVisualInfo *
|
||||||
_cogl_winsys_xlib_get_visual_info (void)
|
_cogl_winsys_xlib_get_visual_info (void)
|
||||||
@ -2004,13 +2062,13 @@ _cogl_winsys_poll_get_info (CoglContext *context,
|
|||||||
|
|
||||||
/* If we've already got a pending swap notify then we'll dispatch
|
/* If we've already got a pending swap notify then we'll dispatch
|
||||||
immediately */
|
immediately */
|
||||||
if (glx_display->pending_swap_notify)
|
if (glx_display->pending_swap_notify || glx_display->pending_resize_notify)
|
||||||
*timeout = 0;
|
*timeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flush_pending_swap_notify_cb (void *data,
|
flush_pending_notifications_cb (void *data,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
CoglFramebuffer *framebuffer = data;
|
CoglFramebuffer *framebuffer = data;
|
||||||
|
|
||||||
@ -2024,6 +2082,12 @@ flush_pending_swap_notify_cb (void *data,
|
|||||||
_cogl_onscreen_notify_swap_buffers (onscreen);
|
_cogl_onscreen_notify_swap_buffers (onscreen);
|
||||||
glx_onscreen->pending_swap_notify = FALSE;
|
glx_onscreen->pending_swap_notify = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (glx_onscreen->pending_resize_notify)
|
||||||
|
{
|
||||||
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
|
glx_onscreen->pending_resize_notify = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2039,12 +2103,13 @@ _cogl_winsys_poll_dispatch (CoglContext *context,
|
|||||||
poll_fds,
|
poll_fds,
|
||||||
n_poll_fds);
|
n_poll_fds);
|
||||||
|
|
||||||
if (glx_display->pending_swap_notify)
|
if (glx_display->pending_swap_notify || glx_display->pending_resize_notify)
|
||||||
{
|
{
|
||||||
g_list_foreach (context->framebuffers,
|
g_list_foreach (context->framebuffers,
|
||||||
flush_pending_swap_notify_cb,
|
flush_pending_notifications_cb,
|
||||||
NULL);
|
NULL);
|
||||||
glx_display->pending_swap_notify = FALSE;
|
glx_display->pending_swap_notify = FALSE;
|
||||||
|
glx_display->pending_resize_notify = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2073,6 +2138,8 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
|||||||
.onscreen_x11_get_window_xid =
|
.onscreen_x11_get_window_xid =
|
||||||
_cogl_winsys_onscreen_x11_get_window_xid,
|
_cogl_winsys_onscreen_x11_get_window_xid,
|
||||||
.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
|
.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility,
|
||||||
|
.onscreen_set_resizable =
|
||||||
|
_cogl_winsys_onscreen_set_resizable,
|
||||||
|
|
||||||
.poll_get_info = _cogl_winsys_poll_get_info,
|
.poll_get_info = _cogl_winsys_poll_get_info,
|
||||||
.poll_dispatch = _cogl_winsys_poll_dispatch,
|
.poll_dispatch = _cogl_winsys_poll_dispatch,
|
||||||
|
@ -120,6 +120,9 @@ typedef struct _CoglWinsysVtable
|
|||||||
const int *rectangles,
|
const int *rectangles,
|
||||||
int n_rectangles);
|
int n_rectangles);
|
||||||
|
|
||||||
|
void
|
||||||
|
(*onscreen_set_resizable) (CoglOnscreen *onscreen, CoglBool resizable);
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_SUPPORT
|
#ifdef COGL_HAS_EGL_SUPPORT
|
||||||
EGLDisplay
|
EGLDisplay
|
||||||
(*context_egl_get_egl_display) (CoglContext *context);
|
(*context_egl_get_egl_display) (CoglContext *context);
|
||||||
|
@ -46,8 +46,9 @@ typedef struct _CoglRendererSdl
|
|||||||
typedef struct _CoglDisplaySdl
|
typedef struct _CoglDisplaySdl
|
||||||
{
|
{
|
||||||
SDL_Surface *surface;
|
SDL_Surface *surface;
|
||||||
CoglBool has_onscreen;
|
CoglOnscreen *onscreen;
|
||||||
Uint32 video_mode_flags;
|
Uint32 video_mode_flags;
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
} CoglDisplaySdl;
|
} CoglDisplaySdl;
|
||||||
|
|
||||||
static CoglFuncPtr
|
static CoglFuncPtr
|
||||||
@ -200,6 +201,39 @@ error:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglFilterReturn
|
||||||
|
sdl_event_filter_cb (SDL_Event *event, void *data)
|
||||||
|
{
|
||||||
|
if (event->type == SDL_VIDEORESIZE)
|
||||||
|
{
|
||||||
|
CoglContext *context = data;
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplaySdl *sdl_display = display->winsys;
|
||||||
|
float width = event->resize.w;
|
||||||
|
float height = event->resize.h;
|
||||||
|
CoglFramebuffer *framebuffer;
|
||||||
|
|
||||||
|
if (!sdl_display->onscreen)
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
|
||||||
|
sdl_display->surface = SDL_SetVideoMode (width, height,
|
||||||
|
0, /* bitsperpixel */
|
||||||
|
sdl_display->video_mode_flags);
|
||||||
|
|
||||||
|
framebuffer = COGL_FRAMEBUFFER (sdl_display->onscreen);
|
||||||
|
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
||||||
|
|
||||||
|
/* We only want to notify that a resize happened when the
|
||||||
|
application calls cogl_context_dispatch so instead of immediately
|
||||||
|
notifying we'll set a flag to remember to notify later */
|
||||||
|
sdl_display->pending_resize_notify = TRUE;
|
||||||
|
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
_cogl_winsys_context_init (CoglContext *context, GError **error)
|
_cogl_winsys_context_init (CoglContext *context, GError **error)
|
||||||
{
|
{
|
||||||
@ -209,6 +243,10 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
|
|||||||
g_error ("cogl_sdl_renderer_set_event_type() or cogl_sdl_context_new() "
|
g_error ("cogl_sdl_renderer_set_event_type() or cogl_sdl_context_new() "
|
||||||
"must be called during initialization");
|
"must be called during initialization");
|
||||||
|
|
||||||
|
_cogl_renderer_add_native_filter (renderer,
|
||||||
|
(CoglNativeFilterFunc)sdl_event_filter_cb,
|
||||||
|
context);
|
||||||
|
|
||||||
return _cogl_context_update_features (context, error);
|
return _cogl_context_update_features (context, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +267,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|||||||
CoglDisplay *display = context->display;
|
CoglDisplay *display = context->display;
|
||||||
CoglDisplaySdl *sdl_display = display->winsys;
|
CoglDisplaySdl *sdl_display = display->winsys;
|
||||||
|
|
||||||
sdl_display->has_onscreen = FALSE;
|
sdl_display->onscreen = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
@ -242,7 +280,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
CoglDisplaySdl *sdl_display = display->winsys;
|
CoglDisplaySdl *sdl_display = display->winsys;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
if (sdl_display->has_onscreen)
|
if (sdl_display->onscreen)
|
||||||
{
|
{
|
||||||
g_set_error (error, COGL_WINSYS_ERROR,
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
|
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
|
||||||
@ -275,7 +313,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
sdl_display->surface->w,
|
sdl_display->surface->w,
|
||||||
sdl_display->surface->h);
|
sdl_display->surface->h);
|
||||||
|
|
||||||
sdl_display->has_onscreen = TRUE;
|
sdl_display->onscreen = onscreen;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -299,6 +337,49 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
|
|||||||
/* SDL doesn't appear to provide a way to set this */
|
/* SDL doesn't appear to provide a way to set this */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
|
||||||
|
CoglBool resizable)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
CoglContext *context = framebuffer->context;
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplaySdl *sdl_display = display->winsys;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
width = cogl_framebuffer_get_width (framebuffer);
|
||||||
|
height = cogl_framebuffer_get_height (framebuffer);
|
||||||
|
|
||||||
|
if (resizable)
|
||||||
|
sdl_display->video_mode_flags |= SDL_RESIZABLE;
|
||||||
|
else
|
||||||
|
sdl_display->video_mode_flags &= ~SDL_RESIZABLE;
|
||||||
|
|
||||||
|
sdl_display->surface = SDL_SetVideoMode (width, height,
|
||||||
|
0, /* bitsperpixel */
|
||||||
|
sdl_display->video_mode_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_poll_dispatch (CoglContext *context,
|
||||||
|
const CoglPollFD *poll_fds,
|
||||||
|
int n_poll_fds)
|
||||||
|
{
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplaySdl *sdl_display = display->winsys;
|
||||||
|
|
||||||
|
if (sdl_display->pending_resize_notify)
|
||||||
|
{
|
||||||
|
CoglOnscreen *onscreen = sdl_display->onscreen;
|
||||||
|
|
||||||
|
g_return_if_fail (onscreen != NULL);
|
||||||
|
|
||||||
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
|
|
||||||
|
sdl_display->pending_resize_notify = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CoglWinsysVtable *
|
const CoglWinsysVtable *
|
||||||
_cogl_winsys_sdl_get_vtable (void)
|
_cogl_winsys_sdl_get_vtable (void)
|
||||||
{
|
{
|
||||||
@ -330,6 +411,9 @@ _cogl_winsys_sdl_get_vtable (void)
|
|||||||
vtable.onscreen_update_swap_throttled =
|
vtable.onscreen_update_swap_throttled =
|
||||||
_cogl_winsys_onscreen_update_swap_throttled;
|
_cogl_winsys_onscreen_update_swap_throttled;
|
||||||
vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility;
|
vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility;
|
||||||
|
vtable.onscreen_set_resizable = _cogl_winsys_onscreen_set_resizable;
|
||||||
|
|
||||||
|
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
||||||
|
|
||||||
vtable_inited = TRUE;
|
vtable_inited = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,8 @@ main (int argc, char **argv)
|
|||||||
cogl_onscreen_show (onscreen);
|
cogl_onscreen_show (onscreen);
|
||||||
data.fb = COGL_FRAMEBUFFER (onscreen);
|
data.fb = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
|
cogl_onscreen_set_resizable (onscreen, TRUE);
|
||||||
|
|
||||||
data.triangle = cogl_primitive_new_p2c4 (data.ctx,
|
data.triangle = cogl_primitive_new_p2c4 (data.ctx,
|
||||||
COGL_VERTICES_MODE_TRIANGLES,
|
COGL_VERTICES_MODE_TRIANGLES,
|
||||||
3, triangle_vertices);
|
3, triangle_vertices);
|
||||||
|
@ -31,6 +31,16 @@ update_cogl_x11_event_mask (CoglOnscreen *onscreen,
|
|||||||
&attrs);
|
&attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resize_handler (CoglOnscreen *onscreen,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *fb = user_data;
|
||||||
|
cogl_framebuffer_set_viewport (fb, width / 4, height / 4, width / 2, height / 2);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -149,6 +159,9 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
fb = COGL_FRAMEBUFFER (onscreen);
|
fb = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
|
||||||
|
cogl_onscreen_set_resizable (onscreen, TRUE);
|
||||||
|
cogl_onscreen_add_resize_handler (onscreen, resize_handler, onscreen);
|
||||||
|
|
||||||
triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
|
triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
|
||||||
3, triangle_vertices);
|
3, triangle_vertices);
|
||||||
pipeline = cogl_pipeline_new (ctx);
|
pipeline = cogl_pipeline_new (ctx);
|
||||||
@ -170,13 +183,18 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
cogl_xlib_renderer_handle_event (renderer, &event);
|
cogl_xlib_renderer_handle_event (renderer, &event);
|
||||||
}
|
}
|
||||||
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
|
|
||||||
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
|
|
||||||
cogl_onscreen_swap_buffers (onscreen);
|
|
||||||
|
|
||||||
|
/* After forwarding native events directly to Cogl you should
|
||||||
|
* then allow Cogl to dispatch any corresponding event
|
||||||
|
* callbacks, such as resize notification callbacks...
|
||||||
|
*/
|
||||||
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
|
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
|
||||||
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
|
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
|
||||||
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
|
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
|
||||||
|
|
||||||
|
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
|
||||||
|
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
|
||||||
|
cogl_onscreen_swap_buffers (onscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user