rm the util directory

This commit is contained in:
Dana Jansens 2003-01-14 00:13:20 +00:00
parent b683a4e0ef
commit 0afb431644
35 changed files with 0 additions and 7530 deletions

View file

@ -48,8 +48,6 @@ AC_CONFIG_FILES([Makefile po/Makefile.in
otk/Makefile
src/Makefile
scripts/Makefile
util/Makefile
util/epist/Makefile
doc/Makefile
doc/doxygen/Makefile
data/Makefile

View file

@ -1,6 +0,0 @@
Makefile
Makefile.in
bsetroot
xftlsfonts
.deps
.libs

View file

@ -1,21 +0,0 @@
CPPFLAGS= @CPPFLAGS@
#SUBDIRS = epist
bin_SCRIPTS = bsetbg
bin_PROGRAMS = bsetroot xftlsfonts
bsetroot_SOURCES = bsetroot.cc
bsetroot_LDADD = ../src/basedisplay.o ../otk/color.o ../otk/gccache.o \
../otk/texture.o ../src/timer.o ../otk/image.o \
../otk/imagecontrol.o ../src/util.o ../src/screeninfo.o
xftlsfonts_SOURCES = xftlsfonts.cc
INCLUDES= -I../src -I../otk
MAINTAINERCLEANFILES = Makefile.in
distclean-local:
rm -f *\~ .\#*
# local dependencies

View file

@ -1,506 +0,0 @@
#!/bin/sh
# Copyright (c) 2000-2002 Timothy M. King (tmk@lordzork.com)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
PATH=$PATH:/usr/bin:/usr/local/bin:/usr/X11R6/bin
img_apps="display xli xsetbg Esetroot qiv wmsetbg xv"
display_full_cmd="display -geometry 800x600 -window root"
display_tile_cmd="display -window root"
display_center_cmd="display -backdrop -window root"
display_default_cmd="$display_center_cmd"
Esetroot_full_cmd="Esetroot -scale"
Esetroot_tile_cmd="Esetroot"
Esetroot_center_cmd="Esetroot -c"
Esetroot_default_cmd="$Esetroot_center_cmd"
wmsetbg_full_cmd="wmsetbg -s -S"
wmsetbg_tile_cmd="wmsetbg -t"
wmsetbg_center_cmd="wmsetbg -e"
wmsetbg_default_cmd="$wmsetbg_center_cmd"
qiv_full_cmd="qiv --root_s"
qiv_tile_cmd="qiv --root_t"
qiv_center_cmd="qiv --root"
qiv_default_cmd="$qiv_center_cmd"
xv_full_cmd="xv -max -smooth -root -quit"
xv_tile_cmd="xv -root -quit"
xv_center_cmd="xv -rmode 5 -root -quit"
xv_default_cmd="$xv_center_cmd"
xli_full_cmd="xli -fullscreen -onroot -quiet"
xli_tile_cmd="xli -onroot -quiet"
xli_center_cmd="xli -center -onroot quiet"
xli_default_cmd="$xli_center_cmd"
xsetbg_full_cmd="xsetbg -fullscreen"
xsetbg_tile_cmd="xsetbg"
xsetbg_center_cmd="xsetbg -center"
xsetbg_default_cmd="$xsetbg_center_cmd"
##################################
me=${0##*/}
version=2.2
copyright="(c) 2000-$(date +%Y) by Timothy M. King (http://lordzork.com/)"
config=$HOME/.bsetbgrc
last_cmd_file=$HOME/.bsetbg_last_cmd
refresh_cmd=xrefresh
p=$me:
#debug=echo
quit()
{
[ "$1" ] && rc=$1 && shift 1
[ "$*" ] && echo -e $*
exit ${rc:-0}
}
bool() {
case $1 in
[yY][eE][sS]|1|[yY]|[tT][rR][uU][eE]|[oO][nN]) : ;;
*) return 1 ;;
esac
}
check_exe_in_path()
{
if [ -z "$1" ]; then
return 1
elif [ -x "$(which $1 2>/dev/null)" ]; then
return 0
elif [ -x "$(type $1 2>/dev/null)" ]; then
return 0
else
return 1
fi
}
help_msg()
{
cat <<EOF
$me $version $copyright
-center <file> center an image on the desktop
-tile <file> tile an image on the desktop
-full <file> stretch an image to fill the desktop
-exec <args> <file> specify an external command to execute
-app <app> specify the image application to use
-post <string> arguments to be passed to the post-command
-debug prints commands without executing them
-display <string> use display connection
-mod <x> <y> modula pattern
-foreground, -fg <color> modula foreground color
-background, -bg <color> modula background color
-gradient <texture> gradient texture
-from <color> gradient start color
-to <color> gradient end color
-solid <color> solid color
-generate <string> generate a config file
-help this message
-version output version information
EOF
quit ${1:-0}
}
get_apps()
{
for a in $img_apps; do
if check_exe_in_path $a; then
eval center_cmd=\$$a\_center_cmd
eval full_cmd=\$$a\_full_cmd
eval tile_cmd=\$$a\_tile_cmd
eval default_cmd=\$$a\_default_cmd
return 0
else
if [ "$not_found" ]; then
not_found="$not_found $a"
else
not_found=$a
fi
fi
done
return 1
}
do_generate()
{
echo -e "# created by $me $version on $(date)\n#"
echo -e "# seting NO_EXEC to a boolean value (eg true/false) will cause $me"
echo -e "# to never modify the root window\n#"
echo -e "#NO_EXEC=\n#"
echo -e "# POST_COMMAND can be set to a command that will be run run every time"
echo -e "# $me sets the root image\n#"
echo -e "#POST_COMMAND=\n#"
echo -e "# if LOG_LAST_CMD is set (boolean), bsetbg will keep a log of the last"
echo -e "# two successful commands.\n#"
echo -e "#LOG_LAST_CMD=\n#"
echo -e "# the LOGFILE specifies the file that bsetbg uses when LOG_LAST_CMD"
echo -e "# is defined. this defaults to ~/.bsetbg_last_cmd .\n#"
echo -e "#LOGFILE=\n#"
echo -e "# the following are default configuration values for the most popular image"
echo -e "# programs. See the man page of the respective application for more info.\n"
[ "$*" ] && img_apps="$*"
for a in $img_apps; do
if check_exe_in_path $a; then
if ! bool $have_match; then
q='\"'
[ "$(eval echo \$$a\_center_cmd)" ] &&
eval echo CENTER=$q\$$a\_center_cmd$q &&
[ "$(eval echo \$$a\_full_cmd)" ] &&
eval echo FULL=$q\$$a\_full_cmd$q &&
[ "$(eval echo \$$a\_tile_cmd)" ] &&
eval echo TILE=$q\$$a\_tile_cmd$q &&
[ "$(eval echo \$$a\_default_cmd)" ] &&
eval echo -e DEFAULT=$q\$$a\_default_cmd$q \\\\n &&
have_match=1
else
[ "$(eval echo \$$a\_center_cmd)" ] &&
eval echo \\#CENTER=$q\$$a\_center_cmd$q
[ "$(eval echo \$$a\_full_cmd)" ] &&
eval echo \\#FULL=$q\$$a\_full_cmd$q
[ "$(eval echo \$$a\_tile_cmd)" ] &&
eval echo \\#TILE=$q\$$a\_tile_cmd$q
[ "$(eval echo \$$a\_default_cmd)" ] &&
eval echo -e \\#DEFAULT=$q\$$a\_default_cmd$q \\\\n
fi
fi
done
quit 0
}
do_bsetroot()
{
if check_exe_in_path bsetroot; then
read_config
$debug bsetroot $* 2>/dev/null; rc=$?
if [ "$rc" -gt 0 ]; then
help_msg $rc
else
log_cmd bsetroot $*; $refresh_cmd 2>/dev/null
fi
else
quit 1 "couldn't find bsetroot in $PATH"
fi
}
do_standard()
{
[ -z "$1" ] && help_msg 1
bool $noconfig || read_config
get_img_command $1
check_img_command $do_this
case $# in
1) file="$1" ;;
*) file="$2"
esac
if [ -f "$file" ]; then
exec_img_command $do_this $file
else
quit 1 "$file does not exist"
fi
}
do_exec()
{
[ "$#" -lt 3 ] && help_msg 3
bool $noconfig || read_config
# check to see if -*c, -*f, or -*t were spcified, if so
# assume the last argument is a filename
b_arg=$(eval echo \$$(( $# - 1 )) )
app=$1
case $b_arg in
-c|*-center|c|-t|*-tile*|t|-f|*-full|f)
eval file=\$$#
f_args="$b_arg $file"
esac
# put the rest of the arguments into the varialbe $e_args
while [ "$*" ]; do
for a in "$*"; do
case $1 in
$b_arg|$file) : ;;
*) e_args="$e_args "$1""
esac
shift 1
done
done
# with $f_args defined, check for image and do things normally
if [ "$f_args" ]; then
[ ! -f "$file" ] && quit 1 "$file does not exist"
if check_img_command $e_args; then
do_this="$e_args"
else
read_config
get_img_command $f_args
check_img_command $do_this
echo "$p couldn't find '$app' in path, using $type command instead"
fi
# without $f_args, run the command blindly if it's in $PATH
elif check_exe_in_path $e_args; then
do_this="$e_args"
else
quit 1 "$p unable to run the following command: $e_args"
fi
exec_img_command $do_this $file
}
get_img_command()
{
case $1 in
*-full|-f|f) type=full; do_this="$full_cmd" ;;
*-tile|-t|t) type=tile; do_this="$tile_cmd" ;;
*-center|-c|c) type=center; do_this="$center_cmd" ;;
*) type=default; do_this="$default_cmd"
esac
}
check_img_command()
{
if check_exe_in_path $1; then
do_this="$*"
rc=0
elif get_apps; then
get_img_command $*
rc=1
else
quit 1 "$p couldn't find a suitable image program. tried the following:\\n
$(for a in $not_found; do echo " $a\\n"; done)"
fi
if [ "$rc" -gt 0 -a -z "$e_args" ] && bool $read_config; then
echo "$p couldn't find a suitable $type command in $config"
fi
return $rc
}
exec_img_command()
{
unset rc
command=$*
if [ "$debug" ]; then
$debug $command
else
$command >/dev/null 2>&1; rc=$?
fi
if [ "$rc" -gt 0 ]; then
echo "$p '$command' exited with status $rc"
get_apps
noconfig=1
parse_args ${f_args:-$my_args}
echo "$p using '$command' as $type"
$debug $command >/dev/null 2>&1; rc=$?
[ "$rc" = 0 ] && log_cmd $do_this $file && $refresh_cmd 2>/dev/null
else
log_cmd $do_this $file; xrefresh 2>/dev/null
fi
return $rc
}
log_cmd()
{
bool $LOG_LAST_CMD || return 1
[ "$debug" ] && return 1
echo -e "$prev_cmd\n$*" >$last_cmd_file
return $?
}
read_config()
{
[ -f $config ] || return 1
if bool $read_config; then
unset read_config
else
read_config=1
fi
. $HOME/.bsetbgrc 2>/dev/null
check_no_exec
full_cmd=$FULL
center_cmd=$CENTER
tile_cmd=$TILE
default_cmd=$CENTER
last_cmd_file=${LOGFILE:-$last_cmd_file}
bool $LOG_LAST_CMD && prev_cmd=$(tail -n 1 $last_cmd_file 2>/dev/null)
}
check_no_exec()
{
bool $NO_EXEC &&
quit 0 "$p no_exec mode. the root window will not be modified."
}
post_command()
{
bool $noconfig || read_config
if [ -n "$POST_COMMAND" -a "$1" = 0 ]; then
if [ -n "$debug" ]; then
$debug "running post_command: $POST_COMMAND $post_args"
else
post_command_output=$($POST_COMMAND $post_args 2>&1); erc=$?
if [ "$erc" -gt 0 ]; then
echo "$p post-command '$POST_COMMAND $post_args' exited with status $erc"
[ -n "$post_command_output" ] &&
echo "$POST_COMMAND $post_args: $post_command_output"
fi
fi
fi
}
add_arg()
{
[ "$1" ] || return 1
if [ "$args" ]; then
args="$args $1"
else
args=$1
fi
}
add_post_arg()
{
[ -z "$1" ] && return 1
if [ "$post_args" ]; then
post_args="$post_args $1"
else
post_args=$1
fi
}
check_cmd()
{
if [ -z "$command" ]; then
command=${2:-$1}; eval ${3:-${2:-$1}}=1
elif bool $do_post; then
add_post_arg ${1}
elif [ "$command" = do_exec ]; then
do_exec=1
elif [ "$command" != do_bsetroot ]; then
finished=1
fi
}
parse_args()
{
case $1 in
-d|*-debug|d)
unset refresh_cmd; debug=echo\ $me\_debug: ;;
-p|*-post|p)
unset finished do_standard do_exec; do_post=1 ;;
-c|*-center|c|-t|*-tile*|t|-f|*-full|f)
case $command in
do_standard|do_generate|do_bsetroot)
finished=1 ;;
do_exec)
if ! bool $got_fcmd; then
add_arg $1 args; got_fcmd=1
else
finished=1
fi ;;
*)
add_arg $1; do_standard=1; command=do_standard
esac ;;
-a|*-app|a|-e|*-exec|e)
command=do_exec; check_cmd ;;
-mod|-gradient|-solid|-display)
check_cmd "do_bsetroot" && add_arg $1 ;;
-g|*-generate*|g)
check_cmd $1 "do_generate" ;;
-v|*-version|v)
[ -z "$command" ] && quit 0 $me $version $copyright ;;
-h|*-help|h)
[ -z "$command" ] && help_msg ;;
*)
bool $finished && return 1
case $1 in -*)
bool $do_exec || bool $do_bsetroot || bool $do_post || help_msg 1
esac
if bool $do_standard || bool $do_exec || bool $do_bsetroot || bool $do_generate; then
add_arg $1
elif bool $do_post; then
add_post_arg $1
else
add_arg $1; command=do_standard; finished=1
fi
esac
}
[ -z "$*" ] && help_msg 1
my_args=$*
for arg in "$@"; do
parse_args "$arg"
shift 1
done
[ "$debug" ] && echo
$debug $command $args
post_command ${rc:-0}
quit $rc

