summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@XPS-FEDORA.(none)>2009-08-15 13:36:52 +0800
committerSam Spilsbury <smspillaz@XPS-FEDORA.(none)>2009-08-15 13:36:52 +0800
commitdd11c33d03e1e0ead4d8654f591813219e8a3322 (patch)
treef5252e57abdd6d79be01e33098dbcbd0a278ccb6
parentc00a0c74e343d45d9382e0183070bcc41cb87c88 (diff)
downloadshelf-dd11c33d03e1e0ead4d8654f591813219e8a3322.tar.gz
shelf-dd11c33d03e1e0ead4d8654f591813219e8a3322.tar.bz2
Initial C++ port. Window Shape restore and IPW adjustment are currently broken for reasons I cannot determine.
-rw-r--r--CMakeLists.txt6
-rw-r--r--Makefile533
-rw-r--r--plugin.info2
-rw-r--r--shelf.c1056
-rw-r--r--shelf.xml.in4
-rw-r--r--src/shelf.cpp853
-rw-r--r--src/shelf.h232
7 files changed, 1091 insertions, 1595 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 18be475..a7b31fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,5 @@
-include (CompizFusion)
+find_package (Compiz REQUIRED)
-compiz_fusion_plugin (shelf)
+include (CompizPlugin)
+
+compiz_plugin (shelf PLUGINDEPS composite opengl)
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 f9172ac..0000000
--- a/plugin.info
+++ /dev/null
@@ -1,2 +0,0 @@
-PLUGIN = shelf
-
diff --git a/shelf.c b/shelf.c
deleted file mode 100644
index e6b636c..0000000
--- a/shelf.c
+++ /dev/null
@@ -1,1056 +0,0 @@
-/*
- * Compiz Fusion Shelf plugin
- *
- * Copyright (C) 2007 Canonical Ltd.
- *
- * 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.
- *
- * Author(s):
- * Kristian Lyngstøl <kristian@bohemians.org>
- * Danny Baumann <maniac@opencompositing.org>
- *
- * Description:
- *
- * This plugin visually resizes a window to allow otherwise obtrusive
- * windows to be visible in a monitor-fashion. Use case: Anything with
- * progress bars, notification programs, etc.
- *
- * Todo:
- * - Check for XShape events
- * - Handle input in a sane way
- * - Mouse-over?
- */
-
-#include <compiz-core.h>
-#include <X11/extensions/shape.h>
-#include <X11/cursorfont.h>
-#include <math.h>
-#include <string.h>
-#include "shelf_options.h"
-
-typedef struct _ShelfedWindowInfo {
- CompWindow *w;
- struct _ShelfedWindowInfo *next;
-
- Window ipw;
-
- XRectangle *inputRects;
- int nInputRects;
- int inputRectOrdering;
-
- XRectangle *frameInputRects;
- int frameNInputRects;
- int frameInputRectOrdering;
-} ShelfedWindowInfo;
-
-typedef struct {
- float scale;
- float targetScale;
- float steps;
-
- ShelfedWindowInfo *info;
-} ShelfWindow;
-
-typedef struct {
- int windowPrivateIndex;
-
- int grabIndex;
- Window grabbedWindow;
-
- Cursor moveCursor;
-
- int lastPointerX;
- int lastPointerY;
-
- ShelfedWindowInfo *shelfedWindows;
-
- PaintWindowProc paintWindow;
- PaintOutputProc paintOutput;
- DamageWindowRectProc damageWindowRect;
- PreparePaintScreenProc preparePaintScreen;
- WindowMoveNotifyProc windowMoveNotify;
-} ShelfScreen;
-
-typedef struct {
- int screenPrivateIndex;
-
- HandleEventProc handleEvent;
-} ShelfDisplay;
-
-static int displayPrivateIndex;
-
-#define GET_SHELF_DISPLAY(d) \
- ((ShelfDisplay *) (d)->base.privates[displayPrivateIndex].ptr)
-#define SHELF_DISPLAY(d) \
- ShelfDisplay *sd = GET_SHELF_DISPLAY (d)
-#define GET_SHELF_SCREEN(s, sd) \
- ((ShelfScreen *) (s)->base.privates[(sd)->screenPrivateIndex].ptr)
-#define SHELF_SCREEN(s) \
- ShelfScreen *ss = GET_SHELF_SCREEN (s, GET_SHELF_DISPLAY (s->display))
-#define GET_SHELF_WINDOW(w, ss) \
- ((ShelfWindow *) (w)->base.privates[(ss)->windowPrivateIndex].ptr)
-#define SHELF_WINDOW(w) \
- ShelfWindow *sw = GET_SHELF_WINDOW (w, \
- GET_SHELF_SCREEN (w->screen, \
- GET_SHELF_DISPLAY (w->screen->display)))
-
-#define SHELF_MIN_SIZE 50.0f // Minimum pixelsize a window can be scaled to
-
-/* Checks if w is a ipw and returns the real window */
-static CompWindow *
-shelfGetRealWindow (CompWindow *w)
-{
- ShelfedWindowInfo *run;
-
- SHELF_SCREEN (w->screen);
-
- for (run = ss->shelfedWindows; run; run = run->next)
- {
- if (w->id == run->ipw)
- return run->w;
- }
-
- return NULL;
-}
-
-static void
-shelfSaveInputShape (CompWindow *w,
- XRectangle **retRects,
- int *retCount,
- int *retOrdering)
-{
- XRectangle *rects;
- int count = 0, ordering;
- Display *dpy = w->screen->display->display;
-
- rects = XShapeGetRectangles (dpy, w->id, ShapeInput, &count, &ordering);
-
- /* check if the returned shape exactly matches the window shape -
- if that is true, the window currently has no set input shape */
- if ((count == 1) &&
- (rects[0].x == -w->serverBorderWidth) &&
- (rects[0].y == -w->serverBorderWidth) &&
- (rects[0].width == (w->serverWidth + w->serverBorderWidth)) &&
- (rects[0].height == (w->serverHeight + w->serverBorderWidth)))
- {
- count = 0;
- }
-
- *retRects = rects;
- *retCount = count;
- *retOrdering = ordering;
-}
-
-/* Shape the input of the window when scaled.
- * Since the IPW will be dealing with the input, removing input
- * from the window entirely is a perfectly good solution. */
-static void
-shelfShapeInput (CompWindow *w)
-{
- CompWindow *fw;
- Display *dpy = w->screen->display->display;
-
- SHELF_WINDOW (w);
-
- /* save old shape */
- shelfSaveInputShape (w, &sw->info->inputRects,
- &sw->info->nInputRects, &sw->info->inputRectOrdering);
-
- fw = findWindowAtDisplay (w->screen->display, w->frame);
- if (fw)
- {
- shelfSaveInputShape(fw, &sw->info->frameInputRects,
- &sw->info->frameNInputRects,
- &sw->info->frameInputRectOrdering);
- }
- else
- {
- sw->info->frameInputRects = NULL;
- sw->info->frameNInputRects = -1;
- sw->info->frameInputRectOrdering = 0;
- }
-
- /* clear shape */
- XShapeSelectInput (dpy, w->id, NoEventMask);
- XShapeCombineRectangles (dpy, w->id, ShapeInput, 0, 0,
- NULL, 0, ShapeSet, 0);
-
- if (w->frame)
- XShapeCombineRectangles (dpy, w->frame, ShapeInput, 0, 0,
- NULL, 0, ShapeSet, 0);
-
- XShapeSelectInput (dpy, w->id, ShapeNotify);
-}
-
-static void
-shelfUnshapeInput (CompWindow *w)
-{
- Display *dpy = w->screen->display->display;
-
- SHELF_WINDOW (w);
-
- if (sw->info->nInputRects)
- {
- XShapeCombineRectangles (dpy, w->id, ShapeInput, 0, 0,
- sw->info->inputRects, sw->info->nInputRects,
- ShapeSet, sw->info->inputRectOrdering);
- }
- else
- {
- XShapeCombineMask (dpy, w->id, ShapeInput, 0, 0, None, ShapeSet);
- }
-
- if (sw->info->frameNInputRects >= 0)
- {
- if (sw->info->frameInputRects)
- {
- XShapeCombineRectangles (dpy, w->frame, ShapeInput, 0, 0,
- sw->info->frameInputRects,
- sw->info->frameNInputRects,
- ShapeSet,
- sw->info->frameInputRectOrdering);
- }
- else
- {
- XShapeCombineMask (dpy, w->frame, ShapeInput, 0, 0, None, ShapeSet);
- }
- }
-}
-
-static void
-shelfPreparePaintScreen (CompScreen *s,
- int msSinceLastPaint)
-{
- CompWindow *w;
- float steps;
-
- SHELF_SCREEN (s);
-
- steps = (float)msSinceLastPaint / (float)shelfGetAnimtime(s->display);
-
- if (steps < 0.005)
- steps = 0.005;
-
- /* FIXME: should only loop over all windows if at least one animation
- is running */
- for (w = s->windows; w; w = w->next)
- GET_SHELF_WINDOW (w, ss)->steps = steps;
-
- UNWRAP (ss, s, preparePaintScreen);
- (*s->preparePaintScreen) (s, msSinceLastPaint);
- WRAP (ss, s, preparePaintScreen, shelfPreparePaintScreen);
-}
-
-static void
-shelfAddWindowToList (ShelfedWindowInfo *info)
-{
- CompScreen *s = info->w->screen;
- ShelfedWindowInfo *run;
-
- SHELF_SCREEN (s);
-
- run = ss->shelfedWindows;
- if (!run)
- ss->shelfedWindows = info;
- else
- {
- for (; run->next; run = run->next);
- run->next = info;
- }
-}
-
-static void
-shelfRemoveWindowFromList (ShelfedWindowInfo *info)
-{
- CompScreen *s = info->w->screen;
- ShelfedWindowInfo *run;
-
- SHELF_SCREEN (s);
-
- if (!ss->shelfedWindows)
- return;
-
- if (ss->shelfedWindows == info)
- ss->shelfedWindows = info->next;
- else
- {
- for (run = ss->shelfedWindows; run->next; run = run->next)
- {
- if (run->next == info)
- {
- run->next = info->next;
- break;
- }
- }
- }
-}
-
-/* Adjust size and location of the input prevention window
- */
-static void
-shelfAdjustIPW (CompWindow *w)
-{
- XWindowChanges xwc;
- Display *dpy = w->screen->display->display;
- float width, height;
-
- SHELF_WINDOW (w);
-
- if (!sw->info || !sw->info->ipw)
- return;
-
- width = w->width + 2 * w->attrib.border_width +
- w->input.left + w->input.right + 2.0f;
- width *= sw->targetScale;
- height = w->height + 2 * w->attrib.border_width +
- w->input.top + w->input.bottom + 2.0f;
- height *= sw->targetScale;
-
- xwc.x = w->attrib.x - w->input.left;
- xwc.y = w->attrib.y - w->input.top;
- xwc.width = (int) width;
- xwc.height = (int) height;
- xwc.stack_mode = Below;
- xwc.sibling = w->id;
-
- XConfigureWindow (dpy, sw->info->ipw,
- CWSibling | CWStackMode | CWX | CWY | CWWidth | CWHeight,
- &xwc);
-
- XMapWindow (dpy, sw->info->ipw);
-}
-
-static void
-shelfAdjustIPWStacking (CompScreen *s)
-{
- ShelfedWindowInfo *run;
-
- SHELF_SCREEN (s);
-
- for (run = ss->shelfedWindows; run; run = run->next)
- {
- if (!run->w->prev || run->w->prev->id != run->ipw)
- shelfAdjustIPW (run->w);
- }
-}
-
-/* Create an input prevention window */
-static void
-shelfCreateIPW (CompWindow *w)
-{
- Window ipw;
- XSetWindowAttributes attrib;
-
- SHELF_WINDOW (w);
-
- if (!sw->info || sw->info->ipw)
- return;
-
- attrib.override_redirect = TRUE;
- attrib.event_mask = 0;
-
- ipw = XCreateWindow (w->screen->display->display,
- w->screen->root,
- w->serverX - w->input.left,
- w->serverY - w->input.top,
- w->serverWidth + w->input.left + w->input.right,
- w->serverHeight + w->input.top + w->input.bottom,
- 0, CopyFromParent, InputOnly, CopyFromParent,
- CWEventMask | CWOverrideRedirect,
- &attrib);
-
- sw->info->ipw = ipw;
-}
-
-static Bool
-shelfHandleShelfInfo (CompWindow *w)
-{
- SHELF_WINDOW (w);
-
- if (sw->targetScale == 1.0f && sw->info)
- {
- if (sw->info->ipw)
- XDestroyWindow (w->screen->display->display, sw->info->ipw);
-
- shelfUnshapeInput (w);
- shelfRemoveWindowFromList (sw->info);
-
- free (sw->info);
- sw->info = NULL;
-
- return FALSE;
- }
- else if (sw->targetScale != 1.0f && !sw->info)
- {
- sw->info = calloc (1, sizeof (ShelfedWindowInfo));
- if (!sw->info)
- return FALSE;
-
- sw->info->w = w;
- shelfShapeInput (w);
- shelfCreateIPW (w);
- shelfAddWindowToList (sw->info);
- }
-
- return TRUE;
-}
-
-/* Sets the scale level and adjust the shape */
-static void
-shelfScaleWindow (CompWindow *w,
- float scale)
-{
- SHELF_WINDOW (w);
-
- if (w->wmType & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
- return;
-
- sw->targetScale = MIN (scale, 1.0f);
-
- if ((float) w->width * sw->targetScale < SHELF_MIN_SIZE)
- sw->targetScale = SHELF_MIN_SIZE / (float) w->width;
-
- if (shelfHandleShelfInfo (w))
- shelfAdjustIPW (w);
-
- addWindowDamage (w);
-}
-
-/* Binding for toggle mode.
- * Toggles through three preset scale levels,
- * currently hard coded to 1.0f (no scale), 0.5f and 0.25f.
- */
-static Bool
-shelfTrigger (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompWindow *w = findWindowAtDisplay (d, d->activeWindow);
- if (!w)
- return TRUE;
-
- SHELF_WINDOW (w);
-
- if (sw->targetScale > 0.5f)
- shelfScaleWindow (w, 0.5f);
- else if (sw->targetScale <= 0.5f && sw->targetScale > 0.25)
- shelfScaleWindow (w, 0.25f);
- else
- shelfScaleWindow (w, 1.0f);
-
- return TRUE;
-}
-
-/* Reset window to 1.0f scale */
-static Bool
-shelfReset (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompWindow *w = findWindowAtDisplay (d, d->activeWindow);
- if (!w)
- return TRUE;
-
- shelfScaleWindow (w, 1.0f);
- return TRUE;
-}
-
-/* Returns the ratio to multiply by to get a window that's 1/ration the
- * size of the screen.
- */
-static inline float
-shelfRat (CompWindow *w,
- float ratio)
-{
- float winHeight = (float) w->height;
- float winWidth = (float) w->width;
- float screenHeight = (float) w->screen->height;
- float screenWidth = (float) w->screen->width;
- float ret;
-
- if (winHeight / screenHeight < winWidth / screenWidth)
- ret = screenWidth / winWidth;
- else
- ret = screenHeight / winHeight;
-
- return ret / ratio;
-}
-
-static Bool
-shelfTriggerScreen (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompWindow *w = findWindowAtDisplay (d, d->activeWindow);
- if (!w)
- return TRUE;
-
- SHELF_WINDOW (w);
-
- /* FIXME: better should save calculated ratio and reuse it */
- if (sw->targetScale > shelfRat (w, 2.0f))
- shelfScaleWindow (w, shelfRat (w, 2.0f));
- else if (sw->targetScale <= shelfRat (w, 2.0f) &&
- sw->targetScale > shelfRat (w, 3.0f))
- shelfScaleWindow (w, shelfRat (w, 3.0f));
- else if (sw->targetScale <= shelfRat (w, 3.0f) &&
- sw->targetScale > shelfRat (w, 6.0f))
- shelfScaleWindow (w, shelfRat (w, 6.0f));
- else
- shelfScaleWindow (w, 1.0f);
-
- return TRUE;
-}
-
-/* shelfInc and shelfDec are matcing functions and bindings;
- * They increase and decrease the scale factor by 'interval'.
- */
-static Bool
-shelfInc (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompWindow *w = findWindowAtDisplay (d, d->activeWindow);
- if (!w)
- return TRUE;
-
- SHELF_WINDOW (w);
-
- shelfScaleWindow (w, sw->targetScale / shelfGetInterval (d));
-
- return TRUE;
-}
-
-static Bool
-shelfDec (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompWindow *w = findWindowAtDisplay (d, d->activeWindow);
- if (!w)
- return TRUE;
-
- SHELF_WINDOW (w);
-
- shelfScaleWindow (w, sw->targetScale * shelfGetInterval (d));
-
- return TRUE;
-}
-
-static void
-handleButtonPress (CompWindow *w,
- unsigned int x,
- unsigned int y)
-{
- CompScreen *s = w->screen;
-
- SHELF_SCREEN (s);
-
- if (!otherScreenGrabExist (s, "shelf", 0))
- {
- (*s->activateWindow) (w);
- ss->grabbedWindow = w->id;
- ss->grabIndex = pushScreenGrab (s, ss->moveCursor, "shelf");
-
- ss->lastPointerX = x;
- ss->lastPointerY = y;
- }
-}
-
-static void
-handleMotionEvent (CompScreen *s,
- unsigned int x,
- unsigned int y)
-{
- CompWindow *w;
- unsigned int dx, dy;
- SHELF_SCREEN (s);
-
- if (!ss->grabIndex)
- return;
-
- w = findWindowAtScreen (s, ss->grabbedWindow);
- if (!w)
- return;
-
- dx = x - ss->lastPointerX;
- dy = y - ss->lastPointerY;
-
- moveWindow (w, dx, dy, TRUE, FALSE);
- syncWindowPosition (w);
-
- ss->lastPointerX += dx;
- ss->lastPointerY += dy;
-}
-
-static void
-handleButtonRelease (CompWindow *w)
-{
- CompScreen *s = w->screen;
-
- SHELF_SCREEN (s);
-
- ss->grabbedWindow = None;
- if (ss->grabIndex)
- {
- moveInputFocusToWindow (w);
- removeScreenGrab (s, ss->grabIndex, NULL);
- ss->grabIndex = 0;
- }
-}
-
-static void
-handleWindowEnter (CompWindow *w,
- XEvent *event)
-{
- XEvent enterEvent;
-
- memcpy (&enterEvent.xcrossing, &event->xcrossing,
- sizeof (XCrossingEvent));
- enterEvent.xcrossing.window = w->id;
-
- XSendEvent (w->screen->display->display, w->id,
- FALSE, EnterWindowMask, &enterEvent);
-}
-
-static CompWindow *
-shelfFindRealWindowID (CompDisplay *d,
- Window wid)
-{
- CompWindow *orig;
-
- orig = findWindowAtDisplay (d, wid);
- if (!orig)
- return NULL;
-
- return shelfGetRealWindow (orig);
-}
-
-static void
-shelfHandleEvent (CompDisplay *d,
- XEvent *event)
-{
- CompWindow *w, *oldPrev, *oldNext;
- CompScreen *s;
-
- SHELF_DISPLAY (d);
-
- switch (event->type)
- {
- case EnterNotify:
- w = shelfFindRealWindowID (d, event->xcrossing.window);
- if (w)
- handleWindowEnter (w, event);
- break;
- case ButtonPress:
- w = shelfFindRealWindowID (d, event->xbutton.window);
- if (w)
- handleButtonPress (w,
- event->xbutton.x_root,
- event->xbutton.y_root);
- break;
- case ButtonRelease:
- s = findScreenAtDisplay (d, event->xbutton.root);
- if (s)
- {
- SHELF_SCREEN (s);
- w = findWindowAtDisplay (d, ss->grabbedWindow);
- if (w)
- handleButtonRelease (w);
- }
- break;
- case MotionNotify:
- s = findScreenAtDisplay (d, event->xmotion.root);
- if (s)
- handleMotionEvent (s,
- event->xmotion.x_root,
- event->xmotion.y_root);
- break;
- case ConfigureNotify:
- w = findWindowAtDisplay (d, event->xconfigure.window);
- if (w)
- {
- oldPrev = w->prev;
- oldNext = w->next;
- }
- break;
- }
-
- UNWRAP (sd, d, handleEvent);
- (*d->handleEvent) (d, event);
- WRAP (sd, d, handleEvent, shelfHandleEvent);
-
- switch (event->type)
- {
- case ConfigureNotify:
- if (w) /* already assigned above */
- {
- if (w->prev != oldPrev || w->next != oldNext)
- {
- /* restacking occured, ensure ipw stacking */
- shelfAdjustIPWStacking (w->screen);
- }
- }
- break;
- }
-}
-
-/* The window was damaged, adjust the damage to fit the actual area we
- * care about.
- */
-static Bool
-shelfDamageWindowRect (CompWindow *w,
- Bool initial,
- BoxPtr rect)
-{
- Bool status = FALSE;
- SHELF_SCREEN (w->screen);
- SHELF_WINDOW (w);
-
- if (sw->scale != 1.0f)
- {
- float xTranslate, yTranslate;
-
- xTranslate = w->input.left * (sw->scale - 1.0f);
- yTranslate = w->input.top * (sw->scale - 1.0f);
-
- damageTransformedWindowRect (w, sw->scale, sw->scale,
- xTranslate, yTranslate, rect);
- status = TRUE;
- }
-
- UNWRAP (ss, w->screen, damageWindowRect);
- status |= (*w->screen->damageWindowRect) (w, initial, rect);
- WRAP (ss, w->screen, damageWindowRect, shelfDamageWindowRect);
-
- return status;
-}
-
-/* Scale the window if it is supposed to be scaled.
- * Translate into place.
- *
- * FIXME: Merge the two translations.
- */
-static Bool
-shelfPaintWindow (CompWindow *w,
- const WindowPaintAttrib *attrib,
- const CompTransform *transform,
- Region region,
- unsigned int mask)
-{
- Bool status;
- CompScreen *s = w->screen;
-
- SHELF_SCREEN (s);
- SHELF_WINDOW (w);
-
- if (sw->targetScale != sw->scale && sw->steps)
- {
- sw->scale += (float) sw->steps * (sw->targetScale - sw->scale);
- if (fabsf (sw->targetScale - sw->scale) < 0.005)
- sw->scale = sw->targetScale;
- }
-
- if (sw->scale != 1.0f)
- {
- CompTransform mTransform = *transform;
- float xTranslate, yTranslate;
-
- xTranslate = w->input.left * (sw->scale - 1.0f);
- yTranslate = w->input.top * (sw->scale - 1.0f);
-
- matrixTranslate (&mTransform, w->attrib.x, w->attrib.y, 0);
- matrixScale (&mTransform, sw->scale, sw->scale, 0);
- matrixTranslate (&mTransform,
- xTranslate / sw->scale - w->attrib.x,
- yTranslate / sw->scale - w->attrib.y,
- 0.0f);
-
- mask |= PAINT_WINDOW_TRANSFORMED_MASK;
-
- /* FIXME: should better use DonePaintScreen for that */
- if (sw->scale != sw->targetScale)
- addWindowDamage (w);
-
- UNWRAP (ss, s, paintWindow);
- status = (*s->paintWindow) (w, attrib, &mTransform, region, mask);
- WRAP (ss, s, paintWindow, shelfPaintWindow);
- }
- else
- {
- UNWRAP (ss, s, paintWindow);
- status = (*s->paintWindow) (w, attrib, transform, region, mask);
- WRAP (ss, s, paintWindow, shelfPaintWindow);
- }
-
- return status;
-}
-
-static Bool
-shelfPaintOutput (CompScreen *s,
- const ScreenPaintAttrib *sAttrib,
- const CompTransform *transform,
- Region region,
- CompOutput *output,
- unsigned int mask)
-{
- Bool status;
-
- SHELF_SCREEN (s);
-
- if (ss->shelfedWindows)
- mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
-
- UNWRAP (ss, s, paintOutput);
- status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
- WRAP (ss, s, paintOutput, shelfPaintOutput);
-
- return status;
-}
-
-static void
-shelfWindowMoveNotify (CompWindow *w,
- int dx,
- int dy,
- Bool immediate)
-{
- SHELF_SCREEN (w->screen);
- SHELF_WINDOW (w);
-
- if (sw->targetScale != 1.00f)
- shelfAdjustIPW (w);
-
- UNWRAP (ss, w->screen, windowMoveNotify);
- (*w->screen->windowMoveNotify) (w, dx, dy, immediate);
- WRAP (ss, w->screen, windowMoveNotify, shelfWindowMoveNotify);
-}
-
-/* Configuration, initialization, boring stuff. --------------------- */
-static Bool
-shelfInitScreen (CompPlugin *p,
- CompScreen *s)
-{
- ShelfScreen *ss;
-
- SHELF_DISPLAY (s->display);
-
- ss = malloc (sizeof (ShelfScreen));
- if (!ss)
- return FALSE; // fixme: error message.
-
- ss->windowPrivateIndex = allocateWindowPrivateIndex (s);
- if (ss->windowPrivateIndex < 0)
- {
- free (ss);
- return FALSE;
- }
-
- ss->moveCursor = XCreateFontCursor (s->display->display, XC_fleur);
-
- ss->lastPointerX = 0;
- ss->lastPointerY = 0;
-
- ss->grabIndex = 0;
- ss->grabbedWindow = None;
- ss->shelfedWindows = NULL;
-
- WRAP (ss, s, preparePaintScreen, shelfPreparePaintScreen);
- WRAP (ss, s, paintWindow, shelfPaintWindow);
- WRAP (ss, s, paintOutput, shelfPaintOutput);
- WRAP (ss, s, damageWindowRect, shelfDamageWindowRect);
- WRAP (ss, s, windowMoveNotify, shelfWindowMoveNotify);
-
- s->base.privates[sd->screenPrivateIndex].ptr = ss;
-
- return TRUE;
-}
-
-static void
-shelfFiniScreen (CompPlugin *p,
- CompScreen *s)
-{
- SHELF_SCREEN (s);
-
- UNWRAP (ss, s, preparePaintScreen);
- UNWRAP (ss, s, paintWindow);
- UNWRAP (ss, s, paintOutput);
- UNWRAP (ss, s, damageWindowRect);
- UNWRAP (ss, s, windowMoveNotify);
-
- freeWindowPrivateIndex (s, ss->windowPrivateIndex);
-
- if (ss->moveCursor)
- XFreeCursor (s->display->display, ss->moveCursor);
-
- free (ss);
-}
-
-static Bool
-shelfInitDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- ShelfDisplay *sd;
-
- if (!checkPluginABI ("core", CORE_ABIVERSION))
- return FALSE;
-
- if (!d->shapeExtension)
- {
- compLogMessage ("shelf", CompLogLevelError,
- "No Shape extension found. Shelfing not possible.\n");
- return FALSE;
- }
-
- sd = malloc (sizeof (ShelfDisplay));
- if (!sd)
- return FALSE;
-
- sd->screenPrivateIndex = allocateScreenPrivateIndex (d);
- if (sd->screenPrivateIndex < 0)
- {
- free (sd);
- return FALSE;
- }
-
- shelfSetTriggerKeyInitiate (d, shelfTrigger);
- shelfSetResetKeyInitiate (d, shelfReset);
- shelfSetTriggerscreenKeyInitiate (d, shelfTriggerScreen);
- shelfSetIncButtonInitiate (d, shelfInc);
- shelfSetDecButtonInitiate (d, shelfDec);
-
- WRAP (sd, d, handleEvent, shelfHandleEvent);
-
- d->base.privates[displayPrivateIndex].ptr = sd;
-
- return TRUE;
-}
-
-static void
-shelfFiniDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- SHELF_DISPLAY (d);
-
- freeScreenPrivateIndex (d, sd->screenPrivateIndex);
-
- UNWRAP (sd, d, handleEvent);
-
- free (sd);
-}
-
-static void
-shelfFini (CompPlugin *p)
-{
- freeDisplayPrivateIndex (displayPrivateIndex);
-}
-
-static Bool
-shelfInit (CompPlugin *p)
-{
- displayPrivateIndex = allocateDisplayPrivateIndex ();
- if (displayPrivateIndex < 0)
- return FALSE;
-
- return TRUE;
-}
-
-static Bool
-shelfInitWindow (CompPlugin *p,
- CompWindow *w)
-{
- ShelfWindow *sw;
-
- SHELF_SCREEN (w->screen);
-
- sw = malloc (sizeof (ShelfWindow));
- if (!sw)
- return FALSE;
-
- sw->scale = 1.0f;
- sw->targetScale = 1.0f;
-
- sw->info = NULL;
-
- w->base.privates[ss->windowPrivateIndex].ptr = sw;
-
- return TRUE;
-}
-
-static void
-shelfFiniWindow (CompPlugin *p,
- CompWindow *w)
-{
- SHELF_WINDOW (w);
-
- if (sw->info)
- {
- sw->targetScale = 1.0f;
- /* implicitly frees sw->info */
- shelfHandleShelfInfo (w);
- }
-
- free (sw);
-}
-
-static CompBool
-shelfInitObject (CompPlugin *p,
- CompObject *o)
-{
- static InitPluginObjectProc dispTab[] = {
- (InitPluginObjectProc) 0, /* InitCore */
- (InitPluginObjectProc) shelfInitDisplay,
- (InitPluginObjectProc) shelfInitScreen,
- (InitPluginObjectProc) shelfInitWindow
- };
-
- RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
-}
-
-static void
-shelfFiniObject (CompPlugin *p,
- CompObject *o)
-{
- static FiniPluginObjectProc dispTab[] = {
- (FiniPluginObjectProc) 0, /* InitCore */
- (FiniPluginObjectProc) shelfFiniDisplay,
- (FiniPluginObjectProc) shelfFiniScreen,
- (FiniPluginObjectProc) shelfFiniWindow
- };
-
- DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
-}
-
-CompPluginVTable shelfVTable = {
- "shelf",
- 0,
- shelfInit,
- shelfFini,
- shelfInitObject,
- shelfFiniObject,
- 0,
- 0
-};
-
-CompPluginVTable*
-getCompPluginInfo (void)
-{
- return &shelfVTable;
-}
diff --git a/shelf.xml.in b/shelf.xml.in
index c968213..e4b5ea3 100644
--- a/shelf.xml.in
+++ b/shelf.xml.in
@@ -9,7 +9,7 @@
<plugin>wall</plugin>
</relation>
</deps>
- <display>
+ <options>
<group>
<_short>Bindings</_short>
<option name="trigger_key" type="key">
@@ -52,6 +52,6 @@
<max>0.999</max>
<precision>0.001</precision>
</option>
- </display>
+ </options>
</plugin>
</compiz>
diff --git a/src/shelf.cpp b/src/shelf.cpp
new file mode 100644
index 0000000..d42b293
--- /dev/null
+++ b/src/shelf.cpp
@@ -0,0 +1,853 @@
+/*
+ * Compiz Shelf plugin
+ *
+ * shelf.h
+ *
+ * Copyright (C) 2007 Canonical Ltd.
+ *
+ * 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.
+ *
+ * Author(s):
+ * Kristian Lyngstøl <kristian@bohemians.org>
+ * Danny Baumann <maniac@opencompositing.org>
+ * Sam Spilsbury <smspillaz@gmail.com>
+ *
+ * Description:
+ *
+ * This plugin visually resizes a window to allow otherwise obtrusive
+ * windows to be visible in a monitor-fashion. Use case: Anything with
+ * progress bars, notification programs, etc.
+ *
+ * Todo:
+ * - Check for XShape events
+ * - Handle input in a sane way
+ * - Mouse-over?
+ */
+
+#include "shelf.h"
+
+COMPIZ_PLUGIN_20090315 (shelf, ShelfPluginVTable);
+
+/* Enables / Disables screen paint functions */
+static void
+toggleScreenFunctions (bool enabled)
+{
+ SHELF_SCREEN (screen);
+
+ screen->handleEventSetEnabled (ss, enabled);
+ ss->cScreen->preparePaintSetEnabled (ss, enabled);
+ ss->gScreen->glPaintOutputSetEnabled (ss, enabled);
+ ss->cScreen->donePaintSetEnabled (ss, enabled);
+}
+
+static void
+toggleWindowFunctions (CompWindow *w, bool enabled)
+{
+ SHELF_WINDOW (w);
+
+ sw->window->moveNotifySetEnabled (sw, enabled);
+ sw->cWindow->damageRectSetEnabled (sw, enabled);
+ sw->gWindow->glPaintSetEnabled (sw, enabled);
+}
+
+/* Checks if w is a ipw and returns the real window */
+CompWindow *
+ShelfWindow::getRealWindow ()
+{
+ ShelfedWindowInfo *run;
+
+ SHELF_SCREEN (screen);
+
+ foreach (run, ss->shelfedWindows)
+ {
+ if (window->id () == run->ipw)
+ return run->w;
+ }
+
+ return NULL;
+}
+
+void
+ShelfWindow::saveInputShape (XRectangle **retRects,
+ int *retCount,
+ int *retOrdering)
+{
+ XRectangle *rects;
+ int count = 0, ordering;
+ Display *dpy = screen->dpy ();
+
+ rects = XShapeGetRectangles (dpy, window->id (), ShapeInput, &count, &ordering);
+
+ /* check if the returned shape exactly matches the window shape -
+ if that is true, the window currently has no set input shape */
+ if ((count == 1) &&
+ (rects[0].x == -window->serverGeometry ().border ()) &&
+ (rects[0].y == -window->serverGeometry ().border ()) &&
+ (rects[0].width == (window->serverWidth () +
+ window->serverGeometry ().border ())) &&
+ (rects[0].height == (window->serverHeight () +
+ window->serverGeometry (). border ())))
+ {
+ count = 0;
+ }
+
+ *retRects = rects;
+ *retCount = count;
+ *retOrdering = ordering;
+}
+
+/* Shape the input of the window when scaled.
+ * Since the IPW will be dealing with the input, removing input
+ * from the window entirely is a perfectly good solution. */
+void
+ShelfWindow::shapeInput ()
+{
+ CompWindow *fw;
+ Display *dpy = screen->dpy ();
+
+ /* save old shape */
+ saveInputShape (&info->inputRects,
+ &info->nInputRects, &info->inputRectOrdering);
+
+ if (info->nInputRects)
+ fprintf (stderr, "saved nInputRects\n");
+
+ fprintf (stderr, "shaped\n");
+
+ fw = screen->findWindow (window->frame ());
+ if (fw)
+ {
+ saveInputShape(&info->frameInputRects,
+ &info->frameNInputRects,
+ &info->frameInputRectOrdering);
+ }
+ else
+ {
+ info->frameInputRects = NULL;
+ info->frameNInputRects = -1;
+ info->frameInputRectOrdering = 0;
+ }
+
+ /* clear shape */
+ XShapeSelectInput (dpy, window->id (), NoEventMask);
+ XShapeCombineRectangles (dpy, window->id (), ShapeInput, 0, 0,
+ NULL, 0, ShapeSet, 0);
+
+ if (window->frame ())
+ XShapeCombineRectangles (dpy, window->frame (), ShapeInput, 0, 0,
+ NULL, 0, ShapeSet, 0);
+
+ XShapeSelectInput (dpy, window->id (), ShapeNotify);
+}
+
+#warning: function ShelfWindow::unshapeInput is broken
+/* This function is broken.
+ * What should happen is that no custom shape was defined, so nInputRects should
+ * be 0 and calling XShapeCombineMask should restore the original shape. However,
+ * it doesn't actually seem to and the window's input shape remains cleared
+ */
+void
+ShelfWindow::unshapeInput ()
+{
+ Display *dpy = screen->dpy ();
+
+ if (info->nInputRects)
+ {
+ XShapeCombineRectangles (dpy, window->id (), ShapeInput, 0, 0,
+ info->inputRects, info->nInputRects,
+ ShapeSet, info->inputRectOrdering);
+ fprintf (stderr, "unshaped window by restoring rects\n");
+ }
+ else
+ {
+ XShapeCombineMask (dpy, window->id (), ShapeInput, 0, 0, None, ShapeSet);
+ fprintf (stderr, "unshaped window by setting shape\n");
+ }
+
+ if (info->frameNInputRects >= 0)
+ {
+ if (info->frameInputRects)
+ {
+ XShapeCombineRectangles (dpy, window->frame (), ShapeInput, 0, 0,
+ info->frameInputRects,
+ info->frameNInputRects,
+ ShapeSet,
+ info->frameInputRectOrdering);
+ }
+ else
+ {
+ XShapeCombineMask (dpy, window->frame (), ShapeInput, 0, 0, None,
+ ShapeSet);
+ }
+ }
+}
+
+void
+ShelfScreen::preparePaint (int msSinceLastPaint)
+{
+ float steps;
+
+ steps = (float) msSinceLastPaint / (float) optionGetAnimtime ();
+
+ if (steps < 0.005)
+ steps = 0.005;
+
+ /* FIXME: should only loop over all windows if at least one animation
+ is running */
+ foreach (CompWindow *w, screen->windows ())
+ ShelfWindow::get (w)->steps = steps;
+
+ cScreen->preparePaint (msSinceLastPaint);
+}
+
+void
+ShelfScreen::addWindowToList (ShelfedWindowInfo *info)
+{
+ shelfedWindows.push_back (info);
+}
+
+void
+ShelfScreen::removeWindowFromList (ShelfedWindowInfo *info)
+{
+ shelfedWindows.remove (info);
+}
+
+/* Adjust size and location of the input prevention window
+ */
+
+#warning: function ShelfWindow::adjustIPW is broken
+
+/* This function is broken.
+ * For some reason, even though the IPW should be of the correct size (as shown
+ * by the fprintfs, it seems that it does not actually 'configure' - so it could
+ * be moved but it will still be in the same place. Perhaps the new restack code
+ * has broken it?
+ */
+void
+ShelfWindow::adjustIPW ()
+{
+ //fprintf (stderr, "adjustIPW\n");
+ XWindowChanges xwc;
+ Display *dpy = screen->dpy ();
+ float width, height;
+
+ if (!info || !info->ipw)
+ return;
+
+ fprintf (stderr, "adjusting\n");
+
+ width = window->width () + 2 * window->geometry ().border () +
+ window->input ().left + window->input ().right + 2.0f;
+ fprintf (stderr, "width is %f\n", width);
+ width *= targetScale;
+ fprintf (stderr, "width is now %f\n", width);
+ height = window->height () + 2 * window->geometry ().border () +
+ window->input ().top + window->input ().bottom + 2.0f;
+ height *= targetScale;
+
+ xwc.x = window->x () - window->input ().left;
+ xwc.y = window->y () - window->input ().top;
+ xwc.width = (int) width;
+ xwc.height = (int) height;
+ xwc.stack_mode = Above;
+ xwc.sibling = window->id ();
+
+ //fprintf (stderr, "width %f height %f x %i y %i\n", width, height, xwc.x, xwc.y);
+ //fprintf (stderr, "window props width %i height %i x %i y %i\n", window->width(), window->height(), window->x (),window->y());
+
+ XConfigureWindow (dpy, info->ipw,
+ CWSibling | CWStackMode | CWX | CWY | CWWidth | CWHeight,
+ &xwc);
+ XMapWindow (dpy, info->ipw);
+}
+
+void
+ShelfScreen::adjustIPWStacking ()
+{
+
+ foreach (ShelfedWindowInfo *run, shelfedWindows)
+ {
+ if (!run->w->prev || run->w->prev->id () != run->ipw)
+ ShelfWindow::get (run->w)->adjustIPW ();
+ }
+}
+
+/* Create an input prevention window */
+void
+ShelfWindow::createIPW ()
+{
+ Window ipw;
+ XSetWindowAttributes attrib;
+
+ if (!info || info->ipw)
+ return;
+
+ attrib.override_redirect = TRUE;
+ attrib.event_mask = 0;
+
+ ipw = XCreateWindow (screen->dpy (),
+ screen->root (),
+ window->serverX () - window->input ().left,
+ window->serverY () - window->input ().top,
+ window->serverWidth () +
+ window->input ().left +
+ window->input ().right,
+ window->serverHeight () + window->input ().top
+ + window->input ().bottom,
+ 0, CopyFromParent, InputOnly, CopyFromParent,
+ CWEventMask | CWOverrideRedirect,
+ &attrib);
+
+ info->ipw = ipw;
+}
+
+ShelfedWindowInfo::ShelfedWindowInfo (CompWindow *window) :
+ w (window),
+ ipw (None),
+ inputRects (NULL),
+ nInputRects (0),
+ inputRectOrdering (0),
+ frameInputRects (NULL),
+ frameNInputRects (0),
+ frameInputRectOrdering (0)
+{
+}
+
+ShelfedWindowInfo::~ShelfedWindowInfo ()
+{
+}
+
+
+bool
+ShelfWindow::handleShelfInfo ()
+{
+ SHELF_SCREEN (screen);
+
+ if (targetScale == 1.0f && info)
+ {
+ if (info->ipw)
+ XDestroyWindow (screen->dpy (), info->ipw);
+
+ unshapeInput ();
+ ss->removeWindowFromList (info);
+
+ delete info;
+ info = NULL;
+
+ return false;
+ }
+ else if (targetScale != 1.0f && !info)
+ {
+ info = new ShelfedWindowInfo (window);
+ if (!info)
+ return false;
+
+ shapeInput ();
+ createIPW ();
+ ss->addWindowToList (info);
+ fprintf (stderr, "created IPW\n");
+ }
+
+ return true;
+}
+
+/* Sets the scale level and adjust the shape */
+void
+ShelfWindow::scale (float fScale)
+{
+ if (window->wmType () & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
+ return;
+
+ targetScale = MIN (fScale, 1.0f);
+
+ if ((float) window->width () * targetScale < SHELF_MIN_SIZE)
+ targetScale = SHELF_MIN_SIZE / (float) window->width ();
+
+ if (handleShelfInfo ())
+ adjustIPW ();
+
+ cWindow->addDamage ();
+}
+
+/* Binding for toggle mode.
+ * Toggles through three preset scale levels,
+ * currently hard coded to 1.0f (no scale), 0.5f and 0.25f.
+ */
+bool
+ShelfScreen::trigger (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ CompWindow *w = screen->findWindow (screen->activeWindow ());
+ if (!w)
+ return TRUE;
+
+ SHELF_WINDOW (w);
+
+ if (sw->targetScale > 0.5f)
+ sw->scale (0.5f);
+ else if (sw->targetScale <= 0.5f && sw->targetScale > 0.25)
+ sw->scale (0.25f);
+ else
+ sw->scale (1.0f);
+
+ toggleWindowFunctions (w, true);
+ toggleScreenFunctions (true);
+
+ return TRUE;
+}
+
+/* Reset window to 1.0f scale */
+bool
+ShelfScreen::reset (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ CompWindow *w = screen->findWindow (screen->activeWindow ());
+ if (!w)
+ return TRUE;
+
+ SHELF_WINDOW (w);
+
+ sw->scale (1.0f);
+
+ toggleWindowFunctions (w, true);
+ toggleScreenFunctions (true);
+
+ return TRUE;
+}
+
+/* Returns the ratio to multiply by to get a window that's 1/ration the
+ * size of the screen.
+ */
+static inline float
+shelfRat (CompWindow *w,
+ float ratio)
+{
+ float winHeight = (float) w->height ();
+ float winWidth = (float) w->width ();
+ float screenHeight = (float) screen->height ();
+ float screenWidth = (float) screen->width ();
+ float ret;
+
+ if (winHeight / screenHeight < winWidth / screenWidth)
+ ret = screenWidth / winWidth;
+ else
+ ret = screenHeight / winHeight;
+
+ return ret / ratio;
+}
+
+bool
+ShelfScreen::triggerScreen (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ CompWindow *w = screen->findWindow (screen->activeWindow ());
+ if (!w)
+ return TRUE;
+
+ SHELF_WINDOW (w);
+
+ /* FIXME: better should save calculated ratio and reuse it */
+ if (sw->targetScale > shelfRat (w, 2.0f))
+ sw->scale (shelfRat (w, 2.0f));
+ else if (sw->targetScale <= shelfRat (w, 2.0f) &&
+ sw->targetScale > shelfRat (w, 3.0f))
+ sw->scale (shelfRat (w, 3.0f));
+ else if (sw->targetScale <= shelfRat (w, 3.0f) &&
+ sw->targetScale > shelfRat (w, 6.0f))
+ sw->scale (shelfRat (w, 6.0f));
+ else
+ sw->scale (1.0f);
+
+ toggleWindowFunctions (w, true);
+ toggleScreenFunctions (true);
+
+ return TRUE;
+}
+
+/* shelfInc and shelfDec are matcing functions and bindings;
+ * They increase and decrease the scale factor by 'interval'.
+ */
+
+bool
+ShelfScreen::inc (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ CompWindow *w = screen->findWindow (screen->activeWindow ());
+ if (!w)
+ return TRUE;
+
+ SHELF_WINDOW (w);
+
+ sw->scale (sw->targetScale / optionGetInterval ());
+
+ toggleWindowFunctions (w, true);
+ toggleScreenFunctions (true);
+
+ return TRUE;
+}
+
+bool
+ShelfScreen::dec (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+ CompWindow *w = screen->findWindow (screen->activeWindow ());
+ if (!w)
+ return TRUE;
+
+ SHELF_WINDOW (w);
+
+ sw->scale (sw->targetScale * optionGetInterval ());
+
+ toggleWindowFunctions (w, true);
+ toggleScreenFunctions (true);
+
+ return TRUE;
+}
+
+void
+ShelfWindow::handleButtonPress (unsigned int x,
+ unsigned int y)
+{
+ SHELF_SCREEN (screen);
+
+ if (!screen->otherGrabExist ("shelf", 0))
+ {
+ window->activate ();
+ ss->grabbedWindow = window->id ();
+ ss->grabIndex = screen->pushGrab (ss->moveCursor, "shelf");
+
+ ss->lastPointerX = x;
+ ss->lastPointerY = y;
+ }
+}
+
+void
+ShelfScreen::handleMotionEvent (unsigned int x,
+ unsigned int y)
+{
+ CompWindow *w;
+ unsigned int dx, dy;
+
+ if (!grabIndex)
+ return;
+
+ w = screen->findWindow (grabbedWindow);
+ if (!w)
+ return;
+
+ dx = x - lastPointerX;
+ dy = y - lastPointerY;
+
+ w->move (dx, dy, TRUE);
+ w->syncPosition ();
+
+ lastPointerX += dx;
+ lastPointerY += dy;
+}
+
+void
+ShelfWindow::handleButtonRelease ()
+{
+ SHELF_SCREEN (screen);
+
+ ss->grabbedWindow = None;
+ if (ss->grabIndex)
+ {
+ window->moveInputFocusTo ();
+ screen->removeGrab (ss->grabIndex, NULL);
+ ss->grabIndex = 0;
+ }
+}
+
+void
+ShelfWindow::handleEnter (XEvent *event)
+{
+ XEvent enterEvent;
+
+ memcpy (&enterEvent.xcrossing, &event->xcrossing,
+ sizeof (XCrossingEvent));
+ enterEvent.xcrossing.window = window->id ();
+
+ XSendEvent (screen->dpy (), window->id (),
+ FALSE, EnterWindowMask, &enterEvent);
+}
+
+CompWindow *
+ShelfScreen::findRealWindowID (Window wid)
+{
+ CompWindow *orig;
+
+ orig = screen->findWindow (wid);
+ if (!orig)
+ return NULL;
+
+ return ShelfWindow::get (orig)->getRealWindow ();
+}
+
+void
+ShelfScreen::handleEvent (XEvent *event)
+{
+ CompWindow *w, *oldPrev, *oldNext;
+
+ switch (event->type)
+ {
+ case EnterNotify:
+ w = findRealWindowID (event->xcrossing.window);
+ if (w)
+ ShelfWindow::get (w)->handleEnter (event);
+ break;
+ case ButtonPress:
+ w = findRealWindowID (event->xbutton.window);
+ if (w)
+ ShelfWindow::get (w)->handleButtonPress (event->xbutton.x_root,
+ event->xbutton.y_root);
+ break;
+ case ButtonRelease:
+ w = screen->findWindow (grabbedWindow);
+ if (w)
+ ShelfWindow::get (w)->handleButtonRelease ();
+ break;
+ case MotionNotify:
+ handleMotionEvent (event->xmotion.x_root,
+ event->xmotion.y_root);
+ break;
+ case ConfigureNotify:
+ w = screen->findWindow (event->xconfigure.window);
+ if (w)
+ {
+ oldPrev = w->prev;
+ oldNext = w->next;
+ }
+ break;
+ }
+
+ screen->handleEvent (event);
+
+ switch (event->type)
+ {
+ case ConfigureNotify:
+ if (w) /* already assigned above */
+ {
+ if (w->prev != oldPrev || w->next != oldNext)
+ {
+ /* restacking occured, ensure ipw stacking */
+ adjustIPWStacking ();
+ }
+ }
+ break;
+ }
+}
+
+/* The window was damaged, adjust the damage to fit the actual area we
+ * care about.
+ */
+
+bool
+ShelfWindow::damageRect (bool initial,
+ CompRect &rect)
+{
+ Bool status = FALSE;
+
+ if (mScale != 1.0f)
+ {
+ float xTranslate, yTranslate;
+
+ xTranslate = window->input ().left * (mScale - 1.0f);
+ yTranslate = window->input ().top * (mScale - 1.0f);
+
+ cWindow->damageTransformedRect (mScale, mScale,
+ xTranslate, yTranslate, rect);
+ status = TRUE;
+ }
+
+ status |= cWindow->damageRect (initial, rect);
+
+ return status;
+}
+
+/* Scale the window if it is supposed to be scaled.
+ * Translate into place.
+ *
+ * FIXME: Merge the two translations.
+ */
+bool
+ShelfWindow::glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ unsigned int mask)
+{
+ if (targetScale != mScale && steps)
+ {
+ mScale += (float) steps * (targetScale - mScale);
+ if (fabsf (targetScale - mScale) < 0.005)
+ mScale = targetScale;
+ }
+
+ if (mScale != 1.0f)
+ {
+ GLMatrix mTransform = transform;
+ float xTranslate, yTranslate;
+
+ xTranslate = window->input ().left * (mScale - 1.0f);
+ yTranslate = window->input ().top * (mScale - 1.0f);
+
+ mTransform.translate (window->x (), window->y (), 0);
+ mTransform.scale (mScale, mScale, 0);
+ mTransform.translate (xTranslate / mScale - window->x (),
+ yTranslate / mScale - window->y (),
+ 0.0f);
+
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+
+ return gWindow->glPaint (attrib, mTransform, region, mask);
+ }
+ else
+ {
+ return gWindow->glPaint (attrib, transform, region, mask);
+ }
+}
+
+bool
+ShelfScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ if (!shelfedWindows.empty ())
+ mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
+
+ return gScreen->glPaintOutput (attrib, transform, region, output, mask);
+}
+
+/* Checks to see if we need to adjust the window further and hence
+ * damages it's area. Also checks if we still need to paint the area of the
+ * window
+ */
+void
+ShelfScreen::donePaint ()
+{
+ bool stillPainting = false;
+ /* Fixme: should create internal window list */
+ foreach (CompWindow *w, screen->windows ())
+ {
+ SHELF_WINDOW (w);
+
+ if (sw->mScale != sw->targetScale)
+ {
+ sw->cWindow->addDamage ();
+ }
+
+ if (sw->mScale == 1.0f && sw->targetScale == 1.0f)
+ toggleWindowFunctions (w, false);
+ else
+ stillPainting = true;
+ }
+
+ if (!stillPainting)
+ toggleScreenFunctions (false);
+
+ cScreen->donePaint ();
+}
+
+void
+ShelfWindow::moveNotify (int dx, int dy, bool immediate)
+{
+ if (targetScale != 1.00f)
+ adjustIPW ();
+
+ window->moveNotify (dx, dy, immediate);
+}
+
+/* Configuration, initialization, boring stuff. --------------------- */
+ShelfScreen::ShelfScreen (CompScreen *screen) :
+ PluginClassHandler <ShelfScreen, CompScreen> (screen),
+ cScreen (CompositeScreen::get (screen)),
+ gScreen (GLScreen::get (screen)),
+ grabIndex (0),
+ grabbedWindow (None),
+ moveCursor (XCreateFontCursor (screen->dpy (), XC_fleur)),
+ lastPointerX (0),
+ lastPointerY (0)
+{
+ ScreenInterface::setHandler (screen, false);
+ CompositeScreenInterface::setHandler (cScreen, false);
+ GLScreenInterface::setHandler (gScreen, false);
+
+ optionSetTriggerKeyInitiate (boost::bind (&ShelfScreen::trigger, this, _1,
+ _2, _3));
+ optionSetResetKeyInitiate (boost::bind (&ShelfScreen::reset, this, _1 , _2,
+ _3));
+ optionSetTriggerscreenKeyInitiate (boost::bind (&ShelfScreen::triggerScreen,
+ this, _1, _2, _3));
+ optionSetIncButtonInitiate (boost::bind (&ShelfScreen::inc, this, _1, _2,
+ _3));
+ optionSetDecButtonInitiate (boost::bind (&ShelfScreen::dec, this, _1, _2,
+ _3));
+}
+
+ShelfScreen::~ShelfScreen ()
+{
+ if (moveCursor)
+ XFreeCursor (screen->dpy (), moveCursor);
+}
+
+ShelfWindow::ShelfWindow (CompWindow *window) :
+ PluginClassHandler <ShelfWindow, CompWindow> (window),
+ window (window),
+ cWindow (CompositeWindow::get (window)),
+ gWindow (GLWindow::get (window)),
+ mScale (1.0f),
+ targetScale (1.0f),
+ steps (0),
+ info (NULL)
+{
+ WindowInterface::setHandler (window, false);
+ CompositeWindowInterface::setHandler (cWindow, false);
+ GLWindowInterface::setHandler (gWindow, false);
+}
+
+ShelfWindow::~ShelfWindow ()
+{
+ if (info)
+ {
+ targetScale = 1.0f;
+ /* implicitly frees sw->info */
+ handleShelfInfo ();
+ }
+}
+
+/* Check for necessary plugin dependencies and for Xorg shape extension.
+ * If we don't have either, bail out */
+bool
+ShelfPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
+ return false;
+ if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
+ return false;
+ if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
+ return false;
+
+ if (!screen->XShape ())
+ {
+ compLogMessage ("shelf", CompLogLevelError,
+ "No Shape extension found. Shelfing not possible \n");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/shelf.h b/src/shelf.h
new file mode 100644
index 0000000..2aa33aa
--- /dev/null
+++ b/src/shelf.h
@@ -0,0 +1,232 @@
+/*
+ * Compiz Shelf plugin
+ *
+ * shelf.h
+ *
+ * Copyright (C) 2007 Canonical Ltd.
+ *
+ * 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.
+ *
+ * Author(s):
+ * Kristian Lyngstøl <kristian@bohemians.org>
+ * Danny Baumann <maniac@opencompositing.org>
+ * Sam Spilsbury <smspillaz@gmail.com>
+ *
+ * Description:
+ *
+ * This plugin visually resizes a window to allow otherwise obtrusive
+ * windows to be visible in a monitor-fashion. Use case: Anything with
+ * progress bars, notification programs, etc.
+ *
+ * Todo:
+ * - Check for XShape events
+ * - Handle input in a sane way
+ * - Mouse-over?
+ */
+
+#include <X11/extensions/shape.h>
+#include <X11/cursorfont.h>
+
+#include <cmath>
+
+#include <core/core.h>
+#include <composite/composite.h>
+#include <opengl/opengl.h>
+
+#include "shelf_options.h"
+
+class ShelfedWindowInfo {
+ public:
+
+ ShelfedWindowInfo (CompWindow *);
+ ~ShelfedWindowInfo ();
+
+ public:
+ CompWindow *w;
+
+ Window ipw;
+
+ XRectangle *inputRects;
+ int nInputRects;
+ int inputRectOrdering;
+
+ XRectangle *frameInputRects;
+ int frameNInputRects;
+ int frameInputRectOrdering;
+};
+
+class ShelfWindow :
+ public PluginClassHandler <ShelfWindow, CompWindow>,
+ public WindowInterface,
+ public CompositeWindowInterface,
+ public GLWindowInterface
+{
+ public:
+ ShelfWindow (CompWindow *);
+ ~ShelfWindow ();
+
+ CompWindow *window;
+ CompositeWindow *cWindow;
+ GLWindow *gWindow;
+
+ float mScale;
+ float targetScale;
+ float steps;
+
+ ShelfedWindowInfo *info;
+
+ void
+ moveNotify (int, int, bool);
+
+ bool
+ damageRect (bool, CompRect &);
+
+ bool
+ glPaint (const GLWindowPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ unsigned int);
+
+ void
+ saveInputShape (XRectangle **rectRects,
+ int *retCount,
+ int *retOrdering);
+
+ CompWindow *
+ getRealWindow ();
+
+ void
+ shapeInput ();
+
+ void
+ unshapeInput ();
+
+ void
+ adjustIPW ();
+
+ void
+ createIPW ();
+
+ bool
+ handleShelfInfo ();
+
+ void
+ scale (float fScale);
+
+ void
+ handleButtonPress (unsigned int x,
+ unsigned int y);
+
+ void
+ handleButtonRelease ();
+
+ void
+ handleEnter (XEvent *event);
+};
+
+#define SHELF_WINDOW(w) \
+ ShelfWindow *sw = ShelfWindow::get (w)
+
+class ShelfScreen :
+ public PluginClassHandler <ShelfScreen, CompScreen>,
+ public ScreenInterface,
+ public CompositeScreenInterface,
+ public GLScreenInterface,
+ public ShelfOptions
+{
+ public:
+
+ ShelfScreen (CompScreen *);
+ ~ShelfScreen ();
+
+ CompositeScreen *cScreen;
+ GLScreen *gScreen;
+
+ CompScreen::GrabHandle grabIndex;
+ Window grabbedWindow;
+
+ Cursor moveCursor;
+
+ int lastPointerX;
+ int lastPointerY;
+
+ std::list <ShelfedWindowInfo *> shelfedWindows;
+
+ void
+ handleEvent (XEvent *);
+
+ void
+ preparePaint (int);
+
+ bool
+ glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int);
+
+ void
+ donePaint ();
+
+ void
+ addWindowToList (ShelfedWindowInfo *info);
+
+ void
+ removeWindowFromList (ShelfedWindowInfo *info);
+
+ void
+ adjustIPWStacking ();
+
+ void
+ handleMotionEvent (unsigned int x,
+ unsigned int y);
+
+ bool
+ trigger (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ bool
+ reset (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ bool
+ triggerScreen (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ bool
+ inc (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ bool
+ dec (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options);
+
+ CompWindow *
+ findRealWindowID (Window wid);
+};
+
+#define SHELF_SCREEN(w) \
+ ShelfScreen *ss = ShelfScreen::get (w)
+
+#define SHELF_MIN_SIZE 50.0f // Minimum pixelsize a window can be scaled to
+
+
+class ShelfPluginVTable :
+ public CompPlugin::VTableForScreenAndWindow <ShelfScreen, ShelfWindow>
+{
+ public:
+ bool init ();
+};