/*-
* Copyright (c) 2001 Jordan DeLong
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "plugutil.h"
/* default flags and the like for a WM_CLASS */
typedef struct wcdefs {
char *res_name; /* resource name */
char *res_class; /* pointer into res_name, don't free() it */
/* dgroup to use, or null */
dgroup_t *dgroup;
/* stacking layer to put the client in */
int stacklayer;
/* these correspond to clientflags_t, read client.h */
int nofocus;
int noresize;
int nomove;
int noiconify;
int nodelete;
int sticky;
SLIST_ENTRY(wcdefs) w_list;
} wcdefs_t;
/* list of wcdefs */
static SLIST_HEAD(, wcdefs) wcdefs_list = SLIST_HEAD_INITIALIZER(wcdefs_list);
/* find a wcdefs based on a res_name and res_class */
static wcdefs_t *wcdefs_find(char *res_name, char *res_class) {
wcdefs_t *wcdefs;
/* make sure it has res_name and res_class */
if (!res_name || !res_class)
return NULL;
/* loop through and cmp the strings */
SLIST_FOREACH(wcdefs, &wcdefs_list, w_list)
if (strcmp(wcdefs->res_class, res_class) == 0)
if (strcmp(wcdefs->res_name, res_name) == 0)
goto found;
return NULL;
found:
return wcdefs;
}
/* handle default setting on newly arriving clients */
static int init_hints(int pcall, client_t *client) {
wcdefs_t *wcdefs;
/* find an appropriate wcdefs */
wcdefs = wcdefs_find(client->classhint.res_name, client->classhint.res_class);
if (!wcdefs)
return PLUGIN_OK;
/*
* set flags to our wcdefs flags. don't touch flags that the user didn't
* say anything about in their rc.
*/
if (wcdefs->nofocus != -1)
client->flags.nofocus = wcdefs->nofocus;
if (wcdefs->noresize != -1)
client->flags.noresize = wcdefs->noresize;
if (wcdefs->nomove != -1)
client->flags.nomove = wcdefs->nomove;
if (wcdefs->noiconify != -1)
client->flags.noiconify = wcdefs->noiconify;
if (wcdefs->nodelete != -1)
client->flags.nodelete = wcdefs->nodelete;
if (wcdefs->sticky != -1)
client->flags.sticky = wcdefs->sticky;
/* set dgroup if we got one specified */
if (wcdefs->dgroup)
client->dgroup = wcdefs->dgroup;
/* set stacking layer if it was specified */
if (wcdefs->stacklayer != -1)
client->stacklayer = wcdefs->stacklayer;
return PLUGIN_OK;
}
/* build our defaults information structures */
int init() {
wcdefs_t *wcdefs;
param_t *param;
char *res_name, *res_class;
int i;
/* get all the wcdefs_t's built */
SUBPARAMS_FOREACH(i, param, &plugin_this->params) {
if (strcmp(param->name, "def") != 0)
continue;
/* get the res_name.res_class pair from the value */
res_name = strdup(param->value);
if (!res_name)
PERR("no memory to strdup res_name.res_class");
res_class = strrchr(res_name, '.');
if (*res_class != '\0')
*res_class++ = '\0';
/* see if a entry exists, or make one */
wcdefs = wcdefs_find(res_name, res_class);
if (!wcdefs) {
wcdefs = malloc(sizeof(wcdefs_t));
if (!wcdefs) {
free(res_name);
PERR("no memory for wcdefs");
}
/* init the structure */
wcdefs->res_name = res_name;
wcdefs->res_class = res_class;
wcdefs->dgroup = NULL;
wcdefs->stacklayer = -1;
wcdefs->nofocus = -1;
wcdefs->noresize = -1;
wcdefs->nomove = -1;
wcdefs->noiconify = -1;
wcdefs->nodelete = -1;
wcdefs->sticky = -1;
SLIST_INSERT_HEAD(&wcdefs_list, wcdefs, w_list);
} else
free(res_name);
/* now read for anything they set */
OPTIONAL_PARAM(¶m->subparams, "nofocus", bool, wcdefs->nofocus, wcdefs->nofocus);
OPTIONAL_PARAM(¶m->subparams, "noresize", bool, wcdefs->noresize, wcdefs->noresize);
OPTIONAL_PARAM(¶m->subparams, "nomove", bool, wcdefs->nomove, wcdefs->nomove);
OPTIONAL_PARAM(¶m->subparams, "noiconify", bool, wcdefs->noiconify, wcdefs->noiconify);
OPTIONAL_PARAM(¶m->subparams, "nodelete", bool, wcdefs->nodelete, wcdefs->nodelete);
OPTIONAL_PARAM(¶m->subparams, "sticky", bool, wcdefs->sticky, wcdefs->sticky);
OPTIONAL_PARAM(¶m->subparams, "dgroup", dgroup, wcdefs->dgroup, wcdefs->dgroup);
OPTIONAL_PARAM(¶m->subparams, "stacklayer", stacklayer, wcdefs->stacklayer, wcdefs->stacklayer);
}
return PLUGIN_OK;
}
/* register our callback */
int start() {
plugin_callback_add(plugin_this, PCALL_INIT_HINTS, init_hints);
return PLUGIN_OK;
}
/* free our wcdefs */
void shutdown() {
wcdefs_t *wcdefs, *next;
wcdefs = SLIST_FIRST(&wcdefs_list);
while (wcdefs) {
/* don't free res_class, it's just a ptr into res_name */
free(wcdefs->res_name);
next = SLIST_NEXT(wcdefs, w_list);
free(wcdefs);
wcdefs = next;
}
}
syntax highlighted by Code2HTML, v. 0.9.1