123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "console/console.h"
- #include "core/fileStream.h"
- #include "game/resource.h"
- #include "game/version.h"
- #include "math/mRandom.h"
- #include "platformX86UNIX/platformX86UNIX.h"
- #include "platformX86UNIX/x86UNIXStdConsole.h"
- #include "platform/event.h"
- #include "platform/gameInterface.h"
- #include "platform/platform.h"
- #include "platform/platformAL.h"
- #include "platform/platformInput.h"
- #include "platform/platformVideo.h"
- #include "platform/profiler.h"
- #include "platformX86UNIX/platformGL.h"
- #include "platformX86UNIX/x86UNIXOGLVideo.h"
- #include "platformX86UNIX/x86UNIXState.h"
- #ifndef TORQUE_DEDICATED
- #include "platformX86UNIX/x86UNIXMessageBox.h"
- #include "platformX86UNIX/x86UNIXInputManager.h"
- #endif
- #include <errno.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <unistd.h> // fork, execvp, chdir
- #include <time.h> // nanosleep
- #ifndef TORQUE_DEDICATED
- #include <X11/Xlib.h>
- #include <X11/Xos.h>
- #include <SDL/SDL.h>
- #include <SDL/SDL_syswm.h>
- #include <SDL/SDL_version.h>
- #endif
- x86UNIXPlatformState *x86UNIXState;
- bool DisplayPtrManager::sgDisplayLocked = false;
- LockFunc_t DisplayPtrManager::sgLockFunc = NULL;
- LockFunc_t DisplayPtrManager::sgUnlockFunc = NULL;
- static U32 lastTimeTick;
- static MRandomLCG sgPlatRandom;
- #ifndef TORQUE_DEDICATED
- extern void InstallRedBookDevices();
- extern void PollRedbookDevices();
- extern bool InitOpenGL();
- // This is called when some X client sends
- // a selection event (e.g. SelectionRequest)
- // to the window
- extern void NotifySelectionEvent(XEvent& event);
- #endif
- //------------------------------------------------------------------------------
- static S32 ParseCommandLine(S32 argc, const char **argv,
- Vector<char*>& newCommandLine)
- {
- x86UNIXState->setExePathName(argv[0]);
- bool foundDedicated = false;
- for ( int i=0; i < argc; i++ )
- {
- // look for platform specific args
- if (dStrcmp(argv[i], "-version") == 0)
- {
- dPrintf("%s (built on %s)\n", getVersionString(), getCompileTimeString());
- dPrintf("gcc: %s\n", __VERSION__);
- return 1;
- }
- if (dStrcmp(argv[i], "-cdaudio") == 0)
- {
- x86UNIXState->setCDAudioEnabled(true);
- continue;
- }
- if (dStrcmp(argv[i], "-dedicated") == 0)
- {
- foundDedicated = true;
- // no continue because dedicated is also handled by script
- }
- if (dStrcmp(argv[i], "-dsleep") == 0)
- {
- x86UNIXState->setDSleep(true);
- continue;
- }
- if (dStrcmp(argv[i], "-nohomedir") == 0)
- {
- x86UNIXState->setUseRedirect(false);
- continue;
- }
- if (dStrcmp(argv[i], "-chdir") == 0)
- {
- if ( ++i >= argc )
- {
- dPrintf("Follow -chdir option with the desired working directory.\n");
- return 1;
- }
- if (chdir(argv[i]) == -1)
- {
- dPrintf("Unable to chdir to %s: %s\n", argv[i], strerror(errno));
- return 1;
- }
- continue;
- }
-
- // copy the arg into newCommandLine
- int argLen = dStrlen(argv[i]) + 1;
- char* argBuf = new char[argLen]; // this memory is deleted in main()
- dStrncpy(argBuf, argv[i], argLen);
- newCommandLine.push_back(argBuf);
- }
- x86UNIXState->setDedicated(foundDedicated);
- #if defined(DEDICATED) && !defined(TORQUE_ENGINE)
- if (!foundDedicated)
- {
- dPrintf("This is a dedicated server build. You must supply the -dedicated command line parameter.\n");
- return 1;
- }
- #endif
- return 0;
- }
- static void DetectWindowingSystem()
- {
- #ifndef TORQUE_DEDICATED
- Display* dpy = XOpenDisplay(NULL);
- if (dpy != NULL)
- {
- x86UNIXState->setXWindowsRunning(true);
- XCloseDisplay(dpy);
- }
- #endif
- }
- //------------------------------------------------------------------------------
- static void InitWindow(const Point2I &initialSize, const char *name)
- {
- x86UNIXState->setWindowSize(initialSize);
- x86UNIXState->setWindowName(name);
- }
- #ifndef TORQUE_DEDICATED
- //------------------------------------------------------------------------------
- static bool InitSDL()
- {
- if (SDL_Init(SDL_INIT_VIDEO) != 0)
- return false;
- atexit(SDL_Quit);
- SDL_SysWMinfo sysinfo;
- SDL_VERSION(&sysinfo.version);
- if (SDL_GetWMInfo(&sysinfo) == 0)
- return false;
- x86UNIXState->setDisplayPointer(sysinfo.info.x11.display);
- DisplayPtrManager::setDisplayLockFunction(sysinfo.info.x11.lock_func);
- DisplayPtrManager::setDisplayUnlockFunction(sysinfo.info.x11.unlock_func);
- DisplayPtrManager xdisplay;
- Display* display = xdisplay.getDisplayPointer();
- x86UNIXState->setScreenNumber(
- DefaultScreen( display ) );
- x86UNIXState->setScreenPointer(
- DefaultScreenOfDisplay( display ) );
- x86UNIXState->setDesktopSize(
- (S32) DisplayWidth(
- display,
- x86UNIXState->getScreenNumber()),
- (S32) DisplayHeight(
- display,
- x86UNIXState->getScreenNumber())
- );
- x86UNIXState->setDesktopBpp(
- (S32) DefaultDepth(
- display,
- x86UNIXState->getScreenNumber()));
- // indicate that we want sys WM messages
- SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
- return true;
- }
- //------------------------------------------------------------------------------
- static void ProcessSYSWMEvent(const SDL_Event& event)
- {
- XEvent& xevent = event.syswm.msg->event.xevent;
- //Con::printf("xevent : %d", xevent.type);
- switch (xevent.type)
- {
- case SelectionRequest:
- // somebody wants our clipboard
- NotifySelectionEvent(xevent);
- break;
- }
- }
- //------------------------------------------------------------------------------
- static void SetAppState()
- {
- U8 state = SDL_GetAppState();
- // if we're not active but we have appactive and inputfocus, set window
- // active and reactivate input
- if ((!x86UNIXState->windowActive() || !Input::isActive()) &&
- state & SDL_APPACTIVE &&
- state & SDL_APPINPUTFOCUS)
- {
- x86UNIXState->setWindowActive(true);
- Input::reactivate();
- }
- // if we are active, but we don't have appactive or input focus,
- // deactivate input (if window not locked) and clear windowActive
- else if (x86UNIXState->windowActive() &&
- !(state & SDL_APPACTIVE && state & SDL_APPINPUTFOCUS))
- {
- if (x86UNIXState->windowLocked())
- Input::deactivate();
- x86UNIXState->setWindowActive(false);
- }
- }
- //------------------------------------------------------------------------------
- static S32 NumEventsPending()
- {
- static const int MaxEvents = 255;
- static SDL_Event events[MaxEvents];
- SDL_PumpEvents();
- return SDL_PeepEvents(events, MaxEvents, SDL_PEEKEVENT, SDL_ALLEVENTS);
- }
- //------------------------------------------------------------------------------
- static void PrintSDLEventQueue()
- {
- static const int MaxEvents = 255;
- static SDL_Event events[MaxEvents];
- SDL_PumpEvents();
- S32 numEvents = SDL_PeepEvents(
- events, MaxEvents, SDL_PEEKEVENT, SDL_ALLEVENTS);
- if (numEvents <= 0)
- {
- dPrintf("SDL Event Queue is empty\n");
- return;
- }
- dPrintf("SDL Event Queue:\n");
- for (int i = 0; i < numEvents; ++i)
- {
- const char *eventType;
- switch (events[i].type)
- {
- case SDL_NOEVENT: eventType = "SDL_NOEVENT"; break;
- case SDL_ACTIVEEVENT: eventType = "SDL_ACTIVEEVENT"; break;
- case SDL_KEYDOWN: eventType = "SDL_KEYDOWN"; break;
- case SDL_KEYUP: eventType = "SDL_KEYUP"; break;
- case SDL_MOUSEMOTION: eventType = "SDL_MOUSEMOTION"; break;
- case SDL_MOUSEBUTTONDOWN: eventType = "SDL_MOUSEBUTTONDOWN"; break;
- case SDL_MOUSEBUTTONUP: eventType = "SDL_MOUSEBUTTONUP"; break;
- case SDL_JOYAXISMOTION: eventType = "SDL_JOYAXISMOTION"; break;
- case SDL_JOYBALLMOTION: eventType = "SDL_JOYBALLMOTION"; break;
- case SDL_JOYHATMOTION: eventType = "SDL_JOYHATMOTION"; break;
- case SDL_JOYBUTTONDOWN: eventType = "SDL_JOYBUTTONDOWN"; break;
- case SDL_JOYBUTTONUP: eventType = "SDL_JOYBUTTONUP"; break;
- case SDL_QUIT: eventType = "SDL_QUIT"; break;
- case SDL_SYSWMEVENT: eventType = "SDL_SYSWMEVENT"; break;
- case SDL_VIDEORESIZE: eventType = "SDL_VIDEORESIZE"; break;
- case SDL_VIDEOEXPOSE: eventType = "SDL_VIDEOEXPOSE"; break;
- /* Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */
- case SDL_USEREVENT: eventType = "SDL_USEREVENT"; break;
- default: eventType = "UNKNOWN!"; break;
- }
- dPrintf("Event %d: %s\n", i, eventType);
- }
- }
- //------------------------------------------------------------------------------
- static bool ProcessMessages()
- {
- static const int MaxEvents = 255;
- static const U32 Mask =
- SDL_QUITMASK | SDL_VIDEORESIZEMASK | SDL_VIDEOEXPOSEMASK |
- SDL_ACTIVEEVENTMASK | SDL_SYSWMEVENTMASK |
- SDL_EVENTMASK(SDL_USEREVENT);
- static SDL_Event events[MaxEvents];
-
- SDL_PumpEvents();
- S32 numEvents = SDL_PeepEvents(events, MaxEvents, SDL_GETEVENT, Mask);
- if (numEvents == 0)
- return true;
- for (int i = 0; i < numEvents; ++i)
- {
- SDL_Event& event = events[i];
- switch (event.type)
- {
- case SDL_QUIT:
- return false;
- break;
- case SDL_VIDEORESIZE:
- case SDL_VIDEOEXPOSE:
- Game->refreshWindow();
- break;
- case SDL_USEREVENT:
- if (event.user.code == TORQUE_SETVIDEOMODE)
- {
- SetAppState();
- // SDL will send a motion event to restore the mouse position
- // on the new window. Ignore that if the window is locked.
- if (x86UNIXState->windowLocked())
- {
- SDL_Event tempEvent;
- SDL_PeepEvents(&tempEvent, 1, SDL_GETEVENT,
- SDL_MOUSEMOTIONMASK);
- }
- }
- break;
- case SDL_ACTIVEEVENT:
- SetAppState();
- break;
- case SDL_SYSWMEVENT:
- ProcessSYSWMEvent(event);
- break;
- }
- }
- return true;
- }
- //------------------------------------------------------------------------------
- // send a destroy window event to the window. assumes
- // window is created.
- void SendQuitEvent()
- {
- SDL_Event quitevent;
- quitevent.type = SDL_QUIT;
- SDL_PushEvent(&quitevent);
- }
- #endif // DEDICATED
- //------------------------------------------------------------------------------
- static inline void Sleep(int secs, int nanoSecs)
- {
- timespec sleeptime;
- sleeptime.tv_sec = secs;
- sleeptime.tv_nsec = nanoSecs;
- nanosleep(&sleeptime, NULL);
- }
- #ifndef TORQUE_DEDICATED
- struct AlertWinState
- {
- bool fullScreen;
- bool cursorHidden;
- bool inputGrabbed;
- };
- //------------------------------------------------------------------------------
- void DisplayErrorAlert(const char* errMsg, bool showSDLError)
- {
- char fullErrMsg[2048];
- dStrncpy(fullErrMsg, errMsg, sizeof(fullErrMsg));
-
- if (showSDLError)
- {
- char* sdlerror = SDL_GetError();
- if (sdlerror != NULL && dStrlen(sdlerror) > 0)
- {
- dStrcat(fullErrMsg, " (Error: ");
- dStrcat(fullErrMsg, sdlerror);
- dStrcat(fullErrMsg, ")");
- }
- }
-
- Platform::AlertOK("Error", fullErrMsg);
- }
- //------------------------------------------------------------------------------
- static inline void AlertDisableVideo(AlertWinState& state)
- {
- state.fullScreen = Video::isFullScreen();
- state.cursorHidden = (SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE);
- state.inputGrabbed = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
- if (state.fullScreen)
- SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
- if (state.cursorHidden)
- SDL_ShowCursor(SDL_ENABLE);
- if (state.inputGrabbed)
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- }
- //------------------------------------------------------------------------------
- static inline void AlertEnableVideo(AlertWinState& state)
- {
- if (state.fullScreen)
- SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
- if (state.cursorHidden)
- SDL_ShowCursor(SDL_DISABLE);
- if (state.inputGrabbed)
- SDL_WM_GrabInput(SDL_GRAB_ON);
- }
- #endif // DEDICATED
- //------------------------------------------------------------------------------
- void Platform::AlertOK(const char *windowTitle, const char *message)
- {
- #ifndef TORQUE_DEDICATED
- if (x86UNIXState->isXWindowsRunning())
- {
- AlertWinState state;
- AlertDisableVideo(state);
- DisplayPtrManager xdisplay;
- XMessageBox mBox(xdisplay.getDisplayPointer());
- mBox.alertOK(windowTitle, message);
- AlertEnableVideo(state);
- }
- else
- #endif
- {
- if (Con::isActive() && StdConsole::isEnabled())
- Con::printf("Alert: %s %s", windowTitle, message);
- else
- dPrintf("Alert: %s %s\n", windowTitle, message);
- }
- }
- //------------------------------------------------------------------------------
- bool Platform::AlertOKCancel(const char *windowTitle, const char *message)
- {
- #ifndef TORQUE_DEDICATED
- if (x86UNIXState->isXWindowsRunning())
- {
- AlertWinState state;
- AlertDisableVideo(state);
- DisplayPtrManager xdisplay;
- XMessageBox mBox(xdisplay.getDisplayPointer());
- bool val =
- mBox.alertOKCancel(windowTitle, message) == XMessageBox::OK;
- AlertEnableVideo(state);
- return val;
- }
- else
- #endif
- {
- if (Con::isActive() && StdConsole::isEnabled())
- Con::printf("Alert: %s %s", windowTitle, message);
- else
- dPrintf("Alert: %s %s\n", windowTitle, message);
- return false;
- }
- }
- //------------------------------------------------------------------------------
- bool Platform::AlertRetry(const char *windowTitle, const char *message)
- {
- #ifndef TORQUE_DEDICATED
- if (x86UNIXState->isXWindowsRunning())
- {
- AlertWinState state;
- AlertDisableVideo(state);
- DisplayPtrManager xdisplay;
- XMessageBox mBox(xdisplay.getDisplayPointer());
- bool val =
- mBox.alertRetryCancel(windowTitle, message) == XMessageBox::Retry;
-
- AlertEnableVideo(state);
- return val;
- }
- else
- #endif
- {
- if (Con::isActive() && StdConsole::isEnabled())
- Con::printf("Alert: %s %s", windowTitle, message);
- else
- dPrintf("Alert: %s %s\n", windowTitle, message);
- return false;
- }
- }
- //------------------------------------------------------------------------------
- bool Platform::excludeOtherInstances(const char *mutexName)
- {
- return AcquireProcessMutex(mutexName);
- }
- //------------------------------------------------------------------------------
- void Platform::enableKeyboardTranslation(void)
- {
- #ifndef TORQUE_DEDICATED
- // JMQ: not sure if this is needed for i18n keyboards
- //SDL_EnableUNICODE( 1 );
- // SDL_EnableKeyRepeat(
- // SDL_DEFAULT_REPEAT_DELAY,
- // SDL_DEFAULT_REPEAT_INTERVAL);
- #endif
- }
- //------------------------------------------------------------------------------
- void Platform::disableKeyboardTranslation(void)
- {
- #ifndef TORQUE_DEDICATED
- //SDL_EnableUNICODE( 0 );
- // SDL_EnableKeyRepeat(0, 0);
- #endif
- }
- //------------------------------------------------------------------------------
- void Platform::setWindowLocked(bool locked)
- {
- #ifndef TORQUE_DEDICATED
- x86UNIXState->setWindowLocked(locked);
- UInputManager* uInputManager =
- dynamic_cast<UInputManager*>( Input::getManager() );
- if ( uInputManager && uInputManager->isEnabled() &&
- Input::isActive() )
- uInputManager->setWindowLocked(locked);
- #endif
- }
- //------------------------------------------------------------------------------
- void Platform::minimizeWindow()
- {
- #ifndef TORQUE_DEDICATED
- if (x86UNIXState->windowCreated())
- SDL_WM_IconifyWindow();
- #endif
- }
- //------------------------------------------------------------------------------
- void Platform::process()
- {
- PROFILE_START(XUX_PlatformProcess);
- stdConsole->process();
- if (x86UNIXState->windowCreated())
- {
- #ifndef TORQUE_DEDICATED
- // process window events
- PROFILE_START(XUX_ProcessMessages);
- bool quit = !ProcessMessages();
- PROFILE_END();
- if(quit)
- {
- // generate a quit event
- Event quitEvent;
- quitEvent.type = QuitEventType;
- Game->postEvent(quitEvent);
- }
- // process input events
- PROFILE_START(XUX_InputProcess);
- Input::process();
- PROFILE_END();
- // poll redbook state
- PROFILE_START(XUX_PollRedbookDevices);
- PollRedbookDevices();
- PROFILE_END();
- // if we're not the foreground window, sleep for 1 ms
- if (!x86UNIXState->windowActive())
- Sleep(0, getBackgroundSleepTime() * 1000000);
- #endif
- }
- else
- {
- // no window
- // if we're not in journal mode, sleep for 1 ms
- // JMQ: since linux's minimum sleep latency seems to be 20ms, this can
- // increase player pings by 10-20ms in the dedicated server. So
- // you have to use -dsleep to enable it. the server sleeps anyway when
- // there are no players connected.
- // JMQ: recent kernels (such as RH 8.0 2.4.18) reduce the latency
- // to 2-4 ms on average.
- if (!Game->isJournalReading() && (x86UNIXState->getDSleep() ||
- Con::getIntVariable("Server::PlayerCount") -
- Con::getIntVariable("Server::BotCount") <= 0))
- {
- PROFILE_START(XUX_Sleep);
- Sleep(0, getBackgroundSleepTime() * 1000000);
- PROFILE_END();
- }
- }
- #ifndef TORQUE_DEDICATED
- #if 0
- // JMQ: disabled this because it may fire mistakenly in some configurations.
- // sdl's default event handling scheme should be enough.
- // crude check to make sure that we're not loading up events. the sdl
- // event queue should never have more than (say) 25 events in it at this
- // point
- const int MaxEvents = 25;
- if (NumEventsPending() > MaxEvents)
- {
- PrintSDLEventQueue();
- AssertFatal(false, "The SDL event queue has too many events!");
- }
- #endif
- #endif
- PROFILE_END();
- }
- // extern U32 calculateCRC(void * buffer, S32 len, U32 crcVal );
- // #if defined(DEBUG) || defined(INTERNAL_RELEASE)
- // static U32 stubCRC = 0;
- // #else
- // static U32 stubCRC = 0xEA63F56C;
- // #endif
- //------------------------------------------------------------------------------
- const Point2I &Platform::getWindowSize()
- {
- return x86UNIXState->getWindowSize();
- }
- //------------------------------------------------------------------------------
- void Platform::setWindowSize( U32 newWidth, U32 newHeight )
- {
- x86UNIXState->setWindowSize( (S32) newWidth, (S32) newHeight );
- }
- //------------------------------------------------------------------------------
- void Platform::initWindow(const Point2I &initialSize, const char *name)
- {
- #ifndef TORQUE_DEDICATED
- // initialize window
- InitWindow(initialSize, name);
- if (!InitOpenGL())
- ImmediateShutdown(1);
- #endif
- }
- //------------------------------------------------------------------------------
- // Web browser function:
- //------------------------------------------------------------------------------
- bool Platform::openWebBrowser( const char* webAddress )
- {
- if (!webAddress || dStrlen(webAddress)==0)
- return false;
- // look for a browser preference variable
- // JMQTODO: be nice to implement some UI to customize this
- const char* webBrowser = Con::getVariable("Pref::Unix::WebBrowser");
- if (dStrlen(webBrowser) == 0)
- webBrowser = NULL;
- pid_t pid = fork();
- if (pid == -1)
- {
- Con::printf("WARNING: Platform::openWebBrowser failed to fork");
- return false;
- }
- else if (pid != 0)
- {
- // parent
- if (Video::isFullScreen())
- Video::toggleFullScreen();
- return true;
- }
- else if (pid == 0)
- {
- // child
- // try to exec konqueror, then netscape
- char* argv[3];
- argv[0] = "";
- argv[1] = const_cast<char*>(webAddress);
- argv[2] = 0;
- int ok = -1;
- // if execvp returns, it means it couldn't execute the program
- if (webBrowser != NULL)
- ok = execvp(webBrowser, argv);
- ok = execvp("konqueror", argv);
- ok = execvp("mozilla", argv);
- ok = execvp("netscape", argv);
- // use dPrintf instead of Con here since we're now in another process,
- dPrintf("WARNING: Platform::openWebBrowser: couldn't launch a web browser\n");
- _exit(-1);
- return false;
- }
- else
- {
- Con::printf("WARNING: Platform::openWebBrowser: forking problem");
- return false;
- }
- }
- //------------------------------------------------------------------------------
- // Login password routines:
- //------------------------------------------------------------------------------
- const char* Platform::getLoginPassword()
- {
- Con::printf("WARNING: Platform::getLoginPassword() is unimplemented");
- return "";
- }
- //------------------------------------------------------------------------------
- bool Platform::setLoginPassword( const char* password )
- {
- Con::printf("WARNING: Platform::setLoginPassword is unimplemented");
- return false;
- }
- //-------------------------------------------------------------------------------
- void TimeManager::process()
- {
- U32 curTime = Platform::getRealMilliseconds();
- TimeEvent event;
- event.elapsedTime = curTime - lastTimeTick;
- if(event.elapsedTime > sgTimeManagerProcessInterval)
- {
- lastTimeTick = curTime;
- Game->postEvent(event);
- }
- }
- //------------------------------------------------------------------------------
- ConsoleFunction( getDesktopResolution, const char*, 1, 1,
- "getDesktopResolution()" )
- {
- if (!x86UNIXState->windowCreated())
- return "0 0 0";
- char buffer[256];
- char* returnString = Con::getReturnBuffer( dStrlen( buffer ) + 1 );
- dSprintf( buffer, sizeof( buffer ), "%d %d %d",
- x86UNIXState->getDesktopSize().x,
- x86UNIXState->getDesktopSize().y,
- x86UNIXState->getDesktopBpp() );
- dStrcpy( returnString, buffer );
- return( returnString );
- }
- //------------------------------------------------------------------------------
- // Silly Korean registry key checker:
- //------------------------------------------------------------------------------
- ConsoleFunction( isKoreanBuild, bool, 1, 1, "isKoreanBuild()" )
- {
- Con::printf("WARNING: isKoreanBuild() is unimplemented");
- return false;
- }
- //------------------------------------------------------------------------------
- int main(S32 argc, const char **argv)
- {
- // init platform state
- x86UNIXState = new x86UNIXPlatformState;
- // parse the command line for unix-specific params
- Vector<char *> newCommandLine;
- S32 returnVal = ParseCommandLine(argc, argv, newCommandLine);
- if (returnVal != 0)
- return returnVal;
- // init lastTimeTick for TimeManager::process()
- lastTimeTick = Platform::getRealMilliseconds();
- // init process control stuff
- ProcessControlInit();
- // check to see if X is running
- DetectWindowingSystem();
-
- // run the game
- returnVal = Game->main(newCommandLine.size(),
- const_cast<const char**>(newCommandLine.address()));
- // dispose of command line
- for(U32 i = 0; i < newCommandLine.size(); i++)
- delete [] newCommandLine[i];
- // dispose of state
- delete x86UNIXState;
- return returnVal;
- }
- void Platform::setWindowTitle( const char* title )
- {
- #ifndef TORQUE_DEDICATED
- x86UNIXState->setWindowName(title);
- SDL_WM_SetCaption(x86UNIXState->getWindowName(), NULL);
- #endif
- }
- Resolution Video::getDesktopResolution()
- {
- Resolution Result;
- Result.h = x86UNIXState->getDesktopSize().x;
- Result.w = x86UNIXState->getDesktopSize().y;
- Result.bpp = x86UNIXState->getDesktopBpp();
- return Result;
- }
- //-----------------------------------------------------------------------------
- void Platform::restartInstance()
- {
- if (Game->isRunning() )
- {
- //Con::errorf( "Error restarting Instance. Game is Still running!");
- return;
- }
- char cmd[2048];
- sprintf(cmd, "%s &", x86UNIXState->getExePathName());
- system(cmd);
- exit(0);
- }
|