266 lines
5.5 KiB
C++
266 lines
5.5 KiB
C++
/***************************************************************************
|
|
|
|
SDLapp.cpp
|
|
|
|
(c) 2006 Laurent Carlier <lordheavy@users.sourceforge.net>
|
|
|
|
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 <iostream>
|
|
#include <string>
|
|
|
|
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();
|
|
}
|
|
|