View file

@ -1,383 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// bsetroot.cc for Blackbox - an X11 Window manager
// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
// Copyright (c) 1997 - 2000, 2002 Brad Hughes <bhughes at trolltech.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
#ifdef HAVE_CTYPE_H
# include <ctype.h>
#endif // HAVE_CTYPE_H
}
#include "gccache.hh"
#include "texture.hh"
#include "util.hh"
#include "bsetroot.hh"
bsetroot::bsetroot(int argc, char **argv, char *dpy_name)
: BaseDisplay(argv[0], dpy_name) {
bool mod = False, sol = False, grd = False;
int mod_x = 0, mod_y = 0;
for (int i = 1; i < argc; i++) {
if (! strcmp("-help", argv[i])) {
usage();
} else if ((! strcmp("-fg", argv[i])) ||
(! strcmp("-foreground", argv[i])) ||
(! strcmp("-from", argv[i]))) {
if ((++i) >= argc) usage(1);
fore = argv[i];
} else if ((! strcmp("-bg", argv[i])) ||
(! strcmp("-background", argv[i])) ||
(! strcmp("-to", argv[i]))) {
if ((++i) >= argc) usage(1);
back = argv[i];
} else if (! strcmp("-solid", argv[i])) {
if ((++i) >= argc) usage(1);
fore = argv[i];
sol = True;
} else if (! strcmp("-mod", argv[i])) {
if ((++i) >= argc) usage();
mod_x = atoi(argv[i]);
if ((++i) >= argc) usage();
mod_y = atoi(argv[i]);
if (mod_x < 1) mod_x = 1;
if (mod_y < 1) mod_y = 1;
mod = True;
} else if (! strcmp("-gradient", argv[i])) {
if ((++i) >= argc) usage();
grad = argv[i];
grd = True;
} else if (! strcmp("-display", argv[i])) {
// -display passed through tests ealier... we just skip it now
i++;
} else {
usage();
}
}
if ((mod + sol + grd) != True) {
fprintf(stderr,
"%s: error: must specify one of: -solid, -mod, -gradient\n",
getApplicationName());
usage(2);
}
img_ctrl = new BImageControl*[getNumberOfScreens()];
for (unsigned int s = 0; s < getNumberOfScreens(); ++s)
img_ctrl[s] = new BImageControl(this, getScreenInfo(s), True);
if (sol && ! fore.empty())
solid();
else if (mod && mod_x && mod_y && ! (fore.empty() || back.empty()))
modula(mod_x, mod_y);
else if (grd && ! (grad.empty() || fore.empty() || back.empty()))
gradient();
else usage();
}
bsetroot::~bsetroot(void) {
XSetCloseDownMode(getXDisplay(), RetainPermanent);
XKillClient(getXDisplay(), AllTemporary);
std::for_each(img_ctrl, img_ctrl + getNumberOfScreens(), PointerAssassin());
delete [] img_ctrl;
}
// adapted from wmsetbg
void bsetroot::setPixmapProperty(int screen, Pixmap pixmap) {
static Atom rootpmap_id = None, esetroot_id = None;
Atom type;
int format;
unsigned long length, after;
unsigned char *data;
const ScreenInfo *screen_info = getScreenInfo(screen);
if (rootpmap_id == None) {
rootpmap_id = XInternAtom(getXDisplay(), "_XROOTPMAP_ID", False);
esetroot_id = XInternAtom(getXDisplay(), "ESETROOT_PMAP_ID", False);
}
XGrabServer(getXDisplay());
/* Clear out the old pixmap */
XGetWindowProperty(getXDisplay(), screen_info->getRootWindow(),
rootpmap_id, 0L, 1L, False, AnyPropertyType,
&type, &format, &length, &after, &data);
if ((type == XA_PIXMAP) && (format == 32) && (length == 1)) {
unsigned char* data_esetroot = 0;
XGetWindowProperty(getXDisplay(), screen_info->getRootWindow(),
esetroot_id, 0L, 1L, False, AnyPropertyType,
&type, &format, &length, &after, &data_esetroot);
if (data && data_esetroot && *((Pixmap *) data)) {
XKillClient(getXDisplay(), *((Pixmap *) data));
XSync(getXDisplay(), False);
XFree(data_esetroot);
}
XFree(data);
}
if (pixmap) {
XChangeProperty(getXDisplay(), screen_info->getRootWindow(),
rootpmap_id, XA_PIXMAP, 32, PropModeReplace,
(unsigned char *) &pixmap, 1);
XChangeProperty(getXDisplay(), screen_info->getRootWindow(),
esetroot_id, XA_PIXMAP, 32, PropModeReplace,
(unsigned char *) &pixmap, 1);
} else {
XDeleteProperty(getXDisplay(), screen_info->getRootWindow(),
rootpmap_id);
XDeleteProperty(getXDisplay(), screen_info->getRootWindow(),
esetroot_id);
}
XUngrabServer(getXDisplay());
XFlush(getXDisplay());
}
// adapted from wmsetbg
Pixmap bsetroot::duplicatePixmap(int screen, Pixmap pixmap,
int width, int height) {
XSync(getXDisplay(), False);
Pixmap copyP = XCreatePixmap(getXDisplay(),
getScreenInfo(screen)->getRootWindow(),
width, height,
DefaultDepth(getXDisplay(), screen));
XCopyArea(getXDisplay(), pixmap, copyP, DefaultGC(getXDisplay(), screen),
0, 0, width, height, 0, 0);
XSync(getXDisplay(), False);
return copyP;
}
void bsetroot::solid(void) {
for (unsigned int screen = 0; screen < getNumberOfScreens(); screen++) {
BColor c(fore, this, screen);
const ScreenInfo *screen_info = getScreenInfo(screen);
XSetWindowBackground(getXDisplay(), screen_info->getRootWindow(),
c.pixel());
XClearWindow(getXDisplay(), screen_info->getRootWindow());
Pixmap pixmap = XCreatePixmap(getXDisplay(),
screen_info->getRootWindow(),
8, 8, DefaultDepth(getXDisplay(), screen));
BPen pen(c);
XFillRectangle(getXDisplay(), pixmap, pen.gc(), 0, 0, 8, 8);
setPixmapProperty(screen, duplicatePixmap(screen, pixmap, 8, 8));
XFreePixmap(getXDisplay(), pixmap);
}
}
void bsetroot::modula(int x, int y) {
char data[32];
long pattern;
unsigned int screen, i;
for (pattern = 0, screen = 0; screen < getNumberOfScreens(); screen++) {
for (i = 0; i < 16; i++) {
pattern <<= 1;
if ((i % x) == 0)
pattern |= 0x0001;
}
for (i = 0; i < 16; i++) {
if ((i % y) == 0) {
data[(i * 2)] = static_cast<char>(0xff);
data[(i * 2) + 1] = static_cast<char>(0xff);
} else {
data[(i * 2)] = pattern & 0xff;
data[(i * 2) + 1] = (pattern >> 8) & 0xff;
}
}
BColor f(fore, this, screen), b(back, this, screen);
GC gc;
Pixmap bitmap;
const ScreenInfo *screen_info = getScreenInfo(screen);
bitmap =
XCreateBitmapFromData(getXDisplay(),
screen_info->getRootWindow(), data,
16, 16);
XGCValues gcv;
gcv.foreground = f.pixel();
gcv.background = b.pixel();
gc = XCreateGC(getXDisplay(), screen_info->getRootWindow(),
GCForeground | GCBackground, &gcv);
Pixmap pixmap = XCreatePixmap(getXDisplay(),
screen_info->getRootWindow(),
16, 16, screen_info->getDepth());
XCopyPlane(getXDisplay(), bitmap, pixmap, gc,
0, 0, 16, 16, 0, 0, 1l);
XSetWindowBackgroundPixmap(getXDisplay(),
screen_info->getRootWindow(),
pixmap);
XClearWindow(getXDisplay(), screen_info->getRootWindow());
setPixmapProperty(screen,
duplicatePixmap(screen, pixmap, 16, 16));
XFreeGC(getXDisplay(), gc);
XFreePixmap(getXDisplay(), bitmap);
if (! (screen_info->getVisual()->c_class & 1))
XFreePixmap(getXDisplay(), pixmap);
}
}
void bsetroot::gradient(void) {
/*
we have to be sure that neither raised nor sunken is specified otherwise
odd looking borders appear. So we convert to lowercase then look for
'raised' or 'sunken' in the description and erase them. To be paranoid
the search is done in a loop.
*/
std::string descr;
descr.reserve(grad.size());
std::string::const_iterator it = grad.begin(), end = grad.end();
for (; it != end; ++it)
descr += tolower(*it);
std::string::size_type pos;
while ((pos = descr.find("raised")) != std::string::npos)
descr.erase(pos, 6); // 6 is strlen raised
while ((pos = descr.find("sunken")) != std::string::npos)
descr.erase(pos, 6);
// now add on 'flat' to prevent the bevels from being added
descr += "flat";
for (unsigned int screen = 0; screen < getNumberOfScreens(); screen++) {
BTexture texture(descr, this, screen, img_ctrl[screen]);
const ScreenInfo *screen_info = getScreenInfo(screen);
texture.setColor(BColor(fore, this, screen));
texture.setColorTo(BColor(back, this, screen));
Pixmap pixmap =
img_ctrl[screen]->renderImage(screen_info->getWidth(),
screen_info->getHeight(),
texture);
XSetWindowBackgroundPixmap(getXDisplay(),
screen_info->getRootWindow(),
pixmap);
XClearWindow(getXDisplay(), screen_info->getRootWindow());
setPixmapProperty(screen,
duplicatePixmap(screen, pixmap,
screen_info->getWidth(),
screen_info->getHeight()));
if (! (screen_info->getVisual()->c_class & 1)) {
img_ctrl[screen]->removeImage(pixmap);
}
}
}
void bsetroot::usage(int exit_code) {
fprintf(stderr,
"%s 2.0\n\n"
"Copyright (c) 1997-2000, 2002 Bradley T Hughes\n"
"Copyright (c) 2001-2002 Sean 'Shaleh' Perry\n\n"
" -display <string> use display connection\n"
" -mod <x> <y> modula pattern\n"
" -foreground, -fg <color> modula foreground color\n"
" -background, -bg <color> modula background color\n\n"
" -gradient <texture> gradient texture\n"
" -from <color> gradient start color\n"
" -to <color> gradient end color\n\n"
" -solid <color> solid color\n\n"
" -help print this help text and exit\n",
getApplicationName());
exit(exit_code);
}
int main(int argc, char **argv) {
char *display_name = (char *) 0;
for (int i = 1; i < argc; i++) {
if (! strcmp(argv[i], "-display")) {
// check for -display option
if ((++i) >= argc) {
fprintf(stderr, "error: '-display' requires an argument\n");
::exit(1);
}
display_name = argv[i];
}
}
bsetroot app(argc, argv, display_name);
return 0;
}

View file

@ -1,60 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// Window.cc for Blackbox - an X11 Window manager
// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
// Copyright (c) 1997 - 2000, 2002 Brad Hughes <bhughes at trolltech.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __bsetroot2_hh
#define __bsetroot2_hh
#include "basedisplay.hh"
#include "image.hh"
#include <string>
class bsetroot : public BaseDisplay {
private:
BImageControl **img_ctrl;
std::string fore, back, grad;
// no copying!!
bsetroot(const bsetroot &);
bsetroot& operator=(const bsetroot&);
inline virtual void process_event(XEvent * /*unused*/) { }
public:
bsetroot(int argc, char **argv, char *dpy_name = 0);
~bsetroot(void);
inline virtual bool handleSignal(int /*unused*/) { return False; }
void setPixmapProperty(int screen, Pixmap pixmap);
Pixmap duplicatePixmap(int screen, Pixmap pixmap, int width, int height);
void gradient(void);
void modula(int x, int y);
void solid(void);
void usage(int exit_code = 0);
};
#endif // __bsetroot2_hh

View file

@ -1,6 +0,0 @@
epist
Makefile.in
Makefile
.deps
epist.1
epistrc.5

View file

@ -1,45 +0,0 @@
* Fixed (hopefully) the ugly bugly that would cause (Marius)
epist to hog the keyboard on invalid keys.
* Added stackedCyclingRaise option, to allow windows (Marius)
to raise on focus when stacked is on.
* Small fixes, better sanity checks, much better (Marius)
error reporting on bad keys and modifiers.
2.1.0
* Improved parser: much better error reporting for
malformed files, most tokens are now case
insensitive. (Marius)
* Added configuration code and options {} block in
the config file (Marius)
* Added chain timeout; (time after which a started
chain is automatically cancelled) enabled with the
chainTimeout option. (Marius)
* 2d matrix workspace navigation code. Enabled with
the workspaceRows option, uses the
{prev,next}Workspace{Row,Column} actions. (Scott, Marius)
* Added stacked window cycling. Enable with the
stackedCycling option. (Marius, Ben)
* New actions: showRootMenu, showWorkspaceMenu,
toggleDecorations (Ben)
* Fixed some internal inconsistencies in action names (Marius)
* Added cancelChain action - users can cancel chains
explicitly (Marius)
* Added toggleGrabs action - can be bound to a key (Marius)
to temporarily disable epist bindings.
* Added/improved command line parameter handling (Ben)
* Added code to handle windows which don't specify
the input focus. (Ben)

View file

