Create the background window

The background window is the parent window for the hourglass child window and the bar child window. This quick tutorial walks you through the process of creating the create_bg_window() function that is used to create the background window.

First, create and initialize the background window variable.

screen_window_t screen_bg_win = NULL;

Next, create the create_bg_window() function. This function is called to create the background window. The function takes a char that is used as a window group name, an array of integers that define the size of the window, and a context for the window to use.

You can create the window with any buffer size. Note that the windowing system will simply scale the contents if the buffers are larger or smaller than the size of the window on the screen. However, it is preferable to make the buffer size match the on-screen dimensions of the window.

The group variable is used in the screen_create_window_group() function to specify the name for the window group. Since this is the parent window, all child windows must use this group ID in order to join the group.

	screen_window_t create_bg_window(const char *group, int dims[2], screen_context_t screen_ctx)
	{
	    screen_window_t screen_win;
	    screen_create_window(&screen_win, screen_ctx);
	    screen_create_window_group(screen_win, group);
	    
	    ... more code not shown.
	
	}

Next, in the create_bg_window() function, set the window visibility to 0, indicating that the window will be invisible. It's important to hide all windows until the window and any associated buffer is properly initialized, otherwise the window will display incomplete results on the screen.

	int vis = 0;
	screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_VISIBLE, &vis);

Next, in the create_bg_window() function, set the background color to yellow. We're using a small trick here by filling the entire window with a solid color without requiring a large buffer to back it up, and without scaling.

	int color = 0xffffff00;
	screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_COLOR, &color);

The second part of the trick is to create a 1x1 buffer. Currently, the Screen and Windowing API doesn't support visible windows without at least one buffer. Instead, create the smallest buffer possible. The format and usage don't apply since the buffer will never be used. Next, to avoid scaling, the source viewport size is set to match the on-screen dimensions of the window.

	int rect[4] = { 0, 0, 1, 1 };
	screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, rect+2);
	screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, dims);

The final part of the trick, is to move the source viewport completely outside the bounds of the 1x1 buffer. The Screen and Windowing API allows this and replaces all areas outside the buffer with the window's color.

	int pos[2] = { -dims[0], -dims[1] };
	screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_POSITION, pos);

Finally, in the create_bg_window() function, create the single 1x1 window buffer by calling the screen_create_window_buffers() function. Call the screen_get_window_property_pv() function and specify the SCREEN_PROPERTY_RENDER_BUFFERS constant to return a handle to the buffer. This buffer must still be created in order to make it visible, even though it won't be used. Remember that the window is still invisible so nothing will appear on the display. The window will be made visible within the event loop, later on in the tutorial.

	screen_buffer_t screen_buf;
	screen_create_window_buffers(screen_win, 1);
	screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf);
	screen_post_window(screen_win, screen_buf, 1, rect, 0);

	return screen_win;