diff options
Diffstat (limited to '')
-rw-r--r-- | doc/protocols | 35 | ||||
-rw-r--r-- | src/mds-kkbd.c | 112 | ||||
-rw-r--r-- | src/mds-kkbd.h | 10 |
3 files changed, 150 insertions, 7 deletions
diff --git a/doc/protocols b/doc/protocols index 09bea45..ac3dfa1 100644 --- a/doc/protocols +++ b/doc/protocols @@ -575,7 +575,7 @@ Required header: Client ID Required header: Keyboard A string that identifies the keyboard that should be - affected. + affected Response: The server implementing support for `Command: get-keyboard-leds` for the keyboard indicated @@ -603,3 +603,36 @@ Reference implementation: kbdtrans --------------------------------------------------------------------- +Command: error + Notify a client about a request failure + +Required header: To + The ID of the client that send a request that failed + +Required header: Message ID + The ID of the message whose request failed + +Required header: Error + The errno number of the error, 0 on success if the + message was not an information query. The string + "custom" can be used if there is not errno number, + optionally followed by a blank space and a number + that identifies the error, this number must be + positive (not zero). + +Conditionally optional header: Length + Available and optional if: "custom" as used in `Error` + The length of the message + +Message: Description of the error, single line, mid- + sentence case, no punctuation in the end, must + not be question but rather it must be a statement + +Purpose: Enable keyboard layout servers to automatically + set active locks when the server starts based on + currently active LED:s + +Compulsivity: highly recommended + +--------------------------------------------------------------------- + diff --git a/src/mds-kkbd.c b/src/mds-kkbd.c index 21da035..98eef1c 100644 --- a/src/mds-kkbd.c +++ b/src/mds-kkbd.c @@ -549,7 +549,7 @@ static int ensure_send_buffer_size(size_t size) return -1; } else - send_buffer_size = size, + send_buffer_size = size; return 0; } @@ -569,6 +569,7 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess { int32_t msgid; size_t n; + int r; if (recv_modify_id == NULL) { @@ -630,7 +631,6 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess with_mutex (send_mutex, r = full_send(send_buffer, strlen(send_buffer)); ); - return r; } @@ -644,15 +644,71 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess */ int handle_keyboard_enumeration(const char* recv_modify_id) { + size_t i, off, top, n = 1 + strlen(KEYBOARD_ID "\n") + 3 * sizeof(size_t); + int32_t msgid; + int r, have_len = 0; + if (recv_modify_id == NULL) { eprint("did not get add modify ID, ignoring."); return 0; } - /* TODO */ + for (i = 0; i < received.header_count; i++) + n += strlen(received.headers[i]); + n += received.header_count; + n += received.payload_size; - return 0; + n += off = 64 + strlen(recv_modify_id) + 3 * sizeof(size_t); + + if (ensure_send_buffer_size(n + 1) < 0) + return -1; + + with_mutex (send_mutex, + msgid = message_id; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + ); + + n = off; + for (i = 0; i < received.header_count; i++) + { + const char* header = received.headers[i]; + if (!have_len && startswith(header, "Length: ")) + { + have_len = 1; + sprintf(send_buffer + n, + "Length: %lu\n", + strlen(KEYBOARD_ID "\n") + received.payload_size); + n += strlen(send_buffer + n); + } + else + { + sprintf(send_buffer + n, + "%s\n", + header); + n += strlen(header) + 1; + } + } + memcpy(send_buffer + n, received.payload, received.payload_size * sizeof(char)); + n += received.payload_size; + n -= off; + + sprintf(send_buffer, + "Modify ID: %s\n" + "Message ID: " PRIi32 "\n" + "Length: %lu\n", + recv_modify_id, msgid, n); + top = strlen(send_buffer) + 1; + send_buffer[top - 1] = '\n'; + off -= top; + n += top; + memmove(send_buffer + off, send_buffer, top * sizeof(char)); + + with_mutex (send_mutex, + r = full_send(send_buffer + off, n); + ); + + return r; } @@ -747,7 +803,9 @@ int handle_set_keyboard_leds(const char* recv_active, const char* recv_mask, int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_message_id, const char* recv_keyboard) { - int r; + int32_t msgid; + size_t n; + int r, leds; if ((recv_keyboard != NULL) && !strequals(recv_keyboard, KEYBOARD_ID)) return 0; @@ -764,6 +822,15 @@ int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_messag return 0; } + leds = get_leds(); + if (leds < 0) + { + int error = errno; + xperror(*argv); + send_errno(error, recv_client_id, recv_message_id); + return -1; + } + with_mutex (send_mutex, msgid = message_id; message_id = message_id == INT32_MAX ? 0 : (message_id + 1); @@ -779,7 +846,7 @@ int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_messag "Message ID: " PRIi32 "\n" "Active:%s%s%s%s%s\n" "Present: " PRESENT_LEDS "\n" - "\n" + "\n", recv_client_id, recv_message_id, msgid, (leds & LED_NUM_LOCK) ? " num" : "", (leds & LED_CAPS_LOCK) ? " caps" : "", @@ -1081,3 +1148,36 @@ int fetch_keys(void) return errno == 0 ? 0 : -1; } + +/** + * Send a response with an error number + * + * @param error The error number + * @param recv_client_id The client's ID + * @param recv_message_id The message ID of the message the client sent + * @return Zero on success, -1 on error + */ +int send_errno(int error, const char* recv_client_id, const char* recv_message_id) +{ + size_t n = 79 + strlen(recv_client_id) + strlen(recv_message_id) + 3 * sizeof(int); + int r; + + if (ensure_send_buffer_size(n + 1) < 0) + return -1; + + with_mutex (send_mutex, + sprintf(send_buffer, + "Command: error\n" + "To: %s\n" + "In response to: %s\n" + "Message ID: " PRIi32 "\n" + "Error: %i\n" + "\n", + recv_client_id, recv_message_id, message_id, error); + + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + r = full_send(send_buffer, strlen(send_buffer)); + ); + return r; +} + diff --git a/src/mds-kkbd.h b/src/mds-kkbd.h index 4b789f5..a7559e4 100644 --- a/src/mds-kkbd.h +++ b/src/mds-kkbd.h @@ -146,6 +146,16 @@ int send_key(int* restrict scancode, int trio); */ int fetch_keys(void); +/** + * Send a response with an error number + * + * @param error The error number + * @param recv_client_id The client's ID + * @param recv_message_id The message ID of the message the client sent + * @return Zero on success, -1 on error + */ +int send_errno(int error, const char* recv_client_id, const char* recv_message_id); + #endif |