Added a pager module
This commit is contained in:
parent
6df78173ed
commit
3e19d90925
1
Makefile
1
Makefile
|
@ -36,6 +36,7 @@ dist:
|
|||
$(PACKAGE)-$(VERSION)/src/applets/logout.c \
|
||||
$(PACKAGE)-$(VERSION)/src/applets/main.c \
|
||||
$(PACKAGE)-$(VERSION)/src/applets/memory.c \
|
||||
$(PACKAGE)-$(VERSION)/src/applets/pager.c \
|
||||
$(PACKAGE)-$(VERSION)/src/applets/tasks.c \
|
||||
$(PACKAGE)-$(VERSION)/src/applets/Makefile \
|
||||
$(PACKAGE)-$(VERSION)/src/applets/project.conf \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TARGETS = clock.so cpu.so desktop.so lock.so logout.so main.so memory.so tasks.so
|
||||
TARGETS = clock.so cpu.so desktop.so lock.so logout.so main.so memory.so pager.so tasks.so
|
||||
PREFIX = /usr/local
|
||||
DESTDIR =
|
||||
LIBDIR = $(PREFIX)/lib
|
||||
|
@ -67,6 +67,13 @@ memory_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
|||
memory.so: $(memory_OBJS)
|
||||
$(LD) -o memory.so $(memory_OBJS)
|
||||
|
||||
pager_OBJS = pager.o
|
||||
pager_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||
pager_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
||||
|
||||
pager.so: $(pager_OBJS)
|
||||
$(LD) -o pager.so $(pager_OBJS)
|
||||
|
||||
tasks_OBJS = tasks.o
|
||||
tasks_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||
tasks_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
||||
|
@ -95,11 +102,14 @@ main.o: main.c
|
|||
memory.o: memory.c
|
||||
$(CC) $(memory_CFLAGS) -c memory.c
|
||||
|
||||
pager.o: pager.c
|
||||
$(CC) $(pager_CFLAGS) -c pager.c
|
||||
|
||||
tasks.o: tasks.c
|
||||
$(CC) $(tasks_CFLAGS) -c tasks.c
|
||||
|
||||
clean:
|
||||
$(RM) $(clock_OBJS) $(cpu_OBJS) $(desktop_OBJS) $(lock_OBJS) $(logout_OBJS) $(main_OBJS) $(memory_OBJS) $(tasks_OBJS)
|
||||
$(RM) $(clock_OBJS) $(cpu_OBJS) $(desktop_OBJS) $(lock_OBJS) $(logout_OBJS) $(main_OBJS) $(memory_OBJS) $(pager_OBJS) $(tasks_OBJS)
|
||||
|
||||
distclean: clean
|
||||
$(RM) $(TARGETS)
|
||||
|
@ -120,6 +130,8 @@ install: all
|
|||
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
|
||||
$(INSTALL) -m 0644 memory.so $(DESTDIR)$(LIBDIR)/Panel/applets/memory.so
|
||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
|
||||
$(INSTALL) -m 0644 pager.so $(DESTDIR)$(LIBDIR)/Panel/applets/pager.so
|
||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
|
||||
$(INSTALL) -m 0644 tasks.so $(DESTDIR)$(LIBDIR)/Panel/applets/tasks.so
|
||||
|
||||
uninstall:
|
||||
|
@ -130,6 +142,7 @@ uninstall:
|
|||
$(RM) $(DESTDIR)$(LIBDIR)/Panel/applets/logout.so
|
||||
$(RM) $(DESTDIR)$(LIBDIR)/Panel/applets/main.so
|
||||
$(RM) $(DESTDIR)$(LIBDIR)/Panel/applets/memory.so
|
||||
$(RM) $(DESTDIR)$(LIBDIR)/Panel/applets/pager.so
|
||||
$(RM) $(DESTDIR)$(LIBDIR)/Panel/applets/tasks.so
|
||||
|
||||
.PHONY: all clean distclean install uninstall
|
||||
|
|
269
src/applets/pager.c
Normal file
269
src/applets/pager.c
Normal file
|
@ -0,0 +1,269 @@
|
|||
/* $Id$ */
|
||||
/* Copyright (c) 2009 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS Pager 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "panel.h"
|
||||
|
||||
|
||||
/* Pager */
|
||||
/* private */
|
||||
/* types */
|
||||
typedef enum _PagerAtom
|
||||
{
|
||||
PAGER_ATOM_NET_CURRENT_DESKTOP = 0,
|
||||
PAGER_ATOM_NET_NUMBER_OF_DESKTOPS
|
||||
} PagerAtom;
|
||||
#define PAGER_ATOM_LAST PAGER_ATOM_NET_NUMBER_OF_DESKTOPS
|
||||
#define PAGER_ATOM_COUNT (PAGER_ATOM_LAST + 1)
|
||||
|
||||
typedef struct _Pager
|
||||
{
|
||||
GtkWidget * hbox;
|
||||
|
||||
GtkWidget ** widgets;
|
||||
size_t widgets_cnt;
|
||||
|
||||
Atom atom[PAGER_ATOM_COUNT];
|
||||
GdkDisplay * display;
|
||||
GdkScreen * screen;
|
||||
GdkWindow * root;
|
||||
} Pager;
|
||||
|
||||
|
||||
/* constants */
|
||||
static const char * _pager_atom[PAGER_ATOM_COUNT] =
|
||||
{
|
||||
"_NET_CURRENT_DESKTOP",
|
||||
"_NET_NUMBER_OF_DESKTOPS"
|
||||
};
|
||||
|
||||
|
||||
/* prototypes */
|
||||
static GtkWidget * _pager_init(PanelApplet * applet);
|
||||
static void _pager_destroy(PanelApplet * applet);
|
||||
|
||||
/* accessors */
|
||||
static int _pager_get_window_property(Pager * pager, Window window,
|
||||
PagerAtom property, Atom atom, unsigned long * cnt,
|
||||
unsigned char ** ret);
|
||||
|
||||
/* useful */
|
||||
static void _pager_do(Pager * pager);
|
||||
|
||||
/* callbacks */
|
||||
static void _on_clicked(GtkWidget * widget, gpointer data);
|
||||
static GdkFilterReturn _on_filter(GdkXEvent * xevent, GdkEvent * event,
|
||||
gpointer data);
|
||||
static void _on_screen_changed(GtkWidget * widget, GdkScreen * previous,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/* public */
|
||||
/* variables */
|
||||
PanelApplet applet =
|
||||
{
|
||||
NULL,
|
||||
_pager_init,
|
||||
_pager_destroy,
|
||||
PANEL_APPLET_POSITION_START,
|
||||
FALSE,
|
||||
TRUE,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* private */
|
||||
/* functions */
|
||||
/* pager_init */
|
||||
static GtkWidget * _pager_init(PanelApplet * applet)
|
||||
{
|
||||
Pager * pager;
|
||||
|
||||
if((pager = malloc(sizeof(*pager))) == NULL)
|
||||
return NULL;
|
||||
applet->priv = pager;
|
||||
pager->hbox = gtk_hbox_new(TRUE, 0);
|
||||
g_signal_connect(G_OBJECT(pager->hbox), "screen-changed", G_CALLBACK(
|
||||
_on_screen_changed), pager);
|
||||
pager->widgets = NULL;
|
||||
pager->widgets_cnt = 0;
|
||||
pager->screen = NULL;
|
||||
pager->display = NULL;
|
||||
pager->root = NULL;
|
||||
return pager->hbox;
|
||||
}
|
||||
|
||||
|
||||
/* pager_destroy */
|
||||
static void _pager_destroy(PanelApplet * applet)
|
||||
{
|
||||
Pager * pager = applet->priv;
|
||||
|
||||
free(pager);
|
||||
}
|
||||
|
||||
|
||||
/* accessors */
|
||||
/* pager_get_window_property */
|
||||
static int _pager_get_window_property(Pager * pager, Window window,
|
||||
PagerAtom property, Atom atom, unsigned long * cnt,
|
||||
unsigned char ** ret)
|
||||
{
|
||||
int res;
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long bytes;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(pager, window, %s, %lu)\n", __func__,
|
||||
_pager_atom[property], atom);
|
||||
#endif
|
||||
res = XGetWindowProperty(GDK_DISPLAY_XDISPLAY(pager->display), window,
|
||||
pager->atom[property], 0, G_MAXLONG, False, atom,
|
||||
&type, &format, cnt, &bytes, ret);
|
||||
if(res != Success)
|
||||
return 1;
|
||||
if(type != atom)
|
||||
{
|
||||
if(*ret != NULL)
|
||||
XFree(*ret);
|
||||
*ret = NULL;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* useful */
|
||||
static void _pager_do(Pager * pager)
|
||||
{
|
||||
unsigned long cnt = 0;
|
||||
unsigned long l;
|
||||
unsigned long * p;
|
||||
unsigned long i;
|
||||
GtkWidget ** q;
|
||||
char buf[16];
|
||||
|
||||
if(_pager_get_window_property(pager, GDK_WINDOW_XWINDOW(pager->root),
|
||||
PAGER_ATOM_NET_NUMBER_OF_DESKTOPS,
|
||||
XA_CARDINAL, &cnt, (void*)&p) != 0)
|
||||
return;
|
||||
l = *p;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() => %ld\n", __func__, l);
|
||||
#endif
|
||||
XFree(p);
|
||||
for(i = 0; i < pager->widgets_cnt; i++)
|
||||
if(pager->widgets[i] != NULL)
|
||||
{
|
||||
gtk_widget_destroy(pager->widgets[i]);
|
||||
pager->widgets[i] = NULL;
|
||||
}
|
||||
if((q = realloc(pager->widgets, l * sizeof(*q))) == NULL)
|
||||
return;
|
||||
pager->widgets = q;
|
||||
pager->widgets_cnt = l;
|
||||
for(i = 0; i < l; i++)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "Desk %ld\n", i + 1);
|
||||
pager->widgets[i] = gtk_button_new_with_label(buf);
|
||||
g_signal_connect(G_OBJECT(pager->widgets[i]), "clicked",
|
||||
G_CALLBACK(_on_clicked), pager);
|
||||
gtk_box_pack_start(GTK_BOX(pager->hbox), pager->widgets[i],
|
||||
FALSE, TRUE, 0);
|
||||
}
|
||||
gtk_widget_show_all(pager->hbox);
|
||||
}
|
||||
|
||||
|
||||
/* callbacks */
|
||||
/* on_clicked */
|
||||
static void _on_clicked(GtkWidget * widget, gpointer data)
|
||||
{
|
||||
Pager * pager = data;
|
||||
size_t i;
|
||||
GdkScreen * screen;
|
||||
GdkDisplay * display;
|
||||
GdkWindow * root;
|
||||
XEvent xev;
|
||||
|
||||
for(i = 0; i < pager->widgets_cnt; i++)
|
||||
if(pager->widgets[i] == widget)
|
||||
break;
|
||||
if(i == pager->widgets_cnt)
|
||||
return;
|
||||
screen = gtk_widget_get_screen(widget);
|
||||
display = gtk_widget_get_display(widget);
|
||||
root = gdk_screen_get_root_window(screen);
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.window = GDK_WINDOW_XWINDOW(root);
|
||||
xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display(
|
||||
display, "_NET_CURRENT_DESKTOP");
|
||||
xev.xclient.format = 32;
|
||||
memset(&xev.xclient.data, sizeof(xev.xclient.data), 0);
|
||||
xev.xclient.data.l[0] = i;
|
||||
XSendEvent(GDK_DISPLAY_XDISPLAY(display), GDK_WINDOW_XWINDOW(root),
|
||||
False,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&xev);
|
||||
}
|
||||
|
||||
|
||||
/* on_filter */
|
||||
static GdkFilterReturn _on_filter(GdkXEvent * xevent, GdkEvent * event,
|
||||
gpointer data)
|
||||
{
|
||||
Pager * pager = data;
|
||||
XEvent * xev = xevent;
|
||||
|
||||
if(xev->type != PropertyNotify)
|
||||
return GDK_FILTER_CONTINUE;
|
||||
if(xev->xproperty.atom != pager->atom[
|
||||
PAGER_ATOM_NET_NUMBER_OF_DESKTOPS])
|
||||
return GDK_FILTER_CONTINUE;
|
||||
_pager_do(pager);
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
/* on_screen_changed */
|
||||
static void _on_screen_changed(GtkWidget * widget, GdkScreen * previous,
|
||||
gpointer data)
|
||||
{
|
||||
Pager * pager = data;
|
||||
GdkEventMask events;
|
||||
size_t i;
|
||||
|
||||
if(pager->screen == NULL)
|
||||
{
|
||||
pager->screen = gtk_widget_get_screen(widget);
|
||||
pager->display = gdk_screen_get_display(pager->screen);
|
||||
pager->root = gdk_screen_get_root_window(pager->screen);
|
||||
events = gdk_window_get_events(pager->root);
|
||||
gdk_window_set_events(pager->root, events
|
||||
| GDK_PROPERTY_CHANGE_MASK);
|
||||
gdk_window_add_filter(pager->root, _on_filter, pager);
|
||||
/* atoms */
|
||||
for(i = 0; i < PAGER_ATOM_COUNT; i++)
|
||||
pager->atom[i] = gdk_x11_get_xatom_by_name_for_display(
|
||||
pager->display, _pager_atom[i]);
|
||||
}
|
||||
_pager_do(pager);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
targets=clock,cpu,desktop,lock,logout,main,memory,tasks
|
||||
targets=clock,cpu,desktop,lock,logout,main,memory,pager,tasks
|
||||
cppflags_force=-I ../../include
|
||||
cflags_force=`pkg-config --cflags gtk+-2.0` -fPIC
|
||||
cflags=-Wall -g -O2 -pedantic
|
||||
|
@ -41,6 +41,11 @@ type=plugin
|
|||
sources=memory.c
|
||||
install=$(LIBDIR)/Panel/applets
|
||||
|
||||
[pager]
|
||||
type=plugin
|
||||
sources=pager.c
|
||||
install=$(LIBDIR)/Panel/applets
|
||||
|
||||
[tasks]
|
||||
type=plugin
|
||||
sources=tasks.c
|
||||
|
|
|
@ -120,7 +120,7 @@ static gboolean _on_idle(gpointer data)
|
|||
/* FIXME load all plugins, a configuration file or ask the user */
|
||||
#ifndef EMBEDDED
|
||||
const char * plugins[] = { "cpu", "clock", "desktop", "lock", "logout",
|
||||
"main", "memory", "tasks", NULL };
|
||||
"main", "memory", "pager", "tasks", NULL };
|
||||
#else
|
||||
const char * plugins[] = { "clock", "desktop", "main", "tasks", NULL };
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user