@ -1,57 +0,0 @@
Epist design notes, by woodblock
--------------------------------
- Chained keybindings like emacs, and I suppose vi if you're wierd like that.
- most actions can take extra parameters. probably only numbers,
or strings, maybe both.
- no interactive string inputs
- A config file that doesn't suck
- exec
- iconify
- raise
- lower
- close
- move to desktop
- send to desktop
- toggle shade
- sticky
- move window
- resize window
- next/prev window (special orders like stacking, grouping, etc?)
- maximize/minimize
- no stupid window
- toggle keybindings
- menus?
class Action {
enum type;
char *string;
int param;
Action next;
}
option <name> <value>;
action [name] <key> <type> <parameter>;
chain [name] <key> {
<action name>,
<action name>,
...
}
eg:
action emacs C-e exec emacs;
action C-a exec aterm -fn smoothansi;
action xmms C-x exec xmms;
chain M-q {
emacs,
xmms
}
Would produce M-q C-e -> emacs, M-q C-x -> xmms, C-a -> aterm.

View file

@ -1,59 +0,0 @@
DEFAULT_RC=$(pkgdatadir)/epistrc
CLEANFILES = epist.1 epistrc.5
CPPFLAGS= @CPPFLAGS@ -DDEFAULTRC=\"$(DEFAULT_RC)\"
#EXTRA_PROGRAMS = epist
bin_PROGRAMS = epist
man_MANS = epist.1 epistrc.5
epist_SOURCES = epist.cc window.cc screen.cc main.cc actions.cc \
yacc_parser.cc parser.cc keytree.cc lex.yy.c config.cc
epist_LDADD = ../../src/xatom.o ../../src/basedisplay.o \
../../src/util.o ../../src/timer.o
MAINTAINERCLEANFILES = Makefile.in
distclean-local:
rm -f *\~ .\#*
epist.1: epist.1.in
@regex_cmd@ -e "s,@pkgdatadir@,$(pkgdatadir)," \
epist.1.in > epist.1
epistrc.5: epistrc.5.in
@regex_cmd@ -e "s,@pkgdatadir@,$(pkgdatadir)," \
epistrc.5.in > epistrc.5
install-data-local: epistrc
test -f $(DESTDIR)$(pkgdatadir)/epistrc || \
$(INSTALL_DATA) epistrc $(DESTDIR)$(pkgdatadir)
uninstall-am:
rm -f $(DESTDIR)$(pkgdatadir)/epistrc
# local dependencies
actions.o: actions.cc actions.hh
config.o: config.cc config.hh
epist.o: epist.cc actions.hh epist.hh window.hh ../../src/util.hh \
keytree.hh ../../src/timer.hh screen.hh config.hh \
../../src/basedisplay.hh parser.hh ../../src/xatom.hh
keytree.o: keytree.cc keytree.hh ../../src/timer.hh actions.hh \
screen.hh window.hh ../../src/util.hh config.hh epist.hh \
../../src/basedisplay.hh
main.o: main.cc ../../version.h epist.hh actions.hh window.hh \
../../src/util.hh keytree.hh ../../src/timer.hh screen.hh config.hh \
../../src/basedisplay.hh
parser.o: parser.cc parser.hh actions.hh keytree.hh ../../src/timer.hh \
screen.hh window.hh ../../src/util.hh config.hh
screen.o: screen.cc ../../src/basedisplay.hh ../../src/timer.hh \
../../src/util.hh ../../src/xatom.hh screen.hh window.hh config.hh \
epist.hh actions.hh keytree.hh
window.o: window.cc epist.hh actions.hh window.hh ../../src/util.hh \
keytree.hh ../../src/timer.hh screen.hh config.hh \
../../src/basedisplay.hh ../../src/xatom.hh
yacc_parser.o: yacc_parser.cc parser.hh actions.hh keytree.hh \
../../src/timer.hh screen.hh window.hh ../../src/util.hh config.hh

View file

@ -1,4 +0,0 @@
- Make sure the parser doesn't puke on invalid actions (doesn't grab
keys or stop parsing)
- Implement the workspace grid using the new netwm spec

View file

@ -1,52 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; -*-
// actions.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "actions.hh"
Action::Action(enum ActionType type, KeyCode keycode, unsigned int modifierMask,
const std::string &str)
: _type(type), _keycode(keycode), _modifierMask(modifierMask)
{
// These are the action types that take string arguments. This
// should probably be moved to a static member
ActionType str_types[] = {
execute,
nextWindowOfClass,
prevWindowOfClass,
nextWindowOfClassOnAllWorkspaces,
prevWindowOfClassOnAllWorkspaces,
noaction
};
for (int i = 0; str_types[i] != noaction; ++i) {
if (type == str_types[i]) {
_stringParam = str;
return;
}
}
_numberParam = atoi( str.c_str() );
// workspace 1 to the user is workspace 0 to us
if (type == changeWorkspace || type == sendToWorkspace)
_numberParam--;
}

View file

@ -1,122 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// actions.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __actions_hh
#define __actions_hh
extern "C" {
#include <X11/Xlib.h>
}
#include <list>
#include <string>
class Action {
public:
enum ActionType {
noaction = 0,
execute, //done
iconify, //done
raise, //done
lower, //done
close, //done
toggleShade, //done
toggleOmnipresent, //done
moveWindowUp, //done
moveWindowDown, //done
moveWindowLeft, //done
moveWindowRight, //done
resizeWindowWidth, //done
resizeWindowHeight, //done
toggleMaximizeFull, //done
toggleMaximizeVertical, //done
toggleMaximizeHorizontal, //done
sendToWorkspace, //done
nextWindow, //done for now
prevWindow, //done for now
nextWindowOnAllWorkspaces, //done for now
prevWindowOnAllWorkspaces, //done for now
nextWindowOnAllScreens, //done for now
prevWindowOnAllScreens, //done for now
nextWindowOfClass, //done for now
prevWindowOfClass, //done for now
nextWindowOfClassOnAllWorkspaces, //done for now
prevWindowOfClassOnAllWorkspaces, //done for now
upWindow,
downWindow,
leftWindow,
rightWindow,
changeWorkspace, //done
nextWorkspace, //done
prevWorkspace, //done
upWorkspace, //all done
downWorkspace,
leftWorkspace,
rightWorkspace,
nextScreen, //done for now
prevScreen, //done for now
// these are openbox extensions
showRootMenu,
showWorkspaceMenu,
toggleDecorations,
toggleGrabs,
stringChain,
keyChain,
numberChain,
cancelChain, //done
NUM_ACTIONS
};
private:
enum ActionType _type;
const KeyCode _keycode;
const unsigned int _modifierMask;
int _numberParam;
std::string _stringParam;
public:
inline enum ActionType type() const { return _type;}
inline const KeyCode keycode() const { return _keycode; }
inline const unsigned int modifierMask() const { return _modifierMask; }
inline const int number() const { return _numberParam; }
inline const std::string &string() const { return _stringParam; }
Action(enum ActionType type, KeyCode keycode, unsigned int modifierMask,
const std::string &str = "");
};
typedef std::list<Action> ActionList;
#endif

View file

@ -1,170 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// config.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
#include "config.hh"
using std::string;
Config::Config() {}
Config::~Config()
{
// deallocate memory for the 3 lists
BoolItemList::const_iterator b_it, b_end = bool_items.end();
for (b_it = bool_items.begin(); b_it != b_end; ++b_it)
delete *b_it;
bool_items.clear();
NumberItemList::const_iterator n_it, n_end = number_items.end();
for (n_it = number_items.begin(); n_it != n_end; ++n_it)
delete *n_it;
number_items.clear();
StringItemList::const_iterator s_it, s_end = string_items.end();
for (s_it = string_items.begin(); s_it != s_end; ++s_it)
delete *s_it;
string_items.clear();
}
bool Config::getValue(Config::StringType type, string &ret) const
{
StringItemList::const_iterator it = string_items.begin(), end = string_items.end();
for (; it != end; ++it) {
if ((*it)->type == type) {
ret = (*it)->value;
return true;
}
}
return false;
}
bool Config::getValue(Config::NumberType type, int &ret) const
{
NumberItemList::const_iterator it = number_items.begin(), end = number_items.end();
for (; it != end; ++it) {
if ((*it)->type == type) {
ret = (*it)->value;
return true;
}
}
return false;
}
bool Config::getValue(Config::BoolType type, bool &ret) const
{
BoolItemList::const_iterator it = bool_items.begin(), end = bool_items.end();
for (; it != end; ++it) {
if ((*it)->type == type) {
ret = (*it)->value;
return true;
}
}
return false;
}
void Config::addOption(const std::string &name, const std::string &value)
{
const struct {
const char *name;
Config::BoolType type;
}
bool_options[] = {
{ "stackedcycling", Config::stackedCycling },
{ "stackedcyclingraise", Config::stackedCyclingRaise },
{ "", NUM_BOOL_TYPES }
};
const struct {
const char *name;
Config::StringType type;
}
string_options[] = {
{ "", NUM_STRING_TYPES }
};
const struct {
const char *name;
Config::NumberType type;
}
number_options[] = {
{ "chaintimeout", chainTimeout },
{ "workspacecolumns", workspaceColumns },
{ "", NUM_NUMBER_TYPES }
};
// if it's bool option, add it to the bool_items list
size_t i = 0;
while (bool_options[i].type != NUM_BOOL_TYPES) {
if (strcasecmp(name.c_str(), bool_options[i].name) == 0) {
BoolItem *item = new BoolItem;
const char *tmp = value.c_str();
item->type = bool_options[i].type;
if (strcasecmp(tmp, "true") == 0 || strcasecmp(tmp, "1") == 0 ||
strcasecmp(tmp, "on") == 0)
item->value = true;
else
item->value = false;
bool_items.push_back(item);
return;
}
i++;
}
// if it's a string, add it to the string_items list
i = 0;
while (string_options[i].type != NUM_STRING_TYPES) {
if (strcasecmp(name.c_str(), string_options[i].name) == 0) {
StringItem *item = new StringItem;
item->type = string_options[i].type;
item->value = value;
string_items.push_back(item);
return;
}
i++;
}
// if it's a number, add it to the number_items list
i = 0;
while (number_options[i].type != NUM_NUMBER_TYPES) {
if (strcasecmp(name.c_str(), number_options[i].name) == 0) {
NumberItem *item = new NumberItem;
item->type = number_options[i].type;
item->value = atoi( value.c_str() );
number_items.push_back(item);
return;
}
i++;
}
}

View file

@ -1,89 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// config.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __config_hh
#define __config_hh
#include <string>
#include <list>
// forward declarations
struct BoolItem;
struct StringItem;
struct NumberItem;
class Config {
public:
enum BoolType {
NO_BOOL_TYPE,
stackedCycling,
stackedCyclingRaise,
NUM_BOOL_TYPES
};
enum StringType {
NO_STRING_TYPE,
NUM_STRING_TYPES
};
enum NumberType {
NO_NUMBER_TYPE,
chainTimeout,
workspaceColumns,
NUM_NUMBER_TYPES
};
private:
typedef std::list<BoolItem *> BoolItemList;
typedef std::list<StringItem *> StringItemList;
typedef std::list<NumberItem *> NumberItemList;
BoolItemList bool_items;
StringItemList string_items;
NumberItemList number_items;
public:
Config();
~Config();
bool getValue(BoolType, bool &) const;
bool getValue(StringType, std::string &) const;
bool getValue(NumberType, int &) const;
void addOption(const std::string &, const std::string &);
};
struct BoolItem {
Config::BoolType type;
bool value;
};
struct StringItem {
Config::StringType type;
std::string value;
};
struct NumberItem {
Config::NumberType type;
int value;
};
#endif // __config_hh

View file

@ -1,26 +0,0 @@
.TH epist 1 "August 16 2002" "epist" "v1.0"
.SH NAME
epist - NetWM keybindings grabber
.SH SYNOPSIS
\fBepist\fR [options]
.SH DESCRIPTION
\fBepist\fR is intended to provide keygrabbing for the OpenBox window manager
for the X Window System. This allows you to control things with keypresses
rather than the mouse.
.SH OPTIONS
.TP
\fB\-display\fR \fIXdisplay\fR
\fIX display\fR is connected to by epist instead of $DISPLAY.
.TP
\fB\-rc\fR \fIrcfile\fR
\fIrcfile\fR is used as the keybindings configuration.
.TP
.SH CONFIGURATION
\fBepist\fR will read its configuration from \fI~/.openbox/epistrc\fR otherwise
a default configuration, installed in \fI@pkgdatadir@/epistrc\fR
will be used. See \fIepistrc\fR(5) for more details on the format of the file.
.SH AUTHOR
The authors of epist are Scott Moynes <smoynes@nexus.carleton.ca>,
Marius Nita <marius@cs.pdx.edu>, and Ben Jansens <ben@orodu.net>.
.SH SEE ALSO
\fIopenbox\fR(1) \fIepistrc\fR(5)

View file

