#ifdef NICE_USELIB_SDL #include #include #include #if defined(Q_WS_X11) #include #endif #include "core/imagedisplay/ImageDisplaySDL.h" using namespace std; namespace NICE { bool ImageDisplaySDL::sdlDisplayActive = false; ImageDisplaySDL::ImageDisplaySDL(QWidget *parent, const char *name) : QWidget(parent, name), screen(NULL), colorImage(NULL) { if (!sdlDisplayActive) { atexit(SDL_Quit); } } ImageDisplaySDL::~ImageDisplaySDL() { if (sdlDisplayActive) { SDL_QuitSubSystem(SDL_INIT_VIDEO); sdlDisplayActive = false; } } void ImageDisplaySDL::resizeEvent(QResizeEvent *) { // is SDL display already usend by another ImageDisplaySDL? if (screen == NULL && sdlDisplayActive) { return; } // We could get a resize event at any time, so clean previous mode screen = NULL; SDL_QuitSubSystem(SDL_INIT_VIDEO); sdlDisplayActive = false; // init SDL, do a little hack to get SDL in this Qt widget char variable[64]; sprintf(variable, "SDL_WINDOWID=0x%lx", winId()); putenv(variable); if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { cerr << "Unable to init SDL: " << SDL_GetError() << endl; return; } // this holds some info about our display const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); // the flags to pass to SDL_SetVideoMode() int videoFlags = 0; int bitDepth = 0; if (videoInfo == NULL) { // FIXME throw an exception cerr << "Video query failed: " << SDL_GetError() << endl; } else { videoFlags = SDL_GL_DOUBLEBUFFER; //#define _OPENGL_ #ifdef _OPENGL_ bitDepth = 32; // use OpenGL videoFlags |= SDL_OPENGL; //videoFlags |= SDL_OPENGLBLIT; // color depth SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bitDepth); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);//Use at least 5 bits of Red SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);//Use at least 5 bits of Green SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);//Use at least 5 bits of Blue SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);//Use at least 16 bits for the depth buffer SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);//Enable double buffering #else bitDepth = 24; #endif videoFlags |= SDL_HWPALETTE; // Store the palette in hardware videoFlags |= SDL_RLEACCEL; // use compression to speedup blit-transfer videoFlags |= SDL_ANYFORMAT; // simply use whatever format the hardware can accomodate videoFlags |= SDL_ASYNCBLIT; //videoFlags |= SDL_RESIZABLE; // Enable window resizing // This checks if hardware blits can be done if (videoInfo->blit_hw) { videoFlags |= SDL_HWACCEL; cerr << "SDL: blit_hw" << endl; } // This checks to see if surfaces can be stored in memory if (videoInfo->hw_available) { videoFlags |= SDL_HWSURFACE; cerr << "SDL: hw_available" << endl; } else { videoFlags |= SDL_SWSURFACE; } } // Set the new video mode with the new window size //screen = SDL_SetVideoMode(width(), height(), 0, 0); screen = SDL_SetVideoMode(width(), height(), bitDepth, videoFlags); if (screen == NULL) { cerr << "Unable to set video mode: " << SDL_GetError() << endl; return; } else { sdlDisplayActive = true; } if (!SDL_WM_ToggleFullScreen(screen)) { cerr << "SDL: SDL_WM_ToggleFullScreen(screen) failed." << endl; } } void ImageDisplaySDL::paintEvent(QPaintEvent *) { #if defined(Q_WS_X11) // Make sure we're not conflicting with drawing from the Qt library XSync(QPaintDevice::x11Display(), FALSE); #endif if (screen != NULL && colorImage != NULL) { // Lock surface if needed // if (SDL_MUSTLOCK(screen)) { // if (SDL_LockSurface(screen) < 0) { // return; // } // } SDL_Surface* sdlImage = SDL_CreateRGBSurfaceFrom(colorImage->getPixelPointer(), colorImage->width(), colorImage->height(), 24, colorImage->getStepsize(), #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0); #else 0xff000000, 0x00ff0000, 0x0000ff00, 0); #endif if (sdlImage) { SDL_Rect dst; dst.x = (screen->w - sdlImage->w) / 2; dst.y = (screen->h - sdlImage->h) / 2; dst.w = sdlImage->w; dst.h = sdlImage->h; SDL_BlitSurface(sdlImage, NULL, screen, &dst); } // Unlock if needed // if (SDL_MUSTLOCK(gScreen)) { // SDL_UnlockSurface(gScreen); // } // Tell SDL to update the whole gScreen //SDL_UpdateRect(screen, 0, 0, m_iWidth, m_iHeight); SDL_Flip(screen); } } void ImageDisplaySDL::setImage(image::ColorImage* _image, const bool copy) { colorImage = _image; resize(colorImage->width(), colorImage->height()); //updateGL(); update(); } } // namespace #else // NICE_USELIB_SDL #include "core/imagedisplay/ImageDisplaySDL.h" namespace NICE { bool ImageDisplaySDL::sdlDisplayActive = false; ImageDisplaySDL::ImageDisplaySDL(QWidget */*parent*/, const char */*name*/) {} ImageDisplaySDL::~ImageDisplaySDL() {} void ImageDisplaySDL::resizeEvent(QResizeEvent *) {} void ImageDisplaySDL::paintEvent(QPaintEvent *) {} void ImageDisplaySDL::setImage(ColorImage* /*_image*/, const bool /*copy*/) {} } // namespace #endif // NICE_USELIB_SDL