diff options
author | Keith Packard <keithp@keithp.com> | 2014-01-30 12:11:34 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2014-01-30 12:11:34 -0800 |
commit | 8ec3e0a5b1cf9d94c5e1b3d66b979ef9e9019aa8 (patch) | |
tree | 392c8c606a066497cc255fb407e324d171abd4ce | |
parent | 739c624630154b422d7f5e4ae92f93df42fa35b9 (diff) |
shmfd example: use O_TMPFILE. Create multiple segments
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | shmfd.c | 60 |
1 files changed, 55 insertions, 5 deletions
@@ -27,17 +27,43 @@ #include <xcb/shm.h> #include <xcb/xcb_aux.h> #include <unistd.h> +#include <fcntl.h> + +#define __O_TMPFILE 020000000 +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) int -make_shm(int size, void **addrp) +shm_tmpfile(void) { - void *addr; + int fd; + int flags; char template[] = "/run/shm/shmfd-XXXXXX"; - int fd = mkstemp(template); - - if (fd < 0) +#ifdef O_TMPFILE + fd = open("/run/shm", O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666); + if (fd >= 0) { + printf ("Using O_TMPFILE\n"); return fd; + } + printf ("Not using O_TMPFILE\n"); + perror("O_TMPFILE"); +#endif + fd = mkstemp(template); + if (fd < 0) + return -1; unlink(template); + if (fcntl(fd, F_GETFD, &flags) >= 0) { + flags |= FD_CLOEXEC; + (void) fcntl(fd, F_SETFD, &flags); + } + return fd; +} + +int +make_shm(int size, void **addrp) +{ + void *addr; + int fd = shm_tmpfile(); + ftruncate(fd, size); addr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { @@ -78,16 +104,21 @@ main (int argc, char **argv) xcb_screen_t *screen; int fd; int segment_fd; + int segment_fd_2; void *addr; void *server_addr; + void *server_addr_2; xcb_shm_seg_t shm_seg; xcb_shm_seg_t shm_server_seg; + xcb_shm_seg_t shm_server_seg_2; xcb_gc_t gc; xcb_window_t window; xcb_generic_event_t *event; xcb_generic_error_t *error; xcb_shm_create_segment_cookie_t shm_create_segment_cookie; + xcb_shm_create_segment_cookie_t shm_create_segment_cookie_2; xcb_shm_create_segment_reply_t *shm_create_segment_reply; + xcb_shm_create_segment_reply_t *shm_create_segment_reply_2; xcb_generic_error_t *shm_create_segment_error; int *shm_create_segment_fds; uint32_t window_mask; @@ -113,6 +144,13 @@ main (int argc, char **argv) (shm_server_seg = xcb_generate_id(c)), size, 1); + shm_create_segment_cookie_2 = xcb_shm_create_segment(c, + (shm_server_seg_2 = xcb_generate_id(c)), + size, + 1); + shm_create_segment_reply_2 = xcb_shm_create_segment_reply (c, + shm_create_segment_cookie_2, + &shm_create_segment_error); shm_create_segment_reply = xcb_shm_create_segment_reply (c, shm_create_segment_cookie, &shm_create_segment_error); @@ -128,6 +166,18 @@ main (int argc, char **argv) else server_addr = NULL; + if (shm_create_segment_reply_2) { + shm_create_segment_fds = xcb_shm_create_segment_reply_fds(c, + shm_create_segment_reply_2); + segment_fd_2 = shm_create_segment_fds[0]; + + server_addr_2 = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, segment_fd_2, 0); + free(shm_create_segment_reply_2); +// paint(server_addr_2, WIDTH, HEIGHT, 1); + } + else + server_addr_2 = NULL; + window_mask = XCB_CW_BACK_PIXEL|XCB_CW_EVENT_MASK; window_values[0] = 0xffffff; window_values[1] = XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_KEY_PRESS; |