Well, there is a open source system for home automation - Plutohome (
www.plutohome.com). This system can use Nokia770/800 as a control panel -
Orbiter. The Orbiter is based on SDL. So, after some hack it started work on
Nokia (os2005/os2006) but there is a problem. Icons on the Orbiter should
change their color according to some events. Initially they are pink. Using
SDL functionality their color can be changed. It works fine for Debian but
it didn't work for Nokia (either scratchbox emulator or real device). All
icons are pink every time.
I'm not developer. I'm integrator. So, it's difficult for me to understand
where is the problem. Have a look attached files. Maybe you can help me.
Thanks in advanced.
On 2/9/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
Hello,
Could you be more specific what are you trying todo and how? Are you
going through pixelvalues and accessing them? See
surface->format->BytesPerPixel. SDL_GetRGB and SDL_MapRGB should work
allright.
// Tapani
________________________________
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of ext Michael
Stepanov
Sent: 09 February, 2007 11:03
To: [email protected]
Subject: [maemo-developers] Nokia SDL color format for pixels
Hi,
I have a question about SDL realization for Nokia770/800. Does
it use some different format to fill a pixel by some color? Because in
my application SDL is used to change color of icons according to some
conditions. It works fine under Linux (Debian) but it didn't work under
Nokia 770 (I tried for both os2005 and os2006). The color of icon is not
changed. Any ideas why?
Is there some manual about Nokia port of SDL?
Thanks in advance.
--
Cheers,
Michael
--
Cheers,
Michael
/*
OrbiterRenderer_SDL
Copyright (C) 2004 Pluto, Inc., a Florida Corporation
www.plutohome.com
Phone: +1 (877) 758-8648
This program is distributed according to the terms of the Pluto Public License, available at:
http://plutohome.com/index.php?section=public_license
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 Pluto Public License for more details.
*/
#include "OrbiterRenderer_SDL.h"
#include "PlutoUtils/CommonIncludes.h"
#include "PlutoUtils/MultiThreadIncludes.h"
#include "DCE/Logger.h"
#include "SerializeClass/ShapesColors.h"
#include "../../SDL_Helpers/SDL_Defs.h"
#include "../RendererOCG.h"
#include "SDLRendererOCGHelper.h"
#include "pluto_main/Define_Effect.h"
#include "pluto_main/Define_DesignObj.h"
#include "pluto_main/Define_Text.h"
#include "pluto_main/Define_DeviceCategory.h"
#include "Gen_Devices/AllCommandsRequests.h"
#include "DataGrid.h"
#include "SDLGraphic.h"
#include "Splitter/TextWrapper.h"
#include "../ScreenHistory.h"
#include "../Orbiter.h"
#ifdef WIN32
#include "../Win32/MainDialog.h"
#endif
#include "SDL_rotozoom.h"
#include <SDL_ttf.h>
#include <SDL_image.h>
#include <sge.h>
#include <sge_surface.h>
#ifdef WIN32
#include <SDL_syswm.h>
#else
#include <SDL/SDL_syswm.h>
#endif
#if !defined(WIN32) && !defined(BLUETOOTH_DONGLE) && !defined(PROXY_ORBITER)
#include "utilities/linux/transparency/transparency.h"
#include "utilities/linux/wrapper/wrapper_x11.h"
#endif
#if !defined(BLUETOOTH_DONGLE) && !defined(PROXY_ORBITER)
#define USE_ONLY_SCREEN_SURFACE
#endif
#ifdef WINCE
#include "wince.h"
#endif
using namespace DCE;
bool g_bResettingVideoMode;
void *SetVideoModeWatchDogThread(void *p)
{
OrbiterRenderer_SDL *pOrbiterRenderer_SDL = (OrbiterRenderer_SDL *) p;
g_pPlutoLogger->Write(LV_STATUS,"Inside WatchDogThread");
Sleep(2000);
if( g_bResettingVideoMode )
{
g_pPlutoLogger->Write(LV_CRITICAL, "SDL_SetVideoMode hangs on init. Xorg is not initialized yet? Restarting...");
#ifndef WIN32
kill(getpid(), SIGKILL);
#endif
}
return NULL;
}
//-----------------------------------------------------------------------------------------------------
OrbiterRenderer_SDL::OrbiterRenderer_SDL(Orbiter *pOrbiter) : OrbiterRenderer(pOrbiter)
{
m_bRelativeMode = false;
m_pScreenImage = NULL;
}
OrbiterRenderer_SDL::~OrbiterRenderer_SDL()
{
// We need to do this before freeing the surface. It's a repeat of what's in Orbiter's destructor
g_pPlutoLogger->Write(LV_STATUS, "about to free surface");
#ifndef USE_ONLY_SCREEN_SURFACE
SDL_FreeSurface(m_pScreenImage);
#endif
m_pScreenImage = NULL;
g_pPlutoLogger->Write(LV_STATUS, "~OrbiterRenderer_SDL finished");
}
void OrbiterRenderer_SDL::Configure()
{
/// SDL 2D code, creates the SDL window
//initializing the engine...
Uint32 uSDLInitFlags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
if(m_bFullScreen)
uSDLInitFlags |= SDL_FULLSCREEN;
if (SDL_Init(uSDLInitFlags) == -1)
{
#ifndef WINCE
cerr << "Failed initializing SDL: " << SDL_GetError() << endl;
#else
printf("Failed to initialize SDL %s\n", SDL_GetError());
#endif //WINCE
#ifndef WIN32 //linux
string sCmd = "/usr/pluto/bin/Start_X.sh";//; /usr/pluto/bin/Start_WM.sh";
g_pPlutoLogger->Write(LV_CRITICAL, "X is not running! Starting X and the window manager: %s", sCmd.c_str());
system(sCmd.c_str());
#endif //linux
exit(1);
}
if (TTF_Init() == -1)
{
#ifndef WINCE
cout << "Failed to init SDL TTF: " << TTF_GetError() << "\nText won't be rendered" << endl;
#endif
}
SDL_WM_SetCaption("OrbiterRenderer_SDL", "OrbiterRenderer_SDL");
atexit(SDL_Quit);
g_pPlutoLogger->Write(LV_STATUS, "Initialized SDL");
#ifdef USE_ONLY_SCREEN_SURFACE
Uint32 uVideoModeFlags = SDL_SWSURFACE | SDL_RESIZABLE;
#if !defined(WIN32) || defined(WINCE)
if(m_bFullScreen)
uVideoModeFlags |= SDL_FULLSCREEN;
#endif
g_bResettingVideoMode=true;
pthread_t hackthread;
pthread_create(&hackthread, NULL, SetVideoModeWatchDogThread, (void*)this);
Screen = SDL_SetVideoMode(OrbiterLogic()->m_iImageWidth, OrbiterLogic()->m_iImageHeight, 0, uVideoModeFlags);
if (Screen == NULL)
{
g_pPlutoLogger->Write(LV_WARNING, "Failed to set video mode (%d x %d): %s", OrbiterLogic()->m_iImageWidth, OrbiterLogic()->m_iImageHeight, SDL_GetError());
exit(1);
}
g_bResettingVideoMode=false;
InitializeAfterSetVideoMode();
SetupWindow();
#endif
g_pPlutoLogger->Write(LV_STATUS, "Set video mode to %d x %d Window.", OrbiterLogic()->m_iImageWidth, OrbiterLogic()->m_iImageHeight);
#ifdef USE_ONLY_SCREEN_SURFACE
m_pScreenImage = Screen;
#else
m_pScreenImage = SDL_CreateRGBSurface(SDL_SWSURFACE, OrbiterLogic()->m_iImageWidth, OrbiterLogic()->m_iImageHeight, 32, rmask, gmask, bmask, amask);
if (m_pScreenImage == NULL)
{
g_pPlutoLogger->Write(LV_WARNING, "SDL_CreateRGBSurface failed! %s",SDL_GetError());
}
#endif
OrbiterLogic()->m_bWeCanRepeat = true;
g_pPlutoLogger->Write(LV_STATUS, "Created back screen surface!");
// we will use the per-pixel transparency
//SetOrbiterWindowTransparency(0.5);
}
//----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::SetOrbiterWindowTransparency(double TransparencyLevel)
{
// FIXME: we shold go until we find the root window
// FIXME: use GetMainWindow(), to avoid duplicate code
#if !defined(WIN32) && !defined(BLUETOOTH_DONGLE) && !defined(PROXY_ORBITER)
X11_Locker_NewDisplay locker_NewDisplay;
SDL_SysWMinfo info;
SDL_VERSION(&info.version); // this is important!
bool bResult = SDL_GetWMInfo(&info);
if (bResult == false)
{
g_pPlutoLogger->Write(LV_WARNING, "OrbiterRenderer_SDL(): error in SDL_GetWMInfo()");
}
Window parent = GetParentWnd( info.info.x11.display, info.info.x11.window );
Window grandparent = GetParentWnd( info.info.x11.display, parent );
Window ggrandparent = GetParentWnd( info.info.x11.display, grandparent );
g_pPlutoLogger->Write(LV_STATUS, "OrbiterRenderer_SDL(): setting transparency");
SetWindowTransparency(locker_NewDisplay.GetDisplay(), info.info.x11.window, TransparencyLevel);
SetWindowTransparency(locker_NewDisplay.GetDisplay(), parent, TransparencyLevel);
SetWindowTransparency(locker_NewDisplay.GetDisplay(), grandparent, TransparencyLevel);
SetWindowTransparency(locker_NewDisplay.GetDisplay(), ggrandparent, TransparencyLevel);
#endif
}
//----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::RenderScreen( bool bRenderGraphicsOnly )
{
#ifdef DEBUG
g_pPlutoLogger->Write(LV_STATUS,"$$$ RENDER SCREEN $$$ %s",
(OrbiterLogic()->m_pScreenHistory_Current ? OrbiterLogic()->m_pScreenHistory_Current->GetObj()->m_ObjectID.c_str() : " NO SCREEN"));
#endif
if (OrbiterLogic()->m_pScreenHistory_Current)
{
PLUTO_SAFETY_LOCK(cm, OrbiterLogic()->m_ScreenMutex);
LockDisplay();
SDL_FillRect(m_pScreenImage, NULL, SDL_MapRGBA(m_pScreenImage->format, 0, 0, 0, 255));
UnlockDisplay();
}
OrbiterRenderer::RenderScreen(bRenderGraphicsOnly);
DisplayImageOnScreen(m_pScreenImage);
}
//----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::DisplayImageOnScreen(SDL_Surface *m_pScreenImage)
{
if(OrbiterLogic()->m_bQuit_get())
return;
PLUTO_SAFETY_LOCK(cm,OrbiterLogic()->m_ScreenMutex);
LockDisplay();
#ifndef USE_ONLY_SCREEN_SURFACE
SDL_BlitSurface(m_pScreenImage, NULL, Screen, NULL);
#endif
SDL_UpdateRect(Screen, 0, 0, 0, 0);
UnlockDisplay();
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::RenderText(string &TextToDisplay,DesignObjText *Text,TextStyle *pTextStyle,
PlutoPoint point, string ObjectID)
{
PLUTO_SAFETY_LOCK(cm,OrbiterLogic()->m_ScreenMutex);
SDL_Rect TextLocation;
TextLocation.x = point.X + Text->m_rPosition.X;
TextLocation.y = point.Y + Text->m_rPosition.Y;
TextLocation.w = Text->m_rPosition.Width;
TextLocation.h = Text->m_rPosition.Height;
#ifdef WIN32
#ifdef WINCE
string BasePath = "C:\\Windows\\Fonts\\";
#else
char pWindowsDirector[MAX_PATH];
GetWindowsDirectory(pWindowsDirector, MAX_PATH);
string BasePath = string(pWindowsDirector) + "\\Fonts\\";
#endif
#else
string BasePath="/usr/share/fonts/truetype/msttcorefonts/";
#endif //win32
WrapAndRenderText(m_pScreenImage, TextToDisplay, TextLocation.x, TextLocation.y, TextLocation.w, TextLocation.h, BasePath,
pTextStyle,Text->m_iPK_HorizAlignment,Text->m_iPK_VertAlignment, &OrbiterLogic()->m_mapTextStyle);
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::HollowRectangle(int X, int Y, int Width, int Height, PlutoColor color, string ParentObjectID/* = ""*/, string ObjectID/* = ""*/)
{
ClipRectangle(X, Y, Width, Height);
sge_Rect(m_pScreenImage,X,Y,Width + X,Height + Y,color.m_Value);
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::SolidRectangle(int x, int y, int width, int height, PlutoColor color,
string ParentObjectID/* = ""*/,
string ObjectID/* = ""*/)
{
ClipRectangle(x, y, width, height);
SDL_Rect Rectangle;
Rectangle.x = x; Rectangle.y = y; Rectangle.w = width; Rectangle.h = height;
if(color.A() < 255)
{
SDL_Rect rectBar;
rectBar.x = 0; rectBar.y = 0; rectBar.w = width; rectBar.h = height;
SDL_Surface *pSDL_Bar = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, rectBar.w, rectBar.h, 32, rmask, gmask, bmask, amask);
SDL_FillRect(pSDL_Bar, &rectBar, SDL_MapRGBA(pSDL_Bar->format, color.R(), color.G(), color.B(), color.A()));
LockDisplay();
SDL_BlitSurface(pSDL_Bar, NULL, m_pScreenImage, &Rectangle);
UnlockDisplay();
SDL_FreeSurface(pSDL_Bar);
}
else
{
LockDisplay();
SDL_FillRect(m_pScreenImage, &Rectangle, SDL_MapRGBA(m_pScreenImage->format, color.R(), color.G(), color.B(), color.A()));
UnlockDisplay();
}
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::RenderGraphic(class PlutoGraphic *pPlutoGraphic,
PlutoRectangle rectTotal, bool bDisableAspectRatio, PlutoPoint point/* = PlutoPoint(0, 0)*/,
int nAlphaChannel/* = 255*/, string ParentObjectID/* = ""*/, string ObjectID/* = ""*/,
string ObjectHash/* = ""*/)
{
if(!pPlutoGraphic || pPlutoGraphic->GraphicType_get() != gtSDLGraphic)
return;//nothing to render or not an sdl graphic
if(pPlutoGraphic->IsEmpty())
return;
SDLGraphic *pSDLGraphic = (SDLGraphic *) pPlutoGraphic;
SDL_Surface *pSDL_Surface = pSDLGraphic->m_pSDL_Surface;
//render the sdl surface
SDL_Rect Destination;
Destination.x = point.X + rectTotal.X;
Destination.y = point.Y + rectTotal.Y;
Destination.w = rectTotal.Width;
Destination.h = rectTotal.Height;
if(pSDL_Surface->w == 0 || pSDL_Surface->h == 0) //nothing to render
return; //malformated image?
else
if(pSDL_Surface->w != rectTotal.Width || pSDL_Surface->h != rectTotal.Height) //different size. we'll have to stretch the surface
{
double ZoomX = 1;
double ZoomY = 1;
SDL_Surface *rotozoom_picture;
if(bDisableAspectRatio) //no aspect ratio kept
{
ZoomX = rectTotal.Width / double(pSDL_Surface->w);
ZoomY = rectTotal.Height / double(pSDL_Surface->h);
}
else //we'll have to keep the aspect
{
ZoomX = ZoomY = min(rectTotal.Width / double(pSDL_Surface->w),
rectTotal.Height / double(pSDL_Surface->h));
}
rotozoom_picture = zoomSurface(pSDL_Surface, ZoomX, ZoomY, SMOOTHING_ON);
LockDisplay();
SDL_BlitSurface(rotozoom_picture, NULL, m_pScreenImage, &Destination);
SDL_FreeSurface(rotozoom_picture);
UnlockDisplay();
}
else //same size ... just blit the surface
{
LockDisplay();
SDL_BlitSurface(pSDL_Surface, NULL, m_pScreenImage, &Destination);
UnlockDisplay();
}
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::SaveBackgroundForDeselect(DesignObj_Orbiter *pObj, PlutoPoint point)
{
SDL_Rect SourceRect;
SourceRect.x = point.X + pObj->m_rPosition.Left(); SourceRect.y = point.Y + pObj->m_rPosition.Top();
SourceRect.w = pObj->m_rPosition.Width; SourceRect.h = pObj->m_rPosition.Height;
SDL_Surface *pSDL_Surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
pObj->m_rPosition.Width, pObj->m_rPosition.Height, 32, rmask, gmask, bmask, amask);
LockDisplay();
SDL_BlitSurface(m_pScreenImage, &SourceRect, pSDL_Surface, NULL);
SDL_SetAlpha(pSDL_Surface, SDL_RLEACCEL , SDL_ALPHA_OPAQUE);
UnlockDisplay();
pObj->m_pGraphicToUndoSelect = new SDLGraphic(pSDL_Surface);
}
//-----------------------------------------------------------------------------------------------------
PlutoGraphic *OrbiterRenderer_SDL::GetBackground( PlutoRectangle &rect )
{
ClipRectangle(rect);
SDL_Surface *pSDL_Surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
rect.Width, rect.Height, 32, rmask, gmask, bmask, amask);
SDL_Rect SourceRect;
SourceRect.x = rect.Left(); SourceRect.y = rect.Top();
SourceRect.w = rect.Width; SourceRect.h = rect.Height;
LockDisplay();
SDL_SetAlpha(m_pScreenImage, 0, 0);
SDL_BlitSurface(m_pScreenImage, &SourceRect, pSDL_Surface, NULL);
UnlockDisplay();
return new SDLGraphic(pSDL_Surface);
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::ReplaceColorInRectangle(int x, int y, int width, int height, PlutoColor ColorToReplace, PlutoColor ReplacementColor, DesignObj_Orbiter *pObj/* = NULL*/)
{
SDL_PixelFormat * PF = m_pScreenImage->format;
Uint32 PlutoPixelDest, PlutoPixelSrc, Pixel;
#ifdef DEBUG
g_pPlutoLogger->Write(LV_STATUS, "ReplaceColor: %u %u %u : %u %u %u",
ColorToReplace.R(), ColorToReplace.G(), ColorToReplace.B(),
ReplacementColor.R(), ReplacementColor.G(), ReplacementColor.B());
#endif
PlutoPixelSrc = (ColorToReplace.R() << PF->Rshift) | (ColorToReplace.G() << PF->Gshift) | (ColorToReplace.B() << PF->Bshift) | (ColorToReplace.A() << PF->Ashift);
unsigned char *Source = (unsigned char *) &PlutoPixelSrc;
PlutoPixelDest = ReplacementColor.R() << PF->Rshift | ReplacementColor.G() << PF->Gshift | ReplacementColor.B() << PF->Bshift;// TODO -- this should work | ReplacementColor.A() << PF->Ashift;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i++)
{
// we may need locking on the surface
Pixel = SDLGraphic::getpixel(m_pScreenImage, i + x, j + y);
unsigned char *pPixel = (unsigned char *) &Pixel;
const int max_diff = 3;
if ( abs(Source[0]-pPixel[0])<max_diff && abs(Source[1]-pPixel[1])<max_diff && abs(Source[2]-pPixel[2])<max_diff && abs(Source[3]-pPixel[3])<max_diff )
{
SDLGraphic::putpixel(m_pScreenImage,i + x, j + y, PlutoPixelDest);
}
}
}
PlutoRectangle rect(x, y, width, height);
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::BeginPaint()
{
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::EndPaint()
{
//if we are using a buffer surface to blit images and text (Bluetooth_Dongle uses this)
//will have to update the hole screen
//if not, the user will call UpdateRect function for each rectangle he must invalidate
#ifndef USE_ONLY_SCREEN_SURFACE
DisplayImageOnScreen(m_pScreenImage);
#endif
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::OnQuit()
{
g_pPlutoLogger->Write(LV_WARNING,"Got an on quit. Pushing an event into SDL");
SDL_Event *pEvent = new SDL_Event;
pEvent->type = SDL_QUIT;
SDL_PushEvent(pEvent);
delete pEvent;
}
//-----------------------------------------------------------------------------------------------------
PlutoGraphic *OrbiterRenderer_SDL::CreateGraphic()
{
return new SDLGraphic(this);
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::UpdateRect(PlutoRectangle rect, PlutoPoint point)
{
//clipping the rectangle
PlutoRectangle localrect = rect;
localrect.X += point.X;
localrect.Y += point.Y;
ClipRectangle(localrect);
#ifdef USE_ONLY_SCREEN_SURFACE
PLUTO_SAFETY_LOCK(cm,OrbiterLogic()->m_ScreenMutex);
LockDisplay();
SDL_UpdateRect(Screen, localrect.Left(), localrect.Top(), localrect.Width, localrect.Height);
UnlockDisplay();
#endif
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::OnIdle()
{
Sleep(5);
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::EventLoop()
{
int SDL_Event_Pending = 0;
SDL_Event Event;
// For now I'll assume that shift + arrows scrolls a grid
while (!OrbiterLogic()->m_bQuit_get()&& !OrbiterLogic()->m_bReload)
{
LockDisplay();
SDL_Event_Pending = SDL_PollEvent(&Event);
UnlockDisplay();
if (SDL_Event_Pending)
{
Orbiter::Event orbiterEvent;
orbiterEvent.type = Orbiter::Event::NOT_PROCESSED;
if (Event.type == SDL_QUIT)
{
g_pPlutoLogger->Write(LV_WARNING, "Received sdl event SDL_QUIT");
break;
}
else if(Event.type == SDL_MOUSEMOTION)
{
if (m_bRelativeMode)
{
orbiterEvent.type = Orbiter::Event::MOUSE_RELATIVE_MOVE;
orbiterEvent.data.region.m_iX = Event.motion.xrel;
orbiterEvent.data.region.m_iY = Event.motion.yrel;
}
else
{
orbiterEvent.type = Orbiter::Event::MOUSE_MOVE;
orbiterEvent.data.region.m_iX = Event.button.x;
orbiterEvent.data.region.m_iY = Event.button.y;
}
orbiterEvent.data.region.m_iButton = Event.button.button;
OrbiterLogic()->ProcessEvent(orbiterEvent);
}
else if (Event.type == SDL_MOUSEBUTTONDOWN)
{
orbiterEvent.type = Orbiter::Event::REGION_DOWN;
orbiterEvent.data.region.m_iX = Event.button.x;
orbiterEvent.data.region.m_iY = Event.button.y;
orbiterEvent.data.region.m_iButton = Event.button.button;
OrbiterLogic()->ProcessEvent(orbiterEvent);
#if defined(WIN32) && !defined(PROXY_ORBITER) && !defined(BLUETOOTH_DONGLE)
RecordMouseAction(Event.button.x, Event.button.y);
#endif
}
else if (Event.type == SDL_MOUSEBUTTONUP)
{
orbiterEvent.type = Orbiter::Event::REGION_UP;
orbiterEvent.data.region.m_iX = Event.button.x;
orbiterEvent.data.region.m_iY = Event.button.y;
orbiterEvent.data.region.m_iButton = Event.button.button;
OrbiterLogic()->ProcessEvent(orbiterEvent);
}
}
else
{
OnIdle();
}
} // while
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::CaptureRelativeMovements()
{
// ERROR:
//
// this function does not return
// it will causes the mouse to vanish (only if SDL_WM_GrabInput returns)
// if SDL_WM_GrabInput returns, then usually SDL_ShowCursor does not return
// the mouse will not appear again because this thread will be
// blocked, so no one will release the mouse-movements
//
// Other notes:
// SDL is not fair here
// it opens a new display and probably new window
// it also installs his error handler, overriding our handler
// in this case X11 will use that bad handler
// and will not stop the app
if (0)
{
g_pPlutoLogger->Write(LV_STATUS,"OrbiterRenderer_SDL::CaptureRelativeMovements()");
m_bRelativeMode = true;
//#ifndef WIN32 // linux
// // sample code
// if (OrbiterLogic()->IsYieldScreen())
// {
// GrabPointer(false);
// GrabKeyboard(false);
// }
// // sample code
//#endif
// warning: incompatible with constrain-mouse in linux
// both keyboard and mouse
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE);
g_pPlutoLogger->Write(LV_STATUS,"OrbiterRenderer_SDL::CaptureRelativeMovements() : done");
}
}
//-----------------------------------------------------------------------------------------------------
void OrbiterRenderer_SDL::ReleaseRelativeMovements()
{
// CaptureRelativeMovements() was deactivated above
if (0)
{
g_pPlutoLogger->Write(LV_STATUS,"OrbiterRenderer_SDL::ReleaseRelativeMovements()");
m_bRelativeMode = false;
// warning: incompatible with constrain-mouse in linux
// both keyboard and mouse
SDL_WM_GrabInput(SDL_GRAB_OFF);
//#ifndef WIN32 // linux
// // sample code
// if (OrbiterLogic()->IsYieldScreen())
// {
// GrabPointer(true);
// GrabKeyboard(true);
// }
// // sample code
//#endif
SDL_ShowCursor(SDL_ENABLE);
g_pPlutoLogger->Write(LV_STATUS,"OrbiterRenderer_SDL::ReleaseRelativeMovements() : done");
}
}
//-----------------------------------------------------------------------------------------------------
#include "SDLGraphic.h"
#include "Logger.h"
#include "SDL_rotozoom.h"
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#include <sge.h>
#include <sge_surface.h>
#include "SDLRendererOCGHelper.h"
#include "../../SDL_Helpers/SDL_Defs.h"
#include "../OrbiterRenderer.h"
#include "../Orbiter.h"
using namespace DCE;
//-------------------------------------------------------------------------------------------------------
SDLGraphic::SDLGraphic(string Filename, eGraphicManagement GraphicManagement,
OrbiterRenderer *pOrbiterRenderer)
: PlutoGraphic(Filename, GraphicManagement, pOrbiterRenderer)
{
Initialize();
}
//-------------------------------------------------------------------------------------------------------
SDLGraphic::SDLGraphic(OrbiterRenderer *pOrbiterRenderer)
: PlutoGraphic(pOrbiterRenderer)
{
Initialize();
}
//-------------------------------------------------------------------------------------------------------
SDLGraphic::SDLGraphic(struct SDL_Surface *pSDL_Surface)
{
Initialize();
m_pSDL_Surface = pSDL_Surface;
if (m_pSDL_Surface == NULL)
{
g_pPlutoLogger->Write(LV_CRITICAL,"SDLGraphic::SDLGraphic() : NULL m_pSDL_Surface");
return;
}
Width = m_pSDL_Surface->w;
Height = m_pSDL_Surface->h;
}
//-------------------------------------------------------------------------------------------------------
SDLGraphic::~SDLGraphic()
{
Clear();
}
//-------------------------------------------------------------------------------------------------------
void SDLGraphic::Initialize()
{
m_pSDL_Surface = NULL;
}
//-------------------------------------------------------------------------------------------------------
bool SDLGraphic::LoadGraphic(char *pData, size_t iSize,int iRotation)
{
if(m_GraphicFormat == GR_OCG)
{
string sErrorMessage =
"Cannot load OCG files in Orbiter SDL. "
"Please uncheck 'Use OCG' device data for this device (" +
StringUtils::ltos(m_pOrbiterRenderer->OrbiterLogic()->m_dwPK_Device) + ").";
g_pPlutoLogger->Write(LV_CRITICAL, sErrorMessage.c_str());
m_pOrbiterRenderer->PromptUser(sErrorMessage.c_str(), 100);
exit(1);
return false;
}
else
{
SDL_RWops * rw = SDL_RWFromMem(pData, int(iSize));
m_pSDL_Surface = IMG_Load_RW(rw, 1); // rw is freed here
}
if( !m_pSDL_Surface )
{
g_pPlutoLogger->Write(LV_CRITICAL, "Unable to read sdl graphic from data %p with size %d", pData, iSize);
return false;
}
if(iRotation)
{
SDL_Surface *pSourceSurface = m_pSDL_Surface;
m_pSDL_Surface = rotozoomSurface(pSourceSurface, iRotation, 1, SMOOTHING_ON);
SDL_FreeSurface(pSourceSurface);
}
Width = m_pSDL_Surface->w;
Height = m_pSDL_Surface->h;
return true;
}
//-------------------------------------------------------------------------------------------------------
void SDLGraphic::Clear()
{
if (m_pSDL_Surface)
{
SDL_FreeSurface(m_pSDL_Surface);
m_pSDL_Surface = NULL;
}
}
//-------------------------------------------------------------------------------------------------------
PlutoGraphic *SDLGraphic::GetHighlightedVersion()
{
if (m_pSDL_Surface == NULL)
{
g_pPlutoLogger->Write(LV_CRITICAL,"SDLGraphic::GetHighlightedVersion() : NULL m_pSDL_Surface");
return NULL;
}
if( m_pSDL_Surface->format->BytesPerPixel!=4 )
return NULL;
SDL_Surface *pSDL_Surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
Width, Height, 32, rmask, gmask, bmask, amask);
SDL_Rect SourceRect;
SourceRect.x = 0; SourceRect.y = 0;
SourceRect.w = Width; SourceRect.h = Height;
SDL_SetAlpha(m_pSDL_Surface, 0, 0);
for(int w=0;w<Width;w++)
{
for(int h=0;h<Height;h++)
{
unsigned char *pS = (unsigned char *) m_pSDL_Surface->pixels + h * m_pSDL_Surface->pitch + w * 4;
unsigned char *pD = (unsigned char *) pSDL_Surface->pixels + h * pSDL_Surface->pitch + w * 4;
pD[0] = min(255,pS[0] + 30);
pD[1] = min(255,pS[1] + 30);
pD[2] = min(255,pS[2] + 30);
pD[3] = 255;
}
}
return new SDLGraphic(pSDL_Surface);
}
//-----------------------------------------------------------------------------------------------------
Uint32 SDLGraphic::getpixel(SDL_Surface *pSDL_Surface,int x, int y)
{
// all pixels outside the pSDL_Surface are black
if (x < 0 || x >= pSDL_Surface->w || y < 0 || y >= pSDL_Surface->h)
return SDL_MapRGB(pSDL_Surface->format, 0, 0, 0);
int bpp = pSDL_Surface->format->BytesPerPixel;
Uint8 * pixel = (Uint8 *) pSDL_Surface->pixels + y * pSDL_Surface->pitch + x * bpp;
switch(bpp)
{
case 1:
return * pixel;
case 2:
return * (Uint16 *) pixel;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return pixel[0] << 16 | pixel[1] << 8 | pixel[2];
else
return pixel[0] | pixel[1] << 8 | pixel[2] << 16;
case 4:
return * (Uint32 *) pixel;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}
//-----------------------------------------------------------------------------------------------------
void SDLGraphic::putpixel(SDL_Surface *pSDL_Surface,int x, int y, Uint32 pixel_color)
{
// don't try to put a pixel outside the pSDL_Surface
if (x < 0 || x >= pSDL_Surface->w || y < 0 || y >= pSDL_Surface->h)
return;
int bpp = pSDL_Surface->format->BytesPerPixel;
Uint8 * pixel = (Uint8 *) pSDL_Surface->pixels + y * pSDL_Surface->pitch + x * bpp;
switch(bpp)
{
case 1:
* pixel = pixel_color;
break;
case 2:
* (Uint16 *) pixel = pixel_color;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
pixel[0] = (pixel_color >> 16) & 0xff;
pixel[1] = (pixel_color >> 8) & 0xff;
pixel[2] = pixel_color & 0xff;
}
else
{
pixel[0] = pixel_color & 0xff;
pixel[1] = (pixel_color >> 8) & 0xff;
pixel[2] = (pixel_color >> 16) & 0xff;
}
break;
case 4:
* (Uint32 *) pixel = pixel_color | 0xFF000000; //opaque
break;
}
}
PlutoGraphic* SDLGraphic::Clone()
{
SDL_Surface* Surface = SDL_DisplayFormat(this->m_pSDL_Surface);
return new SDLGraphic(Surface);
}
bool SDLGraphic::GetInMemoryBitmap(char*& pRawBitmapData, size_t& ulSize)
{
//TODO : implement me!
pRawBitmapData = NULL;
ulSize = 0;
return false;
}
_______________________________________________
maemo-developers mailing list
[email protected]
https://maemo.org/mailman/listinfo/maemo-developers