@ -1,199 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// epist.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif // HAVE_SIGNAL_H
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif // HAVE_LIBGEN_H
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_SYS_STAT_H
# include <sys/types.h>
# include <sys/stat.h>
#endif // HAVE_SYS_STAT_H
}
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
#include "actions.hh"
#include "epist.hh"
#include "screen.hh"
#include "window.hh"
#include "parser.hh"
#include "../../src/xatom.hh"
epist::epist(char **argv, char *dpy_name, char *rc_file)
: BaseDisplay(argv[0], dpy_name) {
_argv = argv;
if (rc_file)
_rc_file = rc_file;
else
_rc_file = expandTilde("~/.openbox/epistrc");
struct stat buf;
if (0 != stat(_rc_file.c_str(), &buf) ||
!S_ISREG(buf.st_mode))
_rc_file = DEFAULTRC;
_xatom = new XAtom(getXDisplay());
_active = _clients.end();
_config = new Config;
_ktree = new keytree(getXDisplay(), this);
// set up the key tree
parser p(_ktree, _config);
p.parse(_rc_file);
for (unsigned int i = 0; i < getNumberOfScreens(); ++i) {
screen *s = new screen(this, i);
if (s->managed()) {
_screens.push_back(s);
s->updateEverything();
}
}
if (_screens.empty()) {
cout << "No compatible window manager found on any screens. Aborting.\n";
::exit(1);
}
activateGrabs();
}
epist::~epist() {
delete _xatom;
}
void epist::activateGrabs() {
ScreenList::const_iterator scrit, scrend = _screens.end();
for (scrit = _screens.begin(); scrit != scrend; ++scrit)
_ktree->grabDefaults(*scrit);
}
bool epist::handleSignal(int sig) {
switch (sig) {
case SIGHUP: {
cout << "epist: Restarting on request.\n";
execvp(_argv[0], _argv);
string base(basename(_argv[0]));
execvp(base.c_str(), _argv);
return false; // this should be unreachable
}
case SIGTERM:
case SIGINT:
case SIGPIPE:
shutdown();
return true;
}
return false;
}
void epist::process_event(XEvent *e) {
ScreenList::const_iterator it, end = _screens.end();
for (it = _screens.begin(); it != end; ++it) {
if ((*it)->rootWindow() == e->xany.window) {
(*it)->processEvent(*e);
return;
}
}
// wasnt a root window, try for client windows
XWindow *w = findWindow(e->xany.window);
if (w) w->processEvent(*e);
}
void epist::addWindow(XWindow *window) {
_windows.insert(WindowLookupPair(window->window(), window));
}
void epist::removeWindow(XWindow *window) {
_windows.erase(window->window());
}
XWindow *epist::findWindow(Window window) const {
WindowLookup::const_iterator it = _windows.find(window);
if (it != _windows.end())
return it->second;
return 0;
}
void epist::cycleScreen(int current, bool forward) const {
unsigned int i;
for (i = 0; i < _screens.size(); ++i)
if (_screens[i]->number() == current) {
current = i;
break;
}
assert(i < _screens.size()); // current is for an unmanaged screen
int dest = current + (forward ? 1 : -1);
if (dest < 0) dest = (signed)_screens.size() - 1;
else if (dest >= (signed)_screens.size()) dest = 0;
const XWindow *target = _screens[dest]->lastActiveWindow();
if (target) target->focus();
}

View file

@ -1,93 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// epist.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __epist_hh
#define __epist_hh
extern "C" {
#include <X11/Xlib.h>
}
#include <string>
#include <map>
#include "actions.hh"
#include "window.hh"
#include "keytree.hh"
#include "config.hh"
#include "../../src/basedisplay.hh"
class XAtom;
class screen;
class epist : public BaseDisplay {
private:
std::string _rc_file;
XAtom *_xatom;
char **_argv;
keytree *_ktree;
Config *_config;
typedef std::vector<screen *> ScreenList;
ScreenList _screens;
typedef std::map<Window, XWindow*> WindowLookup;
typedef WindowLookup::value_type WindowLookupPair;
WindowLookup _windows;
WindowList _clients;
WindowList::iterator _active;
ActionList _actions;
virtual void process_event(XEvent *e);
virtual bool handleSignal(int sig);
void activateGrabs();
public:
epist(char **argv, char *display_name, char *rc_file);
virtual ~epist();
inline XAtom *xatom() { return _xatom; }
void addWindow(XWindow *window);
void removeWindow(XWindow *window);
XWindow *findWindow(Window window) const;
void cycleScreen(int current, bool forward) const;
void getLockModifiers(int &numlockMask, int &scrolllockMask) const {
numlockMask = NumLockMask;
scrolllockMask = ScrollLockMask;
}
const ActionList &actions(void) { return _actions; }
keytree &getKeyTree(void) { return *_ktree; }
inline const Config *getConfig(void) { return _config; }
WindowList& clientsList() { return _clients; }
WindowList::iterator& activeWindow() { return _active; }
};
#endif // __epist_hh

View file

@ -1,53 +0,0 @@
%{
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
#include <stdio.h>
#include <string.h>
#include "yacc_parser.hh"
extern YYSTYPE yylval;
%}
%option yylineno
%%
\{ return OBRACE;
\} return EBRACE;
; return SEMICOLON;
- return DASH;
Options |
options return OPTIONS;
Mod1 |
mod1 |
Mod2 |
mod2 |
Mod3 |
mod3 |
Mod4 |
mod4 |
Mod5 |
mod5 |
Control |
control |
shift |
Shift yylval = (int) strdup(yytext); return BINDING;
on |
On |
true |
True yylval = (int) strdup(yytext); return TRUE;
Off |
off |
false |
False yylval = (int) strdup(yytext); return FALSE;
[0-9]+ yylval = (int) strdup(yytext); return NUMBER;
\".+\" yylval = (int) strdup(yytext); return QUOTES;
[a-zA-Z_0-9]+ yylval = (int) strdup(yytext); return WORD;
#.+\n /* ignore */
\n /* ignore */
[ \t]+ /* */
%%

View file

@ -1,111 +0,0 @@
%{
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
#include <stdio.h>
#include <string.h>
#include "parser.hh"
#define YYPARSE_PARAM parser_obj
#define YYSTYPE char*
extern int yylineno;
extern char *yytext;
extern "C" {
int yylex();
int yywrap() {
return 1;
}
}
void yyerror(const char *c)
{
printf("ERROR: %s, on line %d, near %s\n", c, yylineno, yytext);
}
%}
%token OBRACE EBRACE SEMICOLON DASH NUMBER QUOTES WORD BINDING OPTIONS TRUE FALSE
%expect 1
%%
commands:
| commands command
| commands options_block
;
command:
action_command | chain_command
;
action_command:
binding WORD parameter SEMICOLON
{
((parser*)parser_obj)->setAction($2);
((parser*)parser_obj)->endAction();
}
;
chain_command:
binding obrace commands ebrace
{
((parser*)parser_obj)->endChain();
}
;
options_block:
options_keyword OBRACE options EBRACE
;
binding:
binding_w_modifier bind_key
;
obrace:
OBRACE { ((parser*)parser_obj)->startChain(); }
;
ebrace:
EBRACE { /* ((parser*)parser_obj)->endChain(); */ }
;
binding_w_modifier:
| BINDING DASH binding_w_modifier { ((parser*)parser_obj)->addModifier($1); }
;
bind_key:
OBRACE { ((parser*)parser_obj)->setKey($1); }
| EBRACE { ((parser*)parser_obj)->setKey($1); }
| DASH { ((parser*)parser_obj)->setKey($1); }
| SEMICOLON { ((parser*)parser_obj)->setKey($1); }
| NUMBER { ((parser*)parser_obj)->setKey($1); }
| WORD { ((parser*)parser_obj)->setKey($1); }
;
parameter:
| NUMBER { ((parser*)parser_obj)->setArgumentNum($1); }
| DASH NUMBER { ((parser*)parser_obj)->setArgumentNegNum($2); }
| QUOTES { ((parser*)parser_obj)->setArgumentStr($1); }
| TRUE { ((parser*)parser_obj)->setArgumentTrue($1); }
| FALSE { ((parser*)parser_obj)->setArgumentFalse($1); }
;
options_keyword:
OPTIONS
;
options:
| options option
;
option:
WORD parameter SEMICOLON
{ ((parser*)parser_obj)->setOption($1); }
;
%%

View file

@ -1,50 +0,0 @@
# Default epistrophy rc file
options {
# default option values
stackedCycling false;
chainTimeout 4000;
workspaceColumns 0;
}
Mod1-F1 changeWorkspace 1;
Mod1-F2 changeWorkspace 2;
Mod1-F3 changeWorkspace 3;
Mod1-F4 changeWorkspace 4;
Mod1-F5 changeWorkspace 5;
Mod1-F6 changeWorkspace 6;
Mod1-F7 changeWorkspace 7;
Control-F1 execute "xterm";
Control-Mod1-Right nextWindow;
Control-Mod1-Shift-Right nextwindowonallworkspaces;
Control-Mod1-Left prevWindow;
Control-Mod1-Shift-Left prevwindowonallworkspaces;
Control-Mod1-Up nextWorkspace;
Control-Mod1-Down prevWorkspace;
# These default to 5 pixels.
Mod1-Up moveWindowUp;
Mod1-Down moveWindowDown;
Mod1-Left moveWindowLeft;
Mod1-Right moveWindowRight;
Control-Mod1-Shift-x {
i iconify;
r raise;
l lower;
k close;
s toggleShade;
o toggleOmnipresent;
1 sendToWorkspace 1;
2 sendToWorkspace 2;
3 sendToWorkspace 3;
4 sendToWorkspace 4;
5 sendToWorkspace 5;
6 sendToWorkspace 6;
}

View file

@ -1,193 +0,0 @@
.TH epistrc 5 "August 24, 2002"
.SH NAME
epistrc \- Configuration file for Epist
.SH SYNOPSIS
.B $HOME/.openbox/epistrc
.br
.B @pkgdatadir@/epistrc
.SH DESCRIPTION
\fIepist\fR(1) grabs its configuration and bindings from the epistrc file. All
options shown will work with any window manager that supports the NetWM/EWMH
specification, with the exception of those marked with the
.B [Openbox specific]
tag.
.SH SYNTAX
The epistrc file contains 2 sections:
.SS Options
All of the options for epist are contained inside a clause such as this:
.PP
options {
.br
<option name> <option value>;
.br
}
.PP
The option name is a string of characters, and the option value can be either a string in double quotes, a number, or a boolen value (the words True or False without quotes around them).
.SS Bindings
Bindings are specified in this format:
.PP
<key> <action> <optional parameter>;
.PP
Bindings with chains are specified in this format:
.PP
<root key> {
.br
<key> <action> <optional parameter>;
.br
}
.PP
The <key> is made up of a list of modifiers and a single key. The possible modifiers are: \fIControl\fR, \fIShift\fR, \fIMod1\fR (usually the Alt key), \fIMod2\fR, \fIMod3\fR, \fIMod4\fR (usually the "windows" key), and \fIMod5\fR. You may also specify a <key> without any modifiers.
.PP
Comments can be added by prefixing the commented line with a "#".
.PP
You may nest as many chains as you want. Some examples of bindings are:
.PP
Mod1-Tab nextWindow;
.br
Mod1-Shift-Tab prevWindow;
.br
Mod1-F1 changeWorkspace 1;
.br
Mod1-F2 changeWorkspace 2;
.br
Control-F1 execute "xterm";
.br
Control-Mod1-x {
.br
i iconify;
.br
r raise;
.br
Mod1-x { l lower; }
.br
}
.SH OPTIONS
.SS stackedCycling (boolean, default=off)
When this option is set to True, any window cycling actions, such as nextWindow,
prevWindow, nextWindowOfClass, etc., will cause the windows to focus, but they will
not be raised until the modifiers are released. When the modifier is released,
the focused (and now raised) window will be moved to the top of the stacking order,
so if you execute nextWindow and release the modifiers multiple times, focus will
cycle between two windows.
.SS stackedCyclingRaise (boolean, default=off)
This option modifies the window raise behavior when stackedCycling is turned on.
When true, windows will be raised immediatly on focus, rather than when the
keys are released. This may be desirable if you frequently have windows that are
obscured by other windows.
.SS chainTimeout (number, default=3500)
Specifies the period of time after which a started key chain will
be timed out. It takes a number argument specifying the number of
milliseconds to wait. It defaults to 4000.
.SS workspaceColumns (number, default=0, disabled)
Specifies the number of columns of your workspace layout if you are using
your workspaces in a 2-dimensional manner. This option must exist if one of
the prevWorkspaceColumn, prevWorkspaceRow, nextWorkspaceColumn,
nextWorkspaceRow commands are used.
.SH COMMANDS
.SS execute
Runs a shell command. Takes a single string argument, in ""s.
.SS iconify
Iconifies the currently focused window.
.SS raise
Raises the currently focused window to the top of the stacking order.
.SS lower
Lowers the currently focused window to the bottom of the stacking order.
.SS close
Closes the currently focused window.
.SS toggleShade
Shades and Unshades the currently focused window.
.SS toggleOmnipresent
Sends the window to all workspaces, or moves it from all workspaces to the
current one.
.SS moveWindowUp
.SS moveWindowDown
.SS moveWindowLeft
.SS moveWindowRight
Move the window in the specified direction. Takes a single numerical parameter,
which is the amount to move the window.
.SS resizeWindowWidth
.SS resizeWindowHeight
Resizes the window. Takes a single numerical parameter, which is the
amount to resize the window by. A positive number enlarges the window, a
negative value shrinks the window.
.SS toggleMaximizeFull
Maximizes and Unmaxizes the currently focused window.
.SS toggleMaximizeVertical
Maximizes and Unmaxizes the currently focused window vertically.
.SS toggleMaximizeHorizontal
Maximizes and Unmaxizes the currently focused window horizontally.
.SS sendToWorkspace
Sends the currently focused window to another workspace. This takes a single
numberical parameter, which is the workspace to send the window to. Workspace
numbers begin at 1.
.SS nextWindow
.SS prevWindow
Cycles focus to the next/previous window on the workspace. This can take a
single numerical parameter specifying how many windows to cycle through. If
none is specified, a value of 1 is assumed.
.SS nextWindowOnAllWorkspaces
.SS prevWindowOnAllWorkspaces
Cycles focus to the next/previous window on all workspaces, switching between
workspaces as neccessary. This can take a single numerical parameter specifying
how many windows to cycle through. If none is specified, a value of 1 is
assumed.
.SS nextWindowOnAllScreens
.SS prevWindowOnAllScreens
Cycles focus to the next/previous window on all screens (in a multi-head setup).
This can take a single numerical parameter specifying how many windows to cycle
through. If none is specified, a value of 1 is assumed.
.SS nextWindowOfClass
.SS prevWindowOfClass
Cycles focus to the next/previous window of a certain class on the current
workspace. This can take a single string parameter, in ""s, specifying the
class of the window to cycle to. If the parameter is omitted, the class of the
currently focused window is used. This can take a single numerical parameter
specifying how many windows to cycle through. If none is specified, a value of
1 is assumed.
.SS nextWindowOfClassOnAllWorkspaces
.SS prevWindowOfClassOnAllWorkspaces
Cycles focus to the next/previous window of a certain class on all workspaces.
This can take a single string parameter, in ""s, specifying the class of the
window to cycle to. If the parameter is omitted, the class of the currently
focused window is used. This can take a single numerical parameter specifying
how many windows to cycle through. If none is specified, a value of 1 is
assumed.
.SS changeWorkspace
Changes to a specific workspace. This takes a single numerical paramter,
specifying the number of the workspace to switch to. Workspace numbers begin at
1.
.SS nextWorkspace
.SS prevWorkspace
Switches to the next/previous workspace. This can take a single numerical
parameter specifying how many workspaces to cycle through. If none is specified,
a value of 1 is assumed.
.SS nextScreen
.SS prevScreen
Cycles focus to the next/previous screen (in a multi-head setup).
.SS prevWorkspaceColumn
.SS nextWorkspaceColumn
.SS prevWorkspaceRow
.SS nextWorkspaceRow
Used to navigate the workspaces in a 2-dimensional manner. If these commands are
used, the workspaceColumns action must be specified. See OPTIONS.
.SS toggleGrabs
Disables all keybindings except for the binding which runs this action, for
the current screen. Enables keybindings when run again. This command cannot be
part of a chain.
.SS toggleDecorations
.B [Openbox specific]
.br
Toggles whether or not the window decorations are shown on the currently
focused window. (Decorations include the titlebar, borders, and bottom handle.)
.SS showRootMenu
.B [Openbox specific]
.br
Opens the root menu under the mouse pointer.
.SS showWorkspaceMenu
.B [Openbox specific]
.br
Opens the workspace menu under the mouse pointer.
.SH SEE ALSO
\fIepist\fR(1) \fIopenbox\fR(1)

