Compare commits

..

4 Commits

  1. 1
      .gitignore
  2. 24
      src/.clang-format
  3. 12
      src/.editorconfig
  4. 31
      src/IPCClient.c
  5. 51
      src/config.def.h
  6. 96
      src/config.h
  7. 147
      src/drw.c
  8. 15
      src/drw.h
  9. 135
      src/dwm-msg.c
  10. 927
      src/dwm.c
  11. 361
      src/ipc.c
  12. 43
      src/ipc.h
  13. 4
      src/transient.c
  14. 25
      src/util.c
  15. 77
      src/yajl_dumps.c
  16. 6
      src/yajl_dumps.h

1
.gitignore vendored

@ -8,3 +8,4 @@ src/ewm.desktop
pkg/
*.pkg*
src/compile_commands.json

@ -0,0 +1,24 @@
---
BasedOnStyle: LLVM
IndentWidth: 4
AllowShortFunctionsOnASingleLine: 'None'
AllowShortIfStatementsOnASingleLine: 'Never'
AlignAfterOpenBracket: 'Align'
AlignConsecutiveAssignments: 'Consecutive'
AlignConsecutiveBitFields: 'Consecutive'
AlignConsecutiveMacros: 'Consecutive'
AlignOperands: 'AlignAfterOperator'
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowShortBlocksOnASingleLine: 'Empty'
AllowShortLoopsOnASingleLine: false
BreakBeforeBraces: 'Attach'
BreakBeforeBinaryOperators: 'NonAssignment'
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceBeforeParens: 'ControlStatements'
TabWidth: 4
UseTab: 'ForIndentation'
ColumnLimit: 78
UseCRLF: false
DeriveLineEnding: false

@ -0,0 +1,12 @@
# This file is for unifying the coding style for different editors and IDEs
# See editorconfig.org
root = true
[*.{c,h,cpp,hpp}]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

