I'm writing a GUI in C++ (qcc) for Neutrino 6.5.0 with QNX CAR 2.0 using the screen windowing system, following the documentation tutorial. No visible output is generated, and /dev/screen/{pid}/win-{n}/win-{n}
has status = WIN_STATUS_INVISIBLE
.
(Using {n}
and {pid}
to indicate substitutions of runtime/dynamic variables' values)
I've tried following the tutorial to the letter, but had the same results. In particular, the value of window_group_name
(mainwindowgroup
or veryuniquewgn
) makes no difference; the former being the value suggested by the tutorial, and the latter my own.
I've constructed an MCVE:
#include <cstdlib> // for EXIT_ constants
#include <stdio.h> // for printf(), getchar()
#include <process.h> // for getpid()
#include <screen.h>
#define screen_err(desc) \
if(screen_res != 0) { \
printf("ERR screen: failed to %s\n", desc); \
return EXIT_FAILURE; \
}
int main_withwindow(screen_context_t scr_ctx, screen_window_t scr_win) {
static const char *window_group_name = "veryuniquewgn";
// Dummy to pass as ptr to enum values
int prop;
int screen_res;
screen_res = screen_create_window_group(scr_win, window_group_name);
screen_err("create window group");
prop = SCREEN_FORMAT_RGBA8888;
screen_res = screen_set_window_property_iv(scr_win, SCREEN_PROPERTY_FORMAT,
&prop);
screen_err("set window property: format -> RGBA");
prop = SCREEN_USAGE_NATIVE;
screen_res = screen_set_window_property_iv(scr_win, SCREEN_PROPERTY_USAGE,
&prop);
screen_err("set window property: usage -> native");
screen_res = screen_create_window_buffers(scr_win, 1);
screen_err("create window buffers");
int win_buf_rect[4] = { 0, 0 };
screen_res = screen_get_window_property_iv(scr_win,
SCREEN_PROPERTY_BUFFER_SIZE, win_buf_rect + 2);
screen_err("get window property: buffer_size");
// Array type to easily support multi-buffering in future
screen_buffer_t scr_buf[1];
screen_res = screen_get_window_property_pv(scr_win,
SCREEN_PROPERTY_RENDER_BUFFERS, (void **)scr_buf);
screen_err("get window property: render_buffers");
int bg[] = { SCREEN_BLIT_COLOR, 0xffffff00, SCREEN_BLIT_END };
screen_res = screen_fill(scr_ctx, scr_buf[0], bg);
screen_err("fill buffer with yellow");
screen_res = screen_post_window(scr_win, scr_buf[0], 1, win_buf_rect, 0);
screen_err("post window");
prop = 255;
screen_res = screen_set_window_property_iv(scr_win,
SCREEN_PROPERTY_ZORDER, &prop);
screen_err("set window property: zorder -> 255");
prop = 1;
screen_res = screen_set_window_property_iv(scr_win,
SCREEN_PROPERTY_VISIBLE, &prop);
screen_err("set window property: visible -> true");
screen_res = screen_flush_context(scr_ctx, SCREEN_WAIT_IDLE);
screen_err("flush context to idle");
getchar();
return EXIT_SUCCESS;
}
int main_withcontext(screen_context_t scr_ctx) {
screen_window_t scr_win;
int ret;
int screen_res;
screen_res = screen_create_window(&scr_win, scr_ctx);
screen_err("create window");
ret = main_withwindow(scr_ctx, scr_win);
screen_res = screen_destroy_window(scr_win);
screen_err("destroy window");
return ret;
}
int main(int argc, char *argv[]) {
printf("%d\n", getpid());
screen_context_t scr_ctx;
int ret;
int screen_res;
screen_res = screen_create_context(&scr_ctx, SCREEN_APPLICATION_CONTEXT);
screen_err("create context");
ret = main_withcontext(scr_ctx);
screen_res = screen_destroy_context(scr_ctx);
screen_err("destroy context");
return ret;
}
Given the use of the screen_err()
define, no output - except the first printf
for the pid - indicates no errors from screen_...()
calls. That's exactly what I see when I run this.
Looking in /dev/screen/{pid}
, I see a ctx-{n}/ctx-{n}
and a win-{n}/win-{n}
file, as expected. The former is not human-readable, but the latter, and its differences to its counterpart in a working nto 6.5.0 + CAR 2.0 + libscreen application, yield some insight.
The working application is an HMI for which I do not have the source, and is launched from /etc/ro
as root, and mine is launched from ksh, logged in as root.
They're both 98-line files, so I've produced a diff - the win-{n}
from the working application on the left, and mine on the right - excluding metrics:
(lines over 39 characters compared vertically)
autonomous = 0 autonomous = 1
status = WIN_STATUS_FULLSCREEN status = WIN_STATUS_INVISIBLE
id string = DPY_HMI id string =
insert id = 1 insert id = 3
reclip = 0 reclip = 1
flags = WIN_FLAG_VISIBLE WIN_FLAG_FLOATING
flags = WIN_FLAG_FLOATING
usage = SCREEN_USAGE_OPENGL_ES2 usage = SCREEN_USAGE_NATIVE
order = 240 order = 0
regions = (0,0;800,480) regions = (none)
clipped source viewport = (0,0;800,480 800x480)
clipped source viewport = (0,0;0,0 0x0)
clipped destination rectangle = (0,0;800,480 800x480)
clipped destination rectangle = (0,0;0,0 0x0)
transform = [[1 0 0],[0 1 0],[0 0 1]] transform = [[0 0 0],[0 0 0],[0 0 0]]
Of these differences, usage
is the only one with the value I expect, considering that it reflects the parameter of the relevant call to screen_set_window_property_iv(...)
. For all the rest, especially regions
and flags
, I do not understand why their values differ from those of the working application.
The target's display's native resolution is 800x480.
As it turns out, that code was completely valid and correct. The reason for its failure was a window manager daemon I wasn't aware of suppressing the window. Turning this off solved the problem.