View file

@ -1,256 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// keytree.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
#include "keytree.hh"
#include "epist.hh"
#include "config.hh"
#include <string>
#include <iostream>
using std::string;
keytree::keytree(Display *display, epist *ep)
: _display(display), _timeout_screen(NULL), _timer(NULL), _epist(ep)
{
_head = new keynode;
_head->parent = NULL;
_head->action = NULL; // head's action is always NULL
_current = _head;
// for complete initialization, initialize() has to be called as well. We
// call initialize() when we are certain that the config object (which the
// timer uses) has been fully initialized. (see parser::parse())
}
keytree::~keytree()
{
clearTree(_head);
delete _timer;
}
void keytree::unloadBindings()
{
ChildList::iterator it, end = _head->children.end();
for (it = _head->children.begin(); it != end; ++it)
clearTree(*it);
_head->children.clear();
reset();
}
void keytree::clearTree(keynode *node)
{
if (!node)
return;
ChildList::iterator it, end = node->children.end();
for (it = node->children.begin(); it != end; ++it)
clearTree(*it);
node->children.clear();
if (node->action)
delete node->action;
delete node;
node = NULL;
}
void keytree::grabDefaults(screen *scr)
{
grabChildren(_head, scr);
}
void keytree::ungrabDefaults(screen *scr)
{
Action *act;
ChildList::const_iterator it, end = _head->children.end();
for (it = _head->children.begin(); it != end; ++it) {
act = (*it)->action;
if (act && act->type() != Action::toggleGrabs)
scr->ungrabKey(act->keycode(), act->modifierMask());
}
}
void keytree::grabChildren(keynode *node, screen *scr)
{
Action *act;
ChildList::const_iterator it, end = node->children.end();
for (it = node->children.begin(); it != end; ++it) {
act = (*it)->action;
if (act)
scr->grabKey(act->keycode(), act->modifierMask());
}
}
void keytree::ungrabChildren(keynode *node, screen *scr)
{
ChildList::const_iterator head_it, head_end = _head->children.end();
ChildList::const_iterator it, end = node->children.end();
bool ungrab = true;
// when ungrabbing children, make sure that we don't ungrab any topmost keys
// (children of the head node) This would render those topmost keys useless.
// Topmost keys are _never_ ungrabbed, since they are only grabbed at startup
for (it = node->children.begin(); it != end; ++it) {
if ( (*it)->action ) {
for (head_it = _head->children.begin(); head_it != head_end; ++head_it) {
if ( (*it)->action->modifierMask() == (*head_it)->action->modifierMask() &&
(*it)->action->keycode() == (*head_it)->action->keycode())
{
ungrab = false;
break;
}
}
if (ungrab)
scr->ungrabKey( (*it)->action->keycode(), (*it)->action->modifierMask());
ungrab = true;
}
}
}
const Action * keytree::getAction(const XEvent &e, unsigned int state,
screen *scr)
{
Action *act;
// we're done with the children. ungrab them
if (_current != _head)
ungrabChildren(_current, scr);
ChildList::const_iterator it, end = _current->children.end();
for (it = _current->children.begin(); it != end; ++it) {
act = (*it)->action;
if (e.xkey.keycode == act->keycode() && state == act->modifierMask()) {
if (act->type() == Action::cancelChain) {
// user is cancelling the chain explicitly
_current = _head;
return (const Action *)NULL;
}
else if ( isLeaf(*it) ) {
// node is a leaf, so an action will be executed
if (_timer->isTiming()) {
_timer->stop();
_timeout_screen = NULL;
}
_current = _head;
return act;
}
else {
// node is not a leaf, so we advance down the tree, and grab the
// children of the new current node. no action is executed
if (_timer->isTiming())
_timer->stop();
_timer->start();
_timeout_screen = scr;
_current = *it;
grabChildren(_current, scr);
return (const Action *)NULL;
}
}
}
// action not found. back to the head
_current = _head;
return (const Action *)NULL;
}
void keytree::addAction(Action::ActionType action, unsigned int mask,
string key, string arg)
{
if (action == Action::toggleGrabs && _current != _head) {
// the toggleGrabs key can only be set up as a root key, since if
// it was a chain key, we'd have to not ungrab the whole chain up
// to that key. which kinda defeats the purpose of this function.
return;
}
KeySym sym = XStringToKeysym(key.c_str());
keynode *tmp = new keynode;
tmp->action = new Action(action,
XKeysymToKeycode(_display, sym),
mask, arg);
tmp->parent = _current;
_current->children.push_back(tmp);
}
void keytree::advanceOnNewNode()
{
keynode *tmp = new keynode;
tmp->action = NULL;
tmp->parent = _current;
_current->children.push_back(tmp);
_current = tmp;
}
void keytree::retract()
{
if (_current != _head)
_current = _current->parent;
}
void keytree::setCurrentNodeProps(Action::ActionType action, unsigned int mask,
string key, string arg)
{
if (_current->action)
delete _current->action;
KeySym sym = XStringToKeysym(key.c_str());
_current->action = new Action(action,
XKeysymToKeycode(_display, sym),
mask, arg);
}
void keytree::initialize(void)
{
int tval = 0;
_epist->getConfig()->getValue(Config::chainTimeout, tval);
_timer = new BTimer(_epist, this);
if (tval <= 0)
tval = 3000; // set default timeout to 3 seconds
_timer->setTimeout(tval);
}
void keytree::timeout(void)
{
assert(_timeout_screen != NULL);
if (_current != _head) {
ungrabChildren(_current, _timeout_screen);
_current = _head;
}
_timeout_screen = NULL;
}

View file

@ -1,80 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// keytree.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef _keytree_hh
#define _keytree_hh
#include <list>
#include "../../src/timer.hh"
#include "actions.hh"
#include "screen.hh"
struct keynode; // forward declaration
typedef std::list<keynode *> ChildList;
struct keynode {
Action *action;
keynode *parent;
ChildList children;
};
class keytree : public TimeoutHandler {
public:
keytree(Display *, epist *);
virtual ~keytree();
void grabDefaults(screen *);
void ungrabDefaults(screen *);
const Action * getAction(const XEvent&, unsigned int, screen *);
void unloadBindings();
void timeout();
private:
// only mister parser needs to know about our sekrets (BUMMY)
friend class parser;
void grabChildren(keynode *, screen *);
void ungrabChildren(keynode *, screen *);
void addAction(Action::ActionType, unsigned int, std::string, std::string);
void advanceOnNewNode();
void retract();
void setCurrentNodeProps(Action::ActionType, unsigned int, std::string, std::string);
void initialize();
void reset()
{ _current = _head; }
bool isLeaf(keynode *node)
{ return node->children.empty(); }
void clearTree(keynode *);
keynode *_head;
keynode *_current;
Display *_display;
screen *_timeout_screen;
BTimer *_timer;
epist *_epist;
};
#endif // _keytree_hh

File diff suppressed because it is too large Load diff

View file

@ -1,102 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; -*-
// main.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
}
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
#include "../../version.h"
#include "epist.hh"
static void usage();
int main(int argc, char **argv) {
// parse the command line
char *display_name = 0;
char *rc_file = 0;
for (int i = 1; i < argc; ++i) {
const string argvi(argv[i]);
if (argvi == "-display") {
if (++i >= argc) {
fprintf(stderr, "error: '-display' requires an argument\n");
exit(1);
}
display_name = argv[i];
} else if (argvi == "-rc") {
if (++i >= argc) {
fprintf(stderr, "error: '-rc' requires an argument\n");
exit(1);
}
rc_file = argv[i];
} else if (argvi == "-help") {
usage();
} else if (argvi == "-version") {
fprintf(stderr, "epist - shipped with openbox %s\n",
OPENBOX_VERSION);
exit(0);
}
else
usage();
}
epist ep(argv, display_name, rc_file);
ep.eventLoop();
return 0;
}
static void usage()
{
cout << "usage: epist OPTIONS" << endl;
cout << endl;
cout << "Options:" << endl;
cout <<
" -rc RCFILE Specifies the path to an alternate rc file to load"
<< endl <<
" -display DISPLAY Specifies the X display to run on" << endl <<
" -help Display this help and exit" << endl <<
" -version Display the version and exit" << endl <<
endl;
exit(0);
}

View file

@ -1,221 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// parser.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#include <stdio.h>
#include <string.h>
}
#include "parser.hh"
#include <string>
#include <iostream>
using std::string;
using std::cout;
parser::parser(keytree *kt, Config *conf)
: _kt(kt), _config(conf), _mask(0), _action(Action::noaction),
_key(""), _arg(""), _add(true)
{
}
parser::~parser()
{
// nothing to see here. move along.
}
void parser::parse(string rc_file)
{
extern int yyparse(void *);
extern FILE *yyin;
yyin = fopen(rc_file.c_str(), "r");
if (yyin) {
yyparse(this);
fclose(yyin);
} else {
std::cerr << "ERROR: Configuration file could not be opened/found.\n";
}
_kt->reset();
_kt->initialize();
}
void parser::setKey(string key)
{
KeySym sym = XStringToKeysym(key.c_str());
if (sym == 0) {
std::cerr << "ERROR: Invalid key (" << key << ")! This may cause odd behavior.\n";
_add = false;
} else {
_key = key;
}
}
void parser::setAction(string act)
{
struct {
const char* str;
Action::ActionType act;
}
actions[] = {
{ "noaction", Action::noaction },
{ "execute", Action::execute },
{ "iconify", Action::iconify },
{ "raise", Action::raise },
{ "lower", Action::lower },
{ "close", Action::close },
{ "toggleShade", Action::toggleShade },
{ "toggleOmnipresent", Action::toggleOmnipresent },
{ "movewindowup", Action::moveWindowUp },
{ "movewindowdown", Action::moveWindowDown },
{ "movewindowleft", Action::moveWindowLeft },
{ "movewindowright", Action::moveWindowRight },
{ "resizewindowwidth", Action::resizeWindowWidth },
{ "resizewindowheight", Action::resizeWindowHeight },
{ "togglemaximizefull", Action::toggleMaximizeFull },
{ "togglemaximizevertical", Action::toggleMaximizeVertical },
{ "togglemaximizehorizontal", Action::toggleMaximizeHorizontal },
{ "sendtoworkspace", Action::sendToWorkspace },
{ "nextwindow", Action::nextWindow },
{ "prevwindow", Action::prevWindow },
{ "nextwindowonallworkspaces", Action::nextWindowOnAllWorkspaces },
{ "prevwindowonallworkspaces", Action::prevWindowOnAllWorkspaces },
{ "nextwindowonallscreens", Action::nextWindowOnAllScreens },
{ "prevwindowonallscreens", Action::prevWindowOnAllScreens },
{ "nextwindowofclass", Action::nextWindowOfClass },
{ "prevwindowofclass", Action::prevWindowOfClass },
{ "nextwindowofclassonallworkspaces", Action::nextWindowOfClassOnAllWorkspaces },
{ "prevwindowofclassonallworkspaces", Action::prevWindowOfClassOnAllWorkspaces },
{ "changeworkspace", Action::changeWorkspace },
{ "nextworkspace", Action::nextWorkspace },
{ "prevworkspace", Action::prevWorkspace },
{ "nextworkspacerow", Action::upWorkspace },
{ "prevworkspacerow", Action::downWorkspace },
{ "prevworkspacecolumn", Action::leftWorkspace },
{ "nextworkspacecolumn", Action::rightWorkspace },
{ "nextscreen", Action::nextScreen },
{ "prevscreen", Action::prevScreen },
{ "showrootmenu", Action::showRootMenu },
{ "showworkspacemenu", Action::showWorkspaceMenu },
{ "toggledecorations", Action::toggleDecorations },
{ "togglegrabs", Action::toggleGrabs },
{ "stringchain", Action::stringChain },
{ "keychain", Action::keyChain },
{ "numberchain", Action::numberChain },
{ "cancelchain", Action::cancelChain },
{ "", Action::noaction }
};
bool found = false;
for (int i = 0; actions[i].str != ""; ++i) {
if ( strcasecmp(actions[i].str, act.c_str()) == 0 ) {
_action = actions[i].act;
found = true;
break;
}
}
if (!found) {
cout << "ERROR: Invalid action (" << act << "). Binding ignored.\n";
_add = false;
}
}
void parser::addModifier(string mod)
{
struct {
const char *str;
unsigned int mask;
}
modifiers[] = {
{ "mod1", Mod1Mask },
{ "mod2", Mod2Mask },
{ "mod3", Mod3Mask },
{ "mod4", Mod4Mask },
{ "mod5", Mod5Mask },
{ "control", ControlMask },
{ "shift", ShiftMask },
{ "", 0 }
};
bool found = false;
for (int i = 0; modifiers[i].str != ""; ++i) {
if ( strcasecmp(modifiers[i].str, mod.c_str()) == 0 ) {
_mask |= modifiers[i].mask;
found = true;
break;
}
}
if (!found) {
cout << "ERROR: Invalid modifier (" << mod << "). Binding ignored.\n";
_add = false;
}
}
void parser::endAction()
{
if (_add)
_kt->addAction(_action, _mask, _key, _arg);
reset();
_add = true;
}
void parser::startChain()
{
_kt->advanceOnNewNode();
setChainBinding();
reset();
}
void parser::endChain()
{
_kt->retract();
reset();
}
void parser::setChainBinding()
{
if (_add)
_kt->setCurrentNodeProps(Action::noaction, _mask, _key, "");
_add = true;
reset();
}
void parser::reset()
{
_mask = 0;
_action = Action::noaction;
_key = "";
_arg = "";
}

