diff options
author | Sam Spilsbury <smspillaz@gmail.com> | 2010-07-17 22:57:40 -0700 |
---|---|---|
committer | Sam Spilsbury <smspillaz@gmail.com> | 2010-07-17 22:58:23 -0700 |
commit | 0ab1010697895dd01c98bba343991ffb805e3fc7 (patch) | |
tree | 1fed6cb97d076086808337225e068ed4a937edd8 | |
parent | a8042a93fdea53591ec864118667103472f70840 (diff) | |
download | mousetrails-master.tar.gz mousetrails-master.tar.bz2 |
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | Makefile | 533 | ||||
-rw-r--r-- | mousetrails.c | 1045 | ||||
-rw-r--r-- | mousetrails.xml.in | 6 | ||||
-rw-r--r-- | plugin.info | 3 | ||||
-rw-r--r-- | src/mousetrails.cpp | 731 | ||||
-rw-r--r-- | src/mousetrails.h | 198 |
7 files changed, 936 insertions, 1585 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b114b79 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,5 @@ +find_package (Compiz REQUIRED) + +include (CompizPlugin) + +compiz_plugin (mousetrails PLUGINDEPS composite opengl mousepoll) 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/mousetrails.c b/mousetrails.c deleted file mode 100644 index 15e3695..0000000 --- a/mousetrails.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* - * - * Compiz mouse cursor trails plugin - * - * mousetrails.c - * - * Copyright : (C) 2008 by Erik Johnson - * - * From code originally written by Dennis Kasprzyk - * - * 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 <math.h> -#include <string.h> - -#include <compiz-core.h> -#include <compiz-mousepoll.h> - -#include "mousetrails_options.h" - -#define GET_MOUSETRAILS_DISPLAY(d) \ - ((mousetrailsDisplay *) (d)->base.privates[displayPrivateIndex].ptr) - -#define MOUSETRAILS_DISPLAY(d) \ - mousetrailsDisplay *sd = GET_MOUSETRAILS_DISPLAY (d) - -#define GET_MOUSETRAILS_SCREEN(s, sd) \ - ((mousetrailsScreen *) (s)->base.privates[(sd)->screenPrivateIndex].ptr) - -#define MOUSETRAILS_SCREEN(s) \ - mousetrailsScreen *ss = GET_MOUSETRAILS_SCREEN (s, GET_MOUSETRAILS_DISPLAY (s->display)) - -// in theory the texture array size should be >= trail size -#define TEXTURES_SIZE 51 - -int mousetrailsCursorUpdate (CompScreen *s); - -typedef struct _Particle -{ - //float life; // particle life - float fade; // fade speed - float width; // particle width - float height; // particle height - float w_mod; // particle size modification during life - float h_mod; // particle size modification during life - float r; // red value - float g; // green value - float b; // blue value - float a; // alpha value - float x; // X position - float y; // Y position - float z; // Z position - float xd; - float yd; - int cursorIndex; // array index of cursor serial number -} Particle; - -typedef struct _MouseCursor -{ - GLuint texture; - unsigned long cursor_serial; - unsigned short xhot; - unsigned short yhot; - unsigned short width; - unsigned short height; -} MouseCursor; - -typedef struct _ParticleSystem -{ - int numParticles; - Particle *particles; - float slowdown; - float threshold; - Bool active; - int x, y; - GLuint blendMode; - - int lastx, lasty; - float delta; - int numDisplayedParticles; - int lastGen; - float initialAlpha; - int sizeFactor; - Bool useMousepoll; - - // for random colors - int colorcounter; - float r; // red value - float g; // green value - float b; // blue value - float r2; // red value - float g2; // green value - float b2; // blue value - int colorrate; - int skip; - int atSkip; - int speed; - - // Cursor data - MouseCursor cursors[TEXTURES_SIZE]; // rolling array of cursors grabbed from x - int lastTextureFilled; // last slot used in textures - unsigned long lastCursorSerial; // last cursor serial number grabbed from X - int lastCursorIndex; // ...and its associated array index - - // Moved from drawParticles to get rid of spurious malloc's - GLfloat *vertices_cache; - int vertex_cache_count; - GLfloat *coords_cache; - int coords_cache_count; - GLfloat *colors_cache; - int color_cache_count; - - -} ParticleSystem; - - -static int displayPrivateIndex = 0; - -typedef struct _mousetrailsDisplay -{ - int screenPrivateIndex; - - MousePollFunc *mpFunc; -} -mousetrailsDisplay; - -typedef struct _mousetrailsScreen -{ - int posX; - int posY; - - Bool active; - - ParticleSystem *ps; - - PositionPollingHandle pollHandle; - - PreparePaintScreenProc preparePaintScreen; - DonePaintScreenProc donePaintScreen; - PaintOutputProc paintOutput; -} -mousetrailsScreen; - -static void -initParticles (int numParticles, ParticleSystem * ps) -{ - - if (ps->particles) - free(ps->particles); - //ps->particles = calloc(numParticles, sizeof(Particle)); - ps->particles = calloc(TEXTURES_SIZE, sizeof(Particle)); - - ps->numParticles = numParticles; - ps->numDisplayedParticles = 0; - ps->slowdown = 1; - ps->active = FALSE; - ps->lastx = 0; - ps->lasty = 0; - ps->lastGen = 0; - ps->initialAlpha = 1; - ps->sizeFactor = 10; - ps->colorcounter = 0; - ps->x = 0; - ps->y = 0; - ps->skip = 1; - ps->atSkip = 0; - ps->speed = 1; - ps->useMousepoll = 1; - - ps->lastTextureFilled = -1; - ps->lastCursorIndex = 0; - ps->lastCursorSerial = 0; - - // Initialize cache - ps->vertices_cache = NULL; - ps->colors_cache = NULL; - ps->coords_cache = NULL; - ps->vertex_cache_count = 0; - ps->color_cache_count = 0; - ps->coords_cache_count = 0; - - Particle *part = ps->particles; - int i; - for (i = 0; i < TEXTURES_SIZE; i++, part++){ - part->a = 0.0f; - part->r = 0.0f; - part->g = 0.0f; - part->b = 0.0f; - } - - - for (i = 0; i < TEXTURES_SIZE; i++){ - ps->cursors[i].cursor_serial = 0; - ps->cursors[i].xhot = 0; - ps->cursors[i].yhot = 0; - ps->cursors[i].width = 0; - ps->cursors[i].height = 0; - } - - for (i = 0; i < TEXTURES_SIZE; i++) glGenTextures(1, &ps->cursors[i].texture); - -} - - -static void -drawParticles (CompScreen * s, ParticleSystem * ps) -{ - - if (ps->numDisplayedParticles == 0) return; - - glEnable(GL_BLEND); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnableClientState(GL_COLOR_ARRAY); - glBlendFunc(GL_SRC_ALPHA, ps->blendMode); - glEnable(GL_TEXTURE_2D); - - - // Check that the caches are correct size - - if (ps->vertex_cache_count != 1) - { - ps->vertices_cache = - realloc(ps->vertices_cache, - 4 * 3 * sizeof(GLfloat)); - ps->vertex_cache_count = 1; - } - - if (ps->coords_cache_count != 1) - { - ps->coords_cache = - realloc(ps->coords_cache, - 4 * 2 * sizeof(GLfloat)); - ps->coords_cache_count = 1; - } - - if (ps->color_cache_count != 1) - { - ps->colors_cache = - realloc(ps->colors_cache, - 4 * 4 * sizeof(GLfloat)); - ps->color_cache_count = 1; - } - - - GLfloat *vertices = ps->vertices_cache; - GLfloat *coords = ps->coords_cache; - GLfloat *colors = ps->colors_cache; - - int cornersSize = sizeof (GLfloat) * 8; - int colorSize = sizeof (GLfloat) * 4; - - GLfloat cornerCoords[8] = {0.0, 0.0, - 0.0, 1.0, - 1.0, 1.0, - 1.0, 0.0}; - - int numActive = 0; - - Particle *part = ps->particles; - int i; - for (i = 0; i < ps->numParticles; i++, part++) - { - //if (part->life > 0.0f) - if (part->fade > 0.001f) - { - numActive += 4; - - float w = part->width / 2; - float h = part->height / 2; - - w += (w * part->w_mod) * (1- part->a); - h += (h * part->h_mod) * (1- part->a); - - vertices[0] = part->x - w; - vertices[1] = part->y - h; - vertices[2] = part->z; - - vertices[3] = part->x - w; - vertices[4] = part->y + h; - vertices[5] = part->z; - - vertices[6] = part->x + w; - vertices[7] = part->y + h; - vertices[8] = part->z; - - vertices[9] = part->x + w; - vertices[10] = part->y - h; - vertices[11] = part->z; - - //vertices += 12; - - memcpy (coords, cornerCoords, cornersSize); - - //coords += 8; - - colors[0] = part->r; - colors[1] = part->g; - colors[2] = part->b; - colors[3] = part->a; - memcpy (colors + 4, colors, colorSize); - memcpy (colors + 8, colors, colorSize); - memcpy (colors + 12, colors, colorSize); - - //colors += 16; - - if (ps->cursors[part->cursorIndex].texture) - { - glPushMatrix(); - - glBindTexture(GL_TEXTURE_2D, ps->cursors[part->cursorIndex].texture); - - glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), ps->coords_cache); - glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), ps->vertices_cache); - glColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), ps->colors_cache); - - // draw particles - glDrawArrays(GL_QUADS, 0, numActive); - - glPopMatrix(); - } - - } - - } - - - glDisableClientState(GL_COLOR_ARRAY); - glColor4usv(defaultColor); - screenTexEnvMode(s, GL_REPLACE); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - -} - -static void -updateParticles (ParticleSystem * ps, float time) -{ - int i; - Particle *part; - float speed = (time / 5000.0); - - ps->active = FALSE; - - part = ps->particles; - - int numDisplayedParticles = 0; - - for (i = 0; i < ps->numParticles; i++, part++) - { - if (part->a > 0.001f) - { - // modify opacity - part->a -= 50 * part->a * part->fade * speed; - ps->active = TRUE; - - numDisplayedParticles++; - } - } - ps->numDisplayedParticles = numDisplayedParticles; -} - -static void -finiParticles (ParticleSystem * ps) -{ - free(ps->particles); - if (ps->vertices_cache) - free(ps->vertices_cache); - if (ps->colors_cache) - free(ps->colors_cache); - if (ps->coords_cache) - free(ps->coords_cache); - - int i; - for (i = 0; i < TEXTURES_SIZE; i++) glDeleteTextures(1, &ps->cursors[i].texture); - -} - - -/* -Window root_return; -Window child_return; -int rootX, rootY; -int winX, winY; -unsigned int maskReturn; -Bool status;*/ - -static void -genNewParticles(CompScreen *s, - ParticleSystem *ps, - int time) -{ - - - ps->skip = mousetrailsGetSkip (s) ; - ps->atSkip = (ps->atSkip + 1) % ps->skip; - if (ps->atSkip != 0) return; - - MOUSETRAILS_SCREEN(s); - - Bool rColor = mousetrailsGetRandom (s); - //float life = mousetrailsGetLife (s); - int sizeFactor = ps->sizeFactor; - float threshold = ps->threshold; - //float lifeNeg = 1 - life; - //float fadeExtra = 0.05f * (1.01 - life); - int cursorIndex = 0; - - unsigned short *c = mousetrailsGetColor (s); - - float colr1 = (float)c[0] / 0xffff; - float colg1 = (float)c[1] / 0xffff; - float colb1 = (float)c[2] / 0xffff; - //float cola = (float)c[3] / 0xffff; - - float partw = ps->cursors[ps->lastCursorIndex].width; - float parth = ps->cursors[ps->lastCursorIndex].height; - - float partoffw = ps->cursors[ps->lastCursorIndex].xhot; - float partoffh = ps->cursors[ps->lastCursorIndex].yhot; - - int livex; - int livey; - - // get x cursor position (rootX and rootY) - /*if (!ss->ps->useMousepoll){ - status = XQueryPointer (s->display->display, s->root, - &root_return, &child_return, - &rootX, &rootY, &winX, &winY, &maskReturn); - - livex = rootX; - livey = rootY; - } - else - {*/ - livex = ss->posX; - livey = ss->posY; - //} - - int deltax = livex - ps->x; - int deltay = livey - ps->y; - int delta = deltax * deltax + deltay * deltay; - ss->ps->x = livex; - ss->ps->y = livey; - //if (delta < threshold * threshold) return; - if (delta < 1 ) return; - - int newx = (float)(ps->x + partw/2 - partoffw); - int newy = (float)(ps->y + parth/2 - partoffh); - - - Particle *part = ps->particles; - int i; - - // possibly crashy - if (mousetrailsGetNumParticles(s) != ps->numParticles){ - //initParticles(mousetrailsGetNumParticles (s), ss->ps); - ps->numParticles = mousetrailsGetNumParticles(s); - ps->lastGen = -1; - /*ps->slowdown = mousetrailsGetSlowdown (s); - ps->initialAlpha = mousetrailsGetAlpha (s) ; - ps->sizeFactor = mousetrailsGetSize (s) ; - ps->threshold = mousetrailsGetThreshold (s) ; - ps->colorrate = mousetrailsGetColorrate (s) ;*/ - for (i = 0; i < ps->numParticles; i++, part++){ - part->a = 0.0f; - part->r = 0.0f; - part->g = 0.0f; - part->b = 0.0f; - } - } - - - //if (delta > threshold * threshold) max_new = 1; - - int nextGen = (ps->lastGen + 1) % ps->numParticles; - - for (i = 0; i < ps->numParticles; i++, part++) - { - if (i == nextGen) - { - // record the particle number being generated - ps->lastGen = i; - - cursorIndex = mousetrailsCursorUpdate(s); - - ps->slowdown = mousetrailsGetSlowdown (s); - ps->initialAlpha = mousetrailsGetAlpha (s) ; - ps->sizeFactor = mousetrailsGetSize (s) ; - ps->threshold = mousetrailsGetThreshold (s) ; - ps->colorrate = mousetrailsGetColorrate (s) ; - - // set the cursor array index - part->cursorIndex = ps->lastCursorIndex = cursorIndex; - - part->fade = ps->slowdown / 10.0; - - // set size - part->width = partw; - part->height = parth; - part->w_mod = part->h_mod = ((float)sizeFactor - 10.0) / 10.0; - - // set direction - part->xd = newx - ps->lastx; - part->yd = newy - ps->lasty; - - // set position - part->x = newx; - part->y = newy; - ps->lastx = newx; - ps->lasty = newy; - part->z = 0.0; - - - if (rColor) - { - float value; - // linear smoothing - value = ps->colorcounter; - // sinwave smoothing - nothing spectacular - //value = (float)ps->colorrate - ((float)ps->colorrate / 2) * (1 + cos (3.14159 * (float)ps->colorcounter / (float)ps->colorrate)); - - if (ps->colorcounter == 0) - { - ps->r2 = (float)(random() & 0xff) / 255; - ps->g2 = (float)(random() & 0xff) / 255; - ps->b2 = (float)(random() & 0xff) / 255; - } - ps->r = ((float)ps->colorrate - value)/(float)ps->colorrate * ps->r + value/(float)ps->colorrate * ps->r2; - ps->g = ((float)ps->colorrate - value)/(float)ps->colorrate * ps->g + value/(float)ps->colorrate * ps->g2; - ps->b = ((float)ps->colorrate - value)/(float)ps->colorrate * ps->b + value/(float)ps->colorrate * ps->b2; - part->r = ps->r; - part->g = ps->g; - part->b = ps->b; - ps->colorcounter = (ps->colorcounter + 1) % ps->colorrate; - } - else - { - part->r = colr1; - part->g = colg1; - part->b = colb1; - } - // set transparancy - //part->a = ps->initialAlpha; - float thresholdfactor = 1.0; - if (delta < ps->threshold) thresholdfactor = (float)delta / (float)ps->threshold; - part->a = ps->initialAlpha * thresholdfactor; - - ps->active = TRUE; - } - } -} - -// damageRegion() seems to cause blockiness or jitters on the background window when scrolling, like on a webpage - -static void -damageRegion (CompScreen *s) -{ - REGION r; - int i; - Particle *p; - float w, h, x1, x2, y1, y2; - - MOUSETRAILS_SCREEN (s); - - if (ss->ps->numDisplayedParticles == 0) return; - - if (!ss->ps) - return; - - x1 = s->width; - x2 = 0; - y1 = s->height; - y2 = 0; - - p = ss->ps->particles; - - for (i = 0; i < ss->ps->numParticles; i++, p++) - { - if (p->a > 0.001f){ - w = p->width / 2; - h = p->height / 2; - - w += (w * p->w_mod) * p->a; - h += (h * p->h_mod) * p->a; - - x1 = MIN (x1, p->x - w); - x2 = MAX (x2, p->x + w); - y1 = MIN (y1, p->y - h); - y2 = MAX (y2, p->y + h); - } - } - - r.rects = &r.extents; - r.numRects = r.size = 1; - - r.extents.x1 = floor (x1); - r.extents.x2 = ceil (x2); - r.extents.y1 = floor (y1); - r.extents.y2 = ceil (y2); - - damageScreenRegion (s, &r); -} - - -int mousetrailsCursorUpdate (CompScreen *s) -{ - MOUSETRAILS_SCREEN (s); - - Display * dpy = s->display->display; - XFixesCursorImage *ci = XFixesGetCursorImage(dpy); - - /* Hack to avoid changing to an invisible (bugged)cursor image. - * Example: The animated firefox cursors. - */ - if (ci->width <= 1 && ci->height <= 1) - { - XFree (ci); - return ss->ps->lastCursorIndex; - } - - // only update cursor if necessary (instead of all the time) - if (ci->cursor_serial == ss->ps->lastCursorSerial) - { - XFree (ci); - return ss->ps->lastCursorIndex; - } - - // see if cursor already exists in textures - int i; - for (i = 0; i < TEXTURES_SIZE; i++){ - if (ci->cursor_serial == ss->ps->cursors[i].cursor_serial){ - ss->ps->lastCursorSerial = ci->cursor_serial; - XFree (ci); - return i; - } - } - - // otherwise grab the new cursor into textures - int fillTexture = (ss->ps->lastTextureFilled + 1) % TEXTURES_SIZE; - - unsigned char *pixels = malloc(ci->width * ci->height * 4); - - for (i = 0; i < ci->width * ci->height; i++) - { - unsigned long pix = ci->pixels[i]; - pixels[i * 4] = pix & 0xff; - pixels[(i * 4) + 1] = (pix >> 8) & 0xff; - pixels[(i * 4) + 2] = (pix >> 16) & 0xff; - pixels[(i * 4) + 3] = (pix >> 24) & 0xff; - } - - glBindTexture(GL_TEXTURE_2D, ss->ps->cursors[fillTexture].texture); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ci->width, ci->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, pixels); - glBindTexture(GL_TEXTURE_2D, 0); - - // save data for this cursor - ss->ps->cursors[fillTexture].cursor_serial = ss->ps->lastCursorSerial = ci->cursor_serial; - ss->ps->cursors[fillTexture].xhot = ci->xhot; - ss->ps->cursors[fillTexture].yhot = ci->yhot; - ss->ps->cursors[fillTexture].width = ci->width; - ss->ps->cursors[fillTexture].height = ci->height; - ss->ps->lastTextureFilled = fillTexture; - - XFree (ci); - free (pixels); - - return fillTexture; -} - - -static void -positionUpdate (CompScreen *s, - int x, - int y) -{ - MOUSETRAILS_SCREEN (s); - - ss->posX = x; - ss->posY = y; -} - - - -static void -mousetrailsPreparePaintScreen (CompScreen *s, - int time) -{ - - MOUSETRAILS_SCREEN (s); - MOUSETRAILS_DISPLAY (s->display); - - //Bool useMousepoll = mousetrailsGetMousepoll (s); - - if (ss->active && !ss->pollHandle/* && useMousepoll*/) - { - (*sd->mpFunc->getCurrentPosition) (s, &ss->posX, &ss->posY); - ss->pollHandle = (*sd->mpFunc->addPositionPolling) (s, positionUpdate); - } - - if (ss->active && !ss->ps) - { - ss->ps = calloc(1, sizeof(ParticleSystem)); - if (!ss->ps) - { - UNWRAP (ss, s, preparePaintScreen); - (*s->preparePaintScreen) (s, time); - WRAP (ss, s, preparePaintScreen, mousetrailsPreparePaintScreen); - return; - } - initParticles(mousetrailsGetNumParticles (s), ss->ps); - - ss->ps->slowdown = mousetrailsGetSlowdown (s); - ss->ps->initialAlpha = mousetrailsGetAlpha (s) ; - ss->ps->threshold = mousetrailsGetThreshold (s) ; - ss->ps->colorrate = mousetrailsGetColorrate (s) ; - ss->ps->sizeFactor = mousetrailsGetSize (s) ; - ss->ps->skip = mousetrailsGetSkip (s) ; - ss->ps->blendMode = GL_ONE_MINUS_SRC_ALPHA; - //ss->ps->useMousepoll = mousetrailsGetMousepoll (s); - - mousetrailsCursorUpdate(s); - - } - - - if (ss->ps && ss->ps->active) - { - updateParticles (ss->ps, time); - damageRegion (s); - } - - if (ss->ps && ss->active) - genNewParticles (s, ss->ps, time); - - UNWRAP (ss, s, preparePaintScreen); - (*s->preparePaintScreen) (s, time); - WRAP (ss, s, preparePaintScreen, mousetrailsPreparePaintScreen); - -} - - -static void -mousetrailsDonePaintScreen (CompScreen *s) -{ - MOUSETRAILS_SCREEN (s); - MOUSETRAILS_DISPLAY (s->display); - - if (ss->active || (ss->ps && ss->ps->active)) - damageRegion (s); - - if (!ss->active && ss->pollHandle && ss->ps->useMousepoll) - { - (*sd->mpFunc->removePositionPolling) (s, ss->pollHandle); - ss->pollHandle = 0; - } - - if (!ss->active && ss->ps && !ss->ps->active) - { - finiParticles (ss->ps); - free (ss->ps); - ss->ps = NULL; - } - - UNWRAP (ss, s, donePaintScreen); - (*s->donePaintScreen) (s); - WRAP (ss, s, donePaintScreen, mousetrailsDonePaintScreen); -} - -static Bool -mousetrailsPaintOutput (CompScreen *s, - const ScreenPaintAttrib *sa, - const CompTransform *transform, - Region region, - CompOutput *output, - unsigned int mask) -{ - Bool status; - CompTransform sTransform; - - MOUSETRAILS_SCREEN (s); - - UNWRAP (ss, s, paintOutput); - status = (*s->paintOutput) (s, sa, transform, region, output, mask); - WRAP (ss, s, paintOutput, mousetrailsPaintOutput); - - - - if (!ss->ps || !ss->ps->active) - return status; - -// this doesn't seem to work -// if (mask & PAINT_SCREEN_TRANSFORMED_MASK) return FALSE; - - matrixGetIdentity (&sTransform); - - transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform); - - glPushMatrix (); - glLoadMatrixf (sTransform.m); - - drawParticles (s, ss->ps); - - glPopMatrix(); - - glColor4usv (defaultColor); - - return status; -} - -static Bool -mousetrailsTerminate (CompDisplay *d, - CompAction *action, - CompActionState state, - CompOption *option, - int nOption) -{ - CompScreen *s; - Window xid; - - xid = getIntOptionNamed (option, nOption, "root", 0); - - s = findScreenAtDisplay (d, xid); - if (s) - { - MOUSETRAILS_SCREEN (s); - - ss->active = FALSE; - damageRegion (s); - - return TRUE; - } - return FALSE; -} - -static Bool -mousetrailsInitiate (CompDisplay *d, - CompAction *action, - CompActionState state, - CompOption *option, - int nOption) -{ - - - CompScreen *s; - Window xid; - - xid = getIntOptionNamed (option, nOption, "root", 0); - - s = findScreenAtDisplay (d, xid); - if (s) - { - MOUSETRAILS_SCREEN (s); - - if (ss->active) - return mousetrailsTerminate (d, action, state, option, nOption); - - ss->active = TRUE; - - return TRUE; - } - return FALSE; -} - - -static Bool -mousetrailsInitScreen (CompPlugin *p, - CompScreen *s) -{ - - MOUSETRAILS_DISPLAY (s->display); - - mousetrailsScreen *ss = (mousetrailsScreen *) calloc (1, sizeof (mousetrailsScreen) ); - - if (!ss) - return FALSE; - - s->base.privates[sd->screenPrivateIndex].ptr = ss; - - WRAP (ss, s, paintOutput, mousetrailsPaintOutput); - WRAP (ss, s, preparePaintScreen, mousetrailsPreparePaintScreen); - WRAP (ss, s, donePaintScreen, mousetrailsDonePaintScreen); - - ss->active = TRUE; - - ss->pollHandle = 0; - - ss->ps = NULL; - - return TRUE; -} - - -static void -mousetrailsFiniScreen (CompPlugin *p, - CompScreen *s) -{ - MOUSETRAILS_SCREEN (s); - MOUSETRAILS_DISPLAY (s->display); - - //Restore the original function - UNWRAP (ss, s, paintOutput); - UNWRAP (ss, s, preparePaintScreen); - UNWRAP (ss, s, donePaintScreen); - - if (ss->pollHandle && ss->ps->useMousepoll) - (*sd->mpFunc->removePositionPolling) (s, ss->pollHandle); - - if (ss->ps && ss->ps->active) - damageScreen (s); - - //Free the pointer - free (ss); -} - -static Bool -mousetrailsInitDisplay (CompPlugin *p, - CompDisplay *d) -{ - - //Generate a mousetrails display - mousetrailsDisplay *sd; - int index; - - if (!checkPluginABI ("core", CORE_ABIVERSION) || - !checkPluginABI ("mousepoll", MOUSEPOLL_ABIVERSION)) - return FALSE; - - if (!getPluginDisplayIndex (d, "mousepoll", &index)) - return FALSE; - - sd = (mousetrailsDisplay *) malloc (sizeof (mousetrailsDisplay)); - - if (!sd) - return FALSE; - - //Allocate a private index - sd->screenPrivateIndex = allocateScreenPrivateIndex (d); - - //Check if its valid - if (sd->screenPrivateIndex < 0) - { - //Its invalid so free memory and return - free (sd); - return FALSE; - } - - sd->mpFunc = d->base.privates[index].ptr; - - mousetrailsSetInitiateInitiate (d, mousetrailsInitiate); - mousetrailsSetInitiateTerminate (d, mousetrailsTerminate); - - //Record the display - d->base.privates[displayPrivateIndex].ptr = sd; - return TRUE; -} - -static void -mousetrailsFiniDisplay (CompPlugin *p, - CompDisplay *d) -{ - MOUSETRAILS_DISPLAY (d); - //Free the private index - freeScreenPrivateIndex (d, sd->screenPrivateIndex); - //Free the pointer - free (sd); -} - - - -static Bool -mousetrailsInit (CompPlugin * p) -{ - displayPrivateIndex = allocateDisplayPrivateIndex(); - - if (displayPrivateIndex < 0) - return FALSE; - - return TRUE; -} - -static void -mousetrailsFini (CompPlugin * p) -{ - if (displayPrivateIndex >= 0) - freeDisplayPrivateIndex (displayPrivateIndex); -} - -static CompBool -mousetrailsInitObject (CompPlugin *p, - CompObject *o) -{ - static InitPluginObjectProc dispTab[] = { - (InitPluginObjectProc) 0, /* InitCore */ - (InitPluginObjectProc) mousetrailsInitDisplay, - (InitPluginObjectProc) mousetrailsInitScreen - }; - - RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o)); -} - -static void -mousetrailsFiniObject (CompPlugin *p, - CompObject *o) -{ - static FiniPluginObjectProc dispTab[] = { - (FiniPluginObjectProc) 0, /* FiniCore */ - (FiniPluginObjectProc) mousetrailsFiniDisplay, - (FiniPluginObjectProc) mousetrailsFiniScreen - }; - - DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o)); -} - -CompPluginVTable mousetrailsVTable = { - "mousetrails", - 0, - mousetrailsInit, - mousetrailsFini, - mousetrailsInitObject, - mousetrailsFiniObject, - 0, - 0 -}; - -CompPluginVTable * -getCompPluginInfo (void) -{ - return &mousetrailsVTable; -} diff --git a/mousetrails.xml.in b/mousetrails.xml.in index a1c62b8..d75fa42 100644 --- a/mousetrails.xml.in +++ b/mousetrails.xml.in @@ -12,7 +12,7 @@ <plugin>mousepoll</plugin> </requirement> </deps> - <display> + <options> <group> <_short>Trail Toggle</_short> <option name="initiate" type="key"> @@ -21,8 +21,6 @@ <default><Super>t</default> </option> </group> - </display> - <screen> <group> <_short>Trail Options</_short> <option name="num_particles" type="int"> @@ -104,6 +102,6 @@ <default>false</default> </option>--> </group> - </screen> + </options> </plugin> </compiz> diff --git a/plugin.info b/plugin.info deleted file mode 100644 index f174f18..0000000 --- a/plugin.info +++ /dev/null @@ -1,3 +0,0 @@ -PLUGIN = mousetrails -PKG_DEP = compiz-mousepoll -CHK_HEADERS = compiz-mousepoll.h diff --git a/src/mousetrails.cpp b/src/mousetrails.cpp new file mode 100644 index 0000000..21cbaee --- /dev/null +++ b/src/mousetrails.cpp @@ -0,0 +1,731 @@ +/* + * + * Compiz mouse cursor trails plugin + * + * mousetrails.c + * + * Copyright : (C) 2008 by Erik Johnson + * + * From code originally written by Dennis Kasprzyk + * + * 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 <cstring> + +#include "mousetrails.h" + +COMPIZ_PLUGIN_20090315 (mousetrails, MousetrailsPluginVTable) + +void +ParticleSystem::initParticles (int numParticles) +{ + + if (mParticles) + free(mParticles); + //mParticles = calloc(numParticles, sizeof(Particle)); + mParticles = (Particle *) calloc(TEXTURES_SIZE, sizeof(Particle)); + + mNumParticles = numParticles; + mNumDisplayedParticles = 0; + mSlowdown = 1; + mActive = FALSE; + mLastx = 0; + mLasty = 0; + mLastGen = 0; + mInitialAlpha = 1; + mSizeFactor = 10; + mColorcounter = 0; + mX = 0; + mY = 0; + mSkip = 1; + mAtSkip = 0; + mSpeed = 1; + mUseMousepoll = 1; + + mLastTextureFilled = -1; + mLastCursorIndex = 0; + mLastCursorSerial = 0; + + // Initialize cache + mVertices_cache = NULL; + mColors_cache = NULL; + mCoords_cache = NULL; + mVertex_cache_count = 0; + mColor_cache_count = 0; + mCoords_cache_count = 0; + + Particle *part = mParticles; + int i; + for (i = 0; i < TEXTURES_SIZE; i++, part++){ + part->a = 0.0f; + part->r = 0.0f; + part->g = 0.0f; + part->b = 0.0f; + } + + + for (i = 0; i < TEXTURES_SIZE; i++){ + mCursors[i].cursor_serial = 0; + mCursors[i].xhot = 0; + mCursors[i].yhot = 0; + mCursors[i].width = 0; + mCursors[i].height = 0; + } + + for (i = 0; i < TEXTURES_SIZE; i++) glGenTextures(1, &mCursors[i].texture); + +} + + +void +ParticleSystem::drawParticles () +{ + if (mNumDisplayedParticles == 0) return; + + glEnable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnableClientState(GL_COLOR_ARRAY); + glBlendFunc(GL_SRC_ALPHA, mBlendMode); + glEnable(GL_TEXTURE_2D); + + + // Check that the caches are correct size + + if (mVertex_cache_count != 1) + { + mVertices_cache = + (GLfloat *) realloc(mVertices_cache, + 4 * 3 * sizeof(GLfloat)); + mVertex_cache_count = 1; + } + + if (mCoords_cache_count != 1) + { + mCoords_cache = + (GLfloat *) realloc(mCoords_cache, + 4 * 2 * sizeof(GLfloat)); + mCoords_cache_count = 1; + } + + if (mColor_cache_count != 1) + { + mColors_cache = + (GLfloat *) realloc(mColors_cache, + 4 * 4 * sizeof(GLfloat)); + mColor_cache_count = 1; + } + + + GLfloat *vertices = mVertices_cache; + GLfloat *coords = mCoords_cache; + GLfloat *colors = mColors_cache; + + int cornersSize = sizeof (GLfloat) * 8; + int colorSize = sizeof (GLfloat) * 4; + + GLfloat cornerCoords[8] = {0.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + 1.0, 0.0}; + + int numActive = 0; + + Particle *part = mParticles; + int i; + for (i = 0; i < mNumParticles; i++, part++) + { + //if (part->life > 0.0f) + if (part->fade > 0.001f) + { + numActive += 4; + + float w = part->width / 2; + float h = part->height / 2; + + w += (w * part->w_mod) * (1- part->a); + h += (h * part->h_mod) * (1- part->a); + + vertices[0] = part->x - w; + vertices[1] = part->y - h; + vertices[2] = part->z; + + vertices[3] = part->x - w; + vertices[4] = part->y + h; + vertices[5] = part->z; + + vertices[6] = part->x + w; + vertices[7] = part->y + h; + vertices[8] = part->z; + + vertices[9] = part->x + w; + vertices[10] = part->y - h; + vertices[11] = part->z; + + //vertices += 12; + + memcpy (coords, cornerCoords, cornersSize); + + //coords += 8; + + colors[0] = part->r; + colors[1] = part->g; + colors[2] = part->b; + colors[3] = part->a; + memcpy (colors + 4, colors, colorSize); + memcpy (colors + 8, colors, colorSize); + memcpy (colors + 12, colors, colorSize); + + //colors += 16; + + if (mCursors[part->cursorIndex].texture) + { + glPushMatrix(); + + glBindTexture(GL_TEXTURE_2D, mCursors[part->cursorIndex].texture); + + glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), mCoords_cache); + glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), mVertices_cache); + glColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), mColors_cache); + + // draw particles + glDrawArrays(GL_QUADS, 0, numActive); + + glPopMatrix(); + } + + } + + } + + + glDisableClientState(GL_COLOR_ARRAY); + glColor4usv(defaultColor); + GLScreen::get(screen)->setTexEnvMode (GL_REPLACE); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + +} + +void +ParticleSystem::updateParticles (float time) +{ + int i; + Particle *part; + float speed = (time / 5000.0); + + mActive = FALSE; + + part = mParticles; + + int numDisplayedParticles = 0; + + for (i = 0; i < mNumParticles; i++, part++) + { + if (part->a > 0.001f) + { + // modify opacity + part->a -= 50 * part->a * part->fade * speed; + mActive = TRUE; + + numDisplayedParticles++; + } + } + mNumDisplayedParticles = numDisplayedParticles; +} + +void +ParticleSystem::finiParticles () +{ + free(mParticles); + if (mVertices_cache) + free(mVertices_cache); + if (mColors_cache) + free(mColors_cache); + if (mCoords_cache) + free(mCoords_cache); + + int i; + for (i = 0; i < TEXTURES_SIZE; i++) glDeleteTextures(1, &mCursors[i].texture); + +} + + +/* +Window root_return; +Window child_return; +int rootX, rootY; +int winX, winY; +unsigned int maskReturn; +Bool status;*/ + +void +ParticleSystem::genNewParticles (int time) +{ + MOUSETRAILS_SCREEN (screen); + + + mSkip = ss->optionGetSkip () ; + mAtSkip = (mAtSkip + 1) % mSkip; + if (mAtSkip != 0) return; + + Bool rColor = ss->optionGetRandom (); + //float life = ss->optionGetLife (); + int sizeFactor = mSizeFactor; + //float lifeNeg = 1 - life; + //float fadeExtra = 0.05f * (1.01 - life); + int cursorIndex = 0; + + unsigned short *c = ss->optionGetColor (); + + float colr1 = (float)c[0] / 0xffff; + float colg1 = (float)c[1] / 0xffff; + float colb1 = (float)c[2] / 0xffff; + //float cola = (float)c[3] / 0xffff; + + float partw = mCursors[mLastCursorIndex].width; + float parth = mCursors[mLastCursorIndex].height; + + float partoffw = mCursors[mLastCursorIndex].xhot; + float partoffh = mCursors[mLastCursorIndex].yhot; + + int livex; + int livey; + + // get x cursor position (rootX and rootY) + /*if (!mUseMousepoll){ + status = XQueryPointer (s->display->display, s->root, + &root_return, &child_return, + &rootX, &rootY, &winX, &winY, &maskReturn); + + livex = rootX; + livey = rootY; + } + else + {*/ + livex = ss->mPosX; + livey = ss->mPosY; + //} + + int deltax = livex - mX; + int deltay = livey - mY; + int delta = deltax * deltax + deltay * deltay; + mX = livex; + mY = livey; + //if (delta < threshold * threshold) return; + if (delta < 1 ) return; + + int newx = (float)(mX + partw/2 - partoffw); + int newy = (float)(mY + parth/2 - partoffh); + + + Particle *part = mParticles; + int i; + + // possibly crashy + if (ss->optionGetNumParticles() != mNumParticles){ + //initParticles(ss->optionGetNumParticles (), ss->ps); + mNumParticles = ss->optionGetNumParticles(); + mLastGen = -1; + /*ps->slowdown = ss->optionGetSlowdown (); + mInitialAlpha = ss->optionGetAlpha () ; + mSizeFactor = ss->optionGetSize () ; + mThreshold = ss->optionGetThreshold () ; + mColorrate = ss->optionGetColorrate () ;*/ + for (i = 0; i < mNumParticles; i++, part++){ + part->a = 0.0f; + part->r = 0.0f; + part->g = 0.0f; + part->b = 0.0f; + } + } + + + //if (delta > threshold * threshold) max_new = 1; + + int nextGen = (mLastGen + 1) % mNumParticles; + + for (i = 0; i < mNumParticles; i++, part++) + { + if (i == nextGen) + { + // record the particle number being generated + mLastGen = i; + + cursorIndex = ss->cursorUpdate (); + + mSlowdown = ss->optionGetSlowdown (); + mInitialAlpha = ss->optionGetAlpha () ; + mSizeFactor = ss->optionGetSize () ; + mThreshold = ss->optionGetThreshold () ; + mColorrate = ss->optionGetColorrate () ; + + // set the cursor array index + part->cursorIndex = mLastCursorIndex = cursorIndex; + + part->fade = mSlowdown / 10.0; + + // set size + part->width = partw; + part->height = parth; + part->w_mod = part->h_mod = ((float)sizeFactor - 10.0) / 10.0; + + // set direction + part->xd = newx - mLastx; + part->yd = newy - mLasty; + + // set position + part->x = newx; + part->y = newy; + mLastx = newx; + mLasty = newy; + part->z = 0.0; + + + if (rColor) + { + float value; + // linear smoothing + value = mColorcounter; + // sinwave smoothing - nothing spectacular + //value = (float)mColorrate - ((float)mColorrate / 2) * (1 + cos (3.14159 * (float)mColorcounter / (float)mColorrate)); + + if (mColorcounter == 0) + { + mR2 = (float)(random() & 0xff) / 255; + mG2 = (float)(random() & 0xff) / 255; + mB2 = (float)(random() & 0xff) / 255; + } + mR = ((float)mColorrate - value)/(float)mColorrate * mR + value/(float)mColorrate * mR2; + mG = ((float)mColorrate - value)/(float)mColorrate * mG + value/(float)mColorrate * mG2; + mB = ((float)mColorrate - value)/(float)mColorrate * mB + value/(float)mColorrate * mB2; + part->r = mR; + part->g = mG; + part->b = mB; + mColorcounter = (mColorcounter + 1) % mColorrate; + } + else + { + part->r = colr1; + part->g = colg1; + part->b = colb1; + } + // set transparancy + //part->a = mInitialAlpha; + float thresholdfactor = 1.0; + if (delta < mThreshold) thresholdfactor = (float)delta / (float)mThreshold; + part->a = mInitialAlpha * thresholdfactor; + + mActive = TRUE; + } + } +} + +// damageRegion() seems to cause blockiness or jitters on the background window when scrolling, like on a webpage + +void +MousetrailsScreen::damageRegion () +{ + int i; + Particle *p; + float w, h, x1, x2, y1, y2; + + if (mPs->mNumDisplayedParticles == 0) return; + + if (!mPs) + return; + + x1 = screen->width (); + x2 = 0; + y1 = screen->height (); + y2 = 0; + + p = mPs->mParticles; + + for (i = 0; i < mPs->mNumParticles; i++, p++) + { + if (p->a > 0.001f){ + w = p->width / 2; + h = p->height / 2; + + w += (w * p->w_mod) * p->a; + h += (h * p->h_mod) * p->a; + + x1 = MIN (x1, p->x - w); + x2 = MAX (x2, p->x + w); + y1 = MIN (y1, p->y - h); + y2 = MAX (y2, p->y + h); + } + } + + CompRegion r (floor (x1), floor (y1), ceil (x2) - floor (x1), + ceil (y2) - floor (y1)); + + cScreen->damageRegion (r); +} + +int +MousetrailsScreen::cursorUpdate () +{ + + Display * dpy = screen->dpy (); + XFixesCursorImage *ci = XFixesGetCursorImage(dpy); + + /* Hack to avoid changing to an invisible (bugged)cursor image. + * Example: The animated firefox cursors. + */ + if (ci->width <= 1 && ci->height <= 1) + { + XFree (ci); + return mPs->mLastCursorIndex; + } + + // only update cursor if necessary (instead of all the time) + if (ci->cursor_serial == mPs->mLastCursorSerial) + { + XFree (ci); + return mPs->mLastCursorIndex; + } + + // see if cursor already exists in textures + int i; + for (i = 0; i < TEXTURES_SIZE; i++){ + if (ci->cursor_serial == mPs->mCursors[i].cursor_serial){ + mPs->mLastCursorSerial = ci->cursor_serial; + XFree (ci); + return i; + } + } + + // otherwise grab the new cursor into textures + int fillTexture = (mPs->mLastTextureFilled + 1) % TEXTURES_SIZE; + + unsigned char *pixels = (unsigned char *) malloc(ci->width * ci->height * 4); + + for (i = 0; i < ci->width * ci->height; i++) + { + unsigned long pix = ci->pixels[i]; + pixels[i * 4] = pix & 0xff; + pixels[(i * 4) + 1] = (pix >> 8) & 0xff; + pixels[(i * 4) + 2] = (pix >> 16) & 0xff; + pixels[(i * 4) + 3] = (pix >> 24) & 0xff; + } + + glBindTexture(GL_TEXTURE_2D, mPs->mCursors[fillTexture].texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ci->width, ci->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + glBindTexture(GL_TEXTURE_2D, 0); + + // save data for this cursor + mPs->mCursors[fillTexture].cursor_serial = mPs->mLastCursorSerial = ci->cursor_serial; + mPs->mCursors[fillTexture].xhot = ci->xhot; + mPs->mCursors[fillTexture].yhot = ci->yhot; + mPs->mCursors[fillTexture].width = ci->width; + mPs->mCursors[fillTexture].height = ci->height; + mPs->mLastTextureFilled = fillTexture; + + XFree (ci); + free (pixels); + + return fillTexture; +} + + +void +MousetrailsScreen::positionUpdate (const CompPoint &p) +{ + int x = p.x (); + int y = p.y (); + + mPosX = x; + mPosY = y; +} + + + +void +MousetrailsScreen::preparePaint (int time) +{ + //Bool useMousepoll = optionGetMousepoll (); + + if (mActive && !mPollHandle.active ()) + { + CompPoint p = mPollHandle.getCurrentPosition (); + mPosX = p.x (); + mPosY = p.y (); + mPollHandle.start (); + } + + if (mActive && !mPs) + { + mPs = (ParticleSystem *) calloc(1, sizeof(ParticleSystem)); + if (!mPs) + { + cScreen->preparePaint (time);; + return; + } + mPs->initParticles(optionGetNumParticles ()); + + mPs->mSlowdown = optionGetSlowdown (); + mPs->mInitialAlpha = optionGetAlpha () ; + mPs->mThreshold = optionGetThreshold () ; + mPs->mColorrate = optionGetColorrate () ; + mPs->mSizeFactor = optionGetSize () ; + mPs->mSkip = optionGetSkip () ; + mPs->mBlendMode = GL_ONE_MINUS_SRC_ALPHA; + //mPs->useMousepoll = optionGetMousepoll (); + + cursorUpdate (); + + } + + + if (mPs && mPs->mActive) + { + mPs->updateParticles (time); + damageRegion (); + } + + if (mPs && mActive) + mPs->genNewParticles (time); + + cScreen->preparePaint (time); + +} + +void +MousetrailsScreen::donePaint () +{ + + if (mActive || (mPs && mPs->mActive)) + damageRegion (); + + if (!mActive && mPollHandle.active () && mPs->mUseMousepoll) + { + mPollHandle.stop (); + } + + if (!mActive && mPs && !mPs->mActive) + { + mPs->finiParticles (); + free (mPs); + mPs = NULL; + } + + cScreen->donePaint (); +} + +bool +MousetrailsScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, + const GLMatrix &transform, + const CompRegion ®ion, + CompOutput *output, + unsigned int mask) +{ + bool status; + GLMatrix sTransform (transform); + + status = gScreen->glPaintOutput (attrib, transform, region, output, mask); + + if (!mPs || !mPs->mActive) + return status; + +// this doesn't seem to work +// if (mask & PAINT_SCREEN_TRANSFORMED_MASK) return FALSE; + + sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); + + glPushMatrix (); + glLoadMatrixf (sTransform.getMatrix ()); + + mPs->drawParticles (); + + glPopMatrix(); + + glColor4usv (defaultColor); + + return status; +} + +bool +MousetrailsScreen::terminate (CompAction *action, + CompAction::State state, + CompOption::Vector options) +{ + mActive = false; + damageRegion (); + + return true; +} + +bool +MousetrailsScreen::initiate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + + if (mActive) + return terminate (action, state, options); + + mActive = true; + + return true; +} + +MousetrailsScreen::MousetrailsScreen (CompScreen *screen) : + PluginClassHandler <MousetrailsScreen, CompScreen> (screen), + cScreen (CompositeScreen::get (screen)), + gScreen (GLScreen::get (screen)), + mPosX (0), + mPosY (0), + mActive (false), + mPs (NULL) +{ + CompositeScreenInterface::setHandler (cScreen); + GLScreenInterface::setHandler (gScreen); + + mPollHandle.setCallback (boost::bind (&MousetrailsScreen::positionUpdate, this, _1)); + + optionSetInitiateInitiate (boost::bind (&MousetrailsScreen::initiate, this, _1, _2, _3)); + optionSetInitiateTerminate (boost::bind (&MousetrailsScreen::terminate, this, _1, _2, _3)); +} + +MousetrailsScreen::~MousetrailsScreen () +{ + if (mPollHandle.active ()) + mPollHandle.stop (); + + if (mPs && mPs->mActive) + { + mPs->finiParticles (); + free (mPs); + cScreen->damageScreen (); + } +} + +bool +MousetrailsPluginVTable::init () +{ + if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) || + !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) || + !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) || + !CompPlugin::checkPluginABI ("mousepoll", COMPIZ_MOUSEPOLL_ABI)) + return false; + + return true; +} diff --git a/src/mousetrails.h b/src/mousetrails.h new file mode 100644 index 0000000..c554184 --- /dev/null +++ b/src/mousetrails.h @@ -0,0 +1,198 @@ +/* + * + * Compiz mouse cursor trails plugin + * + * mousetrails.h + * + * Copyright : (C) 2008 by Erik Johnson + * + * From code originally written by Dennis Kasprzyk + * + * 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/core.h> +#include <composite/composite.h> +#include <opengl/opengl.h> +#include <mousepoll/mousepoll.h> + +#include "mousetrails_options.h" + +// in theory the texture array size should be >= trail size +#define TEXTURES_SIZE 51 + +class Particle +{ + public: + //float life; // particle life + float fade; // fade speed + float width; // particle width + float height; // particle height + float w_mod; // particle size modification during life + float h_mod; // particle size modification during life + float r; // red value + float g; // green value + float b; // blue value + float a; // alpha value + float x; // X position + float y; // Y position + float z; // Z position + float xd; + float yd; + int cursorIndex; // array index of cursor serial number +}; + +class MouseCursor +{ + public: + GLuint texture; + unsigned long cursor_serial; + unsigned short xhot; + unsigned short yhot; + unsigned short width; + unsigned short height; +}; + +class ParticleSystem +{ + public: + int mNumParticles; + Particle *mParticles; + float mSlowdown; + float mThreshold; + Bool mActive; + int mX, mY; + GLuint mBlendMode; + + int mLastx, mLasty; + float mDelta; + int mNumDisplayedParticles; + int mLastGen; + float mInitialAlpha; + int mSizeFactor; + Bool mUseMousepoll; + + // for random colors + int mColorcounter; + float mR; // red value + float mG; // green value + float mB; // blue value + float mR2; // red value + float mG2; // green value + float mB2; // blue value + int mColorrate; + int mSkip; + int mAtSkip; + int mSpeed; + + // Cursor data + MouseCursor mCursors[TEXTURES_SIZE]; // rolling array of cursors grabbed from x + int mLastTextureFilled; // last slot used in textures + unsigned long mLastCursorSerial; // last cursor serial number grabbed from X + int mLastCursorIndex; // ...and its associated array index + + // Moved from drawParticles to get rid of spurious malloc's + GLfloat *mVertices_cache; + int mVertex_cache_count; + GLfloat *mCoords_cache; + int mCoords_cache_count; + GLfloat *mColors_cache; + int mColor_cache_count; + + void + initParticles (int f_numParticles); + + void + drawParticles (); + + void + updateParticles (float time); + + void + finiParticles (); + + void + genNewParticles (int time); + +}; + +class MousetrailsScreen : + public PluginClassHandler <MousetrailsScreen, CompScreen>, + public CompositeScreenInterface, + public GLScreenInterface, + public MousetrailsOptions +{ + public: + + MousetrailsScreen (CompScreen *screen); + ~MousetrailsScreen (); + + public: + + CompositeScreen *cScreen; + GLScreen *gScreen; + + int mPosX; + int mPosY; + + Bool mActive; + + ParticleSystem *mPs; + + MousePoller mPollHandle; + + void + preparePaint (int); + + bool + glPaintOutput (const GLScreenPaintAttrib &, + const GLMatrix &, + const CompRegion &, + CompOutput *, + unsigned int ); + + void + donePaint (); + + void + damageRegion (); + + void + positionUpdate (const CompPoint &p); + + bool + terminate (CompAction *action, + CompAction::State state, + CompOption::Vector options); + + bool + initiate (CompAction *action, + CompAction::State state, + CompOption::Vector &options); + + int + cursorUpdate (); + +}; + +#define MOUSETRAILS_SCREEN(s) \ + MousetrailsScreen *ss = MousetrailsScreen::get (s); + +class MousetrailsPluginVTable : + public CompPlugin::VTableForScreen <MousetrailsScreen> +{ + public: + + bool init (); +}; |