日本語 English
Linux 上で GNOME を使い始めて、一番の不満だったのが、アナログ時計のスクリーンセーバがないことだった。これじゃ、夜中に目が覚めても時間がわからない。KDE にはあったのに……。ググってみても、GLText を設定してデジタル時計にするくらいしか手がないらしい。そこで、作ってみることにした。
ところが今度は、GNOME スクリーンセーバの作り方が見つからない(少なくとも日本語では)。Microsoft Windows のスクリーンセーバのように自前のウィンドウに描画するのではだめで、GNOME が用意したスクリーンセーバウィンドウに描画しなければならないらしい。しょうがないので、gnome-screensaver のソースを見てみることにした。
でも、私はまったくの GTK+ 初心者。というより、C で GUI プログラミングをしたこともない。ほとんど、「GTK+入門(現在はオフリンク)」(の中の GDK のページ)のみを先達として、コードを削っていった。だから、以下のプログラムには、どこか間違いがあるに違いない。GNOME の偉い人、宜しくご指導下さい。
閑話休題
GNOME スクリーンセーバとして最低限動作するスケルトンを作成する。
まず、gnome-screensaver のソースを解凍し、savers/ の中の gs-theme-window.c と gs-theme-window.h を取ってくる。
この 2つのファイルのライセンスは LGPL なので、作成したアプリケーションを公開する際には留意して欲しい。
そして、空の config.h を作る(touch config.h)。
gs-theme-window.c が config.h を include
しているので存在しないとコンパイルが通らないのだが、実は gs-theme-window.c は config.h に一切依存していない(本稿執筆時点)。
次に、スクリーンセーバの本体を作る。
gs-base.c |
---|
#include <sysexits.h> #include "gs-theme-window.h" GOptionEntry options[] = { {NULL} }; static void configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data) { } static void expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) { } int main (int argc, char **argv) { GtkWidget *window; GtkWidget *drawing_area; GError *error = NULL; gtk_set_locale (); gtk_init_with_args (&argc, &argv, "", options, "gnome-screensaver", &error); if (error != NULL) { g_printerr ("%s. See --help for usage information.\n", error->message); g_error_free (error); return EX_SOFTWARE; } window = gs_theme_window_new (); g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (gtk_main_quit), NULL); drawing_area = gtk_drawing_area_new (); gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event", GTK_SIGNAL_FUNC (configure_event), NULL); gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event", GTK_SIGNAL_FUNC (expose_event), NULL); gtk_widget_show (drawing_area); gtk_container_add (GTK_CONTAINER (window), drawing_area); gtk_widget_show (window); gtk_main (); return EX_OK; } |
見てわかる通り、window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
の替わりに window = gs_theme_window_new ();
を使っている以外は、ごく普通の GTK+ アプリケーションだ。
次に、skeleton.desktop を作成する。
というより、pkg-config gtk+-2.0 --variable=themesdir gnome-screensaverで取得できるディレクトリ(多分、/usr/share/applications/screensavers)にあるファイルをコピーして編集する。
ASCII 文字以外を使うなら、文字コードは UTF-8 で。
skeleton.desktop |
---|
[Desktop Entry] Encoding=UTF-8 Name=Skeleton Name[ja]=スケルトン Comment=Skeleton screen saver Comment[ja]=スケルトンスクリーンセーバ Exec=skeleton TryExec=skeleton StartupNotify=false Terminal=false Type=Application Categories=GNOME;Screensaver; OnlyShowIn=GNOME; |
最後に、Makefile を作る。
Makefile |
---|
CC = gcc PKG_CONFIG = pkg-config GTK_METADATA = gtk+-2.0 INSTALL = install GS_LIBEXEC_DIR = `${PKG_CONFIG} --variable=privlibexecdir gnome-screensaver` GS_DESKTOP_DIR = `${PKG_CONFIG} --variable=themesdir gnome-screensaver` SOURCES = gs-theme-window.c gs-base.c TARGET = skeleton DESKTOP = ${TARGET}.desktop OBJECTS = $(SOURCES:.c=.o) CFLAGS = `${PKG_CONFIG} ${GTK_METADATA} --cflags` -Wall LIBS = `${PKG_CONFIG} ${GTK_METADATA} --libs` $(TARGET): $(OBJECTS) <--TAB-->$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS) .c.o: <--TAB-->$(CC) $(CFLAGS) -c $< -o $@ clean: <--TAB-->rm -f $(OBJECTS) $(TARGET) core* *.o *~ install: <--TAB-->${INSTALL} -s ${TARGET} ${GS_LIBEXEC_DIR} <--TAB-->${INSTALL} -m 644 ${DESKTOP} ${GS_DESKTOP_DIR} |
make
su
make install
で、GNOME スクリーンセーバとして設定できる。
あとは、configure_event
と expose_event
でお絵描きをして、タイマーでアニメーションにすれば、カスタムスクリーンセーバができあがる(はず)。
Happy hacking!