diff --git a/api/graphics_api.C b/api/graphics_api.C index 8e5a57defd..22e4865b95 100755 --- a/api/graphics_api.C +++ b/api/graphics_api.C @@ -2,10 +2,20 @@ #include "graphics_impl.h" #include "graphics_api.h" +static BOINC_MAIN_STATE boinc_main_state; + +static void init_main_state() { + boinc_main_state.boinc_init_options_general_hook = boinc_init_options_general; + boinc_main_state.boinc_is_standalone_hook = boinc_is_standalone; + boinc_main_state.app_client_shm = app_client_shm; +} + int boinc_init_graphics(void (*worker)()) { - return boinc_init_graphics_impl(worker, boinc_init_options_general); + init_main_state(); + return boinc_init_graphics_impl(worker, &boinc_main_state); } int boinc_init_options_graphics(BOINC_OPTIONS& opt, void (*worker)()) { - return boinc_init_options_graphics_impl(opt, worker, boinc_init_options_general); + init_main_state(); + return boinc_init_options_graphics_impl(opt, worker, &boinc_main_state); } diff --git a/api/graphics_api.h b/api/graphics_api.h index ab0670da22..bd0539f7f0 100755 --- a/api/graphics_api.h +++ b/api/graphics_api.h @@ -39,7 +39,6 @@ typedef void (*WORKER_FUNC_PTR)(); extern int boinc_init_graphics(WORKER_FUNC_PTR); // Functions that must be supplied by the app -// application needs to define mouse, keyboard handlers // extern void app_graphics_render(int xs, int ys, double time_of_day); extern void app_graphics_init(void); diff --git a/api/graphics_impl.C b/api/graphics_impl.C index ef5adc9066..329d346605 100755 --- a/api/graphics_impl.C +++ b/api/graphics_impl.C @@ -58,8 +58,7 @@ double boinc_max_gfx_cpu_frac = 0.5; HANDLE hQuitEvent; #endif -bool graphics_inited = false; - +BOINC_MAIN_STATE* bmsp; static WORKER_FUNC_PTR worker_main; #ifdef _WIN32 @@ -75,10 +74,10 @@ void* foobar(void*) { // the following function can be in a shared library, // so it calls boinc_init_options_general() via a pointer instead of directly // -int boinc_init_graphics_impl(WORKER_FUNC_PTR worker, BIOG_FUNC_PTR init_func) { +int boinc_init_graphics_impl(WORKER_FUNC_PTR worker, BOINC_MAIN_STATE* bmsp) { BOINC_OPTIONS opt; options_defaults(opt); - return boinc_init_options_graphics_impl(opt, worker, init_func); + return boinc_init_options_graphics_impl(opt, worker, bmsp); } int start_worker_thread(WORKER_FUNC_PTR _worker_main) { @@ -156,17 +155,17 @@ int start_worker_thread(WORKER_FUNC_PTR _worker_main) { int boinc_init_options_graphics_impl( BOINC_OPTIONS& opt, WORKER_FUNC_PTR _worker_main, - BIOG_FUNC_PTR init_func + BOINC_MAIN_STATE* _bmsp ) { int retval; - retval = init_func(opt); + bmsp = _bmsp; + retval = bmsp->boinc_init_options_general_hook(opt); if (retval) return retval; if (_worker_main) { retval = start_worker_thread(_worker_main); if (retval) return retval; } - graphics_inited = true; #ifdef _WIN32 win_graphics_event_loop(); fprintf(stderr, "Graphics event loop returned\n"); diff --git a/api/graphics_impl.h b/api/graphics_impl.h index d2e1347a77..1b120fc671 100644 --- a/api/graphics_impl.h +++ b/api/graphics_impl.h @@ -23,11 +23,19 @@ typedef int (*BIOG_FUNC_PTR)(BOINC_OPTIONS&); // ptr to a function like boinc_init_options_general() -typedef int (*BIOGI_FUNC_PTR)(BOINC_OPTIONS&, WORKER_FUNC_PTR, BIOG_FUNC_PTR); +// stuff in the main program that the library need to access +// +struct BOINC_MAIN_STATE { + BIOG_FUNC_PTR boinc_init_options_general_hook; + bool (*boinc_is_standalone_hook)(); + APP_CLIENT_SHM* app_client_shm; +}; + +typedef int (*BIOGI_FUNC_PTR)(BOINC_OPTIONS&, WORKER_FUNC_PTR, BOINC_MAIN_STATE*); // ptr to a function like boinc_init_options_graphics_impl() extern int boinc_init_graphics_impl( - WORKER_FUNC_PTR worker, BIOG_FUNC_PTR init_func + WORKER_FUNC_PTR worker, BOINC_MAIN_STATE* ); // This extern C is needed to make this code work correctly, @@ -41,6 +49,8 @@ extern "C" { extern int boinc_init_options_graphics_impl( BOINC_OPTIONS& opt, WORKER_FUNC_PTR _worker_main, - BIOG_FUNC_PTR init_func + BOINC_MAIN_STATE* ); } + +extern BOINC_MAIN_STATE* bmsp; diff --git a/api/graphics_lib.C b/api/graphics_lib.C index 162162d877..6cca91e234 100644 --- a/api/graphics_lib.C +++ b/api/graphics_lib.C @@ -29,10 +29,12 @@ #include "graphics_impl.h" #include "graphics_lib.h" -#define BOINC_STRLEN 512 +static BOINC_MAIN_STATE boinc_main_state; void* graphics_lib_handle=NULL; +#define BOINC_STRLEN 512 + // This routine never returns. // If a problem arises, it calls boinc_finish(nonzero). // @@ -57,9 +59,12 @@ int boinc_init_options_graphics_lib( void *handle; int retval; char *errormsg; - BIOGI_FUNC_PTR boinc_init_options_graphics_impl_hook; + boinc_main_state.boinc_init_options_general_hook = boinc_init_options_general; + boinc_main_state.boinc_is_standalone_hook = boinc_is_standalone; + boinc_main_state.app_client_shm = app_client_shm; + // figure out name of executable, and append .so // if ((ptr = strrchr(argv0, '/'))) { @@ -111,11 +116,11 @@ int boinc_init_options_graphics_lib( goto no_graphics; } - // here's where we start the graphics thread and the worker - // thread. Normally this function should not return. + // here's where we start the graphics thread and the worker thread. + // Normally this function should not return. // retval = boinc_init_options_graphics_impl_hook( - opt, worker, boinc_init_options_general + opt, worker, &boinc_main_state ); if (retval) { diff --git a/api/x_opengl.C b/api/x_opengl.C index e316a1fe93..7505077cfc 100644 --- a/api/x_opengl.C +++ b/api/x_opengl.C @@ -5,12 +5,13 @@ #include #include "x_opengl.h" -#include "boinc_gl.h" -#include "boinc_api.h" -#include "graphics_api.h" #include "app_ipc.h" #include "util.h" +#include "boinc_gl.h" +#include "graphics_api.h" +#include "graphics_impl.h" + #define BOINC_WINDOW_CLASS_NAME "BOINC_app" #define TIMER_INTERVAL_MSEC 30 @@ -21,12 +22,17 @@ static int acked_graphics_mode; static int xpos = 100, ypos = 100; static int clicked_button; static int win=0; -extern void graphics_thread_init(); static void set_mode(int mode); +// This callback is invoked when a user presses a key. +// +void keyboardD(unsigned char key, int x, int y) { + if (current_graphics_mode == MODE_FULLSCREEN) { + set_mode(MODE_HIDE_GRAPHICS); + } +} + void keyboardU(unsigned char key, int x, int y) { - // This callback is invoked when a user presses a key. - // if (current_graphics_mode == MODE_FULLSCREEN) { set_mode(MODE_HIDE_GRAPHICS); } @@ -59,14 +65,6 @@ void mouse_click_move(int x, int y){ } } -void keyboardD(unsigned char key, int x, int y) { - // This callback is invoked when a user presses a key. - // - if (current_graphics_mode == MODE_FULLSCREEN) { - set_mode(MODE_HIDE_GRAPHICS); - } -} - static void maybe_render() { int width, height; if (visible && (current_graphics_mode != MODE_HIDE_GRAPHICS)) { @@ -79,7 +77,7 @@ static void maybe_render() { } static void close_func() { - if (boinc_is_standalone()) { + if (bmsp->boinc_is_standalone_hook()) { exit(0); } else { set_mode(MODE_HIDE_GRAPHICS); @@ -138,12 +136,12 @@ void set_mode(int mode) { } static void wait_for_initial_message() { - app_client_shm->shm->graphics_reply.send_msg( + bmsp->app_client_shm->shm->graphics_reply.send_msg( xml_graphics_modes[MODE_HIDE_GRAPHICS] ); acked_graphics_mode = MODE_HIDE_GRAPHICS; while (1) { - if (app_client_shm->shm->graphics_request.has_msg()) { + if (bmsp->app_client_shm->shm->graphics_request.has_msg()) { break; } sleep(1); @@ -155,9 +153,9 @@ static void timer_handler(int) { GRAPHICS_MSG m; int new_mode; - if (app_client_shm) { - if (app_client_shm->shm->graphics_request.get_msg(buf)) { - app_client_shm->decode_graphics_msg(buf, m); + if (bmsp->app_client_shm) { + if (bmsp->app_client_shm->shm->graphics_request.get_msg(buf)) { + bmsp->app_client_shm->decode_graphics_msg(buf, m); switch (m.mode) { case MODE_REREAD_PREFS: //only reread graphics prefs if we have a window open @@ -178,7 +176,7 @@ static void timer_handler(int) { } } if (acked_graphics_mode != current_graphics_mode) { - bool sent = app_client_shm->shm->graphics_reply.send_msg( + bool sent = bmsp->app_client_shm->shm->graphics_reply.send_msg( xml_graphics_modes[current_graphics_mode] ); if (sent) acked_graphics_mode = current_graphics_mode; @@ -188,8 +186,8 @@ static void timer_handler(int) { glutTimerFunc(TIMER_INTERVAL_MSEC, timer_handler, 0); } -jmp_buf jbuf; -pthread_t graphics_thread; +static jmp_buf jbuf; +static pthread_t graphics_thread; void restart() { if (pthread_equal(pthread_self(), graphics_thread)) { @@ -200,7 +198,7 @@ void restart() { void xwin_graphics_event_loop() { graphics_thread = pthread_self(); - if (boinc_is_standalone()) { + if (bmsp->boinc_is_standalone_hook()) { set_mode(MODE_WINDOW); } else { wait_for_initial_message(); diff --git a/checkin_notes b/checkin_notes index 73c192698e..de311c01f1 100755 --- a/checkin_notes +++ b/checkin_notes @@ -21164,3 +21164,23 @@ David 12 Dec 2004 graphics_api.h graphics_impl.C,h graphics_lib.C,h + +David 13 Dec 2004 + - bug fixes for graphics lib stuff. + Code in the app's graphics shared library (including x_opengl.C) + must not directly reference variables in the main program + (e.g. app_client_shm) because it will have "shadow" copies of them. + + Changed the graphics_impl interface so that the shared library + function gets passed a pointer to a structure (BOINC_MAIN_STATE) + containing everything it will need to access. + + This is a first pass. May need to add more to BOINC_MAIN_STATE. + And should clean up .h file structure so that compiler will + enforce constraints. + + api/ + graphics_api.C,h + graphics_impl.C,h + graphics_lib.C + x_opengl.C