/*************************************************************************** SDLapp.cpp (c) 2006 Laurent Carlier This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ #include "SDLapp.h" #include "SDLcore.h" #include "SDLwindow.h" #include "SDL_ttf.h" #include #include int SDLapplication::AppCount = 0; int SDLapplication::LockX11Count = 0; SDLapplication *SDLapp; SDLapplication::SDLapplication(int &argc, char **argv) { // init is already done ! if (SDLapplication::AppCount) { SDLapplication::AppCount++; return; } std::string sMsg = "Failed to init: "; Uint32 sysInit = SDL_WasInit(SDL_INIT_EVERYTHING); // if audio is defined, sdl was init by gb.sdl.sound component ! if (sysInit & SDL_INIT_AUDIO) { if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)<0) { sMsg =+ SDL_GetError(); goto _error; } } else { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE | SDL_INIT_JOYSTICK)<0) { sMsg =+ SDL_GetError(); goto _error; } } if (TTF_Init()<0) { sMsg =+ TTF_GetError(); goto _error; } SDLapp = this; SDL_EnableUNICODE(1); SDLcore::Init(); SDLdebug::Init(); return; _error: std::cout << sMsg << std::endl; exit (-1); } SDLapplication::~SDLapplication() { // stop SDL only if it's the last ~SDLapplication call if (SDLapplication::AppCount>1) { SDLapplication::AppCount--; return; } TTF_Quit(); Uint32 sysInit = SDL_WasInit(SDL_INIT_EVERYTHING); // if audio is defined, gb.sdl.audio component still not closed ! if (sysInit & SDL_INIT_AUDIO) SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); else SDL_Quit(); } static int poll_event(SDL_Event *event, bool no_input) { uint mask; SDL_PumpEvents(); mask = SDL_ALLEVENTS; if (no_input) mask ^= SDL_KEYEVENTMASK | SDL_MOUSEEVENTMASK | SDL_JOYEVENTMASK | SDL_QUITMASK; /* We can't return -1, just return 0 (no event) on error */ if ( SDL_PeepEvents(event, 1, SDL_GETEVENT, mask) <= 0 ) return 0; return 1; } void SDLapplication::ManageEvents(bool no_input) { SDL_Event event; while (poll_event(&event, no_input)) { if (!this->HaveWindows()) break; switch(event.type) { case SDL_QUIT: SDLcore::GetWindow()->Quit(); break; case SDL_ACTIVEEVENT: if (event.active.state==SDL_APPINPUTFOCUS) { if (event.active.gain) SDLcore::GetWindow()->GotFocus(); else SDLcore::GetWindow()->LostFocus(); } if (event.active.state==SDL_APPMOUSEFOCUS) { if (event.active.gain) SDLcore::GetWindow()->MouseEnter(); else SDLcore::GetWindow()->MouseLeave(); } break; case SDL_VIDEORESIZE: SDLcore::GetWindow()->SetWidth(event.resize.w); SDLcore::GetWindow()->SetHeight(event.resize.h); SDLcore::GetWindow()->Resize(); // take care if window is closed during resize if (this->HaveWindows()) SDLcore::GetWindow()->Show(); break; case SDL_JOYAXISMOTION: case SDL_JOYHATMOTION: case SDL_JOYBALLMOTION: case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: // Only raise joysticks events if window has input keyboard focus if (SDL_GetAppState() & SDL_APPINPUTFOCUS) SDLcore::GetWindow()->JoyEvent(event); break; case SDL_KEYDOWN: case SDL_KEYUP: SDLcore::GetWindow()->KeyEvent(&event.key, event.type); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: SDLcore::GetWindow()->MouseButtonEvent(&event.button); break; case SDL_MOUSEMOTION: SDLcore::GetWindow()->MouseMotionEvent(&event.motion); break; default: break; } } if (this->HaveWindows()) // take care if window wasn't close during events SDLcore::GetWindow()->Update(); } bool SDLapplication::HaveWindows() { return (SDLcore::GetWindow() ? true : false); } int SDLapplication::DesktopWidth() { LockX11(); int Width = XDisplayWidth(display, DefaultScreen(display)); UnlockX11(); return (Width); } int SDLapplication::DesktopHeight() { LockX11(); int Height = XDisplayHeight(display, DefaultScreen(display)); UnlockX11(); return (Height); } Window SDLapplication::X11appRootWin() { LockX11(); Window win = XDefaultRootWindow(display); UnlockX11(); return (win); } Window SDLapplication::CurrentWin() { LockX11(); // refresh window variable ;) UnlockX11(); return (window); } Display *SDLapplication::X11appDisplay() { LockX11(); // refresh display variable ;) UnlockX11(); return (display); } void SDLapplication::LockX11() { SDLapplication::LockX11Count++; SDL_VERSION(&info.version); SDL_GetWMInfo(&info); if (SDLapplication::LockX11Count==1) info.info.x11.lock_func(); display = info.info.x11.display; window = info.info.x11.window; } void SDLapplication::UnlockX11() { SDLapplication::LockX11Count--; if (SDLapplication::LockX11Count>1) return; SDLapplication::LockX11Count = 0; info.info.x11.unlock_func(); }