2008-08-06 18:36:30 +00:00
|
|
|
// This file is part of BOINC.
|
2005-01-20 23:22:22 +00:00
|
|
|
// http://boinc.berkeley.edu
|
2019-01-12 21:43:48 +00:00
|
|
|
// Copyright (C) 2019 University of California
|
2004-12-10 21:06:42 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
2005-01-20 23:22:22 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
2005-01-20 23:22:22 +00:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
2004-12-10 21:06:42 +00:00
|
|
|
|
|
|
|
// An interface to BOINC graphics in which
|
|
|
|
// the graphics code lives in a separate shared library.
|
|
|
|
// This lets you make applications that work whether or not
|
|
|
|
// the host has X11 and OpenGL libraries.
|
2006-11-08 22:53:32 +00:00
|
|
|
//
|
|
|
|
// This file is the code that's part of the main program
|
2004-12-10 21:06:42 +00:00
|
|
|
|
2010-01-01 02:50:56 +00:00
|
|
|
// DEPRECATED
|
|
|
|
|
2005-12-16 03:33:36 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include "boinc_win.h"
|
|
|
|
#endif
|
|
|
|
|
2005-11-21 18:34:44 +00:00
|
|
|
#include "config.h"
|
2008-02-27 23:26:38 +00:00
|
|
|
#include <cstring>
|
2004-12-10 21:06:42 +00:00
|
|
|
#include <dlfcn.h>
|
|
|
|
|
2004-12-10 23:33:41 +00:00
|
|
|
#include "boinc_api.h"
|
2004-12-13 01:21:50 +00:00
|
|
|
#include "graphics_api.h"
|
|
|
|
#include "graphics_impl.h"
|
2004-12-11 01:01:19 +00:00
|
|
|
#include "graphics_lib.h"
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-13 18:55:42 +00:00
|
|
|
static BOINC_MAIN_STATE boinc_main_state;
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-12 15:21:20 +00:00
|
|
|
void* graphics_lib_handle=NULL;
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-14 20:28:13 +00:00
|
|
|
typedef int (*BIOGI_FUNC_PTR)(BOINC_OPTIONS&, WORKER_FUNC_PTR, BOINC_MAIN_STATE*);
|
|
|
|
// ptr to a function like boinc_init_options_graphics_impl()
|
|
|
|
|
2004-12-11 01:01:19 +00:00
|
|
|
// This routine never returns.
|
|
|
|
// If a problem arises, it calls boinc_finish(nonzero).
|
2004-12-10 23:33:41 +00:00
|
|
|
//
|
|
|
|
// First argument: worker function
|
|
|
|
//
|
2004-12-11 01:01:19 +00:00
|
|
|
// Second argument: argv[0] from command line arguments.
|
|
|
|
// This is the executable name, and is used to derive
|
|
|
|
// the shared object library name: executable_name.so
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-13 01:21:50 +00:00
|
|
|
int boinc_init_graphics_lib(WORKER_FUNC_PTR worker, char* argv0) {
|
2004-12-11 01:01:19 +00:00
|
|
|
BOINC_OPTIONS opt;
|
2004-12-13 19:14:54 +00:00
|
|
|
boinc_options_defaults(opt);
|
2004-12-11 01:01:19 +00:00
|
|
|
return boinc_init_options_graphics_lib(opt, worker, argv0);
|
|
|
|
}
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-11 01:01:19 +00:00
|
|
|
int boinc_init_options_graphics_lib(
|
2004-12-13 01:21:50 +00:00
|
|
|
BOINC_OPTIONS& opt, WORKER_FUNC_PTR worker, char* argv0
|
2004-12-11 01:01:19 +00:00
|
|
|
) {
|
2013-06-03 22:04:20 +00:00
|
|
|
char graphics_lib[MAXPATHLEN];
|
|
|
|
char resolved_name[MAXPATHLEN];
|
2004-12-11 01:01:19 +00:00
|
|
|
char *ptr;
|
|
|
|
int retval;
|
|
|
|
char *errormsg;
|
2004-12-13 01:21:50 +00:00
|
|
|
BIOGI_FUNC_PTR boinc_init_options_graphics_impl_hook;
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-13 18:55:42 +00:00
|
|
|
boinc_main_state.boinc_init_options_general_hook = boinc_init_options_general;
|
|
|
|
boinc_main_state.boinc_is_standalone_hook = boinc_is_standalone;
|
2004-12-13 19:03:10 +00:00
|
|
|
boinc_main_state.boinc_get_init_data_hook = boinc_get_init_data;
|
2008-01-13 04:16:58 +00:00
|
|
|
boinc_main_state.start_timer_thread_hook = start_timer_thread;
|
2004-12-19 07:53:02 +00:00
|
|
|
boinc_main_state.app_client_shmp = &app_client_shm;
|
2004-12-13 18:55:42 +00:00
|
|
|
|
2005-12-01 01:33:06 +00:00
|
|
|
// figure out name of executable, and append .so
|
|
|
|
//
|
|
|
|
if ((ptr = strrchr(argv0, '/'))) {
|
|
|
|
ptr++;
|
|
|
|
} else {
|
|
|
|
ptr = argv0;
|
|
|
|
}
|
2013-06-03 22:04:20 +00:00
|
|
|
strlcpy(graphics_lib, ptr, sizeof(graphics_lib));
|
|
|
|
strlcat(graphics_lib, ".so", sizeof(graphics_lib));
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2004-12-11 01:01:19 +00:00
|
|
|
// boinc-resolve library name: it could be a XML symlink
|
|
|
|
//
|
2013-06-03 22:04:20 +00:00
|
|
|
if (boinc_resolve_filename(graphics_lib, resolved_name, MAXPATHLEN)) {
|
2004-12-11 01:01:19 +00:00
|
|
|
fprintf(stderr,
|
|
|
|
"Unable to boinc_resolve name of shared object file %s\n",
|
|
|
|
graphics_lib
|
|
|
|
);
|
|
|
|
goto no_graphics;
|
|
|
|
}
|
2006-04-13 22:17:23 +00:00
|
|
|
|
|
|
|
// if it's not a symlink, put "./" in front of it
|
|
|
|
//
|
|
|
|
if (!strcmp(graphics_lib, resolved_name)) {
|
2022-08-03 09:21:59 +00:00
|
|
|
snprintf(resolved_name, sizeof(resolved_name), "./%s", graphics_lib);
|
2006-04-13 22:17:23 +00:00
|
|
|
}
|
2004-12-10 23:33:41 +00:00
|
|
|
|
2005-02-11 23:47:49 +00:00
|
|
|
// get handle for shared library.
|
|
|
|
// This handle is a global variable, so it can be declared 'extern'
|
|
|
|
// in worker() and thus worker() has access to functions
|
|
|
|
// from within this shared library
|
2004-12-11 01:01:19 +00:00
|
|
|
//
|
|
|
|
graphics_lib_handle = dlopen(resolved_name, RTLD_NOW);
|
|
|
|
if (!graphics_lib_handle) {
|
2005-02-11 23:47:49 +00:00
|
|
|
errormsg = (char*)dlerror();
|
2004-12-11 01:01:19 +00:00
|
|
|
fprintf(stderr,
|
|
|
|
"dlopen() failed: %s\nNo graphics.\n", errormsg?errormsg:""
|
|
|
|
);
|
|
|
|
goto no_graphics;
|
2004-12-10 23:33:41 +00:00
|
|
|
}
|
|
|
|
|
2004-12-12 14:40:43 +00:00
|
|
|
// use handle from shared library to resolve the 'initialize
|
|
|
|
// graphics' routine from shared library
|
|
|
|
//
|
2004-12-13 01:21:50 +00:00
|
|
|
boinc_init_options_graphics_impl_hook = (BIOGI_FUNC_PTR) dlsym(
|
2004-12-11 01:01:19 +00:00
|
|
|
graphics_lib_handle,
|
|
|
|
"boinc_init_options_graphics_impl"
|
|
|
|
);
|
|
|
|
if (!boinc_init_options_graphics_impl_hook) {
|
2005-02-11 23:47:49 +00:00
|
|
|
errormsg = (char*)dlerror();
|
2004-12-11 01:01:19 +00:00
|
|
|
fprintf(stderr,
|
2004-12-12 14:40:43 +00:00
|
|
|
"dlsym(): no boinc_init_options_graphics_impl() in %s\n%s\n",
|
2004-12-13 01:21:50 +00:00
|
|
|
resolved_name, errormsg?errormsg:""
|
2004-12-11 01:01:19 +00:00
|
|
|
);
|
|
|
|
goto no_graphics;
|
2004-12-10 23:33:41 +00:00
|
|
|
}
|
|
|
|
|
2004-12-13 18:55:42 +00:00
|
|
|
// here's where we start the graphics thread and the worker thread.
|
|
|
|
// Normally this function should not return.
|
2004-12-12 14:40:43 +00:00
|
|
|
//
|
2004-12-11 01:01:19 +00:00
|
|
|
retval = boinc_init_options_graphics_impl_hook(
|
2004-12-13 18:55:42 +00:00
|
|
|
opt, worker, &boinc_main_state
|
2004-12-11 01:01:19 +00:00
|
|
|
);
|
2004-12-10 23:33:41 +00:00
|
|
|
|
|
|
|
if (retval) {
|
2004-12-11 01:01:19 +00:00
|
|
|
fprintf(stderr,
|
|
|
|
"boinc_init_options_graphics_impl() returned %d: unable to create worker thread\n",
|
|
|
|
retval
|
|
|
|
);
|
2004-12-10 23:33:41 +00:00
|
|
|
}
|
|
|
|
|
2004-12-11 01:01:19 +00:00
|
|
|
boinc_finish(retval);
|
2004-12-12 14:40:43 +00:00
|
|
|
// never get here...
|
|
|
|
return 1;
|
|
|
|
|
2004-12-11 01:01:19 +00:00
|
|
|
no_graphics:
|
2004-12-10 23:33:41 +00:00
|
|
|
// unable to resolve the shared object file, or unable to resolve
|
2004-12-12 14:40:43 +00:00
|
|
|
// library dependencies on machine (eg, no X11, no GL libraries,
|
|
|
|
// etc) or unable to find needed symbol in library
|
2004-12-11 01:01:19 +00:00
|
|
|
//
|
2006-03-13 20:45:08 +00:00
|
|
|
boinc_init_options(&opt);
|
2004-12-10 23:33:41 +00:00
|
|
|
worker();
|
|
|
|
|
|
|
|
// worker() should call boinc_finish so we should NEVER get here!
|
2004-12-11 01:01:19 +00:00
|
|
|
//
|
2004-12-10 23:33:41 +00:00
|
|
|
boinc_finish(1);
|
2004-12-12 14:40:43 +00:00
|
|
|
// never get here...
|
2004-12-11 01:01:19 +00:00
|
|
|
return 1;
|
2004-12-10 21:06:42 +00:00
|
|
|
}
|
2004-12-16 03:28:40 +00:00
|
|
|
|
2006-11-08 22:40:03 +00:00
|
|
|
bool boinc_graphics_possible() {
|
|
|
|
#ifdef _WIN32
|
2007-01-04 11:34:17 +00:00
|
|
|
// ???? should not be here
|
2006-11-08 22:40:03 +00:00
|
|
|
#elif defined(__APPLE__)
|
2007-01-04 11:34:17 +00:00
|
|
|
// ???? should not be here
|
2006-11-08 22:40:03 +00:00
|
|
|
#else
|
|
|
|
if (!getenv("DISPLAY")) return false;
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|