summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2010-01-24 14:35:18 +0800
committerSam Spilsbury <smspillaz@gmail.com>2010-01-24 14:35:18 +0800
commit7ab18124697a415d502701a528b1d3191be79a9a (patch)
treed289270028b1087e5155486aa960a498fb23a11e
parent8444675649f44450f1ef6805bb1e15181677b03b (diff)
downloadstackswitch-7ab18124697a415d502701a528b1d3191be79a9a.tar.gz
stackswitch-7ab18124697a415d502701a528b1d3191be79a9a.tar.bz2
Initial C++ port
-rw-r--r--CMakeLists.txt6
-rw-r--r--Makefile533
-rw-r--r--plugin.info4
-rw-r--r--src/stackswitch.cpp1440
-rw-r--r--src/stackswitch.h237
-rw-r--r--stackswitch.c1831
-rw-r--r--stackswitch.xml.in10
7 files changed, 1687 insertions, 2374 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7c39a43..97dfb92 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,5 @@
-include (CompizFusion)
+find_package (Compiz REQUIRED)
-compiz_fusion_plugin (stackswitch PLUGINDEPS text)
+include (CompizPlugin)
+
+compiz_plugin (stackswitch PLUGINDEPS composite opengl text)
diff --git a/Makefile b/Makefile
deleted file mode 100644
index d9a07cf..0000000
--- a/Makefile
+++ /dev/null
@@ -1,533 +0,0 @@
-##
-#
-# Compiz plugin Makefile
-#
-# Copyright : (C) 2007 by Dennis Kasprzyk
-# E-mail : onestone@deltatauchi.de
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-##
-
-# plugin.info file contents
-#
-# PLUGIN = foo
-# PKG_DEP = pango
-# LDFLAGS_ADD = -lGLU
-# CFLAGS_ADD = -I/usr/include/foo
-# CHK_HEADERS = compiz-cube.h
-#
-
-#load config file
-
-ECHO = `which echo`
-
-# default color settings
-color := $(shell if [ $$TERM = "dumb" ]; then $(ECHO) "no"; else $(ECHO) "yes"; fi)
-
-ifeq ($(shell if [ -f plugin.info ]; then $(ECHO) -n "found"; fi ),found)
-include plugin.info
-else
-$(error $(shell if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\033[1;31m[ERROR]\033[0m \"plugin.info\" file not found"; \
- else \
- $(ECHO) "[ERROR] \"plugin.info\" file not found"; \
- fi;))
-endif
-
-ifneq ($(shell if pkg-config --exists compiz; then $(ECHO) -n "found"; fi ),found)
-$(error $(shell if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[1;31m[ERROR]\033[0m Compiz not installed"; \
- else \
- $(ECHO) -n "[ERROR] Compiz not installed"; \
- fi))
-endif
-
-
-ifneq ($(shell if [ -n "$(PKG_DEP)" ]; then if pkg-config --exists $(PKG_DEP); then $(ECHO) -n "found"; fi; \
- else $(ECHO) -n "found"; fi ),found)
-$(error $(shell if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[1;31m[ERROR]\033[0m "; \
- else \
- $(ECHO) -n "[ERROR] "; \
- fi; \
- pkg-config --print-errors --short-errors --errors-to-stdout $(PKG_DEP); ))
-endif
-
-
-ifeq ($(BUILD_GLOBAL),true)
- PREFIX = $(shell pkg-config --variable=prefix compiz)
- CLIBDIR = $(shell pkg-config --variable=libdir compiz)
- CINCDIR = $(shell pkg-config --variable=includedir compiz)
- PKGDIR = $(CLIBDIR)/pkgconfig
- DESTDIR = $(shell pkg-config --variable=libdir compiz)/compiz
- XMLDIR = $(shell pkg-config --variable=prefix compiz)/share/compiz
- IMAGEDIR = $(shell pkg-config --variable=prefix compiz)/share/compiz
- DATADIR = $(shell pkg-config --variable=prefix compiz)/share/compiz
-else
- DESTDIR = $(HOME)/.compiz/plugins
- XMLDIR = $(HOME)/.compiz/metadata
- IMAGEDIR = $(HOME)/.compiz/images
- DATADIR = $(HOME)/.compiz/data
-endif
-
-BUILDDIR = build
-
-CC = gcc
-CPP = g++
-LIBTOOL = libtool
-INSTALL = install
-
-BCOP = `pkg-config --variable=bin bcop`
-
-CFLAGS = -g -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing `pkg-config --cflags $(PKG_DEP) compiz ` $(CFLAGS_ADD)
-LDFLAGS = `pkg-config --libs $(PKG_DEP) compiz ` $(LDFLAGS_ADD)
-
-DEFINES = -DIMAGEDIR=\"$(IMAGEDIR)\" -DDATADIR=\"$(DATADIR)\"
-
-POFILEDIR = $(shell if [ -n "$(PODIR)" ]; then $(ECHO) $(PODIR); else $(ECHO) ./po;fi )
-
-COMPIZ_HEADERS = compiz.h compiz-core.h
-COMPIZ_INC = $(shell pkg-config --variable=includedir compiz)/compiz/
-
-is-bcop-target := $(shell if [ -e $(PLUGIN).xml.in ]; then cat $(PLUGIN).xml.in | grep "useBcop=\"true\""; \
- else if [ -e $(PLUGIN).xml ]; then cat $(PLUGIN).xml | grep "useBcop=\"true\""; fi; fi)
-
-trans-target := $(shell if [ -e $(PLUGIN).xml.in -o -e $(PLUGIN).xml ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN).xml;fi )
-
-bcop-target := $(shell if [ -n "$(is-bcop-target)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN).xml; fi )
-bcop-target-src := $(shell if [ -n "$(is-bcop-target)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN)_options.c; fi )
-bcop-target-hdr := $(shell if [ -n "$(is-bcop-target)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN)_options.h; fi )
-
-gen-schemas := $(shell if [ \( -e $(PLUGIN).xml.in -o -e $(PLUGIN).xml \) -a -n "`pkg-config --variable=xsltdir compiz-gconf`" ]; then $(ECHO) true; fi )
-schema-target := $(shell if [ -n "$(gen-schemas)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN).xml; fi )
-schema-output := $(shell if [ -n "$(gen-schemas)" ]; then $(ECHO) $(BUILDDIR)/compiz-$(PLUGIN).schema; fi )
-
-ifeq ($(BUILD_GLOBAL),true)
- pkg-target := $(shell if [ -e compiz-$(PLUGIN).pc.in -a -n "$(PREFIX)" -a -d "$(PREFIX)" ]; then $(ECHO) "$(BUILDDIR)/compiz-$(PLUGIN).pc"; fi )
- hdr-install-target := $(shell if [ -e compiz-$(PLUGIN).pc.in -a -n "$(PREFIX)" -a -d "$(PREFIX)" -a -e compiz-$(PLUGIN).h ]; then $(ECHO) "compiz-$(PLUGIN).h"; fi )
-endif
-
-# find all the object files
-
-c-objs := $(patsubst %.c,%.lo,$(shell find -name '*.c' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
-c-objs += $(patsubst %.cpp,%.lo,$(shell find -name '*.cpp' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
-c-objs += $(patsubst %.cxx,%.lo,$(shell find -name '*.cxx' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
-c-objs := $(filter-out $(bcop-target-src:.c=.lo),$(c-objs))
-
-h-files := $(shell find -name '*.h' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///')
-h-files += $(bcop-target-hdr)
-h-files += $(foreach file,$(COMPIZ_HEADERS) $(CHK_HEADERS),$(shell $(ECHO) -n "$(COMPIZ_INC)$(file)"))
-
-all-c-objs := $(addprefix $(BUILDDIR)/,$(c-objs))
-all-c-objs += $(bcop-target-src:.c=.lo)
-
-# additional files
-
-data-files := $(shell find data/ -name '*' -type f 2> /dev/null | sed -e 's/data\///')
-image-files := $(shell find images/ -name '*' -type f 2> /dev/null | sed -e 's/images\///')
-
-# system include path parameter, -isystem doesn't work on old gcc's
-inc-path-param = $(shell if [ -z "`gcc --version | head -n 1 | grep ' 3'`" ]; then $(ECHO) "-isystem"; else $(ECHO) "-I"; fi)
-
-# Tests
-ifeq ($(shell if [ -n "$(is-bcop-target)" -a -z "$(BCOP)" ]; then $(ECHO) -n "error"; fi ),error)
-$(error $(shell if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[1;31m[ERROR]\033[0m BCOP not installed but is needed to build plugin"; \
- else \
- $(ECHO) -n "[ERROR] BCOP not installed but is needed to build plugin"; \
- fi))
-endif
-
-ifeq ($(shell if [ "x$(BUILD_GLOBAL)" != "xtrue" -a -e compiz-$(PLUGIN).pc.in ]; then $(ECHO) -n "warn"; fi ),warn)
-$(warning $(shell if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[1;31m[WARNING]\033[0m This plugin might be needed by other plugins. Install it with \"BUILD_GLOBAL=true sudo make install\" "; \
- else \
- $(ECHO) -n "[WARNING] This plugin might be needed by other plugins. Install it with \"BUILD_GLOBAL=true sudo make install\""; \
- fi))
-endif
-
-#
-# Do it.
-#
-
-.PHONY: $(BUILDDIR) build-dir trans-target bcop-build pkg-creation schema-creation c-build-objs c-link-plugin
-
-all: $(BUILDDIR) build-dir trans-target bcop-build pkg-creation schema-creation c-build-objs c-link-plugin
-
-trans-build: $(trans-target)
-
-bcop-build: $(bcop-target-hdr) $(bcop-target-src)
-
-schema-creation: $(schema-output)
-
-c-build-objs: $(all-c-objs)
-
-c-link-plugin: $(BUILDDIR)/lib$(PLUGIN).la
-
-pkg-creation: $(pkg-target)
-
-#
-# Create build directory
-#
-
-$(BUILDDIR) :
- @mkdir -p $(BUILDDIR)
-
-$(DESTDIR) :
- @mkdir -p $(DESTDIR)
-
-#
-# fallback if xml.in doesn't exists
-#
-$(BUILDDIR)/%.xml: %.xml
- @cp $< $@
-
-#
-# Translating
-#
-$(BUILDDIR)/%.xml: %.xml.in
- @if [ -d $(POFILEDIR) ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mtranslate \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "translate $< -> $@"; \
- fi; \
- intltool-merge -x -u $(POFILEDIR) $< $@ > /dev/null; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mtranslate : \033[34m$< -> $@\033[0m"; \
- fi; \
- else \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mconvert \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "convert $< -> $@"; \
- fi; \
- cat $< | sed -e 's;<_;<;g' -e 's;</_;</;g' > $@; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mconvert : \033[34m$< -> $@\033[0m"; \
- fi; \
- fi
-
-#
-# BCOP'ing
-
-$(BUILDDIR)/%_options.h: $(BUILDDIR)/%.xml
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mbcop'ing \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "bcop'ing $< -> $@"; \
- fi
- @$(BCOP) --header=$@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mbcop'ing : \033[34m$< -> $@\033[0m"; \
- fi
-
-$(BUILDDIR)/%_options.c: $(BUILDDIR)/%.xml
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mbcop'ing \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "bcop'ing $< -> $@"; \
- fi
- @$(BCOP) --source=$@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mbcop'ing : \033[34m$< -> $@\033[0m"; \
- fi
-
-#
-# Schema generation
-
-$(BUILDDIR)/compiz-%.schema: $(BUILDDIR)/%.xml
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mschema'ing\033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "schema'ing $< -> $@"; \
- fi
- @xsltproc `pkg-config --variable=xsltdir compiz-gconf`/schemas.xslt $< > $@
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mschema : \033[34m$< -> $@\033[0m"; \
- fi
-
-#
-# pkg config file generation
-
-$(BUILDDIR)/compiz-%.pc: compiz-%.pc.in
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mpkgconfig \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "pkgconfig $< -> $@"; \
- fi
- @COMPIZREQUIRES=`cat $(PKGDIR)/compiz.pc | grep Requires | sed -e 's;Requires: ;;g'`; \
- COMPIZCFLAGS=`cat $(PKGDIR)/compiz.pc | grep Cflags | sed -e 's;Cflags: ;;g'`; \
- sed -e 's;@prefix@;$(PREFIX);g' -e 's;\@libdir@;$(CLIBDIR);g' \
- -e 's;@includedir@;$(CINCDIR);g' -e 's;\@VERSION@;0.0.1;g' \
- -e "s;@COMPIZ_REQUIRES@;$$COMPIZREQUIRES;g" \
- -e "s;@COMPIZ_CFLAGS@;$$COMPIZCFLAGS;g" $< > $@;
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mpkgconfig : \033[34m$< -> $@\033[0m"; \
- fi
-
-#
-# Compiling
-#
-
-$(BUILDDIR)/%.lo: %.c $(h-files)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "compiling $< -> $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=compile $(CC) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
- fi
-
-$(BUILDDIR)/%.lo: $(BUILDDIR)/%.c $(h-files)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "compiling $< -> $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=compile $(CC) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
- fi
-
-$(BUILDDIR)/%.lo: %.cpp $(h-files)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "compiling $< -> $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=compile $(CPP) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
- fi
-
-$(BUILDDIR)/%.lo: %.cxx $(h-files)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "compiling $< -> $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=compile $(CPP) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
- fi
-
-#
-# Linking
-#
-
-cxx-rpath-prefix := -Wl,-rpath,
-
-$(BUILDDIR)/lib$(PLUGIN).la: $(all-c-objs)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mlinking \033[0m: \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "linking : $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=link $(CC) $(LDFLAGS) -rpath $(DESTDIR) -o $@ $(all-c-objs)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mlinking : \033[34m$@\033[0m"; \
- fi
-
-
-clean:
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e -n "\033[0;1;5mremoving \033[0m: \033[0;31m./$(BUILDDIR)\033[0m"; \
- else \
- $(ECHO) "removing : ./$(BUILDDIR)"; \
- fi
- @rm -rf $(BUILDDIR)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mremoving : \033[34m./$(BUILDDIR)\033[0m"; \
- fi
-
-
-install: $(DESTDIR) all
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(DESTDIR)/lib$(PLUGIN).so\033[0m"; \
- else \
- $(ECHO) "install : $(DESTDIR)/lib$(PLUGIN).so"; \
- fi
- @mkdir -p $(DESTDIR)
- @$(INSTALL) $(BUILDDIR)/.libs/lib$(PLUGIN).so $(DESTDIR)/lib$(PLUGIN).so
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(DESTDIR)/lib$(PLUGIN).so\033[0m"; \
- fi
- @if [ -e $(BUILDDIR)/$(PLUGIN).xml ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(XMLDIR)/$(PLUGIN).xml\033[0m"; \
- else \
- $(ECHO) "install : $(XMLDIR)/$(PLUGIN).xml"; \
- fi; \
- mkdir -p $(XMLDIR); \
- $(INSTALL) $(BUILDDIR)/$(PLUGIN).xml $(XMLDIR)/$(PLUGIN).xml; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(XMLDIR)/$(PLUGIN).xml\033[0m"; \
- fi; \
- fi
- @if [ -n "$(hdr-install-target)" ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(CINCDIR)/compiz/$(hdr-install-target)\033[0m"; \
- else \
- $(ECHO) "install : $(CINCDIR)/compiz/$(hdr-install-target)"; \
- fi; \
- $(INSTALL) --mode=u=rw,go=r,a-s $(hdr-install-target) $(CINCDIR)/compiz/$(hdr-install-target); \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(CINCDIR)/compiz/$(hdr-install-target)\033[0m"; \
- fi; \
- fi
- @if [ -n "$(pkg-target)" ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(PKGDIR)/compiz-$(PLUGIN).pc\033[0m"; \
- else \
- $(ECHO) "install : $(PKGDIR)/compiz-$(PLUGIN).pc"; \
- fi; \
- $(INSTALL) --mode=u=rw,go=r,a-s $(pkg-target) $(PKGDIR)/compiz-$(PLUGIN).pc; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(PKGDIR)/compiz-$(PLUGIN).pc\033[0m"; \
- fi; \
- fi
- @if [ -n "$(schema-output)" -a -e "$(schema-output)" ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(schema-output)\033[0m"; \
- else \
- $(ECHO) "install : $(schema-output)"; \
- fi; \
- if [ "x$(USER)" = "xroot" ]; then \
- GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source` \
- gconftool-2 --makefile-install-rule $(schema-output) > /dev/null; \
- else \
- gconftool-2 --install-schema-file=$(schema-output) > /dev/null; \
- fi; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(schema-output)\033[0m"; \
- fi; \
- fi
- @if [ -n "$(data-files)" ]; then \
- mkdir -p $(DATADIR); \
- for FILE in $(data-files); do \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(DATADIR)/$$FILE\033[0m"; \
- else \
- $(ECHO) "install : $(DATADIR)/$$FILE"; \
- fi; \
- FILEDIR="$(DATADIR)/`dirname "$$FILE"`"; \
- mkdir -p "$$FILEDIR"; \
- $(INSTALL) --mode=u=rw,go=r,a-s data/$$FILE $(DATADIR)/$$FILE; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(DATADIR)/$$FILE\033[0m"; \
- fi; \
- done \
- fi
- @if [ -n "$(image-files)" ]; then \
- mkdir -p $(IMAGEDIR); \
- for FILE in $(image-files); do \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5minstall \033[0m: \033[0;31m$(IMAGEDIR)/$$FILE\033[0m"; \
- else \
- $(ECHO) "install : $(IMAGEDIR)/$$FILE"; \
- fi; \
- FILEDIR="$(IMAGEDIR)/`dirname "$$FILE"`"; \
- mkdir -p "$$FILEDIR"; \
- $(INSTALL) --mode=u=rw,go=r,a-s images/$$FILE $(IMAGEDIR)/$$FILE; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0minstall : \033[34m$(IMAGEDIR)/$$FILE\033[0m"; \
- fi; \
- done \
- fi
-
-uninstall:
- @if [ -e $(DESTDIR)/lib$(PLUGIN).so ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(DESTDIR)/lib$(PLUGIN).so\033[0m"; \
- else \
- $(ECHO) "uninstall : $(DESTDIR)/lib$(PLUGIN).so"; \
- fi; \
- rm -f $(DESTDIR)/lib$(PLUGIN).so; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(DESTDIR)/lib$(PLUGIN).so\033[0m"; \
- fi; \
- fi
- @if [ -e $(XMLDIR)/$(PLUGIN).xml ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(XMLDIR)/$(PLUGIN).xml\033[0m"; \
- else \
- $(ECHO) "uninstall : $(XMLDIR)/$(PLUGIN).xml"; \
- fi; \
- rm -f $(XMLDIR)/$(PLUGIN).xml; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(XMLDIR)/$(PLUGIN).xml\033[0m"; \
- fi; \
- fi
- @if [ -n "$(hdr-install-target)" -a -e $(CINCDIR)/compiz/$(hdr-install-target) ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(CINCDIR)/compiz/$(hdr-install-target)\033[0m"; \
- else \
- $(ECHO) "uninstall : $(CINCDIR)/compiz/$(hdr-install-target)"; \
- fi; \
- rm -f $(CINCDIR)/compiz/$(hdr-install-target); \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(CINCDIR)/compiz/$(hdr-install-target)\033[0m"; \
- fi; \
- fi
- @if [ -n "$(pkg-target)" -a -e $(PKGDIR)/compiz-$(PLUGIN).pc ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(PKGDIR)/compiz-$(PLUGIN).pc\033[0m"; \
- else \
- $(ECHO) "uninstall : $(PKGDIR)/compiz-$(PLUGIN).pc"; \
- fi; \
- rm -f $(PKGDIR)/compiz-$(PLUGIN).pc; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(PKGDIR)/compiz-$(PLUGIN).pc\033[0m"; \
- fi; \
- fi
- @if [ -n "$(schema-output)" -a -e "$(schema-output)" -a 'x$(USER)' = 'xroot' ]; then \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(schema-output)\033[0m"; \
- else \
- $(ECHO) "uninstall : $(schema-output)"; \
- fi; \
- GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source` \
- gconftool-2 --makefile-uninstall-rule $(schema-output) > /dev/null; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(schema-output)\033[0m"; \
- fi; \
- fi
- @if [ -n "$(data-files)" ]; then \
- for FILE in $(data-files); do \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(DATADIR)/$$FILE\033[0m"; \
- else \
- $(ECHO) "uninstall : $(DATADIR)/$$FILE"; \
- fi; \
- rm -f $(DATADIR)/$$FILE; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(DATADIR)/$$FILE\033[0m"; \
- fi; \
- done \
- fi
- @if [ -n "$(image-files)" ]; then \
- for FILE in $(image-files); do \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5muninstall \033[0m: \033[0;31m$(IMAGEDIR)/$$FILE\033[0m"; \
- else \
- $(ECHO) "uninstall : $(IMAGEDIR)/$$FILE"; \
- fi; \
- rm -f $(IMAGEDIR)/$$FILE; \
- if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0muninstall : \033[34m$(IMAGEDIR)/$$FILE\033[0m"; \
- fi; \
- done \
- fi
diff --git a/plugin.info b/plugin.info
deleted file mode 100644
index e851ab0..0000000
--- a/plugin.info
+++ /dev/null
@@ -1,4 +0,0 @@
-PLUGIN = stackswitch
-PKG_DEP = compiz-text
-CHK_HEADERS = compiz-text.h
-
diff --git a/src/stackswitch.cpp b/src/stackswitch.cpp
new file mode 100644
index 0000000..34cc3c8
--- /dev/null
+++ b/src/stackswitch.cpp
@@ -0,0 +1,1440 @@
+/*
+ *
+ * Compiz stackswitch switcher plugin
+ *
+ * stackswitch.c
+ *
+ * Copyright : (C) 2007 by Danny Baumann
+ * E-mail : maniac@opencompositing.org
+ *
+ * Based on scale.c and switcher.c:
+ * Copyright : (C) 2007 David Reveman
+ * E-mail : davidr@novell.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "stackswitch.h"
+
+COMPIZ_PLUGIN_20090315 (stackswitch, StackswitchPluginVTable);
+
+bool textAvailable;
+
+bool
+StackswitchWindow::isStackswitchable ()
+{
+ STACKSWITCH_SCREEN (screen);
+
+ if (window->overrideRedirect ())
+ return false;
+
+ if (window->wmType () & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
+ return false;
+
+ if (!window->mapNum () || window->invisible ())
+ {
+ if (ss->optionGetMinimized ())
+ {
+ if (!window->minimized () && !window->inShowDesktopMode () && !window->shaded ())
+ return false;
+ }
+ else
+ return false;
+ }
+
+ if (ss->mType == StackswitchScreen::TypeNormal)
+ {
+ if (!window->mapNum () || window->invisible ())
+ {
+ if (window->serverX () + window->width () <= 0 ||
+ window->serverY () + window->height () <= 0 ||
+ window->serverX () >= screen->width () ||
+ window->serverY () >= screen->height ())
+ return false;
+ }
+ else
+ {
+ if (!window->focus ())
+ return false;
+ }
+ }
+ else if (ss->mType == StackswitchScreen::TypeGroup &&
+ ss->mClientLeader != window->clientLeader () &&
+ ss->mClientLeader != window->id ())
+ {
+ return false;
+ }
+
+ if (window->state () & CompWindowStateSkipTaskbarMask)
+ return false;
+
+ if (!ss->mCurrentMatch.evaluate (window))
+ return false;
+
+ return true;
+}
+
+void
+StackswitchScreen::renderWindowTitle ()
+{
+ CompText::Attrib tA;
+ int ox1, ox2, oy1, oy2;
+ bool showViewport;
+
+ if (!textAvailable)
+ return;
+
+ if (!optionGetWindowTitle ())
+ return;
+
+ CompRect output = screen->getCurrentOutputExtents ();
+
+ ox1 = output.x ();
+ oy1 = output.y ();
+ ox2 = output.x2 ();
+ oy2 = output.y2 ();
+
+ /* 75% of the output device as maximum width */
+ tA.maxWidth = (ox2 - ox1) * 3 / 4;
+ tA.maxHeight = 100;
+
+ tA.family = "Sans";
+ tA.size = optionGetTitleFontSize ();
+ tA.color[0] = optionGetTitleFontColorRed ();
+ tA.color[1] = optionGetTitleFontColorGreen ();
+ tA.color[2] = optionGetTitleFontColorBlue ();
+ tA.color[3] = optionGetTitleFontColorAlpha ();
+
+ tA.flags = CompText::WithBackground | CompText::Ellipsized;
+ if (optionGetTitleFontBold ())
+ tA.flags |= CompText::StyleBold;
+
+ tA.bgHMargin = 15;
+ tA.bgVMargin = 15;
+ tA.bgColor[0] = optionGetTitleBackColorRed ();
+ tA.bgColor[1] = optionGetTitleBackColorGreen ();
+ tA.bgColor[2] = optionGetTitleBackColorBlue ();
+ tA.bgColor[3] = optionGetTitleBackColorAlpha ();
+
+ showViewport = mType == StackswitchScreen::TypeAll;
+ mText.renderWindowTitle (mSelectedWindow, showViewport, tA);
+}
+
+void
+StackswitchScreen::drawWindowTitle (GLMatrix &transform,
+ CompWindow *w)
+{
+ GLboolean wasBlend;
+ GLint oldBlendSrc, oldBlendDst;
+ GLMatrix wTransform (transform), mvp;
+ float x, fY, tx, ix, width, height;
+ int ox1, ox2, oy1, oy2;
+ GLTexture::Matrix m;
+ GLVector v;
+ GLTexture *icon;
+
+ STACKSWITCH_WINDOW (w);
+
+ CompRect output = screen->getCurrentOutputExtents ();
+
+ ox1 = output.x ();
+ oy1 = output.y ();
+ ox2 = output.x2 ();
+ oy2 = output.y2 ();
+
+ width = mText.getWidth ();
+ height = mText.getHeight ();
+
+ x = ox1 + ((ox2 - ox1) / 2);
+ tx = x - (mText.getWidth () / 2);
+
+ switch (optionGetTitleTextPlacement ())
+ {
+ case StackswitchOptions::TitleTextPlacementOnThumbnail:
+ {
+ GLVector v (w->x () + (w->width () / 2.0),
+ w->y () + (w->width () / 2.0),
+ 0.0f,
+ 1.0f);
+ GLMatrix pm (gScreen->projectionMatrix ());
+
+ wTransform.scale (1.0, 1.0, 1.0 / screen->height ());
+ wTransform.translate (sw->mTx, sw->mTy, 0.0f);
+ wTransform.rotate (-mRotation, 1.0, 0.0, 0.0);
+ wTransform.scale (sw->mScale, sw->mScale, 1.0);
+ wTransform.translate (w->input ().left, 0.0 -(w->height () + w->input ().bottom), 0.0f);
+ wTransform.translate (-w->x (), -w->y (), 0.0f);
+
+ mvp = pm * wTransform;;
+ v = mvp * v;
+ v.homogenize ();
+
+ x = (v[GLVector::x] + 1.0) * (ox2 - ox1) * 0.5;
+ fY = (v[GLVector::y] - 1.0) * (oy2 - oy1) * -0.5;
+
+ x += ox1;
+ fY += oy1;
+
+ tx = MAX (ox1, x - (width / 2.0));
+ if (tx + width > ox2)
+ tx = ox2 - width;
+ break;
+ }
+ case TitleTextPlacementCenteredOnScreen:
+ fY = oy1 + ((oy2 - oy1) / 2) + (height / 2);
+ break;
+ case TitleTextPlacementAbove:
+ case TitleTextPlacementBelow:
+ {
+ CompRect workArea;
+ workArea = screen->getWorkareaForOutput (screen->currentOutputDev ().id ());
+
+ if (optionGetTitleTextPlacement () ==
+ TitleTextPlacementAbove)
+ fY = oy1 + workArea.y () + height;
+ else
+ fY = oy1 + workArea.y () + workArea.height () - 96;
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+
+ tx = floor (tx);
+ fY = floor (fY);
+
+ glGetIntegerv (GL_BLEND_SRC, &oldBlendSrc);
+ glGetIntegerv (GL_BLEND_DST, &oldBlendDst);
+
+ wasBlend = glIsEnabled (GL_BLEND);
+ if (!wasBlend)
+ glEnable (GL_BLEND);
+
+ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glColor4f (1.0, 1.0, 1.0, 1.0);
+
+ icon = sw->gWindow->getIcon (96, 96);
+ if (!icon)
+ icon = gScreen->defaultIcon ();
+
+ if (icon && (icon->name ()))
+ {
+ int off;
+
+ ix = x - (icon->width () / 2.0);
+ ix = floor (ix);
+
+ icon->enable (GLTexture::Good);
+
+ m = icon->matrix ();
+
+ glColor4f (0.0, 0.0, 0.0, 0.1);
+
+ for (off = 0; off < 6; off++)
+ {
+ glBegin (GL_QUADS);
+
+ glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0));
+ glVertex2f (ix - off, fY - off);
+ glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, icon->height ()));
+ glVertex2f (ix - off, fY + icon->height () + off);
+ glTexCoord2f (COMP_TEX_COORD_X (m, icon->width ()), COMP_TEX_COORD_Y (m, icon->height ()));
+ glVertex2f (ix + icon->width () + off, fY + icon->height () + off);
+ glTexCoord2f (COMP_TEX_COORD_X (m, icon->width ()), COMP_TEX_COORD_Y (m, 0));
+ glVertex2f (ix + icon->width () + off, fY - off);
+
+ glEnd ();
+ }
+
+ glColor4f (1.0, 1.0, 1.0, 1.0);
+
+ glBegin (GL_QUADS);
+
+ glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0));
+ glVertex2f (ix, fY);
+ glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, icon->height ()));
+ glVertex2f (ix, fY + icon->height ());
+ glTexCoord2f (COMP_TEX_COORD_X (m, icon->width ()), COMP_TEX_COORD_Y (m, icon->height ()));
+ glVertex2f (ix + icon->width (), fY + icon->height ());
+ glTexCoord2f (COMP_TEX_COORD_X (m, icon->width ()), COMP_TEX_COORD_Y (m, 0));
+ glVertex2f (ix + icon->width (), fY);
+
+ glEnd ();
+
+ icon->disable ();
+ }
+
+ mText.draw (tx, fY, 1.0f);
+ #if 0
+ m = &textData->texture->matrix;
+
+ glBegin (GL_QUADS);
+
+ glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0));
+ glVertex2f (tx, fY - height);
+ glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, height));
+ glVertex2f (tx, fY);
+ glTexCoord2f (COMP_TEX_COORD_X (m, width), COMP_TEX_COORD_Y (m, height));
+ glVertex2f (tx + width, fY);
+ glTexCoord2f (COMP_TEX_COORD_X (m, width), COMP_TEX_COORD_Y (m, 0));
+ glVertex2f (tx + width, fY - height);
+
+ glEnd ();
+
+ disableTexture (s, textData->texture);
+ #endif
+ glColor4usv (defaultColor);
+
+ if (!wasBlend)
+ glDisable (GL_BLEND);
+ glBlendFunc (oldBlendSrc, oldBlendDst);
+}
+
+bool
+StackswitchWindow::glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ unsigned int mask)
+{
+ bool status;
+
+ STACKSWITCH_SCREEN (screen);
+
+ if (ss->mState != StackswitchScreen::StateNone)
+ {
+ GLWindowPaintAttrib sAttrib (attrib);
+ bool scaled = false;
+ float rotation;
+
+ if (window->mapNum ())
+ {
+ if (!gWindow->textures ().empty ())
+ gWindow->bind ();
+ }
+
+ if (mAdjust || mSlot)
+ {
+ scaled = (mAdjust && ss->mState != StackswitchScreen::StateSwitching) ||
+ (mSlot && ss->mPaintingSwitcher);
+ mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
+ }
+ else if (ss->mState != StackswitchScreen::StateIn)
+ {
+ if (ss->optionGetDarkenBack ())
+ {
+ /* modify brightness of the other windows */
+ sAttrib.brightness = sAttrib.brightness / 2;
+ }
+ }
+
+ status = gWindow->glPaint (sAttrib, transform, region, mask);
+
+ if (ss->optionGetInactiveRotate ())
+ rotation = MIN (mRotation, ss->mRotation);
+ else
+ rotation = ss->mRotation;
+
+ if (scaled && gWindow->textures ().size ())
+ {
+ GLFragment::Attrib fragment (gWindow->lastPaintAttrib ());
+ GLMatrix wTransform (transform);
+
+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
+ return false;
+
+ if (mSlot)
+ {
+ if (window->id () != ss->mSelectedWindow)
+ fragment.setOpacity ((float)fragment.getOpacity () *
+ ss->optionGetInactiveOpacity () / 100);
+ }
+
+ if (window->alpha () || fragment.getOpacity () != OPAQUE)
+ mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+
+ wTransform.scale (1.0, 1.0, 1.0 / screen->height ());
+ wTransform.translate (mTx, mTy, 0.0f);
+
+ wTransform.rotate (-rotation, 1.0, 0.0, 0.0);
+ wTransform.scale (mScale, mScale, 1.0);
+
+ wTransform.translate (window->input ().left, 0.0 -(window->height () + window->input ().bottom), 0.0f);
+ wTransform.translate (-window->x (), -window->y (), 0.0f);
+ glPushMatrix ();
+ glLoadMatrixf (wTransform.getMatrix ());
+
+ gWindow->glDraw (wTransform, fragment, region, mask |
+ PAINT_WINDOW_TRANSFORMED_MASK);
+
+ glPopMatrix ();
+ }
+
+ if (scaled && !gWindow->textures ().size ())
+ {
+ GLTexture *icon;
+
+ icon = gWindow->getIcon (96, 96);
+ if (!icon)
+ icon = ss->gScreen->defaultIcon ();
+
+ if (icon && (icon->name ()))
+ {
+ CompRegion iconReg (0, 0, icon->width (), icon->height ());
+ GLTexture::Matrix matrix;
+ GLTexture::MatrixList matl;
+ float scale;
+
+ scale = MIN (window->width () / icon->width (),
+ window->height () / icon->height ());
+ scale *= mScale;
+
+ mask |= PAINT_WINDOW_BLEND_MASK;
+
+ /* if we paint the icon for a minimized window, we need
+ to force the usage of a good texture filter */
+ if (!gWindow->textures ().size ())
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+
+ matrix = icon->matrix ();
+ matl.push_back (matrix);
+
+ gWindow->geometry ().vCount =
+ gWindow->geometry ().indexCount = 0;
+ gWindow->glAddGeometry (matl, iconReg, infiniteRegion);
+
+ if (gWindow->geometry ().vCount)
+ {
+ GLMatrix wTransform (transform);
+
+ if (!gWindow->textures ().size ())
+ sAttrib.opacity = gWindow->paintAttrib ().opacity;
+
+ GLFragment::Attrib fragment (sAttrib);
+
+ wTransform.scale (1.0, 1.0, 1.0 / screen->height ());
+ wTransform.translate (mTx, mTy, 0.0f);
+
+ wTransform.rotate (-rotation, 1.0, 0.0, 0.0);
+ wTransform.scale (scale, scale, 1.0);
+
+ wTransform.translate (0.0, -icon->height (), 0.0f);
+
+ glPushMatrix ();
+ glLoadMatrixf (wTransform.getMatrix ());
+
+ gWindow->glDrawTexture (icon, fragment, mask);
+
+ glPopMatrix ();
+ }
+ }
+ }
+ }
+ else
+ {
+ status = gWindow->glPaint (attrib, transform, region, mask);
+ }
+
+ return status;
+}
+
+bool
+StackswitchWindow::compareWindows (CompWindow *w1,
+ CompWindow *w2)
+{
+ if (w1->mapNum () && !w2->mapNum ())
+ return false;
+
+ if (w2->mapNum () && !w1->mapNum ())
+ return true;
+
+ if (w2->activeNum () - w1->activeNum ())
+ return true;
+ else
+ return false;
+}
+
+bool
+StackswitchWindow::compareStackswitchWindowDepth (StackswitchDrawSlot *a1,
+ StackswitchDrawSlot *a2)
+{
+ StackswitchSlot *s1 = *(a1->slot);
+ StackswitchSlot *s2 = *(a2->slot);
+
+ if (s1->y < s2->y)
+ return true;
+ else if (s1->y > s2->y)
+ return false;
+ else
+ {
+ CompWindow *w1 = a1->w;
+ CompWindow *w2 = a2->w;
+
+ STACKSWITCH_SCREEN (screen);
+ if (w1->id () == ss->mSelectedWindow)
+ return false;
+ else if (w2->id () == ss->mSelectedWindow)
+ return true;
+ else
+ return false;
+ }
+}
+
+bool
+StackswitchScreen::layoutThumbs ()
+{
+ int index;
+ int ww, wh;
+ float xScale, yScale;
+ int ox1, ox2, oy1, oy2;
+ float swi = 0.0, oh, rh, ow;
+ int cols, rows, col = 0, row = 0, r, c;
+ int cindex, ci, gap, hasActive = 0;
+ bool exit;
+
+ if ((mState == StateNone) || (mState == StateIn))
+ return false;
+
+ CompRect output = screen->getCurrentOutputExtents ();
+
+ ox1 = output.x ();
+ oy1 = output.y ();
+ ox2 = output.x2 ();
+ oy2 = output.y2 ();
+ ow = (float)(ox2 - ox1) * 0.9;
+
+ foreach (CompWindow *w, mWindows)
+ {
+ ww = w->width () + w->input ().left + w->input ().right;
+ wh = w->height () + w->input ().top + w->input ().bottom;
+
+ swi += ((float)ww / (float)wh) * (ow / (float)(oy2 - oy1));
+ }
+
+ cols = ceil (sqrtf (swi));
+
+ swi = 0.0;
+ foreach (CompWindow *w, mWindows)
+ {
+ ww = w->width () + w->input ().left + w->input ().right;
+ wh = w->height () + w->input ().top + w->input ().bottom;
+
+ swi += (float)ww / (float)wh;
+
+ if (swi > cols)
+ {
+ row++;
+ swi = (float)ww / (float)wh;
+ col = 0;
+ }
+
+ col++;
+ }
+ rows = row + 1;
+
+ oh = ow / cols;
+ oh *= (float)(oy2 - oy1) / (float)(oy2 - oy1);
+
+ rh = ((float)(oy2 - oy1) * 0.8) / rows;
+
+ index = 0;
+ foreach (CompWindow *w, mWindows)
+ {
+ StackswitchDrawSlot *dSlot;
+ STACKSWITCH_WINDOW (w);
+
+ if (!sw->mSlot)
+ sw->mSlot = new StackswitchSlot;
+
+ if (!sw->mSlot)
+ return false;
+
+ dSlot = new StackswitchDrawSlot;
+
+ mDrawSlots.at (index) = dSlot;
+
+ mDrawSlots.at (index)->w = w;
+ mDrawSlots.at (index)->slot = &sw->mSlot;
+
+ index++;
+ }
+
+ index = 0;
+
+ for (r = 0; r < rows && index < mWindows.size (); r++)
+ {
+ CompWindow *w;
+ c = 0;
+ swi = 0.0;
+ cindex = index;
+ exit = false;
+ while (index < mWindows.size () && !exit)
+ {
+ w = mWindows.at (index);
+
+ STACKSWITCH_WINDOW (w);
+ sw->mSlot->x = ox1 + swi;
+ sw->mSlot->y = oy2 - (rh * r) - ((oy2 - oy1) * 0.1);
+
+
+ ww = w->width () + w->input ().left + w->input ().right;
+ wh = w->height () + w->input ().top + w->input ().bottom;
+
+ if (ww > ow)
+ xScale = ow / (float) ww;
+ else
+ xScale = 1.0f;
+
+ if (wh > oh)
+ yScale = oh / (float) wh;
+ else
+ yScale = 1.0f;
+
+ sw->mSlot->scale = MIN (xScale, yScale);
+
+ if (swi + (ww * sw->mSlot->scale) > ow && cindex != index)
+ {
+ exit = true;
+ continue;
+ }
+
+ if (w->id () == mSelectedWindow)
+ hasActive = 1;
+ swi += ww * sw->mSlot->scale;
+
+ c++;
+ index++;
+ }
+
+ gap = ox2 - ox1 - swi;
+ gap /= c + 1;
+
+ index = cindex;
+ ci = 1;
+ while (ci <= c)
+ {
+ w = mWindows.at (index);
+
+ STACKSWITCH_WINDOW (w);
+ sw->mSlot->x += ci * gap;
+
+ if (hasActive == 0)
+ sw->mSlot->y += sqrt(2 * oh * oh) - rh;
+
+ ci++;
+ index++;
+ }
+
+ if (hasActive == 1)
+ hasActive++;
+ }
+
+ /* sort the draw list so that the windows with the
+ lowest Y value (the windows being farest away)
+ are drawn first */
+ sort (mDrawSlots.begin (), mDrawSlots.end (),
+ StackswitchWindow::compareStackswitchWindowDepth);
+
+ return true;
+}
+
+void
+StackswitchWindow::addToList ()
+{
+ STACKSWITCH_SCREEN (screen);
+
+ ss->mWindows.push_back (window);
+ ss->mDrawSlots.resize (ss->mWindows.size ());
+}
+
+bool
+StackswitchScreen::updateWindowList ()
+{
+ sort (mWindows.begin (), mWindows.end (), StackswitchWindow::compareWindows);
+
+ return layoutThumbs ();
+}
+
+
+bool
+StackswitchScreen::createWindowList ()
+{
+ foreach (CompWindow *w, screen->windows ())
+ {
+ STACKSWITCH_WINDOW (w);
+ if (sw->isStackswitchable ())
+ {
+ STACKSWITCH_WINDOW (w);
+
+ sw->addToList ();
+ sw->mAdjust = true;
+ }
+ }
+
+ return updateWindowList ();
+}
+
+void
+StackswitchScreen::switchToWindow (bool toNext)
+{
+ CompWindow *w = NULL, *itwin;
+ std::vector <CompWindow *>::iterator it;
+
+ if (!mGrabIndex)
+ return;
+
+ foreach (itwin, screen->windows ())
+ {
+ if (itwin->id () == mSelectedWindow)
+ break;
+ }
+
+ it = std::find (mWindows.begin (), mWindows.end (), itwin);
+
+ if (it == mWindows.end ())
+ return;
+
+ if (toNext)
+ {
+ it++;
+ if (it == mWindows.end ())
+ w = mWindows.front ();
+ else
+ w = *it;
+ }
+ else
+ {
+ if (it == mWindows.begin ())
+ w = mWindows.back ();
+ else
+ {
+ it--;
+ w = *it;
+ }
+ }
+
+ if (w)
+ {
+ Window old = mSelectedWindow;
+
+ mSelectedWindow = w->id ();
+ if (old != w->id ())
+ {
+ mRotateAdjust = true;
+ mMoreAdjust = true;
+ foreach (CompWindow *win, screen->windows ())
+ {
+ STACKSWITCH_WINDOW (win);
+ sw->mAdjust = true;
+ }
+
+ cScreen->damageScreen ();
+ renderWindowTitle ();
+ }
+ }
+}
+
+int
+StackswitchScreen::countWindows ()
+{
+ int count = 0;
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ STACKSWITCH_WINDOW (w);
+
+ if (sw->isStackswitchable ())
+ count++;
+ }
+
+ return count;
+}
+
+int
+StackswitchScreen::adjustStackswitchRotation (float chunk)
+{
+ float dx, adjust, amount, rot;
+
+ if (mState != StateNone && mState != StateIn)
+ rot = optionGetTilt ();
+ else
+ rot = 0.0;
+
+ dx = rot - mRotation;
+
+ adjust = dx * 0.15f;
+ amount = fabs (dx) * 1.5f;
+ if (amount < 0.2f)
+ amount = 0.2f;
+ else if (amount > 2.0f)
+ amount = 2.0f;
+
+ mRVelocity = (amount * mRVelocity + adjust) / (amount + 1.0f);
+
+ if (fabs (dx) < 0.1f && fabs (mRVelocity) < 0.2f)
+ {
+ mRVelocity = 0.0f;
+ mRotation = rot;
+ return false;
+ }
+
+ mRotation += mRVelocity * chunk;
+ return true;
+}
+
+int
+StackswitchWindow::adjustStackswitchVelocity ()
+{
+ float dx, dy, ds, dr, adjust, amount;
+ float x1, y1, scale, rot;
+ STACKSWITCH_SCREEN (screen);
+
+ if (mSlot)
+ {
+ scale = mSlot->scale;
+ x1 = mSlot->x;
+ y1 = mSlot->y;
+ }
+ else
+ {
+ scale = 1.0f;
+ x1 = window->x () - window->input ().left;
+ y1 = window->y () + window->height () + window->input ().bottom;
+ }
+
+ if (window->id () == ss->mSelectedWindow)
+ rot = ss->mRotation;
+ else
+ rot = 0.0;
+
+ dx = x1 - mTx;
+
+ adjust = dx * 0.15f;
+ amount = fabs (dx) * 1.5f;
+ if (amount < 0.5f)
+ amount = 0.5f;
+ else if (amount > 5.0f)
+ amount = 5.0f;
+
+ mXVelocity = (amount * mXVelocity + adjust) / (amount + 1.0f);
+
+ dy = y1 - mTy;
+
+ adjust = dy * 0.15f;
+ amount = fabs (dy) * 1.5f;
+ if (amount < 0.5f)
+ amount = 0.5f;
+ else if (amount > 5.0f)
+ amount = 5.0f;
+
+ mYVelocity = (amount * mYVelocity + adjust) / (amount + 1.0f);
+
+ ds = scale - mScale;
+ adjust = ds * 0.1f;
+ amount = fabs (ds) * 7.0f;
+ if (amount < 0.01f)
+ amount = 0.01f;
+ else if (amount > 0.15f)
+ amount = 0.15f;
+
+ mScaleVelocity = (amount * mScaleVelocity + adjust) /
+ (amount + 1.0f);
+
+ dr = rot - mRotation;
+ adjust = dr * 0.15f;
+ amount = fabs (dr) * 1.5f;
+ if (amount < 0.2f)
+ amount = 0.2f;
+ else if (amount > 2.0f)
+ amount = 2.0f;
+
+ mRotVelocity = (amount * mRotVelocity + adjust) / (amount + 1.0f);
+
+ if (fabs (dx) < 0.1f && fabs (mXVelocity) < 0.2f &&
+ fabs (dy) < 0.1f && fabs (mYVelocity) < 0.2f &&
+ fabs (ds) < 0.001f && fabs (mScaleVelocity) < 0.002f &&
+ fabs (dr) < 0.1f && fabs (mRotVelocity) < 0.2f)
+ {
+ mXVelocity = mYVelocity = mScaleVelocity = 0.0f;
+ mTx = x1;
+ mTy = y1;
+ mRotation = rot;
+ mScale = scale;
+
+ return 0;
+ }
+
+ return 1;
+}
+
+bool
+StackswitchScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ bool status;
+ GLMatrix sTransform = transform;
+
+ if (mState != StateNone || mRotation != 0.0)
+ {
+ mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
+ mask |= PAINT_SCREEN_TRANSFORMED_MASK;
+ mask |= PAINT_SCREEN_CLEAR_MASK;
+ sTransform.translate (0.0, -0.5, -DEFAULT_Z_CAMERA);
+ sTransform.rotate (-mRotation, 1.0, 0.0, 0.0);
+ sTransform.translate (0.0, 0.5, DEFAULT_Z_CAMERA);
+ }
+
+ status = gScreen->glPaintOutput (attrib, sTransform, region, output, mask);
+
+ if (mState != StateNone && (output->id () == ~0 ||
+ screen->outputDevs ().at (screen->currentOutputDev ().id ()) == *output))
+ {
+ int i;
+ CompWindow *aw = NULL;
+
+ sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
+
+ glPushMatrix ();
+ glLoadMatrixf (sTransform.getMatrix ());
+
+ mPaintingSwitcher = true;
+
+ for (i = 0; i < mWindows.size (); i++)
+ {
+ if (mDrawSlots.at (i)->slot && *(mDrawSlots.at (i)->slot))
+ {
+ CompWindow *w = mDrawSlots.at (i)->w;
+ if (w->id () == mSelectedWindow)
+ aw = w;
+
+ STACKSWITCH_WINDOW (w);
+
+ sw->gWindow->glPaint (sw->gWindow->paintAttrib (), sTransform,
+ infiniteRegion, 0);
+ }
+ }
+
+
+ GLMatrix tTransform (transform);
+ tTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
+ glLoadMatrixf (tTransform.getMatrix ());
+
+ if ((mState != StateIn) && aw)
+ drawWindowTitle (sTransform, aw);
+
+ mPaintingSwitcher = false;
+
+ glPopMatrix ();
+ }
+
+ return status;
+}
+
+void
+StackswitchScreen::preparePaint (int msSinceLastPaint)
+{
+ if (mState != StateNone && (mMoreAdjust || mRotateAdjust))
+ {
+ int steps;
+ float amount, chunk;
+
+ amount = msSinceLastPaint * 0.05f * optionGetSpeed ();
+ steps = amount / (0.5f * optionGetTimestep ());
+
+ if (!steps)
+ steps = 1;
+ chunk = amount / (float) steps;
+
+ layoutThumbs ();
+ while (steps--)
+ {
+ mRotateAdjust = adjustStackswitchRotation (chunk);
+ mMoreAdjust = false;
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ STACKSWITCH_WINDOW (w);
+
+ if (sw->mAdjust)
+ {
+ sw->mAdjust = sw->adjustStackswitchVelocity ();
+
+ mMoreAdjust |= sw->mAdjust;
+
+ sw->mTx += sw->mXVelocity * chunk;
+ sw->mTy += sw->mYVelocity * chunk;
+ sw->mScale += sw->mScaleVelocity * chunk;
+ sw->mRotation += sw->mRotVelocity * chunk;
+ }
+ else if (sw->mSlot)
+ {
+ sw->mScale = sw->mSlot->scale;
+ sw->mTx = sw->mSlot->x;
+ sw->mTy = sw->mSlot->y;
+ if (w->id () == mSelectedWindow)
+ sw->mRotation = mRotation;
+ else
+ sw->mRotation = 0.0;
+ }
+ }
+
+ if (!mMoreAdjust && !mRotateAdjust)
+ break;
+ }
+ }
+
+ cScreen->preparePaint (msSinceLastPaint);
+}
+
+void
+StackswitchScreen::donePaint ()
+{
+ if (mState != StateNone)
+ {
+ if (mMoreAdjust)
+ {
+ cScreen->damageScreen ();
+ }
+ else
+ {
+ if (mRotateAdjust)
+ cScreen->damageScreen ();
+
+ if (mState == StateIn)
+ mState = StateNone;
+ else if (mState == StateOut)
+ mState = StateSwitching;
+ }
+ }
+
+ cScreen->donePaint ();
+}
+
+bool
+StackswitchScreen::terminate (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ if (mGrabIndex)
+ {
+ screen->removeGrab (mGrabIndex, 0);
+ mGrabIndex = 0;
+ }
+
+ if (mState != StateNone)
+ {
+ CompWindow *w;
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ STACKSWITCH_WINDOW (w);
+
+ if (sw->mSlot)
+ {
+ delete sw->mSlot;
+ sw->mSlot = NULL;
+
+ sw->mAdjust = true;
+ }
+ }
+ mMoreAdjust = true;
+ mState = StateIn;
+ cScreen->damageScreen ();
+
+ if (!(state & CompAction::StateCancel) && mSelectedWindow)
+ {
+ w = screen->findWindow (mSelectedWindow);
+ if (w)
+ screen->sendWindowActivationRequest (w->id ());
+ }
+ }
+
+
+ if (action)
+ action->setState (action->state () & ~(CompAction::StateTermKey |
+ CompAction::StateTermButton |
+ CompAction::StateTermEdge));
+
+ return false;
+}
+
+bool
+StackswitchScreen::initiate (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ CompMatch match;
+ CompMatch nilMatch = CompMatch ();
+ int count;
+
+ if (screen->otherGrabExist ("stackswitch", 0))
+ return false;
+
+ mCurrentMatch = optionGetWindowMatch ();
+
+ match = CompOption::getMatchOptionNamed (options, "match", nilMatch);
+ if (!match.isEmpty ())
+ {
+ mCurrentMatch = match;
+ }
+
+ count = countWindows ();
+
+ if (count < 1)
+ return false;
+
+ if (!mGrabIndex)
+ {
+ mGrabIndex = screen->pushGrab (screen->invisibleCursor (), "stackswitch");
+ }
+
+ if (mGrabIndex)
+ {
+ mState = StateOut;
+
+ if (!createWindowList ())
+ return false;
+
+ mSelectedWindow = mWindows.front ()->id ();
+ renderWindowTitle ();
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ STACKSWITCH_WINDOW (w);
+
+ sw->mTx = w->x () - w->input ().left;
+ sw->mTy = w->y () + w->height () + w->input ().bottom;
+ }
+ mMoreAdjust = true;
+ cScreen->damageScreen ();
+ }
+
+ return true;
+}
+
+bool
+StackswitchScreen::doSwitch (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options,
+ bool nextWindow,
+ StackswitchScreen::StackswitchType type)
+{
+ bool ret = true;
+
+ if ((mState == StateNone) || (mState == StateIn))
+ {
+ if (type == TypeGroup)
+ {
+ CompWindow *w;
+ w = screen->findWindow (CompOption::getIntOptionNamed (options,
+ "window",
+ 0));
+ if (w)
+ {
+ mType = TypeGroup;
+ mClientLeader =
+ (w->clientLeader ()) ? w->clientLeader () : w->id ();
+ ret = initiate (action, state, options);
+ }
+ }
+ else
+ {
+ mType = type;
+ ret = initiate (action, state, options);
+ }
+
+ if (state & CompAction::StateInitKey)
+ action->setState (action->state () | CompAction::StateTermKey);
+
+ if (state & CompAction::StateInitEdge)
+ action->setState (action->state () | CompAction::StateTermEdge);
+ else if (state & CompAction::StateInitButton)
+ action->setState (action->state () | CompAction::StateTermButton);
+ }
+
+ if (ret)
+ switchToWindow (nextWindow);
+
+
+ return ret;
+}
+
+void
+StackswitchScreen::windowRemove (Window id)
+{
+ CompWindow *w;
+
+ w = screen->findWindow (id);
+ if (w)
+ {
+ bool inList = false;
+ std::vector <CompWindow *>::iterator it;
+ Window selected;
+
+ STACKSWITCH_WINDOW (w);
+
+ if (mState == StateNone)
+ return;
+
+ if (sw->isStackswitchable ())
+ return;
+
+ selected = mSelectedWindow;
+
+ while (it != mWindows.begin ())
+ {
+ //CompWindow *w = *it;
+
+ if (w && id == (*it)->id ())
+ {
+ inList = true;
+
+ if (w->id () == selected)
+ {
+ if (it < mWindows.end ()--)
+ {
+ it++;
+ selected = (*(it))->id ();
+ it--;
+ }
+ else
+ selected = mWindows.front ()->id ();
+
+ mSelectedWindow = selected;
+ }
+
+ mWindows.erase (it); // ???
+ break;
+
+ }
+ it--;
+ }
+
+ if (!inList)
+ return;
+
+ if (mWindows.size ())
+ {
+ CompOption o ("root", CompOption::TypeInt);
+ CompOption::Vector opts;
+
+ o.value ().set ((int) screen->root ());
+
+ terminate (NULL, 0, opts);
+ return;
+ }
+
+ if (!mGrabIndex)
+ return;
+
+ if (updateWindowList ())
+ {
+ mMoreAdjust = true;
+ mState = StateOut;
+ cScreen->damageScreen ();
+ }
+ }
+}
+
+void
+StackswitchScreen::handleEvent (XEvent *event)
+{
+
+ screen->handleEvent (event);
+
+ switch (event->type) {
+ case PropertyNotify:
+ if (event->xproperty.atom == XA_WM_NAME)
+ {
+ CompWindow *w;
+ w = screen->findWindow (event->xproperty.window);
+ if (w)
+ {
+ if (mGrabIndex && (w->id () == mSelectedWindow))
+ {
+ renderWindowTitle ();
+ cScreen->damageScreen ();
+ }
+ }
+ }
+ break;
+ case UnmapNotify:
+ windowRemove (event->xunmap.window);
+ break;
+ case DestroyNotify:
+ windowRemove (event->xdestroywindow.window);
+ break;
+ }
+}
+
+bool
+StackswitchWindow::damageRect (bool initial,
+ const CompRect &rect)
+{
+ bool status = false;
+
+ STACKSWITCH_SCREEN (screen);
+
+ if (initial)
+ {
+ if (ss->mGrabIndex && isStackswitchable ())
+ {
+ addToList ();
+ if (ss->updateWindowList ())
+ {
+ mAdjust = true;
+ ss->mMoreAdjust = true;
+ ss->mState = StackswitchScreen::StateOut;
+ ss->cScreen->damageScreen ();
+ }
+ }
+ }
+ else if (ss->mState == StackswitchScreen::StateSwitching)
+ {
+ if (mSlot)
+ {
+ ss->cScreen->damageScreen ();
+ status = true;
+ }
+ }
+
+ status |= cWindow->damageRect (initial, rect);
+
+ return status;
+}
+
+StackswitchScreen::StackswitchScreen (CompScreen *screen) :
+ PluginClassHandler <StackswitchScreen, CompScreen> (screen),
+ cScreen (CompositeScreen::get (screen)),
+ gScreen (GLScreen::get (screen)),
+ mGrabIndex (0),
+ mState (StateNone),
+ mMoreAdjust (false),
+ mRotateAdjust (false),
+ mPaintingSwitcher (false),
+ mRVelocity (0.0f),
+ mRotation (0.0f),
+ mClientLeader (None),
+ mSelectedWindow (None)
+{
+ ScreenInterface::setHandler (screen);
+ CompositeScreenInterface::setHandler (cScreen);
+ GLScreenInterface::setHandler (gScreen);
+
+ optionSetNextKeyInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, true, TypeNormal));
+ optionSetNextAllKeyInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, true, TypeAll));
+ optionSetNextGroupKeyInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, true, TypeGroup));
+ optionSetNextKeyTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetNextAllKeyTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetNextGroupKeyTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetPrevKeyInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, false, TypeNormal));
+ optionSetPrevAllKeyInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, false, TypeAll));
+ optionSetPrevGroupKeyInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, false, TypeGroup));
+ optionSetPrevKeyTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetPrevAllKeyTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetPrevGroupKeyTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+
+ optionSetNextButtonInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, true, TypeNormal));
+ optionSetNextAllButtonInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, true, TypeAll));
+ optionSetNextGroupButtonInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, true, TypeGroup));
+ optionSetNextButtonTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetNextAllButtonTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetNextGroupButtonTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetPrevButtonInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, false, TypeNormal));
+ optionSetPrevAllButtonInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, false, TypeAll));
+ optionSetPrevGroupButtonInitiate (boost::bind (&StackswitchScreen::doSwitch, this,
+ _1, _2, _3, false, TypeGroup));
+ optionSetPrevButtonTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetPrevAllButtonTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+ optionSetPrevGroupButtonTerminate (boost::bind (&StackswitchScreen::terminate, this,
+ _1, _2, _3));
+}
+
+StackswitchScreen::~StackswitchScreen ()
+{
+ mWindows.clear ();
+ mDrawSlots.clear ();
+}
+
+StackswitchWindow::StackswitchWindow (CompWindow *window) :
+ PluginClassHandler <StackswitchWindow, CompWindow> (window),
+ window (window),
+ cWindow (CompositeWindow::get (window)),
+ gWindow (GLWindow::get (window)),
+ mSlot (NULL),
+ mXVelocity (0.0f),
+ mYVelocity (0.0f),
+ mScaleVelocity (0.0f),
+ mRotVelocity (0.0f),
+ mTx (0.0f),
+ mTy (0.0f),
+ mScale (1.0f),
+ mRotation (0.0f),
+ mAdjust (false)
+{
+ CompositeWindowInterface::setHandler (cWindow);
+ GLWindowInterface::setHandler (gWindow);
+}
+
+StackswitchWindow::~StackswitchWindow ()
+{
+ if (mSlot)
+ delete mSlot;
+}
+
+bool
+StackswitchPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
+ !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
+ !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
+ return false;
+
+ if (!CompPlugin::checkPluginABI ("text", COMPIZ_TEXT_ABI))
+ {
+ compLogMessage ("stackswitch", CompLogLevelWarn, "No compatible text plugin"\
+ " loaded");
+ textAvailable = false;
+ }
+ else
+ textAvailable = true;
+
+ return true;
+}
diff --git a/src/stackswitch.h b/src/stackswitch.h
new file mode 100644
index 0000000..e12bd26
--- /dev/null
+++ b/src/stackswitch.h
@@ -0,0 +1,237 @@
+/*
+ *
+ * Compiz stackswitch switcher plugin
+ *
+ * stackswitch.h
+ *
+ * Copyright : (C) 2008 by Dennis Kasprzyk
+ * E-mail : onestone@beryl-project.org
+ *
+ * Based on scale.c and switcher.c:
+ * Copyright : (C) 2007 David Reveman
+ * E-mail : davidr@novell.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <cmath>
+#include <core/atoms.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+
+#include <core/core.h>
+#include <core/pluginclasshandler.h>
+#include <opengl/opengl.h>
+#include <text/text.h>
+#include <composite/composite.h>
+
+#include "stackswitch_options.h"
+
+typedef struct _StackswitchSlot {
+ int x, y; /* thumb center coordinates */
+ float scale; /* size scale (fit to maximal thumb size) */
+} StackswitchSlot;
+
+typedef struct _StackswitchDrawSlot {
+ CompWindow *w;
+ StackswitchSlot **slot;
+} StackswitchDrawSlot;
+
+class StackswitchScreen :
+ public PluginClassHandler <StackswitchScreen, CompScreen>,
+ public ScreenInterface,
+ public CompositeScreenInterface,
+ public GLScreenInterface,
+ public StackswitchOptions
+{
+ public:
+
+ StackswitchScreen (CompScreen *);
+ ~StackswitchScreen ();
+
+ public:
+
+ typedef enum {
+ StateNone = 0,
+ StateOut,
+ StateSwitching,
+ StateIn
+ } StackswitchState;
+
+ typedef enum {
+ TypeNormal = 0,
+ TypeGroup,
+ TypeAll
+ } StackswitchType;
+
+ public:
+
+ CompositeScreen *cScreen;
+ GLScreen *gScreen;
+
+ /* text display support */
+ CompText mText;
+
+ void
+ handleEvent (XEvent *);
+
+ void
+ preparePaint (int);
+
+ bool
+ glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+
+ void
+ donePaint ();
+
+ void
+ renderWindowTitle ();
+
+ void
+ drawWindowTitle (GLMatrix &transform,
+ CompWindow *w);
+
+ bool
+ layoutThumbs ();
+
+ bool
+ updateWindowList ();
+
+ bool
+ createWindowList ();
+
+ void
+ switchToWindow (bool toNext);
+
+ int
+ countWindows ();
+
+ int
+ adjustStackswitchRotation (float chunk);
+
+ bool
+ terminate (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ bool
+ initiate (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ bool
+ doSwitch (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options,
+ bool nextWindow,
+ StackswitchType type);
+
+ void
+ windowRemove (Window id);
+
+ CompScreen::GrabHandle mGrabIndex;
+
+ StackswitchState mState;
+ StackswitchType mType;
+ bool mMoreAdjust;
+ bool mRotateAdjust;
+
+ bool mPaintingSwitcher;
+
+ GLfloat mRVelocity;
+ GLfloat mRotation;
+
+ /* only used for sorting */
+ std::vector <CompWindow *> mWindows;
+ std::vector <StackswitchDrawSlot *> mDrawSlots;
+
+ Window mClientLeader;
+ Window mSelectedWindow;
+
+ CompMatch mMatch;
+ CompMatch mCurrentMatch;
+
+};
+
+#define STACKSWITCH_SCREEN(s) \
+ StackswitchScreen *ss = StackswitchScreen::get (s)
+
+class StackswitchWindow :
+ public PluginClassHandler <StackswitchWindow, CompWindow>,
+ public CompositeWindowInterface,
+ public GLWindowInterface
+{
+ public:
+
+ StackswitchWindow (CompWindow *w);
+ ~StackswitchWindow ();
+
+ public:
+
+ CompWindow *window;
+ CompositeWindow *cWindow;
+ GLWindow *gWindow;
+
+ bool
+ damageRect (bool, const CompRect &);
+
+ bool
+ glPaint (const GLWindowPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ unsigned int );
+
+ int
+ adjustStackswitchVelocity ();
+
+ void
+ addToList ();
+
+ static bool
+ compareStackswitchWindowDepth (StackswitchDrawSlot *a1,
+ StackswitchDrawSlot *a2);
+
+ static bool
+ compareWindows (CompWindow *w1,
+ CompWindow *w2);
+
+ bool
+ isStackswitchable ();
+
+ StackswitchSlot *mSlot;
+
+ GLfloat mXVelocity;
+ GLfloat mYVelocity;
+ GLfloat mScaleVelocity;
+ GLfloat mRotVelocity;
+
+ GLfloat mTx;
+ GLfloat mTy;
+ GLfloat mScale;
+ GLfloat mRotation;
+ bool mAdjust;
+};
+
+#define STACKSWITCH_WINDOW(w) \
+ StackswitchWindow *sw = StackswitchWindow::get (w)
+
+class StackswitchPluginVTable :
+ public CompPlugin::VTableForScreenAndWindow <StackswitchScreen, StackswitchWindow>
+{
+ public:
+
+ bool init ();
+};
diff --git a/stackswitch.c b/stackswitch.c
deleted file mode 100644
index 744673d..0000000
--- a/stackswitch.c
+++ /dev/null
@@ -1,1831 +0,0 @@
-/*
- *
- * Compiz stackswitch switcher plugin
- *
- * stackswitch.c
- *
- * Copyright : (C) 2007 by Danny Baumann
- * E-mail : maniac@opencompositing.org
- *
- * Based on scale.c and switcher.c:
- * Copyright : (C) 2007 David Reveman
- * E-mail : davidr@novell.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <sys/time.h>
-
-#include <X11/Xatom.h>
-#include <X11/cursorfont.h>
-
-#include <compiz-core.h>
-#include <compiz-text.h>
-#include "stackswitch_options.h"
-
-typedef enum {
- StackswitchStateNone = 0,
- StackswitchStateOut,
- StackswitchStateSwitching,
- StackswitchStateIn
-} StackswitchState;
-
-typedef enum {
- StackswitchTypeNormal = 0,
- StackswitchTypeGroup,
- StackswitchTypeAll
-} StackswitchType;
-
-static int StackswitchDisplayPrivateIndex;
-
-typedef struct _StackswitchSlot {
- int x, y; /* thumb center coordinates */
- float scale; /* size scale (fit to maximal thumb size) */
-} StackswitchSlot;
-
-typedef struct _StackswitchDrawSlot {
- CompWindow *w;
- StackswitchSlot **slot;
-} StackswitchDrawSlot;
-
-typedef struct _StackswitchDisplay {
- int screenPrivateIndex;
- HandleEventProc handleEvent;
- TextFunc *textFunc;
-} StackswitchDisplay;
-
-typedef struct _StackswitchScreen {
- int windowPrivateIndex;
-
- PreparePaintScreenProc preparePaintScreen;
- DonePaintScreenProc donePaintScreen;
- PaintOutputProc paintOutput;
- PaintWindowProc paintWindow;
- DamageWindowRectProc damageWindowRect;
-
- int grabIndex;
-
- StackswitchState state;
- StackswitchType type;
- Bool moreAdjust;
- Bool rotateAdjust;
-
- Bool paintingSwitcher;
-
- GLfloat rVelocity;
- GLfloat rotation;
-
- /* only used for sorting */
- CompWindow **windows;
- StackswitchDrawSlot *drawSlots;
- int windowsSize;
- int nWindows;
-
- Window clientLeader;
- Window selectedWindow;
-
- /* text display support */
- CompTextData *textData;
-
- CompMatch match;
- CompMatch *currentMatch;
-} StackswitchScreen;
-
-typedef struct _StackswitchWindow {
-
- StackswitchSlot *slot;
-
- GLfloat xVelocity;
- GLfloat yVelocity;
- GLfloat scaleVelocity;
- GLfloat rotVelocity;
-
- GLfloat tx;
- GLfloat ty;
- GLfloat scale;
- GLfloat rotation;
- Bool adjust;
-} StackswitchWindow;
-
-#define STACKSWITCH_DISPLAY(d) PLUGIN_DISPLAY(d, Stackswitch, s)
-#define STACKSWITCH_SCREEN(sc) PLUGIN_SCREEN(sc, Stackswitch, s)
-#define STACKSWITCH_WINDOW(w) PLUGIN_WINDOW(w, Stackswitch, s)
-
-static Bool
-isStackswitchWin (CompWindow *w)
-{
- STACKSWITCH_SCREEN (w->screen);
-
- if (w->attrib.override_redirect)
- return FALSE;
-
- if (w->wmType & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
- return FALSE;
-
- if (!w->mapNum || w->attrib.map_state != IsViewable)
- {
- if (stackswitchGetMinimized (w->screen))
- {
- if (!w->minimized && !w->inShowDesktopMode && !w->shaded)
- return FALSE;
- }
- else
- return FALSE;
- }
-
- if (ss->type == StackswitchTypeNormal)
- {
- if (!w->mapNum || w->attrib.map_state != IsViewable)
- {
- if (w->serverX + w->width <= 0 ||
- w->serverY + w->height <= 0 ||
- w->serverX >= w->screen->width ||
- w->serverY >= w->screen->height)
- return FALSE;
- }
- else
- {
- if (!(*w->screen->focusWindow) (w))
- return FALSE;
- }
- }
- else if (ss->type == StackswitchTypeGroup &&
- ss->clientLeader != w->clientLeader &&
- ss->clientLeader != w->id)
- {
- return FALSE;
- }
-
- if (w->state & CompWindowStateSkipTaskbarMask)
- return FALSE;
-
- if (!matchEval (ss->currentMatch, w))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-stackswitchFreeWindowTitle (CompScreen *s)
-{
- STACKSWITCH_SCREEN (s);
- STACKSWITCH_DISPLAY (s->display);
-
- if (!ss->textData)
- return;
-
- (sd->textFunc->finiTextData) (s, ss->textData);
- ss->textData = NULL;
-}
-
-static void
-stackswitchRenderWindowTitle (CompScreen *s)
-{
- CompTextAttrib tA;
- int ox1, ox2, oy1, oy2;
- Bool showViewport;
-
- STACKSWITCH_SCREEN (s);
- STACKSWITCH_DISPLAY (s->display);
-
- stackswitchFreeWindowTitle (s);
-
- if (!sd->textFunc)
- return;
-
- if (!stackswitchGetWindowTitle (s))
- return;
-
- getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);
-
- /* 75% of the output device as maximum width */
- tA.maxWidth = (ox2 - ox1) * 3 / 4;
- tA.maxHeight = 100;
-
- tA.family = "Sans";
- tA.size = stackswitchGetTitleFontSize (s);
- tA.color[0] = stackswitchGetTitleFontColorRed (s);
- tA.color[1] = stackswitchGetTitleFontColorGreen (s);
- tA.color[2] = stackswitchGetTitleFontColorBlue (s);
- tA.color[3] = stackswitchGetTitleFontColorAlpha (s);
-
- tA.flags = CompTextFlagWithBackground | CompTextFlagEllipsized;
- if (stackswitchGetTitleFontBold (s))
- tA.flags |= CompTextFlagStyleBold;
-
- tA.bgHMargin = 15;
- tA.bgVMargin = 15;
- tA.bgColor[0] = stackswitchGetTitleBackColorRed (s);
- tA.bgColor[1] = stackswitchGetTitleBackColorGreen (s);
- tA.bgColor[2] = stackswitchGetTitleBackColorBlue (s);
- tA.bgColor[3] = stackswitchGetTitleBackColorAlpha (s);
-
- showViewport = ss->type == StackswitchTypeAll;
- ss->textData = (sd->textFunc->renderWindowTitle) (s, ss->selectedWindow,
- showViewport, &tA);
-}
-
-static void
-stackswitchDrawWindowTitle (CompScreen *s,
- CompTransform *transform,
- CompWindow *w)
-{
- GLboolean wasBlend;
- GLint oldBlendSrc, oldBlendDst;
- CompTransform wTransform = *transform, mvp, pm;
- float x, y, tx, ix, width, height;
- int ox1, ox2, oy1, oy2, i;
- CompMatrix *m;
- CompVector v;
- CompIcon *icon;
-
- STACKSWITCH_SCREEN (s);
- STACKSWITCH_WINDOW (w);
-
- getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);
-
- width = ss->textData->width;
- height = ss->textData->height;
-
- x = ox1 + ((ox2 - ox1) / 2);
- tx = x - (ss->textData->width / 2);
-
- switch (stackswitchGetTitleTextPlacement (s))
- {
- case TitleTextPlacementOnThumbnail:
- v.x = w->attrib.x + (w->attrib.width / 2.0);
- v.y = w->attrib.y + (w->attrib.height / 2.0);
- v.z = 0.0;
- v.w = 1.0;
-
- matrixScale (&wTransform, 1.0, 1.0, 1.0 / s->height);
- matrixTranslate (&wTransform, sw->tx, sw->ty, 0.0f);
- matrixRotate (&wTransform, -ss->rotation, 1.0, 0.0, 0.0);
- matrixScale (&wTransform, sw->scale, sw->scale, 1.0);
- matrixTranslate (&wTransform, +w->input.left, 0.0 -(w->attrib.height + w->input.bottom), 0.0f);
- matrixTranslate (&wTransform, -w->attrib.x, -w->attrib.y, 0.0f);
-
- for (i=0; i < 16; i++)
- pm.m[i] = s->projection[i];
- matrixMultiply (&mvp, &pm, &wTransform);
- matrixMultiplyVector (&v, &v, &mvp);
- matrixVectorDiv (&v);
-
- x = (v.x + 1.0) * (ox2 - ox1) * 0.5;
- y = (v.y - 1.0) * (oy2 - oy1) * -0.5;
-
- x += ox1;
- y += oy1;
-
- tx = MAX (ox1, x - (width / 2.0));
- if (tx + width > ox2)
- tx = ox2 - width;
- break;
- case TitleTextPlacementCenteredOnScreen:
- y = oy1 + ((oy2 - oy1) / 2) + (height / 2);
- break;
- case TitleTextPlacementAbove:
- case TitleTextPlacementBelow:
- {
- XRectangle workArea;
- getWorkareaForOutput (s, s->currentOutputDev, &workArea);
-
- if (stackswitchGetTitleTextPlacement (s) ==
- TitleTextPlacementAbove)
- y = oy1 + workArea.y + height;
- else
- y = oy1 + workArea.y + workArea.height - 96;
- }
- break;
- default:
- return;
- break;
- }
-
- tx = floor (tx);
- y = floor (y);
-
- glGetIntegerv (GL_BLEND_SRC, &oldBlendSrc);
- glGetIntegerv (GL_BLEND_DST, &oldBlendDst);
-
- wasBlend = glIsEnabled (GL_BLEND);
- if (!wasBlend)
- glEnable (GL_BLEND);
-
- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
- glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glColor4f (1.0, 1.0, 1.0, 1.0);
-
- icon = getWindowIcon (w, 96, 96);
- if (!icon)
- icon = w->screen->defaultIcon;
-
- if (icon && (icon->texture.name || iconToTexture (w->screen, icon)))
- {
- int off;
-
- ix = x - (icon->width / 2.0);
- ix = floor (ix);
-
- enableTexture (s, &icon->texture,COMP_TEXTURE_FILTER_GOOD);
-
- m = &icon->texture.matrix;
-
- glColor4f (0.0, 0.0, 0.0, 0.1);
-
- for (off = 0; off < 6; off++)
- {
- glBegin (GL_QUADS);
-
- glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0));
- glVertex2f (ix - off, y - off);
- glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, icon->height));
- glVertex2f (ix - off, y + icon->height + off);
- glTexCoord2f (COMP_TEX_COORD_X (m, icon->width), COMP_TEX_COORD_Y (m, icon->height));
- glVertex2f (ix + icon->width + off, y + icon->height + off);
- glTexCoord2f (COMP_TEX_COORD_X (m, icon->width), COMP_TEX_COORD_Y (m, 0));
- glVertex2f (ix + icon->width + off, y - off);
-
- glEnd ();
- }
-
- glColor4f (1.0, 1.0, 1.0, 1.0);
-
- glBegin (GL_QUADS);
-
- glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0));
- glVertex2f (ix, y);
- glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, icon->height));
- glVertex2f (ix, y + icon->height);
- glTexCoord2f (COMP_TEX_COORD_X (m, icon->width), COMP_TEX_COORD_Y (m, icon->height));
- glVertex2f (ix + icon->width, y + icon->height);
- glTexCoord2f (COMP_TEX_COORD_X (m, icon->width), COMP_TEX_COORD_Y (m, 0));
- glVertex2f (ix + icon->width, y);
-
- glEnd ();
-
- disableTexture (s, &icon->texture);
- }
-
- enableTexture (s, ss->textData->texture, COMP_TEXTURE_FILTER_GOOD);
-
- m = &ss->textData->texture->matrix;
-
- glBegin (GL_QUADS);
-
- glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m ,0));
- glVertex2f (tx, y - height);
- glTexCoord2f (COMP_TEX_COORD_X (m, 0), COMP_TEX_COORD_Y (m, height));
- glVertex2f (tx, y);
- glTexCoord2f (COMP_TEX_COORD_X (m, width), COMP_TEX_COORD_Y (m, height));
- glVertex2f (tx + width, y);
- glTexCoord2f (COMP_TEX_COORD_X (m, width), COMP_TEX_COORD_Y (m, 0));
- glVertex2f (tx + width, y - height);
-
- glEnd ();
-
- disableTexture (s, ss->textData->texture);
- glColor4usv (defaultColor);
-
- if (!wasBlend)
- glDisable (GL_BLEND);
- glBlendFunc (oldBlendSrc, oldBlendDst);
-}
-
-static Bool
-stackswitchPaintWindow (CompWindow *w,
- const WindowPaintAttrib *attrib,
- const CompTransform *transform,
- Region region,
- unsigned int mask)
-{
- CompScreen *s = w->screen;
- Bool status;
-
- STACKSWITCH_SCREEN (s);
-
- if (ss->state != StackswitchStateNone)
- {
- WindowPaintAttrib sAttrib = *attrib;
- Bool scaled = FALSE;
- float rotation;
-
- STACKSWITCH_WINDOW (w);
-
- if (w->mapNum)
- {
- if (!w->texture->pixmap && !w->bindFailed)
- bindWindow (w);
- }
-
- if (sw->adjust || sw->slot)
- {
- scaled = (sw->adjust && ss->state != StackswitchStateSwitching) ||
- (sw->slot && ss->paintingSwitcher);
- mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
- }
- else if (ss->state != StackswitchStateIn)
- {
- if (stackswitchGetDarkenBack (s))
- {
- /* modify brightness of the other windows */
- sAttrib.brightness = sAttrib.brightness / 2;
- }
- }
-
- UNWRAP (ss, s, paintWindow);
- status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
- WRAP (ss, s, paintWindow, stackswitchPaintWindow);
-
- if (stackswitchGetInactiveRotate(s))
- rotation = MIN (sw->rotation, ss->rotation);
- else
- rotation = ss->rotation;
-
- if (scaled && w->texture->pixmap)
- {
- FragmentAttrib fragment;
- CompTransform wTransform = *transform;
-
- if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
- return FALSE;
-
- initFragmentAttrib (&fragment, &w->lastPaint);
-
- if (sw->slot)
- {
- if (w->id != ss->selectedWindow)
- fragment.opacity = (float)fragment.opacity *
- stackswitchGetInactiveOpacity (s) / 100;
- }
-
- if (w->alpha || fragment.opacity != OPAQUE)
- mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
-
-
- matrixScale (&wTransform, 1.0, 1.0, 1.0 / s->height);
- matrixTranslate (&wTransform, sw->tx, sw->ty, 0.0f);
-
- matrixRotate (&wTransform, -rotation, 1.0, 0.0, 0.0);
- matrixScale (&wTransform, sw->scale, sw->scale, 1.0);
-
- matrixTranslate (&wTransform, +w->input.left, 0.0 -(w->attrib.height + w->input.bottom), 0.0f);
- matrixTranslate (&wTransform, -w->attrib.x, -w->attrib.y, 0.0f);
- glPushMatrix ();
- glLoadMatrixf (wTransform.m);
-
- (*s->drawWindow) (w, &wTransform, &fragment, region,
- mask | PAINT_WINDOW_TRANSFORMED_MASK);
-
- glPopMatrix ();
- }
-
- if (scaled && !w->texture->pixmap)
- {
- CompIcon *icon;
-
- icon = getWindowIcon (w, 96, 96);
- if (!icon)
- icon = w->screen->defaultIcon;
-
- if (icon && (icon->texture.name || iconToTexture (w->screen, icon)))
- {
- REGION iconReg;
- CompMatrix matrix;
- float scale;
-
- scale = MIN (w->attrib.width / icon->width,
- w->attrib.height / icon->height);
- scale *= sw->scale;
-
- mask |= PAINT_WINDOW_BLEND_MASK;
-
- /* if we paint the icon for a minimized window, we need
- to force the usage of a good texture filter */
- if (!w->texture->pixmap)
- mask |= PAINT_WINDOW_TRANSFORMED_MASK;
-
- iconReg.rects = &iconReg.extents;
- iconReg.numRects = 1;
-
- iconReg.extents.x1 = 0;
- iconReg.extents.y1 = 0;
- iconReg.extents.x2 = icon->width;
- iconReg.extents.y2 = icon->height;
-
- matrix = icon->texture.matrix;
-
- w->vCount = w->indexCount = 0;
- (*w->screen->addWindowGeometry) (w, &matrix, 1,
- &iconReg, &infiniteRegion);
-
- if (w->vCount)
- {
- FragmentAttrib fragment;
- CompTransform wTransform = *transform;
-
- if (!w->texture->pixmap)
- sAttrib.opacity = w->paint.opacity;
-
- initFragmentAttrib (&fragment, &sAttrib);
-
- matrixScale (&wTransform, 1.0, 1.0, 1.0 / s->height);
- matrixTranslate (&wTransform, sw->tx, sw->ty, 0.0f);
-
- matrixRotate (&wTransform, -rotation, 1.0, 0.0, 0.0);
- matrixScale (&wTransform, scale, scale, 1.0);
-
- matrixTranslate (&wTransform, 0.0, -icon->height, 0.0f);
-
- glPushMatrix ();
- glLoadMatrixf (wTransform.m);
-
- (*w->screen->drawWindowTexture) (w, &icon->texture,
- &fragment, mask);
-
- glPopMatrix ();
- }
- }
- }
- }
- else
- {
- UNWRAP (ss, s, paintWindow);
- status = (*s->paintWindow) (w, attrib, transform, region, mask);
- WRAP (ss, s, paintWindow, stackswitchPaintWindow);
- }
-
- return status;
-}
-
-static int
-compareWindows (const void *elem1,
- const void *elem2)
-{
- CompWindow *w1 = *((CompWindow **) elem1);
- CompWindow *w2 = *((CompWindow **) elem2);
-
- if (w1->mapNum && !w2->mapNum)
- return -1;
-
- if (w2->mapNum && !w1->mapNum)
- return 1;
-
- return w2->activeNum - w1->activeNum;
-}
-
-static int
-compareStackswitchWindowDepth (const void *elem1,
- const void *elem2)
-{
- StackswitchSlot *a1 = *(((StackswitchDrawSlot *) elem1)->slot);
- StackswitchSlot *a2 = *(((StackswitchDrawSlot *) elem2)->slot);
-
- if (a1->y < a2->y)
- return -1;
- else if (a1->y > a2->y)
- return 1;
- else
- {
- CompWindow *a1 = (((StackswitchDrawSlot *) elem1)->w);
- CompWindow *a2 = (((StackswitchDrawSlot *) elem2)->w);
- STACKSWITCH_SCREEN (a1->screen);
- if (a1->id == ss->selectedWindow)
- return 1;
- else if (a2->id == ss->selectedWindow)
- return -1;
- else
- return 0;
- }
-}
-
-static Bool
-layoutThumbs (CompScreen *s)
-{
- CompWindow *w;
- int index;
- int ww, wh;
- float xScale, yScale;
- int ox1, ox2, oy1, oy2;
- float swi = 0.0, oh, rh, ow;
- int cols, rows, col = 0, row = 0, r, c;
- int cindex, ci, gap, hasActive = 0;
- Bool exit;
-
- STACKSWITCH_SCREEN (s);
-
- if ((ss->state == StackswitchStateNone) || (ss->state == StackswitchStateIn))
- return FALSE;
-
- getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);
- ow = (float)(ox2 - ox1) * 0.9;
-
- for (index = 0; index < ss->nWindows; index++)
- {
- w = ss->windows[index];
-
- ww = w->attrib.width + w->input.left + w->input.right;
- wh = w->attrib.height + w->input.top + w->input.bottom;
-
- swi += ((float)ww / (float)wh) * (ow / (float)(oy2 - oy1));
- }
-
- cols = ceil (sqrtf (swi));
-
- swi = 0.0;
- for (index = 0; index < ss->nWindows; index++)
- {
- w = ss->windows[index];
-
- ww = w->attrib.width + w->input.left + w->input.right;
- wh = w->attrib.height + w->input.top + w->input.bottom;
-
- swi += (float)ww / (float)wh;
-
- if (swi > cols)
- {
- row++;
- swi = (float)ww / (float)wh;
- col = 0;
- }
-
- col++;
- }
- rows = row + 1;
-
- oh = ow / cols;
- oh *= (float)(oy2 - oy1) / (float)(oy2 - oy1);
-
- rh = ((float)(oy2 - oy1) * 0.8) / rows;
-
- for (index = 0; index < ss->nWindows; index++)
- {
- w = ss->windows[index];
-
- STACKSWITCH_WINDOW (w);
-
- if (!sw->slot)
- sw->slot = malloc (sizeof (StackswitchSlot));
-
- if (!sw->slot)
- return FALSE;
-
- ss->drawSlots[index].w = w;
- ss->drawSlots[index].slot = &sw->slot;
- }
-
- index = 0;
-
- for (r = 0; r < rows && index < ss->nWindows; r++)
- {
- c = 0;
- swi = 0.0;
- cindex = index;
- exit = FALSE;
- while (index < ss->nWindows && !exit)
- {
- w = ss->windows[index];
-
- STACKSWITCH_WINDOW (w);
- sw->slot->x = ox1 + swi;
- sw->slot->y = oy2 - (rh * r) - ((oy2 - oy1) * 0.1);
-
-
- ww = w->attrib.width + w->input.left + w->input.right;
- wh = w->attrib.height + w->input.top + w->input.bottom;
-
- if (ww > ow)
- xScale = ow / (float) ww;
- else
- xScale = 1.0f;
-
- if (wh > oh)
- yScale = oh / (float) wh;
- else
- yScale = 1.0f;
-
- sw->slot->scale = MIN (xScale, yScale);
-
- if (swi + (ww * sw->slot->scale) > ow && cindex != index)
- {
- exit = TRUE;
- continue;
- }
-
- if (w->id == ss->selectedWindow)
- hasActive = 1;
- swi += ww * sw->slot->scale;
-
- c++;
- index++;
- }
-
- gap = ox2 - ox1 - swi;
- gap /= c + 1;
-
- index = cindex;
- ci = 1;
- while (ci <= c)
- {
- w = ss->windows[index];
-
- STACKSWITCH_WINDOW (w);
- sw->slot->x += ci * gap;
-
- if (hasActive == 0)
- sw->slot->y += sqrt(2 * oh * oh) - rh;
-
- ci++;
- index++;
- }
-
- if (hasActive == 1)
- hasActive++;
- }
-
- /* sort the draw list so that the windows with the
- lowest Y value (the windows being farest away)
- are drawn first */
- qsort (ss->drawSlots, ss->nWindows, sizeof (StackswitchDrawSlot),
- compareStackswitchWindowDepth);
-
- return TRUE;
-}
-
-static void
-stackswitchAddWindowToList (CompScreen *s,
- CompWindow *w)
-{
- STACKSWITCH_SCREEN (s);
-
- if (ss->windowsSize <= ss->nWindows)
- {
- ss->windows = realloc (ss->windows,
- sizeof (CompWindow *) * (ss->nWindows + 32));
- if (!ss->windows)
- return;
-
- ss->drawSlots = realloc (ss->drawSlots,
- sizeof (StackswitchDrawSlot) * (ss->nWindows + 32));
-
- if (!ss->drawSlots)
- return;
-
- ss->windowsSize = ss->nWindows + 32;
- }
-
- ss->windows[ss->nWindows++] = w;
-}
-
-static Bool
-stackswitchUpdateWindowList (CompScreen *s)
-{
- STACKSWITCH_SCREEN (s);
-
- qsort (ss->windows, ss->nWindows, sizeof (CompWindow *), compareWindows);
-
- return layoutThumbs (s);
-}
-
-static Bool
-stackswitchCreateWindowList (CompScreen *s)
-{
- CompWindow *w;
-
- STACKSWITCH_SCREEN (s);
-
- ss->nWindows = 0;
-
- for (w = s->windows; w; w = w->next)
- {
- if (isStackswitchWin (w))
- {
- STACKSWITCH_WINDOW (w);
-
- stackswitchAddWindowToList (s, w);
- sw->adjust = TRUE;
- }
- }
-
- return stackswitchUpdateWindowList (s);
-}
-
-static void
-switchToWindow (CompScreen *s,
- Bool toNext)
-{
- CompWindow *w;
- int cur;
-
- STACKSWITCH_SCREEN (s);
-
- if (!ss->grabIndex)
- return;
-
- for (cur = 0; cur < ss->nWindows; cur++)
- {
- if (ss->windows[cur]->id == ss->selectedWindow)
- break;
- }
-
- if (cur == ss->nWindows)
- return;
-
- if (toNext)
- w = ss->windows[(cur + 1) % ss->nWindows];
- else
- w = ss->windows[(cur + ss->nWindows - 1) % ss->nWindows];
-
- if (w)
- {
- Window old = ss->selectedWindow;
-
- ss->selectedWindow = w->id;
- if (old != w->id)
- {
-
- ss->rotateAdjust = TRUE;
- ss->moreAdjust = TRUE;
- for (w = s->windows; w; w = w->next)
- {
- STACKSWITCH_WINDOW (w);
- sw->adjust = TRUE;
- }
-
- damageScreen (s);
- stackswitchRenderWindowTitle (s);
- }
- }
-}
-
-static int
-stackswitchCountWindows (CompScreen *s)
-{
- CompWindow *w;
- int count = 0;
-
- for (w = s->windows; w; w = w->next)
- {
- if (isStackswitchWin (w))
- count++;
- }
-
- return count;
-}
-
-static int
-adjustStackswitchRotation (CompScreen *s,
- float chunk)
-{
- float dx, adjust, amount, rot;
-
- STACKSWITCH_SCREEN(s);
-
- if (ss->state != StackswitchStateNone && ss->state != StackswitchStateIn)
- rot = stackswitchGetTilt (s);
- else
- rot = 0.0;
-
- dx = rot - ss->rotation;
-
- adjust = dx * 0.15f;
- amount = fabs (dx) * 1.5f;
- if (amount < 0.2f)
- amount = 0.2f;
- else if (amount > 2.0f)
- amount = 2.0f;
-
- ss->rVelocity = (amount * ss->rVelocity + adjust) / (amount + 1.0f);
-
- if (fabs (dx) < 0.1f && fabs (ss->rVelocity) < 0.2f)
- {
- ss->rVelocity = 0.0f;
- ss->rotation = rot;
- return FALSE;
- }
-
- ss->rotation += ss->rVelocity * chunk;
- return TRUE;
-}
-
-static int
-adjustStackswitchVelocity (CompWindow *w)
-{
- float dx, dy, ds, dr, adjust, amount;
- float x1, y1, scale, rot;
-
- STACKSWITCH_WINDOW (w);
- STACKSWITCH_SCREEN (w->screen);
-
- if (sw->slot)
- {
- scale = sw->slot->scale;
- x1 = sw->slot->x;
- y1 = sw->slot->y;
- }
- else
- {
- scale = 1.0f;
- x1 = w->attrib.x - w->input.left;
- y1 = w->attrib.y + w->attrib.height + w->input.bottom;
- }
-
- if (w->id == ss->selectedWindow)
- rot = ss->rotation;
- else
- rot = 0.0;
-
- dx = x1 - sw->tx;
-
- adjust = dx * 0.15f;
- amount = fabs (dx) * 1.5f;
- if (amount < 0.5f)
- amount = 0.5f;
- else if (amount > 5.0f)
- amount = 5.0f;
-
- sw->xVelocity = (amount * sw->xVelocity + adjust) / (amount + 1.0f);
-
- dy = y1 - sw->ty;
-
- adjust = dy * 0.15f;
- amount = fabs (dy) * 1.5f;
- if (amount < 0.5f)
- amount = 0.5f;
- else if (amount > 5.0f)
- amount = 5.0f;
-
- sw->yVelocity = (amount * sw->yVelocity + adjust) / (amount + 1.0f);
-
- ds = scale - sw->scale;
- adjust = ds * 0.1f;
- amount = fabs (ds) * 7.0f;
- if (amount < 0.01f)
- amount = 0.01f;
- else if (amount > 0.15f)
- amount = 0.15f;
-
- sw->scaleVelocity = (amount * sw->scaleVelocity + adjust) /
- (amount + 1.0f);
-
- dr = rot - sw->rotation;
- adjust = dr * 0.15f;
- amount = fabs (dr) * 1.5f;
- if (amount < 0.2f)
- amount = 0.2f;
- else if (amount > 2.0f)
- amount = 2.0f;
-
- sw->rotVelocity = (amount * sw->rotVelocity + adjust) / (amount + 1.0f);
-
- if (fabs (dx) < 0.1f && fabs (sw->xVelocity) < 0.2f &&
- fabs (dy) < 0.1f && fabs (sw->yVelocity) < 0.2f &&
- fabs (ds) < 0.001f && fabs (sw->scaleVelocity) < 0.002f &&
- fabs (dr) < 0.1f && fabs (sw->rotVelocity) < 0.2f)
- {
- sw->xVelocity = sw->yVelocity = sw->scaleVelocity = 0.0f;
- sw->tx = x1;
- sw->ty = y1;
- sw->rotation = rot;
- sw->scale = scale;
-
- return 0;
- }
-
- return 1;
-}
-
-static Bool
-stackswitchPaintOutput (CompScreen *s,
- const ScreenPaintAttrib *sAttrib,
- const CompTransform *transform,
- Region region,
- CompOutput *output,
- unsigned int mask)
-{
- Bool status;
- CompTransform sTransform = *transform;
-
- STACKSWITCH_SCREEN (s);
-
- if (ss->state != StackswitchStateNone || ss->rotation != 0.0)
- {
- mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
- mask |= PAINT_SCREEN_TRANSFORMED_MASK;
- mask |= PAINT_SCREEN_CLEAR_MASK;
- matrixTranslate (&sTransform, 0.0, -0.5, -DEFAULT_Z_CAMERA);
- matrixRotate (&sTransform, -ss->rotation, 1.0, 0.0, 0.0);
- matrixTranslate (&sTransform, 0.0, 0.5, DEFAULT_Z_CAMERA);
- }
-
- UNWRAP (ss, s, paintOutput);
- status = (*s->paintOutput) (s, sAttrib, &sTransform, region, output, mask);
- WRAP (ss, s, paintOutput, stackswitchPaintOutput);
-
- if (ss->state != StackswitchStateNone && (output->id == ~0 ||
- s->outputDev[s->currentOutputDev].id == output->id))
- {
- int i;
- CompWindow *aw = NULL;
-
- transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform);
- glPushMatrix ();
- glLoadMatrixf (sTransform.m);
-
- ss->paintingSwitcher = TRUE;
-
- for (i = 0; i < ss->nWindows; i++)
- {
- if (ss->drawSlots[i].slot && *(ss->drawSlots[i].slot))
- {
- CompWindow *w = ss->drawSlots[i].w;
- if (w->id == ss->selectedWindow)
- aw = w;
-
- (*s->paintWindow) (w, &w->paint, &sTransform,
- &infiniteRegion, 0);
- }
- }
-
-
- CompTransform tTransform = *transform;
- transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &tTransform);
- glLoadMatrixf (tTransform.m);
-
- if (ss->textData && (ss->state != StackswitchStateIn) && aw)
- stackswitchDrawWindowTitle (s, &sTransform, aw);
-
- ss->paintingSwitcher = FALSE;
-
- glPopMatrix ();
- }
-
- return status;
-}
-
-static void
-stackswitchPreparePaintScreen (CompScreen *s,
- int msSinceLastPaint)
-{
- STACKSWITCH_SCREEN (s);
-
- if (ss->state != StackswitchStateNone && (ss->moreAdjust || ss->rotateAdjust))
- {
- CompWindow *w;
- int steps;
- float amount, chunk;
-
- amount = msSinceLastPaint * 0.05f * stackswitchGetSpeed (s);
- steps = amount / (0.5f * stackswitchGetTimestep (s));
-
- if (!steps)
- steps = 1;
- chunk = amount / (float) steps;
-
- layoutThumbs (s);
- while (steps--)
- {
- ss->rotateAdjust = adjustStackswitchRotation (s, chunk);
- ss->moreAdjust = FALSE;
-
- for (w = s->windows; w; w = w->next)
- {
- STACKSWITCH_WINDOW (w);
-
- if (sw->adjust)
- {
- sw->adjust = adjustStackswitchVelocity (w);
-
- ss->moreAdjust |= sw->adjust;
-
- sw->tx += sw->xVelocity * chunk;
- sw->ty += sw->yVelocity * chunk;
- sw->scale += sw->scaleVelocity * chunk;
- sw->rotation += sw->rotVelocity * chunk;
- }
- else if (sw->slot)
- {
- sw->scale = sw->slot->scale;
- sw->tx = sw->slot->x;
- sw->ty = sw->slot->y;
- if (w->id == ss->selectedWindow)
- sw->rotation = ss->rotation;
- else
- sw->rotation = 0.0;
- }
- }
-
- if (!ss->moreAdjust && !ss->rotateAdjust)
- break;
- }
- }
-
- UNWRAP (ss, s, preparePaintScreen);
- (*s->preparePaintScreen) (s, msSinceLastPaint);
- WRAP (ss, s, preparePaintScreen, stackswitchPreparePaintScreen);
-}
-
-static void
-stackswitchDonePaintScreen (CompScreen *s)
-{
- STACKSWITCH_SCREEN (s);
-
- if (ss->state != StackswitchStateNone)
- {
- if (ss->moreAdjust)
- {
- damageScreen (s);
- }
- else
- {
- if (ss->rotateAdjust)
- damageScreen (s);
-
- if (ss->state == StackswitchStateIn)
- ss->state = StackswitchStateNone;
- else if (ss->state == StackswitchStateOut)
- ss->state = StackswitchStateSwitching;
- }
- }
-
- UNWRAP (ss, s, donePaintScreen);
- (*s->donePaintScreen) (s);
- WRAP (ss, s, donePaintScreen, stackswitchDonePaintScreen);
-}
-
-static Bool
-stackswitchTerminate (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
-
- for (s = d->screens; s; s = s->next)
- {
- STACKSWITCH_SCREEN (s);
-
- if (xid && s->root != xid)
- continue;
-
- if (ss->grabIndex)
- {
- removeScreenGrab (s, ss->grabIndex, 0);
- ss->grabIndex = 0;
- }
-
- if (ss->state != StackswitchStateNone)
- {
- CompWindow *w;
-
- for (w = s->windows; w; w = w->next)
- {
- STACKSWITCH_WINDOW (w);
-
- if (sw->slot)
- {
- free (sw->slot);
- sw->slot = NULL;
-
- sw->adjust = TRUE;
- }
- }
- ss->moreAdjust = TRUE;
- ss->state = StackswitchStateIn;
- damageScreen (s);
-
- if (!(state & CompActionStateCancel) && ss->selectedWindow)
- {
- w = findWindowAtScreen (s, ss->selectedWindow);
- if (w)
- sendWindowActivationRequest (s, w->id);
- }
- }
- }
-
- if (action)
- action->state &= ~(CompActionStateTermKey |
- CompActionStateTermButton |
- CompActionStateTermEdge);
-
- return FALSE;
-}
-
-static Bool
-stackswitchInitiate (CompScreen *s,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompWindow *w;
- CompMatch *match;
- int count;
-
- STACKSWITCH_SCREEN (s);
-
- if (otherScreenGrabExist (s, "stackswitch", 0))
- return FALSE;
-
- ss->currentMatch = stackswitchGetWindowMatch (s);
-
- match = getMatchOptionNamed (option, nOption, "match", NULL);
- if (match)
- {
- matchFini (&ss->match);
- matchInit (&ss->match);
- if (matchCopy (&ss->match, match))
- {
- matchUpdate (s->display, &ss->match);
- ss->currentMatch = &ss->match;
- }
- }
-
- count = stackswitchCountWindows (s);
-
- if (count < 1)
- return FALSE;
-
- if (!ss->grabIndex)
- {
- ss->grabIndex = pushScreenGrab (s, s->invisibleCursor, "stackswitch");
- }
-
- if (ss->grabIndex)
- {
- ss->state = StackswitchStateOut;
-
- if (!stackswitchCreateWindowList (s))
- return FALSE;
-
- ss->selectedWindow = ss->windows[0]->id;
- stackswitchRenderWindowTitle (s);
-
- for (w = s->windows; w; w = w->next)
- {
- STACKSWITCH_WINDOW (w);
-
- sw->tx = w->attrib.x - w->input.left;
- sw->ty = w->attrib.y + w->attrib.height + w->input.bottom;
- }
- ss->moreAdjust = TRUE;
- damageScreen (s);
- }
-
- return TRUE;
-}
-
-static Bool
-stackswitchDoSwitch (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption,
- Bool nextWindow,
- StackswitchType type)
-{
- CompScreen *s;
- Window xid;
- Bool ret = TRUE;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
-
- s = findScreenAtDisplay (d, xid);
- if (s)
- {
- STACKSWITCH_SCREEN (s);
-
- if ((ss->state == StackswitchStateNone) || (ss->state == StackswitchStateIn))
- {
- if (type == StackswitchTypeGroup)
- {
- CompWindow *w;
- w = findWindowAtDisplay (d, getIntOptionNamed (option, nOption,
- "window", 0));
- if (w)
- {
- ss->type = StackswitchTypeGroup;
- ss->clientLeader =
- (w->clientLeader) ? w->clientLeader : w->id;
- ret = stackswitchInitiate (s, action, state, option, nOption);
- }
- }
- else
- {
- ss->type = type;
- ret = stackswitchInitiate (s, action, state, option, nOption);
- }
-
- if (state & CompActionStateInitKey)
- action->state |= CompActionStateTermKey;
-
- if (state & CompActionStateInitEdge)
- action->state |= CompActionStateTermEdge;
- else if (state & CompActionStateInitButton)
- action->state |= CompActionStateTermButton;
- }
-
- if (ret)
- switchToWindow (s, nextWindow);
- }
-
- return ret;
-}
-
-static Bool
-stackswitchNext (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- return stackswitchDoSwitch (d, action, state, option, nOption,
- TRUE, StackswitchTypeNormal);
-}
-
-static Bool
-stackswitchPrev (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- return stackswitchDoSwitch (d, action, state, option, nOption,
- FALSE, StackswitchTypeNormal);
-}
-
-static Bool
-stackswitchNextAll (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- return stackswitchDoSwitch (d, action, state, option, nOption,
- TRUE, StackswitchTypeAll);
-}
-
-static Bool
-stackswitchPrevAll (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- return stackswitchDoSwitch (d, action, state, option, nOption,
- FALSE, StackswitchTypeAll);
-}
-
-static Bool
-stackswitchNextGroup (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- return stackswitchDoSwitch (d, action, state, option, nOption,
- TRUE, StackswitchTypeGroup);
-}
-
-static Bool
-stackswitchPrevGroup (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- return stackswitchDoSwitch (d, action, state, option, nOption,
- FALSE, StackswitchTypeGroup);
-}
-
-
-static void
-stackswitchWindowRemove (CompDisplay *d,
- Window id)
-{
- CompWindow *w;
-
- w = findWindowAtDisplay (d, id);
- if (w)
- {
- Bool inList = FALSE;
- int j, i = 0;
- Window selected;
-
- STACKSWITCH_SCREEN (w->screen);
-
- if (ss->state == StackswitchStateNone)
- return;
-
- if (isStackswitchWin (w))
- return;
-
- selected = ss->selectedWindow;
-
- while (i < ss->nWindows)
- {
- if (w->id == ss->windows[i]->id)
- {
- inList = TRUE;
-
- if (w->id == selected)
- {
- if (i < (ss->nWindows - 1))
- selected = ss->windows[i + 1]->id;
- else
- selected = ss->windows[0]->id;
-
- ss->selectedWindow = selected;
- }
-
- ss->nWindows--;
- for (j = i; j < ss->nWindows; j++)
- ss->windows[j] = ss->windows[j + 1];
- }
- else
- {
- i++;
- }
- }
-
- if (!inList)
- return;
-
- if (ss->nWindows == 0)
- {
- CompOption o;
-
- o.type = CompOptionTypeInt;
- o.name = "root";
- o.value.i = w->screen->root;
-
- stackswitchTerminate (d, NULL, 0, &o, 1);
- return;
- }
-
- if (!ss->grabIndex)
- return;
-
- if (stackswitchUpdateWindowList (w->screen))
- {
- ss->moreAdjust = TRUE;
- ss->state = StackswitchStateOut;
- damageScreen (w->screen);
- }
- }
-}
-
-static void
-stackswitchHandleEvent (CompDisplay *d,
- XEvent *event)
-{
- STACKSWITCH_DISPLAY (d);
-
- UNWRAP (sd, d, handleEvent);
- (*d->handleEvent) (d, event);
- WRAP (sd, d, handleEvent, stackswitchHandleEvent);
-
- switch (event->type) {
- case PropertyNotify:
- if (event->xproperty.atom == XA_WM_NAME)
- {
- CompWindow *w;
- w = findWindowAtDisplay (d, event->xproperty.window);
- if (w)
- {
- STACKSWITCH_SCREEN (w->screen);
- if (ss->grabIndex && (w->id == ss->selectedWindow))
- {
- stackswitchRenderWindowTitle (w->screen);
- damageScreen (w->screen);
- }
- }
- }
- break;
- case UnmapNotify:
- stackswitchWindowRemove (d, event->xunmap.window);
- break;
- case DestroyNotify:
- stackswitchWindowRemove (d, event->xdestroywindow.window);
- break;
- }
-}
-
-static Bool
-stackswitchDamageWindowRect (CompWindow *w,
- Bool initial,
- BoxPtr rect)
-{
- Bool status = FALSE;
- CompScreen *s = w->screen;
-
- STACKSWITCH_SCREEN (s);
-
- if (initial)
- {
- if (ss->grabIndex && isStackswitchWin (w))
- {
- stackswitchAddWindowToList (s, w);
- if (stackswitchUpdateWindowList (s))
- {
- STACKSWITCH_WINDOW (w);
-
- sw->adjust = TRUE;
- ss->moreAdjust = TRUE;
- ss->state = StackswitchStateOut;
- damageScreen (s);
- }
- }
- }
- else if (ss->state == StackswitchStateSwitching)
- {
- STACKSWITCH_WINDOW (w);
-
- if (sw->slot)
- {
- damageScreen (s);
- status = TRUE;
- }
- }
-
- UNWRAP (ss, s, damageWindowRect);
- status |= (*s->damageWindowRect) (w, initial, rect);
- WRAP (ss, s, damageWindowRect, stackswitchDamageWindowRect);
-
- return status;
-}
-
-static Bool
-stackswitchInitDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- StackswitchDisplay *sd;
- int index;
-
- if (!checkPluginABI ("core", CORE_ABIVERSION))
- return FALSE;
-
- sd = malloc (sizeof (StackswitchDisplay));
- if (!sd)
- return FALSE;
-
- sd->screenPrivateIndex = allocateScreenPrivateIndex (d);
- if (sd->screenPrivateIndex < 0)
- {
- free (sd);
- return FALSE;
- }
-
- if (checkPluginABI ("text", TEXT_ABIVERSION) &&
- getPluginDisplayIndex (d, "text", &index))
- {
- sd->textFunc = d->base.privates[index].ptr;
- }
- else
- {
- compLogMessage ("stackswitch", CompLogLevelWarn,
- "No compatible text plugin found.");
- sd->textFunc = NULL;
- }
-
- stackswitchSetNextKeyInitiate (d, stackswitchNext);
- stackswitchSetNextKeyTerminate (d, stackswitchTerminate);
- stackswitchSetPrevKeyInitiate (d, stackswitchPrev);
- stackswitchSetPrevKeyTerminate (d, stackswitchTerminate);
- stackswitchSetNextAllKeyInitiate (d, stackswitchNextAll);
- stackswitchSetNextAllKeyTerminate (d, stackswitchTerminate);
- stackswitchSetPrevAllKeyInitiate (d, stackswitchPrevAll);
- stackswitchSetPrevAllKeyTerminate (d, stackswitchTerminate);
- stackswitchSetNextGroupKeyInitiate (d, stackswitchNextGroup);
- stackswitchSetNextGroupKeyTerminate (d, stackswitchTerminate);
- stackswitchSetPrevGroupKeyInitiate (d, stackswitchPrevGroup);
- stackswitchSetPrevGroupKeyTerminate (d, stackswitchTerminate);
-
- stackswitchSetNextButtonInitiate (d, stackswitchNext);
- stackswitchSetNextButtonTerminate (d, stackswitchTerminate);
- stackswitchSetPrevButtonInitiate (d, stackswitchPrev);
- stackswitchSetPrevButtonTerminate (d, stackswitchTerminate);
- stackswitchSetNextAllButtonInitiate (d, stackswitchNextAll);
- stackswitchSetNextAllButtonTerminate (d, stackswitchTerminate);
- stackswitchSetPrevAllButtonInitiate (d, stackswitchPrevAll);
- stackswitchSetPrevAllButtonTerminate (d, stackswitchTerminate);
- stackswitchSetNextGroupButtonInitiate (d, stackswitchNextGroup);
- stackswitchSetNextGroupButtonTerminate (d, stackswitchTerminate);
- stackswitchSetPrevGroupButtonInitiate (d, stackswitchPrevGroup);
- stackswitchSetPrevGroupButtonTerminate (d, stackswitchTerminate);
-
- WRAP (sd, d, handleEvent, stackswitchHandleEvent);
-
- d->base.privates[StackswitchDisplayPrivateIndex].ptr = sd;
-
- return TRUE;
-}
-
-static void
-stackswitchFiniDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- STACKSWITCH_DISPLAY (d);
-
- freeScreenPrivateIndex (d, sd->screenPrivateIndex);
-
- UNWRAP (sd, d, handleEvent);
-
- free (sd);
-}
-
-static Bool
-stackswitchInitScreen (CompPlugin *p,
- CompScreen *s)
-{
- StackswitchScreen *ss;
-
- STACKSWITCH_DISPLAY (s->display);
-
- ss = malloc (sizeof (StackswitchScreen));
- if (!ss)
- return FALSE;
-
- ss->windowPrivateIndex = allocateWindowPrivateIndex (s);
- if (ss->windowPrivateIndex < 0)
- {
- free (ss);
- return FALSE;
- }
-
- ss->grabIndex = 0;
-
- ss->state = StackswitchStateNone;
-
- ss->windows = NULL;
- ss->drawSlots = NULL;
- ss->windowsSize = 0;
-
- ss->paintingSwitcher = FALSE;
-
- ss->selectedWindow = None;
-
- ss->moreAdjust = FALSE;
- ss->rotateAdjust = FALSE;
-
- ss->rVelocity = 0;
- ss->rotation = 0.0;
-
- ss->textData = NULL;
-
- matchInit (&ss->match);
-
- WRAP (ss, s, preparePaintScreen, stackswitchPreparePaintScreen);
- WRAP (ss, s, donePaintScreen, stackswitchDonePaintScreen);
- WRAP (ss, s, paintOutput, stackswitchPaintOutput);
- WRAP (ss, s, paintWindow, stackswitchPaintWindow);
- WRAP (ss, s, damageWindowRect, stackswitchDamageWindowRect);
-
- s->base.privates[sd->screenPrivateIndex].ptr = ss;
-
- return TRUE;
-}
-
-static void
-stackswitchFiniScreen (CompPlugin *p,
- CompScreen *s)
-{
- STACKSWITCH_SCREEN (s);
-
- freeWindowPrivateIndex (s, ss->windowPrivateIndex);
-
- UNWRAP (ss, s, preparePaintScreen);
- UNWRAP (ss, s, donePaintScreen);
- UNWRAP (ss, s, paintOutput);
- UNWRAP (ss, s, paintWindow);
- UNWRAP (ss, s, damageWindowRect);
-
- matchFini (&ss->match);
-
- stackswitchFreeWindowTitle (s);
-
- if (ss->windows)
- free (ss->windows);
-
- if (ss->drawSlots)
- free (ss->drawSlots);
-
- free (ss);
-}
-
-static Bool
-stackswitchInitWindow (CompPlugin *p,
- CompWindow *w)
-{
- StackswitchWindow *sw;
-
- STACKSWITCH_SCREEN (w->screen);
-
- sw = malloc (sizeof (StackswitchWindow));
- if (!sw)
- return FALSE;
-
- sw->slot = 0;
- sw->scale = 1.0f;
- sw->tx = sw->ty = 0.0f;
- sw->adjust = FALSE;
- sw->xVelocity = sw->yVelocity = 0.0f;
- sw->scaleVelocity = 0.0f;
- sw->rotation = 0.0f;
- sw->rotVelocity = 0.0f;
-
- w->base.privates[ss->windowPrivateIndex].ptr = sw;
-
- return TRUE;
-}
-
-static void
-stackswitchFiniWindow (CompPlugin *p,
- CompWindow *w)
-{
- STACKSWITCH_WINDOW (w);
-
- if (sw->slot)
- free (sw->slot);
-
- free (sw);
-}
-
-static CompBool
-stackswitchInitObject (CompPlugin *p,
- CompObject *o)
-{
- static InitPluginObjectProc dispTab[] = {
- (InitPluginObjectProc) 0, /* InitCore */
- (InitPluginObjectProc) stackswitchInitDisplay,
- (InitPluginObjectProc) stackswitchInitScreen,
- (InitPluginObjectProc) stackswitchInitWindow
- };
-
- RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
-}
-
-static void
-stackswitchFiniObject (CompPlugin *p,
- CompObject *o)
-{
- static FiniPluginObjectProc dispTab[] = {
- (FiniPluginObjectProc) 0, /* FiniCore */
- (FiniPluginObjectProc) stackswitchFiniDisplay,
- (FiniPluginObjectProc) stackswitchFiniScreen,
- (FiniPluginObjectProc) stackswitchFiniWindow
- };
-
- DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
-}
-
-static Bool
-stackswitchInit (CompPlugin *p)
-{
- StackswitchDisplayPrivateIndex = allocateDisplayPrivateIndex ();
- if (StackswitchDisplayPrivateIndex < 0)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-stackswitchFini (CompPlugin *p)
-{
- freeDisplayPrivateIndex (StackswitchDisplayPrivateIndex);
-}
-
-CompPluginVTable stackswitchVTable = {
- "stackswitch",
- 0,
- stackswitchInit,
- stackswitchFini,
- stackswitchInitObject,
- stackswitchFiniObject,
- 0,
- 0
-};
-
-CompPluginVTable *
-getCompPluginInfo (void)
-{
- return &stackswitchVTable;
-}
diff --git a/stackswitch.xml.in b/stackswitch.xml.in
index 0851b07..bd48d7a 100644
--- a/stackswitch.xml.in
+++ b/stackswitch.xml.in
@@ -8,8 +8,12 @@
<relation type="after">
<plugin>text</plugin>
</relation>
+ <requirement>
+ <plugin>composite</plugin>
+ <plugin>opengl</plugin>
+ </requirement>
</deps>
- <display>
+ <options>
<group>
<_short>Key bindings</_short>
<option name="next_key" type="key">
@@ -65,8 +69,6 @@
<_long>Show switcher if not visible and select previous window of the current application.</_long>
</option>
</group>
- </display>
- <screen>
<group>
<_short>Behavior</_short>
<option name="speed" type="float">
@@ -184,6 +186,6 @@
</desc>
</option>
</group>
- </screen>
+ </options>
</plugin>
</compiz>