From 11fbf1b13a4e4216ad07fb009515cf2eda9ca2e3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 4 Aug 2003 00:52:42 +0000 Subject: [PATCH] Date: Sat, 2 Aug 2003 16:22:51 +0300 From: "Mike Gorchak" Subject: New patches for QNX6 Here my patches for the SDL/QNX: QNXSDL.diff - diff to non-QNX related sources: - updated BUGS file, I think QNX6 is now will be officially supported - configure.in - added shared library support for QNX, and removed dependency between the ALSA and QNX6. - SDL_audio.c - added QNX NTO sound bootstrap insted of ALSA's. - SDL_sysaudio.h - the same. - SDL_nto_audio.c - the same. - SDL_video.c - right now, QNX doesn't offer any method to obtain pointers to the OpenGL functions by function name, so they must be hardcoded in library, otherwise OpenGL will not be supported. - testsprite.c - fixed: do not draw vertical red line if we are in non-double-buffered mode. sdlqnxph.tar.gz - archive of the ./src/video/photon/* . Too many changes in code to make diffs :) : + Added stub for support hide/unhide window event + Added full YUV overlays support. + Added window maximize support. + Added mouse wheel events. + Added support for some specific key codes in Unicode mode (like ESC). + Added more checks to the all memory allocation code. + Added SDL_DOUBLEBUF support in all fullscreen modes. + Added fallback to window mode, if desired fullscreen mode is not supported. + Added stub support for the GL_LoadLibrary and GL_GetProcAddress functions. + Added resizable window support without caption. ! Fixed bug in the Ph_EV_EXPOSE event handler, when rectangles to update is 0 and when width or height of the rectangle is 0. ! Fixed bug in the event handler code. Events has not been passed to the window widget handler. ! Fixed codes for Win keys (Super/Hyper/Menu). ! Fixed memory leak, when deallocation palette. ! Fixed palette emulation code bugs. ! Fixed fullscreen and hwsurface handling. ! Fixed CLOSE button bug. First event was passed to the handler, but second terminated the application. Now all events passed to the application correctly. - Removed all printfs in code, now SDL_SetError used instead of them. - Disabled ToggleFullScreen function. README.QNX - updated README.QNX file. Added much more issues. --- BUGS | 11 +- README.QNX | 104 +++++++++-- configure.in | 3 + src/audio/SDL_audio.c | 3 + src/audio/SDL_sysaudio.h | 3 + src/audio/nto/SDL_nto_audio.c | 6 +- src/video/SDL_video.c | 4 + src/video/photon/SDL_ph_events.c | 163 ++++++++++++++---- src/video/photon/SDL_ph_image.c | 264 +++++++++++++++------------- src/video/photon/SDL_ph_image_c.h | 1 + src/video/photon/SDL_ph_modes.c | 243 +++++++++++++++----------- src/video/photon/SDL_ph_modes_c.h | 4 +- src/video/photon/SDL_ph_mouse.c | 17 +- src/video/photon/SDL_ph_video.c | 278 +++++++++++++++++------------- src/video/photon/SDL_ph_video.h | 51 +++--- src/video/photon/SDL_ph_wm.c | 5 +- src/video/photon/SDL_phyuv.c | 270 +++++++++++++++++------------ src/video/photon/SDL_phyuv_c.h | 36 +++- test/testsprite.c | 24 +-- 19 files changed, 928 insertions(+), 562 deletions(-) diff --git a/BUGS b/BUGS index 6b775e80d..f10c6f70f 100644 --- a/BUGS +++ b/BUGS @@ -141,6 +141,10 @@ EPOC: No console output screen. Printing to stdout do not have any effect. +QNX: + Fullscreen switch doesn't work correctly. + + OpenBSD: -= NOT YET SUPPORTED =- This is reported to work, but I haven't verified this. @@ -183,13 +187,6 @@ AIX: -= NOT YET SUPPORTED =- More information on this port is available at: http://www.kom.e-technik.tu-darmstadt.de/~griff/SDL/ -QNX: -= NOT YET SUPPORTED =- - Only static libraries are being made, no shared ones. - - The only hardware surface is the primary view surface. - - Fullscreen doesn't display correctly. - AmigaOS: -= NOT YET SUPPORTED =- The OpenGL support isn't implemented yet. diff --git a/README.QNX b/README.QNX index f227ca951..66102c84d 100644 --- a/README.QNX +++ b/README.QNX @@ -1,27 +1,94 @@ README by Mike Gorchak , +Last changed at 29 Jul 2003. + +========================================================================= +OpenGL: OpenGL in window mode works well and stable, in fullscreen -mode too, but fullscreen mode has not been heavily tested. - If you have QNX RtP 6.1.0 w/ or w/o Patch A you must download -new Photon3D runtime from http://developers.qnx.com. The versions -of OS before 6.1.0 are not supported. - -Problems: -1. While creating OpenGL context software renderer mode is - artificially selected (QSSL made acceleration only for Voodoo - boards in fullscreen mode, sorry but I don't have this board, - if you want acceleration - you may remove some line in source - code). -2. Photon has some errors in detecting how much bits per pixel - videomode has. -3. No shared libraries yet. We need manually set flag to - 'configure' --disable-shared. -4. Due to Photon API limitation, flag SDL_HWSURFACE supported on- - ly in case of desktop bpp is equal requested bpp in window mo- - de. +mode too, but fullscreen mode has not been heavily tested yet. + If you have QNX RtP version 6.1.0 and above you must download +new Photon3D runtime from http://developers.qnx.com or install it +from public repository or from public CD, available with QNX. The +versions of OS before 6.1.0 are not supported. + While creating OpenGL context software renderer mode is +artificially selected (QSSL made acceleration only for Voodoo +boards in fullscreen mode, sorry but I don't have this board to +test OpenGL - maybe it work or maybe not :)). If you want accele- +ration - you may remove some line in source code: find the file +SDL_ph_video.c and remove the following + + OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FORCE_SW; + +line in the ph_SetupOpenGLContext() function or change argument +to the PHOGL_ATTRIB_FORCE_HW or PHOGL_ATTRIB_FAVOR_HW. + +========================================================================= +Wheel and multibutton mouses: + + Photon emitting keyboard events (key up and down) when moved +mouse wheel. But key_scan field appears valid according to flags, +and it contain zero. It is base method of detecting mouse wheel +events under photon. It looks like a hack, but it works for me :) +on different PC configurations. + +I'm tested it on: + +1. Genius Optical NetScroll/+ (1 wheel) +2. A4Tech Optical GreatEye WheelMouse, model: WOP-35. (2 wheels + + 2 additional buttons). Wheel for vertical scrolling works as + usual, but second wheel for horizontal scrolling emitting two + consequented events up or down, so it can provide more fast + scrolling then the first wheel. Additional buttons doesn't + emitting any events, but its look like handled by photon in + unusual way - like click to front, but works not with any win- + dow, looks like bug-o-feature :). + +========================================================================= +CDROM handling issues: + Access to CDROM can be provided only with 'root' previleges. +I can't do anything with this fact. /dev/cd0 have the brw------- +flags and root:root rights. + +========================================================================= +Video Overlays: + + Overlays can flickering during the window movement, resizing, +etc. It happens because photon driver updates the real window +contents behind the overlay, then draws the temporary chroma key +color over window contents. It can be done without the chroma key +using but it cause overlay will be always on top. So flickering +during the movement much better in that case. + Double buffering code temporary disabled in the photon driver +code, beacuse on my GF2-MX it cause accidently buffer switch, +which going to the old frame showing. S3 Savage3D have the same +problem, but ATI Rage 128 has not this problem. I think it can be +fixed later. Current code works very fine, so maybe double buffe- +ring is not needed right now. + Something strange appears when you tried to move window with +overlay beyond the left border of the screen. Overlay trying to +stay at position x=0, but when tried to move it a bit more it +jumps at posituin x=-60. Really strange, looks like overlay +doesn't love the negotive coordinates. + +========================================================================= +Shared library building: + + Shared library can be built, but before running autogen.sh +script you need manually delete the libtool m4 stuff from +the acinclude.m4 file (it comes after ESD detection code up to +end of the file). Because libtool stuff in the acinclude.m4 file +very old and doesn't know anything about the QNX. Just remove it +and run autogen.sh script. + +========================================================================= Some building issues: + Feel free to not pass --disable-shared option to configure, +if you read comment above about 'Shared library building'. Other- +wise this option is strongly recomended, because the sdl-config +script will be unfunctional. + Run configure script without x11 support, e.g.: a) for OpenGL support: @@ -42,3 +109,4 @@ support, e.g.: --with-sdl-exec-prefix=/usr/local \ --prefix=/usr/local --without-x + diff --git a/configure.in b/configure.in index 47a2eb77f..ff3929804 100644 --- a/configure.in +++ b/configure.in @@ -2531,6 +2531,9 @@ case "$ARCH" in openbsd | netbsd | bsdi) SHARED_SYSTEM_LIBS="$SYSTEM_LIBS" ;; + qnx) + SHARED_SYSTEM_LIBS="$SYSTEM_LIBS" + ;; macosx) SHARED_SYSTEM_LIBS="-framework Cocoa" if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index d18dbc135..a22338043 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -50,6 +50,9 @@ static AudioBootStrap *bootstrap[] = { #ifdef ALSA_SUPPORT &ALSA_bootstrap, #endif +#ifdef QNXNTOAUDIO_SUPPORT + &QNXNTOAUDIO_bootstrap, +#endif #ifdef SUNAUDIO_SUPPORT &SUNAUDIO_bootstrap, #endif diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 654ce81b8..a8a7503cd 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -114,6 +114,9 @@ extern AudioBootStrap DMA_bootstrap; #ifdef ALSA_SUPPORT extern AudioBootStrap ALSA_bootstrap; #endif +#ifdef QNXNTOAUDIO_SUPPORT +extern AudioBootStrap QNXNTOAUDIO_bootstrap; +#endif #ifdef SUNAUDIO_SUPPORT extern AudioBootStrap SUNAUDIO_bootstrap; #endif diff --git a/src/audio/nto/SDL_nto_audio.c b/src/audio/nto/SDL_nto_audio.c index eb42c5869..62d9ca684 100644 --- a/src/audio/nto/SDL_nto_audio.c +++ b/src/audio/nto/SDL_nto_audio.c @@ -163,9 +163,8 @@ static SDL_AudioDevice *Audio_CreateDevice(int devindex) return this; } -/* Don't change the name from "ALSA_bootstrap" - that's how it's called */ -AudioBootStrap ALSA_bootstrap = { - DRIVER_NAME, "Neutrino PCM audio", +AudioBootStrap QNXNTOAUDIO_bootstrap = { + DRIVER_NAME, "QNX6 NTO PCM audio", Audio_Available, Audio_CreateDevice }; @@ -489,4 +488,3 @@ static int NTO_OpenAudio(_THIS, SDL_AudioSpec *spec) /* We're ready to rock and roll. :-) */ return(0); } - diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 47add9ae7..8a2561f7d 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -727,6 +727,7 @@ SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags) #ifdef HAVE_OPENGL /* Load GL symbols (before MakeCurrent, where we need glGetString). */ if ( flags & (SDL_OPENGL | SDL_OPENGLBLIT) ) { +#ifndef __QNXNTO__ #define SDL_PROC(ret,func,params) \ do { \ video->func = SDL_GL_GetProcAddress(#func); \ @@ -735,6 +736,9 @@ do { \ return(NULL); \ } \ } while ( 0 ); +#else +#define SDL_PROC(ret,func,params) video->func=func; +#endif /* __QNXNTO__ */ #include "SDL_glfuncs.h" #undef SDL_PROC } diff --git a/src/video/photon/SDL_ph_events.c b/src/video/photon/SDL_ph_events.c index ebe627d7a..ed7f2643f 100644 --- a/src/video/photon/SDL_ph_events.c +++ b/src/video/photon/SDL_ph_events.c @@ -29,12 +29,13 @@ static char rcsid = #define DISABLE_X11 -#include #include #include -#include #include +#include +#include + #include "SDL.h" #include "SDL_syswm.h" #include "SDL_sysevents.h" @@ -44,6 +45,8 @@ static char rcsid = #include "SDL_ph_modes_c.h" #include "SDL_ph_image_c.h" #include "SDL_ph_events_c.h" +#include "SDL_phyuv_c.h" + /* The translation tables from a photon keysym to a SDL keysym */ @@ -90,8 +93,8 @@ static void set_motion_sensitivity(_THIS, unsigned int flags) if( window ) { - rid = PtWidgetRid( window ); - if( rid != 0 && PhRegionQuery( rid, ®ion, NULL, NULL, 0 ) == 0 ) + rid = PtWidgetRid(window); + if( rid != 0 && PhRegionQuery(rid, ®ion, NULL, NULL, 0) == 0 ) { region.events_sense=(region.events_sense & ~fields)|(flags & fields); PhRegionChange(Ph_REGION_EV_SENSE, 0, ®ion, NULL, NULL); @@ -114,6 +117,8 @@ static Uint8 ph2sdl_mousebutton(unsigned short button_state) return (mouse_button); } +// void* PtAppCreateContext(); + static int ph_DispatchEvent(_THIS) { int posted; @@ -217,15 +222,56 @@ static int ph_DispatchEvent(_THIS) { posted = SDL_PrivateQuit(); } + /* request to hide/unhide */ + else if (winEvent->event_f==Ph_WM_HIDE) + { + if (currently_hided) + { + /* got unhide window event */ + /* TODO: restore application's palette if in palette mode */ + currently_hided=0; + } + else + { + /* got hide window event */ + /* TODO: restore original palette if in palette mode */ + currently_hided=1; + } + } /* request to resize */ else if (winEvent->event_f==Ph_WM_RESIZE) { SDL_PrivateResize(winEvent->size.w, winEvent->size.h); } + /* request to move */ + else if (winEvent->event_f==Ph_WM_MOVE) + { + if (current_overlay!=NULL) + { + int lockedstate=current_overlay->hwdata->locked; + int chromastate=current_overlay->hwdata->ischromakey; + SDL_Rect target; + + current_overlay->hwdata->locked=1; + target.x=current_overlay->hwdata->CurrentViewPort.pos.x; + target.y=current_overlay->hwdata->CurrentViewPort.pos.y; + target.w=current_overlay->hwdata->CurrentViewPort.size.w; + target.h=current_overlay->hwdata->CurrentViewPort.size.h; + current_overlay->hwdata->ischromakey=0; + ph_DisplayYUVOverlay(this, current_overlay, &target); + current_overlay->hwdata->ischromakey=chromastate; + current_overlay->hwdata->locked=lockedstate; + } + } /* request to maximize */ else if (winEvent->event_f==Ph_WM_MAX) { - /* TODO: get screen resolution, set window pos to 0, 0 and resize it ! */ + /* window already moved and resized here */ + SDL_PrivateResize(winEvent->size.w-winEvent->pos.x, winEvent->size.h-winEvent->pos.y); + } + /* request to restore */ + else if (winEvent->event_f==Ph_WM_RESTORE) + { } } break; @@ -233,19 +279,38 @@ static int ph_DispatchEvent(_THIS) /* window has been resized, moved or removed */ case Ph_EV_EXPOSE: { - if (SDL_VideoSurface) + if (event->num_rects!=0) { - rect = PhGetRects(event); - - for(i=0;inum_rects;i++) + if (SDL_VideoSurface) { - sdlrects[i].x = rect[i].ul.x; - sdlrects[i].y = rect[i].ul.y; - sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1; - sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1; + rect = PhGetRects(event); + + for(i=0;inum_rects;i++) + { + sdlrects[i].x = rect[i].ul.x; + sdlrects[i].y = rect[i].ul.y; + sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1; + sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1; + } + + this->UpdateRects(this, event->num_rects, sdlrects); + + if (current_overlay!=NULL) + { + int lockedstate=current_overlay->hwdata->locked; + SDL_Rect target; + + current_overlay->hwdata->locked=1; + target.x=current_overlay->hwdata->CurrentViewPort.pos.x; + target.y=current_overlay->hwdata->CurrentViewPort.pos.y; + target.w=current_overlay->hwdata->CurrentViewPort.size.w; + target.h=current_overlay->hwdata->CurrentViewPort.size.h; + current_overlay->hwdata->forcedredraw=1; + ph_DisplayYUVOverlay(this, current_overlay, &target); + current_overlay->hwdata->forcedredraw=0; + current_overlay->hwdata->locked=lockedstate; + } } - - this->UpdateRects(this, event->num_rects, sdlrects); } } break; @@ -260,13 +325,32 @@ static int ph_DispatchEvent(_THIS) if (Pk_KF_Key_Down & keyEvent->key_flags) { + /* split the wheel events from real key events */ + if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) + { + posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); + break; + } + if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) + { + posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); + break; + } posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym)); } else /* must be key release */ { - /* Ignore repeated key release events */ - /* if (! Pk_KF_Key_Repeat & keyEvent->key_flags ) */ - + /* split the wheel events from real key events */ + if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) + { + posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); + break; + } + if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) + { + posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); + break; + } posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym)); } } @@ -282,9 +366,9 @@ int ph_Pending(_THIS) /* Flush the display connection and look to see if events are queued */ PgFlush(); - while( 1 ) - { /* note this is a non-blocking call */ - switch( PhEventPeek( event, EVENT_SIZE ) ) + while (1) + { + switch(PhEventPeek(event, EVENT_SIZE)) { case Ph_EVENT_MSG: return 1; @@ -308,6 +392,7 @@ void ph_PumpEvents(_THIS) while (ph_Pending(this)) { + PtEventHandler(event); ph_DispatchEvent(this); } } @@ -318,11 +403,15 @@ void ph_InitKeymap(void) /* Odd keys used in international keyboards */ for (i=0; i 0) + switch (keysym->scancode) { - utf8len = mbtowc(&unicode, utf8, utf8len); - if (utf8len > 0) - keysym->unicode = unicode; + case 0x01: keysym->unicode = 27; + break; + default: + utf8len = PhKeyToMb(utf8, key); + if (utf8len > 0) + { + utf8len = mbtowc(&unicode, utf8, utf8len); + if (utf8len > 0) + { + keysym->unicode = unicode; + } + } + break; } + } return (keysym); diff --git a/src/video/photon/SDL_ph_image.c b/src/video/photon/SDL_ph_image.c index 73132c372..28317cdef 100644 --- a/src/video/photon/SDL_ph_image.c +++ b/src/video/photon/SDL_ph_image.c @@ -35,54 +35,11 @@ static char rcsid = #include "SDL_video.h" #include "SDL_pixels_c.h" #include "SDL_ph_image_c.h" - -/* Mask values for SDL_ReallocFormat() */ -struct ColourMasks -{ - Uint32 red; - Uint32 green; - Uint32 blue; - Uint32 alpha; - Uint32 bpp; -}; - -static const struct ColourMasks *ph_GetColourMasks( int format ) -{ - /* The alpha mask doesn't appear to be needed */ - static const struct ColourMasks phColorMasks[5] = { - /* 8 bit */ {0, 0, 0, 0, 8}, - /* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 16}, - /* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16}, - /* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24}, - /* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32}, - }; - - switch( format ) - { - case Pg_IMAGE_PALETTE_BYTE: - return &phColorMasks[0]; - break; - case Pg_IMAGE_DIRECT_1555: - case Pg_IMAGE_DIRECT_555: - return &phColorMasks[1]; - break; - case Pg_IMAGE_DIRECT_565: - return &phColorMasks[2]; - break; - case Pg_IMAGE_DIRECT_888: - return &phColorMasks[3]; - break; - case Pg_IMAGE_DIRECT_8888: - return &phColorMasks[4]; - break; - } - return NULL; -} +#include "SDL_ph_modes_c.h" int ph_SetupImage(_THIS, SDL_Surface *screen) { PgColor_t* palette=NULL; - const struct ColourMasks* mask; int type=0; int bpp; @@ -112,7 +69,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) } break; default:{ - fprintf(stderr,"ph_SetupImage(): unsupported bpp=%d !\n", bpp); + SDL_SetError("ph_SetupImage(): unsupported bpp=%d !\n", bpp); return -1; } break; @@ -123,12 +80,18 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) { /* creating image palette */ palette=malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t)); + if (palette==NULL) + { + SDL_SetError("ph_SetupImage(): can't allocate memory for palette !\n"); + return -1; + } PgGetPalette(palette); /* using shared memory for speed (set last param to 1) */ if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL) { - fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8 !\n"); + SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=8 !\n"); + free(palette); return -1; } } @@ -137,19 +100,13 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) /* using shared memory for speed (set last param to 1) */ if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL) { - fprintf(stderr,"ph_SetupImage: PhCreateImage failed !\n"); + SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=%d !\n", bpp); return -1; } } screen->pixels = SDL_Image->image; - screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */ - - mask = ph_GetColourMasks(type); - if (mask != NULL) - { - SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0); - } + screen->pitch = SDL_Image->bpl; this->UpdateRects = ph_NormalUpdate; @@ -158,11 +115,9 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) int ph_SetupOCImage(_THIS, SDL_Surface *screen) { - const struct ColourMasks *mask; int type = 0; int bpp; - screen->flags &= ~SDL_DOUBLEBUF; OCImage.flags = screen->flags; bpp=screen->format->BitsPerPixel; @@ -191,7 +146,7 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) } break; default:{ - fprintf(stderr,"ph_SetupOCImage(): unsupported bpp=%d !\n", bpp); + SDL_SetError("ph_SetupOCImage(): unsupported bpp=%d !\n", bpp); return -1; } break; @@ -203,35 +158,22 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) if (OCImage.offscreen_context == NULL) { - fprintf(stderr, "ph_SetupOCImage(): PdCreateOffscreenContext failed !\n"); + SDL_SetError("ph_SetupOCImage(): PdCreateOffscreenContext() function failed !\n"); return -1; } - /* If the bit depth of the context is different than was requested, - * these values need to be updated accordingly. SDL will - * allocate a shadow surface if it needs to. */ - mask = ph_GetColourMasks(OCImage.offscreen_context->format); - if (mask != NULL) - { - SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0); - - if (mask->bpp > 8) - { - screen->flags &= ~SDL_HWPALETTE; - } - } + screen->pitch = OCImage.offscreen_context->pitch; - screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */ + OCImage.dc_ptr = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context); - OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context); - - if (OCImage.dc_ptr.ptr8 == NULL) + if (OCImage.dc_ptr == NULL) { - fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n"); + SDL_SetError("ph_SetupOCImage(): PdGetOffscreenContextPtr function failed !\n"); + PhDCRelease(OCImage.offscreen_context); return -1; } - OCImage.FrameData0 = OCImage.dc_ptr.ptr8; + OCImage.FrameData0 = OCImage.dc_ptr; OCImage.CurrentFrameData = OCImage.FrameData0; OCImage.current = 0; @@ -253,67 +195,108 @@ int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen) int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen) { - const struct ColourMasks *mask; - screen->flags &= ~SDL_DOUBLEBUF; OCImage.flags = screen->flags; - OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY); - - if (OCImage.offscreen_context == NULL) + /* Begin direct mode */ + if (!ph_EnterFullScreen(this, screen)) { - fprintf(stderr, "ph_SetupFullScreenImage(): PdCreateOffscreenContext failed !\n"); return -1; } - /* If the bit depth of the context is different than was requested, - * these values need to be updated accordingly. SDL will - * allocate a shadow surface if it needs to. */ - mask = ph_GetColourMasks(OCImage.offscreen_context->format); - if (mask != NULL) + /* store palette for fullscreen */ + if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8)) { - SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0); + PgGetPalette(savedpal); + PgGetPalette(syspalph); + } - if (mask->bpp > 8) + OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY); + if (OCImage.offscreen_context == NULL) + { + SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext() function failed !\n"); + return -1; + } + + if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) + { + OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_CRTC_SAFE); + if (OCImage.offscreen_backcontext == NULL) { - screen->flags &= ~SDL_HWPALETTE; + SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n"); + return -1; } } - screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */ - - OCImage.dc_ptr.ptr8 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context); - - if (OCImage.dc_ptr.ptr8 == NULL) + OCImage.FrameData0 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context); + if (OCImage.FrameData0 == NULL) { - fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n"); + SDL_SetError("ph_SetupFullScreenImage(): PdGetOffscreenContextPtr() function failed !\n"); + ph_DestroyImage(this, screen); return -1; } - /* wait for hw */ - PgWaitHWIdle(); - - OCImage.FrameData0 = OCImage.dc_ptr.ptr8; - OCImage.CurrentFrameData = OCImage.FrameData0; - OCImage.current = 0; + if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) + { + OCImage.FrameData1 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_backcontext); + if (OCImage.FrameData1 == NULL) + { + SDL_SetError("ph_SetupFullScreenImage(back): PdGetOffscreenContextPtr() function failed !\n"); + ph_DestroyImage(this, screen); + return -1; + } + } - PhDCSetCurrent(OCImage.offscreen_context); + /* wait for the hardware */ + PgWaitHWIdle(); - screen->pixels = OCImage.CurrentFrameData; + if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) + { + OCImage.current = 1; + PhDCSetCurrent(OCImage.offscreen_backcontext); + screen->pitch = OCImage.offscreen_backcontext->pitch; + screen->pixels = OCImage.FrameData1; + PgSwapDisplay(OCImage.offscreen_context, 0); + } + else + { + OCImage.current = 0; + PhDCSetCurrent(OCImage.offscreen_context); + screen->pitch = OCImage.offscreen_context->pitch; + screen->pixels = OCImage.FrameData0; + } - this->UpdateRects = ph_OCUpdate; + this->UpdateRects = ph_OCDCUpdate; return 0; } void ph_DestroyImage(_THIS, SDL_Surface *screen) { + if (currently_fullscreen) + { + /* if we right now in 8bpp fullscreen we must release palette */ + if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8)) + { + PgSetPalette(syspalph, 0, -1, 0, 0, 0); + PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0); + PgFlush(); + } + ph_LeaveFullScreen(this); + } + if (OCImage.offscreen_context != NULL) { PhDCRelease(OCImage.offscreen_context); OCImage.offscreen_context = NULL; OCImage.FrameData0 = NULL; + } + if (OCImage.offscreen_backcontext != NULL) + { + PhDCRelease(OCImage.offscreen_backcontext); + OCImage.offscreen_backcontext = NULL; OCImage.FrameData1 = NULL; } + OCImage.CurrentFrameData = NULL; if (SDL_Image) { @@ -354,6 +337,7 @@ int ph_SetupUpdateFunction(_THIS, SDL_Surface *screen, Uint32 flags) return ph_SetupImage(this, screen); } + int ph_AllocHWSurface(_THIS, SDL_Surface *surface) { return(-1); @@ -364,9 +348,41 @@ void ph_FreeHWSurface(_THIS, SDL_Surface *surface) return; } -int ph_FlipHWSurface(_THIS, SDL_Surface *surface) +int ph_FlipHWSurface(_THIS, SDL_Surface *screen) { - return(0); + PhArea_t area; + + area.pos.x=0; + area.pos.y=0; + area.size.w=screen->w; + area.size.h=screen->h; + + if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) + { + if (OCImage.current==0) + { + PgSwapDisplay(OCImage.offscreen_context, 0); + OCImage.current=1; + screen->pitch = OCImage.offscreen_backcontext->pitch; + screen->pixels = OCImage.FrameData1; +// memcpy(OCImage.FrameData1, OCImage.FrameData0, OCImage.offscreen_context->shared_size); + PgContextBlitArea(OCImage.offscreen_context, &area, OCImage.offscreen_backcontext, &area); + PhDCSetCurrent(OCImage.offscreen_backcontext); + PgFlush(); + } + else + { + PgSwapDisplay(OCImage.offscreen_backcontext, 0); + OCImage.current=0; + screen->pitch = OCImage.offscreen_context->pitch; + screen->pixels = OCImage.FrameData0; +// memcpy(OCImage.FrameData0, OCImage.FrameData1, OCImage.offscreen_context->shared_size); + PgContextBlitArea(OCImage.offscreen_backcontext, &area, OCImage.offscreen_context, &area); + PhDCSetCurrent(OCImage.offscreen_context); + PgFlush(); + } + } + return 0; } int ph_LockHWSurface(_THIS, SDL_Surface *surface) @@ -399,6 +415,11 @@ void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) continue; } + if (rects[i].h==0) /* Clipped? */ + { + continue; + } + ph_pos.x = rects[i].x; ph_pos.y = rects[i].y; ph_rect.ul.x = rects[i].x; @@ -408,13 +429,13 @@ void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0) { - fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n"); + SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n"); } } if (PgFlush() < 0) { - fprintf(stderr,"ph_NormalUpdate(): PgFlush failed.\n"); + SDL_SetError("ph_NormalUpdate(): PgFlush failed.\n"); } } @@ -437,6 +458,11 @@ void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects) continue; } + if (rects[i].h == 0) /* Clipped? */ + { + continue; + } + src_rect.pos.x=rects[i].x; src_rect.pos.y=rects[i].y; dest_rect.pos.x=rects[i].x; @@ -457,16 +483,16 @@ void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects) if (PgFlush() < 0) { - fprintf(stderr,"ph_OCUpdate(): PgFlush failed.\n"); + SDL_SetError("ph_OCUpdate(): PgFlush failed.\n"); } - - /* later used to toggling double buffer */ - if (OCImage.current == 0) - { - OCImage.CurrentFrameData = OCImage.FrameData0; - } - else +} + +void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + PgWaitHWIdle(); + + if (PgFlush() < 0) { - OCImage.CurrentFrameData = OCImage.FrameData1; + SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n"); } } diff --git a/src/video/photon/SDL_ph_image_c.h b/src/video/photon/SDL_ph_image_c.h index 37671139d..96fc1a47d 100644 --- a/src/video/photon/SDL_ph_image_c.h +++ b/src/video/photon/SDL_ph_image_c.h @@ -39,4 +39,5 @@ extern int ph_FlipHWSurface(_THIS, SDL_Surface *surface); extern void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); extern void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects); +extern void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects); extern void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect *rects); diff --git a/src/video/photon/SDL_ph_modes.c b/src/video/photon/SDL_ph_modes.c index 8d6f75e04..889319f2b 100644 --- a/src/video/photon/SDL_ph_modes.c +++ b/src/video/photon/SDL_ph_modes.c @@ -25,6 +25,7 @@ static char rcsid = "@(#) $Id$"; #endif +#include "SDL_error.h" #include "SDL_ph_modes_c.h" static unsigned long key1, key2; @@ -39,8 +40,6 @@ static int compare_modes_by_res(const void* mode1, const void* mode2) { if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0) { - fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n", - *(unsigned short*)mode1); return 0; } @@ -48,19 +47,26 @@ static int compare_modes_by_res(const void* mode1, const void* mode2) if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0) { - fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n", - *(unsigned short*)mode2); return 0; } key2 = mode_info.width * mode_info.height; if (key1 > key2) + { return 1; - else if (key1 == key2) - return 0; + } else - return -1; + { + if (key1 == key2) + { + return 0; + } + else + { + return -1; + } + } } SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) @@ -76,7 +82,7 @@ SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) if (PgGetVideoModeList( &mode_list ) < 0) { - fprintf(stderr,"error: PgGetVideoModeList failed\n"); + SDL_SetError("ph_ListModes(): PgGetVideoModeList() function failed !\n"); return NULL; } @@ -86,7 +92,7 @@ SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) { if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0) { - fprintf(stderr,"error: PgGetVideoModeInfo failed on mode: 0x%x\n", mode_list.modes[i]); + SDL_SetError("ph_ListModes(): PgGetVideoModeInfo() function failed on mode: 0x%X.\n", mode_list.modes[i]); return NULL; } if(mode_info.bits_per_pixel == format->BitsPerPixel) @@ -120,22 +126,12 @@ void ph_FreeVideoModes(_THIS) /* return the mode associated with width, height and bpp */ /* if there is no mode then zero is returned */ -int get_mode(int width, int height, int bpp) +int ph_GetVideoMode(int width, int height, int bpp) { int i; - if(width<640) - { - width=640; - } - if(height<480) - { - height=480; - } - if (PgGetVideoModeList(&mode_list) < 0) { - fprintf(stderr,"error: PgGetVideoModeList failed\n"); return -1; } @@ -144,7 +140,6 @@ int get_mode(int width, int height, int bpp) { if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0) { - fprintf(stderr,"error: PgGetVideoModeInfo failed\n"); return 0; } @@ -159,89 +154,124 @@ int get_mode(int width, int height, int bpp) return (i == mode_list.num_modes) ? 0 : mode_list.modes[i]; } -int get_mode_any_format(int width, int height, int bpp) /* return the mode associated with width, height and bpp */ /* if requested bpp is not found the mode with closest bpp is returned */ +int get_mode_any_format(int width, int height, int bpp) { int i, closest, delta, min_delta; - if (PgGetVideoModeList( &mode_list ) < 0) - { - fprintf(stderr,"error: PgGetVideoModeList failed\n"); - return -1; - } - - qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res); - for(i=0;iflags & SDL_ANYFORMAT) + { + if ((mode = get_mode_any_format(screen->w, screen->h, screen->format->BitsPerPixel)) == 0) + { + SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n"); + return 0; + } + } + else + { + if ((mode = ph_GetVideoMode(screen->w, screen->h, screen->format->BitsPerPixel)) == 0) + { + SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n"); + return 0; + } + } + + /* save old video mode caps */ + PgGetVideoMode(&settings); + old_video_mode=settings.mode; + old_refresh_rate=settings.refresh; + + /* setup new video mode */ + settings.mode = mode; + settings.refresh = 0; + settings.flags = 0; + + if (PgSetVideoMode(&settings) < 0) + { + SDL_SetError("ph_EnterFullScreen(): PgSetVideoMode() call failed !\n"); + return 0; + } + if (this->screen) { if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL) @@ -255,12 +285,12 @@ int ph_EnterFullScreen(_THIS) if (OCImage.direct_context==NULL) { OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext(); - } - - if (!OCImage.direct_context) - { - fprintf(stderr, "ph_EnterFullScreen(): Can't create direct context !\n"); - return 0; + if (!OCImage.direct_context) + { + SDL_SetError("ph_EnterFullScreen(): Can't create direct context !\n"); + ph_LeaveFullScreen(this); + return 0; + } } OCImage.oldDC=PdDirectStart(OCImage.direct_context); @@ -277,7 +307,7 @@ int ph_LeaveFullScreen(_THIS) if (currently_fullscreen) { - if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL) + if ((this->screen) && ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)) { #ifdef HAVE_OPENGL #endif /* HAVE_OPENGL */ @@ -285,22 +315,30 @@ int ph_LeaveFullScreen(_THIS) } else { - PdDirectStop(OCImage.direct_context); - PdReleaseDirectContext(OCImage.direct_context); - PhDCSetCurrent(OCImage.oldDC); + if (OCImage.direct_context) + { + PdDirectStop(OCImage.direct_context); + PdReleaseDirectContext(OCImage.direct_context); + OCImage.direct_context=NULL; + } + if (OCImage.oldDC) + { + PhDCSetCurrent(OCImage.oldDC); + OCImage.oldDC=NULL; + } currently_fullscreen=0; /* Restore old video mode */ if (old_video_mode != -1) { - mymode_settings.mode= (unsigned short) old_video_mode; - mymode_settings.refresh= (unsigned short) old_refresh_rate; - mymode_settings.flags= 0; + mymode_settings.mode = (unsigned short) old_video_mode; + mymode_settings.refresh = (unsigned short) old_refresh_rate; + mymode_settings.flags = 0; if (PgSetVideoMode(&mymode_settings) < 0) { - fprintf(stderr, "Ph_LeaveFullScreen(): PgSetVideoMode failed !\n"); + SDL_SetError("Ph_LeaveFullScreen(): PgSetVideoMode() function failed !\n"); return 0; } } @@ -308,7 +346,6 @@ int ph_LeaveFullScreen(_THIS) old_video_mode=-1; old_refresh_rate=-1; } - } return 1; } diff --git a/src/video/photon/SDL_ph_modes_c.h b/src/video/photon/SDL_ph_modes_c.h index 48b062522..59e3e0f51 100644 --- a/src/video/photon/SDL_ph_modes_c.h +++ b/src/video/photon/SDL_ph_modes_c.h @@ -36,9 +36,9 @@ static char rcsid = extern SDL_Rect **ph_ListModes(_THIS,SDL_PixelFormat *format, Uint32 flags); extern void ph_FreeVideoModes(_THIS); extern int ph_ResizeFullScreen(_THIS); -extern int ph_EnterFullScreen(_THIS); +extern int ph_EnterFullScreen(_THIS, SDL_Surface* screen); extern int ph_LeaveFullScreen(_THIS); -extern int get_mode(int width, int height, int bpp); +extern int ph_GetVideoMode(int width, int height, int bpp); extern int get_mode_any_format(int width, int height, int bpp); extern int ph_ToggleFullScreen(_THIS, int on); diff --git a/src/video/photon/SDL_ph_mouse.c b/src/video/photon/SDL_ph_mouse.c index e7c62decc..f34394310 100644 --- a/src/video/photon/SDL_ph_mouse.c +++ b/src/video/photon/SDL_ph_mouse.c @@ -46,19 +46,18 @@ void ph_FreeWMCursor(_THIS, WMcursor *cursor) { SDL_Lock_EventThread(); - if (PtSetResource( window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0) < 0) + if (PtSetResource(window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0) < 0) { /* TODO: output error msg */ } SDL_Unlock_EventThread(); } - /* free(cursor->ph_cursor.images); */ + free(cursor); } -WMcursor *ph_CreateWMCursor(_THIS, - Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) +WMcursor *ph_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) { WMcursor* cursor; int clen, i; @@ -73,8 +72,12 @@ WMcursor *ph_CreateWMCursor(_THIS, memset(cursor,0,sizeof(WMcursor)); cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2); + if (cursor->ph_cursor == NULL) - printf("cursor malloc failed\n"); + { + SDL_SetError("ph_CreateWMCursor(): cursor malloc failed !\n"); + return NULL; + } memset(cursor->ph_cursor,0,(sizeof(PhCursorDef_t) + 32*4*2)); @@ -137,7 +140,7 @@ int ph_ShowWMCursor(_THIS, WMcursor *cursor) return (0); } - /* Set the photon cursor cursor, or blank if cursor is NULL */ + /* Set the photon cursor, or blank if cursor is NULL */ if (cursor!=NULL) { PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0); @@ -148,7 +151,7 @@ int ph_ShowWMCursor(_THIS, WMcursor *cursor) } else /* Ph_CURSOR_NONE */ { - PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0); + PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0); nargs = 1; } diff --git a/src/video/photon/SDL_ph_video.c b/src/video/photon/SDL_ph_video.c index 3426b80f6..44ccec224 100644 --- a/src/video/photon/SDL_ph_video.c +++ b/src/video/photon/SDL_ph_video.c @@ -59,9 +59,12 @@ static void ph_DeleteDevice(SDL_VideoDevice *device); static void ph_UpdateMouse(_THIS); #ifdef HAVE_OPENGL -int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags); +static int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags); static void ph_GL_SwapBuffers(_THIS); static int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); +static int ph_GL_LoadLibrary(_THIS, const char* path); +static void* ph_GL_GetProcAddress(_THIS, const char* proc); + #endif /* HAVE_OPENGL */ static int ph_Available(void) @@ -109,7 +112,7 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) device->ToggleFullScreen = ph_ToggleFullScreen; device->UpdateMouse = ph_UpdateMouse; device->SetColors = ph_SetColors; - device->UpdateRects = NULL; /* ph_SetupUpdateFunction */ + device->UpdateRects = NULL; /* set up in ph_SetupUpdateFunction */ device->VideoQuit = ph_VideoQuit; device->AllocHWSurface = ph_AllocHWSurface; device->CheckHWBlit = NULL; @@ -134,19 +137,21 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) device->PumpEvents = ph_PumpEvents; /* OpenGL support. */ - device->GL_LoadLibrary = NULL; - device->GL_GetProcAddress = NULL; device->GL_MakeCurrent = NULL; #ifdef HAVE_OPENGL device->GL_SwapBuffers = ph_GL_SwapBuffers; device->GL_GetAttribute = ph_GL_GetAttribute; + device->GL_LoadLibrary = ph_GL_LoadLibrary; + device->GL_GetProcAddress = ph_GL_GetProcAddress; #else device->GL_SwapBuffers = NULL; device->GL_GetAttribute = NULL; + device->GL_LoadLibrary = NULL; + device->GL_GetProcAddress = NULL; #endif /* HAVE_OPENGL */ device->free = ph_DeleteDevice; - + return device; } @@ -179,10 +184,6 @@ static PtWidget_t *ph_CreateWindow(_THIS) PtWidget_t *widget; widget = PtCreateWidget(PtWindow, NULL, 0, 0); - if (widget == NULL) - { - SDL_SetError("Couldn't create video window"); - } return widget; } @@ -199,28 +200,38 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE) { - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX); - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MAX); - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_CLOSE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_MAX | Ph_WM_RESTORE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MOVE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN); } else { - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX); - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX); - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_MOVE | Ph_WM_CLOSE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN); } if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)) { - PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE); + if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE) + { + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE); + } + else + { + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_BORDER); + } } else { PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE | - Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN); + Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN); } - if (flags & SDL_FULLSCREEN) + if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) { PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0); PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX); @@ -231,6 +242,7 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) { PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISMAX | Ph_WM_STATE_ISALTKEY); PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE); + PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE); PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED); } @@ -240,10 +252,38 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) return 0; } +static const struct ColourMasks* ph_GetColourMasks(int bpp) +{ + /* The alpha mask doesn't appears to be needed */ + static const struct ColourMasks phColorMasks[5] = { + /* 8 bit */ {0, 0, 0, 0, 8}, + /* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 15}, + /* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16}, + /* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24}, + /* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32}, + }; + + switch (bpp) + { + case 8: + return &phColorMasks[0]; + case 15: + return &phColorMasks[1]; + case 16: + return &phColorMasks[2]; + case 24: + return &phColorMasks[3]; + case 32: + return &phColorMasks[4]; + } + return NULL; +} + static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) { PgVideoModeInfo_t my_mode_info; PgHWCaps_t my_hwcaps; + int i; window=NULL; desktoppal=SDLPH_PAL_NONE; @@ -264,6 +304,7 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) window = ph_CreateWindow(this); if (window == NULL) { + SDL_SetError("ph_VideoInit(): Couldn't create video window !\n"); return -1; } @@ -274,17 +315,21 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) if (SDL_BlankCursor == NULL) { - fprintf(stderr, "ph_VideoInit(): could not create blank cursor !\n"); + return -1; } if (PgGetGraphicsHWCaps(&my_hwcaps) < 0) { - fprintf(stderr,"ph_VideoInit(): GetGraphicsHWCaps failed !\n"); + SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n"); + this->FreeWMCursor(this, SDL_BlankCursor); + return -1; } if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &my_mode_info) < 0) { - fprintf(stderr,"ph_VideoInit(): PgGetVideoModeInfo failed !\n"); + SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n"); + this->FreeWMCursor(this, SDL_BlankCursor); + return -1; } /* We need to return BytesPerPixel as it in used by CreateRGBsurface */ @@ -298,8 +343,27 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) PgGetPalette(savedpal); PgGetPalette(syspalph); } + else + { + for(i=0; i<_Pg_MAX_PALETTE; i++) + { + savedpal[i]=PgRGB(0, 0, 0); + syspalph[i]=PgRGB(0, 0, 0); + } + } currently_fullscreen = 0; + currently_hided = 0; + current_overlay = NULL; + + OCImage.direct_context = NULL; + OCImage.offscreen_context = NULL; + OCImage.offscreen_backcontext = NULL; + OCImage.oldDC = NULL; + OCImage.CurrentFrameData = NULL; + OCImage.FrameData0 = NULL; + OCImage.FrameData1 = NULL; + this->info.wm_available = 1; @@ -309,18 +373,33 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { - PgDisplaySettings_t settings; - SDL_Color* colors; - int mode; - int rtnval; - int i; + const struct ColourMasks* mask; /* Lock the event thread, in multi-threading environments */ SDL_Lock_EventThread(); current->flags = flags; - ph_SetupWindow(this, width, height, flags); + /* if we do not have desired fullscreen mode, then fallback into window mode */ + if (((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && (ph_GetVideoMode(width, height, bpp)==0)) + { + current->flags &= ~SDL_FULLSCREEN; + current->flags &= ~SDL_NOFRAME; + current->flags &= ~SDL_RESIZABLE; + } + + ph_SetupWindow(this, width, height, current->flags); + + mask = ph_GetColourMasks(bpp); + if (mask != NULL) + { + SDL_ReallocFormat(current, mask->bpp, mask->red, mask->green, mask->blue, 0); + } + else + { + SDL_SetError("ph_SetVideoMode(): desired bpp is not supported by photon !\n"); + return NULL; + } #ifdef HAVE_OPENGL if (current->flags & SDL_OPENGL) @@ -334,72 +413,41 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, { /* if context creation fail, report no OpenGL to high level */ current->flags &= ~SDL_OPENGL; + return NULL; } #else if (current->flags & SDL_OPENGL) /* if no built-in OpenGL support */ { - fprintf(stderr, "ph_SetVideoMode(): no OpenGL support, try to recompile library.\n"); + SDL_SetError("ph_SetVideoMode(): no OpenGL support, try to recompile library.\n"); current->flags &= ~SDL_OPENGL; return NULL; #endif /* HAVE_OPENGL */ } else { - /* Initialize the window */ - if (current->flags & SDL_FULLSCREEN) /* Direct Context , assume SDL_HWSURFACE also set */ + /* Initialize internal variables */ + if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) { - /* Get the video mode and set it */ - if (current->flags & SDL_ANYFORMAT) - { - if ((mode = get_mode_any_format(width, height, bpp)) == 0) - { - fprintf(stderr,"ph_SetVideoMode(): get_mode_any_format failed !\n"); - exit(1); - } - } - else - { - if ((mode = get_mode(width, height, bpp)) == 0) - { - fprintf(stderr,"ph_SetVideoMode(): get_mode failed !\n"); - exit(1); - } - } - if (bpp==8) { desktoppal=SDLPH_PAL_SYSTEM; } - - /* save old video mode caps */ - PgGetVideoMode(&settings); - old_video_mode=settings.mode; - old_refresh_rate=settings.refresh; - - /* setup new video mode */ - settings.mode = mode; - settings.refresh = 0; - settings.flags = 0; - - if (PgSetVideoMode(&settings) < 0) - { - fprintf(stderr,"ph_SetVideoMode(): PgSetVideoMode failed !\n"); - } current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */ - current->flags |= SDL_HWSURFACE; - - /* Begin direct mode */ - ph_EnterFullScreen(this); - - } /* end fullscreen flag */ + } else { - /* Use offscreen memory iff SDL_HWSURFACE flag is set */ - if (current->flags & SDL_HWSURFACE) + /* remove this if we'll support non-fullscreen sw/hw+doublebuf */ + current->flags &= ~SDL_DOUBLEBUF; + + /* Use offscreen memory if SDL_HWSURFACE flag is set */ + if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { - /* no stretch blit in offscreen context */ - current->flags &= ~SDL_RESIZABLE; + + if (desktopbpp!=bpp) + { + current->flags &= ~SDL_HWSURFACE; + } } /* using palette emulation code in window mode */ @@ -407,33 +455,16 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, { if (desktopbpp>=15) { - desktoppal=SDLPH_PAL_EMULATE; + desktoppal = SDLPH_PAL_EMULATE; } else { - desktoppal=SDLPH_PAL_SYSTEM; - } - - /* fill the palette */ - PgGetPalette(savedpal); - PgGetPalette(syspalph); - - current->format->palette = calloc(1, sizeof(SDL_Palette)); - current->format->palette->ncolors = _Pg_MAX_PALETTE; - current->format->palette->colors = (SDL_Color *)calloc(_Pg_MAX_PALETTE, sizeof(SDL_Color)); - - colors = current->format->palette->colors; - - for(i=0; i<256; i++) - { - colors[i].r = PgRedValue(syspalph[i]); - colors[i].g = PgGreenValue(syspalph[i]); - colors[i].b = PgBlueValue(syspalph[i]); + desktoppal = SDLPH_PAL_SYSTEM; } } else { - desktoppal=SDLPH_PAL_NONE; + desktoppal = SDLPH_PAL_NONE; } } } @@ -441,22 +472,22 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, current->w = width; current->h = height; - /* These values can be overridden in ph_SetupUpdateFunction() */ - current->format->BitsPerPixel = bpp; - current->format->BytesPerPixel = (bpp+7)/8; - current->pitch = SDL_CalculatePitch(current); + if (desktoppal==SDLPH_PAL_SYSTEM) + { + current->flags|=SDL_HWPALETTE; + } - /* Must call at least once it setup image planes */ - rtnval = ph_SetupUpdateFunction(this, current, current->flags); - - if (rtnval==-1) + /* Must call at least once for setup image planes */ + if (ph_SetupUpdateFunction(this, current, current->flags)==-1) { - fprintf(stderr,"ph_SetVideoMode(): ph_SetupUpdateFunction failed !\n"); return NULL; } - /* finish window drawing */ - PtFlush(); + /* finish window drawing, if we are not in fullscreen, of course */ + if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) + { + PtFlush(); + } SDL_Unlock_EventThread(); @@ -470,13 +501,16 @@ static void ph_VideoQuit(_THIS) PhRegion_t region_info; #endif /* HAVE_OPENGL */ - ph_DestroyImage(this, SDL_VideoSurface); - - if (currently_fullscreen) + /* restore palette */ + if (desktopbpp==8) { - ph_LeaveFullScreen(this); + PgSetPalette(syspalph, 0, -1, 0, 0, 0); + PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0); + PgFlush(); } + ph_DestroyImage(this, SDL_VideoSurface); + #ifdef HAVE_OPENGL /* prevent double SEGFAULT during parachute mode */ if (this->screen) @@ -509,14 +543,6 @@ static void ph_VideoQuit(_THIS) } #endif /* HAVE_OPENGL */ - /* restore palette */ - if (desktoppal!=SDLPH_PAL_NONE) - { - PgSetPalette(savedpal, 1, 0, _Pg_MAX_PALETTE, Pg_PALSET_HARD | Pg_PALSET_FORCE_EXPOSE, 0); - /* pass -1, to force release palette */ - PgSetPalette(savedpal, 1, 0, -1, Pg_PALSET_HARD | Pg_PALSET_FORCE_EXPOSE, 0); - } - if (event!=NULL) { free(event); @@ -543,6 +569,7 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b); SDL_Image->palette[i] = syspalph[i]; } + /* image needs to be redrawn */ this->UpdateRects(this, 1, &updaterect); } @@ -559,14 +586,14 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) { /* window mode must use soft palette */ - PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_SOFT, 0); + PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0); /* image needs to be redrawn */ this->UpdateRects(this, 1, &updaterect); } else { /* fullscreen mode must use hardware palette */ - PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_HARDLOCKED, 0); + PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0); } } else @@ -628,7 +655,7 @@ int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags) if (oglctx==NULL) { - fprintf(stderr,"ph_SetupOpenGLContext(): cannot create OpenGL context.\n"); + SDL_SetError("ph_SetupOpenGLContext(): cannot create OpenGL context !\n"); return (-1); } @@ -675,6 +702,19 @@ int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) return 0; } +int ph_GL_LoadLibrary(_THIS, const char* path) +{ + /* if code compiled with HAVE_OPENGL, the library already linked */ + this->gl_config.driver_loaded = 1; + + return 0; +} + +void* ph_GL_GetProcAddress(_THIS, const char* proc) +{ + return NULL; +} + #endif /* HAVE_OPENGL */ static void ph_UpdateMouse(_THIS) diff --git a/src/video/photon/SDL_ph_video.h b/src/video/photon/SDL_ph_video.h index f4d0c15bc..da5e54f9d 100644 --- a/src/video/photon/SDL_ph_video.h +++ b/src/video/photon/SDL_ph_video.h @@ -20,22 +20,23 @@ slouken@libsdl.org */ -#ifndef _SDL_ph_video_h -#define _SDL_ph_video_h +#ifndef __SDL_PH_VIDEO_H__ +#define __SDL_PH_VIDEO_H__ #include "SDL_mouse.h" #include "SDL_sysvideo.h" -#include "Ph.h" -#include "Pt.h" +#include +#include #include #include + #ifdef HAVE_OPENGL -#include + #include #endif /* HAVE_OPENGL */ /* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *this +#define _THIS SDL_VideoDevice* this #define PH_OGL_MAX_ATTRIBS 32 @@ -43,18 +44,23 @@ #define SDLPH_PAL_EMULATE 0x00000001L #define SDLPH_PAL_SYSTEM 0x00000002L -typedef union vidptr{ - uint8_t* volatile ptr8; - uint16_t* volatile ptr16; - uint32_t* volatile ptr32; - } VidPtr_t; - -typedef struct { +typedef struct +{ unsigned char* Y; unsigned char* V; unsigned char* U; } FRAMEDATA; +/* Mask values for SDL_ReallocFormat() */ +struct ColourMasks +{ + Uint32 red; + Uint32 green; + Uint32 blue; + Uint32 alpha; + Uint32 bpp; +}; + /* Private display data */ struct SDL_PrivateVideoData { PgDisplaySettings_t mode_settings; @@ -69,8 +75,9 @@ struct SDL_PrivateVideoData { struct { PdDirectContext_t* direct_context; PdOffscreenContext_t* offscreen_context; + PdOffscreenContext_t* offscreen_backcontext; PhDrawContext_t* oldDC; - VidPtr_t dc_ptr; + uint8_t* dc_ptr; unsigned char* CurrentFrameData; unsigned char* FrameData0; unsigned char* FrameData1; @@ -85,13 +92,15 @@ struct SDL_PrivateVideoData { int mouse_relative; WMcursor* BlankCursor; - int depth; /* current visual depth (not bpp) */ - int desktopbpp; /* bpp of desktop at the moment of start */ - int desktoppal; /* palette mode emulation or system */ + int depth; /* current visual depth (not bpp) */ + int desktopbpp; /* bpp of desktop at the moment of start */ + int desktoppal; /* palette mode emulation or system */ int currently_fullscreen; + int currently_hided; /* 1 - window hided (minimazed), 0 - normal */ PhEvent_t* event; + SDL_Overlay* overlay; }; #define mode_settings (this->hidden->mode_settings) @@ -106,11 +115,13 @@ struct SDL_PrivateVideoData { #define desktoppal (this->hidden->desktoppal) #define savedpal (this->hidden->savedpal) #define syspalph (this->hidden->syspalph) +#define currently_fullscreen (this->hidden->currently_fullscreen) +#define currently_hided (this->hidden->currently_hided) +#define event (this->hidden->event) +#define current_overlay (this->hidden->overlay) /* Old variable names */ #define mouse_relative (this->hidden->mouse_relative) -#define currently_fullscreen (this->hidden->currently_fullscreen) -#define event (this->hidden->event) #define SDL_BlankCursor (this->hidden->BlankCursor) -#endif /* _SDL_x11video_h */ +#endif /* __SDL_PH_VIDEO_H__ */ diff --git a/src/video/photon/SDL_ph_wm.c b/src/video/photon/SDL_ph_wm.c index b7f06d5d1..979711bfa 100644 --- a/src/video/photon/SDL_ph_wm.c +++ b/src/video/photon/SDL_ph_wm.c @@ -75,8 +75,9 @@ int ph_IconifyWindow(_THIS) memset( &windowevent, 0, sizeof (event) ); windowevent.event_f = Ph_WM_HIDE; windowevent.event_state = Ph_WM_EVSTATE_HIDE; - windowevent.rid = PtWidgetRid( window ); - PtForwardWindowEvent( &windowevent ); + windowevent.rid = PtWidgetRid(window); + PtForwardWindowEvent(&windowevent); + SDL_Unlock_EventThread(); return 0; diff --git a/src/video/photon/SDL_phyuv.c b/src/video/photon/SDL_phyuv.c index 260869109..5822eab15 100644 --- a/src/video/photon/SDL_phyuv.c +++ b/src/video/photon/SDL_phyuv.c @@ -25,7 +25,7 @@ static char rcsid = "@(#) $Id$"; #endif -/* This is the QNX Realtime Platform version for SDL YUV video overlays */ +/* This is the QNX Realtime Platform version of SDL YUV video overlays */ #include #include @@ -43,36 +43,15 @@ static char rcsid = #define OVERLAY_STATE_ACTIVE 1 /* The functions used to manipulate software video overlays */ -static struct private_yuvhwfuncs ph_yuvfuncs = { +static struct private_yuvhwfuncs ph_yuvfuncs = +{ ph_LockYUVOverlay, ph_UnlockYUVOverlay, ph_DisplayYUVOverlay, ph_FreeYUVOverlay }; -struct private_yuvhwdata { - FRAMEDATA* CurrentFrameData; - FRAMEDATA* FrameData0; - FRAMEDATA* FrameData1; - PgScalerProps_t props; - PgScalerCaps_t caps; - PgVideoChannel_t* channel; - PhArea_t CurrentWindow; - long format; - int planar; - int scaler_on; - int current; - long YStride; - long VStride; - long UStride; - int ischromakey; - long chromakey; - unsigned long State; - long flags; - int locked; -}; - -int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1 ) +int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1) { int planes = 0; @@ -96,11 +75,11 @@ int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1 ) return planes; } -SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) +SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display) { - SDL_Overlay *overlay; - struct private_yuvhwdata *hwdata; - int xv_port; + SDL_Overlay* overlay; + struct private_yuvhwdata* hwdata; + int vidport; int rtncode; int planes; int i=0; @@ -109,15 +88,17 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD /* Create the overlay structure */ overlay = calloc(1, sizeof(SDL_Overlay)); - if (overlay == NULL) { + if (overlay == NULL) + { SDL_OutOfMemory(); - return (NULL); + return NULL; } /* Fill in the basic members */ overlay->format = format; overlay->w = width; overlay->h = height; + overlay->hwdata = NULL; /* Set up the YUV surface function structure */ overlay->hwfuncs = &ph_yuvfuncs; @@ -125,36 +106,41 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD /* Create the pixel data and lookup tables */ hwdata = calloc(1, sizeof(struct private_yuvhwdata)); - overlay->hwdata = hwdata; - if (hwdata == NULL) { + if (hwdata == NULL) + { SDL_OutOfMemory(); SDL_FreeYUVOverlay(overlay); - return(NULL); + return NULL; } + overlay->hwdata = hwdata; + PhDCSetCurrent(0); if (overlay->hwdata->channel == NULL) { - if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL) + if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER, 0)) == NULL) { SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno)); SDL_FreeYUVOverlay(overlay); - - return(NULL); + return NULL; } } + overlay->hwdata->forcedredraw=0; + PtGetAbsPosition(window, &pos.x, &pos.y); - overlay->hwdata->CurrentWindow.pos.x = pos.x; - overlay->hwdata->CurrentWindow.pos.y = pos.y; - overlay->hwdata->CurrentWindow.size.w = width; - overlay->hwdata->CurrentWindow.size.h = height; + overlay->hwdata->CurrentWindowPos.x = pos.x; + overlay->hwdata->CurrentWindowPos.y = pos.y; + overlay->hwdata->CurrentViewPort.pos.x = 0; + overlay->hwdata->CurrentViewPort.pos.y = 0; + overlay->hwdata->CurrentViewPort.size.w = width; + overlay->hwdata->CurrentViewPort.size.h = height; overlay->hwdata->State = OVERLAY_STATE_UNINIT; overlay->hwdata->FrameData0 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA)); overlay->hwdata->FrameData1 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA)); - xv_port = -1; + vidport = -1; i=0; overlay->hwdata->ischromakey=0; @@ -171,7 +157,7 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD { overlay->hwdata->ischromakey=1; } - xv_port=1; + vidport=1; break; } } @@ -183,33 +169,28 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD } while(1); - if (xv_port == -1) + if (vidport == -1) { SDL_SetError("No available video ports for requested format\n"); SDL_FreeYUVOverlay(overlay); - return(NULL); + return NULL; } - + overlay->hwdata->format = format; overlay->hwdata->props.format = format; overlay->hwdata->props.size = sizeof(PgScalerProps_t); - overlay->hwdata->props.src_dim.w = width; - overlay->hwdata->props.src_dim.h = height; - - /* Don't use chromakey for now, blitting a surface will cover the window, - * and therefore the chroma. */ - overlay->hwdata->chromakey = 0; - PtSetResource(window, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0); + overlay->hwdata->props.src_dim.w = width; + overlay->hwdata->props.src_dim.h = height; - PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport); + overlay->hwdata->chromakey = PgGetOverlayChromaColor(); + + PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport); overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER; if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey)) { overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE; - overlay->hwdata->props.color_key = overlay->hwdata->chromakey; - overlay->hwdata->props.color_key_mask = 0x00FFFFFFUL; } else { @@ -221,9 +202,8 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD switch(rtncode) { case -1: SDL_SetError("PgConfigScalerChannel failed\n"); - SDL_FreeYUVOverlay(overlay); - return(NULL); - break; + SDL_FreeYUVOverlay(overlay); + return NULL; case 1: case 0: default: @@ -232,21 +212,39 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); - if(overlay->hwdata->channel->yplane1 != NULL) + if(overlay->hwdata->channel->yplane1 != NULL) overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch; - if(overlay->hwdata->channel->uplane1 != NULL) + if(overlay->hwdata->channel->uplane1 != NULL) overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch; - if(overlay->hwdata->channel->vplane1 != NULL) + if(overlay->hwdata->channel->vplane1 != NULL) overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch; + /* check for the validness of all planes */ + if ((overlay->hwdata->channel->yplane1 == NULL) && + (overlay->hwdata->channel->uplane1 == NULL) && + (overlay->hwdata->channel->vplane1 == NULL)) + { + SDL_FreeYUVOverlay(overlay); + SDL_SetError("PgConfigScaler() returns all planes equal NULL\n"); + return NULL; + } +/* overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); - if(overlay->hwdata->current==0) + if (overlay->hwdata->current==0) + { overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; + } else + { overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; + } +*/ + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; +/* overlay->hwdata->locked = 1; +*/ /* Find the pitch and offset values for the overlay */ overlay->planes = planes; @@ -279,29 +277,36 @@ SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SD overlay->hwdata->scaler_on = 0; overlay->hw_overlay = 1; - return (overlay); + current_overlay=overlay; + + return overlay; } -int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay) +int ph_LockYUVOverlay(_THIS, SDL_Overlay* overlay) { if (overlay == NULL) + { return 0; + } - overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); + overlay->hwdata->locked = 1; + +/* overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); if (overlay->hwdata->current == -1) { - SDL_SetError("PgNextFrame failed, bailing out\n"); + SDL_SetError("ph_LockYUVOverlay: PgNextFrame() failed, bailing out\n"); SDL_FreeYUVOverlay(overlay); - return(NULL); + return 0; } - overlay->hwdata->locked = 1; - - /* set current frame for double buffering */ if (overlay->hwdata->current == 0) + { overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; + } else + { overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; + } if (overlay->planes > 0) { @@ -318,67 +323,83 @@ int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay) overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch; overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V; } +*/ return(0); } -void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) +void ph_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay) { - int rtncode; - - if(overlay == NULL) - return; - - if(overlay->hwdata->scaler_on == 1) + if (overlay == NULL) { - rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); - switch(rtncode) - { - case -1: - SDL_SetError("PgConfigScalerChannel failed\n"); - SDL_FreeYUVOverlay(overlay); - break; - case 1: - grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); - break; - case 0: - default: - break; - } + return; } - /* This would be the best place to draw chromakey but we do not have a SDL_Surface in the args - * This means we might see a chromakey flicker at startup. */ + overlay->hwdata->locked = 0; } -int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) +int ph_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* dstrect) { int rtncode; PhPoint_t pos; + SDL_Rect backrect; + PhRect_t windowextent; + int winchanged=0; - if(overlay == NULL) + if ((overlay == NULL) || (overlay->hwdata==NULL)) + { return -1; + } + + if (overlay->hwdata->State == OVERLAY_STATE_UNINIT) + { + return -1; + } + + PtGetAbsPosition(window, &pos.x, &pos.y); + if ((pos.x!=overlay->hwdata->CurrentWindowPos.x) || + (pos.y!=overlay->hwdata->CurrentWindowPos.y)) + { + winchanged=1; + overlay->hwdata->CurrentWindowPos.x=pos.x; + overlay->hwdata->CurrentWindowPos.y=pos.y; + } - /* If CurrentWindow has change, move the viewport */ - if((overlay->hwdata->CurrentWindow.pos.x != dstrect->x) || - (overlay->hwdata->CurrentWindow.pos.y != dstrect->y) || - (overlay->hwdata->CurrentWindow.size.w != dstrect->w) || - (overlay->hwdata->CurrentWindow.size.h != dstrect->h) || - (overlay->hwdata->scaler_on==0)) + /* If CurrentViewPort position/size has been changed, then move/resize the viewport */ + if ((overlay->hwdata->CurrentViewPort.pos.x != dstrect->x) || + (overlay->hwdata->CurrentViewPort.pos.y != dstrect->y) || + (overlay->hwdata->CurrentViewPort.size.w != dstrect->w) || + (overlay->hwdata->CurrentViewPort.size.h != dstrect->h) || + (overlay->hwdata->scaler_on==0) || (winchanged==1) || + (overlay->hwdata->forcedredraw==1)) { - if(overlay->hwdata->State == OVERLAY_STATE_UNINIT) - return -1; + + if (overlay->hwdata->ischromakey==1) + { + /* restore screen behind the overlay/chroma color. */ + backrect.x=overlay->hwdata->CurrentViewPort.pos.x; + backrect.y=overlay->hwdata->CurrentViewPort.pos.y; + backrect.w=overlay->hwdata->CurrentViewPort.size.w; + backrect.h=overlay->hwdata->CurrentViewPort.size.h; + this->UpdateRects(this, 1, &backrect); + + /* Draw the new rectangle of the chroma color at the viewport position */ + PgSetFillColor(overlay->hwdata->chromakey); + PgDrawIRect(dstrect->x, dstrect->y, dstrect->x+dstrect->w-1, dstrect->y+dstrect->h-1, Pg_DRAW_FILL); + PgFlush(); + } overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE; overlay->hwdata->scaler_on = 1; - PtGetAbsPosition(window, &pos.x, &pos.y); - overlay->hwdata->CurrentWindow.pos.x = pos.x + dstrect->x; - overlay->hwdata->CurrentWindow.pos.y = pos.y + dstrect->y; - overlay->hwdata->CurrentWindow.size.w = dstrect->w; - overlay->hwdata->CurrentWindow.size.h = dstrect->h; - - PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport); + PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, PtWidgetRid(window), &windowextent); + overlay->hwdata->CurrentViewPort.pos.x = pos.x-windowextent.ul.x+dstrect->x; + overlay->hwdata->CurrentViewPort.pos.y = pos.y-windowextent.ul.y+dstrect->y; + overlay->hwdata->CurrentViewPort.size.w = dstrect->w; + overlay->hwdata->CurrentViewPort.size.h = dstrect->h; + PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport); + overlay->hwdata->CurrentViewPort.pos.x = dstrect->x; + overlay->hwdata->CurrentViewPort.pos.y = dstrect->y; rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); @@ -397,19 +418,26 @@ int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) } } - if (!overlay->hwdata->locked) + +/* + if (overlay->hwdata->locked==0) { overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); if (overlay->hwdata->current == -1) { - SDL_SetError("PgNextVideoFrame failed\n"); + SDL_SetError("ph_LockYUVOverlay: PgNextFrame() failed, bailing out\n"); SDL_FreeYUVOverlay(overlay); return 0; } + if (overlay->hwdata->current == 0) + { overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; + } else + { overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; + } if (overlay->planes > 0) { @@ -427,17 +455,33 @@ int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V; } } +*/ return 0; } void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) { + SDL_Rect backrect; + if (overlay == NULL) + { return; + } if (overlay->hwdata == NULL) + { return; + } + + current_overlay=NULL; + + /* restore screen behind the overlay/chroma color. */ + backrect.x=overlay->hwdata->CurrentViewPort.pos.x; + backrect.y=overlay->hwdata->CurrentViewPort.pos.y; + backrect.w=overlay->hwdata->CurrentViewPort.size.w; + backrect.h=overlay->hwdata->CurrentViewPort.size.h; + this->UpdateRects(this, 1, &backrect); /* it is need for some buggy drivers, that can't hide overlay before */ /* freeing buffer, so we got trash on the srceen */ diff --git a/src/video/photon/SDL_phyuv_c.h b/src/video/photon/SDL_phyuv_c.h index 1670b19f8..5a22bffbb 100644 --- a/src/video/photon/SDL_phyuv_c.h +++ b/src/video/photon/SDL_phyuv_c.h @@ -25,13 +25,37 @@ static char rcsid = "@(#) $Id$"; #endif -/* This is the XFree86 Xv extension implementation of YUV video overlays */ +/* This is the photon implementation of YUV video overlays */ #include "SDL_video.h" #include "SDL_ph_video.h" -extern SDL_Overlay *ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); -extern int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay); -extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay); -extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); -extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay); +struct private_yuvhwdata +{ + FRAMEDATA* CurrentFrameData; + FRAMEDATA* FrameData0; + FRAMEDATA* FrameData1; + PgScalerProps_t props; + PgScalerCaps_t caps; + PgVideoChannel_t* channel; + PhArea_t CurrentViewPort; + PhPoint_t CurrentWindowPos; + long format; + int scaler_on; + int current; + long YStride; + long VStride; + long UStride; + int ischromakey; + long chromakey; + int forcedredraw; + unsigned long State; + long flags; + int locked; +}; + +extern SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display); +extern int ph_LockYUVOverlay(_THIS, SDL_Overlay* overlay); +extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay); +extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* dstrect); +extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay* overlay); diff --git a/test/testsprite.c b/test/testsprite.c index e90174366..aa839fa5b 100644 --- a/test/testsprite.c +++ b/test/testsprite.c @@ -54,10 +54,6 @@ int LoadSprite(SDL_Surface *screen, char *file) void MoveSprites(SDL_Surface *screen, Uint32 background) { -#if DEBUG_FLIP - static int t = 0; -#endif - int i, nupdates; SDL_Rect area, *position, *velocity; @@ -90,15 +86,19 @@ void MoveSprites(SDL_Surface *screen, Uint32 background) #if DEBUG_FLIP { - Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0); - SDL_Rect r; - r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20); - r.y = 0; - r.w = 20; - r.h = screen->h; + if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + static int t = 0; + + Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0); + SDL_Rect r; + r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20); + r.y = 0; + r.w = 20; + r.h = screen->h; - SDL_FillRect (screen, &r, color); - t+=2; + SDL_FillRect (screen, &r, color); + t+=2; + } } #endif