aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libaxl_connect_without_handshake.c3
-rw-r--r--libaxl_receive_handshake.c34
-rw-r--r--libaxl_send_request.c29
3 files changed, 53 insertions, 13 deletions
diff --git a/libaxl_connect_without_handshake.c b/libaxl_connect_without_handshake.c
index 181cdb2..e05dd66 100644
--- a/libaxl_connect_without_handshake.c
+++ b/libaxl_connect_without_handshake.c
@@ -62,6 +62,7 @@ libaxl_connect_without_handshake(const char *host, const char *protocol, int dis
if ((!protocol || !*protocol) && (!host || !*host)) {
sprintf(path, "/tmp/.X11-unix/X%i", display);
fd = connect_unix(path);
+ /* TODO also try abstract address version with a NUL byte before it (truncate address to remove tailing NULs) */
if (fd < 0) {
fd = connect_tcp_ip("localhost", display);
if (fd >= 0)
@@ -88,7 +89,7 @@ libaxl_connect_without_handshake(const char *host, const char *protocol, int dis
conn = libaxl_create(fd);
if (conn)
- conn->info.default_screen_number = screen;
+ conn->info.default_screen_number = screen < 0 ? 0 : screen;
return conn;
}
diff --git a/libaxl_receive_handshake.c b/libaxl_receive_handshake.c
index d26a5d4..f37fe88 100644
--- a/libaxl_receive_handshake.c
+++ b/libaxl_receive_handshake.c
@@ -50,11 +50,13 @@ libaxl_receive_handshake(LIBAXL_CONTEXT *restrict ctx, int *restrict majorp, int
{
LIBAXL_CONNECTION *conn = ctx->conn;
char *restrict inbuf, *new;
- size_t i, n, t, len, vendor_len, out_off, in_off;
+ size_t i, j, k, n, t, len, vendor_len, out_off, in_off;
ssize_t r;
int read_stage = 0, saved_errno, status;
struct response *resp;
uint32_t xid_base, xid_mask;
+ struct libaxl_screen *screen;
+ struct libaxl_depth *depth;
#ifdef MSG_TRUNC
int flag_trunc;
#endif
@@ -205,7 +207,7 @@ continue_read:
conn->info_buf = inbuf;
conn->info.vendor = inbuf;
conn->info.formats = (void *)&inbuf[t];
- conn->info.screens = (void *)&inbuf[t + conn->info.nformats * 8];
+ conn->info.screens = screen = (void *)&inbuf[t + conn->info.nformats * 8];
if ((size_t)conn->info.default_screen_number < conn->info.nscreens) {
conn->info.default_screen = conn->info.screens;
for (i = 0; i < (size_t)conn->info.default_screen_number; i++)
@@ -214,6 +216,34 @@ continue_read:
conn->info.default_screen = NULL;
}
+ for (i = 0; i < (size_t)conn->info.nscreens; i++) {
+ screen->root = ntohl(screen->root);
+ screen->default_colormap = ntohl(screen->default_colormap);
+ screen->white_pixel = ntohl(screen->white_pixel);
+ screen->black_pixel = ntohl(screen->black_pixel);
+ screen->current_input_masks = ntohl(screen->current_input_masks);
+ screen->width_in_pixels = ntohs(screen->width_in_pixels);
+ screen->height_in_pixels = ntohs(screen->height_in_pixels);
+ screen->width_in_millimeters = ntohs(screen->width_in_millimeters);
+ screen->height_in_millimeters = ntohs(screen->height_in_millimeters);
+ screen->min_installed_maps = ntohs(screen->min_installed_maps);
+ screen->max_installed_maps = ntohs(screen->max_installed_maps);
+ screen->root_visual = ntohs(screen->root_visual);
+ depth = screen->allowed_depths;
+ for (j = 0; j < (size_t)screen->number_of_allowed_depths; j++) {
+ depth->number_of_visuals = ntohs(depth->number_of_visuals);
+ for (k = 0; k < (size_t)depth->number_of_visuals; k++) {
+ depth->visuals[k].visual_id = ntohl(depth->visuals[k].visual_id);
+ depth->visuals[k].colormap_entries = ntohs(depth->visuals[k].colormap_entries);
+ depth->visuals[k].red_mask = ntohl(depth->visuals[k].red_mask);
+ depth->visuals[k].green_mask = ntohl(depth->visuals[k].green_mask);
+ depth->visuals[k].blue_mask = ntohl(depth->visuals[k].blue_mask);
+ }
+ depth = (void *)(uintptr_t)&depth->visuals[depth->number_of_visuals];
+ }
+ screen = (void *)(uintptr_t)depth;
+ }
+
ctx->in_buf_size = 0;
ctx->in_buf = NULL;
break;
diff --git a/libaxl_send_request.c b/libaxl_send_request.c
index 471da0b..11352c8 100644
--- a/libaxl_send_request.c
+++ b/libaxl_send_request.c
@@ -180,6 +180,8 @@ libaxl_send_request(LIBAXL_CONTEXT *restrict ctx, union libaxl_request_const_ptr
uint32_t mask;
char *buf = ctx->out_buf, *subbuf, *new;
size_t size = ctx->out_buf_size;
+ uint16_t u16;
+ uint32_t u32;
RLOCK_CONNECTION_SEND(conn);
pending = conn->pending_out;
@@ -225,12 +227,15 @@ again:
case '_':
buf[o++] = 0; /* need not be 0 */
+ i += 1;
/* fall through */
case ',':
buf[o++] = 0; /* need not be 0 */
+ i += 1;
/* fall through */
case '.':
buf[o++] = 0; /* need not be 0 */
+ i += 1;
break;
case '!':
@@ -261,15 +266,17 @@ again:
break;
case 's':
- *(uint16_t *)&buf[o] = htons(*(const uint16_t *)&req[i]);
- TWOS_COMPLEMENT16(&buf[o]);
+ u16 = *(const uint16_t *)&req[i];
+ TWOS_COMPLEMENT16(&u16);
+ *(uint16_t *)&buf[o] = htons(u16);
i += 2;
o += 2;
break;
case 'S':
- *(uint32_t *)&buf[o] = htonl(*(const uint32_t *)&req[i]);
- TWOS_COMPLEMENT32(&buf[o]);
+ u32 = *(const uint32_t *)&req[i];
+ TWOS_COMPLEMENT32(&u32);
+ *(uint32_t *)&buf[o] = htonl(u32);
i += 4;
o += 4;
break;
@@ -416,9 +423,10 @@ again:
case '2':
case 's':
if (mask & 1) {
- *(uint32_t *)&buf[o] = htonl((uint32_t)*(const uint16_t *)&req[i]);
- if (*fmt == 'z')
- TWOS_COMPLEMENT16(&buf[o]);
+ u16 = *(const uint16_t *)&req[i];
+ if (*fmt == 's')
+ TWOS_COMPLEMENT16(&u16);
+ *(uint32_t *)&buf[o] = htonl((uint32_t)u16);
o += 4;
}
mask >>= 1;
@@ -428,9 +436,10 @@ again:
case '4':
case 'S':
if (mask & 1) {
- *(uint32_t *)&buf[o] = htonl(*(const uint32_t *)&req[i]);
- if (*fmt == 'z')
- TWOS_COMPLEMENT32(&buf[o]);
+ u32 = *(const uint16_t *)&req[i];
+ if (*fmt == 'S')
+ TWOS_COMPLEMENT32(&u32);
+ *(uint32_t *)&buf[o] = htonl(u32);
o += 4;
}
mask >>= 1;