Glib の g_io_add_watch を使う – biochem_fan’s note
判り易いサンプルコードをありがとう。
GIOChannel はファイル・ディスクリプタであれば何でも監視できるのか。
だいぶ解ってきた、かも。
色々試してみると。
GIOChannel *channel; channel = g_io_channel_unix_new(0);
だけで stdin の GIOChannel が得られるようだ。
ファイル・ディスクリプタってつまり固有の整数と思えばいい?
関係無いけど GApplication で新たに解ったことが。
g_application_hold(app); でインクリメントすれば参照カウントが増える。
これなら GtkWindow を作らずともメインループが回せる。
実は GApplication を使うコレをやろうと思っていたんですが。
HowDoI/GNotification – GNOME Wiki!
何をどうやっても動かない、書いているとおりにコピペしてもだ。
手段が悪いのかバグなのかは解らない、後回し!
これを組み合わせて通知領域にメッセージを投げるコードでも。
端末に撃ち込んだ文字列を即座に通知するサンプル。
今回は notify-send コマンドに投げて茶でも濁しておきます。
#include <glib.h>
#include <gio/gio.h>
/*
gcc ioc.c `pkg-config --cflags --libs gio-2.0`
*/
static gboolean
io_func_cb(GIOChannel *source, GIOCondition condition, gpointer app) {
GError *error = NULL;
GNotification *notification;
gchar *text;
gchar *s;
g_io_channel_read_line(source, &text, NULL, NULL, &error);
if (g_strcmp0(text, "exit\n") == 0) {
/* Decriment */
g_application_release(app);
g_free(text);
return FALSE;
}
s = g_strdup_printf("notify-send -i gtk-ok %s", text);
g_spawn_command_line_async(s, NULL);
g_free(s);
g_free(text);
return TRUE;
}
static void
activate_cb (GApplication *app, gpointer user_data) {
GIOChannel *channel;
/* 0 == stdin */
channel = g_io_channel_unix_new(0);
g_io_add_watch (channel, G_IO_IN, io_func_cb, app);
g_io_channel_unref(channel);
/* Inclement */
g_application_hold(app);
}
int
main (int argc, char* argv[]) {
GApplication *app;
/*
g_type_init(); // < 2.36
g_thread_init(argc, argv); // < 2.32
*/
app = g_application_new("org.suzuki.hayabusa", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate_cb), NULL);
g_printf("Type 'exit' to exit\n");
/* MainLoop run */
g_application_run(app, argc, argv);
g_application_quit(app);
return 0;
}
作った後で気が付いたけどコレだと普通にループ文でも同じことができるやw
やっぱり GUI を使ってナンボの仕組みなんだろうね。
g_application_hold の実験ということで。
