mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
Merge branch 'linux' of git://github.com/chneukirchen/cwm into linux
Conflicts: group.c xutil.c
This commit is contained in:
commit
1fad01ad39
14
LICENSE
14
LICENSE
@ -1,14 +0,0 @@
|
|||||||
Copyright (c) 2004,2005 Marius Aamodt Eriksen <marius@monkey.org>
|
|
||||||
Copyright (c) 2004 Andy Adamson <dros@monkey.org>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
4
calmwm.c
4
calmwm.c
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
@ -27,9 +27,9 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
20
calmwm.h
20
calmwm.h
@ -88,6 +88,10 @@ size_t strlcat(char *, const char *, size_t);
|
|||||||
#define CWM_RCYCLE 0x0002
|
#define CWM_RCYCLE 0x0002
|
||||||
#define CWM_INGROUP 0x0004
|
#define CWM_INGROUP 0x0004
|
||||||
|
|
||||||
|
/* menu */
|
||||||
|
#define CWM_MENU_DUMMY 0x0001
|
||||||
|
#define CWM_MENU_FILE 0x0002
|
||||||
|
|
||||||
#define KBTOGROUP(X) ((X) - 1)
|
#define KBTOGROUP(X) ((X) - 1)
|
||||||
|
|
||||||
union arg {
|
union arg {
|
||||||
@ -283,7 +287,7 @@ TAILQ_HEAD(cmd_q, cmd);
|
|||||||
struct menu {
|
struct menu {
|
||||||
TAILQ_ENTRY(menu) entry;
|
TAILQ_ENTRY(menu) entry;
|
||||||
TAILQ_ENTRY(menu) resultentry;
|
TAILQ_ENTRY(menu) resultentry;
|
||||||
#define MENU_MAXENTRY 50
|
#define MENU_MAXENTRY 200
|
||||||
char text[MENU_MAXENTRY + 1];
|
char text[MENU_MAXENTRY + 1];
|
||||||
char print[MENU_MAXENTRY + 1];
|
char print[MENU_MAXENTRY + 1];
|
||||||
void *ctx;
|
void *ctx;
|
||||||
@ -380,6 +384,10 @@ void search_match_client(struct menu_q *, struct menu_q *,
|
|||||||
char *);
|
char *);
|
||||||
void search_match_exec(struct menu_q *, struct menu_q *,
|
void search_match_exec(struct menu_q *, struct menu_q *,
|
||||||
char *);
|
char *);
|
||||||
|
void search_match_exec_path(struct menu_q *, struct menu_q *,
|
||||||
|
char *);
|
||||||
|
void search_match_path_any(struct menu_q *, struct menu_q *,
|
||||||
|
char *);
|
||||||
void search_match_text(struct menu_q *, struct menu_q *,
|
void search_match_text(struct menu_q *, struct menu_q *,
|
||||||
char *);
|
char *);
|
||||||
void search_print_client(struct menu *, int);
|
void search_print_client(struct menu *, int);
|
||||||
@ -463,9 +471,9 @@ int font_descent(struct screen_ctx *);
|
|||||||
void font_draw(struct screen_ctx *, const char *, int,
|
void font_draw(struct screen_ctx *, const char *, int,
|
||||||
Drawable, int, int);
|
Drawable, int, int);
|
||||||
u_int font_height(struct screen_ctx *);
|
u_int font_height(struct screen_ctx *);
|
||||||
void font_init(struct screen_ctx *, const char *);
|
void font_init(struct screen_ctx *, const char *,
|
||||||
|
const char *);
|
||||||
int font_width(struct screen_ctx *, const char *, int);
|
int font_width(struct screen_ctx *, const char *, int);
|
||||||
XftFont *font_make(struct screen_ctx *, const char *);
|
|
||||||
|
|
||||||
void xev_loop(void);
|
void xev_loop(void);
|
||||||
|
|
||||||
@ -498,7 +506,7 @@ void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *);
|
|||||||
void xu_ewmh_net_showing_desktop(struct screen_ctx *);
|
void xu_ewmh_net_showing_desktop(struct screen_ctx *);
|
||||||
void xu_ewmh_net_virtual_roots(struct screen_ctx *);
|
void xu_ewmh_net_virtual_roots(struct screen_ctx *);
|
||||||
void xu_ewmh_net_current_desktop(struct screen_ctx *, long);
|
void xu_ewmh_net_current_desktop(struct screen_ctx *, long);
|
||||||
void xu_ewmh_net_desktop_names(struct screen_ctx *, unsigned char *, int);
|
void xu_ewmh_net_desktop_names(struct screen_ctx *, char *, int);
|
||||||
|
|
||||||
void xu_ewmh_net_wm_desktop(struct client_ctx *);
|
void xu_ewmh_net_wm_desktop(struct client_ctx *);
|
||||||
|
|
||||||
@ -507,9 +515,11 @@ void u_exec(char *);
|
|||||||
void u_spawn(char *);
|
void u_spawn(char *);
|
||||||
|
|
||||||
void *xcalloc(size_t, size_t);
|
void *xcalloc(size_t, size_t);
|
||||||
void xfree(void *);
|
|
||||||
void *xmalloc(size_t);
|
void *xmalloc(size_t);
|
||||||
char *xstrdup(const char *);
|
char *xstrdup(const char *);
|
||||||
|
int xasprintf(char **, const char *, ...)
|
||||||
|
__attribute__((__format__ (printf, 2, 3)))
|
||||||
|
__attribute__((__nonnull__ (2)));
|
||||||
|
|
||||||
/* Externs */
|
/* Externs */
|
||||||
extern Display *X_Dpy;
|
extern Display *X_Dpy;
|
||||||
|
14
client.c
14
client.c
@ -19,14 +19,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -166,12 +166,12 @@ client_delete(struct client_ctx *cc)
|
|||||||
while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
|
while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
|
||||||
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
||||||
if (wn->name != emptystring)
|
if (wn->name != emptystring)
|
||||||
xfree(wn->name);
|
free(wn->name);
|
||||||
xfree(wn);
|
free(wn);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_freehints(cc);
|
client_freehints(cc);
|
||||||
xfree(cc);
|
free(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -582,8 +582,8 @@ match:
|
|||||||
assert(wn != NULL);
|
assert(wn != NULL);
|
||||||
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
||||||
if (wn->name != emptystring)
|
if (wn->name != emptystring)
|
||||||
xfree(wn->name);
|
free(wn->name);
|
||||||
xfree(wn);
|
free(wn);
|
||||||
cc->nameqlen--;
|
cc->nameqlen--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
90
conf.c
90
conf.c
@ -19,14 +19,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -62,8 +62,7 @@ conf_gap(struct conf *c, struct screen_ctx *sc)
|
|||||||
void
|
void
|
||||||
conf_font(struct conf *c, struct screen_ctx *sc)
|
conf_font(struct conf *c, struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
font_init(sc, c->color[CWM_COLOR_FONT].name);
|
font_init(sc, c->font, c->color[CWM_COLOR_FONT].name);
|
||||||
sc->font = font_make(sc, c->font);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct color color_binds[] = {
|
static struct color color_binds[] = {
|
||||||
@ -210,20 +209,19 @@ conf_clear(struct conf *c)
|
|||||||
|
|
||||||
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
|
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
|
||||||
TAILQ_REMOVE(&c->cmdq, cmd, entry);
|
TAILQ_REMOVE(&c->cmdq, cmd, entry);
|
||||||
xfree(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((kb = TAILQ_FIRST(&c->keybindingq)) != NULL) {
|
while ((kb = TAILQ_FIRST(&c->keybindingq)) != NULL) {
|
||||||
TAILQ_REMOVE(&c->keybindingq, kb, entry);
|
TAILQ_REMOVE(&c->keybindingq, kb, entry);
|
||||||
xfree(kb);
|
free(kb);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ag = TAILQ_FIRST(&c->autogroupq)) != NULL) {
|
while ((ag = TAILQ_FIRST(&c->autogroupq)) != NULL) {
|
||||||
TAILQ_REMOVE(&c->autogroupq, ag, entry);
|
TAILQ_REMOVE(&c->autogroupq, ag, entry);
|
||||||
xfree(ag->class);
|
free(ag->class);
|
||||||
if (ag->name)
|
free(ag->name);
|
||||||
xfree(ag->name);
|
free(ag);
|
||||||
xfree(ag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((as = TAILQ_FIRST(&c->autostartq)) != NULL) {
|
while ((as = TAILQ_FIRST(&c->autostartq)) != NULL) {
|
||||||
@ -234,18 +232,18 @@ conf_clear(struct conf *c)
|
|||||||
|
|
||||||
while ((wm = TAILQ_FIRST(&c->ignoreq)) != NULL) {
|
while ((wm = TAILQ_FIRST(&c->ignoreq)) != NULL) {
|
||||||
TAILQ_REMOVE(&c->ignoreq, wm, entry);
|
TAILQ_REMOVE(&c->ignoreq, wm, entry);
|
||||||
xfree(wm);
|
free(wm);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((mb = TAILQ_FIRST(&c->mousebindingq)) != NULL) {
|
while ((mb = TAILQ_FIRST(&c->mousebindingq)) != NULL) {
|
||||||
TAILQ_REMOVE(&c->mousebindingq, mb, entry);
|
TAILQ_REMOVE(&c->mousebindingq, mb, entry);
|
||||||
xfree(mb);
|
free(mb);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < CWM_COLOR_MAX; i++)
|
for (i = 0; i < CWM_COLOR_MAX; i++)
|
||||||
xfree(c->color[i].name);
|
free(c->color[i].name);
|
||||||
|
|
||||||
xfree(c->font);
|
free(c->font);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -473,24 +471,22 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
|||||||
{
|
{
|
||||||
struct keybinding *current_binding;
|
struct keybinding *current_binding;
|
||||||
char *substring, *tmp;
|
char *substring, *tmp;
|
||||||
int iter;
|
int i;
|
||||||
|
|
||||||
current_binding = xcalloc(1, sizeof(*current_binding));
|
current_binding = xcalloc(1, sizeof(*current_binding));
|
||||||
|
|
||||||
if ((substring = strchr(name, '-')) != NULL) {
|
if ((substring = strchr(name, '-')) != NULL) {
|
||||||
for (iter = 0; iter < nitems(bind_mods); iter++) {
|
for (i = 0; i < nitems(bind_mods); i++) {
|
||||||
if ((tmp = strchr(name, bind_mods[iter].chr)) !=
|
if ((tmp = strchr(name, bind_mods[i].chr)) !=
|
||||||
NULL && tmp < substring) {
|
NULL && tmp < substring) {
|
||||||
current_binding->modmask |=
|
current_binding->modmask |= bind_mods[i].mask;
|
||||||
bind_mods[iter].mask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip past the modifiers */
|
/* skip past the modifiers */
|
||||||
substring++;
|
substring++;
|
||||||
} else {
|
} else
|
||||||
substring = name;
|
substring = name;
|
||||||
}
|
|
||||||
|
|
||||||
if (substring[0] == '[' &&
|
if (substring[0] == '[' &&
|
||||||
substring[strlen(substring)-1] == ']') {
|
substring[strlen(substring)-1] == ']') {
|
||||||
@ -503,23 +499,25 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
|||||||
|
|
||||||
if (current_binding->keysym == NoSymbol &&
|
if (current_binding->keysym == NoSymbol &&
|
||||||
current_binding->keycode == 0) {
|
current_binding->keycode == 0) {
|
||||||
xfree(current_binding);
|
free(current_binding);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We now have the correct binding, remove duplicates. */
|
/* We now have the correct binding, remove duplicates. */
|
||||||
conf_unbind(c, current_binding);
|
conf_unbind(c, current_binding);
|
||||||
|
|
||||||
if (strcmp("unmap", binding) == 0)
|
if (strcmp("unmap", binding) == 0) {
|
||||||
|
free(current_binding);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (iter = 0; iter < nitems(name_to_kbfunc); iter++) {
|
for (i = 0; i < nitems(name_to_kbfunc); i++) {
|
||||||
if (strcmp(name_to_kbfunc[iter].tag, binding) != 0)
|
if (strcmp(name_to_kbfunc[i].tag, binding) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
current_binding->callback = name_to_kbfunc[iter].handler;
|
current_binding->callback = name_to_kbfunc[i].handler;
|
||||||
current_binding->flags = name_to_kbfunc[iter].flags;
|
current_binding->flags = name_to_kbfunc[i].flags;
|
||||||
current_binding->argument = name_to_kbfunc[iter].argument;
|
current_binding->argument = name_to_kbfunc[i].argument;
|
||||||
conf_grab(c, current_binding);
|
conf_grab(c, current_binding);
|
||||||
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
|
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
|
||||||
return;
|
return;
|
||||||
@ -537,10 +535,7 @@ conf_unbind(struct conf *c, struct keybinding *unbind)
|
|||||||
{
|
{
|
||||||
struct keybinding *key = NULL, *keynxt;
|
struct keybinding *key = NULL, *keynxt;
|
||||||
|
|
||||||
for (key = TAILQ_FIRST(&c->keybindingq);
|
TAILQ_FOREACH_SAFE(key, &c->keybindingq, entry, keynxt) {
|
||||||
key != TAILQ_END(&c->keybindingq); key = keynxt) {
|
|
||||||
keynxt = TAILQ_NEXT(key, entry);
|
|
||||||
|
|
||||||
if (key->modmask != unbind->modmask)
|
if (key->modmask != unbind->modmask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -549,7 +544,7 @@ conf_unbind(struct conf *c, struct keybinding *unbind)
|
|||||||
key->keysym == unbind->keysym) {
|
key->keysym == unbind->keysym) {
|
||||||
conf_ungrab(c, key);
|
conf_ungrab(c, key);
|
||||||
TAILQ_REMOVE(&c->keybindingq, key, entry);
|
TAILQ_REMOVE(&c->keybindingq, key, entry);
|
||||||
xfree(key);
|
free(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -577,16 +572,15 @@ conf_mousebind(struct conf *c, char *name, char *binding)
|
|||||||
struct mousebinding *current_binding;
|
struct mousebinding *current_binding;
|
||||||
char *substring, *tmp;
|
char *substring, *tmp;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
int iter;
|
int i;
|
||||||
|
|
||||||
current_binding = xcalloc(1, sizeof(*current_binding));
|
current_binding = xcalloc(1, sizeof(*current_binding));
|
||||||
|
|
||||||
if ((substring = strchr(name, '-')) != NULL) {
|
if ((substring = strchr(name, '-')) != NULL) {
|
||||||
for (iter = 0; iter < nitems(bind_mods); iter++) {
|
for (i = 0; i < nitems(bind_mods); i++) {
|
||||||
if ((tmp = strchr(name, bind_mods[iter].chr)) !=
|
if ((tmp = strchr(name, bind_mods[i].chr)) !=
|
||||||
NULL && tmp < substring) {
|
NULL && tmp < substring) {
|
||||||
current_binding->modmask |=
|
current_binding->modmask |= bind_mods[i].mask;
|
||||||
bind_mods[iter].mask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,17 +593,20 @@ conf_mousebind(struct conf *c, char *name, char *binding)
|
|||||||
if (errstr)
|
if (errstr)
|
||||||
warnx("number of buttons is %s: %s", errstr, substring);
|
warnx("number of buttons is %s: %s", errstr, substring);
|
||||||
|
|
||||||
|
/* We now have the correct binding, remove duplicates. */
|
||||||
conf_mouseunbind(c, current_binding);
|
conf_mouseunbind(c, current_binding);
|
||||||
|
|
||||||
if (strcmp("unmap", binding) == 0)
|
if (strcmp("unmap", binding) == 0) {
|
||||||
|
free(current_binding);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (iter = 0; iter < nitems(name_to_mousefunc); iter++) {
|
for (i = 0; i < nitems(name_to_mousefunc); i++) {
|
||||||
if (strcmp(name_to_mousefunc[iter].tag, binding) != 0)
|
if (strcmp(name_to_mousefunc[i].tag, binding) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
current_binding->context = name_to_mousefunc[iter].context;
|
current_binding->context = name_to_mousefunc[i].context;
|
||||||
current_binding->callback = name_to_mousefunc[iter].handler;
|
current_binding->callback = name_to_mousefunc[i].handler;
|
||||||
TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry);
|
TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -620,16 +617,13 @@ conf_mouseunbind(struct conf *c, struct mousebinding *unbind)
|
|||||||
{
|
{
|
||||||
struct mousebinding *mb = NULL, *mbnxt;
|
struct mousebinding *mb = NULL, *mbnxt;
|
||||||
|
|
||||||
for (mb = TAILQ_FIRST(&c->mousebindingq);
|
TAILQ_FOREACH_SAFE(mb, &c->mousebindingq, entry, mbnxt) {
|
||||||
mb != TAILQ_END(&c->mousebindingq); mb = mbnxt) {
|
|
||||||
mbnxt = TAILQ_NEXT(mb, entry);
|
|
||||||
|
|
||||||
if (mb->modmask != unbind->modmask)
|
if (mb->modmask != unbind->modmask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mb->button == unbind->button) {
|
if (mb->button == unbind->button) {
|
||||||
TAILQ_REMOVE(&c->mousebindingq, mb, entry);
|
TAILQ_REMOVE(&c->mousebindingq, mb, entry);
|
||||||
xfree(mb);
|
free(mb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
cwmrc.5
4
cwmrc.5
@ -14,7 +14,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: October 31 2012 $
|
.Dd $Mdocdate: November 7 2012 $
|
||||||
.Dt CWMRC 5
|
.Dt CWMRC 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -59,7 +59,7 @@ used to override
|
|||||||
.Dq sticky group mode .
|
.Dq sticky group mode .
|
||||||
.Pp
|
.Pp
|
||||||
The name and class values, respectively, for existing windows
|
The name and class values, respectively, for existing windows
|
||||||
may be obtained using
|
are both set in the WM_CLASS property and may be obtained using
|
||||||
.Xr xprop 1 .
|
.Xr xprop 1 .
|
||||||
.Pp
|
.Pp
|
||||||
.It Ic bind Ar keys command
|
.It Ic bind Ar keys command
|
||||||
|
28
font.c
28
font.c
@ -19,13 +19,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -49,7 +49,7 @@ font_height(struct screen_ctx *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
font_init(struct screen_ctx *sc, const char *color)
|
font_init(struct screen_ctx *sc, const char *name, const char *color)
|
||||||
{
|
{
|
||||||
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
|
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
|
||||||
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which));
|
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which));
|
||||||
@ -59,6 +59,10 @@ font_init(struct screen_ctx *sc, const char *color)
|
|||||||
if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which),
|
if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which),
|
||||||
DefaultColormap(X_Dpy, sc->which), color, &sc->xftcolor))
|
DefaultColormap(X_Dpy, sc->which), color, &sc->xftcolor))
|
||||||
errx(1, "XftColorAllocName");
|
errx(1, "XftColorAllocName");
|
||||||
|
|
||||||
|
sc->font = XftFontOpenName(X_Dpy, sc->which, name);
|
||||||
|
if (sc->font == NULL)
|
||||||
|
errx(1, "XftFontOpenName");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -80,21 +84,3 @@ font_draw(struct screen_ctx *sc, const char *text, int len,
|
|||||||
XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor, sc->font, x, y,
|
XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor, sc->font, x, y,
|
||||||
(const FcChar8*)text, len);
|
(const FcChar8*)text, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
XftFont *
|
|
||||||
font_make(struct screen_ctx *sc, const char *name)
|
|
||||||
{
|
|
||||||
XftFont *fn = NULL;
|
|
||||||
FcPattern *pat, *patx;
|
|
||||||
XftResult res;
|
|
||||||
|
|
||||||
if ((pat = FcNameParse((const FcChar8*)name)) == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if ((patx = XftFontMatch(X_Dpy, sc->which, pat, &res)) != NULL)
|
|
||||||
fn = XftFontOpenPattern(X_Dpy, patx);
|
|
||||||
|
|
||||||
FcPatternDestroy(pat);
|
|
||||||
|
|
||||||
return (fn);
|
|
||||||
}
|
|
||||||
|
13
group.c
13
group.c
@ -20,11 +20,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -130,7 +131,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
XRestackWindows(X_Dpy, winlist, gc->nhidden);
|
XRestackWindows(X_Dpy, winlist, gc->nhidden);
|
||||||
xfree(winlist);
|
free(winlist);
|
||||||
|
|
||||||
gc->hidden = 0;
|
gc->hidden = 0;
|
||||||
group_setactive(sc, gc->shortcut - 1);
|
group_setactive(sc, gc->shortcut - 1);
|
||||||
@ -420,7 +421,7 @@ group_menu(XButtonEvent *e)
|
|||||||
cleanup:
|
cleanup:
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,7 +546,7 @@ group_update_names(struct screen_ctx *sc)
|
|||||||
if (prop_ret != NULL)
|
if (prop_ret != NULL)
|
||||||
XFree(prop_ret);
|
XFree(prop_ret);
|
||||||
if (sc->group_nonames != 0)
|
if (sc->group_nonames != 0)
|
||||||
xfree(sc->group_names);
|
free(sc->group_names);
|
||||||
|
|
||||||
sc->group_names = strings;
|
sc->group_names = strings;
|
||||||
sc->group_nonames = n;
|
sc->group_nonames = n;
|
||||||
@ -556,7 +557,7 @@ group_update_names(struct screen_ctx *sc)
|
|||||||
static void
|
static void
|
||||||
group_set_names(struct screen_ctx *sc)
|
group_set_names(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
unsigned char *p, *q;
|
char *p, *q;
|
||||||
size_t len = 0, tlen, slen;
|
size_t len = 0, tlen, slen;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -567,7 +568,7 @@ group_set_names(struct screen_ctx *sc)
|
|||||||
tlen = len;
|
tlen = len;
|
||||||
for (i = 0; i < sc->group_nonames; i++) {
|
for (i = 0; i < sc->group_nonames; i++) {
|
||||||
slen = strlen(sc->group_names[i]) + 1;
|
slen = strlen(sc->group_names[i]) + 1;
|
||||||
(void)strlcpy((char *) q, sc->group_names[i], tlen);
|
(void)strlcpy(q, sc->group_names[i], tlen);
|
||||||
tlen -= slen;
|
tlen -= slen;
|
||||||
q += slen;
|
q += slen;
|
||||||
}
|
}
|
||||||
|
34
kbfunc.c
34
kbfunc.c
@ -19,16 +19,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -246,7 +246,7 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
|
|||||||
|
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
|
|||||||
|
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,10 +373,11 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
|
|||||||
}
|
}
|
||||||
(void)closedir(dirp);
|
(void)closedir(dirp);
|
||||||
}
|
}
|
||||||
xfree(path);
|
free(path);
|
||||||
|
|
||||||
if ((mi = menu_filter(sc, &menuq, label, NULL, 1,
|
if ((mi = menu_filter(sc, &menuq, label, NULL,
|
||||||
search_match_exec, NULL)) != NULL) {
|
CWM_MENU_DUMMY | CWM_MENU_FILE,
|
||||||
|
search_match_exec_path, NULL)) != NULL) {
|
||||||
if (mi->text[0] == '\0')
|
if (mi->text[0] == '\0')
|
||||||
goto out;
|
goto out;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@ -394,10 +395,10 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (mi != NULL && mi->dummy)
|
if (mi != NULL && mi->dummy)
|
||||||
xfree(mi);
|
free(mi);
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,10 +451,10 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
|||||||
(void)strlcpy(mi->text, hostbuf, sizeof(mi->text));
|
(void)strlcpy(mi->text, hostbuf, sizeof(mi->text));
|
||||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||||
}
|
}
|
||||||
xfree(lbuf);
|
free(lbuf);
|
||||||
(void)fclose(fp);
|
(void)fclose(fp);
|
||||||
|
|
||||||
if ((mi = menu_filter(sc, &menuq, "ssh", NULL, 1,
|
if ((mi = menu_filter(sc, &menuq, "ssh", NULL, CWM_MENU_DUMMY,
|
||||||
search_match_exec, NULL)) != NULL) {
|
search_match_exec, NULL)) != NULL) {
|
||||||
if (mi->text[0] == '\0')
|
if (mi->text[0] == '\0')
|
||||||
goto out;
|
goto out;
|
||||||
@ -464,10 +465,10 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (mi != NULL && mi->dummy)
|
if (mi != NULL && mi->dummy)
|
||||||
xfree(mi);
|
free(mi);
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,15 +481,14 @@ kbfunc_client_label(struct client_ctx *cc, union arg *arg)
|
|||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
|
|
||||||
/* dummy is set, so this will always return */
|
/* dummy is set, so this will always return */
|
||||||
mi = menu_filter(cc->sc, &menuq, "label", cc->label, 1,
|
mi = menu_filter(cc->sc, &menuq, "label", cc->label, CWM_MENU_DUMMY,
|
||||||
search_match_text, NULL);
|
search_match_text, NULL);
|
||||||
|
|
||||||
if (!mi->abort) {
|
if (!mi->abort) {
|
||||||
if (cc->label != NULL)
|
free(cc->label);
|
||||||
xfree(cc->label);
|
|
||||||
cc->label = xstrdup(mi->text);
|
cc->label = xstrdup(mi->text);
|
||||||
}
|
}
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
80
menu.c
80
menu.c
@ -20,13 +20,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -37,10 +38,11 @@
|
|||||||
enum ctltype {
|
enum ctltype {
|
||||||
CTL_NONE = -1,
|
CTL_NONE = -1,
|
||||||
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
|
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
|
||||||
CTL_ABORT, CTL_ALL
|
CTL_TAB, CTL_ABORT, CTL_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct menu_ctx {
|
struct menu_ctx {
|
||||||
|
struct screen_ctx *sc;
|
||||||
char searchstr[MENU_MAXENTRY + 1];
|
char searchstr[MENU_MAXENTRY + 1];
|
||||||
char dispstr[MENU_MAXENTRY*2 + 1];
|
char dispstr[MENU_MAXENTRY*2 + 1];
|
||||||
char promptstr[MENU_MAXENTRY + 1];
|
char promptstr[MENU_MAXENTRY + 1];
|
||||||
@ -54,6 +56,7 @@ struct menu_ctx {
|
|||||||
int height;
|
int height;
|
||||||
int width;
|
int width;
|
||||||
int num;
|
int num;
|
||||||
|
int flags;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
void (*match)(struct menu_q *, struct menu_q *, char *);
|
void (*match)(struct menu_q *, struct menu_q *, char *);
|
||||||
@ -93,7 +96,7 @@ menu_init(struct screen_ctx *sc)
|
|||||||
|
|
||||||
struct menu *
|
struct menu *
|
||||||
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
||||||
char *initial, int dummy,
|
char *initial, int flags,
|
||||||
void (*match)(struct menu_q *, struct menu_q *, char *),
|
void (*match)(struct menu_q *, struct menu_q *, char *),
|
||||||
void (*print)(struct menu *, int))
|
void (*print)(struct menu *, int))
|
||||||
{
|
{
|
||||||
@ -114,6 +117,8 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
|||||||
xsave = mc.x;
|
xsave = mc.x;
|
||||||
ysave = mc.y;
|
ysave = mc.y;
|
||||||
|
|
||||||
|
mc.sc = sc;
|
||||||
|
mc.flags = flags;
|
||||||
if (prompt == NULL) {
|
if (prompt == NULL) {
|
||||||
evmask = MENUMASK;
|
evmask = MENUMASK;
|
||||||
mc.promptstr[0] = '\0';
|
mc.promptstr[0] = '\0';
|
||||||
@ -181,8 +186,9 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (dummy == 0 && mi->dummy) { /* no mouse based match */
|
if ((mc.flags & CWM_MENU_DUMMY) == 0 && mi->dummy) {
|
||||||
xfree(mi);
|
/* no mouse based match */
|
||||||
|
free(mi);
|
||||||
mi = NULL;
|
mi = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +205,38 @@ out:
|
|||||||
return (mi);
|
return (mi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct menu *
|
||||||
|
menu_complete_path(struct menu_ctx *mc)
|
||||||
|
{
|
||||||
|
struct menu *mi, *mr;
|
||||||
|
struct menu_q menuq;
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
path = xcalloc(1, sizeof(mr->text));
|
||||||
|
mr = xcalloc(1, sizeof(*mr));
|
||||||
|
|
||||||
|
TAILQ_INIT(&menuq);
|
||||||
|
if ((mi = menu_filter(mc->sc, &menuq, mc->searchstr, NULL,
|
||||||
|
CWM_MENU_DUMMY, search_match_path_any, NULL)) != NULL) {
|
||||||
|
mr->abort = mi->abort;
|
||||||
|
mr->dummy = mi->dummy;
|
||||||
|
strlcpy(path, mi->text, sizeof(mi->text));
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
|
free(mi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path[0] != '\0')
|
||||||
|
snprintf(mr->text, sizeof(mr->text), "%s \"%s\"",
|
||||||
|
mc->searchstr, path);
|
||||||
|
else if (!mr->abort)
|
||||||
|
strlcpy(mr->text, mc->searchstr, sizeof(mr->text));
|
||||||
|
free(path);
|
||||||
|
return (mr);
|
||||||
|
}
|
||||||
|
|
||||||
static struct menu *
|
static struct menu *
|
||||||
menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
||||||
struct menu_q *resultq)
|
struct menu_q *resultq)
|
||||||
@ -257,6 +295,33 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
|||||||
mc->searchstr[0] = '\0';
|
mc->searchstr[0] = '\0';
|
||||||
mc->changed = 1;
|
mc->changed = 1;
|
||||||
break;
|
break;
|
||||||
|
case CTL_TAB:
|
||||||
|
if ((mi = TAILQ_FIRST(resultq)) != NULL) {
|
||||||
|
/*
|
||||||
|
* - We are in exec_path menu mode
|
||||||
|
* - It is equal to the input
|
||||||
|
* We got a command, launch the file menu
|
||||||
|
*/
|
||||||
|
if ((mc->flags & CWM_MENU_FILE) &&
|
||||||
|
(strncmp(mc->searchstr, mi->text,
|
||||||
|
strlen(mi->text))) == 0)
|
||||||
|
return (menu_complete_path(mc));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put common prefix of the results into searchstr
|
||||||
|
*/
|
||||||
|
(void)strlcpy(mc->searchstr,
|
||||||
|
mi->text, sizeof(mc->searchstr));
|
||||||
|
while ((mi = TAILQ_NEXT(mi, resultentry)) != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (tolower(mc->searchstr[i]) ==
|
||||||
|
tolower(mi->text[i]))
|
||||||
|
i++;
|
||||||
|
mc->searchstr[i] = '\0';
|
||||||
|
}
|
||||||
|
mc->changed = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CTL_ALL:
|
case CTL_ALL:
|
||||||
mc->list = !mc->list;
|
mc->list = !mc->list;
|
||||||
break;
|
break;
|
||||||
@ -484,6 +549,9 @@ menu_keycode(XKeyEvent *ev, enum ctltype *ctl, char *chr)
|
|||||||
case XK_Return:
|
case XK_Return:
|
||||||
*ctl = CTL_RETURN;
|
*ctl = CTL_RETURN;
|
||||||
break;
|
break;
|
||||||
|
case XK_Tab:
|
||||||
|
*ctl = CTL_TAB;
|
||||||
|
break;
|
||||||
case XK_Up:
|
case XK_Up:
|
||||||
*ctl = CTL_UP;
|
*ctl = CTL_UP;
|
||||||
break;
|
break;
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -253,7 +253,7 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
|
|||||||
} else {
|
} else {
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,6 +282,6 @@ mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
|
|||||||
else
|
else
|
||||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||||
TAILQ_REMOVE(&menuq, mi, entry);
|
TAILQ_REMOVE(&menuq, mi, entry);
|
||||||
xfree(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
568
queue.h
Normal file
568
queue.h
Normal file
@ -0,0 +1,568 @@
|
|||||||
|
/* $OpenBSD: "queue.h",v 1.36 2012/04/11 13:29:14 naddy Exp $ */
|
||||||
|
/* $NetBSD: "queue.h",v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* The Regents of the University of California. 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 University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||||
|
*
|
||||||
|
* @(#)"queue.h" 8.5 (Berkeley) 8/20/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS_QUEUE_H_
|
||||||
|
#define _SYS_QUEUE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file defines five types of data structures: singly-linked lists,
|
||||||
|
* lists, simple queues, tail queues, and circular queues.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* A singly-linked list is headed by a single forward pointer. The elements
|
||||||
|
* are singly linked for minimum space and pointer manipulation overhead at
|
||||||
|
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||||
|
* added to the list after an existing element or at the head of the list.
|
||||||
|
* Elements being removed from the head of the list should use the explicit
|
||||||
|
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||||
|
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||||
|
* for applications with large datasets and few or no removals or for
|
||||||
|
* implementing a LIFO queue.
|
||||||
|
*
|
||||||
|
* A list is headed by a single forward pointer (or an array of forward
|
||||||
|
* pointers for a hash table header). The elements are doubly linked
|
||||||
|
* so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before
|
||||||
|
* or after an existing element or at the head of the list. A list
|
||||||
|
* may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A simple queue is headed by a pair of pointers, one the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are singly
|
||||||
|
* linked to save space, so elements can only be removed from the
|
||||||
|
* head of the list. New elements can be added to the list before or after
|
||||||
|
* an existing element, at the head of the list, or at the end of the
|
||||||
|
* list. A simple queue may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
|
* linked so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before or
|
||||||
|
* after an existing element, at the head of the list, or at the end of
|
||||||
|
* the list. A tail queue may be traversed in either direction.
|
||||||
|
*
|
||||||
|
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
|
* linked so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before or after
|
||||||
|
* an existing element, at the head of the list, or at the end of the list.
|
||||||
|
* A circle queue may be traversed in either direction, but has a more
|
||||||
|
* complex end of list detection.
|
||||||
|
*
|
||||||
|
* For details on the use of these macros, see the queue(3) manual page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
|
||||||
|
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
|
||||||
|
#else
|
||||||
|
#define _Q_INVALIDATE(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List definitions.
|
||||||
|
*/
|
||||||
|
#define SLIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *slh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SLIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define SLIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *sle_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List access methods.
|
||||||
|
*/
|
||||||
|
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||||
|
#define SLIST_END(head) NULL
|
||||||
|
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
|
||||||
|
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||||
|
|
||||||
|
#define SLIST_FOREACH(var, head, field) \
|
||||||
|
for((var) = SLIST_FIRST(head); \
|
||||||
|
(var) != SLIST_END(head); \
|
||||||
|
(var) = SLIST_NEXT(var, field))
|
||||||
|
|
||||||
|
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = SLIST_FIRST(head); \
|
||||||
|
(var) && ((tvar) = SLIST_NEXT(var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List functions.
|
||||||
|
*/
|
||||||
|
#define SLIST_INIT(head) { \
|
||||||
|
SLIST_FIRST(head) = SLIST_END(head); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||||
|
(elm)->field.sle_next = (slistelm)->field.sle_next; \
|
||||||
|
(slistelm)->field.sle_next = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
(elm)->field.sle_next = (head)->slh_first; \
|
||||||
|
(head)->slh_first = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE_AFTER(elm, field) do { \
|
||||||
|
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||||
|
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||||
|
if ((head)->slh_first == (elm)) { \
|
||||||
|
SLIST_REMOVE_HEAD((head), field); \
|
||||||
|
} else { \
|
||||||
|
struct type *curelm = (head)->slh_first; \
|
||||||
|
\
|
||||||
|
while (curelm->field.sle_next != (elm)) \
|
||||||
|
curelm = curelm->field.sle_next; \
|
||||||
|
curelm->field.sle_next = \
|
||||||
|
curelm->field.sle_next->field.sle_next; \
|
||||||
|
_Q_INVALIDATE((elm)->field.sle_next); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List definitions.
|
||||||
|
*/
|
||||||
|
#define LIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *lh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define LIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *le_next; /* next element */ \
|
||||||
|
struct type **le_prev; /* address of previous next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List access methods
|
||||||
|
*/
|
||||||
|
#define LIST_FIRST(head) ((head)->lh_first)
|
||||||
|
#define LIST_END(head) NULL
|
||||||
|
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
|
||||||
|
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||||
|
|
||||||
|
#define LIST_FOREACH(var, head, field) \
|
||||||
|
for((var) = LIST_FIRST(head); \
|
||||||
|
(var)!= LIST_END(head); \
|
||||||
|
(var) = LIST_NEXT(var, field))
|
||||||
|
|
||||||
|
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = LIST_FIRST(head); \
|
||||||
|
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List functions.
|
||||||
|
*/
|
||||||
|
#define LIST_INIT(head) do { \
|
||||||
|
LIST_FIRST(head) = LIST_END(head); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||||
|
(listelm)->field.le_next->field.le_prev = \
|
||||||
|
&(elm)->field.le_next; \
|
||||||
|
(listelm)->field.le_next = (elm); \
|
||||||
|
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||||
|
(elm)->field.le_next = (listelm); \
|
||||||
|
*(listelm)->field.le_prev = (elm); \
|
||||||
|
(listelm)->field.le_prev = &(elm)->field.le_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
|
||||||
|
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
|
||||||
|
(head)->lh_first = (elm); \
|
||||||
|
(elm)->field.le_prev = &(head)->lh_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_REMOVE(elm, field) do { \
|
||||||
|
if ((elm)->field.le_next != NULL) \
|
||||||
|
(elm)->field.le_next->field.le_prev = \
|
||||||
|
(elm)->field.le_prev; \
|
||||||
|
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_REPLACE(elm, elm2, field) do { \
|
||||||
|
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
|
||||||
|
(elm2)->field.le_next->field.le_prev = \
|
||||||
|
&(elm2)->field.le_next; \
|
||||||
|
(elm2)->field.le_prev = (elm)->field.le_prev; \
|
||||||
|
*(elm2)->field.le_prev = (elm2); \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.le_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple queue definitions.
|
||||||
|
*/
|
||||||
|
#define SIMPLEQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *sqh_first; /* first element */ \
|
||||||
|
struct type **sqh_last; /* addr of last next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SIMPLEQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).sqh_first }
|
||||||
|
|
||||||
|
#define SIMPLEQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *sqe_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple queue access methods.
|
||||||
|
*/
|
||||||
|
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||||
|
#define SIMPLEQ_END(head) NULL
|
||||||
|
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
|
||||||
|
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||||
|
|
||||||
|
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||||
|
for((var) = SIMPLEQ_FIRST(head); \
|
||||||
|
(var) != SIMPLEQ_END(head); \
|
||||||
|
(var) = SIMPLEQ_NEXT(var, field))
|
||||||
|
|
||||||
|
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = SIMPLEQ_FIRST(head); \
|
||||||
|
(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple queue functions.
|
||||||
|
*/
|
||||||
|
#define SIMPLEQ_INIT(head) do { \
|
||||||
|
(head)->sqh_first = NULL; \
|
||||||
|
(head)->sqh_last = &(head)->sqh_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
(head)->sqh_first = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
(elm)->field.sqe_next = NULL; \
|
||||||
|
*(head)->sqh_last = (elm); \
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
(listelm)->field.sqe_next = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
|
||||||
|
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
|
||||||
|
(head)->sqh_last = &(head)->sqh_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
|
||||||
|
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
|
||||||
|
== NULL) \
|
||||||
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue definitions.
|
||||||
|
*/
|
||||||
|
#define TAILQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *tqh_first; /* first element */ \
|
||||||
|
struct type **tqh_last; /* addr of last next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).tqh_first }
|
||||||
|
|
||||||
|
#define TAILQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *tqe_next; /* next element */ \
|
||||||
|
struct type **tqe_prev; /* address of previous next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tail queue access methods
|
||||||
|
*/
|
||||||
|
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||||
|
#define TAILQ_END(head) NULL
|
||||||
|
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||||
|
#define TAILQ_LAST(head, headname) \
|
||||||
|
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||||
|
/* XXX */
|
||||||
|
#define TAILQ_PREV(elm, headname, field) \
|
||||||
|
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||||
|
#define TAILQ_EMPTY(head) \
|
||||||
|
(TAILQ_FIRST(head) == TAILQ_END(head))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH(var, head, field) \
|
||||||
|
for((var) = TAILQ_FIRST(head); \
|
||||||
|
(var) != TAILQ_END(head); \
|
||||||
|
(var) = TAILQ_NEXT(var, field))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = TAILQ_FIRST(head); \
|
||||||
|
(var) != TAILQ_END(head) && \
|
||||||
|
((tvar) = TAILQ_NEXT(var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||||
|
for((var) = TAILQ_LAST(head, headname); \
|
||||||
|
(var) != TAILQ_END(head); \
|
||||||
|
(var) = TAILQ_PREV(var, headname, field))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
|
||||||
|
for ((var) = TAILQ_LAST(head, headname); \
|
||||||
|
(var) != TAILQ_END(head) && \
|
||||||
|
((tvar) = TAILQ_PREV(var, headname, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue functions.
|
||||||
|
*/
|
||||||
|
#define TAILQ_INIT(head) do { \
|
||||||
|
(head)->tqh_first = NULL; \
|
||||||
|
(head)->tqh_last = &(head)->tqh_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||||
|
(head)->tqh_first->field.tqe_prev = \
|
||||||
|
&(elm)->field.tqe_next; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||||
|
(head)->tqh_first = (elm); \
|
||||||
|
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
(elm)->field.tqe_next = NULL; \
|
||||||
|
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||||
|
*(head)->tqh_last = (elm); \
|
||||||
|
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||||
|
(elm)->field.tqe_next->field.tqe_prev = \
|
||||||
|
&(elm)->field.tqe_next; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||||
|
(listelm)->field.tqe_next = (elm); \
|
||||||
|
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||||
|
(elm)->field.tqe_next = (listelm); \
|
||||||
|
*(listelm)->field.tqe_prev = (elm); \
|
||||||
|
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||||
|
if (((elm)->field.tqe_next) != NULL) \
|
||||||
|
(elm)->field.tqe_next->field.tqe_prev = \
|
||||||
|
(elm)->field.tqe_prev; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||||
|
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||||
|
_Q_INVALIDATE((elm)->field.tqe_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.tqe_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
|
||||||
|
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
|
||||||
|
(elm2)->field.tqe_next->field.tqe_prev = \
|
||||||
|
&(elm2)->field.tqe_next; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &(elm2)->field.tqe_next; \
|
||||||
|
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
|
||||||
|
*(elm2)->field.tqe_prev = (elm2); \
|
||||||
|
_Q_INVALIDATE((elm)->field.tqe_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.tqe_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circular queue definitions.
|
||||||
|
*/
|
||||||
|
#define CIRCLEQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *cqh_first; /* first element */ \
|
||||||
|
struct type *cqh_last; /* last element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
|
||||||
|
|
||||||
|
#define CIRCLEQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *cqe_next; /* next element */ \
|
||||||
|
struct type *cqe_prev; /* previous element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circular queue access methods
|
||||||
|
*/
|
||||||
|
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||||
|
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||||
|
#define CIRCLEQ_END(head) ((void *)(head))
|
||||||
|
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
|
||||||
|
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
|
||||||
|
#define CIRCLEQ_EMPTY(head) \
|
||||||
|
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
|
||||||
|
|
||||||
|
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||||
|
for((var) = CIRCLEQ_FIRST(head); \
|
||||||
|
(var) != CIRCLEQ_END(head); \
|
||||||
|
(var) = CIRCLEQ_NEXT(var, field))
|
||||||
|
|
||||||
|
#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = CIRCLEQ_FIRST(head); \
|
||||||
|
(var) != CIRCLEQ_END(head) && \
|
||||||
|
((tvar) = CIRCLEQ_NEXT(var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||||
|
for((var) = CIRCLEQ_LAST(head); \
|
||||||
|
(var) != CIRCLEQ_END(head); \
|
||||||
|
(var) = CIRCLEQ_PREV(var, field))
|
||||||
|
|
||||||
|
#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
|
||||||
|
for ((var) = CIRCLEQ_LAST(head, headname); \
|
||||||
|
(var) != CIRCLEQ_END(head) && \
|
||||||
|
((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circular queue functions.
|
||||||
|
*/
|
||||||
|
#define CIRCLEQ_INIT(head) do { \
|
||||||
|
(head)->cqh_first = CIRCLEQ_END(head); \
|
||||||
|
(head)->cqh_last = CIRCLEQ_END(head); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
|
||||||
|
(elm)->field.cqe_prev = (listelm); \
|
||||||
|
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
|
||||||
|
(head)->cqh_last = (elm); \
|
||||||
|
else \
|
||||||
|
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
|
||||||
|
(listelm)->field.cqe_next = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||||
|
(elm)->field.cqe_next = (listelm); \
|
||||||
|
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
|
||||||
|
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
|
||||||
|
(head)->cqh_first = (elm); \
|
||||||
|
else \
|
||||||
|
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
|
||||||
|
(listelm)->field.cqe_prev = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
(elm)->field.cqe_next = (head)->cqh_first; \
|
||||||
|
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
|
||||||
|
if ((head)->cqh_last == CIRCLEQ_END(head)) \
|
||||||
|
(head)->cqh_last = (elm); \
|
||||||
|
else \
|
||||||
|
(head)->cqh_first->field.cqe_prev = (elm); \
|
||||||
|
(head)->cqh_first = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
(elm)->field.cqe_next = CIRCLEQ_END(head); \
|
||||||
|
(elm)->field.cqe_prev = (head)->cqh_last; \
|
||||||
|
if ((head)->cqh_first == CIRCLEQ_END(head)) \
|
||||||
|
(head)->cqh_first = (elm); \
|
||||||
|
else \
|
||||||
|
(head)->cqh_last->field.cqe_next = (elm); \
|
||||||
|
(head)->cqh_last = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||||
|
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
|
||||||
|
(head)->cqh_last = (elm)->field.cqe_prev; \
|
||||||
|
else \
|
||||||
|
(elm)->field.cqe_next->field.cqe_prev = \
|
||||||
|
(elm)->field.cqe_prev; \
|
||||||
|
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
|
||||||
|
(head)->cqh_first = (elm)->field.cqe_next; \
|
||||||
|
else \
|
||||||
|
(elm)->field.cqe_prev->field.cqe_next = \
|
||||||
|
(elm)->field.cqe_next; \
|
||||||
|
_Q_INVALIDATE((elm)->field.cqe_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.cqe_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
|
||||||
|
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
|
||||||
|
CIRCLEQ_END(head)) \
|
||||||
|
(head).cqh_last = (elm2); \
|
||||||
|
else \
|
||||||
|
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
|
||||||
|
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
|
||||||
|
CIRCLEQ_END(head)) \
|
||||||
|
(head).cqh_first = (elm2); \
|
||||||
|
else \
|
||||||
|
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
|
||||||
|
_Q_INVALIDATE((elm)->field.cqe_prev); \
|
||||||
|
_Q_INVALIDATE((elm)->field.cqe_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* !_SYS_QUEUE_H_ */
|
4
screen.c
4
screen.c
@ -19,13 +19,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
52
search.c
52
search.c
@ -19,19 +19,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <glob.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
|
||||||
|
#define PATH_EXEC 0x1
|
||||||
|
|
||||||
static int strsubmatch(char *, char *, int);
|
static int strsubmatch(char *, char *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -161,6 +164,43 @@ search_print_client(struct menu *mi, int list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search, int flag)
|
||||||
|
{
|
||||||
|
struct menu *mi;
|
||||||
|
char pattern[MAXPATHLEN];
|
||||||
|
glob_t g;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
TAILQ_INIT(resultq);
|
||||||
|
|
||||||
|
(void)strlcpy(pattern, search, sizeof(pattern));
|
||||||
|
(void)strlcat(pattern, "*", sizeof(pattern));
|
||||||
|
|
||||||
|
if (glob(pattern, GLOB_MARK, NULL, &g) != 0)
|
||||||
|
return;
|
||||||
|
for (i = 0; i < g.gl_pathc; i++) {
|
||||||
|
if ((flag & PATH_EXEC) && access(g.gl_pathv[i], X_OK))
|
||||||
|
continue;
|
||||||
|
mi = xcalloc(1, sizeof(*mi));
|
||||||
|
(void)strlcpy(mi->text, g.gl_pathv[i], sizeof(mi->text));
|
||||||
|
TAILQ_INSERT_TAIL(resultq, mi, resultentry);
|
||||||
|
}
|
||||||
|
globfree(&g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
search_match_path_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||||
|
{
|
||||||
|
return (search_match_path(menuq, resultq, search, PATH_EXEC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
search_match_path_any(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||||
|
{
|
||||||
|
return (search_match_path(menuq, resultq, search, 0));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||||
{
|
{
|
||||||
@ -196,6 +236,14 @@ search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
search_match_exec_path(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||||
|
{
|
||||||
|
search_match_exec(menuq, resultq, search);
|
||||||
|
if (TAILQ_EMPTY(resultq))
|
||||||
|
search_match_path_exec(menuq, resultq, search);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
strsubmatch(char *sub, char *str, int zeroidx)
|
strsubmatch(char *sub, char *str, int zeroidx)
|
||||||
{
|
{
|
||||||
|
4
util.c
4
util.c
@ -19,13 +19,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
@ -25,14 +25,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
33
xmalloc.c
33
xmalloc.c
@ -19,13 +19,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
@ -35,6 +36,8 @@ xmalloc(size_t siz)
|
|||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
if (siz == 0)
|
||||||
|
errx(1, "xmalloc: zero size");
|
||||||
if ((p = malloc(siz)) == NULL)
|
if ((p = malloc(siz)) == NULL)
|
||||||
err(1, "malloc");
|
err(1, "malloc");
|
||||||
|
|
||||||
@ -46,18 +49,16 @@ xcalloc(size_t no, size_t siz)
|
|||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
if (siz == 0 || no == 0)
|
||||||
|
errx(1, "xcalloc: zero size");
|
||||||
|
if (SIZE_MAX / no < siz)
|
||||||
|
errx(1, "xcalloc: no * siz > SIZE_MAX");
|
||||||
if ((p = calloc(no, siz)) == NULL)
|
if ((p = calloc(no, siz)) == NULL)
|
||||||
err(1, "calloc");
|
err(1, "calloc");
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
xfree(void *p)
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
xstrdup(const char *str)
|
xstrdup(const char *str)
|
||||||
{
|
{
|
||||||
@ -68,3 +69,19 @@ xstrdup(const char *str)
|
|||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xasprintf(char **ret, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
i = vasprintf(ret, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (i < 0 || *ret == NULL)
|
||||||
|
err(1, "asprintf");
|
||||||
|
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
14
xutil.c
14
xutil.c
@ -19,10 +19,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include "queue.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -188,7 +189,7 @@ xu_getstrprop(Window win, Atom atm, char **text) {
|
|||||||
XTextProperty prop2;
|
XTextProperty prop2;
|
||||||
if (Xutf8TextListToTextProperty(X_Dpy, list, nitems,
|
if (Xutf8TextListToTextProperty(X_Dpy, list, nitems,
|
||||||
XUTF8StringStyle, &prop2) == Success) {
|
XUTF8StringStyle, &prop2) == Success) {
|
||||||
*text = xstrdup((char *) prop2.value);
|
*text = xstrdup((const char *)prop2.value);
|
||||||
XFree(prop2.value);
|
XFree(prop2.value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -292,7 +293,8 @@ xu_ewmh_net_supported_wm_check(struct screen_ctx *sc)
|
|||||||
XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK].atom,
|
XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK].atom,
|
||||||
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
|
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
|
||||||
XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME].atom,
|
XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME].atom,
|
||||||
XA_WM_NAME, 8, PropModeReplace, WMNAME, strlen(WMNAME));
|
XA_WM_NAME, 8, PropModeReplace, (unsigned char *)WMNAME,
|
||||||
|
strlen(WMNAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -339,7 +341,7 @@ xu_ewmh_net_client_list(struct screen_ctx *sc)
|
|||||||
winlist[j++] = cc->win;
|
winlist[j++] = cc->win;
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST].atom,
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST].atom,
|
||||||
XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i);
|
XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i);
|
||||||
xfree(winlist);
|
free(winlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -396,10 +398,10 @@ xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xu_ewmh_net_desktop_names(struct screen_ctx *sc, unsigned char *data, int n)
|
xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n)
|
||||||
{
|
{
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom,
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom,
|
||||||
cwmh[UTF8_STRING].atom, 8, PropModeReplace, data, n);
|
cwmh[UTF8_STRING].atom, 8, PropModeReplace, (unsigned char *)data, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Application Window Properties */
|
/* Application Window Properties */
|
||||||
|
Loading…
Reference in New Issue
Block a user