View file

@ -1,77 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// parser.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __parser_hh
#define __parser_hh
#include "actions.hh"
#include "keytree.hh"
#include "config.hh"
#include <string>
class parser {
public:
parser(keytree *, Config *);
~parser();
void parse(std::string);
void setArgumentNum(std::string arg)
{ _arg = arg; }
void setArgumentNegNum(std::string arg)
{ _arg = "-" + arg; }
void setArgumentStr(std::string arg)
{ _arg = arg.substr(1, arg.size() - 2); }
void setArgumentTrue(std::string)
{ _arg = "true"; }
void setArgumentFalse(std::string)
{ _arg = "false"; }
void setOption(std::string opt)
{ _config->addOption(opt, _arg); }
void setKey(std::string);
void setAction(std::string);
void addModifier(std::string);
void endAction();
void startChain();
void setChainBinding();
void endChain();
private:
void reset();
keytree *_kt;
Config *_config;
unsigned int _mask;
Action::ActionType _action;
std::string _key;
std::string _arg;
bool _add;
};
#endif //__parser_hh

View file

@ -1,849 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// screen.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/* A few comments about stacked cycling:
* When stacked cycling is turned on, the focused window is always at the top
* (front) of the list (_clients), EXCEPT for when we are in cycling mode.
* (_cycling is true) If we were to add the focused window to the top of the
* stack while we were cycling, we would end in a deadlock between 2 windows.
* When the modifiers are released, the window that has focus (but it's not
* at the top of the stack, since we are cycling) is placed at the top of the
* stack and raised.
* Hooray and Bummy. - Marius
*/
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif // HAVE_UNISTD_H
#include <X11/keysym.h>
}
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::hex;
using std::dec;
using std::string;
#include "../../src/basedisplay.hh"
#include "../../src/xatom.hh"
#include "screen.hh"
#include "epist.hh"
#include "config.hh"
screen::screen(epist *epist, int number)
: _clients(epist->clientsList()), _active(epist->activeWindow()),
_config(epist->getConfig()), _grabbed(true), _cycling(false),
_stacked_cycling(false), _stacked_raise(false)
{
_epist = epist;
_xatom = _epist->xatom();
_last_active = _clients.end();
_number = number;
_info = _epist->getScreenInfo(_number);
_root = _info->getRootWindow();
_config->getValue(Config::stackedCycling, _stacked_cycling);
if (_stacked_cycling)
_config->getValue(Config::stackedCyclingRaise, _stacked_raise);
// find a window manager supporting NETWM, waiting for it to load if we must
int count = 20; // try for 20 seconds
_managed = false;
while (! (_epist->doShutdown() || _managed || count <= 0)) {
if (! (_managed = findSupportingWM()))
sleep(1);
--count;
}
if (_managed)
cout << "Found compatible window manager '" << _wm_name << "' for screen "
<< _number << ".\n";
else {
cout << "Unable to find a compatible window manager for screen " <<
_number << ".\n";
return;
}
XSelectInput(_epist->getXDisplay(), _root, PropertyChangeMask);
}
screen::~screen() {
if (_managed)
XSelectInput(_epist->getXDisplay(), _root, None);
}
bool screen::findSupportingWM() {
Window support_win;
if (! _xatom->getValue(_root, XAtom::net_supporting_wm_check, XAtom::window,
support_win) || support_win == None)
return false;
string title;
_xatom->getValue(support_win, XAtom::net_wm_name, XAtom::utf8, title);
_wm_name = title;
return true;
}
XWindow *screen::findWindow(const XEvent &e) const {
assert(_managed);
WindowList::const_iterator it, end = _clients.end();
for (it = _clients.begin(); it != end; ++it)
if (**it == e.xany.window)
break;
if(it == end)
return 0;
return *it;
}
void screen::processEvent(const XEvent &e) {
assert(_managed);
assert(e.xany.window == _root);
switch (e.type) {
case PropertyNotify:
// root window
if (e.xproperty.atom == _xatom->getAtom(XAtom::net_number_of_desktops))
updateNumDesktops();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_current_desktop))
updateActiveDesktop();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_active_window))
updateActiveWindow();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_client_list)) {
// catch any window unmaps first
XEvent ev;
if (XCheckTypedWindowEvent(_epist->getXDisplay(), e.xany.window,
DestroyNotify, &ev) ||
XCheckTypedWindowEvent(_epist->getXDisplay(), e.xany.window,
UnmapNotify, &ev)) {
XWindow *win = _epist->findWindow(e.xany.window);
if (win) win->processEvent(ev);
}
updateClientList();
}
break;
case KeyPress:
handleKeypress(e);
break;
case KeyRelease:
handleKeyrelease(e);
break;
default:
break;
}
}
void screen::handleKeypress(const XEvent &e) {
int scrolllockMask, numlockMask;
_epist->getLockModifiers(numlockMask, scrolllockMask);
// Mask out the lock modifiers. We want our keys to always work
// This should be made an option
unsigned int state = e.xkey.state & ~(LockMask|scrolllockMask|numlockMask);
keytree &ktree = _epist->getKeyTree();
const Action *it = ktree.getAction(e, state, this);
if (!it)
return;
switch (it->type()) {
case Action::nextScreen:
_epist->cycleScreen(_number, true);
return;
case Action::prevScreen:
_epist->cycleScreen(_number, false);
return;
case Action::nextWorkspace:
cycleWorkspace(true, it->number() != 0 ? it->number(): 1);
return;
case Action::prevWorkspace:
cycleWorkspace(false, it->number() != 0 ? it->number(): 1);
return;
case Action::nextWindow:
cycleWindow(state, true, it->number() != 0 ? it->number(): 1);
return;
case Action::prevWindow:
cycleWindow(state, false, it->number() != 0 ? it->number(): 1);
return;
case Action::nextWindowOnAllWorkspaces:
cycleWindow(state, true, it->number() != 0 ? it->number(): 1, false, true);
return;
case Action::prevWindowOnAllWorkspaces:
cycleWindow(state, false, it->number() != 0 ? it->number(): 1, false, true);
return;
case Action::nextWindowOnAllScreens:
cycleWindow(state, true, it->number() != 0 ? it->number(): 1, true);
return;
case Action::prevWindowOnAllScreens:
cycleWindow(state, false, it->number() != 0 ? it->number(): 1, true);
return;
case Action::nextWindowOfClass:
cycleWindow(state, true, it->number() != 0 ? it->number(): 1,
false, false, true, it->string());
return;
case Action::prevWindowOfClass:
cycleWindow(state, false, it->number() != 0 ? it->number(): 1,
false, false, true, it->string());
return;
case Action::nextWindowOfClassOnAllWorkspaces:
cycleWindow(state, true, it->number() != 0 ? it->number(): 1,
false, true, true, it->string());
return;
case Action::prevWindowOfClassOnAllWorkspaces:
cycleWindow(state, false, it->number() != 0 ? it->number(): 1,
false, true, true, it->string());
return;
case Action::changeWorkspace:
changeWorkspace(it->number());
return;
case Action::upWorkspace:
changeWorkspaceVert(-1);
return;
case Action::downWorkspace:
changeWorkspaceVert(1);
return;
case Action::leftWorkspace:
changeWorkspaceHorz(-1);
return;
case Action::rightWorkspace:
changeWorkspaceHorz(1);
return;
case Action::execute:
execCommand(it->string());
return;
case Action::showRootMenu:
_xatom->sendClientMessage(rootWindow(), XAtom::openbox_show_root_menu,
None);
return;
case Action::showWorkspaceMenu:
_xatom->sendClientMessage(rootWindow(), XAtom::openbox_show_workspace_menu,
None);
return;
case Action::toggleGrabs: {
if (_grabbed) {
ktree.ungrabDefaults(this);
_grabbed = false;
} else {
ktree.grabDefaults(this);
_grabbed = true;
}
return;
}
default:
break;
}
// these actions require an active window
if (_active != _clients.end()) {
XWindow *window = *_active;
switch (it->type()) {
case Action::iconify:
window->iconify();
return;
case Action::close:
window->close();
return;
case Action::raise:
window->raise();
return;
case Action::lower:
window->lower();
return;
case Action::sendToWorkspace:
window->sendTo(it->number());
return;
case Action::toggleOmnipresent:
if (window->desktop() == 0xffffffff)
window->sendTo(_active_desktop);
else
window->sendTo(0xffffffff);
return;
case Action::moveWindowUp:
window->move(window->x(), window->y() -
(it->number() != 0 ? it->number(): 1));
return;
case Action::moveWindowDown:
window->move(window->x(), window->y() +
(it->number() != 0 ? it->number(): 1));
return;
case Action::moveWindowLeft:
window->move(window->x() - (it->number() != 0 ? it->number(): 1),
window->y());
return;
case Action::moveWindowRight:
window->move(window->x() + (it->number() != 0 ? it->number(): 1),
window->y());
return;
case Action::resizeWindowWidth:
window->resizeRel(it->number(), 0);
return;
case Action::resizeWindowHeight:
window->resizeRel(0, it->number());
return;
case Action::toggleShade:
window->shade(! window->shaded());
return;
case Action::toggleMaximizeHorizontal:
window->toggleMaximize(XWindow::Max_Horz);
return;
case Action::toggleMaximizeVertical:
window->toggleMaximize(XWindow::Max_Vert);
return;
case Action::toggleMaximizeFull:
window->toggleMaximize(XWindow::Max_Full);
return;
case Action::toggleDecorations:
window->decorate(! window->decorated());
return;
default:
assert(false); // unhandled action type!
break;
}
}
}
void screen::handleKeyrelease(const XEvent &) {
// the only keyrelease event we care about (for now) is when we do stacked
// cycling and the modifier is released
if (_stacked_cycling && _cycling && nothingIsPressed()) {
// all modifiers have been released. ungrab the keyboard, move the
// focused window to the top of the Z-order and raise it
ungrabModifiers();
if (_active != _clients.end()) {
XWindow *w = *_active;
bool e = _last_active == _active;
_clients.remove(w);
_clients.push_front(w);
_active = _clients.begin();
if (e) _last_active = _active;
w->raise();
}
_cycling = false;
}
}
// do we want to add this window to our list?
bool screen::doAddWindow(Window window) const {
assert(_managed);
Atom type;
if (! _xatom->getValue(window, XAtom::net_wm_window_type, XAtom::atom,
type))
return True;
if (type == _xatom->getAtom(XAtom::net_wm_window_type_dock) ||
type == _xatom->getAtom(XAtom::net_wm_window_type_menu))
return False;
return True;
}
void screen::updateEverything() {
updateNumDesktops();
updateActiveDesktop();
updateClientList();
updateActiveWindow();
}
void screen::updateNumDesktops() {
assert(_managed);
if (! _xatom->getValue(_root, XAtom::net_number_of_desktops, XAtom::cardinal,
(unsigned long)_num_desktops))
_num_desktops = 1; // assume that there is at least 1 desktop!
}
void screen::updateActiveDesktop() {
assert(_managed);
if (! _xatom->getValue(_root, XAtom::net_current_desktop, XAtom::cardinal,
(unsigned long)_active_desktop))
_active_desktop = 0; // there must be at least one desktop, and it must
// be the current one
}
void screen::updateClientList() {
assert(_managed);
WindowList::iterator insert_point = _active;
if (insert_point != _clients.end())
++insert_point; // get to the item client the focused client
// get the client list from the root window
Window *rootclients = 0;
unsigned long num = (unsigned) -1;
if (! _xatom->getValue(_root, XAtom::net_client_list, XAtom::window, num,
&rootclients))
num = 0;
WindowList::iterator it;
const WindowList::iterator end = _clients.end();
unsigned long i;
for (i = 0; i < num; ++i) {
for (it = _clients.begin(); it != end; ++it)
if (**it == rootclients[i])
break;
if (it == end) { // didn't already exist
if (doAddWindow(rootclients[i])) {
// cout << "Added window: 0x" << hex << rootclients[i] << dec << endl;
// insert new clients after the active window
_clients.insert(insert_point, new XWindow(_epist, this,
rootclients[i]));
}
}
}
// remove clients that no longer exist (that belong to this screen)
for (it = _clients.begin(); it != end;) {
WindowList::iterator it2 = it;
++it;
// is on another screen?
if ((*it2)->getScreen() != this)
continue;
for (i = 0; i < num; ++i)
if (**it2 == rootclients[i])
break;
if (i == num) { // no longer exists
// cout << "Removed window: 0x" << hex << (*it2)->window() << dec << endl;
// watch for the active and last-active window
if (it2 == _active)
_active = _clients.end();
if (it2 == _last_active)
_last_active = _clients.end();
delete *it2;
_clients.erase(it2);
}
}
if (rootclients) delete [] rootclients;
}
const XWindow *screen::lastActiveWindow() const {
if (_last_active != _clients.end())
return *_last_active;
// find a window if one exists
WindowList::const_iterator it, end = _clients.end();
for (it = _clients.begin(); it != end; ++it)
if ((*it)->getScreen() == this && ! (*it)->iconic() &&
(*it)->canFocus() &&
((*it)->desktop() == 0xffffffff ||
(*it)->desktop() == _active_desktop))
return *it;
// no windows on this screen
return 0;
}
void screen::updateActiveWindow() {
assert(_managed);
Window a = None;
_xatom->getValue(_root, XAtom::net_active_window, XAtom::window, a);
WindowList::iterator it, end = _clients.end();
for (it = _clients.begin(); it != end; ++it) {
if (**it == a) {
if ((*it)->getScreen() != this)
return;
break;
}
}
_active = it;
if (_active != end) {
/* if we're not cycling and a window gets focus, add it to the top of the
* cycle stack.
*/
if (_stacked_cycling && !_cycling) {
XWindow *win = *_active;
_clients.remove(win);
_clients.push_front(win);
_active = _clients.begin();
_last_active = _active;
}
}
/* cout << "Active window is now: ";
if (_active == _clients.end()) cout << "None\n";
else cout << "0x" << hex << (*_active)->window() << dec << endl;
*/
}
void screen::execCommand(const string &cmd) const {
pid_t pid;
if ((pid = fork()) == 0) {
// disconnect the child from epist's session and the tty
if (setsid() == -1) {
cout << "warning: could not start a new process group\n";
perror("setsid");
}
// make the command run on the correct screen
if (putenv(const_cast<char*>(_info->displayString().c_str()))) {
cout << "warning: couldn't set environment variable 'DISPLAY'\n";
perror("putenv()");
}
execl("/bin/sh", "sh", "-c", cmd.c_str(), NULL);
exit(-1);
} else if (pid == -1) {
cout << _epist->getApplicationName() <<
": Could not fork a process for executing a command\n";
}
}
void screen::cycleWindow(unsigned int state, const bool forward,
const int increment, const bool allscreens,
const bool alldesktops, const bool sameclass,
const string &cn)
{
assert(_managed);
assert(increment > 0);
if (_clients.empty()) return;
string classname(cn);
if (sameclass && classname.empty() && _active != _clients.end())
classname = (*_active)->appClass();
WindowList::const_iterator target = _active,
begin = _clients.begin(),
end = _clients.end();
XWindow *t = 0;
for (int x = 0; x < increment; ++x) {
while (1) {
if (forward) {
if (target == end) {
target = begin;
} else {
++target;
}
} else {
if (target == begin)
target = end;
--target;
}
// must be no window to focus
if (target == _active)
return;
// start back at the beginning of the loop
if (target == end)
continue;
// determine if this window is invalid for cycling to
t = *target;
if (t->iconic()) continue;
if (! allscreens && t->getScreen() != this) continue;
if (! alldesktops && ! (t->desktop() == _active_desktop ||
t->desktop() == 0xffffffff)) continue;
if (sameclass && ! classname.empty() &&
t->appClass() != classname) continue;
if (! t->canFocus()) continue;
// found a good window so break out of the while, and perhaps continue
// with the for loop
break;
}
}
// phew. we found the window, so focus it.
if (_stacked_cycling && state) {
if (!_cycling) {
// grab modifiers so we can intercept KeyReleases from them
grabModifiers();
_cycling = true;
}
// if the window is on another desktop, we can't use XSetInputFocus, since
// it doesn't imply a workspace change.
if (_stacked_raise || (t->desktop() != _active_desktop &&
t->desktop() != 0xffffffff))
t->focus(); // raise
else
t->focus(false); // don't raise
}
else {
t->focus();
}
}
void screen::cycleWorkspace(const bool forward, const int increment,
const bool loop) const {
assert(_managed);
assert(increment > 0);
unsigned int destination = _active_desktop;
for (int x = 0; x < increment; ++x) {
if (forward) {
if (destination < _num_desktops - 1)
++destination;
else if (loop)
destination = 0;
} else {
if (destination > 0)
--destination;
else if (loop)
destination = _num_desktops - 1;
}
}
if (destination != _active_desktop)
changeWorkspace(destination);
}
void screen::changeWorkspace(const int num) const {
assert(_managed);
_xatom->sendClientMessage(_root, XAtom::net_current_desktop, _root, num);
}
void screen::changeWorkspaceVert(const int num) const {
assert(_managed);
int width = 0;
int num_desktops = (signed)_num_desktops;
int active_desktop = (signed)_active_desktop;
int wnum = 0;
_config->getValue(Config::workspaceColumns, width);
if (width > num_desktops || width <= 0)
return;
// a cookie to the person that makes this pretty
if (num < 0) {
wnum = active_desktop - width;
if (wnum < 0) {
wnum = num_desktops/width * width + active_desktop;
if (wnum >= num_desktops)
wnum = num_desktops - 1;
}
}
else {
wnum = active_desktop + width;
if (wnum >= num_desktops) {
wnum = (active_desktop + width) % num_desktops - 1;
if (wnum < 0)
wnum = 0;
}
}
changeWorkspace(wnum);
}
void screen::changeWorkspaceHorz(const int num) const {
assert(_managed);
int width = 0;
int num_desktops = (signed)_num_desktops;
int active_desktop = (signed)_active_desktop;
int wnum = 0;
_config->getValue(Config::workspaceColumns, width);
if (width > num_desktops || width <= 0)
return;
if (num < 0) {
if (active_desktop % width != 0)
changeWorkspace(active_desktop - 1);
else {
wnum = active_desktop + width - 1;
if (wnum >= num_desktops)
wnum = num_desktops - 1;
}
}
else {
if (active_desktop % width != width - 1) {
wnum = active_desktop + 1;
if (wnum >= num_desktops)
wnum = num_desktops / width * width;
}
else
wnum = active_desktop - width + 1;
}
changeWorkspace(wnum);
}
void screen::grabKey(const KeyCode keyCode, const int modifierMask) const {
Display *display = _epist->getXDisplay();
int numlockMask, scrolllockMask;
_epist->getLockModifiers(numlockMask, scrolllockMask);
XGrabKey(display, keyCode, modifierMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|LockMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|scrolllockMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|numlockMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|LockMask|scrolllockMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|scrolllockMask|numlockMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|numlockMask|LockMask,
_root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, keyCode,
modifierMask|numlockMask|LockMask|scrolllockMask,
_root, True, GrabModeAsync, GrabModeAsync);
}
void screen::ungrabKey(const KeyCode keyCode, const int modifierMask) const {
Display *display = _epist->getXDisplay();
int numlockMask, scrolllockMask;
_epist->getLockModifiers(numlockMask, scrolllockMask);
XUngrabKey(display, keyCode, modifierMask, _root);
XUngrabKey(display, keyCode, modifierMask|LockMask, _root);
XUngrabKey(display, keyCode, modifierMask|scrolllockMask, _root);
XUngrabKey(display, keyCode, modifierMask|numlockMask, _root);
XUngrabKey(display, keyCode, modifierMask|LockMask|scrolllockMask, _root);
XUngrabKey(display, keyCode, modifierMask|scrolllockMask|numlockMask, _root);
XUngrabKey(display, keyCode, modifierMask|numlockMask|LockMask, _root);
XUngrabKey(display, keyCode, modifierMask|numlockMask|LockMask|
scrolllockMask, _root);
}
void screen::grabModifiers() const {
Display *display = _epist->getXDisplay();
XGrabKeyboard(display, rootWindow(), True, GrabModeAsync,
GrabModeAsync, CurrentTime);
}
void screen::ungrabModifiers() const {
Display *display = _epist->getXDisplay();
XUngrabKeyboard(display, CurrentTime);
}
bool screen::nothingIsPressed(void) const
{
char keys[32];
XQueryKeymap(_epist->getXDisplay(), keys);
for (int i = 0; i < 32; ++i) {
if (keys[i] != 0)
return false;
}
return true;
}

