Hi,
I want to insert gtk+ in host softwares and I
have some problems during execution of the main loop.
I work with gtk 2.2 on Win32 ( Windows 2000
).
I think if we put the creation and the execution of
the main loop in another thread,
the main loop of host software and gtk main loop
will be able to run without collisions.
I have exploded the gtk_main() for understanding
but when I run it,
the program stop after a moment and block in the
g_main_context_dispatch() and I'm sure that I have acquire the context
!
When I run this code in my myRun method ( without
thread managment ), it runs very well !...
You could see the source in
attachment.
Are there some forgotting or mistackes ? Is a
knowing problem on Win32 platforms ?
So, if you are the solution for running gtk in a
software without collision between their main loops, I will be so happy
!
Thanks a lot by advance.
Sébastien Masino.
|
void myRun ( void ) { gtk_disable_setlocale(); gtk_init( &argc, &argv ); g_thread_init(0); GThread* thread = g_thread_create_full ( mainThreadFunction, NULL, 0, true, false, GTK_THREAD_PRIORITY_NORMAL, 0 ); g_usleep( 1000 ); g_thread_join( thread ); } void* mainThreadFunction ( gpointer data ) { bool result, some_ready; int max_priority, timeout; int nfds = 0; int allocated_nfds = 0; GPollFD* fds = 0; GPollFunc pollFunc; // -- Create Main loop gdk_threads_init(); GMainLoop* mainLoop = g_main_loop_new( NULL, true ); GMainContext* mainContext = g_main_loop_get_context( mainLoop ); if ( g_main_loop_is_running ( mainLoop ) ) { // -- Run Main loop until it will be stopped by "g_main_loop_quit()" gdk_threads_leave(); //LOCK_CONTEXT( mainContext ) // -- opaque while ( g_main_loop_is_running ( mainLoop ) ) { // -- Acquire main loop context ( We must be the owner of the context for preparing, querying, check, polling and dispatching ) result = g_main_context_acquire ( mainContext ); if( !result ) { printf("Context not acquired\n"); } else { // -- Prepare context ( Prepares to poll sources within a main loop ) g_main_context_prepare ( mainContext, &max_priority ); // -- Query of context with iterative method for allocating polling informations array ( Determines information necessary to poll this main loop ) while( ( nfds = g_main_context_query ( mainContext, max_priority, &timeout, fds, allocated_nfds ) ) > allocated_nfds ) { if( fds ) { g_free ( fds ); } allocated_nfds = nfds; fds = g_new ( GPollFD, allocated_nfds ); } // -- Get current poll func from main loop context and execute it pollFunc = g_main_context_get_poll_func ( mainContext ); if ( nfds || timeout != 0 ) { (*pollFunc)( fds, nfds, timeout ); } // -- Check main loop context ( passes the result of polling back to the main loop ) some_ready = g_main_context_check ( mainContext, max_priority, fds, nfds ); // -- Un allocate polling array ( it's just for be clean but it's not very effective ) if( fds ) { g_free ( fds ); fds = 0; } allocated_nfds = nfds = 0; // -- Then, dispatch ... if( some_ready ) { g_main_context_dispatch ( mainContext ); } // -- Release main loop context g_main_context_release ( mainContext ); } } //UNLOCK_CONTEXT( mainContext ) // -- opaque gdk_threads_enter(); gdk_flush(); } return NULL; }