Getting started
QNX Screen Graphics Subsystem is a graphics framework, and so, applications that you develop using this framework can vary greatly in complexity and functionality. That said, most Screen applications, when simplified, perform some sort of rendering with the intention to show the resultant image on a display. To develop a basic Screen application, you should follow these steps:
- Create a Screen context.
- Create a render target.
- Set the appropriate properties of your render target.
- Create buffer(s) for your render target.
- Render to your target.
- Post your image.
- Handle Screen events.
Create a Screen context
Create a Screen context by calling screen_create_context(). For example:
...
screen_context_t screen_ctx;
screen_create_context(&screen_ctx, SCREEN_APPLICATION_CONTEXT);
...
Most of your application's interaction with Screen is within the scope of this context. You identify and gain access to Screen API objects through this context.
You must create a context with the appropriate privileges for your application. The
type of privileges that your application needs may be based on its functionality.
See Screen context types
.
Create a render target
This is what holds the buffer or buffers that your application will
render to. A render target can be a stream, a pixmap or a window. You can also use a
combination of these targets, depending on your application. See Render Targets
. For example:
...
screen_context_t screen_ctx;
screen_window_t screen_win;
...
screen_create_window(&screen_win, screen_ctx);
...
Set the appropriate properties of your render target
Now that you've created your target, you must set the appropriate properties on the target. At a minimum, you should set the usage property (SCREEN_PROPERTY_USAGE). For example:
...
int usage = SCREEN_USAGE_NATIVE;
...
screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
...
Among other factors, the type of rendering that your application performs can affect
which properties on your render target you need to set. See Rendering
.
Create buffer(s) for your render target
You need to create one, or more, buffers for your render target. For example:
...
/* Use a double-buffered window. This allows your application to work on a frame while
* Screen is updating the framebuffer with previous changes.
*/
int nbuffers = 2;
...
screen_create_window_buffers(screen_win, nbuffers);
...
The number of buffers that you can create depends on your render target. See
Render Targets
.
Render to your target
In the rendering loop of your Screen application, you need to access the buffer(s) of your render target, draw to the buffer(s), and post your image.
Each time before you can render to your target, you'll need access to the buffer(s) of your render target. These are the areas that you'll be copying from, and writing to. You'll want to retrieve the SCREEN_PROPERTY_RENDER_BUFFERS of your render target. This property will give you the handle to the buffers that are available for rendering. For example:
...
while (1) {
...
screen_buffer_t screen_buf[2];
screen_get_window_property_pv(screen_win,
SCREEN_PROPERTY_RENDER_BUFFERS,
(void **)screen_buf);
...
}
...
At this point, you can use different ways of rendering to draw to your buffer(s). For example, you can use screen_fill() to request pixel copying.
...
while (1) {
...
screen_buffer_t screen_buf[2];
screen_get_window_property_pv(screen_win,
SCREEN_PROPERTY_RENDER_BUFFERS,
(void **)screen_buf);
...
int win_background[] = { SCREEN_BLIT_COLOR, 0xffffff00, SCREEN_BLIT_END };
screen_fill(screen_ctx, screen_buf[0], win_background);
...
}
...
For information on different ways of rendering, see Rendering
.
Post your image
Up until this point, you've rendered to your target, or
requested operations (e.g., fill), but you need to trigger Screen to put the image to the display. How you do this may
depend on how your application is rendering to the buffer. See Rendering
. For example, if you are rendering to a
window, you call screen_post_window():
...
while (1) {
screen_buffer_t screen_buf[2];
screen_get_window_property_pv(screen_win,
SCREEN_PROPERTY_RENDER_BUFFERS,
(void **)screen_buf);
...
int win_background[] = { SCREEN_BLIT_COLOR, 0xffffff00, SCREEN_BLIT_END };
screen_fill(screen_ctx, screen_buf[0], win_background);
...
screen_post_window(screen_win, screen_buf[0], 0, NULL, 0);
...
}
...
Handle Screen events
Screen events, which include both input and general
events, are associated with your application's context and can be handled in your
rendering loop. See Event Handling
. For example:
...
int val;
...
while (1) {
while (!screen_get_event(screen_ctx, screen_ev, 0)) {
screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TYPE, &val);
switch (val) {
case SCREEN_EVENT_KEYBOARD:
screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_FLAGS, &val);
if (val & KEY_DOWN) {
screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_SYM, &val);
switch (val) {
case KEYCODE_ESCAPE:
{
/* clean up resources */
return EXIT_SUCCESS;
}
default:
break;
}
}
break;
...
}
}
...
screen_buffer_t screen_buf[2];
screen_get_window_property_pv(screen_win,
SCREEN_PROPERTY_RENDER_BUFFERS,
(void **)screen_buf);
...
int win_background[] = { SCREEN_BLIT_COLOR, 0xffffff00, SCREEN_BLIT_END };
screen_fill(screen_ctx, screen_buf[0], win_background);
...
screen_post_window(screen_win, screen_buf[0], 0, NULL, 0);
...
}
...
You choose which type of events that your application will handle. See Screen event types
for all the
events that Screen may send to your application.