View file

@ -1,110 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// screen.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __screen_hh
#define __screen_hh
extern "C" {
#include "X11/Xlib.h"
}
#include <vector>
#include <string>
#include "window.hh"
#include "config.hh"
class epist;
class screen;
class XAtom;
class ScreenInfo;
class screen {
epist *_epist;
XAtom *_xatom;
int _number;
Window _root;
const ScreenInfo *_info;
std::string _wm_name;
WindowList &_clients;
WindowList::iterator &_active;
WindowList::iterator _last_active;
unsigned int _active_desktop;
unsigned int _num_desktops;
const Config *_config;
bool _managed;
bool _grabbed; // used for keygrab toggle function
bool _cycling; // used for stacked cycling
bool _stacked_cycling;
bool _stacked_raise;
XWindow *findWindow(const XEvent &e) const;
void updateNumDesktops();
void updateActiveDesktop();
void updateClientList();
void updateActiveWindow();
bool doAddWindow(Window window) const;
bool findSupportingWM();
bool isModifier(const KeyCode kc) const;
bool nothingIsPressed(void) const;
public:
screen(epist *epist, int number);
virtual ~screen();
inline Window rootWindow() const { return _root; }
inline bool managed() const { return _managed; }
inline int number() const { return _number; }
const XWindow *lastActiveWindow() const;
void processEvent(const XEvent &e);
void handleKeypress(const XEvent &e);
void handleKeyrelease(const XEvent &e);
void updateEverything();
void cycleWindow(unsigned int state, const bool forward, const int increment,
const bool allscreens = false,
const bool alldesktops = false,
const bool sameclass = false,
const std::string &classname = "");
void cycleWorkspace(const bool forward, const int increment,
const bool loop = true) const;
void changeWorkspace(const int num) const;
void changeWorkspaceVert(const int num) const;
void changeWorkspaceHorz(const int num) const;
void toggleShaded(const Window win) const;
void execCommand(const std::string &cmd) const;
void grabKey(const KeyCode keyCode, const int modifierMask) const;
void ungrabKey(const KeyCode keyCode, const int modifierMask) const;
void grabModifiers(void) const;
void ungrabModifiers(void) const;
};
#endif // __screen_hh

View file

