From 966c654112561b21fca076a8e967033510da9981 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 10 Dec 2011 11:16:32 +0000 Subject: [PATCH] implement the GET_LOG_MARKERS IPC request/reply --- docs/ipc | 60 ++++++++++++++++++++++++++++++++++++++++-------- include/i3/ipc.h | 6 +++++ src/ipc.c | 47 +++++++++++++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 12 deletions(-) diff --git a/docs/ipc b/docs/ipc index fc46590e..c76d0154 100644 --- a/docs/ipc +++ b/docs/ipc @@ -1,7 +1,7 @@ IPC interface (interprocess communication) ========================================== Michael Stapelberg -October 2011 +December 2011 This document describes how to interface with i3 from a separate process. This is useful for example to remote-control i3 (to write test cases for example) or @@ -68,6 +68,10 @@ GET_BAR_CONFIG (6):: Gets the configuration (as JSON map) of the workspace bar with the given ID. If no ID is provided, an array with all configured bar IDs is returned instead. +GET_LOG_MARKERS (7):: + Gets the SHM log markers for the current position, the last wrap, the + SHM segment name and segment size. This is necessary for tools like + i3-dump-log which want to display the SHM log. So, a typical message could look like this: -------------------------------------------------- @@ -111,18 +115,20 @@ The following reply types are implemented: COMMAND (0):: Confirmation/Error code for the COMMAND message. -GET_WORKSPACES (1):: +WORKSPACES (1):: Reply to the GET_WORKSPACES message. SUBSCRIBE (2):: Confirmation/Error code for the SUBSCRIBE message. -GET_OUTPUTS (3):: +OUTPUTS (3):: Reply to the GET_OUTPUTS message. -GET_TREE (4):: +TREE (4):: Reply to the GET_TREE message. -GET_MARKS (5):: +MARKS (5):: Reply to the GET_MARKS message. -GET_BAR_CONFIG (6):: +BAR_CONFIG (6):: Reply to the GET_BAR_CONFIG message. +LOG_MARKERS (7):: + Reply to the GET_LOG_MARKERS message. === COMMAND reply @@ -134,7 +140,7 @@ property is +success (bool)+, but this will be expanded in future versions. { "success": true } ------------------- -=== GET_WORKSPACES reply +=== WORKSPACES reply The reply consists of a serialized list of workspaces. Each workspace has the following properties: @@ -248,7 +254,7 @@ rect (map):: ] ------------------- -=== GET_TREE reply +=== TREE reply The reply consists of a serialized tree. Each node in the tree (representing one container) has at least the properties listed below. While the nodes might @@ -431,7 +437,7 @@ JSON dump: } ------------------------ -=== GET_MARKS reply +=== MARKS reply The reply consists of a single array of strings for each container that has a mark. The order of that array is undefined. If more than one container has the @@ -440,7 +446,7 @@ contents are not unique). If no window has a mark the response will be the empty array []. -=== GET_BAR_CONFIG reply +=== BAR_CONFIG reply This can be used by third-party workspace bars (especially i3bar, but others are free to implement compatible alternatives) to get the +bar+ block @@ -524,6 +530,40 @@ urgent_workspace_text/urgent_workspace_bar:: } -------------- +=== LOG_MARKERS reply + +Gets the SHM log markers for the current position, the last wrap, the +SHM segment name and segment size. This is necessary for tools like +i3-dump-log which want to display the SHM log. + +The reply is a JSON map with the following entries: + +shmname (string):: + The name of the SHM segment, will be of the format +/i3-log-+. +size (integer):: + The size (in bytes) of the SHM segment. If this is 0, SHM logging is + disabled. +offset_next_write (integer):: + The offset in the SHM segment at which the next write will happen. + Tools should start printing lines from here, since the bytes following + this offset are the oldest log lines. However, the first line might be + garbled, so it makes sense to skip all bytes until the first \0. +offset_last_wrap (integer):: + The offset in the SHM segment at which the last wrap occured. i3 only + stores entire messages in the SHM log, so it might waste a few bytes at + the end to be more efficient. Tools should not print content after the + offset_last_wrap. + +*Example*: +----------------------------- +{ + "offset_next_write":132839, + "offset_last_wrap":26214400, + "shmname":"/i3-log-3392", + "size":26214400 +} +----------------------------- + == Events [[events]] diff --git a/include/i3/ipc.h b/include/i3/ipc.h index bfadf4cf..e8de2e1e 100644 --- a/include/i3/ipc.h +++ b/include/i3/ipc.h @@ -40,6 +40,9 @@ /** Request the configuration for a specific 'bar' */ #define I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG 6 +/** Request the SHM debug log start/wrap markers */ +#define I3_IPC_MESSAGE_TYPE_GET_LOG_MARKERS 7 + /* * Messages from i3 to clients * @@ -66,6 +69,9 @@ /** Bar config reply type */ #define I3_IPC_REPLY_TYPE_BAR_CONFIG 6 +/** Request the SHM debug log start/wrap markers */ +#define I3_IPC_REPLY_TYPE_LOG_MARKERS 7 + /* * Events from i3 to clients. Events have the first bit set high. * diff --git a/src/ipc.c b/src/ipc.c index fe1464e6..60f456c3 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -612,6 +612,48 @@ IPC_HANDLER(get_bar_config) { y(free); } +/* + * Formats the reply message for a GET_LOG_MARKERS request and sends it to the + * client. + * + */ +IPC_HANDLER(get_log_markers) { +#if YAJL_MAJOR >= 2 + yajl_gen gen = yajl_gen_alloc(NULL); +#else + yajl_gen gen = yajl_gen_alloc(NULL, NULL); +#endif + + int offset_next_write, offset_last_wrap, logsize; + get_log_markers(&offset_next_write, &offset_last_wrap, &logsize); + + y(map_open); + ystr("offset_next_write"); + y(integer, offset_next_write); + + ystr("offset_last_wrap"); + y(integer, offset_last_wrap); + + ystr("shmname"); + ystr(shmlogname); + + ystr("size"); + y(integer, logsize); + + y(map_close); + + const unsigned char *payload; +#if YAJL_MAJOR >= 2 + size_t length; +#else + unsigned int length; +#endif + y(get_buf, &payload, &length); + + ipc_send_message(fd, length, I3_IPC_REPLY_TYPE_LOG_MARKERS, payload); + y(free); +} + /* * Callback for the YAJL parser (will be called when a string is parsed). * @@ -697,14 +739,15 @@ IPC_HANDLER(subscribe) { /* The index of each callback function corresponds to the numeric * value of the message type (see include/i3/ipc.h) */ -handler_t handlers[7] = { +handler_t handlers[8] = { handle_command, handle_get_workspaces, handle_subscribe, handle_get_outputs, handle_tree, handle_get_marks, - handle_get_bar_config + handle_get_bar_config, + handle_get_log_markers }; /*