summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile463
-rw-r--r--plugin.info2
-rw-r--r--session.c878
-rw-r--r--session.xml.in17
5 files changed, 1361 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..378eac2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e1835ab
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,463 @@
+##
+#
+# 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
+#
+
+#load config file
+include plugin.info
+
+
+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
+
+ECHO = `which echo`
+
+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 )
+
+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 $(PLUGIN).h ]; then $(ECHO) "$(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 += $(shell pkg-config --variable=includedir compiz)/compiz/compiz.h
+
+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)
+
+# default color settings
+color := $(shell if [ $$TERM = "dumb" ]; then $(ECHO) "no"; else $(ECHO) "yes"; fi)
+
+#
+# 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); \
+ cp $(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; \
+ cp $(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; \
+ cp $(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; \
+ gconftool-2 --install-schema-file=$(schema-output) > /dev/null; \
+ 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; \
+ cp 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; \
+ cp 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 "$(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
new file mode 100644
index 0000000..2298638
--- /dev/null
+++ b/plugin.info
@@ -0,0 +1,2 @@
+PLUGIN = session
+PKG_DEP = libxml-2.0
diff --git a/session.c b/session.c
new file mode 100644
index 0000000..0762743
--- /dev/null
+++ b/session.c
@@ -0,0 +1,878 @@
+/**
+ *
+ * Compiz session plugin
+ *
+ * session.c
+ *
+ * Copyright (c) 2007 Travis Watkins <amaranth@ubuntu.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ **/
+
+#define _GNU_SOURCE
+#include <X11/Xatom.h>
+
+#include <compiz.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <poll.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <pwd.h>
+#include <X11/SM/SMlib.h>
+#include <X11/ICE/ICElib.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+
+#define SM_DEBUG(x)
+
+#define XDG_DATA_DEFAULT ".local/share"
+
+static SmcConn smcConnection;
+static CompWatchFdHandle iceWatchFdHandle;
+static Bool connected = 0;
+static Bool iceConnected = 0;
+static char *smClientId;
+
+static void iceInit (void);
+
+static int displayPrivateIndex;
+
+typedef void (* SessionWindowFunc) (CompWindow *w, char *clientId, char *name,
+ void *user_data);
+
+typedef struct _SessionDisplay
+{
+ Atom visibleNameAtom;
+ Atom clientIdAtom;
+ Atom embedInfoAtom;
+} SessionDisplay;
+
+#define GET_SESSION_DISPLAY(d) \
+ ((SessionDisplay *) (d)->privates[displayPrivateIndex].ptr)
+
+#define SESSION_DISPLAY(d) \
+ SessionDisplay *sd = GET_SESSION_DISPLAY (d)
+
+static char*
+sessionGetUtf8Property (CompDisplay *d,
+ Window id,
+ Atom atom)
+{
+ Atom type;
+ int format;
+ unsigned long nitems;
+ unsigned long bytesAfter;
+ char *val;
+ int result;
+ char *retval;
+
+ result = XGetWindowProperty (d->display, id, atom, 0L, 65536, False,
+ d->utf8StringAtom, &type, &format, &nitems,
+ &bytesAfter, (unsigned char **)&val);
+
+ if (result != Success)
+ return NULL;
+
+ if (type != d->utf8StringAtom || format != 8 || nitems == 0)
+ {
+ if (val)
+ XFree (val);
+ return NULL;
+ }
+
+ retval = strndup (val, nitems);
+ XFree (val);
+
+ return retval;
+}
+
+static char*
+sessionGetTextProperty (CompDisplay *d,
+ Window id,
+ Atom atom)
+{
+ XTextProperty text;
+ char *retval = NULL;
+
+ text.nitems = 0;
+ if (XGetTextProperty (d->display, id, &text, atom))
+ {
+ if (text.value) {
+ retval = strndup ((char *)text.value,text.nitems);
+ XFree (text.value);
+ }
+ }
+
+ return retval;
+}
+
+static char*
+sessionGetWindowName (CompDisplay *d,
+ Window id)
+{
+ char *name;
+
+ SESSION_DISPLAY (d);
+
+ name = sessionGetUtf8Property (d, id, sd->visibleNameAtom);
+
+ if (!name)
+ name = sessionGetUtf8Property(d, id, d->wmNameAtom);
+
+ if (!name)
+ name = sessionGetTextProperty (d, id, XA_WM_NAME);
+
+ return name;
+}
+
+static Bool
+sessionGetIsEmbedded (CompDisplay *d, Window id)
+{
+ SESSION_DISPLAY (d);
+ Atom actual_type_return;
+ int actual_format_return;
+ unsigned long nitems_return;
+ unsigned long bytes_after_return;
+ unsigned char *prop_return = 0;
+ if (XGetWindowProperty(d->display, id, sd->embedInfoAtom, 0, 2,
+ FALSE, XA_CARDINAL, &actual_type_return,
+ &actual_format_return, &nitems_return,
+ &bytes_after_return, &prop_return) == Success)
+ {
+ if (nitems_return > 1)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static char*
+sessionGetClientId (CompWindow *w)
+{
+ SESSION_DISPLAY (w->screen->display);
+ Window clientLeader;
+ char *clientId;
+ XTextProperty text;
+ text.nitems = 0;
+
+ clientId = NULL;
+ clientLeader = w->clientLeader;
+
+ if (clientLeader == w->id)
+ return NULL;
+
+ //try to find clientLeader on transient parents
+ if (clientLeader == None)
+ {
+ CompWindow *window;
+ window = w;
+ while (window->transientFor != None)
+ {
+ if (window->transientFor == window->id)
+ break;
+
+ window = findWindowAtScreen (w->screen, window->transientFor);
+ if (window->clientLeader != None)
+ {
+ clientLeader = window->clientLeader;
+ break;
+ }
+ }
+ }
+
+ if (clientLeader != None)
+ {
+ if (XGetTextProperty (w->screen->display->display, clientLeader, &text,
+ sd->clientIdAtom))
+ {
+ if (text.value) {
+ clientId = strndup ((char *)text.value, text.nitems);
+ XFree (text.value);
+ }
+ }
+ }
+ else
+ {
+ //some apps set SM_CLIENT_ID on the app
+ if (XGetTextProperty (w->screen->display->display, w->id, &text,
+ sd->clientIdAtom))
+ {
+ if (text.value) {
+ clientId = strndup ((char *)text.value, text.nitems);
+ XFree (text.value);
+ }
+ }
+ }
+ return clientId;
+}
+
+static int
+sessionGetIntForProp (xmlNodePtr node, char *prop)
+{
+ xmlChar *temp;
+ int num;
+
+ temp = xmlGetProp (node, BAD_CAST prop);
+ if (temp != NULL)
+ {
+ num = xmlXPathCastStringToNumber (temp);
+ xmlFree (temp);
+ return num;
+ }
+ return 0;
+}
+
+static void
+sessionForeachWindow (CompDisplay *d, SessionWindowFunc func, void *user_data)
+{
+ CompScreen *s;
+ CompWindow *w;
+ char *clientId;
+ char *name;
+
+ for (s = d->screens; s; s = s->next)
+ {
+ for (w = s->windows; w; w = w->next)
+ {
+ //filter out embedded windows (notification icons)
+ if (sessionGetIsEmbedded (d, w->id))
+ continue;
+
+ clientId = sessionGetClientId (w);
+
+ if (clientId == NULL)
+ continue;
+
+ name = sessionGetWindowName (d, w->id);
+
+ (* func) (w, clientId, name, user_data);
+ }
+ }
+}
+
+static void
+sessionWriteWindow (CompWindow *w, char *clientId, char *name, void *user_data)
+{
+ FILE *outfile = (FILE*) user_data;
+
+ fprintf (outfile, " <window id=\"%s\" title=\"%s\" class=\"%s\" name=\"%s\">\n",
+ clientId,
+ name ? name : "",
+ w->resClass ? w->resClass : "",
+ w->resName ? w->resName : "");
+
+ //save sticky
+ if (w->state & CompWindowStateStickyMask ||
+ w->type & CompWindowTypeDesktopMask ||
+ w->type & CompWindowTypeDockMask)
+ fprintf (outfile, " <sticky/>\n");
+
+ //save minimized
+ if (w->minimized)
+ fprintf (outfile, " <minimized/>\n");
+
+ //save maximized
+ if (w->state & MAXIMIZE_STATE)
+ fprintf (outfile, " <maximized/>\n");
+
+ //save workspace
+ if (!(w->type & CompWindowTypeDesktopMask ||
+ w->type & CompWindowTypeDockMask))
+ fprintf (outfile, " <workspace index=\"%d\"/>\n",
+ w->desktop);
+
+ //save geometry
+ fprintf (outfile, " <geometry x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/>\n",
+ w->serverX, w->serverY, w->width, w->height);
+
+ fprintf (outfile, " </window>\n");
+}
+
+/**
+ * Implementation of mkdir -p. Create the directory given by @path, creating
+ * the whole directory tree if necessary.
+ *
+ * @param path: The absolute path to be created, not `/` terminated
+ * @param mode: The permissions given to newly created directories
+ * @return: True if the directory given by @path now exists
+ *
+ * TODO: It doesn't check if EEXIST means the directory exists or that it's a
+ * file. It should return FALSE if a file exists with the name we want.
+**/
+
+static Bool mkdirp(const char *path, mode_t mode)
+{
+ char *partialPath;
+ char *delim;
+ Bool success;
+
+ success = !mkdir (path, mode); /* Mkdir returns 0 on success */
+ success |= (errno == EEXIST); /* We don't care if the directory is
+ already there */
+ if (!success && (errno == ENOENT)) /* ENOENT means we must recursively */
+ { /* create the parent's parent */
+ delim = strrchr (path, '/');
+ if (!delim)
+ return FALSE; /* Input string is not a valid absolue path! */
+
+ partialPath = malloc (delim - path + 1);
+ if (!partialPath)
+ return FALSE;
+
+ strncpy (partialPath, path, delim - path);
+ partialPath[delim - path] = '\0';
+
+ if (mkdirp (partialPath, mode));
+ success = !mkdir (path, mode);
+
+ free (partialPath);
+ }
+ return success;
+}
+
+/**
+ * Get absolute path to the session file directory.
+ * @param buffer: Buffer to place path in
+ * @param size: Size of the buffer
+ * @return: buffer
+ */
+static char *
+getSessionFilePath (char *buffer, size_t size)
+{
+ char *xdgDir;
+ struct passwd *p = getpwuid(geteuid());
+
+ //setup filename and create directories as needed
+ buffer[0] = '\0';
+ if ((xdgDir = getenv ("XDG_DATA_HOME")))
+ {
+ strncat (buffer, xdgDir, size);
+ }
+ else
+ {
+ strncat (buffer, p->pw_dir, size);
+ strncat (buffer, "/", size);
+ strncat (buffer, XDG_DATA_DEFAULT, size);
+ }
+ strncat (buffer, "/compiz/session", size);
+ return buffer;
+}
+
+static void
+saveState (CompDisplay *d)
+{
+ char filename[1024];
+ FILE *outfile;
+
+ getSessionFilePath(filename, 1024);
+ if (mkdirp (filename, 0700))
+ {
+ strncat (filename, "/", 1024);
+ strncat (filename, smClientId, 1024);
+ }
+ else
+ {
+ return;
+ }
+
+ outfile = fopen (filename, "w");
+ if (outfile == NULL)
+ {
+ return;
+ }
+
+ fprintf (outfile, "<compiz_session id=\"%s\">\n", smClientId);
+
+ sessionForeachWindow (d, sessionWriteWindow, outfile);
+
+ fprintf (outfile, "</compiz_session>\n");
+ fclose (outfile);
+}
+
+static void
+sessionReadWindow (CompWindow *w, char *clientId, char *name, void *user_data)
+{
+ xmlNodePtr cur;
+ xmlChar *newName;
+ xmlChar *newClientId;
+ Bool foundWindow = FALSE;
+ xmlNodePtr root = (xmlNodePtr) user_data;
+
+ if (clientId == NULL)
+ return;
+
+ for (cur = root->xmlChildrenNode; cur; cur = cur->next)
+ {
+ if (xmlStrcmp (cur->name, BAD_CAST "window") == 0)
+ {
+ newClientId = xmlGetProp (cur, BAD_CAST "id");
+ if (newClientId != NULL)
+ {
+ if (clientId == (char*) newClientId)
+ {
+ foundWindow = TRUE;
+ break;
+ }
+ xmlFree (newClientId);
+ }
+
+ newName = xmlGetProp (cur, BAD_CAST "name");
+ if (newName != NULL)
+ {
+ if (name == (char*) newName)
+ {
+ foundWindow = TRUE;
+ break;
+ }
+ xmlFree (newName);
+ }
+ }
+ }
+
+ if (foundWindow)
+ {
+ printf ("found window\n");
+ for (cur = cur->xmlChildrenNode; cur; cur = cur->next)
+ {
+ if (xmlStrcmp (cur->name, BAD_CAST "geometry") == 0)
+ {
+ double x, y, width, height;
+
+ x = sessionGetIntForProp (cur, "x");
+ y = sessionGetIntForProp (cur, "y");
+ width = sessionGetIntForProp (cur, "width");
+ height = sessionGetIntForProp (cur, "height");
+
+ resizeWindow (w, x, y, width, height, 0);
+ }
+ }
+ }
+}
+
+static void
+loadState (CompDisplay *d, char *previousId)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ char filename[1024];
+
+ getSessionFilePath (filename, 1024);
+ strncat (filename, "/", 1024);
+ strncat (filename, previousId, 1024);
+
+ doc = xmlParseFile (filename);
+ if (doc == NULL)
+ return;
+
+ root = xmlDocGetRootElement (doc);
+ if (root == NULL)
+ goto out;
+
+ if (xmlStrcmp (root->name, BAD_CAST "compiz_session") != 0)
+ goto out;
+
+ sessionForeachWindow (d, sessionReadWindow, root);
+
+ out:
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+}
+
+
+
+
+static void
+setCloneRestartCommands (SmcConn connection)
+{
+ char *restartv[10];
+ char *clonev[10];
+ SmProp prop1, prop2, *props[2];
+ int i;
+
+ prop1.name = SmRestartCommand;
+ prop1.type = SmLISTofARRAY8;
+
+ i = 0;
+ restartv[i] = "compiz";
+ ++i;
+ restartv[i] = "--sm-client-id";
+ ++i;
+ restartv[i] = smClientId;
+ ++i;
+ restartv[i] = NULL;
+
+ prop1.vals = malloc (i * sizeof (SmPropValue));
+ if (!prop1.vals)
+ return;
+
+ i = 0;
+ while (restartv[i])
+ {
+ prop1.vals[i].value = restartv[i];
+ prop1.vals[i].length = strlen (restartv[i]);
+ ++i;
+ }
+ prop1.num_vals = i;
+
+
+ prop2.name = SmCloneCommand;
+ prop2.type = SmLISTofARRAY8;
+
+ i = 0;
+ clonev[i] = "compiz";
+ ++i;
+ clonev[i] = NULL;
+
+ prop2.vals = malloc (i * sizeof (SmPropValue));
+ if (!prop2.vals)
+ return;
+
+ i = 0;
+ while (clonev[i])
+ {
+ prop2.vals[i].value = clonev[i];
+ prop2.vals[i].length = strlen (clonev[i]);
+ ++i;
+ }
+ prop2.num_vals = i;
+
+
+ props[0] = &prop1;
+ props[1] = &prop2;
+
+ SmcSetProperties (connection, 2, props);
+}
+
+static void
+setRestartStyle (SmcConn connection, char hint)
+{
+ SmProp prop, *pProp;
+ SmPropValue propVal;
+
+ prop.name = SmRestartStyleHint;
+ prop.type = SmCARD8;
+ prop.num_vals = 1;
+ prop.vals = &propVal;
+ propVal.value = &hint;
+ propVal.length = 1;
+
+ pProp = &prop;
+
+ SmcSetProperties (connection, 1, &pProp);
+}
+
+static void
+saveYourselfGotProps (SmcConn connection,
+ SmPointer client_data,
+ int num_props,
+ SmProp **props)
+{
+ setRestartStyle (connection, SmRestartIfRunning);
+ setCloneRestartCommands (connection);
+ SmcSaveYourselfDone (connection, 1);
+}
+
+static void
+saveYourselfCallback (SmcConn connection,
+ SmPointer client_data,
+ int saveType,
+ Bool shutdown,
+ int interact_Style,
+ Bool fast)
+{
+ saveState ((CompDisplay*) client_data);
+
+ if (!SmcGetProperties (connection, saveYourselfGotProps, NULL))
+ SmcSaveYourselfDone (connection, 1);
+}
+
+static void
+dieCallback (SmcConn connection,
+ SmPointer clientData)
+{
+ closeSession ();
+ exit (0);
+}
+
+static void
+saveCompleteCallback (SmcConn connection,
+ SmPointer clientData)
+{
+}
+
+static void
+shutdownCancelledCallback (SmcConn connection,
+ SmPointer clientData)
+{
+}
+
+static void
+initSession2 (CompDisplay *d, char *smPrevClientId)
+{
+ static SmcCallbacks callbacks;
+
+ if (getenv ("SESSION_MANAGER"))
+ {
+ char errorBuffer[1024];
+
+ iceInit ();
+
+ callbacks.save_yourself.callback = saveYourselfCallback;
+ callbacks.save_yourself.client_data = d;
+
+ callbacks.die.callback = dieCallback;
+ callbacks.die.client_data = NULL;
+
+ callbacks.save_complete.callback = saveCompleteCallback;
+ callbacks.save_complete.client_data = NULL;
+
+ callbacks.shutdown_cancelled.callback = shutdownCancelledCallback;
+ callbacks.shutdown_cancelled.client_data = NULL;
+
+ smcConnection = SmcOpenConnection (NULL,
+ NULL,
+ SmProtoMajor,
+ SmProtoMinor,
+ SmcSaveYourselfProcMask |
+ SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &callbacks,
+ smPrevClientId,
+ &smClientId,
+ sizeof (errorBuffer),
+ errorBuffer);
+ if (!smcConnection)
+ compLogMessage (NULL, "session", CompLogLevelWarn,
+ "SmcOpenConnection failed: %s",
+ errorBuffer);
+ else
+ connected = TRUE;
+ }
+}
+
+void
+closeSession (void)
+{
+ if (connected)
+ {
+ setRestartStyle (smcConnection, SmRestartIfRunning);
+
+ if (SmcCloseConnection (smcConnection, 0, NULL) != SmcConnectionInUse)
+ connected = FALSE;
+ if (smClientId) {
+ free (smClientId);
+ smClientId = NULL;
+ }
+ }
+}
+
+/* ice connection handling taken and updated from gnome-ice.c
+ * original gnome-ice.c code written by Tom Tromey <tromey@cygnus.com>
+ */
+
+/* This is called when data is available on an ICE connection. */
+static Bool
+iceProcessMessages (void *data)
+{
+ IceConn connection = (IceConn) data;
+ IceProcessMessagesStatus status;
+
+ SM_DEBUG (printf ("ICE connection process messages\n"));
+
+ status = IceProcessMessages (connection, NULL, NULL);
+
+ if (status == IceProcessMessagesIOError)
+ {
+ SM_DEBUG (printf ("ICE connection process messages"
+ " - error => shutting down the connection\n"));
+
+ IceSetShutdownNegotiation (connection, False);
+ IceCloseConnection (connection);
+ }
+
+ return 1;
+}
+
+/* This is called when a new ICE connection is made. It arranges for
+ the ICE connection to be handled via the event loop. */
+static void
+iceNewConnection (IceConn connection,
+ IcePointer clientData,
+ Bool opening,
+ IcePointer *watchData)
+{
+ if (opening)
+ {
+ SM_DEBUG (printf ("ICE connection opening\n"));
+
+ /* Make sure we don't pass on these file descriptors to any
+ exec'ed children */
+ fcntl (IceConnectionNumber (connection), F_SETFD,
+ fcntl (IceConnectionNumber (connection),
+ F_GETFD,0) | FD_CLOEXEC);
+
+ iceWatchFdHandle = compAddWatchFd (IceConnectionNumber (connection),
+ POLLIN | POLLPRI | POLLHUP | POLLERR,
+ iceProcessMessages, connection);
+
+ iceConnected = 1;
+ }
+ else
+ {
+ SM_DEBUG (printf ("ICE connection closing\n"));
+
+ if (iceConnected)
+ {
+ compRemoveWatchFd (iceWatchFdHandle);
+
+ iceWatchFdHandle = 0;
+ iceConnected = 0;
+ }
+ }
+}
+
+static IceIOErrorHandler oldIceHandler;
+
+static void
+iceErrorHandler (IceConn connection)
+{
+ if (oldIceHandler)
+ (*oldIceHandler) (connection);
+}
+
+/* We call any handler installed before (or after) iceInit but
+ avoid calling the default libICE handler which does an exit() */
+static void
+iceInit (void)
+{
+ static Bool iceInitialized = 0;
+
+ if (!iceInitialized)
+ {
+ IceIOErrorHandler defaultIceHandler;
+
+ oldIceHandler = IceSetIOErrorHandler (NULL);
+ defaultIceHandler = IceSetIOErrorHandler (iceErrorHandler);
+
+ if (oldIceHandler == defaultIceHandler)
+ oldIceHandler = NULL;
+
+ IceAddConnectionWatch (iceNewConnection, NULL);
+
+ iceInitialized = 1;
+ }
+}
+
+
+
+
+static int
+sessionGetVersion(CompPlugin * p,
+ int version)
+{
+ return ABIVERSION;
+}
+
+static int
+sessionInit (CompPlugin *p)
+{
+ displayPrivateIndex = allocateDisplayPrivateIndex ();
+ if (displayPrivateIndex < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+sessionFini (CompPlugin *p)
+{
+ freeDisplayPrivateIndex(displayPrivateIndex);
+}
+
+static int
+sessionInitDisplay (CompPlugin *p, CompDisplay *d)
+{
+ SessionDisplay *sd;
+ int i;
+ char *previousId = NULL;
+
+ sd = malloc (sizeof (SessionDisplay));
+ if (!sd)
+ return FALSE;
+
+ d->privates[displayPrivateIndex].ptr = sd;
+
+ sd->visibleNameAtom = XInternAtom (d->display,
+ "_NET_WM_VISIBLE_NAME", 0);
+ sd->clientIdAtom = XInternAtom (d->display,
+ "SM_CLIENT_ID", 0);
+ sd->embedInfoAtom = XInternAtom (d->display,
+ "_XEMBED_INFO", 0);
+
+ for (i = 0; i < programArgc; i++)
+ {
+ if (strcmp(programArgv[i], "--sm-client-id") == 0)
+ {
+ i++;
+ printf ("%s\n", programArgv[i]);
+ previousId = malloc (strlen (programArgv[i]) + 1);
+ previousId = strdup (programArgv[i]);
+ break;
+ }
+ }
+
+ initSession2 (d, previousId);
+
+ if (previousId != NULL)
+ loadState (d, previousId);
+
+ return TRUE;
+}
+
+static void
+sessionFiniDisplay (CompPlugin *p, CompDisplay *d)
+{
+ SESSION_DISPLAY (d);
+ closeSession ();
+ free (sd);
+}
+
+static CompPluginVTable sessionVTable =
+{
+ "session",
+ sessionGetVersion,
+ 0,
+ sessionInit,
+ sessionFini,
+ sessionInitDisplay,
+ sessionFiniDisplay,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+CompPluginVTable * getCompPluginInfo(void)
+{
+ return &sessionVTable;
+}
+
diff --git a/session.xml.in b/session.xml.in
new file mode 100644
index 0000000..c2ecc2e
--- /dev/null
+++ b/session.xml.in
@@ -0,0 +1,17 @@
+<compiz>
+ <plugin name="session">
+ <deps>
+ <relation type="before">
+ <plugin>ccp</plugin>
+ <plugin>gconf</plugin>
+ <plugin>kconfig</plugin>
+ </relation>
+ </deps>
+ <_short>Session Management</_short>
+ <_long>Talk to session manager and save/load window state</_long>
+ <category>Utility</category>
+ </plugin>
+</compiz>
+
+
+