summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vincent.sanders@collabora.co.uk>2013-03-21 18:05:54 (GMT)
committer Vincent Sanders <vincent.sanders@collabora.co.uk>2013-03-21 18:05:54 (GMT)
commitf75a698b15f978c854cc424ee79a38e157165091 (patch)
tree675badfbfadf62498370333cab889f7bb5cea41e
parent4b1e1482c42b31277acf96377013e716521982aa (diff)
downloadlibnsfb-f75a698b15f978c854cc424ee79a38e157165091.tar.gz
libnsfb-f75a698b15f978c854cc424ee79a38e157165091.tar.bz2
initial wayland surface connection
-rw-r--r--Makefile8
-rw-r--r--src/surface/Makefile24
-rw-r--r--src/surface/wld.c (renamed from src/surface/wl.c)967
-rw-r--r--src/surface/x.c4
-rwxr-xr-xtest/runtest.sh2
5 files changed, 695 insertions, 310 deletions
diff --git a/Makefile b/Makefile
index 2b07e87..89d7b6b 100644
--- a/Makefile
+++ b/Makefile
@@ -18,15 +18,21 @@ WARNFLAGS := -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align \
-Wmissing-declarations -Wnested-externs -Werror -pedantic \
-Wno-overlength-strings # For nsglobe.c
CFLAGS := -g -std=c99 -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112L \
- -I$(CURDIR)/include/ -I$(CURDIR)/src $(WARNFLAGS) $(CFLAGS)
+ -I$(CURDIR)/include/ -I$(CURDIR)/src $(WARNFLAGS) $(CFLAGS) -Wno-error
NSFB_XCB_PKG_NAMES := xcb xcb-icccm xcb-image xcb-keysyms xcb-atom
+# determine which surface handlers can be compiled based upon avalable library
$(eval $(call pkg_config_package_available,NSFB_VNC_AVAILABLE,libvncserver))
$(eval $(call pkg_config_package_available,NSFB_SDL_AVAILABLE,sdl))
$(eval $(call pkg_config_package_available,NSFB_XCB_AVAILABLE,$(NSFB_XCB_PKG_NAMES)))
$(eval $(call pkg_config_package_available,NSFB_WLD_AVAILABLE,wayland-client))
+# surfaces not detectable via pkg-config
+NSFB_ABLE_AVAILABLE := no
+NSFB_LINUX_AVAILABLE := yes
+
+# Flags and setup for each support library
ifeq ($(NSFB_SDL_AVAILABLE),yes)
$(eval $(call pkg_config_package_add_flags,sdl,CFLAGS))
$(eval $(call pkg_config_package_add_flags,sdl,TESTCFLAGS,TESTLDFLAGS))
diff --git a/src/surface/Makefile b/src/surface/Makefile
index 332d81d..ad23cc4 100644
--- a/src/surface/Makefile
+++ b/src/surface/Makefile
@@ -1,20 +1,16 @@
# Sources
-DIR_SOURCES := surface.c able.c ram.c linux.c
-ifeq ($(NSFB_SDL_AVAILABLE),yes)
- DIR_SOURCES := $(DIR_SOURCES) sdl.c
-endif
+# Common surface code and heap based surface handler
+SURFACE_HANDLER_yes := surface.c ram.c
-ifeq ($(NSFB_XCB_AVAILABLE),yes)
- DIR_SOURCES := $(DIR_SOURCES) x.c
-endif
+# optional surface handlers
+SURFACE_HANDLER_$(NSFB_ABLE_AVAILABLE) += able.c
+SURFACE_HANDLER_$(NSFB_LINUX_AVAILABLE) += linux.c
+SURFACE_HANDLER_$(NSFB_SDL_AVAILABLE) += sdl.c
+SURFACE_HANDLER_$(NSFB_XCB_AVAILABLE) += x.c
+SURFACE_HANDLER_$(NSFB_VNC_AVAILABLE) += vnc.c
+SURFACE_HANDLER_$(NSFB_WLD_AVAILABLE) += wld.c
-ifeq ($(NSFB_VNC_AVAILABLE),yes)
- DIR_SOURCES := $(DIR_SOURCES) vnc.c
-endif
-
-ifeq ($(NSFB_WLD_AVAILABLE),yes)
- DIR_SOURCES := $(DIR_SOURCES) wl.c
-endif
+DIR_SOURCES := $(SURFACE_HANDLER_yes)
include $(NSBUILD)/Makefile.subdir
diff --git a/src/surface/wl.c b/src/surface/wld.c
index fbe26cf..d450738 100644
--- a/src/surface/wl.c
+++ b/src/surface/wld.c
@@ -67,7 +67,7 @@ xcb_free_size_hints(xcb_size_hints_t *hints)
typedef struct xstate_s {
xcb_connection_t *connection; /* The x server connection */
xcb_screen_t *screen; /* The screen to put the window on */
- xcb_key_symbols_t *keysymbols; /* keysym mappings */
+ xcb_key_symbols_t *keysymbols; /* keysym mappings */
xcb_shm_segment_info_t shminfo;
@@ -80,7 +80,7 @@ typedef struct xstate_s {
} xstate_t;
/* X keyboard codepage to nsfb mapping*/
-enum nsfb_key_code_e XCSKeyboardMap[256] = {
+static enum nsfb_key_code_e XCSKeyboardMap[256] = {
NSFB_KEY_UNKNOWN, /* */
NSFB_KEY_UNKNOWN, /* */
NSFB_KEY_UNKNOWN, /* */
@@ -369,30 +369,30 @@ xkeysym_to_nsfbkeycode(xcb_keysym_t ks)
uint8_t chrcode = ks & 0xFF;
if (ks != XCB_NO_SYMBOL) {
-
- switch (codeset) {
- case 0x00: /* Latin 1 */
- case 0x01: /* Latin 2 */
- case 0x02: /* Latin 3 */
- case 0x03: /* Latin 4 */
- case 0x04: /* Katakana */
- case 0x05: /* Arabic */
- case 0x06: /* Cyrillic */
- case 0x07: /* Greek */
- case 0x08: /* Technical */
- case 0x0A: /* Publishing */
- case 0x0C: /* Hebrew */
- case 0x0D: /* Thai */
- /* this is somewhat incomplete, but the nsfb codes are lined up on
- * the ascii codes and x seems to have done similar
- */
- nsfb_key = (enum nsfb_key_code_e)chrcode;
- break;
-
- case 0xFF: /* Keyboard */
- nsfb_key = XCSKeyboardMap[chrcode];
- break;
- }
+
+ switch (codeset) {
+ case 0x00: /* Latin 1 */
+ case 0x01: /* Latin 2 */
+ case 0x02: /* Latin 3 */
+ case 0x03: /* Latin 4 */
+ case 0x04: /* Katakana */
+ case 0x05: /* Arabic */
+ case 0x06: /* Cyrillic */
+ case 0x07: /* Greek */
+ case 0x08: /* Technical */
+ case 0x0A: /* Publishing */
+ case 0x0C: /* Hebrew */
+ case 0x0D: /* Thai */
+ /* this is somewhat incomplete, but the nsfb codes are lined up on
+ * the ascii codes and x seems to have done similar
+ */
+ nsfb_key = (enum nsfb_key_code_e)chrcode;
+ break;
+
+ case 0xFF: /* Keyboard */
+ nsfb_key = XCSKeyboardMap[chrcode];
+ break;
+ }
}
return nsfb_key;
@@ -430,29 +430,29 @@ static int
update_pixmap(xstate_t *xstate, int x, int y, int width, int height)
{
if (xstate->shminfo.shmseg == 0) {
- /* not using shared memory */
- xcb_put_image(xstate->connection,
- xstate->image->format,
- xstate->pmap,
- xstate->gc,
- xstate->image->width,
- height,
- 0,
- y,
- 0,
- xstate->image->depth,
- (height) * xstate->image->stride,
- xstate->image->data + (y * xstate->image->stride));
+ /* not using shared memory */
+ xcb_put_image(xstate->connection,
+ xstate->image->format,
+ xstate->pmap,
+ xstate->gc,
+ xstate->image->width,
+ height,
+ 0,
+ y,
+ 0,
+ xstate->image->depth,
+ (height) * xstate->image->stride,
+ xstate->image->data + (y * xstate->image->stride));
} else {
- /* shared memory */
- xcb_image_shm_put(xstate->connection,
- xstate->pmap,
- xstate->gc,
- xstate->image,
- xstate->shminfo,
- x,y,
- x,y,
- width,height,0);
+ /* shared memory */
+ xcb_image_shm_put(xstate->connection,
+ xstate->pmap,
+ xstate->gc,
+ xstate->image,
+ xstate->shminfo,
+ x,y,
+ x,y,
+ width,height,0);
}
return 0;
@@ -464,12 +464,12 @@ update_and_redraw_pixmap(xstate_t *xstate, int x, int y, int width, int height)
update_pixmap(xstate, x, y, width, height);
xcb_copy_area(xstate->connection,
- xstate->pmap,
- xstate->window,
- xstate->gc,
- x, y,
- x, y,
- width, height);
+ xstate->pmap,
+ xstate->window,
+ xstate->gc,
+ x, y,
+ x, y,
+ width, height);
xcb_flush(xstate->connection);
@@ -497,89 +497,93 @@ xcopy(nsfb_t *nsfb, nsfb_bbox_t *srcbox, nsfb_bbox_t *dstbox)
/* clear the cursor if its within the region to be altered */
if ((cursor != NULL) &&
- (cursor->plotted == true) &&
- (nsfb_plot_bbox_intersect(&allbox, &cursor->loc))) {
+ (cursor->plotted == true) &&
+ (nsfb_plot_bbox_intersect(&allbox, &cursor->loc))) {
- nsfb_cursor_clear(nsfb, cursor);
- update_pixmap(xstate,
- cursor->savloc.x0,
- cursor->savloc.y0,
- cursor->savloc.x1 - cursor->savloc.x0,
- cursor->savloc.y1 - cursor->savloc.y0);
+ nsfb_cursor_clear(nsfb, cursor);
+ update_pixmap(xstate,
+ cursor->savloc.x0,
+ cursor->savloc.y0,
+ cursor->savloc.x1 - cursor->savloc.x0,
+ cursor->savloc.y1 - cursor->savloc.y0);
- /* must sync here or local framebuffer and remote pixmap will not be
- * consistant
- */
- xcb_aux_sync(xstate->connection);
+ /* must sync here or local framebuffer and remote pixmap will not be
+ * consistant
+ */
+ xcb_aux_sync(xstate->connection);
}
/* copy the area on the server */
xcb_copy_area(xstate->connection,
- xstate->pmap,
- xstate->pmap,
- xstate->gc,
- srcbox->x0,
- srcbox->y0,
- dstbox->x0,
- dstbox->y0,
- srcbox->x1 - srcbox->x0,
- srcbox->y1 - srcbox->y0);
+ xstate->pmap,
+ xstate->pmap,
+ xstate->gc,
+ srcbox->x0,
+ srcbox->y0,
+ dstbox->x0,
+ dstbox->y0,
+ srcbox->x1 - srcbox->x0,
+ srcbox->y1 - srcbox->y0);
/* do the copy in the local memory too */
srcptr = (nsfb->ptr +
- (srcy * nsfb->linelen) +
- ((srcx * nsfb->bpp) / 8));
+ (srcy * nsfb->linelen) +
+ ((srcx * nsfb->bpp) / 8));
dstptr = (nsfb->ptr +
- (dsty * nsfb->linelen) +
- ((dstx * nsfb->bpp) / 8));
+ (dsty * nsfb->linelen) +
+ ((dstx * nsfb->bpp) / 8));
if (width == nsfb->width) {
- /* take shortcut and use memmove */
- memmove(dstptr, srcptr, (width * height * nsfb->bpp) / 8);
+ /* take shortcut and use memmove */
+ memmove(dstptr, srcptr, (width * height * nsfb->bpp) / 8);
} else {
- if (srcy > dsty) {
- for (hloop = height; hloop > 0; hloop--) {
- memmove(dstptr, srcptr, (width * nsfb->bpp) / 8);
- srcptr += nsfb->linelen;
- dstptr += nsfb->linelen;
- }
- } else {
- srcptr += height * nsfb->linelen;
- dstptr += height * nsfb->linelen;
- for (hloop = height; hloop > 0; hloop--) {
- srcptr -= nsfb->linelen;
- dstptr -= nsfb->linelen;
- memmove(dstptr, srcptr, (width * nsfb->bpp) / 8);
- }
- }
+ if (srcy > dsty) {
+ for (hloop = height; hloop > 0; hloop--) {
+ memmove(dstptr, srcptr, (width * nsfb->bpp) / 8);
+ srcptr += nsfb->linelen;
+ dstptr += nsfb->linelen;
+ }
+ } else {
+ srcptr += height * nsfb->linelen;
+ dstptr += height * nsfb->linelen;
+ for (hloop = height; hloop > 0; hloop--) {
+ srcptr -= nsfb->linelen;
+ dstptr -= nsfb->linelen;
+ memmove(dstptr, srcptr, (width * nsfb->bpp) / 8);
+ }
+ }
}
if ((cursor != NULL) &&
- (cursor->plotted == false)) {
- nsfb_cursor_plot(nsfb, cursor);
+ (cursor->plotted == false)) {
+ nsfb_cursor_plot(nsfb, cursor);
}
/* update the x window */
xcb_copy_area(xstate->connection,
- xstate->pmap,
- xstate->window,
- xstate->gc,
- dstx, dsty,
- dstx, dsty,
- width, height);
+ xstate->pmap,
+ xstate->window,
+ xstate->gc,
+ dstx, dsty,
+ dstx, dsty,
+ width, height);
return true;
}
+static int
+wld_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format)
+{
+}
-static int
+static int
x_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format)
{
if (nsfb->surface_priv != NULL)
- return -1; /* if were already initialised fail */
+ return -1; /* if were already initialised fail */
nsfb->width = width;
nsfb->height = height;
@@ -602,9 +606,9 @@ find_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp)
xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
for(; fmt != fmtend; ++fmt) {
- if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp)) {
- return fmt;
- }
+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp)) {
+ return fmt;
+ }
}
return 0;
}
@@ -627,24 +631,24 @@ create_shm_image(xstate_t *xstate, int width, int height, int bpp)
ck = xcb_shm_query_version(xstate->connection);
rep = xcb_shm_query_version_reply(xstate->connection, ck , NULL);
if (!rep) {
- fprintf (stderr, "Server has no shm support.\n");
- return NULL;
+ fprintf (stderr, "Server has no shm support.\n");
+ return NULL;
}
if ((rep->major_version < 1) ||
- (rep->major_version == 1 && rep->minor_version == 0)) {
- fprintf(stderr, "server SHM support is insufficient.\n");
- free(rep);
- return NULL;
+ (rep->major_version == 1 && rep->minor_version == 0)) {
+ fprintf(stderr, "server SHM support is insufficient.\n");
+ free(rep);
+ return NULL;
}
free(rep);
if (bpp == 32)
- depth = 24;
+ depth = 24;
fmt = find_format(xstate->connection, depth, bpp);
if (fmt == NULL)
- return NULL;
+ return NULL;
/* doing it this way ensures we deal with bpp smaller than 8 */
image_size = (bpp * width * height) >> 3;
@@ -652,7 +656,7 @@ create_shm_image(xstate_t *xstate, int width, int height, int bpp)
/* get the shared memory segment */
shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777);
if (shmid == -1)
- return NULL;
+ return NULL;
xstate->shminfo.shmid = shmid;
@@ -662,7 +666,7 @@ create_shm_image(xstate_t *xstate, int width, int height, int bpp)
xstate->shminfo.shmseg = xcb_generate_id(xstate->connection);
shm_attach_cookie = xcb_shm_attach_checked(xstate->connection,
xstate->shminfo.shmseg,
- xstate->shminfo.shmid,
+ xstate->shminfo.shmid,
0);
generic_error = xcb_request_check(xstate->connection, shm_attach_cookie);
@@ -673,26 +677,26 @@ create_shm_image(xstate_t *xstate, int width, int height, int bpp)
shmctl(xstate->shminfo.shmid, IPC_RMID, 0);
if (generic_error != NULL) {
- /* unable to attach shm */
- xstate->shminfo.shmseg = 0;
+ /* unable to attach shm */
+ xstate->shminfo.shmseg = 0;
- free(generic_error);
- return NULL;
+ free(generic_error);
+ return NULL;
}
return xcb_image_create(width,
- height,
- XCB_IMAGE_FORMAT_Z_PIXMAP,
- fmt->scanline_pad,
- fmt->depth,
- fmt->bits_per_pixel,
- 0,
- setup->image_byte_order,
- XCB_IMAGE_ORDER_LSB_FIRST,
- image_data,
- image_size,
- image_data);
+ height,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ fmt->scanline_pad,
+ fmt->depth,
+ fmt->bits_per_pixel,
+ 0,
+ setup->image_byte_order,
+ XCB_IMAGE_ORDER_LSB_FIRST,
+ image_data,
+ image_size,
+ image_data);
}
@@ -706,31 +710,31 @@ create_image(xcb_connection_t *c, int width, int height, int bpp)
uint32_t image_size;
if (bpp == 32)
- depth = 24;
+ depth = 24;
fmt = find_format(c, depth, bpp);
if (fmt == NULL)
- return NULL;
+ return NULL;
/* doing it this way ensures we deal with bpp smaller than 8 */
image_size = (bpp * width * height) >> 3;
image_data = calloc(1, image_size);
if (image_data == NULL)
- return NULL;
+ return NULL;
return xcb_image_create(width,
- height,
- XCB_IMAGE_FORMAT_Z_PIXMAP,
- fmt->scanline_pad,
- fmt->depth,
- fmt->bits_per_pixel,
- 0,
- setup->image_byte_order,
- XCB_IMAGE_ORDER_LSB_FIRST,
- image_data,
- image_size,
- image_data);
+ height,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ fmt->scanline_pad,
+ fmt->depth,
+ fmt->bits_per_pixel,
+ 0,
+ setup->image_byte_order,
+ XCB_IMAGE_ORDER_LSB_FIRST,
+ image_data,
+ image_size,
+ image_data);
}
/**
@@ -751,22 +755,386 @@ create_blank_cursor(xcb_connection_t *conn, const xcb_screen_t *scr)
ck = xcb_create_pixmap_checked (conn, 1, pix, scr->root, 1, 1);
err = xcb_request_check (conn, ck);
if (err) {
- fprintf (stderr, "Cannot create pixmap: %d", err->error_code);
- free (err);
+ fprintf (stderr, "Cannot create pixmap: %d", err->error_code);
+ free (err);
}
ck = xcb_create_cursor_checked (conn, cur, pix, pix, 0, 0, 0, 0, 0, 0, 0, 0);
err = xcb_request_check (conn, ck);
if (err) {
- fprintf (stderr, "Cannot create cursor: %d", err->error_code);
- free (err);
+ fprintf (stderr, "Cannot create cursor: %d", err->error_code);
+ free (err);
}
return cur;
}
-static int wl_initialise(nsfb_t *nsfb)
+/** structure for display, registry and other global objects that
+ * should be cached when connecting to a wayland instance
+ */
+struct wld_connection {
+ struct wl_display *display; /**< connection object */
+ struct wl_registry *registry; /**< registry object */
+
+ /** compositor object, available once teh registry messages have
+ * been processed
+ */
+ struct wl_compositor *compositor;
+
+ /** shell object, available once the registry messages have been
+ * processed
+ */
+ struct wl_shell *shell;
+
+ /** shared memory object, available once the registry messages
+ * have been processed
+ */
+ struct wl_shm *shm;
+
+ /** shared memory formats available */
+ uint32_t shm_formats;
+};
+
+
+/** shared memory interface format available callback
+ *
+ * @param ctx context from when listener was added.
+ * @param wl_shm The shared memory object.
+ * @param format The available shared memory format. Found in
+ * wayland-client-protocol.h there are currently only two
+ * formats available (A|X)RGB8888 so using a bitfield is ok.
+ */
+static void
+shm_format(void *ctx, struct wl_shm *wl_shm, uint32_t format)
+{
+ struct wld_connection* connection = ctx;
+
+ connection->shm_formats |= (1 << format);
+}
+
+/** shared memory interface callback handlers */
+struct wl_shm_listener shm_listenter = {
+ shm_format
+};
+
+
+/** registry global addition callback
+ *
+ * @param ctx context from when listener was added
+ */
+static void
+registry_handle_global(void *ctx,
+ struct wl_registry *registry,
+ uint32_t id,
+ const char *interface,
+ uint32_t version)
+{
+ struct wld_connection* connection = ctx;
+
+ /* process new interfaces appearing on the global registry */
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ /* compositor interface is available. Bind the interface */
+ connection->compositor = wl_registry_bind(registry,
+ id,
+ &wl_compositor_interface,
+ 1);
+
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ /* shell interface is available. Bind the interface */
+ connection->shell = wl_registry_bind(registry,
+ id,
+ &wl_shell_interface,
+ 1);
+
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ /* shared memory interface is available. Bind the interface
+ * and add a listener for the shared memory callbacks
+ */
+ connection->shm = wl_registry_bind(registry,
+ id,
+ &wl_shm_interface,
+ 1);
+ if (connection->shm != NULL) {
+ connection->shm_formats = 0;
+ wl_shm_add_listener(connection->shm, &shm_listenter, connection);
+ }
+ }
+}
+
+/** registry global removal callback */
+static void
+registry_handle_global_remove(void *data,
+ struct wl_registry *registry,
+ uint32_t name)
+{
+}
+
+/** registry global callback handlers */
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+
+/** construct a new connection to the wayland instance and aquire all
+ * necessary global objects
+ */
+static struct wld_connection*
+new_connection(void)
+{
+ struct wld_connection* connection;
+
+ connection = calloc(1, sizeof(struct wld_connection));
+
+ if (connection == NULL) {
+ return NULL;
+ }
+
+ /* make a connection to the wayland server */
+ connection->display = wl_display_connect(NULL);
+ if (connection->display == NULL) {
+ fprintf(stderr, "Unable to open display\n");
+ free(connection);
+ return NULL;
+ }
+
+ /* create the registry object and attach its callback handlers */
+ connection->registry = wl_display_get_registry(connection->display);
+ if (connection->registry == NULL) {
+ fprintf(stderr, "Unable create registry\n");
+ wl_display_flush(connection->display);
+ wl_display_disconnect(connection->display);
+ free(connection);
+ return NULL;
+ }
+
+ wl_registry_add_listener(connection->registry,
+ &registry_listener,
+ connection);
+ /* perform a round trip to ensure registry messages have been processed */
+ wl_display_roundtrip(connection->display);
+
+ /* all global objects from the registry should now be available. */
+
+ if (connection->shm == NULL) {
+ /* The shared memory interface is available so fail. */
+ fprintf(stderr, "No shared memory interface available\n");
+
+ free_connection(connection);
+
+ return NULL;
+ }
+
+ /* perform a round trip to ensure interface messages have been processed */
+ wl_display_roundtrip(connection->display);
+
+ /* check the XRGB8888 shared memory format is available */
+ if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
+ fprintf(stderr, "WL_SHM_FORMAT_XRGB8888 not available\n");
+
+ free_connection(connection);
+
+ return NULL;
+ }
+
+ return connection;
+}
+
+static void
+free_connection(struct wld_connection* connection)
+{
+ if (connection->compositor != NULL) {
+ wl_compositor_destroy(connection->compositor);
+ }
+
+ if (connection->shell != NULL) {
+ wl_shell_destroy(connection->shell);
+ }
+
+ if (connection->shm != NULL) {
+ wl_shm_destroy(connection->shm);
+ }
+
+ wl_registry_destroy(connection->registry);
+
+ wl_display_flush(connection->display);
+
+ wl_display_disconnect(connection->display);
+
+ free(connection);
+}
+
+typedef struct wldstate_s {
+ struct wld_connection* connection; /**< connection to wayland server */
+ struct wld_window *window;
+#if 0
+ xcb_connection_t *connection; /* The x server connection */
+ xcb_screen_t *screen; /* The screen to put the window on */
+ xcb_key_symbols_t *keysymbols; /* keysym mappings */
+
+ xcb_shm_segment_info_t shminfo;
+
+ xcb_image_t *image; /* The X image buffer */
+
+ xcb_window_t window; /* The handle to the window */
+ xcb_pixmap_t pmap; /* The handle to the backing pixmap */
+ xcb_gcontext_t gc; /* The handle to the pixmap plotting graphics context */
+ xcb_shm_seg_t segment; /* The handle to the image shared memory */
+#endif
+
+} wldstate_t;
+
+/* wayland window encompasing the display and shell surfaces */
+struct wld_window {
+ struct wld_connection* connection; /**< connection to wayland server */
+
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+ struct wl_callback *callback;
+
+ int width, height;
+
+#if 0
+ struct buffer buffers[2];
+ struct buffer *prev_buffer;
+#endif
+};
+
+static void
+handle_ping(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t serial)
+{
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+handle_configure(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+}
+
+static void
+handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
{
}
+static const struct wl_shell_surface_listener shell_surface_listener = {
+ handle_ping,
+ handle_configure,
+ handle_popup_done
+};
+
+static struct wld_window *
+new_window(struct wld_connection *connection, int width, int height)
+{
+ struct wld_window *window;
+
+ window = calloc(1, sizeof *window);
+ if (window == NULL) {
+ return NULL;
+ }
+
+ window->connection = connection;
+ window->callback = NULL;
+ window->width = width;
+ window->height = height;
+
+ window->surface = wl_compositor_create_surface(connection->compositor);
+ if (window->surface == NULL) {
+ fprintf(stderr, "failed to create compositor surface\n");
+ free(window);
+ return NULL;
+ }
+
+ window->shell_surface = wl_shell_get_shell_surface(connection->shell,
+ window->surface);
+ if (window->shell_surface == NULL) {
+ fprintf(stderr, "failed to create shell surface\n");
+
+ wl_surface_destroy(window->surface);
+
+ free(window);
+ return NULL;
+ }
+
+ wl_shell_surface_add_listener(window->shell_surface,
+ &shell_surface_listener, window);
+
+ wl_shell_surface_set_title(window->shell_surface, "nsfb");
+
+ wl_shell_surface_set_toplevel(window->shell_surface);
+
+ return window;
+}
+
+static void
+free_window(struct wld_window *window)
+{
+ if (window->callback != NULL) {
+
+ wl_callback_destroy(window->callback);
+ }
+
+ wl_shell_surface_destroy(window->shell_surface);
+ wl_surface_destroy(window->surface);
+
+ free(window);
+}
+
+
+static int wld_initialise(nsfb_t *nsfb)
+{
+ wldstate_t *wldstate = nsfb->surface_priv;
+
+ if (wldstate != NULL)
+ return -1; /* already initialised */
+
+ /* check bpp is what we can support. */
+ if (nsfb->bpp != 32) {
+ return -1;
+ }
+
+ wldstate = calloc(1, sizeof(wldstate_t));
+ if (wldstate == NULL) {
+ return -1; /* no memory */
+ }
+
+ wldstate->connection = new_connection();
+ if (wldstate->connection == NULL) {
+ fprintf(stderr, "Error initialising wayland connection\n");
+ free(wldstate);
+ return -1; /* error */
+ }
+
+ wldstate->window = new_window(wldstate->connection,
+ nsfb->width,
+ nsfb->height);
+ if (wldstate->connection == NULL) {
+ fprintf(stderr, "Error creating wayland window\n");
+
+ free_connection(wldstate->connection);
+
+ free(wldstate);
+ return -1; /* error */
+ }
+
+ nsfb->surface_priv = wldstate;
+
+ return 0;
+}
+
+static int wld_finalise(nsfb_t *nsfb)
+{
+ wldstate_t *wldstate = nsfb->surface_priv;
+
+ if (wldstate == NULL) {
+ return 0; /* not initialised */
+ }
+
+ free_window(wldstate->window);
+
+ free_connection(wldstate->connection);
+}
+
static int x_initialise(nsfb_t *nsfb)
{
uint32_t mask;
@@ -776,28 +1144,28 @@ static int x_initialise(nsfb_t *nsfb)
xcb_cursor_t blank_cursor;
if (xstate != NULL)
- return -1; /* already initialised */
+ return -1; /* already initialised */
/* sanity check bpp. */
if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8))
- return -1;
+ return -1;
xstate = calloc(1, sizeof(xstate_t));
if (xstate == NULL)
- return -1; /* no memory */
+ return -1; /* no memory */
/* open connection with the server */
xstate->connection = xcb_connect(NULL, NULL);
if (xstate->connection == NULL) {
- fprintf(stderr, "Memory error opening display\n");
- free(xstate);
- return -1; /* no memory */
+ fprintf(stderr, "Memory error opening display\n");
+ free(xstate);
+ return -1; /* no memory */
}
if (xcb_connection_has_error(xstate->connection) != 0) {
- fprintf(stderr, "Error opening display\n");
- free(xstate);
- return -1; /* no memory */
+ fprintf(stderr, "Error opening display\n");
+ free(xstate);
+ return -1; /* no memory */
}
/* get screen */
@@ -807,13 +1175,13 @@ static int x_initialise(nsfb_t *nsfb)
xstate->image = create_shm_image(xstate, nsfb->width, nsfb->height, nsfb->bpp);
if (xstate->image == NULL)
- xstate->image = create_image(xstate->connection, nsfb->width, nsfb->height, nsfb->bpp);
+ xstate->image = create_image(xstate->connection, nsfb->width, nsfb->height, nsfb->bpp);
if (xstate->image == NULL) {
- fprintf(stderr, "Unable to create image\n");
- free(xstate);
- xcb_disconnect(xstate->connection);
- return -1;
+ fprintf(stderr, "Unable to create image\n");
+ free(xstate);
+ xcb_disconnect(xstate->connection);
+ return -1;
}
/* ensure plotting information is stored */
@@ -834,19 +1202,19 @@ static int x_initialise(nsfb_t *nsfb)
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS |
- XCB_EVENT_MASK_BUTTON_RELEASE |
- XCB_EVENT_MASK_POINTER_MOTION;
+ XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_POINTER_MOTION;
values[2] = blank_cursor;
xstate->window = xcb_generate_id(xstate->connection);
xcb_create_window (xstate->connection,
- XCB_COPY_FROM_PARENT,
- xstate->window,
- xstate->screen->root,
- 0, 0, xstate->image->width, xstate->image->height, 1,
- XCB_WINDOW_CLASS_INPUT_OUTPUT,
- xstate->screen->root_visual,
- mask, values);
+ XCB_COPY_FROM_PARENT,
+ xstate->window,
+ xstate->screen->root,
+ 0, 0, xstate->image->width, xstate->image->height, 1,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ xstate->screen->root_visual,
+ mask, values);
/* set size hits on window */
hints = xcb_alloc_size_hints();
xcb_size_hints_set_max_size(hints, xstate->image->width, xstate->image->height);
@@ -867,7 +1235,7 @@ static int x_initialise(nsfb_t *nsfb)
xcb_create_gc(xstate->connection, xstate->gc, xstate->pmap, mask, values);
/* if (nsfb->bpp == 8)
- set_palette(nsfb);
+ set_palette(nsfb);
*/
/* put the image into the pixmap */
@@ -885,7 +1253,7 @@ static int x_finalise(nsfb_t *nsfb)
{
xstate_t *xstate = nsfb->surface_priv;
if (xstate == NULL)
- return 0;
+ return 0;
xcb_key_symbols_free(xstate->keysymbols);
@@ -898,6 +1266,10 @@ static int x_finalise(nsfb_t *nsfb)
return 0;
}
+static bool wld_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+}
+
static bool x_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
{
xcb_generic_event_t *e;
@@ -909,7 +1281,7 @@ static bool x_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
xstate_t *xstate = nsfb->surface_priv;
if (xstate == NULL)
- return false;
+ return false;
xcb_flush(xstate->connection);
@@ -917,133 +1289,133 @@ static bool x_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
e = xcb_poll_for_event(xstate->connection);
if ((e == NULL) && (timeout != 0)) {
- if (timeout > 0) {
- int confd;
- fd_set rfds;
- struct timeval tv;
- int retval;
+ if (timeout > 0) {
+ int confd;
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
- confd = xcb_get_file_descriptor(xstate->connection);
- FD_ZERO(&rfds);
- FD_SET(confd, &rfds);
+ confd = xcb_get_file_descriptor(xstate->connection);
+ FD_ZERO(&rfds);
+ FD_SET(confd, &rfds);
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = timeout % 1000;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = timeout % 1000;
- retval = select(confd + 1, &rfds, NULL, NULL, &tv);
- if (retval == 0) {
+ retval = select(confd + 1, &rfds, NULL, NULL, &tv);
+ if (retval == 0) {
/* timeout, nothing happened */
event->type = NSFB_EVENT_CONTROL;
event->value.controlcode = NSFB_CONTROL_TIMEOUT;
return true;
- }
- }
- e = xcb_wait_for_event(xstate->connection);
+ }
+ }
+ e = xcb_wait_for_event(xstate->connection);
}
if (e == NULL) {
- if (xcb_connection_has_error(xstate->connection) != 0) {
- /* connection closed quiting time */
- event->type = NSFB_EVENT_CONTROL;
- event->value.controlcode = NSFB_CONTROL_QUIT;
- return true;
- } else {
- return false; /* no event */
- }
+ if (xcb_connection_has_error(xstate->connection) != 0) {
+ /* connection closed quiting time */
+ event->type = NSFB_EVENT_CONTROL;
+ event->value.controlcode = NSFB_CONTROL_QUIT;
+ return true;
+ } else {
+ return false; /* no event */
+ }
}
event->type = NSFB_EVENT_NONE;
switch (e->response_type) {
case XCB_EXPOSE:
- ee = (xcb_expose_event_t *)e;
- xcb_copy_area(xstate->connection,
- xstate->pmap,
- xstate->window,
- xstate->gc,
- ee->x, ee->y,
- ee->x, ee->y,
- ee->width, ee->height);
- xcb_flush (xstate->connection);
- break;
+ ee = (xcb_expose_event_t *)e;
+ xcb_copy_area(xstate->connection,
+ xstate->pmap,
+ xstate->window,
+ xstate->gc,
+ ee->x, ee->y,
+ ee->x, ee->y,
+ ee->width, ee->height);
+ xcb_flush (xstate->connection);
+ break;
case XCB_MOTION_NOTIFY:
- emn = (xcb_motion_notify_event_t *)e;
- event->type = NSFB_EVENT_MOVE_ABSOLUTE;
- event->value.vector.x = emn->event_x;
- event->value.vector.y = emn->event_y;
- event->value.vector.z = 0;
- break;
+ emn = (xcb_motion_notify_event_t *)e;
+ event->type = NSFB_EVENT_MOVE_ABSOLUTE;
+ event->value.vector.x = emn->event_x;
+ event->value.vector.y = emn->event_y;
+ event->value.vector.z = 0;
+ break;
case XCB_BUTTON_PRESS:
- ebp = (xcb_button_press_event_t *)e;
- event->type = NSFB_EVENT_KEY_DOWN;
+ ebp = (xcb_button_press_event_t *)e;
+ event->type = NSFB_EVENT_KEY_DOWN;
- switch (ebp->detail) {
+ switch (ebp->detail) {
- case X_BUTTON_LEFT:
- event->value.keycode = NSFB_KEY_MOUSE_1;
- break;
+ case X_BUTTON_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
- case X_BUTTON_MIDDLE:
- event->value.keycode = NSFB_KEY_MOUSE_2;
- break;
+ case X_BUTTON_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
- case X_BUTTON_RIGHT:
- event->value.keycode = NSFB_KEY_MOUSE_3;
- break;
+ case X_BUTTON_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
- case X_BUTTON_WHEELUP:
- event->value.keycode = NSFB_KEY_MOUSE_4;
- break;
+ case X_BUTTON_WHEELUP:
+ event->value.keycode = NSFB_KEY_MOUSE_4;
+ break;
- case X_BUTTON_WHEELDOWN:
- event->value.keycode = NSFB_KEY_MOUSE_5;
- break;
- }
- break;
+ case X_BUTTON_WHEELDOWN:
+ event->value.keycode = NSFB_KEY_MOUSE_5;
+ break;
+ }
+ break;
case XCB_BUTTON_RELEASE:
- ebp = (xcb_button_press_event_t *)e;
- event->type = NSFB_EVENT_KEY_UP;
+ ebp = (xcb_button_press_event_t *)e;
+ event->type = NSFB_EVENT_KEY_UP;
- switch (ebp->detail) {
+ switch (ebp->detail) {
- case X_BUTTON_LEFT:
- event->value.keycode = NSFB_KEY_MOUSE_1;
- break;
+ case X_BUTTON_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
- case X_BUTTON_MIDDLE:
- event->value.keycode = NSFB_KEY_MOUSE_2;
- break;
+ case X_BUTTON_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
- case X_BUTTON_RIGHT:
- event->value.keycode = NSFB_KEY_MOUSE_3;
- break;
+ case X_BUTTON_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
- case X_BUTTON_WHEELUP:
- event->value.keycode = NSFB_KEY_MOUSE_4;
- break;
+ case X_BUTTON_WHEELUP:
+ event->value.keycode = NSFB_KEY_MOUSE_4;
+ break;
- case X_BUTTON_WHEELDOWN:
- event->value.keycode = NSFB_KEY_MOUSE_5;
- break;
- }
- break;
+ case X_BUTTON_WHEELDOWN:
+ event->value.keycode = NSFB_KEY_MOUSE_5;
+ break;
+ }
+ break;
case XCB_KEY_PRESS:
- ekp = (xcb_key_press_event_t *)e;
- event->type = NSFB_EVENT_KEY_DOWN;
- event->value.keycode = xkeysym_to_nsfbkeycode(xcb_key_symbols_get_keysym(xstate->keysymbols, ekp->detail, 0));
- break;
+ ekp = (xcb_key_press_event_t *)e;
+ event->type = NSFB_EVENT_KEY_DOWN;
+ event->value.keycode = xkeysym_to_nsfbkeycode(xcb_key_symbols_get_keysym(xstate->keysymbols, ekp->detail, 0));
+ break;
case XCB_KEY_RELEASE:
- ekr = (xcb_key_release_event_t *)e;
- event->type = NSFB_EVENT_KEY_UP;
- event->value.keycode = xkeysym_to_nsfbkeycode(xcb_key_symbols_get_keysym(xstate->keysymbols, ekr->detail, 0));
- break;
+ ekr = (xcb_key_release_event_t *)e;
+ event->type = NSFB_EVENT_KEY_UP;
+ event->value.keycode = xkeysym_to_nsfbkeycode(xcb_key_symbols_get_keysym(xstate->keysymbols, ekr->detail, 0));
+ break;
}
@@ -1052,19 +1424,27 @@ static bool x_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
return true;
}
+static int wld_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+}
+
static int x_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
{
struct nsfb_cursor_s *cursor = nsfb->cursor;
if ((cursor != NULL) &&
- (cursor->plotted == true) &&
- (nsfb_plot_bbox_intersect(box, &cursor->loc))) {
- nsfb_cursor_clear(nsfb, cursor);
+ (cursor->plotted == true) &&
+ (nsfb_plot_bbox_intersect(box, &cursor->loc))) {
+ nsfb_cursor_clear(nsfb, cursor);
}
return 0;
}
+static int
+wld_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+}
static int
x_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
@@ -1075,29 +1455,32 @@ x_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
if ((cursor != NULL) && (cursor->plotted == true)) {
- nsfb_plot_add_rect(&cursor->savloc, &cursor->loc, &redraw);
+ nsfb_plot_add_rect(&cursor->savloc, &cursor->loc, &redraw);
- /* screen area */
- fbarea.x0 = 0;
- fbarea.y0 = 0;
- fbarea.x1 = nsfb->width;
- fbarea.y1 = nsfb->height;
+ /* screen area */
+ fbarea.x0 = 0;
+ fbarea.y0 = 0;
+ fbarea.x1 = nsfb->width;
+ fbarea.y1 = nsfb->height;
- nsfb_plot_clip(&fbarea, &redraw);
+ nsfb_plot_clip(&fbarea, &redraw);
- nsfb_cursor_clear(nsfb, cursor);
+ nsfb_cursor_clear(nsfb, cursor);
- nsfb_cursor_plot(nsfb, cursor);
+ nsfb_cursor_plot(nsfb, cursor);
- /* TODO: This is hediously ineficient - should keep the pointer image
- * as a pixmap and plot server side
- */
- update_and_redraw_pixmap(xstate, redraw.x0, redraw.y0, redraw.x1 - redraw.x0, redraw.y1 - redraw.y0);
+ /* TODO: This is hediously ineficient - should keep the pointer image
+ * as a pixmap and plot server side
+ */
+ update_and_redraw_pixmap(xstate, redraw.x0, redraw.y0, redraw.x1 - redraw.x0, redraw.y1 - redraw.y0);
}
return true;
}
+static int wld_update(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+}
static int x_update(nsfb_t *nsfb, nsfb_bbox_t *box)
{
@@ -1106,7 +1489,7 @@ static int x_update(nsfb_t *nsfb, nsfb_bbox_t *box)
if ((cursor != NULL) &&
(cursor->plotted == false)) {
- nsfb_cursor_plot(nsfb, cursor);
+ nsfb_cursor_plot(nsfb, cursor);
}
update_and_redraw_pixmap(xstate, box->x0, box->y0, box->x1 - box->x0, box->y1 - box->y0);
@@ -1114,17 +1497,17 @@ static int x_update(nsfb_t *nsfb, nsfb_bbox_t *box)
return 0;
}
-const nsfb_surface_rtns_t wl_rtns = {
- .initialise = x_initialise,
- .finalise = x_finalise,
- .input = x_input,
- .claim = x_claim,
- .update = x_update,
- .cursor = x_cursor,
- .geometry = x_set_geometry,
+const nsfb_surface_rtns_t wld_rtns = {
+ .initialise = wld_initialise,
+ .finalise = wld_finalise,
+ .input = wld_input,
+ .claim = wld_claim,
+ .update = wld_update,
+ .cursor = wld_cursor,
+ .geometry = wld_set_geometry,
};
-NSFB_SURFACE_DEF(wl, NSFB_SURFACE_WL, &wl_rtns)
+NSFB_SURFACE_DEF(wld, NSFB_SURFACE_WL, &wld_rtns)
/*
* Local variables:
diff --git a/src/surface/x.c b/src/surface/x.c
index b9c3429..f5ee01b 100644
--- a/src/surface/x.c
+++ b/src/surface/x.c
@@ -79,8 +79,8 @@ typedef struct xstate_s {
xcb_shm_seg_t segment; /* The handle to the image shared memory */
} xstate_t;
-/* X keyboard codepage to nsfb mapping*/
-enum nsfb_key_code_e XCSKeyboardMap[256] = {
+/* X keyboard codepage to nsfb mapping */
+static enum nsfb_key_code_e XCSKeyboardMap[256] = {
NSFB_KEY_UNKNOWN, /* */
NSFB_KEY_UNKNOWN, /* */
NSFB_KEY_UNKNOWN, /* */
diff --git a/test/runtest.sh b/test/runtest.sh
index 81739c5..464cacb 100755
--- a/test/runtest.sh
+++ b/test/runtest.sh
@@ -2,7 +2,7 @@
TEST_PATH=$1
-TEST_FRONTEND=wl
+TEST_FRONTEND=wld
${TEST_PATH}/test_frontend ${TEST_FRONTEND}
${TEST_PATH}/test_plottest ${TEST_FRONTEND}