cwm/xutil.c

310 lines
6.9 KiB
C
Raw Normal View History

2007-04-27 21:58:48 +04:00
/*
* calmwm - the calm window manager
*
* Copyright (c) 2004 Marius Aamodt Eriksen <marius@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.
2007-04-27 21:58:48 +04:00
*
2011-05-11 17:53:51 +04:00
* $OpenBSD$
2007-04-27 21:58:48 +04:00
*/
#include <sys/param.h>
#include <sys/queue.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
2007-04-27 21:58:48 +04:00
#include "calmwm.h"
static unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask };
2007-04-27 21:58:48 +04:00
int
xu_ptr_grab(Window win, int mask, Cursor curs)
{
return (XGrabPointer(X_Dpy, win, False, mask,
GrabModeAsync, GrabModeAsync,
None, curs, CurrentTime) == GrabSuccess ? 0 : -1);
2007-04-27 21:58:48 +04:00
}
int
xu_ptr_regrab(int mask, Cursor curs)
{
return (XChangeActivePointerGrab(X_Dpy, mask,
curs, CurrentTime) == GrabSuccess ? 0 : -1);
2007-04-27 21:58:48 +04:00
}
void
xu_ptr_ungrab(void)
{
XUngrabPointer(X_Dpy, CurrentTime);
2007-04-27 21:58:48 +04:00
}
void
2007-04-27 21:58:48 +04:00
xu_btn_grab(Window win, int mask, u_int btn)
{
int i;
for (i = 0; i < nitems(ign_mods); i++)
XGrabButton(X_Dpy, btn, (mask | ign_mods[i]), win,
False, BUTTONMASK, GrabModeAsync,
GrabModeSync, None, None);
2007-04-27 21:58:48 +04:00
}
void
xu_btn_ungrab(Window win, int mask, u_int btn)
{
int i;
for (i = 0; i < nitems(ign_mods); i++)
XUngrabButton(X_Dpy, btn, (mask | ign_mods[i]), win);
2007-04-27 21:58:48 +04:00
}
void
xu_ptr_getpos(Window rootwin, int *x, int *y)
{
Window w0, w1;
int tmp0, tmp1;
u_int tmp2;
2007-04-27 21:58:48 +04:00
2008-04-16 00:24:41 +04:00
XQueryPointer(X_Dpy, rootwin, &w0, &w1, &tmp0, &tmp1, x, y, &tmp2);
2007-04-27 21:58:48 +04:00
}
void
xu_ptr_setpos(Window win, int x, int y)
{
XWarpPointer(X_Dpy, None, win, 0, 0, 0, 0, x, y);
2007-04-27 21:58:48 +04:00
}
void
xu_key_grab(Window win, int mask, int keysym)
{
KeyCode code;
int i;
2007-04-27 21:58:48 +04:00
code = XKeysymToKeycode(X_Dpy, keysym);
if ((XkbKeycodeToKeysym(X_Dpy, code, 0, 0) != keysym) &&
(XkbKeycodeToKeysym(X_Dpy, code, 0, 1) == keysym))
2007-04-27 21:58:48 +04:00
mask |= ShiftMask;
for (i = 0; i < nitems(ign_mods); i++)
XGrabKey(X_Dpy, code, (mask | ign_mods[i]), win,
True, GrabModeAsync, GrabModeAsync);
}
void
xu_key_ungrab(Window win, int mask, int keysym)
{
KeyCode code;
int i;
code = XKeysymToKeycode(X_Dpy, keysym);
if ((XkbKeycodeToKeysym(X_Dpy, code, 0, 0) != keysym) &&
(XkbKeycodeToKeysym(X_Dpy, code, 0, 1) == keysym))
mask |= ShiftMask;
for (i = 0; i < nitems(ign_mods); i++)
XUngrabKey(X_Dpy, code, (mask | ign_mods[i]), win);
2007-04-27 21:58:48 +04:00
}
void
xu_configure(struct client_ctx *cc)
{
XConfigureEvent ce;
ce.type = ConfigureNotify;
ce.event = cc->win;
ce.window = cc->win;
ce.x = cc->geom.x;
ce.y = cc->geom.y;
ce.width = cc->geom.width;
ce.height = cc->geom.height;
ce.border_width = cc->bwidth;
ce.above = None;
ce.override_redirect = 0;
XSendEvent(X_Dpy, cc->win, False, StructureNotifyMask, (XEvent *)&ce);
}
2007-04-27 21:58:48 +04:00
void
xu_sendmsg(Window win, Atom atm, long val)
2007-04-27 21:58:48 +04:00
{
XEvent e;
2007-04-27 21:58:48 +04:00
(void)memset(&e, 0, sizeof(e));
2007-04-27 21:58:48 +04:00
e.xclient.type = ClientMessage;
e.xclient.window = win;
2007-04-27 21:58:48 +04:00
e.xclient.message_type = atm;
e.xclient.format = 32;
e.xclient.data.l[0] = val;
e.xclient.data.l[1] = CurrentTime;
XSendEvent(X_Dpy, win, False, 0, &e);
2007-04-27 21:58:48 +04:00
}
int
xu_getprop(Window win, Atom atm, Atom type, long len, u_char **p)
2007-04-27 21:58:48 +04:00
{
Atom realtype;
u_long n, extra;
int format;
2007-04-27 21:58:48 +04:00
if (XGetWindowProperty(X_Dpy, win, atm, 0L, len, False, type,
&realtype, &format, &n, &extra, p) != Success || *p == NULL)
2007-04-27 21:58:48 +04:00
return (-1);
if (n == 0)
XFree(*p);
return (n);
}
int
xu_getstrprop(Window win, Atom atm, char **text) {
XTextProperty prop;
char **list;
2010-05-23 02:32:08 +04:00
int nitems = 0;
*text = NULL;
XGetTextProperty(X_Dpy, win, &prop, atm);
if (!prop.nitems)
return (0);
if (Xutf8TextPropertyToTextList(X_Dpy, &prop, &list,
&nitems) == Success && nitems > 0 && *list) {
if (nitems > 1) {
XTextProperty prop2;
if (Xutf8TextListToTextProperty(X_Dpy, list, nitems,
XUTF8StringStyle, &prop2) == Success) {
*text = xstrdup(prop2.value);
XFree(prop2.value);
}
} else {
*text = xstrdup(*list);
}
XFreeStringList(list);
}
XFree(prop.value);
return (nitems);
}
2007-04-27 21:58:48 +04:00
int
xu_getstate(struct client_ctx *cc, int *state)
{
long *p = NULL;
if (xu_getprop(cc->win, WM_STATE, WM_STATE, 2L, (u_char **)&p) <= 0)
2007-04-27 21:58:48 +04:00
return (-1);
*state = (int)*p;
XFree((char *)p);
return (0);
}
void
xu_setstate(struct client_ctx *cc, int state)
{
long dat[2];
2007-04-27 21:58:48 +04:00
dat[0] = state;
dat[1] = None;
2007-04-27 21:58:48 +04:00
cc->state = state;
XChangeProperty(X_Dpy, cc->win, WM_STATE, WM_STATE, 32,
2007-04-27 21:58:48 +04:00
PropModeReplace, (unsigned char *)dat, 2);
}
Atom cwm_atoms[CWM_NO_ATOMS];
char *atoms[CWM_NO_ATOMS] = {
"WM_STATE",
"WM_DELETE_WINDOW",
"WM_TAKE_FOCUS",
"WM_PROTOCOLS",
"_MOTIF_WM_HINTS",
"UTF8_STRING",
"_NET_SUPPORTED",
"_NET_SUPPORTING_WM_CHECK",
"_NET_WM_NAME",
"_NET_ACTIVE_WINDOW",
"_NET_CLIENT_LIST",
"_NET_NUMBER_OF_DESKTOPS",
"_NET_CURRENT_DESKTOP",
"_NET_DESKTOP_VIEWPORT",
"_NET_DESKTOP_GEOMETRY",
"_NET_VIRTUAL_ROOTS",
"_NET_SHOWING_DESKTOP",
"_NET_DESKTOP_NAMES",
"_NET_WM_DESKTOP",
"_NET_WORKAREA",
};
void
xu_getatoms(void)
{
XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms);
}
void
xu_ewmh_net_supported(struct screen_ctx *sc)
{
XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTED, XA_ATOM, 32,
PropModeReplace, (unsigned char *)&_NET_SUPPORTED,
CWM_NO_ATOMS - CWM_NETWM_START);
}
/*
* The netwm spec says that to prove that the hint is not stale, one
* must provide _NET_SUPPORTING_WM_CHECK containing a window created by
* the root window. The property must be set on the root window and the
* window itself. This child window also must have _NET_WM_NAME set with
* the window manager name.
*/
void
xu_ewmh_net_supported_wm_check(struct screen_ctx *sc)
{
Window w;
w = XCreateSimpleWindow(X_Dpy, sc->rootwin, -1, -1, 1, 1, 0, 0, 0);
XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTING_WM_CHECK,
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
XChangeProperty(X_Dpy, w, _NET_SUPPORTING_WM_CHECK,
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
XChangeProperty(X_Dpy, w, _NET_WM_NAME, UTF8_STRING,
8, PropModeReplace, WMNAME, strlen(WMNAME));
}
unsigned long
xu_getcolor(struct screen_ctx *sc, char *name)
{
XColor color, tmp;
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
name, &color, &tmp)) {
warnx("XAllocNamedColor error: '%s'", name);
return (0);
}
return (color.pixel);
}
void
xu_freecolor(struct screen_ctx *sc, unsigned long pixel)
{
XFreeColors(X_Dpy, DefaultColormap(X_Dpy, sc->which), &pixel, 1, 0L);
}