@ -1,477 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
// window.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
using std::dec;
#include "epist.hh"
#include "screen.hh"
#include "window.hh"
#include "../../src/xatom.hh"
// defined by black/openbox
const unsigned long XWindow::PropBlackboxAttributesElements;
const unsigned long XWindow::AttribDecoration;
const unsigned long XWindow::DecorNone;
const unsigned long XWindow::DecorNormal;
XWindow::XWindow(epist *epist, screen *screen, Window window)
: _epist(epist), _screen(screen), _xatom(epist->xatom()), _window(window) {
_unmapped = false;
XSelectInput(_epist->getXDisplay(), _window,
PropertyChangeMask | StructureNotifyMask);
updateBlackboxAttributes();
updateNormalHints();
updateWMHints();
updateDimentions();
updateState();
updateDesktop();
updateTitle();
updateClass();
_epist->addWindow(this);
}
XWindow::~XWindow() {
if (! _unmapped)
XSelectInput(_epist->getXDisplay(), _window, None);
_epist->removeWindow(this);
}
void XWindow::updateDimentions() {
Window root, child;
int x, y;
unsigned int w, h, b, d;
if (XGetGeometry(_epist->getXDisplay(), _window, &root, &x, &y, &w, &h,
&b, &d) &&
XTranslateCoordinates(_epist->getXDisplay(), _window, root, x, y,
&x, &y, &child))
_rect.setRect(x, y, w, h);
else
_rect.setRect(0, 0, 1, 1);
}
void XWindow::updateBlackboxAttributes() {
unsigned long *data;
unsigned long num = PropBlackboxAttributesElements;
_decorated = true;
if (_xatom->getValue(_window,
XAtom::blackbox_attributes, XAtom::blackbox_attributes,
num, &data)) {
if (num == PropBlackboxAttributesElements)
if (data[0] & AttribDecoration)
_decorated = (data[4] != DecorNone);
delete data;
}
}
void XWindow::updateNormalHints() {
XSizeHints size;
long ret;
// defaults
_gravity = NorthWestGravity;
_inc_x = _inc_y = 1;
_base_x = _base_y = 0;
if (XGetWMNormalHints(_epist->getXDisplay(), _window, &size, &ret)) {
if (size.flags & PWinGravity)
_gravity = size.win_gravity;
if (size.flags & PBaseSize) {
_base_x = size.base_width;
_base_y = size.base_height;
}
if (size.flags & PResizeInc) {
_inc_x = size.width_inc;
_inc_y = size.height_inc;
}
}
}
void XWindow::updateWMHints() {
XWMHints *hints;
// assume a window takes input if it doesnt specify
_can_focus = True;
if ((hints = XGetWMHints(_epist->getXDisplay(), _window)) != NULL) {
if (hints->flags & InputHint)
_can_focus = hints->input;
XFree(hints);
}
}
void XWindow::updateState() {
// set the defaults
_shaded = _iconic = _max_vert = _max_horz = false;
unsigned long num = (unsigned) -1;
Atom *state;
if (! _xatom->getValue(_window, XAtom::net_wm_state, XAtom::atom,
num, &state))
return;
for (unsigned long i = 0; i < num; ++i) {
if (state[i] == _xatom->getAtom(XAtom::net_wm_state_maximized_vert))
_max_vert = true;
if (state[i] == _xatom->getAtom(XAtom::net_wm_state_maximized_horz))
_max_horz = true;
if (state[i] == _xatom->getAtom(XAtom::net_wm_state_shaded))
_shaded = true;
if (state[i] == _xatom->getAtom(XAtom::net_wm_state_hidden))
_iconic = true;
}
delete [] state;
}
void XWindow::updateDesktop() {
if (! _xatom->getValue(_window, XAtom::net_wm_desktop, XAtom::cardinal,
static_cast<unsigned long>(_desktop)))
_desktop = 0;
}
void XWindow::updateTitle() {
_title = "";
// try netwm
if (! _xatom->getValue(_window, XAtom::net_wm_name, XAtom::utf8, _title)) {
// try old x stuff
_xatom->getValue(_window, XAtom::wm_name, XAtom::ansi, _title);
}
if (_title.empty())
_title = "Unnamed";
}
void XWindow::updateClass() {
// set the defaults
_app_name = _app_class = "";
XAtom::StringVect v;
unsigned long num = 2;
if (! _xatom->getValue(_window, XAtom::wm_class, XAtom::ansi, num, v))
return;
if (num > 0) _app_name = v[0];
if (num > 1) _app_class = v[1];
}
void XWindow::processEvent(const XEvent &e) {
assert(e.xany.window == _window);
switch (e.type) {
case ConfigureNotify:
updateDimentions();
break;
case PropertyNotify:
if (e.xproperty.atom == XA_WM_NORMAL_HINTS)
updateNormalHints();
else if (e.xproperty.atom == XA_WM_HINTS)
updateWMHints();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::blackbox_attributes))
updateBlackboxAttributes();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_state))
updateState();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_desktop))
updateDesktop();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_name) ||
e.xproperty.atom == _xatom->getAtom(XAtom::wm_name))
updateTitle();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::wm_class))
updateClass();
break;
case DestroyNotify:
case UnmapNotify:
_unmapped = true;
break;
}
}
void XWindow::shade(const bool sh) const {
_xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, (sh ? 1 : 0),
_xatom->getAtom(XAtom::net_wm_state_shaded));
}
void XWindow::close() const {
_xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_close_window,
_window);
}
void XWindow::raise() const {
XRaiseWindow(_epist->getXDisplay(), _window);
}
void XWindow::lower() const {
XLowerWindow(_epist->getXDisplay(), _window);
}
void XWindow::iconify() const {
_xatom->sendClientMessage(_screen->rootWindow(), XAtom::wm_change_state,
_window, IconicState);
}
void XWindow::focus(bool raise) const {
// this will cause the window to be uniconified also
if (raise) {
_xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_active_window,
_window);
} else {
XSetInputFocus(_epist->getXDisplay(), _window, None, CurrentTime);
}
}
void XWindow::sendTo(unsigned int dest) const {
_xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_wm_desktop,
_window, dest);
}
void XWindow::move(int x, int y) const {
// get the window's decoration sizes (margins)
Strut margins;
Window win = _window, parent, root, last = None;
Window *children = 0;
unsigned int nchildren;
XWindowAttributes wattr;
while (XQueryTree(_epist->getXDisplay(), win, &root, &parent, &children,
&nchildren)) {
if (children && nchildren > 0)
XFree(children); // don't care about the children
if (! parent) // no parent!?
return;
// if the parent window is the root window, stop here
if (parent == root)
break;
last = win;
win = parent;
}
if (! (XTranslateCoordinates(_epist->getXDisplay(), last, win, 0, 0,
(int *) &margins.left,
(int *) &margins.top,
&parent) &&
XGetWindowAttributes(_epist->getXDisplay(), win, &wattr)))
return;
margins.right = wattr.width - _rect.width() - margins.left;
margins.bottom = wattr.height - _rect.height() - margins.top;
margins.left += wattr.border_width;
margins.right += wattr.border_width;
margins.top += wattr.border_width;
margins.bottom += wattr.border_width;
// this makes things work. why? i don't know. but you need them.
margins.right -= 2;
margins.bottom -= 2;
// find the frame's reference position based on the window's gravity
switch (_gravity) {
case NorthWestGravity:
x -= margins.left;
y -= margins.top;
break;
case NorthGravity:
x += (margins.left + margins.right) / 2;
y -= margins.top;
break;
case NorthEastGravity:
x += margins.right;
y -= margins.top;
case WestGravity:
x -= margins.left;
y += (margins.top + margins.bottom) / 2;
break;
case CenterGravity:
x += (margins.left + margins.right) / 2;
y += (margins.top + margins.bottom) / 2;
break;
case EastGravity:
x += margins.right;
y += (margins.top + margins.bottom) / 2;
case SouthWestGravity:
x -= margins.left;
y += margins.bottom;
break;
case SouthGravity:
x += (margins.left + margins.right) / 2;
y += margins.bottom;
break;
case SouthEastGravity:
x += margins.right;
y += margins.bottom;
break;
default:
break;
}
XMoveWindow(_epist->getXDisplay(), _window, x, y);
}
void XWindow::resizeRel(int dwidth, int dheight) const {
// resize in increments if requested by the window
unsigned int width = _rect.width(), height = _rect.height();
unsigned int wdest = width + (dwidth * _inc_x) / _inc_x * _inc_x + _base_x;
unsigned int hdest = height + (dheight * _inc_y) / _inc_y * _inc_y + _base_y;
XResizeWindow(_epist->getXDisplay(), _window, wdest, hdest);
}
void XWindow::resizeAbs(unsigned int width, unsigned int height) const {
// resize in increments if requested by the window
unsigned int wdest = width / _inc_x * _inc_x + _base_x;
unsigned int hdest = height / _inc_y * _inc_y + _base_y;
if (width > wdest) {
while (width > wdest)
wdest += _inc_x;
} else {
while (width < wdest)
wdest -= _inc_x;
}
if (height > hdest) {
while (height > hdest)
hdest += _inc_y;
} else {
while (height < hdest)
hdest -= _inc_y;
}
XResizeWindow(_epist->getXDisplay(), _window, wdest, hdest);
}
void XWindow::toggleMaximize(Max max) const {
switch (max) {
case Max_Full:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, (_max_vert == _max_horz ? 2 : 1),
_xatom->getAtom(XAtom::net_wm_state_maximized_horz),
_xatom->getAtom(XAtom::net_wm_state_maximized_vert));
break;
case Max_Horz:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, 2,
_xatom->getAtom(XAtom::net_wm_state_maximized_horz));
break;
case Max_Vert:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, 2,
_xatom->getAtom(XAtom::net_wm_state_maximized_vert));
break;
case Max_None:
assert(false); // you should not do this. it is pointless and probly a bug
break;
}
}
void XWindow::maximize(Max max) const {
switch (max) {
case Max_None:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, 0,
_xatom->getAtom(XAtom::net_wm_state_maximized_horz),
_xatom->getAtom(XAtom::net_wm_state_maximized_vert));
break;
case Max_Full:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, 1,
_xatom->getAtom(XAtom::net_wm_state_maximized_horz),
_xatom->getAtom(XAtom::net_wm_state_maximized_vert));
break;
case Max_Horz:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, 1,
_xatom->getAtom(XAtom::net_wm_state_maximized_horz));
break;
case Max_Vert:
_xatom->
sendClientMessage(_screen->rootWindow(), XAtom::net_wm_state,
_window, 1,
_xatom->getAtom(XAtom::net_wm_state_maximized_vert));
break;
}
}
void XWindow::decorate(bool d) const {
_xatom->sendClientMessage(_screen->rootWindow(),
XAtom::blackbox_change_attributes,
_window, AttribDecoration,
0, 0, 0, (d ? DecorNormal : DecorNone));
}

View file

@ -1,135 +0,0 @@
// -*- mode: C++; indent-tabs-mode: nil; -*-
// window.hh for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef __window_hh
#define __window_hh
extern "C" {
#include <X11/Xlib.h>
}
#include <list>
#include <string>
#include "../../src/util.hh"
class epist;
class screen;
class XAtom;
class XWindow {
public:
enum Max {
Max_None,
Max_Horz,
Max_Vert,
Max_Full
};
private:
// defined by black/openbox
static const unsigned long PropBlackboxAttributesElements = 9;
static const unsigned long AttribDecoration = 1 << 6;
static const unsigned long DecorNone = 0;
static const unsigned long DecorNormal = 2;
epist *_epist;
screen *_screen;
XAtom *_xatom;
Window _window;
unsigned int _desktop;
std::string _title;
std::string _app_name;
std::string _app_class;
Rect _rect;
int _inc_x, _inc_y; // resize increments
int _base_x, _base_y; // base size
int _gravity;
bool _can_focus;
// states
bool _shaded;
bool _iconic;
bool _max_vert;
bool _max_horz;
bool _decorated;
bool _unmapped;
void updateDimentions();
void updateBlackboxAttributes();
void updateNormalHints();
void updateWMHints();
void updateState();
void updateDesktop();
void updateTitle();
void updateClass();
public:
XWindow(epist *epist, screen *screen, Window window);
virtual ~XWindow();
inline screen *getScreen() const { return _screen; }
inline Window window() const { return _window; }
inline unsigned int desktop() const { return _desktop; }
inline const std::string &title() const { return _title; }
inline const std::string &appName() const { return _app_name; }
inline const std::string &appClass() const { return _app_class; }
inline bool canFocus() const { return _can_focus; }
inline bool shaded() const { return _shaded; }
inline bool iconic() const { return _iconic; }
inline bool maxVert() const { return _max_vert; }
inline bool maxHorz() const { return _max_horz; }
inline bool decorated() const { return _decorated; }
inline const Rect &area() const { return _rect; }
inline unsigned int x() const { return _rect.x(); }
inline unsigned int y() const { return _rect.y(); }
inline unsigned int width() const { return _rect.width(); }
inline unsigned int height() const { return _rect.height(); }
void processEvent(const XEvent &e);
void shade(const bool sh) const;
void close() const;
void raise() const;
void lower() const;
void iconify() const;
void focus(bool raise = true) const;
void decorate(bool d) const;
void sendTo(unsigned int dest) const;
void move(int x, int y) const;
void resizeRel(int dwidth, int dheight) const;
void resizeAbs(unsigned int width, unsigned int height) const;
void toggleMaximize(Max max) const; // i hate toggle functions
void maximize(Max max) const;
bool operator == (const XWindow &w) const { return w._window == _window; }
bool operator == (const Window &w) const { return w == _window; }
};
typedef std::list<XWindow *> WindowList;
#endif // __window_hh

File diff suppressed because it is too large Load diff

View file

@ -1,17 +0,0 @@
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#define OBRACE 257
#define EBRACE 258
#define SEMICOLON 259
#define DASH 260
#define NUMBER 261
#define QUOTES 262
#define WORD 263
#define BINDING 264
#define OPTIONS 265
#define TRUE 266
#define FALSE 267
extern YYSTYPE yylval;

View file

@ -1,153 +0,0 @@
const char *NAME = "xftlsfonts";
const char *VERSION = "1.0";
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif // HAVE_CONFIG_H
#ifndef XFT
#include <iostream>
using std::cout;
using std::endl;
int main(int, char **) {
cout << NAME << " version " << VERSION << endl;
cout << "Copyright (c) 2002, Ben Jansens <ben@orodu.net>" << endl;
cout << endl;
cout << "Openbox was built without support for Xft fonts. This utility must"
<< endl;
cout << "must be built with Xft support in order to function." << endl;
}
#else // XFT
extern "C" {
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
}
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::cout;
using std::endl;
int main(int argc, char **argv) {
if (argc > 1)
for (int i = 1; i < argc; ++i)
if (string(argv[i]) == "-help" ||
string(argv[i]) == "--help" ||
string(argv[i]) == "-version" ||
string(argv[i]) == "--version") {
cout << NAME << " version " << VERSION << endl;
cout << "Copyright (c) 2002, Ben Jansens <ben@orodu.net>" << endl;
cout << endl;
cout << "Usage: " << argv[0] << " [options]" << endl;
cout << " -style Show possible styles for each font" << endl;
cout << " -slant Show the slant for each font" << endl;
cout << " -weight Show the weight for each font" << endl;
cout << " -file Show which files contain each font" << endl;
cout << endl;
return 1;
}
Display *display = XOpenDisplay(NULL);
if (! display) {
cout << "Failed to open connection to X display\n";
return 2;
}
XftObjectSet *obj = XftObjectSetCreate();
if (! obj) {
cout << "Failed to create an XftObjectSet\n";
return 2;
}
XftObjectSetAdd(obj, XFT_FAMILY);
if (argc > 1)
for (int i = 1; i < argc; ++i) {
if (string(argv[i]) == "-style") XftObjectSetAdd(obj, XFT_STYLE);
else if (string(argv[i]) == "-file") XftObjectSetAdd(obj, XFT_FILE);
else if (string(argv[i]) == "-slant") XftObjectSetAdd(obj, XFT_SLANT);
else if (string(argv[i]) == "-weight") XftObjectSetAdd(obj, XFT_WEIGHT);
}
XftPattern *pat = XftPatternCreate();
if (! pat) {
cout << "Failed to create an XftPattern\n";
exit(2);
}
XftFontSet *set = XftListFontsPatternObjects(display, DefaultScreen(display),
pat, obj);
if (! set) {
cout << "Failed to find a matching XftFontSet\n";
exit(2);
}
XFree(pat);
XFree(obj);
for (int i = 0; i < set->nfont; ++i) {
for (int e = 0; e < set->fonts[i]->num; ++e) {
// if (string(set->fonts[i]->elts[e].object) != "family")
// continue; // i just want font family names
if (e > 0)
cout << " "; // indent after the first element
cout << set->fonts[i]->elts[e].object << ": ";
XftValueList *vallist = set->fonts[i]->elts[e].values;
bool f = true;
do {
if (f)
f = false;
else
cout << ", ";
XftValue val = vallist->value;
switch (val.type) {
case XftTypeVoid:
cout << "(void)";
break;
case XftTypeInteger:
cout << val.u.i;
break;
case XftTypeDouble:
cout << val.u.d;
break;
case XftTypeString:
cout << val.u.s;
break;
case XftTypeBool:
cout << val.u.b;
break;
#ifdef XFT_UTF8
case XftTypeMatrix:
cout << "xx(" << val.u.m->xx << ") ";
cout << "xy(" << val.u.m->xy << ") ";
cout << "yx(" << val.u.m->yx << ") ";
cout << "yy(" << val.u.m->yy << ")";
break;
#endif
}
} while ((vallist = vallist->next));
cout << endl;
}
}
cout << endl << "Found " << set->nfont << " matches." << endl;
XFree(set);
XCloseDisplay(display);
return 0;
}
#endif // XFT