From 12f82239701b65d0d16d7f0ea48b9817d1253731 Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Mon, 31 Jan 2005 08:37:38 +0000 Subject: [PATCH] *** empty log message *** (Old svn revision: 527) --- Makefile.am | 1 - Makefile.in | 538 ---------------------------------------- src/Makefile.am | 2 +- src/functions.c | 138 +++++++++++ src/functions.h | 34 +++ src/gui.c | 260 +++++++++++++++++++ src/gui.h | 36 +++ src/main.c | 53 ++++ src/types.h | 33 +++ src/xfce4-taskmanager | Bin 37062 -> 0 bytes src/xfce4-taskmanager.c | 325 ------------------------ 11 files changed, 555 insertions(+), 865 deletions(-) delete mode 100644 Makefile.am delete mode 100644 Makefile.in create mode 100644 src/functions.c create mode 100644 src/functions.h create mode 100644 src/gui.c create mode 100644 src/gui.h create mode 100644 src/main.c create mode 100644 src/types.h delete mode 100755 src/xfce4-taskmanager delete mode 100644 src/xfce4-taskmanager.c diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index f963eff..0000000 --- a/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src \ No newline at end of file diff --git a/Makefile.in b/Makefile.in deleted file mode 100644 index f598073..0000000 --- a/Makefile.in +++ /dev/null @@ -1,538 +0,0 @@ -# Makefile.in generated by automake 1.9.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = . -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ - ChangeLog INSTALL NEWS depcomp install-sh missing -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno configure.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-exec-recursive install-info-recursive \ - install-recursive installcheck-recursive installdirs-recursive \ - pdf-recursive ps-recursive uninstall-info-recursive \ - uninstall-recursive -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - { test ! -d $(distdir) \ - || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr $(distdir); }; } -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DEPS_CFLAGS = @DEPS_CFLAGS@ -DEPS_LIBS = @DEPS_LIBS@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EXEEXT = @EXEEXT@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_STRIP = @ac_ct_STRIP@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -SUBDIRS = src -all: all-recursive - -.SUFFIXES: -am--refresh: - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ - cd $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -uninstall-info-am: - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @set fnord $$MAKEFLAGS; amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $$MAKEFLAGS; amf=$$2; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(am__remove_distdir) - mkdir $(distdir) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(mkdir_p) "$(distdir)/$$subdir" \ - || exit 1; \ - distdir=`$(am__cd) $(distdir) && pwd`; \ - top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ - (cd $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$top_distdir" \ - distdir="$$distdir/$$subdir" \ - distdir) \ - || exit 1; \ - fi; \ - done - -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r $(distdir) -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) - -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && cd $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck - $(am__remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' -distuninstallcheck: - @cd $(distuninstallcheck_dir) \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -info: info-recursive - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-recursive - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: uninstall-info-am - -uninstall-info: uninstall-info-recursive - -.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ - check-am clean clean-generic clean-recursive ctags \ - ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \ - dist-tarZ dist-zip distcheck distclean distclean-generic \ - distclean-recursive distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - maintainer-clean-recursive mostlyclean mostlyclean-generic \ - mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/Makefile.am b/src/Makefile.am index 03d996f..300c380 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ bin_PROGRAMS = xfce4-taskmanager -xfce4_taskmanager_SOURCES = xfce4-taskmanager.c +xfce4_taskmanager_SOURCES = main.c types.h gui.c gui.h functions.c functions.h INCLUDES = $(DEPS_CFLAGS) diff --git a/src/functions.c b/src/functions.c new file mode 100644 index 0000000..92a6a05 --- /dev/null +++ b/src/functions.c @@ -0,0 +1,138 @@ +/* + * xfce4-taskmanager - very simple taskmanger + * + * Copyright (c) 2004 Johannes Zellner, + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "functions.h" + +task_count = 0; + +/* function to kill the current task */ +void send_signal_to_task(gchar *task_id, gchar *signal) +{ + if(task_id != "" && signal != NULL) + { + gchar command[64] = "kill -"; + g_strlcat(command,signal, 64); + g_strlcat(command," ", 64); + g_strlcat(command,task_id, 64); + + if(system(command) != 0) + xfce_err("Couldn't %s the task with ID %s", signal, task_id); + } +} + +void refresh_task_list() +{ + /* markes all tasks to "not checked" */ + gint i; + + for(i = 0; i < task_count; i++) + all_tasks[i].checked = FALSE; + + /* load the current taskdetails */ + DIR *dir; + struct dirent *dir_entry; + + if((dir = opendir("/proc")) == NULL) + printf("Error: couldn't load the directory\n"); + + while((dir_entry = readdir(dir)) != NULL) + { + if(atoi(dir_entry->d_name) != 0) + { + FILE *task_file; + gchar task_file_name[256] = "/proc/"; + g_strlcat(task_file_name,dir_entry->d_name, 256); + g_strlcat(task_file_name,"/status", 256); + + gchar buffer[256]; + gint line_count = 0; + struct task task; + struct passwd *passwdp; + + if((task_file = fopen(task_file_name,"r")) != NULL) + { + while(fgets(buffer, 256, task_file) != NULL) + { + if(line_count == 0) + strcpy(task.name,g_strstrip(g_strsplit(buffer, ":", 2)[1])); + else if(line_count == 3) + strcpy(task.pid,g_strstrip(g_strsplit(buffer, ":", 2)[1])); + else if(line_count == 5) + strcpy(task.ppid,g_strstrip(g_strsplit(buffer, ":", 2)[1])); + else if(line_count == 7) + { + passwdp = getpwuid(atoi(g_strsplit(g_strstrip(g_strsplit(buffer, ":", 2)[1]), "\t", 2)[0])); + strcpy(task.uid, passwdp->pw_name); + } + + line_count++; + } + + line_count = 0; + fclose(task_file); + + /* check if task is new and marks the task that its checked*/ + gboolean new_task = TRUE; + + for(i = 0; i < task_count; i++) + { + if(strcmp(all_tasks[i].pid,task.pid) == 0) + { + all_tasks[i].checked = TRUE; + new_task = FALSE; + } + } + + if(new_task) + { + task.checked = TRUE; + all_tasks[task_count] = task; + task_count++; + add_new_list_item(task); + } + } + } + } + closedir(dir); + + /* removing all tasks which are not marked */ + i = 0; + + while(i < task_count) + { + if(!all_tasks[i].checked) + { + remove_list_item(all_tasks[i]); + remove_task_from_array(i); + } + i++; + } +} + +void remove_task_from_array(gint count) +{ + gint i; + + for(i = count; i < task_count; i++) + { + all_tasks[i] = all_tasks[i+1]; + } + task_count--; +} diff --git a/src/functions.h b/src/functions.h new file mode 100644 index 0000000..04a2459 --- /dev/null +++ b/src/functions.h @@ -0,0 +1,34 @@ +/* + * xfce4-taskmanager - very simple taskmanger + * + * Copyright (c) 2004 Johannes Zellner, + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "types.h" + +struct task all_tasks[512]; +gint task_count; + +struct task task_list; + +void refresh_task_list(void); +void send_signal_to_task(gchar *task_id, gchar *signal); diff --git a/src/gui.c b/src/gui.c new file mode 100644 index 0000000..c594a02 --- /dev/null +++ b/src/gui.c @@ -0,0 +1,260 @@ +/* + * xfce4-taskmanager - very simple taskmanger + * + * Copyright (c) 2004 Johannes Zellner, + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "gui.h" + +/* create the GUI */ +void create_gui(void) +{ + GtkWidget *window, *eventbox, *box, *button, *scrolled_window, *tree_view, *main_popup_menu, *task_popup_menu; + GtkCellRenderer *cell_renderer; + GtkTreeViewColumn *column; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), "xfce4-taskmanager"); + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); + gtk_widget_set_size_request(GTK_WIDGET(window), 450, 400); + + /* popupmenus */ + task_popup_menu = create_task_popup_menu(); + main_popup_menu = create_main_popup_menu(); + + /* eventbox */ + eventbox = gtk_event_box_new(); + gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventbox), FALSE); + gtk_widget_add_events(GTK_WIDGET(eventbox), "BUTTON_PRESS"); + g_signal_connect_swapped(G_OBJECT(eventbox), "button-press-event", G_CALLBACK(handle_mouse_events), G_OBJECT(main_popup_menu)); + gtk_container_set_border_width(GTK_CONTAINER(eventbox), 0); + + gtk_container_add(GTK_CONTAINER(window), eventbox); + gtk_widget_show(eventbox); + + box = gtk_vbox_new(FALSE, 10); + gtk_container_set_border_width(GTK_CONTAINER(box), 10); + gtk_container_add(GTK_CONTAINER(eventbox), box); + gtk_widget_show(box); + + /* tasklist */ + scrolled_window = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_ETCHED_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start(GTK_BOX(box), scrolled_window, TRUE, TRUE, 0); + gtk_widget_show(scrolled_window); + + tree_view = gtk_tree_view_new(); + g_signal_connect_swapped(G_OBJECT(tree_view), "button-press-event", G_CALLBACK(handle_mouse_events), G_OBJECT(task_popup_menu)); + gtk_container_add(GTK_CONTAINER(scrolled_window), tree_view); + gtk_widget_show(tree_view); + + selection = gtk_tree_view_get_selection(tree_view); + + list_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), list_store); + + cell_renderer = gtk_cell_renderer_text_new(); + + column = gtk_tree_view_column_new_with_attributes("User", cell_renderer, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column); + + column = gtk_tree_view_column_new_with_attributes("PID", cell_renderer, "text", 1, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column); + + column = gtk_tree_view_column_new_with_attributes("PPID", cell_renderer, "text", 2, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column); + + column = gtk_tree_view_column_new_with_attributes("Command", cell_renderer, "text", 3, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column); + + /* load the tasklist */ + refresh_task_list(); + + /* Quit-button */ + button = gtk_button_new_from_stock(GTK_STOCK_QUIT); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0); + gtk_widget_show(button); + + gtk_widget_show(window); +} + +/* add new tasks to the list */ +gboolean add_new_list_item(struct task task) +{ + GtkTreeIter iter; + + /* Append new line in the list */ + gtk_list_store_append(GTK_LIST_STORE(list_store), &iter); + + /* Fill the appended line with data */ + gchar *list_value_1 = g_strdup_printf("%s", task.uid); + gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, list_value_1, -1); + g_free(list_value_1); + + gchar *list_value_2 = g_strdup_printf("%s", task.pid); + gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 1, list_value_2, -1); + g_free(list_value_2); + + gchar *list_value_3 = g_strdup_printf("%s", task.ppid); + gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 2, list_value_3, -1); + g_free(list_value_3); + + gchar *list_value_4 = g_strdup_printf("%s", task.name); + gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 3, list_value_4, -1); + g_free(list_value_4); + + return(TRUE); +} + +void remove_list_item(struct task task) +{ + gboolean valid; + GtkTreeIter iter; + + valid = gtk_tree_model_get_iter_first(list_store, &iter); + + while(valid) + { + gchar *str_data; + gtk_tree_model_get(list_store, &iter, 1, &str_data, -1); + + if(strcmp(task.pid,str_data) == 0) + { + gtk_list_store_remove(list_store, &iter); + g_free(str_data); + break; + } + g_free(str_data); + + valid = gtk_tree_model_iter_next(list_store, &iter); + } +} + +GtkWidget *create_task_popup_menu() +{ + GtkWidget *menu, *menuitem; + + menu = gtk_menu_new(); + + menuitem = gtk_menu_item_new_with_label("Stop"); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(handle_task_menu), "STOP"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_menu_item_new_with_label("Continue"); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(handle_task_menu), "CONT"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_menu_item_new_with_label("Term"); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(handle_task_menu), "TERM"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_menu_item_new_with_label("Kill"); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(handle_task_menu), "KILL"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + return(menu); +} + +GtkWidget *create_main_popup_menu() +{ + GtkWidget *menu, *menuitem; + + menu = gtk_menu_new(); + + menuitem = gtk_menu_item_new_with_label("About"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_main_quit), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show(menuitem); + + return(menu); +} + +gboolean handle_mouse_events(GtkWidget *widget, GdkEventButton *event) +{ + if(event->button == 3) + { + GdkEventButton *mouseevent = (GdkEventButton *)event; + gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL, mouseevent->button, mouseevent->time); + return FALSE; + } + return(FALSE); +} + +void handle_task_menu(GtkWidget *widget, gchar *signal) +{ + if(signal != NULL) + { + if(strcmp(signal, "TERM") == 0) + { + if(xfce_confirm("Really TERM the Task?", GTK_STOCK_YES, NULL)) + { + gchar *task_id = ""; + GtkTreeModel *model; + GtkTreeIter iter; + + if(gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gtk_tree_model_get(model, &iter, 1, &task_id, -1); + send_signal_to_task(task_id, signal); + //refresh_task_list(); + } + } + } + else if(strcmp(signal, "KILL") == 0) + { + if(xfce_confirm("Really KILL the Task?", GTK_STOCK_YES, NULL)) + { + gchar *task_id = ""; + GtkTreeModel *model; + GtkTreeIter iter; + + if(gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gtk_tree_model_get(model, &iter, 1, &task_id, -1); + send_signal_to_task(task_id, signal); + //refresh_task_list(); + } + } + } + else + { + gchar *task_id = ""; + GtkTreeModel *model; + GtkTreeIter iter; + + if(gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gtk_tree_model_get(model, &iter, 1, &task_id, -1); + send_signal_to_task(task_id, signal); + } + } + } +} diff --git a/src/gui.h b/src/gui.h new file mode 100644 index 0000000..465811b --- /dev/null +++ b/src/gui.h @@ -0,0 +1,36 @@ +/* + * xfce4-taskmanager - very simple taskmanger + * + * Copyright (c) 2004 Johannes Zellner, + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "types.h" +#include "functions.h" + +GtkTreeSelection *selection; +GtkListStore *list_store; + +void gui_create(void); +gboolean add_new_list_item(struct task task); +void remove_list_item(struct task task); +GtkWidget *create_task_popup_menu(void); +GtkWidget *create_main_popup_menu(void); +gboolean handle_mouse_events(GtkWidget *widget, GdkEventButton *event); +void handle_task_menu(GtkWidget *widget, gchar *signal); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..dfd1fea --- /dev/null +++ b/src/main.c @@ -0,0 +1,53 @@ +/* + * xfce4-taskmanager - very simple taskmanger + * + * Copyright (c) 2004 Johannes Zellner, + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "gui.h" + +/* config vars */ +#define REFRESH_INTERVAL 1 + +/* handler for SIGALRM to refresh the list */ +void refresh_handler(void) +{ + refresh_task_list(); + alarm(REFRESH_INTERVAL); +} + +/* main */ +int main(int argc, char *argv[]) +{ + gtk_init(&argc, &argv); + + create_gui(); + + signal(SIGALRM, refresh_handler); + alarm(REFRESH_INTERVAL); + + gtk_main(); + + return 0; +} diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..092ff0a --- /dev/null +++ b/src/types.h @@ -0,0 +1,33 @@ +/* + * xfce4-taskmanager - very simple taskmanger + * + * Copyright (c) 2004 Johannes Zellner, + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __TYPES_H_ +#define __TYPES_H_ + +struct task +{ + gchar pid[256]; + gchar ppid[256]; + gchar uid[256]; + gchar name[256]; + gboolean checked; +}; + +#endif diff --git a/src/xfce4-taskmanager b/src/xfce4-taskmanager deleted file mode 100755 index ae4c22746a49b67daef26e936062db933af7e8cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37062 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 Zfr - * - * 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 Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* config vars */ -#define REFRESH_INTERVAL 3 - -gchar *current_task_id = ""; -GtkListStore *model; -GtkWidget *window; - -struct task -{ - gchar pid[256]; - gchar ppid[256]; - gchar uid[256]; - gchar name[256]; -}; - -/* called, if the user select a listitem */ -static void select_task(GtkTreeSelection *selection) -{ - GtkTreeIter iter; - GtkTreeModel *model; - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - gtk_tree_model_get (model, &iter, 1, ¤t_task_id, -1); - } -} - -/* appends a new listitem */ -static void add_new_list_item(struct task task) -{ - GtkTreeIter iter; - struct passwd *passwdp; - - /* Append new line in the list */ - gtk_list_store_append(GTK_LIST_STORE(model), &iter); - - /* Fill the appended line with data */ - passwdp = getpwuid(atoi(task.uid)); - gchar *list_value_1 = g_strdup_printf("%s", passwdp->pw_name); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, list_value_1, -1); - g_free(list_value_1); - - gchar *list_value_2 = g_strdup_printf("%s", task.pid); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, list_value_2, -1); - g_free(list_value_2); - - gchar *list_value_3 = g_strdup_printf("%s", task.ppid); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, 2, list_value_3, -1); - g_free(list_value_3); - - gchar *list_value_4 = g_strdup_printf("%s", task.name); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, 3, list_value_4, -1); - g_free(list_value_4); -} - -/* reads all taskes from 'ps' and creates the listitems */ -static void get_task_list(void) -{ - DIR *dir; - struct dirent *dir_entry; - - if((dir = opendir("/proc")) == NULL) - printf("Error: couldn't load the directory\n"); - - while((dir_entry = readdir(dir)) != NULL) - { - if(atoi(dir_entry->d_name) != 0) - { - FILE *task_file; - gchar task_file_name[256] = "/proc/"; - g_strlcat(task_file_name,dir_entry->d_name, 256); - g_strlcat(task_file_name,"/status", 256); - - gchar buffer[256]; - gint line_count = 0; - struct task task; - - if((task_file = fopen(task_file_name,"r")) != NULL) - { - while(fgets(buffer, 256, task_file) != NULL) - { - if(line_count == 0) - strcpy(task.name,g_strstrip(g_strsplit(buffer, ":", 2)[1])); - else if(line_count == 3) - strcpy(task.pid,g_strstrip(g_strsplit(buffer, ":", 2)[1])); - else if(line_count == 5) - strcpy(task.ppid,g_strstrip(g_strsplit(buffer, ":", 2)[1])); - else if(line_count == 7) - strcpy(task.uid,g_strsplit(g_strstrip(g_strsplit(buffer, ":", 2)[1]), "\t", 2)[0]); - - line_count++; - } - - line_count = 0; - fclose(task_file); - - add_new_list_item(task); - } - } - } - closedir(dir); -} - -/* function to kill the current task */ -static void send_signal_to_task(gchar *signal) -{ - if(current_task_id != "") - { - gchar command[64] = "kill -"; - g_strlcat(command,signal, 64); - g_strlcat(command," ", 64); - g_strlcat(command,current_task_id, 64); - - if(system(command) != 0) - xfce_err("Couldn't %s the task with ID %s", signal, current_task_id); - } -} - -/* handles all the button events */ -static void handle_events(GtkWidget *widget, gchar *widget_action) -{ - if(strcmp(widget_action, "task_stop") == 0) - { - send_signal_to_task("STOP"); - gtk_list_store_clear(GTK_LIST_STORE(model)); - get_task_list(); - } - if(strcmp(widget_action, "task_cont") == 0) - { - send_signal_to_task("CONT"); - gtk_list_store_clear(GTK_LIST_STORE(model)); - get_task_list(); - } - if(strcmp(widget_action, "task_term") == 0) - { - if(xfce_confirm("Really TERM the task?", GTK_STOCK_OK, NULL)) - { - send_signal_to_task("TERM"); - gtk_list_store_clear(GTK_LIST_STORE(model)); - get_task_list(); - } - } - if(strcmp(widget_action, "task_kill") == 0) - { - if(xfce_confirm("Really KILL the task?", GTK_STOCK_OK, NULL)) - { - send_signal_to_task("KILL"); - gtk_list_store_clear(GTK_LIST_STORE(model)); - get_task_list(); - } - } - if(strcmp(widget_action, "button_reload") == 0) - { - gtk_list_store_clear(GTK_LIST_STORE(model)); - get_task_list(); - } - if(strcmp(widget_action, "button_quit") == 0) - { - gtk_main_quit(); - } -} - -/* handles all the mouse events */ -static gboolean handle_mouse_events(GtkWidget *widget, GdkEventButton *event) -{ - printf("hallo"); - if(event->button == 3) - { - GdkEventButton *mouseevent = (GdkEventButton *)event; - gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL, mouseevent->button, mouseevent->time); - return FALSE; - } - - return FALSE; -} - -/* create the GUI */ -static void create_gui(void) -{ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "xfce4-taskmanager"); - g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK (gtk_main_quit), NULL); - gtk_container_set_border_width (GTK_CONTAINER (window), 10); - gtk_widget_set_size_request (GTK_WIDGET (window), 450, 400); - - GtkWidget *button; - GtkWidget *box1; - - box1 = gtk_vbox_new(FALSE, 10); - - /* list rightclickmenu */ - GtkWidget *list_popupmenu; - GtkWidget *popupmenuitem; - - list_popupmenu = gtk_menu_new(); - - popupmenuitem = gtk_menu_item_new_with_label("Stop"); - gtk_menu_shell_append(GTK_MENU_SHELL(list_popupmenu), popupmenuitem); - g_signal_connect(G_OBJECT(popupmenuitem), "activate", G_CALLBACK(handle_events), "task_stop"); - gtk_widget_show(popupmenuitem); - - popupmenuitem = gtk_menu_item_new_with_label("Continue"); - gtk_menu_shell_append(GTK_MENU_SHELL(list_popupmenu), popupmenuitem); - g_signal_connect(G_OBJECT(popupmenuitem), "activate", G_CALLBACK(handle_events), "task_cont"); - gtk_widget_show(popupmenuitem); - - popupmenuitem = gtk_menu_item_new_with_label("Term"); - gtk_menu_shell_append(GTK_MENU_SHELL(list_popupmenu), popupmenuitem); - g_signal_connect(G_OBJECT(popupmenuitem), "activate", G_CALLBACK(handle_events), "task_term"); - gtk_widget_show(popupmenuitem); - - popupmenuitem = gtk_menu_item_new_with_label("Kill"); - gtk_menu_shell_append(GTK_MENU_SHELL(list_popupmenu), popupmenuitem); - g_signal_connect(G_OBJECT(popupmenuitem), "activate", G_CALLBACK(handle_events), "task_kill"); - gtk_widget_show(popupmenuitem); - - /* tasklistgui */ - GtkWidget *scrolled_window; - GtkTreeSelection *select; - GtkWidget *tree_view; - GtkTreeIter iter; - GtkCellRenderer *cell; - GtkTreeViewColumn *column; - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_ETCHED_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - tree_view = gtk_tree_view_new(); - gtk_container_add (GTK_CONTAINER(scrolled_window), tree_view); - gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (model)); - - g_signal_connect_swapped (G_OBJECT(tree_view), "button-press-event", G_CALLBACK(handle_mouse_events), G_OBJECT(list_popupmenu)); - - gtk_widget_show (tree_view); - - cell = gtk_cell_renderer_text_new(); - - column = gtk_tree_view_column_new_with_attributes("User", cell, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), GTK_TREE_VIEW_COLUMN (column)); - - column = gtk_tree_view_column_new_with_attributes("PID", cell, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), GTK_TREE_VIEW_COLUMN (column)); - - column = gtk_tree_view_column_new_with_attributes("PPID", cell, "text", 2, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), GTK_TREE_VIEW_COLUMN (column)); - - column = gtk_tree_view_column_new_with_attributes("Command", cell, "text", 3, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), GTK_TREE_VIEW_COLUMN (column)); - - select = gtk_tree_view_get_selection(GTK_TREE_VIEW (tree_view)); - gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE); - g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(select_task), NULL); - - /* load the tasklist */ - get_task_list(); - - gtk_box_pack_start(GTK_BOX(box1), scrolled_window, TRUE, TRUE, 0); - gtk_widget_show(scrolled_window); - - /* QUIT-Button */ - button = gtk_button_new_from_stock(GTK_STOCK_QUIT); - g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK(handle_events), "button_quit"); - gtk_box_pack_start(GTK_BOX(box1), button, FALSE, TRUE, 0); - gtk_widget_show(button); - - gtk_container_add (GTK_CONTAINER(window), box1); - gtk_widget_show(box1); - - gtk_widget_show(window); -} - -/* handler for SIGALRM to refresh the list */ -void refresh_handler(void) -{ - gtk_list_store_clear(GTK_LIST_STORE(model)); - get_task_list(); - alarm(REFRESH_INTERVAL); -} - -/* main */ -int main(int argc, char *argv[]) -{ - gtk_init(&argc, &argv); - - create_gui(); - - signal(SIGALRM, refresh_handler); - alarm(REFRESH_INTERVAL); - - gtk_main(); - - return 0; -}