diff options
author | Vincent Sanders <vincent.sanders@collabora.co.uk> | 2013-03-21 18:05:54 +0000 |
---|---|---|
committer | Vincent Sanders <vincent.sanders@collabora.co.uk> | 2013-03-21 18:05:54 +0000 |
commit | f75a698b15f978c854cc424ee79a38e157165091 (patch) | |
tree | 675badfbfadf62498370333cab889f7bb5cea41e /src/surface | |
parent | 4b1e1482c42b31277acf96377013e716521982aa (diff) | |
download | libnsfb-f75a698b15f978c854cc424ee79a38e157165091.tar.gz libnsfb-f75a698b15f978c854cc424ee79a38e157165091.tar.bz2 |
initial wayland surface connection
Diffstat (limited to 'src/surface')
-rw-r--r-- | src/surface/Makefile | 24 | ||||
-rw-r--r-- | src/surface/wld.c (renamed from src/surface/wl.c) | 967 | ||||
-rw-r--r-- | src/surface/x.c | 4 |
3 files changed, 687 insertions, 308 deletions
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, + ®istry_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, /* */ |