Skip to content

Commit

Permalink
status: replace BSON with cJSON
Browse files Browse the repository at this point in the history
Rather than relying on libbson to supply a convenient wrapper to
creating JSON fragments, instead use a dedicated/embeddable C API to
achieve the same result.

Although libbson might be fast, there simply isn't enough JSON being
used as an IPC mechanism for the overhead of using libbson.  By
overhead, this is referring to the fact that not every linux
distribution or BSD have packaged bson, or have a new enough version of
it.

Fixes #408
  • Loading branch information
ThomasAdam committed Jul 7, 2021
1 parent 5a4f6c2 commit c6bcf69
Show file tree
Hide file tree
Showing 5 changed files with 3,444 additions and 44 deletions.
81 changes: 39 additions & 42 deletions fvwm/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "libs/fvwm_x11.h"
#include "libs/fvwmlib.h"
#include "libs/fvwmsignal.h"
#include "libs/cJSON.h"
#include "libs/setpgrp.h"
#include "libs/Grab.h"
#include "libs/Parse.h"
Expand Down Expand Up @@ -129,86 +130,82 @@ static FILE *status_fp;
void
status_send(void)
{
bson_t msg, screens;
bson_t *desktops[256], *desk_doc[256], *individual_d[256];
int i, d_count;
cJSON *msg = NULL, *screens = NULL;
cJSON *desk_doc[1024], *individual_d[1024];
int m_count, d_count;
FvwmWindow *fw_cur;
DesktopsInfo *di;
struct monitor *m, *m_cur;
size_t json_len;
char *as_json;
char *as_json = NULL;

if (status_fp == NULL)
if (status_fp == NULL || !Scr.flags.are_windows_captured)
return;

memset(desktops, 0, sizeof(bson_t));
memset(individual_d, 0, sizeof(bson_t));
memset(desk_doc, 0, sizeof(bson_t));
memset(individual_d, 0, sizeof(cJSON));
memset(desk_doc, 0, sizeof(cJSON));

msg = cJSON_CreateObject();

m_cur = monitor_get_current();

bson_init(&msg);
BSON_APPEND_INT64(&msg, "version", 2);
BSON_APPEND_UTF8(&msg, "current_screen", m_cur->si->name);
BSON_APPEND_UTF8(&msg, "desktop_mode",
cJSON_AddNumberToObject(msg, "version", 2);
cJSON_AddStringToObject(msg, "current_screen", m_cur->si->name);
cJSON_AddStringToObject(msg, "desktop_mode",
monitor_mode == MONITOR_TRACKING_G && is_tracking_shared ? "shared" :
monitor_mode == MONITOR_TRACKING_G ? "global" :
monitor_mode == MONITOR_TRACKING_M ? "per-monitor" :
"unknown");

BSON_APPEND_DOCUMENT_BEGIN(&msg, "screens", &screens);
screens = cJSON_AddObjectToObject(msg, "screens");

d_count = 0;
d_count = 0, m_count = 0;
TAILQ_FOREACH(m, &monitor_q, entry) {
desktops[d_count] = bson_new();
desk_doc[d_count] = bson_new();
cJSON *this_desktop;
if ((desk_doc[d_count] = cJSON_CreateObject()) == NULL)
goto out;

this_desktop = cJSON_AddObjectToObject(desk_doc[d_count],
"desktops");

di = m->Desktops->next;
while (di != NULL) {
individual_d[d_count] = bson_new();
BSON_APPEND_INT64(individual_d[d_count], "number",
if ((individual_d[d_count] = cJSON_CreateObject()) == NULL)
goto out;
cJSON_AddNumberToObject(individual_d[d_count], "number",
di->desk);
BSON_APPEND_BOOL(individual_d[d_count], "is_current",
cJSON_AddBoolToObject(individual_d[d_count], "is_current",
di->desk == m->virtual_scr.CurrentDesk);
BSON_APPEND_BOOL(individual_d[d_count], "is_urgent",
cJSON_AddBoolToObject(individual_d[d_count], "is_urgent",
desk_get_fw_urgent(m, di->desk));
BSON_APPEND_INT64(individual_d[d_count],
cJSON_AddNumberToObject(individual_d[d_count],
"number_of_clients", desk_get_fw_count(m, di->desk));
BSON_APPEND_DOCUMENT(desktops[d_count], di->name,
individual_d[d_count]);
BSON_APPEND_DOCUMENT(desk_doc[d_count], "desktops",
desktops[d_count]);
cJSON_AddItemToObject(this_desktop, di->name, individual_d[d_count]);

di = di->next;
}

fw_cur = get_focus_window();
if (fw_cur != NULL && fw_cur->m == m) {
BSON_APPEND_UTF8(desk_doc[d_count], "current_client",
fw_cur->visible_name);
cJSON_AddStringToObject(desk_doc[d_count],
"current_client", fw_cur->visible_name);
}
BSON_APPEND_DOCUMENT(&screens, m->si->name, desk_doc[d_count]);

cJSON_AddItemToObject(screens, m->si->name, desk_doc[d_count]);

d_count++;
m_count++;
}
bson_append_document_end(&msg, &screens);

if ((as_json = bson_as_relaxed_extended_json(&msg, &json_len)) == NULL)
if ((as_json = cJSON_PrintUnformatted(msg)) == NULL) {
goto out;
}

fflush(status_fp);
fprintf(status_fp, "%s\n", as_json);
fflush(status_fp);

out:
bson_free(as_json);
for (i = 0; i < d_count; i++) {
if (desk_doc[i] != NULL)
bson_free(desk_doc[i]);
if (desktops[i] != NULL)
bson_free(desktops[i]);
if (individual_d[i] != NULL)
bson_free(individual_d[i]);
}
bson_destroy(&msg);
cJSON_free(as_json);
cJSON_Delete(msg);
}

#define PIPENAME "fvwm3.pipe"
Expand Down
1 change: 0 additions & 1 deletion fvwm/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -2559,7 +2559,6 @@ void HandleFocusIn(const evh_args_t *ea)
fw->m->virtual_scr.CurrentDesk)
EWMH_SetCurrentDesktop(fw->m);
}
status_send();
}
last_focus_w = focus_w;
last_focus_fw = focus_fw;
Expand Down
3 changes: 2 additions & 1 deletion libs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ libfvwm3_a_SOURCES = \
fsm.h ftime.h fvwm_sys_stat.h fvwm_x11.h fvwmlib.h fvwmrect.h fvwmsignal.h \
gravity.c gravity.h getpwuid.h lang-strings.h log.h modifiers.h queue.h \
safemalloc.h setpgrp.h strlcpy.h timeout.h vpacket.h wcontext.h wild.h \
cJSON.h \
\
BidiJoin.c Flocale.c PictureUtils.c FScreen.c Graphics.c \
PictureGraphics.c Bindings.c FlocaleCharset.c Parse.c \
Expand All @@ -26,7 +27,7 @@ libfvwm3_a_SOURCES = \
fvwmrect.c FRenderInit.c safemalloc.c FBidi.c \
wild.c Grab.c Event.c ClientMsg.c setpgrp.c FShape.c \
FGettext.c Rectangles.c timeout.c flist.c charmap.c wcontext.c \
modifiers.c fsm.c FTips.c fio.c fvwmlib3.c strlcpy.c getpwuid.c
modifiers.c fsm.c FTips.c fio.c fvwmlib3.c strlcpy.c getpwuid.c cJSON.c

libfvwm3_a_LIBADD = @LIBOBJS@

Expand Down
Loading

0 comments on commit c6bcf69

Please sign in to comment.