@ -5,12 +5,11 @@
#include "util.h"
IPCClient *
ipc_client_new(int fd)
{
IPCClient *ipc_client_new(int fd) {
IPCClient *c = (IPCClient *) malloc(sizeof(IPCClient));
if (c == NULL) return NULL;
if (c == NULL)
return NULL;
// Initialize struct
memset(&c->event, 0, sizeof(struct epoll_event));
@ -26,9 +25,7 @@ ipc_client_new(int fd)
return c;
}
void
ipc_list_add_client(IPCClientList *list, IPCClient *nc)
{
void ipc_list_add_client(IPCClientList *list, IPCClient *nc) {
DEBUG("Adding client with fd %d to list\n", nc->fd);
if (*list == NULL) {
@ -44,22 +41,22 @@ ipc_list_add_client(IPCClientList *list, IPCClient *nc)
}
}
void
ipc_list_remove_client(IPCClientList *list, IPCClient *c)
{
void ipc_list_remove_client(IPCClientList *list, IPCClient *c) {
IPCClient *cprev = c->prev;
IPCClient *cnext = c->next;
if (cprev != NULL) cprev->next = c->next;
if (cnext != NULL) cnext->prev = c->prev;
if (c == *list) *list = c->next;
if (cprev != NULL)
cprev->next = c->next;
if (cnext != NULL)
cnext->prev = c->prev;
if (c == *list)
*list = c->next;
}
IPCClient *
ipc_list_get_client(IPCClientList list, int fd)
{
IPCClient *ipc_list_get_client(IPCClientList list, int fd) {
for (IPCClient *c = list; c; c = c->next) {
if (c->fd == fd) return c;
if (c->fd == fd)
return c;
}
return NULL;

@ -9,7 +9,8 @@ static const int topbar = 1; /* 0 means bottom bar */
static const int usealtbar = 1; /* 1 means use non-dwm status bar */
static const char *altbarclass = "Polybar"; /* Alternate bar class name */
static const char *alttrayname = "tray"; /* Polybar tray instance name */
static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */
static const char *altbarcmd =
"$HOME/bar.sh"; /* Alternate bar launch command */
static const char *fonts[] = {"monospace:size=10"};
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
@ -31,7 +32,8 @@ static const Rule rules[] = {
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
/* class instance title tags mask isfloating monitor
*/
{"Gimp", NULL, NULL, 0, 1, -1},
{"Firefox", NULL, NULL, 1 << 8, 0, -1},
};
@ -39,7 +41,8 @@ static const Rule rules[] = {
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
static const int resizehints =
1; /* 1 means respect size hints in tiled resizals */
static const Layout layouts[] = {
/* symbol arrange function */
@ -54,16 +57,27 @@ static const Layout layouts[] = {
{MODKEY, KEY, view, {.ui = 1 << TAG}}, \
{MODKEY | ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \
{MODKEY | ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
{MODKEY | ControlMask | ShiftMask, \
KEY, \
toggletag, \
{.ui = 1 << TAG}},
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
#define SHCMD(cmd) \
{ \
.v = (const char *[]) { \
"/bin/sh", "-c", cmd, NULL \
} \
}
#define STATUSBAR "dwmblocks"
/* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static char dmenumon[2] =
"0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = {
"dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf",
col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL};
static const char *termcmd[] = {"st", NULL};
static Key keys[] = {
@ -111,22 +125,17 @@ static Key keys[] = {
{MODKEY, XK_minus, setgaps, {.i = -1}},
{MODKEY, XK_equal, setgaps, {.i = +1}},
{MODKEY | ShiftMask, XK_equal, setgaps, {.i = 0}},
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
TAGKEYS(XK_1, 0) TAGKEYS(XK_2, 1) TAGKEYS(XK_3, 2) TAGKEYS(XK_4, 3)
TAGKEYS(XK_5, 4) TAGKEYS(XK_6, 5) TAGKEYS(XK_7, 6) TAGKEYS(XK_8, 7)
TAGKEYS(XK_9, 8){MODKEY | ShiftMask, XK_q, quit, {0}},
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
* ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
/* click event mask button function argument
*/
{ClkLtSymbol, 0, Button1, setlayout, {0}},
{ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]}},
{ClkWinTitle, 0, Button2, zoom, {0}},
@ -157,6 +166,4 @@ static IPCCommand ipccommands[] = {
IPCCOMMAND(togglefloating, 1, {ARG_TYPE_NONE}),
IPCCOMMAND(setmfact, 1, {ARG_TYPE_FLOAT}),
IPCCOMMAND(setlayoutsafe, 1, {ARG_TYPE_PTR}),
IPCCOMMAND( quit, 1, {ARG_TYPE_NONE} )
};
IPCCOMMAND(quit, 1, {ARG_TYPE_NONE})};

@ -2,24 +2,27 @@
#include <X11/XF86keysym.h>
#define STATUSBAR "dwmblocks"
/* appearance */
static const unsigned int borderpx = 2; /* border pixel of windows */
static const unsigned int borderpx = 0; /* border pixel of windows */
static const unsigned int snap = 0; /* snap pixel (32)*/
static const unsigned int gappx = 0;
static const unsigned int gapmodes[] = { 0, 20 };
static const unsigned int gapmodes[] = {20, 0};
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 0; /* 0 means bottom bar */
static const int topbar = 1; /* 0 means bottom bar */
static const int barverticalpadding = 6; /* Vertical bar padding */
static const int usealtbar = 1; /* 1 means use non-dwm status bar */
static const int usealtbar = 0; /* 1 means use non-dwm status bar */
static const char *altbarclass = "Polybar"; /* Alternate bar class name */
static const char *alttrayname = "tray"; /* Polybar tray instance name */
static const char *altbarcmd = "$HOME/.config/polybar/launch"; /* Alternate bar launch command */
// static const char *altbarcmd = "$HOME/.config/polybar/launch"; /*
// Alternate bar launch command */
static const char *altbarcmd = "";
static const char *fonts[] = {"Fira Code:size=11"};
static const char dmenufont[] = "Fira Code:size=15";
static const char bg_alt_color[] = "#272a34";
static const char bg_color[] = "#282c34";
static const char bg_color[] = "#181818";
static const char bg_alt_color[] = "#111111";
static const char text_color[] = "#bbc2cf";
static const char selected_color[] = "#81a2be";
static const char border_color_sel[] = "#444953";
@ -45,7 +48,9 @@ static const Rule rules[] = {
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
/* class instance title tags mask
* isfloating monitor
*/
{"Gimp", NULL, NULL, 0, 1, -1},
{"Firefox", NULL, NULL, 1 << 8, 0, -1},
{"discord", NULL, NULL, 0, 0, -1},
@ -56,7 +61,8 @@ static const Rule rules[] = {
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
static const int resizehints =
1; /* 1 means respect size hints in tiled resizals */
static const Layout layouts[] = {
/* symbol arrange function */
@ -71,27 +77,47 @@ static const Layout layouts[] = {
{MODKEY, KEY, view, {.ui = 1 << TAG}}, \
{MODKEY | ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \
{MODKEY | ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
{MODKEY | ControlMask | ShiftMask, \
KEY, \
toggletag, \
{.ui = 1 << TAG}},
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
#define SHCMD(cmd) \
{ \
.v = (const char *[]) { \
"/bin/sh", "-c", cmd, NULL \
} \
}
/* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-p", "Run $", "-z", "512", NULL };
static char dmenumon[2] =
"0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = {"dmenu_run", "-m", dmenumon, "-p",
"Run $", "-z", "512", NULL};
static const char *termcmd[] = {"alacritty", NULL};
static const char *browsercmd[] = {"firefox", NULL};
static const char *betterlockscreencmd[] = { "betterlockscreen", "--lock", "blur", NULL };
static const char *betterlockscreencmd[] = {"betterlockscreen", "--lock",
"blur", NULL};
static const char *screenshotcmd[] = {"flameshot", "gui", NULL};
static const char *cmuspausecmd[] = {"cmus-remote", "--pause", NULL};
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XF86XK_AudioLowerVolume, spawn, SHCMD("amixer -q set Master 5%- unmute; pkill -RTMIN+1 dwmblocks") },
{ MODKEY, XF86XK_AudioRaiseVolume, spawn, SHCMD("amixer -q set Master 5%+ unmute; pkill -RTMIN+1 dwmblocks") },
{ MODKEY, XF86XK_AudioMute, spawn, SHCMD("amixer -q set Master toggle; pkill -RTMIN+1 dwmblocks") },
{ MODKEY|ShiftMask, XF86XK_AudioMute, spawn, SHCMD("amixer set Capture toggle") },
//{ MODKEY, XK_d, spawn, {.v = dmenucmd } },
/* modifier key
* function argument
*/
{MODKEY, XF86XK_AudioLowerVolume, spawn,
SHCMD("amixer -q set Master 5%- unmute; pkill -RTMIN+1 dwmblocks")},
{MODKEY, XF86XK_AudioRaiseVolume, spawn,
SHCMD("amixer -q set Master 5%+ unmute; pkill -RTMIN+1 dwmblocks")},
{MODKEY, XF86XK_AudioMute, spawn,
SHCMD("amixer -q set Master toggle; pkill -RTMIN+1 dwmblocks")},
{MODKEY | ShiftMask, XF86XK_AudioMute, spawn,
SHCMD("amixer set Capture toggle")},
//{ MODKEY, XK_d, spawn, {.v
//= dmenucmd
//}
//},
{MODKEY, XK_d, spawn, SHCMD("rofi -show drun")},
{MODKEY, XK_s, spawn, SHCMD("rofi -show ssh")},
{MODKEY, XK_w, spawn, SHCMD("rofi -show window")},
@ -127,7 +153,9 @@ static Key keys[] = {
{MODKEY, XK_f, setlayout, {.v = &layouts[1]}},
{MODKEY, XK_t, setlayout, {.v = &layouts[0]}},
{MODKEY, XK_m, setlayout, {.v = &layouts[2]}},
//{ MODKEY, XK_space, setlayout, {0} },
//{ MODKEY, XK_space, setlayout,
//{0}
//},
{MODKEY | ShiftMask, XK_space, togglefloating, {0}},
{MODKEY | ShiftMask, XK_f, togglefullscr, {0}},
{MODKEY, XK_0, view, {.ui = ~0}},
@ -136,7 +164,7 @@ static Key keys[] = {
{MODKEY, XK_period, focusmon, {.i = +1}},
{MODKEY | ShiftMask, XK_comma, tagmon, {.i = -1}},
{MODKEY | ShiftMask, XK_period, tagmon, {.i = +1}},
{ MODKEY|ShiftMask, XK_x, spawn, {.v = betterlockscreencmd} },
{MODKEY | ShiftMask, XK_l, spawn, {.v = betterlockscreencmd}},
{MODKEY, XK_Print, spawn, {.v = screenshotcmd}},
{MODKEY, XK_u, spawn, {.v = cmuspausecmd}},
{MODKEY, XK_g, switchgaps, {.i = +1}},
@ -144,22 +172,18 @@ static Key keys[] = {
{MODKEY, XK_minus, setgaps, {.i = -1}},
{MODKEY, XK_plus, setgaps, {.i = +1}},
{MODKEY | ShiftMask, XK_equal, setgaps, {.i = 0}},
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_e, quit, {0} },
TAGKEYS(XK_1, 0) TAGKEYS(XK_2, 1) TAGKEYS(XK_3, 2) TAGKEYS(XK_4, 3)
TAGKEYS(XK_5, 4) TAGKEYS(XK_6, 5) TAGKEYS(XK_7, 6) TAGKEYS(XK_8, 7)
TAGKEYS(XK_9, 8){MODKEY | ShiftMask, XK_e, quit, {0}},
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
* ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
/* click event mask button
* function argument
*/
{ClkStatusText, 0, Button1, sigstatusbar, {.i = 1}},
{ClkStatusText, 0, Button2, sigstatusbar, {.i = 2}},
{ClkStatusText, 0, Button3, sigstatusbar, {.i = 3}},
@ -178,7 +202,6 @@ static Button buttons[] = {
{ClkTagBar, MODKEY, Button3, toggletag, {0}},
};
static const char *ipcsockpath = "/tmp/dwm.sock";
static IPCCommand ipccommands[] = {
IPCCOMMAND(view, 1, {ARG_TYPE_UINT}),
@ -194,5 +217,4 @@ static IPCCommand ipccommands[] = {
IPCCOMMAND(togglefloating, 1, {ARG_TYPE_NONE}),
IPCCOMMAND(setmfact, 1, {ARG_TYPE_FLOAT}),
IPCCOMMAND(setlayoutsafe, 1, {ARG_TYPE_PTR}),
IPCCOMMAND( quit, 1, {ARG_TYPE_NONE} )
};
IPCCOMMAND(quit, 1, {ARG_TYPE_NONE})};

@ -1,9 +1,9 @@
/* See LICENSE file for copyright and license details. */
#include <X11/Xft/Xft.h>
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
@ -12,22 +12,20 @@
#define UTF_SIZ 4
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0,
0xF8};
static const long utfmin[UTF_SIZ + 1] = {0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF,
0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
static long utf8decodebyte(const char c, size_t *i) {
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
if (((unsigned char) c & utfmask[*i]) == utfbyte[*i])
return (unsigned char) c & ~utfmask[*i];
return 0;
}
static size_t
utf8validate(long *u, size_t i)
{
static size_t utf8validate(long *u, size_t i) {
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
@ -35,9 +33,7 @@ utf8validate(long *u, size_t i)
return i;
}
static size_t
utf8decode(const char *c, long *u, size_t clen)
{
static size_t utf8decode(const char *c, long *u, size_t clen) {
size_t i, j, len, type;
long udecoded;
@ -60,9 +56,8 @@ utf8decode(const char *c, long *u, size_t clen)
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw_create(Display *dpy, int screen, Window root, unsigned int w,
unsigned int h) {
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
@ -77,9 +72,7 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
void drw_resize(Drw *drw, unsigned int w, unsigned int h) {
if (!drw)
return;
@ -87,12 +80,11 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h,
DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
void drw_free(Drw *drw) {
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
@ -102,9 +94,8 @@ drw_free(Drw *drw)
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
static Fnt *xfont_create(Drw *drw, const char *fontname,
FcPattern *fontpattern) {
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
@ -116,11 +107,14 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
fprintf(stderr, "error, cannot load font from name: '%s'\n",
fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
fprintf(stderr,
"error, cannot parse font name to pattern: '%s'\n",
fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
@ -141,7 +135,8 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
* and lots more all over the internet.
*/
FcBool iscol;
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
if (FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch
&& iscol) {
XftFontClose(drw->dpy, xfont);
return NULL;
}
@ -155,9 +150,7 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
return font;
}
static void
xfont_free(Fnt *font)
{
static void xfont_free(Fnt *font) {
if (!font)
return;
if (font->pattern)
@ -166,9 +159,7 @@ xfont_free(Fnt *font)
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *drw_fontset_create(Drw *drw, const char *fonts[], size_t fontcount) {
Fnt *cur, *ret = NULL;
size_t i;
@ -184,24 +175,20 @@ drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
void drw_fontset_free(Fnt *font) {
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname) {
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
DefaultColormap(drw->dpy, drw->screen), clrname,
dest))
die("error, cannot allocate color '%s'", clrname);
dest->pixel |= 0xff << 24;
@ -209,14 +196,13 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) {
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
if (!drw || !clrnames || clrcount < 2
|| !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
@ -224,35 +210,31 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
void drw_setfontset(Drw *drw, Fnt *set) {
if (drw)
drw->fonts = set;
}
void
drw_setscheme(Drw *drw, Clr *scm)
{
void drw_setscheme(Drw *drw, Clr *scm) {
if (drw)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h,
int filled, int invert) {
if (!drw || !drw->scheme)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
XSetForeground(drw->dpy, drw->gc,
invert ? drw->scheme[ColBg].pixel
: drw->scheme[ColFg].pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h,
unsigned int lpad, const char *text, int invert) {
char buf[1024];
int ty;
unsigned int ew;
@ -274,7 +256,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (!render) {
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XSetForeground(drw->dpy, drw->gc,
drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
@ -291,7 +274,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
charexists =
charexists
|| XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
if (curfont == usedfont) {
utf8strlen += utf8charlen;
@ -325,7 +310,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
usedfont->xfont, x, ty,
(XftChar8 *) buf, len);
}
x += ew;
w -= ew;
@ -346,8 +332,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
/* Refer to the comment in xfont_create for more information.
*/
die("the first font in the cache must be loaded from a font "
"string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
@ -364,8 +352,11 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
if (usedfont
&& XftCharExists(drw->dpy, usedfont->xfont,
utf8codepoint)) {
for (curfont = drw->fonts; curfont->next;
curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
@ -381,9 +372,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w,
unsigned int h) {
if (!drw)
return;
@ -391,17 +381,14 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
XSync(drw->dpy, False);
}
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
unsigned int drw_fontset_getwidth(Drw *drw, const char *text) {
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
void drw_font_getexts(Fnt *font, const char *text, unsigned int len,
unsigned int *w, unsigned int *h) {
XGlyphInfo ext;
if (!font || !text)
@ -414,9 +401,7 @@ drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w,
*h = font->h;
}
Cur *
drw_cur_create(Drw *drw, int shape)
{
Cur *drw_cur_create(Drw *drw, int shape) {
Cur *cur;
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
@ -427,9 +412,7 @@ drw_cur_create(Drw *drw, int shape)
return cur;
}
void
drw_cur_free(Drw *drw, Cur *cursor)
{
void drw_cur_free(Drw *drw, Cur *cursor) {
if (!cursor)
return;

@ -27,7 +27,8 @@ typedef struct {
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w,
unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
@ -35,7 +36,8 @@ void drw_free(Drw *drw);
Fnt *drw_fontset_create(Drw *drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt *set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len,
unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
@ -50,8 +52,11 @@ void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h,
int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h,
unsigned int lpad, const char *text, int invert);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w,
unsigned int h);

@ -65,9 +65,8 @@ typedef struct dwm_ipc_header {
uint8_t type;
} __attribute((packed)) dwm_ipc_header_t;
static int
recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply)
{
static int recv_message(uint8_t *msg_type, uint32_t *reply_size,
uint8_t **reply) {
uint32_t read_bytes = 0;
const int32_t to_read = sizeof(dwm_ipc_header_t);
char header[to_read];
@ -79,15 +78,19 @@ recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply)
if (n == 0) {
if (read_bytes == 0) {
fprintf(stderr, "Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
"Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32
" total bytes.\n",
read_bytes, to_read);
return -2;
} else {
fprintf(stderr, "Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
"Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32
" total bytes.\n",
read_bytes, to_read);
return -3;
}
@ -120,16 +123,20 @@ recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply)
// Extract payload
read_bytes = 0;
while (read_bytes < *reply_size) {
ssize_t n = read(sock_fd, *reply + read_bytes, *reply_size - read_bytes);
ssize_t n =
read(sock_fd, *reply + read_bytes, *reply_size - read_bytes);
if (n == 0) {
fprintf(stderr, "Unexpectedly reached EOF while reading payload.");
fprintf(stderr, "Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n",
fprintf(stderr,
"Unexpectedly reached EOF while reading payload.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n",
read_bytes, *reply_size);
free(*reply);
return -2;
} else if (n == -1) {
if (errno == EINTR || errno == EAGAIN) continue;
if (errno == EINTR || errno == EAGAIN)
continue;
free(*reply);
return -1;
}
@ -140,9 +147,8 @@ recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply)
return 0;
}
static int
read_socket(IPCMessageType *msg_type, uint32_t *msg_size, char **msg)
{
static int read_socket(IPCMessageType *msg_type, uint32_t *msg_size,
char **msg) {
int ret = -1;
while (ret != 0) {
@ -150,7 +156,8 @@ read_socket(IPCMessageType *msg_type, uint32_t *msg_size, char **msg)
if (ret < 0) {
// Try again (non-fatal error)
if (ret == -1 && (errno == EINTR || errno == EAGAIN)) continue;
if (ret == -1 && (errno == EINTR || errno == EAGAIN))
continue;
fprintf(stderr, "Error receiving response from socket. ");
fprintf(stderr, "The connection might have been lost.\n");
@ -161,9 +168,7 @@ read_socket(IPCMessageType *msg_type, uint32_t *msg_size, char **msg)
return 0;
}
static ssize_t
write_socket(const void *buf, size_t count)
{
static ssize_t write_socket(const void *buf, size_t count) {
size_t written = 0;
while (written < count) {
@ -181,9 +186,7 @@ write_socket(const void *buf, size_t count)
return written;
}
static void
connect_to_socket()
{
static void connect_to_socket() {
struct sockaddr_un addr;
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
@ -194,16 +197,17 @@ connect_to_socket()
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, DEFAULT_SOCKET_PATH);
connect(sock, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un));
connect(sock, (const struct sockaddr *) &addr,
sizeof(struct sockaddr_un));
sock_fd = sock;
}
static int
send_message(IPCMessageType msg_type, uint32_t msg_size, uint8_t *msg)
{
dwm_ipc_header_t header = {
.magic = IPC_MAGIC_ARR, .size = msg_size, .type = msg_type};
static int send_message(IPCMessageType msg_type, uint32_t msg_size,
uint8_t *msg) {
dwm_ipc_header_t header = {.magic = IPC_MAGIC_ARR,
.size = msg_size,
.type = msg_type};
size_t header_size = sizeof(dwm_ipc_header_t);
size_t total_size = header_size + msg_size;
@ -220,9 +224,7 @@ send_message(IPCMessageType msg_type, uint32_t msg_size, uint8_t *msg)
return 0;
}
static int
is_float(const char *s)
{
static int is_float(const char *s) {
size_t len = strlen(s);
int is_dot_used = 0;
int is_minus_used = 0;
@ -245,9 +247,7 @@ is_float(const char *s)
return 1;
}
static int
is_unsigned_int(const char *s)
{
static int is_unsigned_int(const char *s) {
size_t len = strlen(s);
// Unsigned int can only have digits
@ -261,9 +261,7 @@ is_unsigned_int(const char *s)
return 1;
}
static int
is_signed_int(const char *s)
{
static int is_signed_int(const char *s) {
size_t len = strlen(s);
// Signed int can only have digits and a negative sign at the start
@ -279,9 +277,7 @@ is_signed_int(const char *s)
return 1;
}
static void
flush_socket_reply()
{
static void flush_socket_reply() {
IPCMessageType reply_type;
uint32_t reply_size;
char *reply;
@ -291,9 +287,7 @@ flush_socket_reply()
free(reply);
}
static void
print_socket_reply()
{
static void print_socket_reply() {
IPCMessageType reply_type;
uint32_t reply_size;
char *reply;
@ -305,9 +299,7 @@ print_socket_reply()
free(reply);
}
static int
run_command(const char *name, char *args[], int argc)
{
static int run_command(const char *name, char *args[], int argc) {
const unsigned char *msg;
size_t msg_size;
@ -351,35 +343,27 @@ run_command(const char *name, char *args[], int argc)
return 0;
}
static int
get_monitors()
{
static int get_monitors() {
send_message(IPC_TYPE_GET_MONITORS, 1, (uint8_t *) "");
print_socket_reply();
return 0;
}
static int
get_tags()
{
static int get_tags() {
send_message(IPC_TYPE_GET_TAGS, 1, (uint8_t *) "");
print_socket_reply();
return 0;
}
static int
get_layouts()
{
static int get_layouts() {
send_message(IPC_TYPE_GET_LAYOUTS, 1, (uint8_t *) "");
print_socket_reply();
return 0;
}
static int
get_dwm_client(Window win)
{
static int get_dwm_client(Window win) {
const unsigned char *msg;
size_t msg_size;
@ -406,9 +390,7 @@ get_dwm_client(Window win)
return 0;
}
static int
subscribe(const char *event)
{
static int subscribe(const char *event) {
const unsigned char *msg;
size_t msg_size;
@ -440,9 +422,7 @@ subscribe(const char *event)
return 0;
}
static void
usage_error(const char *prog_name, const char *format, ...)
{
static void usage_error(const char *prog_name, const char *format, ...) {
va_list args;
va_start(args, format);
@ -455,9 +435,7 @@ usage_error(const char *prog_name, const char *format, ...)
exit(1);
}
static void
print_usage(const char *name)
{
static void print_usage(const char *name) {
printf("usage: %s [options] <command> [...]\n", name);
puts("");
puts("Commands:");
@ -472,11 +450,15 @@ print_usage(const char *name)
puts(" get_dwm_client <window_id> Get dwm client proprties");
puts("");
puts(" subscribe [events...] Subscribe to specified events");
puts(" Options: " IPC_EVENT_TAG_CHANGE ",");
puts(" Options: " IPC_EVENT_TAG_CHANGE
",");
puts(" " IPC_EVENT_LAYOUT_CHANGE ",");
puts(" " IPC_EVENT_CLIENT_FOCUS_CHANGE ",");
puts(" " IPC_EVENT_MONITOR_FOCUS_CHANGE ",");
puts(" " IPC_EVENT_FOCUSED_TITLE_CHANGE ",");
puts(" " IPC_EVENT_CLIENT_FOCUS_CHANGE
",");
puts(" " IPC_EVENT_MONITOR_FOCUS_CHANGE
",");
puts(" " IPC_EVENT_FOCUSED_TITLE_CHANGE
",");
puts(" " IPC_EVENT_FOCUSED_STATE_CHANGE);
puts("");
puts(" help Display this message");
@ -487,9 +469,7 @@ print_usage(const char *name)
puts("");
}
int
main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
const char *prog_name = argv[0];
connect_to_socket();
@ -504,12 +484,14 @@ main(int argc, char *argv[])
i++;
}
if (i >= argc) usage_error(prog_name, "Expected an argument, got none");
if (i >= argc)
usage_error(prog_name, "Expected an argument, got none");
if (strcmp(argv[i], "help") == 0)
print_usage(prog_name);
else if (strcmp(argv[i], "run_command") == 0) {
if (++i >= argc) usage_error(prog_name, "No command specified");
if (++i >= argc)
usage_error(prog_name, "No command specified");
// Command name
char *command = argv[i];
// Command arguments are everything after command name
@ -534,7 +516,8 @@ main(int argc, char *argv[])
usage_error(prog_name, "Expected the window id");
} else if (strcmp(argv[i], "subscribe") == 0) {
if (++i < argc) {
for (int j = i; j < argc; j++) subscribe(argv[j]);
for (int j = i; j < argc; j++)
subscribe(argv[j]);
} else
usage_error(prog_name, "Expected event name");
// Keep listening for events forever

File diff suppressed because it is too large Load Diff

@ -31,9 +31,7 @@ static const int IPC_SOCKET_BACKLOG = 5;
* Create IPC socket at specified path and return file descriptor to socket.
* This initializes the static variable sockaddr.
*/
static int
ipc_create_socket(const char *filename)
{
static int ipc_create_socket(const char *filename) {
char *normal_filename;
char *parent;
const size_t addr_size = sizeof(struct sockaddr_un);
@ -44,8 +42,8 @@ ipc_create_socket(const char *filename)
// In case socket file exists
unlink(normal_filename);
// For portability clear the addr structure, since some implementations have
// nonstandard fields in the structure
// For portability clear the addr structure, since some implementations
// have nonstandard fields in the structure
memset(&sockaddr, 0, addr_size);
parentdir(normal_filename, &parent);
@ -83,17 +81,16 @@ ipc_create_socket(const char *filename)
}
/**
* Internal function used to receive IPC messages from a given file descriptor.
* Internal function used to receive IPC messages from a given file
* descriptor.
*
* Returns -1 on error reading (could be EAGAIN or EINTR)
* Returns -2 if EOF before header could be read
* Returns -3 if invalid IPC header
* Returns -4 if message length exceeds MAX_MESSAGE_SIZE
*/
static int
ipc_recv_message(int fd, uint8_t *msg_type, uint32_t *reply_size,
uint8_t **reply)
{
static int ipc_recv_message(int fd, uint8_t *msg_type, uint32_t *reply_size,
uint8_t **reply) {
uint32_t read_bytes = 0;
const int32_t to_read = sizeof(dwm_ipc_header_t);
char header[to_read];
@ -105,15 +102,19 @@ ipc_recv_message(int fd, uint8_t *msg_type, uint32_t *reply_size,
if (n == 0) {
if (read_bytes == 0) {
fprintf(stderr, "Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
"Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32
" total bytes.\n",
read_bytes, to_read);
return -2;
} else {
fprintf(stderr, "Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
"Unexpectedly reached EOF while reading header.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32
" total bytes.\n",
read_bytes, to_read);
return -3;
}
@ -155,18 +156,22 @@ ipc_recv_message(int fd, uint8_t *msg_type, uint32_t *reply_size,
read_bytes = 0;
while (read_bytes < *reply_size) {
const ssize_t n = read(fd, *reply + read_bytes, *reply_size - read_bytes);
const ssize_t n =
read(fd, *reply + read_bytes, *reply_size - read_bytes);
if (n == 0) {
fprintf(stderr, "Unexpectedly reached EOF while reading payload.");
fprintf(stderr, "Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n",
fprintf(stderr,
"Unexpectedly reached EOF while reading payload.");
fprintf(stderr,
"Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n",
read_bytes, *reply_size);
free(*reply);
return -2;
} else if (n == -1) {
// TODO: Should we return and wait for another epoll event?
// This would require saving the partial read in some way.
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) continue;
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
continue;
free(*reply);
return -1;
@ -186,13 +191,12 @@ ipc_recv_message(int fd, uint8_t *msg_type, uint32_t *reply_size,
* Returns -1 on unknown error trying to write, errno will carry over from
* write() call
*/
static ssize_t
ipc_write_message(int fd, const void *buf, size_t count)
{
static ssize_t ipc_write_message(int fd, const void *buf, size_t count) {
size_t written = 0;
while (written < count) {
const ssize_t n = write(fd, (uint8_t *)buf + written, count - written);
const ssize_t n =
write(fd, (uint8_t *) buf + written, count - written);
if (n == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
@ -215,20 +219,16 @@ ipc_write_message(int fd, const void *buf, size_t count)
* handle, set yajl options, and in the future any other initialization that
* should occur for event messages.
*/
static void
ipc_event_init_message(yajl_gen *gen)
{
static void ipc_event_init_message(yajl_gen *gen) {
*gen = yajl_gen_alloc(NULL);
yajl_gen_config(*gen, yajl_gen_beautify, 1);
}
/**
* Prepares buffers of IPC subscribers of specified event using buffer from yajl
* handle.
* Prepares buffers of IPC subscribers of specified event using buffer from
* yajl handle.
*/
static void
ipc_event_prepare_send_message(yajl_gen gen, IPCEvent event)
{
static void ipc_event_prepare_send_message(yajl_gen gen, IPCEvent event) {
const unsigned char *buffer;
size_t len = 0;
@ -251,21 +251,17 @@ ipc_event_prepare_send_message(yajl_gen gen, IPCEvent event)
* handle, set yajl options, and in the future any other initialization that
* should occur for reply messages.
*/
static void
ipc_reply_init_message(yajl_gen *gen)
{
static void ipc_reply_init_message(yajl_gen *gen) {
*gen = yajl_gen_alloc(NULL);
yajl_gen_config(*gen, yajl_gen_beautify, 1);
}
/**
* Prepares the IPC client's buffer with a message using the buffer of the yajl
* handle.
* Prepares the IPC client's buffer with a message using the buffer of the
* yajl handle.
*/
static void
ipc_reply_prepare_send_message(yajl_gen gen, IPCClient *c,
IPCMessageType msg_type)
{
static void ipc_reply_prepare_send_message(yajl_gen gen, IPCClient *c,
IPCMessageType msg_type) {
const unsigned char *buffer;
size_t len = 0;
@ -284,9 +280,7 @@ ipc_reply_prepare_send_message(yajl_gen gen, IPCClient *c,
* Returns 0 if a command with the specified name was found
* Returns -1 if a command with the specified name could not be found
*/
static int
ipc_get_ipc_command(const char *name, IPCCommand *ipc_command)
{
static int ipc_get_ipc_command(const char *name, IPCCommand *ipc_command) {
for (int i = 0; i < ipc_commands_len; i++) {
if (strcmp(ipc_commands[i].name, name) == 0) {
*ipc_command = ipc_commands[i];
@ -307,9 +301,8 @@ ipc_get_ipc_command(const char *name, IPCCommand *ipc_command)
* Returns 0 if the message was successfully parsed
* Returns -1 otherwise
*/
static int
ipc_parse_run_command(char *msg, IPCParsedCommand *parsed_command)
{
static int ipc_parse_run_command(char *msg,
IPCParsedCommand *parsed_command) {
char error_buffer[1000];
yajl_val parent = yajl_tree_parse(msg, error_buffer, 1000);
@ -336,7 +329,8 @@ ipc_parse_run_command(char *msg, IPCParsedCommand *parsed_command)
const char *command_name = YAJL_GET_STRING(command_val);
size_t command_name_len = strlen(command_name);
parsed_command->name = (char *)malloc((command_name_len + 1) * sizeof(char));
parsed_command->name =
(char *) malloc((command_name_len + 1) * sizeof(char));
strcpy(parsed_command->name, command_name);
DEBUG("Received command: %s\n", parsed_command->name);
@ -409,11 +403,10 @@ ipc_parse_run_command(char *msg, IPCParsedCommand *parsed_command)
/**
* Free the members of a IPCParsedCommand struct
*/
static void
ipc_free_parsed_command_members(IPCParsedCommand *command)
{
static void ipc_free_parsed_command_members(IPCParsedCommand *command) {
for (int i = 0; i < command->argc; i++) {
if (command->arg_types[i] == ARG_TYPE_STR) free((void *)command->args[i].v);
if (command->arg_types[i] == ARG_TYPE_STR)
free((void *) command->args[i].v);
}
free(command->args);
free(command->arg_types);
@ -428,10 +421,10 @@ ipc_free_parsed_command_members(IPCParsedCommand *command)
* Returns -1 if the argument count doesn't match
* Returns -2 if the argument types don't match
*/
static int
ipc_validate_run_command(IPCParsedCommand *parsed, const IPCCommand actual)
{
if (actual.argc != parsed->argc) return -1;
static int ipc_validate_run_command(IPCParsedCommand *parsed,
const IPCCommand actual) {
if (actual.argc != parsed->argc)
return -1;
for (int i = 0; i < parsed->argc; i++) {
ArgType ptype = parsed->arg_types[i];
@ -458,9 +451,7 @@ ipc_validate_run_command(IPCParsedCommand *parsed, const IPCCommand actual)
* Returns 0 if a valid event name was given
* Returns -1 otherwise
*/
static int
ipc_event_stoi(const char *subscription, IPCEvent *event)
{
static int ipc_event_stoi(const char *subscription, IPCEvent *event) {
if (strcmp(subscription, "tag_change_event") == 0)
*event = IPC_EVENT_TAG_CHANGE;
else if (strcmp(subscription, "client_focus_change_event") == 0)
@ -479,16 +470,15 @@ ipc_event_stoi(const char *subscription, IPCEvent *event)
}
/**
* Parse a IPC_TYPE_SUBSCRIBE message from a client. This function extracts the
* event name and the subscription action from the message.
* Parse a IPC_TYPE_SUBSCRIBE message from a client. This function extracts
* the event name and the subscription action from the message.
*
* Returns 0 if message was successfully parsed
* Returns -1 otherwise
*/
static int
ipc_parse_subscribe(const char *msg, IPCSubscriptionAction *subscribe,
IPCEvent *event)
{
static int ipc_parse_subscribe(const char *msg,
IPCSubscriptionAction *subscribe,
IPCEvent *event) {
char error_buffer[100];
yajl_val parent = yajl_tree_parse((char *) msg, error_buffer, 100);
@ -514,7 +504,8 @@ ipc_parse_subscribe(const char *msg, IPCSubscriptionAction *subscribe,
const char *event_str = YAJL_GET_STRING(event_val);
DEBUG("Received event: %s\n", event_str);
if (ipc_event_stoi(event_str, event) < 0) return -1;
if (ipc_event_stoi(event_str, event) < 0)
return -1;
const char *action_path[] = {"action", 0};
yajl_val action_val = yajl_tree_get(parent, action_path, yajl_t_string);
@ -547,9 +538,7 @@ ipc_parse_subscribe(const char *msg, IPCSubscriptionAction *subscribe,
* Returns 0 if message was successfully parsed
* Returns -1 otherwise
*/
static int
ipc_parse_get_dwm_client(const char *msg, Window *win)
{
static int ipc_parse_get_dwm_client(const char *msg, Window *win) {
char error_buffer[100];
yajl_val parent = yajl_tree_parse(msg, error_buffer, 100);
@ -581,20 +570,19 @@ ipc_parse_get_dwm_client(const char *msg, Window *win)
/**
* Called when an IPC_TYPE_RUN_COMMAND message is received from a client. This
* function parses, executes the given command, and prepares a reply message to
* the client indicating success/failure.
* function parses, executes the given command, and prepares a reply message
* to the client indicating success/failure.
*
* NOTE: There is currently no check for argument validity beyond the number of
* arguments given and types of arguments. There is also no way to check if the
* function succeeded based on dwm's void(const Arg*) function types. Pointer
* arguments can cause crashes if they are not validated in the function itself.
* NOTE: There is currently no check for argument validity beyond the number
* of arguments given and types of arguments. There is also no way to check if
* the function succeeded based on dwm's void(const Arg*) function types.
* Pointer arguments can cause crashes if they are not validated in the
* function itself.
*
* Returns 0 if message was successfully parsed
* Returns -1 on failure parsing message
*/
static int
ipc_run_command(IPCClient *ipc_client, char *msg)
{
static int ipc_run_command(IPCClient *ipc_client, char *msg) {
IPCParsedCommand parsed_command;
IPCCommand ipc_command;
@ -609,7 +597,8 @@ ipc_run_command(IPCClient *ipc_client, char *msg)
if (ipc_get_ipc_command(parsed_command.name, &ipc_command) < 0) {
ipc_prepare_reply_failure(ipc_client, IPC_TYPE_RUN_COMMAND,
"Command %s not found", parsed_command.name);
"Command %s not found",
parsed_command.name);
ipc_free_parsed_command_members(&parsed_command);
return -1;
}
@ -630,7 +619,8 @@ ipc_run_command(IPCClient *ipc_client, char *msg)
if (parsed_command.argc == 1)
ipc_command.func.single_param(parsed_command.args);
else if (parsed_command.argc > 1)
ipc_command.func.array_param(parsed_command.args, parsed_command.argc);
ipc_command.func.array_param(parsed_command.args,
parsed_command.argc);
DEBUG("Called function for command %s\n", parsed_command.name);
@ -644,9 +634,7 @@ ipc_run_command(IPCClient *ipc_client, char *msg)
* Called when an IPC_TYPE_GET_MONITORS message is received from a client. It
* prepares a reply with the properties of all of the monitors in JSON.
*/
static void
ipc_get_monitors(IPCClient *c, Monitor *mons, Monitor *selmon)
{
static void ipc_get_monitors(IPCClient *c, Monitor *mons, Monitor *selmon) {
yajl_gen gen;
ipc_reply_init_message(&gen);
dump_monitors(gen, mons, selmon);
@ -658,9 +646,8 @@ ipc_get_monitors(IPCClient *c, Monitor *mons, Monitor *selmon)
* Called when an IPC_TYPE_GET_TAGS message is received from a client. It
* prepares a reply with info about all the tags in JSON.
*/
static void
ipc_get_tags(IPCClient *c, const char *tags[], const int tags_len)
{
static void ipc_get_tags(IPCClient *c, const char *tags[],
const int tags_len) {
yajl_gen gen;
ipc_reply_init_message(&gen);
@ -673,9 +660,8 @@ ipc_get_tags(IPCClient *c, const char *tags[], const int tags_len)
* Called when an IPC_TYPE_GET_LAYOUTS message is received from a client. It
* prepares a reply with a JSON array of available layouts
*/
static void
ipc_get_layouts(IPCClient *c, const Layout layouts[], const int layouts_len)
{
static void ipc_get_layouts(IPCClient *c, const Layout layouts[],
const int layouts_len) {
yajl_gen gen;
ipc_reply_init_message(&gen);
@ -685,20 +671,20 @@ ipc_get_layouts(IPCClient *c, const Layout layouts[], const int layouts_len)
}
/**
* Called when an IPC_TYPE_GET_DWM_CLIENT message is received from a client. It
* prepares a JSON reply with the properties of the client with the specified
* window XID.
* Called when an IPC_TYPE_GET_DWM_CLIENT message is received from a client.
* It prepares a JSON reply with the properties of the client with the
* specified window XID.
*
* Returns 0 if the message was successfully parsed and if the client with the
* specified window XID was found
* Returns -1 if the message could not be parsed
*/
static int
ipc_get_dwm_client(IPCClient *ipc_client, const char *msg, const Monitor *mons)
{
static int ipc_get_dwm_client(IPCClient *ipc_client, const char *msg,
const Monitor *mons) {
Window win;
if (ipc_parse_get_dwm_client(msg, &win) < 0) return -1;
if (ipc_parse_get_dwm_client(msg, &win) < 0)
return -1;
// Find client with specified window XID
for (const Monitor *m = mons; m; m = m->next)
@ -722,20 +708,19 @@ ipc_get_dwm_client(IPCClient *ipc_client, const char *msg, const Monitor *mons)
/**
* Called when an IPC_TYPE_SUBSCRIBE message is received from a client. It
* subscribes/unsubscribes the client from the specified event and replies with
* the result.
* subscribes/unsubscribes the client from the specified event and replies
* with the result.
*
* Returns 0 if the message was successfully parsed.
* Returns -1 if the message could not be parsed
*/
static int
ipc_subscribe(IPCClient *c, const char *msg)
{
static int ipc_subscribe(IPCClient *c, const char *msg) {
IPCSubscriptionAction action = IPC_ACTION_SUBSCRIBE;
IPCEvent event = 0;
if (ipc_parse_subscribe(msg, &action, &event)) {
ipc_prepare_reply_failure(c, IPC_TYPE_SUBSCRIBE, "Event does not exist");
ipc_prepare_reply_failure(c, IPC_TYPE_SUBSCRIBE,
"Event does not exist");
return -1;
}
@ -755,15 +740,14 @@ ipc_subscribe(IPCClient *c, const char *msg)
return 0;
}
int
ipc_init(const char *socket_path, const int p_epoll_fd, IPCCommand commands[],
const int commands_len)
{
int ipc_init(const char *socket_path, const int p_epoll_fd,
IPCCommand commands[], const int commands_len) {
// Initialize struct to 0
memset(&sock_epoll_event, 0, sizeof(sock_epoll_event));
int socket_fd = ipc_create_socket(socket_path);
if (socket_fd < 0) return -1;
if (socket_fd < 0)
return -1;
ipc_commands = commands;
ipc_commands_len = commands_len;
@ -781,9 +765,7 @@ ipc_init(const char *socket_path, const int p_epoll_fd, IPCCommand commands[],
return socket_fd;
}
void
ipc_cleanup()
{
void ipc_cleanup() {
IPCClient *c = ipc_clients;
// Free clients and their buffers
while (c) {
@ -809,27 +791,19 @@ ipc_cleanup()
close(sock_fd);
}
int
ipc_get_sock_fd()
{
int ipc_get_sock_fd() {
return sock_fd;
}
IPCClient *
ipc_get_client(int fd)
{
IPCClient *ipc_get_client(int fd) {
return ipc_list_get_client(ipc_clients, fd);
}
int
ipc_is_client_registered(int fd)
{
int ipc_is_client_registered(int fd) {
return (ipc_get_client(fd) != NULL);
}
int
ipc_accept_client()
{
int ipc_accept_client() {
int fd = -1;
struct sockaddr_un client_addr;
@ -852,7 +826,8 @@ ipc_accept_client()
}
IPCClient *nc = ipc_client_new(fd);
if (nc == NULL) return -1;
if (nc == NULL)
return -1;
// Wake up to messages from this client
nc->event.data.fd = fd;
@ -866,9 +841,7 @@ ipc_accept_client()
return fd;
}
int
ipc_drop_client(IPCClient *c)
{
int ipc_drop_client(IPCClient *c) {
int fd = c->fd;
shutdown(fd, SHUT_RDWR);
int res = close(fd);
@ -891,21 +864,20 @@ ipc_drop_client(IPCClient *c)
return res;
}
int
ipc_read_client(IPCClient *c, IPCMessageType *msg_type, uint32_t *msg_size,
char **msg)
{
int ipc_read_client(IPCClient *c, IPCMessageType *msg_type,
uint32_t *msg_size, char **msg) {
int fd = c->fd;
int ret =
ipc_recv_message(fd, (uint8_t *)msg_type, msg_size, (uint8_t **)msg);
int ret = ipc_recv_message(fd, (uint8_t *) msg_type, msg_size,
(uint8_t **) msg);
if (ret < 0) {
// This will happen if these errors occur while reading header
if (ret == -1 &&
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
if (ret == -1
&& (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
return -2;
fprintf(stderr, "Error reading message: dropping client at fd %d\n", fd);
fprintf(stderr, "Error reading message: dropping client at fd %d\n",
fd);
ipc_drop_client(c);
return -1;
@ -929,12 +901,11 @@ ipc_read_client(IPCClient *c, IPCMessageType *msg_type, uint32_t *msg_size,
return 0;
}
ssize_t
ipc_write_client(IPCClient *c)
{
ssize_t ipc_write_client(IPCClient *c) {
const ssize_t n = ipc_write_message(c->fd, c->buffer, c->buffer_size);
if (n < 0) return n;
if (n < 0)
return n;
// TODO: Deal with client timeouts
@ -959,12 +930,11 @@ ipc_write_client(IPCClient *c)
return n;
}
void
ipc_prepare_send_message(IPCClient *c, const IPCMessageType msg_type,
const uint32_t msg_size, const char *msg)
{
dwm_ipc_header_t header = {
.magic = IPC_MAGIC_ARR, .type = msg_type, .size = msg_size};
void ipc_prepare_send_message(IPCClient *c, const IPCMessageType msg_type,
const uint32_t msg_size, const char *msg) {
dwm_ipc_header_t header = {.magic = IPC_MAGIC_ARR,
.type = msg_type,
.size = msg_size};
uint32_t header_size = sizeof(dwm_ipc_header_t);
uint32_t packet_size = header_size + msg_size;
@ -987,10 +957,8 @@ ipc_prepare_send_message(IPCClient *c, const IPCMessageType msg_type,
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, c->fd, &c->event);
}
void
ipc_prepare_reply_failure(IPCClient *c, IPCMessageType msg_type,
const char *format, ...)
{
void ipc_prepare_reply_failure(IPCClient *c, IPCMessageType msg_type,
const char *format, ...) {
yajl_gen gen;
va_list args;
@ -1013,39 +981,32 @@ ipc_prepare_reply_failure(IPCClient *c, IPCMessageType msg_type,
free(buffer);
}
void
ipc_prepare_reply_success(IPCClient *c, IPCMessageType msg_type)
{
void ipc_prepare_reply_success(IPCClient *c, IPCMessageType msg_type) {
const char *success_msg = "{\"result\":\"success\"}";
const size_t msg_len = strlen(success_msg) + 1; // +1 for null char
ipc_prepare_send_message(c, msg_type, msg_len, success_msg);
}
void
ipc_tag_change_event(int mon_num, TagState old_state, TagState new_state)
{
void ipc_tag_change_event(int mon_num, TagState old_state,
TagState new_state) {
yajl_gen gen;
ipc_event_init_message(&gen);
dump_tag_event(gen, mon_num, old_state, new_state);
ipc_event_prepare_send_message(gen, IPC_EVENT_TAG_CHANGE);
}
void
ipc_client_focus_change_event(int mon_num, Client *old_client,
Client *new_client)
{
void ipc_client_focus_change_event(int mon_num, Client *old_client,
Client *new_client) {
yajl_gen gen;
ipc_event_init_message(&gen);
dump_client_focus_change_event(gen, old_client, new_client, mon_num);
ipc_event_prepare_send_message(gen, IPC_EVENT_CLIENT_FOCUS_CHANGE);
}
void
ipc_layout_change_event(const int mon_num, const char *old_symbol,
void ipc_layout_change_event(const int mon_num, const char *old_symbol,
const Layout *old_layout, const char *new_symbol,
const Layout *new_layout)
{
const Layout *new_layout) {
yajl_gen gen;
ipc_event_init_message(&gen);
dump_layout_change_event(gen, mon_num, old_symbol, old_layout, new_symbol,
@ -1053,30 +1014,27 @@ ipc_layout_change_event(const int mon_num, const char *old_symbol,
ipc_event_prepare_send_message(gen, IPC_EVENT_LAYOUT_CHANGE);
}
void
ipc_monitor_focus_change_event(const int last_mon_num, const int new_mon_num)
{
void ipc_monitor_focus_change_event(const int last_mon_num,
const int new_mon_num) {
yajl_gen gen;
ipc_event_init_message(&gen);
dump_monitor_focus_change_event(gen, last_mon_num, new_mon_num);
ipc_event_prepare_send_message(gen, IPC_EVENT_MONITOR_FOCUS_CHANGE);
}
void
ipc_focused_title_change_event(const int mon_num, const Window client_id,
const char *old_name, const char *new_name)
{
void ipc_focused_title_change_event(const int mon_num, const Window client_id,
const char *old_name,
const char *new_name) {
yajl_gen gen;
ipc_event_init_message(&gen);
dump_focused_title_change_event(gen, mon_num, client_id, old_name, new_name);
dump_focused_title_change_event(gen, mon_num, client_id, old_name,
new_name);
ipc_event_prepare_send_message(gen, IPC_EVENT_FOCUSED_TITLE_CHANGE);
}
void
ipc_focused_state_change_event(const int mon_num, const Window client_id,
void ipc_focused_state_change_event(const int mon_num, const Window client_id,
const ClientState *old_state,
const ClientState *new_state)
{
const ClientState *new_state) {
yajl_gen gen;
ipc_event_init_message(&gen);
dump_focused_state_change_event(gen, mon_num, client_id, old_state,
@ -1084,20 +1042,21 @@ ipc_focused_state_change_event(const int mon_num, const Window client_id,
ipc_event_prepare_send_message(gen, IPC_EVENT_FOCUSED_STATE_CHANGE);
}
void
ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon)
{
void ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon) {
for (Monitor *m = mons; m; m = m->next) {
unsigned int urg = 0, occ = 0, tagset = 0;
for (Client *c = m->clients; c; c = c->next) {
occ |= c->tags;
if (c->isurgent) urg |= c->tags;
if (c->isurgent)
urg |= c->tags;
}
tagset = m->tagset[m->seltags];
TagState new_state = {.selected = tagset, .occupied = occ, .urgent = urg};
TagState new_state = {.selected = tagset,
.occupied = occ,
.urgent = urg};
if (memcmp(&m->tagstate, &new_state, sizeof(TagState)) != 0) {
ipc_tag_change_event(m->num, m->tagstate, new_state);
@ -1109,22 +1068,24 @@ ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon)
m->lastsel = m->sel;
}
if (strcmp(m->ltsymbol, m->lastltsymbol) != 0 ||
m->lastlt != m->lt[m->sellt]) {
ipc_layout_change_event(m->num, m->lastltsymbol, m->lastlt, m->ltsymbol,
m->lt[m->sellt]);
if (strcmp(m->ltsymbol, m->lastltsymbol) != 0
|| m->lastlt != m->lt[m->sellt]) {
ipc_layout_change_event(m->num, m->lastltsymbol, m->lastlt,
m->ltsymbol, m->lt[m->sellt]);
strcpy(m->lastltsymbol, m->ltsymbol);
m->lastlt = m->lt[m->sellt];
}
if (*lastselmon != selmon) {
if (*lastselmon != NULL)
ipc_monitor_focus_change_event((*lastselmon)->num, selmon->num);
ipc_monitor_focus_change_event((*lastselmon)->num,
selmon->num);
*lastselmon = selmon;
}
Client *sel = m->sel;
if (!sel) continue;
if (!sel)
continue;
ClientState *o = &m->sel->prevstate;
ClientState n = {.oldstate = sel->oldstate,
.isfixed = sel->isfixed,
@ -1139,12 +1100,11 @@ ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon)
}
}
int
ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
int ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
Monitor **lastselmon, Monitor *selmon,
const char *tags[], const int tags_len,
const Layout *layouts, const int layouts_len)
{
const Layout *layouts,
const int layouts_len) {
int fd = ev->data.fd;
IPCClient *c = ipc_get_client(fd);
@ -1153,14 +1113,16 @@ ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
ipc_drop_client(c);
} else if (ev->events & EPOLLOUT) {
DEBUG("Sending message to client at fd %d...\n", fd);
if (c->buffer_size) ipc_write_client(c);
if (c->buffer_size)
ipc_write_client(c);
} else if (ev->events & EPOLLIN) {
IPCMessageType msg_type = 0;
uint32_t msg_size = 0;
char *msg = NULL;
DEBUG("Received message from fd %d\n", fd);
if (ipc_read_client(c, &msg_type, &msg_size, &msg) < 0) return -1;
if (ipc_read_client(c, &msg_type, &msg_size, &msg) < 0)
return -1;
if (msg_type == IPC_TYPE_GET_MONITORS)
ipc_get_monitors(c, mons, selmon);
@ -1169,12 +1131,15 @@ ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
else if (msg_type == IPC_TYPE_GET_LAYOUTS)
ipc_get_layouts(c, layouts, layouts_len);
else if (msg_type == IPC_TYPE_RUN_COMMAND) {
if (ipc_run_command(c, msg) < 0) return -1;
if (ipc_run_command(c, msg) < 0)
return -1;
ipc_send_events(mons, lastselmon, selmon);
} else if (msg_type == IPC_TYPE_GET_DWM_CLIENT) {
if (ipc_get_dwm_client(c, msg, mons) < 0) return -1;
if (ipc_get_dwm_client(c, msg, mons) < 0)
return -1;
} else if (msg_type == IPC_TYPE_SUBSCRIBE) {
if (ipc_subscribe(c, msg) < 0) return -1;
if (ipc_subscribe(c, msg) < 0)
return -1;
} else {
fprintf(stderr, "Invalid message type received from fd %d", fd);
ipc_prepare_reply_failure(c, msg_type, "Invalid message type: %d",
@ -1182,17 +1147,17 @@ ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
}
free(msg);
} else {
fprintf(stderr, "Epoll event returned %d from fd %d\n", ev->events, fd);
fprintf(stderr, "Epoll event returned %d from fd %d\n", ev->events,
fd);
return -1;
}
return 0;
}
int
ipc_handle_socket_epoll_event(struct epoll_event *ev)
{
if (!(ev->events & EPOLLIN)) return -1;
int ipc_handle_socket_epoll_event(struct epoll_event *ev) {
if (!(ev->events & EPOLLIN))
return -1;
// EPOLLIN means incoming client connection request
fputs("Received EPOLLIN event on socket\n", stderr);

@ -88,15 +88,15 @@ typedef struct IPCParsedCommand {
* @param commands Address of IPCCommands array defined in config.h
* @param commands_len Length of commands[] array
*
* @return int The file descriptor of the socket if it was successfully created,
* -1 otherwise
* @return int The file descriptor of the socket if it was successfully
* created, -1 otherwise
*/
int ipc_init(const char *socket_path, const int p_epoll_fd,
IPCCommand commands[], const int commands_len);
/**
* Uninitialize the socket and module. Free allocated memory and restore static
* variables to their state before ipc_init
* Uninitialize the socket and module. Free allocated memory and restore
* static variables to their state before ipc_init
*/
void ipc_cleanup();
@ -150,16 +150,16 @@ int ipc_accept_client();
* @param c Address of IPCClient
* @param msg_type Address to IPCMessageType variable which will be assigned
* the message type of the received message
* @param msg_size Address to uint32_t variable which will be assigned the size
* of the received message
* @param msg_size Address to uint32_t variable which will be assigned the
* size of the received message
* @param msg Address to char* variable which will be assigned the address of
* the received message. This must be freed using free().
*
* @return 0 on success, -1 on error reading message, -2 if reading the message
* resulted in EAGAIN, EINTR, or EWOULDBLOCK.
* @return 0 on success, -1 on error reading message, -2 if reading the
* message resulted in EAGAIN, EINTR, or EWOULDBLOCK.
*/
int ipc_read_client(IPCClient *c, IPCMessageType *msg_type, uint32_t *msg_size,
char **msg);
int ipc_read_client(IPCClient *c, IPCMessageType *msg_type,
uint32_t *msg_size, char **msg);
/**
* Write any pending buffer of the client to the client's socket
@ -204,8 +204,8 @@ void ipc_prepare_reply_failure(IPCClient *c, IPCMessageType msg_type,
void ipc_prepare_reply_success(IPCClient *c, IPCMessageType msg_type);
/**
* Send a tag_change_event to all subscribers. Should be called only when there
* has been a tag state change.
* Send a tag_change_event to all subscribers. Should be called only when
* there has been a tag state change.
*
* @param mon_num The index of the monitor (Monitor.num property)
* @param old_state The old tag state
@ -259,7 +259,8 @@ void ipc_monitor_focus_change_event(const int last_mon_num,
* @param new_name New name of the client window
*/
void ipc_focused_title_change_event(const int mon_num, const Window client_id,
const char *old_name, const char *new_name);
const char *old_name,
const char *new_name);
/**
* Send a focused_state_change_event to all subscribers. Should only be called
@ -285,8 +286,8 @@ void ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon);
/**
* Handle an epoll event caused by a registered IPC client. Read, process, and
* handle any received messages from clients. Write pending buffer to client if
* the client is ready to receive messages. Drop clients that have sent an
* handle any received messages from clients. Write pending buffer to client
* if the client is ready to receive messages. Drop clients that have sent an
* EPOLLHUP.
*
* @param ev Associated epoll event returned by epoll_wait
@ -304,16 +305,18 @@ void ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon);
int ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
Monitor **lastselmon, Monitor *selmon,
const char *tags[], const int tags_len,
const Layout *layouts, const int layouts_len);
const Layout *layouts,
const int layouts_len);
/**
* Handle an epoll event caused by the IPC socket. This function only handles an
* EPOLLIN event indicating a new client requesting to connect to the socket.
* Handle an epoll event caused by the IPC socket. This function only handles
* an EPOLLIN event indicating a new client requesting to connect to the
* socket.
*
* @param ev Associated epoll event returned by epoll_wait
*
* @return 0, if the event was successfully handled, -1 if not an EPOLLIN event
* or if a new IPC client connection request could not be accepted.
* @return 0, if the event was successfully handled, -1 if not an EPOLLIN
* event or if a new IPC client connection request could not be accepted.
*/
int ipc_handle_socket_epoll_event(struct epoll_event *ev);

@ -1,9 +1,9 @@
/* cc transient.c -o transient -lX11 */
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
Display *d;

@ -1,16 +1,14 @@
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include "util.h"
void *
ecalloc(size_t nmemb, size_t size)
{
void *ecalloc(size_t nmemb, size_t size) {
void *p;
if (!(p = calloc(nmemb, size)))
@ -18,8 +16,7 @@ ecalloc(size_t nmemb, size_t size)
return p;
}
void
die(const char *fmt, ...) {
void die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
@ -36,9 +33,7 @@ die(const char *fmt, ...) {
exit(1);
}
int
normalizepath(const char *path, char **normal)
{
int normalizepath(const char *path, char **normal) {
size_t len = strlen(path);
*normal = (char *) malloc((len + 1) * sizeof(char));
const char *walk = path;
@ -71,9 +66,7 @@ normalizepath(const char *path, char **normal)
return 0;
}
int
parentdir(const char *path, char **parent)
{
int parentdir(const char *path, char **parent) {
char *normal;
char *walk;
@ -99,9 +92,7 @@ parentdir(const char *path, char **parent)
return 0;
}
int
mkdirp(const char *path)
{
int mkdirp(const char *path) {
char *normal;
char *walk;
size_t normallen;
@ -156,9 +147,7 @@ mkdirp(const char *path)
return 0;
}
int
nullterminate(char **str, size_t *len)
{
int nullterminate(char **str, size_t *len) {
if ((*str)[*len - 1] == '\0')
return 0;

@ -2,9 +2,7 @@
#include <stdint.h>
int
dump_tag(yajl_gen gen, const char *name, const int tag_mask)
{
int dump_tag(yajl_gen gen, const char *name, const int tag_mask) {
// clang-format off
YMAP(
YSTR("bit_mask"); YINT(tag_mask);
@ -15,9 +13,7 @@ dump_tag(yajl_gen gen, const char *name, const int tag_mask)
return 0;
}
int
dump_tags(yajl_gen gen, const char *tags[], int tags_len)
{
int dump_tags(yajl_gen gen, const char *tags[], int tags_len) {
// clang-format off
YARR(
for (int i = 0; i < tags_len; i++)
@ -28,9 +24,7 @@ dump_tags(yajl_gen gen, const char *tags[], int tags_len)
return 0;
}
int
dump_client(yajl_gen gen, Client *c)
{
int dump_client(yajl_gen gen, Client *c) {
// clang-format off
YMAP(
YSTR("name"); YSTR(c->name);
@ -95,9 +89,7 @@ dump_client(yajl_gen gen, Client *c)
return 0;
}
int
dump_monitor(yajl_gen gen, Monitor *mon, int is_selected)
{
int dump_monitor(yajl_gen gen, Monitor *mon, int is_selected) {
// clang-format off
YMAP(
YSTR("master_factor"); YDOUBLE(mon->mfact);
@ -161,9 +153,7 @@ dump_monitor(yajl_gen gen, Monitor *mon, int is_selected)
return 0;
}
int
dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon)
{
int dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon) {
// clang-format off
YARR(
for (Monitor *mon = mons; mon; mon = mon->next) {
@ -178,9 +168,8 @@ dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon)
return 0;
}
int
dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len)
{
int dump_layouts(yajl_gen gen, const Layout layouts[],
const int layouts_len) {
// clang-format off
YARR(
for (int i = 0; i < layouts_len; i++) {
@ -197,9 +186,7 @@ dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len)
return 0;
}
int
dump_tag_state(yajl_gen gen, TagState state)
{
int dump_tag_state(yajl_gen gen, TagState state) {
// clang-format off
YMAP(
YSTR("selected"); YINT(state.selected);
@ -211,10 +198,8 @@ dump_tag_state(yajl_gen gen, TagState state)
return 0;
}
int
dump_tag_event(yajl_gen gen, int mon_num, TagState old_state,
TagState new_state)
{
int dump_tag_event(yajl_gen gen, int mon_num, TagState old_state,
TagState new_state) {
// clang-format off
YMAP(
YSTR("tag_change_event"); YMAP(
@ -228,10 +213,8 @@ dump_tag_event(yajl_gen gen, int mon_num, TagState old_state,
return 0;
}
int
dump_client_focus_change_event(yajl_gen gen, Client *old_client,
Client *new_client, int mon_num)
{
int dump_client_focus_change_event(yajl_gen gen, Client *old_client,
Client *new_client, int mon_num) {
// clang-format off
YMAP(
YSTR("client_focus_change_event"); YMAP(
@ -245,11 +228,10 @@ dump_client_focus_change_event(yajl_gen gen, Client *old_client,
return 0;
}
int
dump_layout_change_event(yajl_gen gen, const int mon_num,
int dump_layout_change_event(yajl_gen gen, const int mon_num,
const char *old_symbol, const Layout *old_layout,
const char *new_symbol, const Layout *new_layout)
{
const char *new_symbol,
const Layout *new_layout) {
// clang-format off
YMAP(
YSTR("layout_change_event"); YMAP(
@ -265,10 +247,8 @@ dump_layout_change_event(yajl_gen gen, const int mon_num,
return 0;
}
int
dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
const int new_mon_num)
{
int dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
const int new_mon_num) {
// clang-format off
YMAP(
YSTR("monitor_focus_change_event"); YMAP(
@ -281,11 +261,10 @@ dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
return 0;
}
int
dump_focused_title_change_event(yajl_gen gen, const int mon_num,
const Window client_id, const char *old_name,
const char *new_name)
{
int dump_focused_title_change_event(yajl_gen gen, const int mon_num,
const Window client_id,
const char *old_name,
const char *new_name) {
// clang-format off
YMAP(
YSTR("focused_title_change_event"); YMAP(
@ -300,9 +279,7 @@ dump_focused_title_change_event(yajl_gen gen, const int mon_num,
return 0;
}
int
dump_client_state(yajl_gen gen, const ClientState *state)
{
int dump_client_state(yajl_gen gen, const ClientState *state) {
// clang-format off
YMAP(
YSTR("old_state"); YBOOL(state->oldstate);
@ -317,12 +294,10 @@ dump_client_state(yajl_gen gen, const ClientState *state)
return 0;
}
int
dump_focused_state_change_event(yajl_gen gen, const int mon_num,
int dump_focused_state_change_event(yajl_gen gen, const int mon_num,
const Window client_id,
const ClientState *old_state,
const ClientState *new_state)
{
const ClientState *new_state) {
// clang-format off
YMAP(
YSTR("focused_state_change_event"); YMAP(
@ -337,9 +312,7 @@ dump_focused_state_change_event(yajl_gen gen, const int mon_num,
return 0;
}
int
dump_error_message(yajl_gen gen, const char *reason)
{
int dump_error_message(yajl_gen gen, const char *reason) {
// clang-format off
YMAP(
YSTR("result"); YSTR("error");

@ -44,14 +44,16 @@ int dump_client_focus_change_event(yajl_gen gen, Client *old_client,
int dump_layout_change_event(yajl_gen gen, const int mon_num,
const char *old_symbol, const Layout *old_layout,
const char *new_symbol, const Layout *new_layout);
const char *new_symbol,
const Layout *new_layout);
int dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
const int new_mon_num);
int dump_focused_title_change_event(yajl_gen gen, const int mon_num,
const Window client_id,
const char *old_name, const char *new_name);
const char *old_name,
const char *new_name);
int dump_client_state(yajl_gen gen, const ClientState *state);

Loading…
Cancel
Save