getting inside gtk_main()



i wanted to emulate XForm's way of handling signals, in which, without
using a pipe or other heavyweight mechanism, i could notify a GTK UI
that a (POSIX) signal had been received. this is hard to do because
you can't use a signal handler - it runs asynchronously with respect
to GTK, and we can't use GTK_THREAD_ENTER/GTK_THREAD_LEAVE because
that may take too long to complete.

at the time, Miguel agreed that XForm's way of doing this was good,
but pointed out that it wasn't part of the current GTK release, and
unlikely to be part of a future release.  so, Miguel wrote:

>Actually, that makes sense.  You just need to have your own gtk_main:
>
>music_main ()
>{
>        while (gtk_events_pending ()){
>                gtk_main_iteration ();
>                if (alarm_handler_flag){
>                        alarm_handler_flag = 0;
>                        do_alarm_thingie ();
>                }
>        }
>}                                        

finally, as i get around to porting the particular program (which
makes heavy use of SIGALRM, every 20ms or so), i decided to try this
out. 

alas, it doesn't work. in fact, the loop above isn't even what
gtk_main() does. what this will do is process all X traffic necessary
to flush the queue of pending stuff (created by prior calls to GTK
functions), and then will exit the loop because gtk_events_pending()
will return FALSE. this is OK when you're doing this as a recursive
invocation of "gtk_main()", but its certainly not the equivalent of a
top level gtk_main().

so, i'm looking for some way to say: "every time gtk_main_iteration()
is done, please check this flag, do this if its set, and then unset
it". as far as i can tell, the operation of gtk_main() fundamentally
comes down to:

  if (g_main_is_running (main_loops->data))
    {
      GDK_THREADS_LEAVE ();
      g_main_run (loop);
      GDK_THREADS_ENTER ();
      gdk_flush ();
    }

in turn, g_main_run () mostly calls g_main_iterate() telling it to
both block and dispatch:

  loop->is_running = TRUE;
  while (loop->is_running)
    g_main_iterate (TRUE, TRUE);

i could use:

  while (gtk_main_iteration());

but i have no idea how to know when to leave the loop.

in short, i can see no way to actually accomplish the effect i want
without writing my own version of gtk_main(), which is OK, but clearly
not very optimal.

any ideas ?

--p



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]