g_application_hold

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;
}

notify_send

作った後で気が付いたけどコレだと普通にループ文でも同じことができるやw
やっぱり GUI を使ってナンボの仕組みなんだろうね。
g_application_hold の実験ということで。