From d2d37ef74a76e9cb9a90501f35875de2b192f7b1 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Fri, 21 Sep 2007 16:22:16 -0500 Subject: shit, i really need to remember to commit this stuff --- Makefile | 463 ++++++++++++++++++++++++++++++++++++++++++++++++ plugin.info | 2 + session.c | 579 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1044 insertions(+) create mode 100644 Makefile create mode 100644 plugin.info create mode 100644 session.c 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; $@; \ + 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..6ed585e --- /dev/null +++ b/session.c @@ -0,0 +1,579 @@ +/** + * + * Compiz session plugin + * + * session.c + * + * Copyright (c) 2007 Travis Watkins + * + * + * 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static int displayPrivateIndex; + +typedef struct _SessionDisplay +{ + Atom visibleNameAtom; + Atom clientIdAtom; + + SmcConn smcConnection; + CompWatchFdHandle iceWatchFdHandle; + Bool connected; + Bool iceConnected; + Bool iceInitialized; + char *smClientId; +} 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 void +sessionSaveState (CompDisplay *d) +{ + SESSION_DISPLAY (d); + CompScreen *s; + CompWindow *w; + char *name; + FILE *outfile; + + outfile = fopen ("/home/travis/.config/compiz/session", "w"); + if (outfile == NULL) + { + return; + } + + fprintf (outfile, "\n", sd->smClientId); + + for (s = d->screens; s; s = s->next) + { + for (w = s->windows; w; w = w->next) + { + char *clientId = NULL; + Window clientLeader; + clientLeader = w->clientLeader; + + if (w->clientLeader == w->id) + continue; + + //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 (s, window->transientFor); + if (window->clientLeader != None) + { + clientLeader = window->clientLeader; + break; + } + } + } + + if (clientLeader != None) + { + XTextProperty text; + text.nitems = 0; + + if (XGetTextProperty (d->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 + XTextProperty text; + text.nitems = 0; + + if (XGetTextProperty (d->display, w->id, &text, sd->clientIdAtom)) + { + if (text.value) { + clientId = strndup ((char *)text.value, text.nitems); + XFree (text.value); + } + } + } + + if (clientId == NULL) + continue; + + name = sessionGetWindowName (d, w->id); + + fprintf (outfile, " \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, " \n"); + + //save minimized + if (w->minimized) + fprintf (outfile, " \n"); + + //save maximized + if (w->state & MAXIMIZE_STATE) + fprintf (outfile, " \n"); + + //save workspace + if (!(w->type & CompWindowTypeDesktopMask || + w->type & CompWindowTypeDockMask)) + fprintf (outfile, " \n", w->desktop); + + //save geometry + fprintf (outfile, " \n", + w->serverX, w->serverY, w->width, w->height); + + fprintf (outfile, " \n"); + } + } + + fprintf (outfile, "\n"); + fclose (outfile); +} + +static void +sessionSetCloneRestartCommands (SmcConn connection, CompDisplay *d) +{ + SESSION_DISPLAY (d); + 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] = sd->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 +sessionSetRestartStyle (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 = ∝ + + SmcSetProperties (connection, 1, &pProp); +} + +static void +sessionCloseSession (CompDisplay *d) +{ + SESSION_DISPLAY (d); + + if (sd->connected) + { + sessionSetRestartStyle (sd->smcConnection, SmRestartIfRunning); + + if (SmcCloseConnection (sd->smcConnection, 0, NULL) != SmcConnectionInUse) + sd->connected = FALSE; + if (sd->smClientId) { + free (sd->smClientId); + sd->smClientId = NULL; + } + } +} + +static void +sessionSaveYourselfCallback (SmcConn connection, + SmPointer client_data, + int saveType, + Bool shutdown, + int interact_Style, + Bool fast) +{ + sessionSaveState ((CompDisplay*) client_data); + + sessionSetRestartStyle (connection, SmRestartIfRunning); + sessionSetCloneRestartCommands (connection, (CompDisplay*) client_data); + SmcSaveYourselfDone (connection, 1); +} + +static void +sessionDieCallback (SmcConn connection, + SmPointer clientData) +{ + sessionCloseSession ((CompDisplay*) clientData); + exit (0); +} + +/* ice connection handling taken and updated from gnome-ice.c + * original gnome-ice.c code written by Tom Tromey + */ + +/* This is called when data is available on an ICE connection. */ +static Bool +sessionIceProcessMessages (void *data) +{ + IceConn connection = (IceConn) data; + IceProcessMessagesStatus status; + + status = IceProcessMessages (connection, NULL, NULL); + + if (status == IceProcessMessagesIOError) + { + 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 +sessionIceNewConnection (IceConn connection, + IcePointer clientData, + Bool opening, + IcePointer *watchData) +{ + SESSION_DISPLAY ((CompDisplay*) clientData); + + if (opening) + { + /* 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); + + sd->iceWatchFdHandle = compAddWatchFd (IceConnectionNumber (connection), + POLLIN | POLLPRI | POLLHUP | POLLERR, + sessionIceProcessMessages, connection); + + sd->iceConnected = 1; + } + else + { + if (sd->iceConnected) + { + compRemoveWatchFd (sd->iceWatchFdHandle); + + sd->iceWatchFdHandle = 0; + sd->iceConnected = 0; + } + } +} + +static IceIOErrorHandler oldIceHandler; + +static void +sessionIceErrorHandler (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 +sessionIceInit (CompDisplay *d) +{ + SESSION_DISPLAY (d); + + if (!sd->iceInitialized) + { + IceIOErrorHandler defaultIceHandler; + + oldIceHandler = IceSetIOErrorHandler (NULL); + defaultIceHandler = IceSetIOErrorHandler (sessionIceErrorHandler); + + if (oldIceHandler == defaultIceHandler) + oldIceHandler = NULL; + + IceAddConnectionWatch (sessionIceNewConnection, d); + + sd->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) +{ + static SmcCallbacks callbacks; + SessionDisplay *sd; + char *previousId = NULL;; + int i; + + sd = malloc (sizeof (SessionDisplay)); + if (!sd) + return FALSE; + + sd->visibleNameAtom = XInternAtom (d->display, + "_NET_WM_VISIBLE_NAME", 0); + sd->clientIdAtom = XInternAtom (d->display, + "SM_CLIENT_ID", 0); + + for (i = 0; i < programArgc; i++) + { + if (strcmp(programArgv[i], "--sm-client-id") == 0) + { + previousId = programArgv[++i]; + break; + } + } + + if (getenv ("SESSION_MANAGER")) + { + char errorBuffer[1024]; + + sessionIceInit (d); + + callbacks.save_yourself.callback = sessionSaveYourselfCallback; + callbacks.save_yourself.client_data = d; + + callbacks.die.callback = sessionDieCallback; + callbacks.die.client_data = NULL; + + sd->smcConnection = SmcOpenConnection (NULL, + NULL, + SmProtoMajor, + SmProtoMinor, + SmcSaveYourselfProcMask | + SmcDieProcMask, + &callbacks, + previousId, + &sd->smClientId, + sizeof (errorBuffer), + errorBuffer); + if (!sd->smcConnection) + { + compLogMessage (NULL, "session", CompLogLevelWarn, + "SmcOpenConnection failed: %s", + errorBuffer); + return FALSE; + } + else + sd->connected = FALSE; + } + + sd->iceConnected = FALSE; + sd->iceInitialized = FALSE; + + d->privates[displayPrivateIndex].ptr = sd; + + return TRUE; +} + +static void +sessionFiniDisplay (CompPlugin *p, CompDisplay *d) +{ + SESSION_DISPLAY (d); + sessionCloseSession (d); + 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; +} + -- cgit v1.1 From 3e1d798fb48e49e9d85721572e174f59c9350c83 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Fri, 21 Sep 2007 16:35:21 -0500 Subject: it works again --- session.c | 250 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 146 insertions(+), 104 deletions(-) diff --git a/session.c b/session.c index 6ed585e..5a9bd35 100644 --- a/session.c +++ b/session.c @@ -33,19 +33,22 @@ #include #include +#define SM_DEBUG(x) + +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 struct _SessionDisplay { Atom visibleNameAtom; Atom clientIdAtom; - - SmcConn smcConnection; - CompWatchFdHandle iceWatchFdHandle; - Bool connected; - Bool iceConnected; - Bool iceInitialized; - char *smClientId; } SessionDisplay; #define GET_SESSION_DISPLAY(d) \ @@ -127,7 +130,7 @@ sessionGetWindowName (CompDisplay *d, } static void -sessionSaveState (CompDisplay *d) +writeFile (CompDisplay *d) { SESSION_DISPLAY (d); CompScreen *s; @@ -141,7 +144,7 @@ sessionSaveState (CompDisplay *d) return; } - fprintf (outfile, "\n", sd->smClientId); + fprintf (outfile, "\n", smClientId); for (s = d->screens; s; s = s->next) { @@ -244,9 +247,8 @@ sessionSaveState (CompDisplay *d) } static void -sessionSetCloneRestartCommands (SmcConn connection, CompDisplay *d) +setCloneRestartCommands (SmcConn connection) { - SESSION_DISPLAY (d); char *restartv[10]; char *clonev[10]; SmProp prop1, prop2, *props[2]; @@ -260,7 +262,7 @@ sessionSetCloneRestartCommands (SmcConn connection, CompDisplay *d) ++i; restartv[i] = "--sm-client-id"; ++i; - restartv[i] = sd->smClientId; + restartv[i] = smClientId; ++i; restartv[i] = NULL; @@ -307,7 +309,7 @@ sessionSetCloneRestartCommands (SmcConn connection, CompDisplay *d) } static void -sessionSetRestartStyle (SmcConn connection, char hint) +setRestartStyle (SmcConn connection, char hint) { SmProp prop, *pProp; SmPropValue propVal; @@ -325,44 +327,109 @@ sessionSetRestartStyle (SmcConn connection, char hint) } static void -sessionCloseSession (CompDisplay *d) +saveYourselfGotProps (SmcConn connection, + SmPointer client_data, + int num_props, + SmProp **props) { - SESSION_DISPLAY (d); + setRestartStyle (connection, SmRestartIfRunning); + setCloneRestartCommands (connection); + SmcSaveYourselfDone (connection, 1); +} - if (sd->connected) - { - sessionSetRestartStyle (sd->smcConnection, SmRestartIfRunning); +static void +saveYourselfCallback (SmcConn connection, + SmPointer client_data, + int saveType, + Bool shutdown, + int interact_Style, + Bool fast) +{ + writeFile ((CompDisplay*) client_data); - if (SmcCloseConnection (sd->smcConnection, 0, NULL) != SmcConnectionInUse) - sd->connected = FALSE; - if (sd->smClientId) { - free (sd->smClientId); - sd->smClientId = NULL; - } - } + if (!SmcGetProperties (connection, saveYourselfGotProps, NULL)) + SmcSaveYourselfDone (connection, 1); } static void -sessionSaveYourselfCallback (SmcConn connection, - SmPointer client_data, - int saveType, - Bool shutdown, - int interact_Style, - Bool fast) +dieCallback (SmcConn connection, + SmPointer clientData) { - sessionSaveState ((CompDisplay*) client_data); + closeSession (); + exit (0); +} - sessionSetRestartStyle (connection, SmRestartIfRunning); - sessionSetCloneRestartCommands (connection, (CompDisplay*) client_data); - SmcSaveYourselfDone (connection, 1); +static void +saveCompleteCallback (SmcConn connection, + SmPointer clientData) +{ } static void -sessionDieCallback (SmcConn connection, - SmPointer clientData) +shutdownCancelledCallback (SmcConn connection, + SmPointer clientData) { - sessionCloseSession ((CompDisplay*) clientData); - exit (0); +} + +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 @@ -371,15 +438,20 @@ sessionDieCallback (SmcConn connection, /* This is called when data is available on an ICE connection. */ static Bool -sessionIceProcessMessages (void *data) +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); } @@ -390,35 +462,37 @@ sessionIceProcessMessages (void *data) /* 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 -sessionIceNewConnection (IceConn connection, - IcePointer clientData, - Bool opening, - IcePointer *watchData) +iceNewConnection (IceConn connection, + IcePointer clientData, + Bool opening, + IcePointer *watchData) { - SESSION_DISPLAY ((CompDisplay*) clientData); - 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); - sd->iceWatchFdHandle = compAddWatchFd (IceConnectionNumber (connection), - POLLIN | POLLPRI | POLLHUP | POLLERR, - sessionIceProcessMessages, connection); + iceWatchFdHandle = compAddWatchFd (IceConnectionNumber (connection), + POLLIN | POLLPRI | POLLHUP | POLLERR, + iceProcessMessages, connection); - sd->iceConnected = 1; + iceConnected = 1; } else { - if (sd->iceConnected) + SM_DEBUG (printf ("ICE connection closing\n")); + + if (iceConnected) { - compRemoveWatchFd (sd->iceWatchFdHandle); + compRemoveWatchFd (iceWatchFdHandle); - sd->iceWatchFdHandle = 0; - sd->iceConnected = 0; + iceWatchFdHandle = 0; + iceConnected = 0; } } } @@ -426,7 +500,7 @@ sessionIceNewConnection (IceConn connection, static IceIOErrorHandler oldIceHandler; static void -sessionIceErrorHandler (IceConn connection) +iceErrorHandler (IceConn connection) { if (oldIceHandler) (*oldIceHandler) (connection); @@ -435,28 +509,29 @@ sessionIceErrorHandler (IceConn connection) /* We call any handler installed before (or after) iceInit but avoid calling the default libICE handler which does an exit() */ static void -sessionIceInit (CompDisplay *d) +iceInit (void) { - SESSION_DISPLAY (d); + static Bool iceInitialized = 0; - if (!sd->iceInitialized) + if (!iceInitialized) { IceIOErrorHandler defaultIceHandler; oldIceHandler = IceSetIOErrorHandler (NULL); - defaultIceHandler = IceSetIOErrorHandler (sessionIceErrorHandler); + defaultIceHandler = IceSetIOErrorHandler (iceErrorHandler); if (oldIceHandler == defaultIceHandler) oldIceHandler = NULL; - IceAddConnectionWatch (sessionIceNewConnection, d); + IceAddConnectionWatch (iceNewConnection, NULL); - sd->iceInitialized = 1; + iceInitialized = 1; } } static int -sessionGetVersion(CompPlugin * p, int version) +sessionGetVersion(CompPlugin * p, + int version) { return ABIVERSION; } @@ -480,10 +555,9 @@ sessionFini (CompPlugin *p) static int sessionInitDisplay (CompPlugin *p, CompDisplay *d) { - static SmcCallbacks callbacks; - SessionDisplay *sd; - char *previousId = NULL;; - int i; + SessionDisplay *sd; + Bool found = FALSE; + int i; sd = malloc (sizeof (SessionDisplay)); if (!sd) @@ -498,47 +572,15 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) { if (strcmp(programArgv[i], "--sm-client-id") == 0) { - previousId = programArgv[++i]; + found = TRUE; break; } } - if (getenv ("SESSION_MANAGER")) - { - char errorBuffer[1024]; - - sessionIceInit (d); - - callbacks.save_yourself.callback = sessionSaveYourselfCallback; - callbacks.save_yourself.client_data = d; - - callbacks.die.callback = sessionDieCallback; - callbacks.die.client_data = NULL; - - sd->smcConnection = SmcOpenConnection (NULL, - NULL, - SmProtoMajor, - SmProtoMinor, - SmcSaveYourselfProcMask | - SmcDieProcMask, - &callbacks, - previousId, - &sd->smClientId, - sizeof (errorBuffer), - errorBuffer); - if (!sd->smcConnection) - { - compLogMessage (NULL, "session", CompLogLevelWarn, - "SmcOpenConnection failed: %s", - errorBuffer); - return FALSE; - } - else - sd->connected = FALSE; - } - - sd->iceConnected = FALSE; - sd->iceInitialized = FALSE; + if (found) + initSession2 (d, programArgv[++i]); + else + initSession2 (d, NULL); d->privates[displayPrivateIndex].ptr = sd; @@ -549,7 +591,7 @@ static void sessionFiniDisplay (CompPlugin *p, CompDisplay *d) { SESSION_DISPLAY (d); - sessionCloseSession (d); + closeSession (); free (sd); } -- cgit v1.1 From 1c9c0cba20bbdc3e55cb36c2e1aa1f26f21d688c Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 06:03:29 -0500 Subject: initialize the session even if we didn't get a client id --- session.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/session.c b/session.c index 5a9bd35..59b60bb 100644 --- a/session.c +++ b/session.c @@ -556,7 +556,7 @@ static int sessionInitDisplay (CompPlugin *p, CompDisplay *d) { SessionDisplay *sd; - Bool found = FALSE; + char *previousId = NULL; int i; sd = malloc (sizeof (SessionDisplay)); @@ -572,15 +572,12 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) { if (strcmp(programArgv[i], "--sm-client-id") == 0) { - found = TRUE; + previousId = programArgv[++i]; break; } } - if (found) - initSession2 (d, programArgv[++i]); - else - initSession2 (d, NULL); + initSession2 (d, previousId); d->privates[displayPrivateIndex].ptr = sd; -- cgit v1.1 From aba665de6264ac0187deead967a3cd80aa4de531 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 06:24:35 -0500 Subject: create save file properly using session ID --- session.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/session.c b/session.c index 59b60bb..c84d570 100644 --- a/session.c +++ b/session.c @@ -27,9 +27,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -130,15 +132,37 @@ sessionGetWindowName (CompDisplay *d, } static void -writeFile (CompDisplay *d) +saveState (CompDisplay *d) { SESSION_DISPLAY (d); - CompScreen *s; - CompWindow *w; - char *name; - FILE *outfile; + CompScreen *s; + CompWindow *w; + char filename[1024]; + char *name; + FILE *outfile; + struct passwd *p = getpwuid(geteuid()); + + //setup filename and create directories as needed + strncat (filename, p->pw_dir, 1024); + strncat (filename, "/.compiz/", 1024); + if (mkdir (filename, 0700) == 0 || errno == EEXIST) + { + strncat (filename, "session/", 1024); + if (mkdir (filename, 0700) == 0 || errno == EEXIST) + { + strncat (filename, smClientId, 1024); + } + else + { + return; + } + } + else + { + return; + } - outfile = fopen ("/home/travis/.config/compiz/session", "w"); + outfile = fopen (filename, "w"); if (outfile == NULL) { return; @@ -247,6 +271,11 @@ writeFile (CompDisplay *d) } static void +loadState (CompDisplay *d) +{ +} + +static void setCloneRestartCommands (SmcConn connection) { char *restartv[10]; @@ -345,7 +374,7 @@ saveYourselfCallback (SmcConn connection, int interact_Style, Bool fast) { - writeFile ((CompDisplay*) client_data); + saveState ((CompDisplay*) client_data); if (!SmcGetProperties (connection, saveYourselfGotProps, NULL)) SmcSaveYourselfDone (connection, 1); -- cgit v1.1 From 0c31ad82f6f0c38a198e01d054c6bf9db3c6eb45 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 18:20:20 -0500 Subject: blah blah, commit more often, or at least don't only commit when it's broken --- session.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 211 insertions(+), 50 deletions(-) diff --git a/session.c b/session.c index c84d570..65bf6bc 100644 --- a/session.c +++ b/session.c @@ -34,6 +34,9 @@ #include #include #include +#include +#include +#include #define SM_DEBUG(x) @@ -51,6 +54,7 @@ typedef struct _SessionDisplay { Atom visibleNameAtom; Atom clientIdAtom; + Atom embedInfoAtom; } SessionDisplay; #define GET_SESSION_DISPLAY(d) \ @@ -131,10 +135,106 @@ sessionGetWindowName (CompDisplay *d, 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; + + clientLeader = w->clientLeader; + clientId = NULL; + + 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 saveState (CompDisplay *d) { - SESSION_DISPLAY (d); CompScreen *s; CompWindow *w; char filename[1024]; @@ -178,55 +278,11 @@ saveState (CompDisplay *d) Window clientLeader; clientLeader = w->clientLeader; - if (w->clientLeader == w->id) + //filter out embedded windows (notification icons) + if (sessionGetIsEmbedded (d, w->id)) continue; - //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 (s, window->transientFor); - if (window->clientLeader != None) - { - clientLeader = window->clientLeader; - break; - } - } - } - - if (clientLeader != None) - { - XTextProperty text; - text.nitems = 0; - - if (XGetTextProperty (d->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 - XTextProperty text; - text.nitems = 0; - - if (XGetTextProperty (d->display, w->id, &text, sd->clientIdAtom)) - { - if (text.value) { - clientId = strndup ((char *)text.value, text.nitems); - XFree (text.value); - } - } - } + clientId = sessionGetClientId (w); if (clientId == NULL) continue; @@ -256,7 +312,8 @@ saveState (CompDisplay *d) //save workspace if (!(w->type & CompWindowTypeDesktopMask || w->type & CompWindowTypeDockMask)) - fprintf (outfile, " \n", w->desktop); + fprintf (outfile, " \n", + w->desktop); //save geometry fprintf (outfile, " \n", @@ -271,8 +328,107 @@ saveState (CompDisplay *d) } static void -loadState (CompDisplay *d) +loadState (CompDisplay *d, char *previousId) { + xmlDocPtr doc; + xmlNodePtr root; + xmlNodePtr cur; + CompScreen *s; + CompWindow *w; + char *filename; + char *name; + xmlChar *newName = NULL; + xmlChar *newClientId = NULL; + char *clientId = NULL; + Bool foundWindow = FALSE; + struct passwd *p = getpwuid(geteuid()); + + //setup filename and create directories as needed + filename = malloc (1024); + memset (filename, '\0', 1024); + strncat (filename, p->pw_dir, 1024); + strncat (filename, "/.compiz/", 1024); + strncat (filename, "session/", 1024); + strncat (filename, previousId, 1024); +printf ("loading file %s\n", filename); + + doc = xmlParseFile (filename); + free (filename); + if (doc == NULL) + return; + + root = xmlDocGetRootElement (doc); + if (root == NULL) + { + xmlFreeDoc (doc); + return; + } + + if (xmlStrcmp (root->name, BAD_CAST "compiz_session") != 0) + { + xmlFreeDoc (doc); + return; + } + + for (s = d->screens; s; s = s->next) + { + for (w = s->windows; w; w = w->next) + { + clientId = sessionGetClientId (w); + + if (clientId == NULL) + continue; + + name = sessionGetWindowName (d, w->id); + + cur = root->xmlChildrenNode; + while (cur != NULL) + { + printf ("current tag: %s\n", cur->name); + if (xmlStrcmp (cur->name, BAD_CAST "window") == 0) + { + newClientId = xmlGetProp (cur, BAD_CAST "id"); + if (newClientId != NULL) + { + if (clientId == (char*) newClientId) + { + foundWindow = TRUE; + } + xmlFree (newClientId); + } + + newName = xmlGetProp (cur, BAD_CAST "name"); + if (newName != NULL) + { + if (name == (char*) newName) + { + foundWindow = TRUE; + } + xmlFree (newName); + } + } + cur = cur->next; + } + if (foundWindow) + { + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + 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 @@ -596,6 +752,8 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) "_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++) { @@ -608,6 +766,9 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) initSession2 (d, previousId); + if (previousId != NULL) + loadState (d, previousId); + d->privates[displayPrivateIndex].ptr = sd; return TRUE; -- cgit v1.1 From 5950cfac047d24f02b758e650b9e2138919ddcfe Mon Sep 17 00:00:00 2001 From: amaranth Date: Sun, 23 Sep 2007 01:20:53 +0200 Subject: Dummy commit --- dummy | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dummy diff --git a/dummy b/dummy new file mode 100644 index 0000000..e69de29 -- cgit v1.1 From dfb2987154107833a415d9c0b161acc3dbbeacb3 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 18:52:13 -0500 Subject: cleanup --- session.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/session.c b/session.c index 65bf6bc..b47f67a 100644 --- a/session.c +++ b/session.c @@ -164,14 +164,13 @@ sessionGetClientId (CompWindow *w) XTextProperty text; text.nitems = 0; - clientLeader = w->clientLeader; clientId = NULL; - if (clientLeader == w->id) + if (w->clientLeader == w->id) return NULL; //try to find clientLeader on transient parents - if (clientLeader == None) + if (w->clientLeader == None) { CompWindow *window; window = w; @@ -381,8 +380,7 @@ printf ("loading file %s\n", filename); name = sessionGetWindowName (d, w->id); - cur = root->xmlChildrenNode; - while (cur != NULL) + for (cur = root->xmlChildrenNode; cur; cur = cur->next) { printf ("current tag: %s\n", cur->name); if (xmlStrcmp (cur->name, BAD_CAST "window") == 0) @@ -393,6 +391,7 @@ printf ("loading file %s\n", filename); if (clientId == (char*) newClientId) { foundWindow = TRUE; + break; } xmlFree (newClientId); } @@ -403,20 +402,20 @@ printf ("loading file %s\n", filename); if (name == (char*) newName) { foundWindow = TRUE; + break; } xmlFree (newName); } } - cur = cur->next; } + if (foundWindow) { - cur = cur->xmlChildrenNode; - while (cur != NULL) + for (cur = cur->xmlChildrenNode; cur; cur = cur->next) { if (xmlStrcmp (cur->name, BAD_CAST "geometry") == 0) { - double x, y, width, height; + double x, y, width, height; x = sessionGetIntForProp (cur, "x"); y = sessionGetIntForProp (cur, "y"); -- cgit v1.1 From 51ece2c0cd8f93d4cf1abf705781b5da2b7b422b Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 19:52:35 -0500 Subject: more cleanup, doesn't seem to crash anymore --- session.c | 253 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 128 insertions(+), 125 deletions(-) diff --git a/session.c b/session.c index b47f67a..1437cee 100644 --- a/session.c +++ b/session.c @@ -50,6 +50,9 @@ static void iceInit (void); static int displayPrivateIndex; +typedef void (* SessionWindowFunc) (CompWindow *w, char *clientId, char *name, + void *user_data); + typedef struct _SessionDisplay { Atom visibleNameAtom; @@ -230,19 +233,80 @@ sessionGetIntForProp (xmlNodePtr node, char *prop) 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); + + 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; + + if (clientId == NULL) + return; + + fprintf (outfile, " \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, " \n"); + + //save minimized + if (w->minimized) + fprintf (outfile, " \n"); + + //save maximized + if (w->state & MAXIMIZE_STATE) + fprintf (outfile, " \n"); + + //save workspace + if (!(w->type & CompWindowTypeDesktopMask || + w->type & CompWindowTypeDockMask)) + fprintf (outfile, " \n", + w->desktop); + + //save geometry + fprintf (outfile, " \n", + w->serverX, w->serverY, w->width, w->height); + + fprintf (outfile, " \n"); +} static void saveState (CompDisplay *d) { - CompScreen *s; - CompWindow *w; char filename[1024]; - char *name; FILE *outfile; - struct passwd *p = getpwuid(geteuid()); //setup filename and create directories as needed - strncat (filename, p->pw_dir, 1024); + strncat (filename, getenv("HOME"), 1024); strncat (filename, "/.compiz/", 1024); if (mkdir (filename, 0700) == 0 || errno == EEXIST) { @@ -269,61 +333,70 @@ saveState (CompDisplay *d) fprintf (outfile, "\n", smClientId); - for (s = d->screens; s; s = s->next) - { - for (w = s->windows; w; w = w->next) - { - char *clientId = NULL; - Window clientLeader; - clientLeader = w->clientLeader; + sessionForeachWindow (d, sessionWriteWindow, outfile); - //filter out embedded windows (notification icons) - if (sessionGetIsEmbedded (d, w->id)) - continue; + fprintf (outfile, "\n"); + fclose (outfile); +} - clientId = sessionGetClientId (w); +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) - continue; + if (clientId == NULL) + return; - name = sessionGetWindowName (d, w->id); + for (cur = root->xmlChildrenNode; cur; cur = cur->next) + { + printf ("current tag: %s\n", cur->name); + 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); + } - fprintf (outfile, " \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, " \n"); - - //save minimized - if (w->minimized) - fprintf (outfile, " \n"); - - //save maximized - if (w->state & MAXIMIZE_STATE) - fprintf (outfile, " \n"); - - //save workspace - if (!(w->type & CompWindowTypeDesktopMask || - w->type & CompWindowTypeDockMask)) - fprintf (outfile, " \n", - w->desktop); - - //save geometry - fprintf (outfile, " \n", - w->serverX, w->serverY, w->width, w->height); - - fprintf (outfile, " \n"); + newName = xmlGetProp (cur, BAD_CAST "name"); + if (newName != NULL) + { + if (name == (char*) newName) + { + foundWindow = TRUE; + break; + } + xmlFree (newName); + } } } - fprintf (outfile, "\n"); - fclose (outfile); + if (foundWindow) + { + 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 @@ -331,28 +404,16 @@ loadState (CompDisplay *d, char *previousId) { xmlDocPtr doc; xmlNodePtr root; - xmlNodePtr cur; - CompScreen *s; - CompWindow *w; - char *filename; - char *name; - xmlChar *newName = NULL; - xmlChar *newClientId = NULL; - char *clientId = NULL; - Bool foundWindow = FALSE; - struct passwd *p = getpwuid(geteuid()); + char filename[1024]; //setup filename and create directories as needed - filename = malloc (1024); - memset (filename, '\0', 1024); - strncat (filename, p->pw_dir, 1024); + strncat (filename, getenv("HOME"), 1024); strncat (filename, "/.compiz/", 1024); strncat (filename, "session/", 1024); strncat (filename, previousId, 1024); printf ("loading file %s\n", filename); doc = xmlParseFile (filename); - free (filename); if (doc == NULL) return; @@ -369,65 +430,7 @@ printf ("loading file %s\n", filename); return; } - for (s = d->screens; s; s = s->next) - { - for (w = s->windows; w; w = w->next) - { - clientId = sessionGetClientId (w); - - if (clientId == NULL) - continue; - - name = sessionGetWindowName (d, w->id); - - for (cur = root->xmlChildrenNode; cur; cur = cur->next) - { - printf ("current tag: %s\n", cur->name); - 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) - { - 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); - } - } - } - } - } + sessionForeachWindow (d, sessionReadWindow, root); } static void -- cgit v1.1 From 3ce96cc5d66ca21cc1e73941f77bf7d5678e26e6 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 19:57:36 -0500 Subject: delete dummy --- dummy | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dummy diff --git a/dummy b/dummy deleted file mode 100644 index e69de29..0000000 -- cgit v1.1 From 868cc90cccd8b9886d22f115acbed175bde70255 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 20:18:12 -0500 Subject: more cleanup --- session.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/session.c b/session.c index 1437cee..a56f261 100644 --- a/session.c +++ b/session.c @@ -304,15 +304,18 @@ saveState (CompDisplay *d) { char filename[1024]; FILE *outfile; + struct passwd *p = getpwuid(geteuid()); //setup filename and create directories as needed - strncat (filename, getenv("HOME"), 1024); - strncat (filename, "/.compiz/", 1024); + filename[0] = '\0'; + strncat (filename, p->pw_dir, 1024); + strncat (filename, "/.compiz", 1024); if (mkdir (filename, 0700) == 0 || errno == EEXIST) { - strncat (filename, "session/", 1024); + strncat (filename, "/session", 1024); if (mkdir (filename, 0700) == 0 || errno == EEXIST) { + strncat (filename, "/", 1024); strncat (filename, smClientId, 1024); } else @@ -353,9 +356,9 @@ sessionReadWindow (CompWindow *w, char *clientId, char *name, void *user_data) for (cur = root->xmlChildrenNode; cur; cur = cur->next) { - printf ("current tag: %s\n", cur->name); if (xmlStrcmp (cur->name, BAD_CAST "window") == 0) { + printf ("checking window\n"); newClientId = xmlGetProp (cur, BAD_CAST "id"); if (newClientId != NULL) { @@ -382,10 +385,12 @@ sessionReadWindow (CompWindow *w, char *clientId, char *name, void *user_data) if (foundWindow) { + printf ("found window\n"); for (cur = cur->xmlChildrenNode; cur; cur = cur->next) { if (xmlStrcmp (cur->name, BAD_CAST "geometry") == 0) { + printf ("setting geometry\n"); double x, y, width, height; x = sessionGetIntForProp (cur, "x"); @@ -405,13 +410,14 @@ loadState (CompDisplay *d, char *previousId) xmlDocPtr doc; xmlNodePtr root; char filename[1024]; + struct passwd *p = getpwuid(geteuid()); //setup filename and create directories as needed - strncat (filename, getenv("HOME"), 1024); + filename[0] = '\0'; + strncat (filename, p->pw_dir, 1024); strncat (filename, "/.compiz/", 1024); strncat (filename, "session/", 1024); strncat (filename, previousId, 1024); -printf ("loading file %s\n", filename); doc = xmlParseFile (filename); if (doc == NULL) @@ -419,20 +425,21 @@ printf ("loading file %s\n", filename); root = xmlDocGetRootElement (doc); if (root == NULL) - { - xmlFreeDoc (doc); - return; - } + goto out; if (xmlStrcmp (root->name, BAD_CAST "compiz_session") != 0) - { - xmlFreeDoc (doc); - return; - } + goto out; sessionForeachWindow (d, sessionReadWindow, root); + + out: + xmlFreeDoc(doc); + xmlCleanupParser(); } + + + static void setCloneRestartCommands (SmcConn connection) { @@ -716,6 +723,9 @@ iceInit (void) } } + + + static int sessionGetVersion(CompPlugin * p, int version) -- cgit v1.1 From 5663004ef3e6b1726324d48bdcfd9e70ba83e3e0 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 21:14:05 -0500 Subject: add ignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build -- cgit v1.1 From 4023e0c13c0b6fa24c91e29ab35d24657fdcb48f Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 12:28:42 +1000 Subject: Implement mkdir -p Makes implementing XDG_DATA_HOME support much easier. Why doesn't the stdlib implement this? --- session.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/session.c b/session.c index a56f261..92a6dea 100644 --- a/session.c +++ b/session.c @@ -299,6 +299,47 @@ sessionWriteWindow (CompWindow *w, char *clientId, char *name, void *user_data) fprintf (outfile, " \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, int mode) +{ + char *partialPath, *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 (partialPath, mode); + + free (partialPath); + } + return success; +} + static void saveState (CompDisplay *d) { -- cgit v1.1 From db8d558d524e14f17115250aaa6171ab44e2ad1c Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 21:33:52 -0500 Subject: fix crash by adding metadata to make plugin load very early --- session.xml.in | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 session.xml.in diff --git a/session.xml.in b/session.xml.in new file mode 100644 index 0000000..67e4d49 --- /dev/null +++ b/session.xml.in @@ -0,0 +1,15 @@ + + + + + ccp + + + <_short>Session Management + <_long>Talk to session manager and save/load window state + Utility + + + + + -- cgit v1.1 From 7ae2ce926bb11554835698d35ea646ebcba56db5 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 21:35:49 -0500 Subject: add more dependencies --- session.xml.in | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/session.xml.in b/session.xml.in index 67e4d49..c2ecc2e 100644 --- a/session.xml.in +++ b/session.xml.in @@ -1,14 +1,16 @@ - - - - ccp - - - <_short>Session Management - <_long>Talk to session manager and save/load window state - Utility - + + + + ccp + gconf + kconfig + + + <_short>Session Management + <_long>Talk to session manager and save/load window state + Utility + -- cgit v1.1 From e43ab1237f6b3fdf1ea7a142fc239170a0809ac8 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 12:43:59 +1000 Subject: Follow XDG BaseDir spec. Put session files in /compiz/session, with default of .local/share/compiz/session --- session.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/session.c b/session.c index 92a6dea..1b89bf1 100644 --- a/session.c +++ b/session.c @@ -40,6 +40,8 @@ #define SM_DEBUG(x) +#define XDG_DATA_DEFAULT ".local/share" + static SmcConn smcConnection; static CompWatchFdHandle iceWatchFdHandle; static Bool connected = 0; @@ -344,25 +346,27 @@ static void saveState (CompDisplay *d) { char filename[1024]; + char *xdgDir; FILE *outfile; struct passwd *p = getpwuid(geteuid()); //setup filename and create directories as needed filename[0] = '\0'; - strncat (filename, p->pw_dir, 1024); - strncat (filename, "/.compiz", 1024); - if (mkdir (filename, 0700) == 0 || errno == EEXIST) + if (xdgDir = getenv ("XDG_DATA_HOME")) { - strncat (filename, "/session", 1024); - if (mkdir (filename, 0700) == 0 || errno == EEXIST) - { - strncat (filename, "/", 1024); - strncat (filename, smClientId, 1024); - } - else - { - return; - } + strncat (filename, xdgDir, 1024); + } + else + { + strncat (filename, p->pw_dir, 1024); + strncat (filename, "/", 1024); + strncat (filename, XDG_DATA_DEFAULT, 1024); + } + strncat (filename, "/compiz/session", 1024); + if (mkdirp (filename, 700)) + { + strncat (filename, "/", 1024); + strncat (filename, smClientId, 1024); } else { -- cgit v1.1 From 6beeb7a332e4f454a2e03eb46018fe183f4d1165 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 12:45:55 +1000 Subject: Match coding style --- session.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/session.c b/session.c index 1b89bf1..ee22155 100644 --- a/session.c +++ b/session.c @@ -315,7 +315,8 @@ sessionWriteWindow (CompWindow *w, char *clientId, char *name, void *user_data) static Bool mkdirp(const char *path, int mode) { - char *partialPath, *delim; + char *partialPath; + char *delim; Bool success; success = !mkdir (path, mode); /* Mkdir returns 0 on success */ -- cgit v1.1 From 73e50886d8a0feda980f189ff77bc5b4bac56389 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 13:04:43 +1000 Subject: Factor out getSessionFilePath from saveState --- session.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/session.c b/session.c index ee22155..f5e195f 100644 --- a/session.c +++ b/session.c @@ -343,27 +343,39 @@ static Bool mkdirp(const char *path, int mode) return success; } -static void -saveState (CompDisplay *d) +/** + * 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 filename[1024]; char *xdgDir; - FILE *outfile; - struct passwd *p = getpwuid(geteuid()); - //setup filename and create directories as needed - filename[0] = '\0'; + buffer[0] = '\0'; if (xdgDir = getenv ("XDG_DATA_HOME")) { - strncat (filename, xdgDir, 1024); + strncat (buffer, xdgDir, size); } else { - strncat (filename, p->pw_dir, 1024); - strncat (filename, "/", 1024); - strncat (filename, XDG_DATA_DEFAULT, 1024); + strncat (buffer, p->pw_dir, size); + strncat (buffer, "/", size); + strncat (buffer, XDG_DATA_DEFAULT, size); } - strncat (filename, "/compiz/session", 1024); + return buffer; +} + +static void +saveState (CompDisplay *d) +{ + char filename[1024]; + FILE *outfile; + struct passwd *p = getpwuid(geteuid()); + + getSessionFilePath(filename, 1024); if (mkdirp (filename, 700)) { strncat (filename, "/", 1024); -- cgit v1.1 From 51a2d30e4193e55dbb3c1c138c9d989f71adc0d6 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 13:10:02 +1000 Subject: Make loadState use getSessionFilePath() XDG BaseDir spec compliance is now feature-complete (I hope!) --- session.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/session.c b/session.c index f5e195f..9508174 100644 --- a/session.c +++ b/session.c @@ -470,11 +470,8 @@ loadState (CompDisplay *d, char *previousId) char filename[1024]; struct passwd *p = getpwuid(geteuid()); - //setup filename and create directories as needed - filename[0] = '\0'; - strncat (filename, p->pw_dir, 1024); - strncat (filename, "/.compiz/", 1024); - strncat (filename, "session/", 1024); + getSessionFilePath (filename, 1024); + strncat (filename, "/", 1024); strncat (filename, previousId, 1024); doc = xmlParseFile (filename); -- cgit v1.1 From 0f2fb2780853c091139ca32a14aad9e7c65e998f Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 13:12:55 +1000 Subject: Fix getSessionFilePath build, and remove surplus variables from \{load,save\}State --- session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session.c b/session.c index 9508174..b9b3297 100644 --- a/session.c +++ b/session.c @@ -353,6 +353,8 @@ 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")) @@ -373,7 +375,6 @@ saveState (CompDisplay *d) { char filename[1024]; FILE *outfile; - struct passwd *p = getpwuid(geteuid()); getSessionFilePath(filename, 1024); if (mkdirp (filename, 700)) @@ -468,7 +469,6 @@ loadState (CompDisplay *d, char *previousId) xmlDocPtr doc; xmlNodePtr root; char filename[1024]; - struct passwd *p = getpwuid(geteuid()); getSessionFilePath (filename, 1024); strncat (filename, "/", 1024); -- cgit v1.1 From 782d173328d3389d329e4a337e26afad7754641f Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 13:14:16 +1000 Subject: Silence gcc 'paren around assignment as truth value' warning --- session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.c b/session.c index b9b3297..b14bb62 100644 --- a/session.c +++ b/session.c @@ -357,7 +357,7 @@ getSessionFilePath (char *buffer, size_t size) //setup filename and create directories as needed buffer[0] = '\0'; - if (xdgDir = getenv ("XDG_DATA_HOME")) + if ((xdgDir = getenv ("XDG_DATA_HOME"))) { strncat (buffer, xdgDir, size); } -- cgit v1.1 From 1b539095f21ba5c6914bea8ca249a5998b2e8a62 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sat, 22 Sep 2007 22:25:12 -0500 Subject: still with the crashing --- session.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/session.c b/session.c index a56f261..6669287 100644 --- a/session.c +++ b/session.c @@ -168,12 +168,13 @@ sessionGetClientId (CompWindow *w) text.nitems = 0; clientId = NULL; + clientLeader = w->clientLeader; - if (w->clientLeader == w->id) + if (clientLeader == w->id) return NULL; //try to find clientLeader on transient parents - if (w->clientLeader == None) + if (clientLeader == None) { CompWindow *window; window = w; @@ -251,6 +252,9 @@ sessionForeachWindow (CompDisplay *d, SessionWindowFunc func, void *user_data) clientId = sessionGetClientId (w); + if (clientId == NULL) + continue; + name = sessionGetWindowName (d, w->id); (* func) (w, clientId, name, user_data); @@ -263,9 +267,6 @@ sessionWriteWindow (CompWindow *w, char *clientId, char *name, void *user_data) { FILE *outfile = (FILE*) user_data; - if (clientId == NULL) - return; - fprintf (outfile, " \n", clientId, name ? name : "", @@ -348,8 +349,8 @@ sessionReadWindow (CompWindow *w, char *clientId, char *name, void *user_data) xmlNodePtr cur; xmlChar *newName; xmlChar *newClientId; - Bool foundWindow = FALSE; - xmlNodePtr root = (xmlNodePtr) user_data; + Bool foundWindow = FALSE; + xmlNodePtr root = (xmlNodePtr) user_data; if (clientId == NULL) return; @@ -358,7 +359,6 @@ sessionReadWindow (CompWindow *w, char *clientId, char *name, void *user_data) { if (xmlStrcmp (cur->name, BAD_CAST "window") == 0) { - printf ("checking window\n"); newClientId = xmlGetProp (cur, BAD_CAST "id"); if (newClientId != NULL) { @@ -390,7 +390,6 @@ sessionReadWindow (CompWindow *w, char *clientId, char *name, void *user_data) { if (xmlStrcmp (cur->name, BAD_CAST "geometry") == 0) { - printf ("setting geometry\n"); double x, y, width, height; x = sessionGetIntForProp (cur, "x"); @@ -753,7 +752,7 @@ static int sessionInitDisplay (CompPlugin *p, CompDisplay *d) { SessionDisplay *sd; - char *previousId = NULL; + char *previousId; int i; sd = malloc (sizeof (SessionDisplay)); @@ -771,7 +770,10 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) { if (strcmp(programArgv[i], "--sm-client-id") == 0) { - previousId = programArgv[++i]; + i++; + printf ("%s\n", programArgv[i]); + previousId = malloc (strlen (programArgv[i]) + 1); + previousId = strdup (programArgv[i]); break; } } -- cgit v1.1 From 3beb80eeb266cdf2f452b8e64a49bbdd6557fe76 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 18:33:25 +1000 Subject: Fix segfault on startup when no previous session ID specified It is important to remember that pointers are not initialised to NULL automatically! --- session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.c b/session.c index b5dd618..6c4bb14 100644 --- a/session.c +++ b/session.c @@ -807,8 +807,8 @@ static int sessionInitDisplay (CompPlugin *p, CompDisplay *d) { SessionDisplay *sd; - char *previousId; int i; + char *previousId = NULL; sd = malloc (sizeof (SessionDisplay)); if (!sd) -- cgit v1.1 From d28696831980fb3226638f48730d3566cb25613d Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 18:35:02 +1000 Subject: Fix segfault on startup when a previous session ID is specified It is important to remember to assign global pointers before calling functions that try to dereference them! :) --- session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session.c b/session.c index 6c4bb14..b53aad9 100644 --- a/session.c +++ b/session.c @@ -814,6 +814,8 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) if (!sd) return FALSE; + d->privates[displayPrivateIndex].ptr = sd; + sd->visibleNameAtom = XInternAtom (d->display, "_NET_WM_VISIBLE_NAME", 0); sd->clientIdAtom = XInternAtom (d->display, @@ -838,8 +840,6 @@ sessionInitDisplay (CompPlugin *p, CompDisplay *d) if (previousId != NULL) loadState (d, previousId); - d->privates[displayPrivateIndex].ptr = sd; - return TRUE; } -- cgit v1.1 From a29deb7d1483bdab8f6839be3408ff3ac5ac08a5 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 18:38:48 +1000 Subject: Return the right subdirectory from getSessionFilePath. And now for some stupidity of my own. Actually append /compiz/session to . --- session.c | 1 + 1 file changed, 1 insertion(+) diff --git a/session.c b/session.c index b53aad9..5488bdd 100644 --- a/session.c +++ b/session.c @@ -368,6 +368,7 @@ getSessionFilePath (char *buffer, size_t size) strncat (buffer, "/", size); strncat (buffer, XDG_DATA_DEFAULT, size); } + strncat (buffer, "/compiz/session", size); return buffer; } -- cgit v1.1 From 785fc4dc1167ad7e845133fa8e082a01d45c5773 Mon Sep 17 00:00:00 2001 From: Christopher James Halse Rogers Date: Sun, 23 Sep 2007 18:51:38 +1000 Subject: Fix permission setting & path creation in mkdirp --- session.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/session.c b/session.c index 5488bdd..0762743 100644 --- a/session.c +++ b/session.c @@ -314,7 +314,7 @@ sessionWriteWindow (CompWindow *w, char *clientId, char *name, void *user_data) * file. It should return FALSE if a file exists with the name we want. **/ -static Bool mkdirp(const char *path, int mode) +static Bool mkdirp(const char *path, mode_t mode) { char *partialPath; char *delim; @@ -337,7 +337,7 @@ static Bool mkdirp(const char *path, int mode) partialPath[delim - path] = '\0'; if (mkdirp (partialPath, mode)); - success = !mkdir (partialPath, mode); + success = !mkdir (path, mode); free (partialPath); } @@ -379,7 +379,7 @@ saveState (CompDisplay *d) FILE *outfile; getSessionFilePath(filename, 1024); - if (mkdirp (filename, 700)) + if (mkdirp (filename, 0700)) { strncat (filename, "/", 1024); strncat (filename, smClientId, 1024); -- cgit v1.1