From 1989dab8975ece65dfd9e891fbdeecf87644e62b Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 11 Jul 2009 23:31:20 +0000 Subject: [PATCH] Initial release --- Makefile | 39 ++++++++ project.conf | 5 + src/.cvsignore | 2 + src/Makefile | 44 ++++++++ src/main.c | 50 +++++++++ src/panel.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++ src/panel.h | 31 ++++++ src/project.conf | 16 +++ 8 files changed, 443 insertions(+) create mode 100644 Makefile create mode 100644 project.conf create mode 100644 src/.cvsignore create mode 100644 src/Makefile create mode 100644 src/main.c create mode 100644 src/panel.c create mode 100644 src/panel.h create mode 100644 src/project.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a28d11d --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +PACKAGE = Panel +VERSION = 0.0.0 +SUBDIRS = src +RM = rm -f +LN = ln -sf +TAR = tar -czvf + + +all: subdirs + +subdirs: + @for i in $(SUBDIRS); do (cd $$i && $(MAKE)) || exit; done + +clean: + @for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done + +distclean: + @for i in $(SUBDIRS); do (cd $$i && $(MAKE) distclean) || exit; done + +dist: + $(RM) -r $(PACKAGE)-$(VERSION) + $(LN) . $(PACKAGE)-$(VERSION) + @$(TAR) $(PACKAGE)-$(VERSION).tar.gz \ + $(PACKAGE)-$(VERSION)/src/panel.c \ + $(PACKAGE)-$(VERSION)/src/main.c \ + $(PACKAGE)-$(VERSION)/src/Makefile \ + $(PACKAGE)-$(VERSION)/src/panel.h \ + $(PACKAGE)-$(VERSION)/src/project.conf \ + $(PACKAGE)-$(VERSION)/Makefile \ + $(PACKAGE)-$(VERSION)/project.conf + $(RM) $(PACKAGE)-$(VERSION) + +install: all + @for i in $(SUBDIRS); do (cd $$i && $(MAKE) install) || exit; done + +uninstall: + @for i in $(SUBDIRS); do (cd $$i && $(MAKE) uninstall) || exit; done + +.PHONY: all subdirs clean distclean dist install uninstall diff --git a/project.conf b/project.conf new file mode 100644 index 0000000..f0acc6c --- /dev/null +++ b/project.conf @@ -0,0 +1,5 @@ +package=Panel +version=0.0.0 + +subdirs=src +dist=Makefile diff --git a/src/.cvsignore b/src/.cvsignore new file mode 100644 index 0000000..1143996 --- /dev/null +++ b/src/.cvsignore @@ -0,0 +1,2 @@ +.cvsignore +panel diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..d771038 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,44 @@ +TARGETS = panel +PREFIX = /usr/local +DESTDIR = +BINDIR = $(PREFIX)/bin +CC = cc +CPPFLAGSF= +CPPFLAGS= +CFLAGSF = -W `pkg-config gtk+-2.0 --cflags` +CFLAGS = -Wall -g -O2 +LDFLAGSF= `pkg-config gtk+-2.0 --libs` +RM = rm -f +MKDIR = mkdir -p +INSTALL = install + + +all: $(TARGETS) + +panel_OBJS = panel.o main.o +panel_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +panel_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +panel: $(panel_OBJS) + $(CC) -o panel $(panel_OBJS) $(panel_LDFLAGS) + +panel.o: panel.c panel.h + $(CC) $(panel_CFLAGS) -c panel.c + +main.o: main.c panel.h + $(CC) $(panel_CFLAGS) -c main.c + +clean: + $(RM) $(panel_OBJS) + +distclean: clean + $(RM) $(TARGETS) + +install: all + $(MKDIR) $(DESTDIR)$(BINDIR) + $(INSTALL) -m 0755 panel $(DESTDIR)$(BINDIR)/panel + +uninstall: + $(RM) $(DESTDIR)$(BINDIR)/panel + +.PHONY: all clean distclean install uninstall diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..9a7add8 --- /dev/null +++ b/src/main.c @@ -0,0 +1,50 @@ +/* $Id$ */ +/* Copyright (c) 2009 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Panel */ +/* 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, version 3 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include "panel.h" + + +/* usage */ +static int _usage(void) +{ + fputs("Usage: panel\n", stderr); + return 1; +} + + +/* main */ +int main(int argc, char * argv[]) +{ + Panel * panel; + int o; + + gtk_init(&argc, &argv); + while((o = getopt(argc, argv, "")) != -1) + switch(o) + { + default: + return _usage(); + } + if(optind != argc) + return _usage(); + panel = panel_new(); + gtk_main(); + panel_delete(panel); + return 0; +} diff --git a/src/panel.c b/src/panel.c new file mode 100644 index 0000000..b5bae3a --- /dev/null +++ b/src/panel.c @@ -0,0 +1,256 @@ +/* $Id$ */ +/* Copyright (c) 2009 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Panel */ +/* 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, version 3 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include +#include +#include "panel.h" + + +/* Panel */ +/* private */ +/* types */ +struct _Panel +{ + GdkWindow * root; + GtkWidget * window; + GtkWidget * clock; + + gint width; /* width of the root window */ + gint height; /* height of the root window */ +}; + + +/* prototypes */ +static int _panel_error(Panel * panel, char const * message, int ret); + + +/* public */ +/* panel_new */ +static GtkWidget * _new_button(char const * stock); +static gboolean _on_button_press(GtkWidget * widget, GdkEventButton * event, + gpointer data); +static void _on_lock(GtkWidget * widget, gpointer * data); +static void _on_menu(GtkWidget * widget, gpointer * data); +static void _on_menu_position(GtkMenu * menu, gint * x, gint * y, + gboolean * push_in, gpointer data); +static void _on_run(GtkWidget * widget, gpointer data); +static gboolean _on_timeout_clock(gpointer data); + +Panel * panel_new(void) +{ + Panel * panel; + GtkWidget * event; + GtkWidget * hbox; + GtkWidget * widget; + gint x; + gint y; + gint depth; + + if((panel = malloc(sizeof(*panel))) == NULL) + return NULL; + /* root window */ + panel->root = gdk_screen_get_root_window( + gdk_display_get_default_screen( + gdk_display_get_default())); + gdk_window_get_geometry(panel->root, &x, &y, &panel->width, + &panel->height, &depth); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() x=%d y=%d width=%d height=%d depth=%d\n", + __func__, x, y, panel->width, panel->height, depth); +#endif + /* panel */ + panel->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_move(GTK_WINDOW(panel->window), 0, panel->height - 56); + gtk_window_set_default_size(GTK_WINDOW(panel->window), panel->width, + 56); + gtk_window_set_type_hint(GTK_WINDOW(panel->window), + GDK_WINDOW_TYPE_HINT_DOCK); + event = gtk_event_box_new(); + g_signal_connect(G_OBJECT(event), "button-press-event", G_CALLBACK( + _on_button_press), panel); + hbox = gtk_hbox_new(FALSE, 4); + /* main menu */ + widget = _new_button("gnome-main-menu"); + g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(_on_menu), + panel); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + /* quick launch */ + widget = _new_button("gnome-lockscreen"); + g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(_on_lock), + panel); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), _new_button("gnome-logout"), FALSE, + TRUE, 0); + /* clock */ + panel->clock = gtk_label_new(" \n "); + gtk_label_set_justify(GTK_LABEL(panel->clock), GTK_JUSTIFY_CENTER); + g_timeout_add(1000, _on_timeout_clock, panel); + _on_timeout_clock(panel); + gtk_box_pack_end(GTK_BOX(hbox), panel->clock, FALSE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(event), hbox); + gtk_container_add(GTK_CONTAINER(panel->window), event); + gtk_container_set_border_width(GTK_CONTAINER(panel->window), 4); + gtk_widget_show_all(panel->window); + return panel; +} + +static GtkWidget * _new_button(char const * stock) +{ + GtkWidget * button; + GtkWidget * image; + + button = gtk_button_new(); + image = gtk_image_new_from_icon_name(stock, + GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_button_set_image(GTK_BUTTON(button), image); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + return button; +} + +static gboolean _on_button_press(GtkWidget * widget, GdkEventButton * event, + gpointer data) +{ + GtkWidget * menu; + GtkWidget * menuitem; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + if(event->type != GDK_BUTTON_PRESS || event->button != 3) + return FALSE; +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() right-click\n", __func__); +#endif + menu = gtk_menu_new(); + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_PROPERTIES, + NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show_all(menu); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, data, event->button, + event->time); + return FALSE; +} + +static void _on_lock(GtkWidget * widget, gpointer * data) +{ + /* XXX could be more efficient and integrated */ + system("xscreensaver-command -lock"); +} + +static void _on_menu(GtkWidget * widget, gpointer * data) +{ + GtkWidget * menu; + GtkWidget * menuitem; + GtkWidget * image; + + menu = gtk_menu_new(); + menuitem = gtk_image_menu_item_new_with_label("Applications"); + image = gtk_image_new_from_icon_name("gnome-applications", GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_image_menu_item_new_with_label("Run..."); + image = gtk_image_new_from_stock(GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(_on_run), + data); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, + NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_image_menu_item_new_with_label("Lock screen"); + image = gtk_image_new_from_icon_name("gnome-lockscreen", + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); + g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(_on_lock), + data); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_image_menu_item_new_with_label("Logout..."); + image = gtk_image_new_from_icon_name("gnome-logout", + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + gtk_widget_show_all(menu); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, _on_menu_position, data, 0, + gtk_get_current_event_time()); +} + +static void _on_menu_position(GtkMenu * menu, gint * x, gint * y, + gboolean * push_in, gpointer data) +{ + Panel * panel = data; + GtkRequisition req; + + gtk_widget_size_request(GTK_WIDGET(menu), &req); +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() width=%d, height=%d\n", __func__, + req.width, req.height); +#endif + if(req.height <= 0) + return; + *x = 4; + *y = panel->height - 52 - req.height; + *push_in = TRUE; +} + +static void _on_run(GtkWidget * widget, gpointer data) +{ + /* XXX could be more efficient and integrated */ + system("run"); +} + +static gboolean _on_timeout_clock(gpointer data) +{ + Panel * panel = data; + struct timeval tv; + time_t t; + struct tm tm; + char buf[32]; + + if(gettimeofday(&tv, NULL) != 0) + return _panel_error(panel, "gettimeofday", TRUE); + t = tv.tv_sec; + localtime_r(&t, &tm); + strftime(buf, sizeof(buf), "%T\n%d/%m/%Y", &tm); + gtk_label_set_text(GTK_LABEL(panel->clock), buf); + return TRUE; +} + + +/* panel_delete */ +void panel_delete(Panel * panel) +{ + free(panel); +} + + +/* private */ +/* functions */ +static int _panel_error(Panel * panel, char const * message, int ret) +{ + fputs("panel: ", stderr); + perror(message); + return ret; +} diff --git a/src/panel.h b/src/panel.h new file mode 100644 index 0000000..fe4a9d1 --- /dev/null +++ b/src/panel.h @@ -0,0 +1,31 @@ +/* $Id$ */ +/* Copyright (c) 2009 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Panel */ +/* 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, version 3 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#ifndef PANEL_PANEL_H +# define PANEL_PANEL_H + + +/* Panel */ +/* types */ +typedef struct _Panel Panel; + + +/* functions */ +Panel * panel_new(void); +void panel_delete(Panel * panel); + +# endif /* !PANEL_PANEL_H */ diff --git a/src/project.conf b/src/project.conf new file mode 100644 index 0000000..85bfdd1 --- /dev/null +++ b/src/project.conf @@ -0,0 +1,16 @@ +targets=panel +cflags_force=-W `pkg-config gtk+-2.0 --cflags` +cflags=-Wall -g -O2 +ldflags_force=`pkg-config gtk+-2.0 --libs` +dist=Makefile,panel.h + +[panel] +type=binary +sources=panel.c,main.c +install=$(BINDIR) + +[main.c] +depends=panel.h + +[panel.c] +depends=panel.h