Search code examples
c++qnxqnx-neutrino

C++/libscreen fails to update visibility


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.


Solution

  • 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.