rm the util directory
This commit is contained in:
parent
b683a4e0ef
commit
0afb431644
35 changed files with 0 additions and 7530 deletions
|
@ -48,8 +48,6 @@ AC_CONFIG_FILES([Makefile po/Makefile.in
|
||||||
otk/Makefile
|
otk/Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
scripts/Makefile
|
scripts/Makefile
|
||||||
util/Makefile
|
|
||||||
util/epist/Makefile
|
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
doc/doxygen/Makefile
|
doc/doxygen/Makefile
|
||||||
data/Makefile
|
data/Makefile
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
bsetroot
|
|
||||||
xftlsfonts
|
|
||||||
.deps
|
|
||||||
.libs
|
|
|
@ -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
|
|
506
util/bsetbg
506
util/bsetbg
|
@ -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
|
|
383
util/bsetroot.cc
383
util/bsetroot.cc
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,6 +0,0 @@
|
||||||
epist
|
|
||||||
Makefile.in
|
|
||||||
Makefile
|
|
||||||
.deps
|
|
||||||
epist.1
|
|
||||||
epistrc.5
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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.
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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--;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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)
|
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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]+ /* */
|
|
||||||
%%
|
|
||||||
|
|
|
@ -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); }
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
1716
util/epist/lex.yy.c
1716
util/epist/lex.yy.c
File diff suppressed because it is too large
Load diff
|
@ -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);
|
|
||||||
}
|
|
|
@ -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 = "";
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -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
|
@ -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;
|
|
|
@ -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
|
|
||||||
|
|
Loading…
Reference in a new issue