diff options
Diffstat (limited to 'distrib/sdl-1.2.12/src/video/cybergfx/SDL_cgxvideo.c')
-rw-r--r-- | distrib/sdl-1.2.12/src/video/cybergfx/SDL_cgxvideo.c | 1375 |
1 files changed, 1375 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.12/src/video/cybergfx/SDL_cgxvideo.c b/distrib/sdl-1.2.12/src/video/cybergfx/SDL_cgxvideo.c new file mode 100644 index 0000000..e306746 --- /dev/null +++ b/distrib/sdl-1.2.12/src/video/cybergfx/SDL_cgxvideo.c @@ -0,0 +1,1375 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + * CGX based SDL video driver implementation by Gabriele Greco + * gabriele.greco@aruba.it + */ + +#include "SDL_endian.h" +#include "SDL_timer.h" +#include "SDL_thread.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" +#include "SDL_cgxgl_c.h" +#include "SDL_cgxvideo.h" +#include "SDL_cgxwm_c.h" +#include "SDL_amigamouse_c.h" +#include "SDL_amigaevents_c.h" +#include "SDL_cgxmodes_c.h" +#include "SDL_cgximage_c.h" + +/* Initialization/Query functions */ +static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int CGX_ToggleFullScreen(_THIS, int on); +static void CGX_UpdateMouse(_THIS); +static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); +static void CGX_VideoQuit(_THIS); + +/* CGX driver bootstrap functions */ + +struct Library *CyberGfxBase=NULL; +struct IntuitionBase *IntuitionBase=NULL; +struct GfxBase *GfxBase=NULL; + +int CGX_SetGamma(_THIS, float red, float green, float blue) +{ + SDL_SetError("Gamma correction not supported"); + return -1; +} + +int CGX_GetGamma(_THIS, float red, float green, float blue) +{ + SDL_SetError("Gamma correction not supported"); + return -1; +} + +int CGX_SetGammaRamp(_THIS, Uint16 *ramp) +{ +#if 0 + Int i, ncolors; + XColor xcmap[256]; + + /* See if actually setting the gamma is supported */ + if ( SDL_Visual->class != DirectColor ) { + SDL_SetError("Gamma correction not supported on this visual"); + return(-1); + } + + /* Calculate the appropriate palette for the given gamma ramp */ + ncolors = SDL_Visual->map_entries; + for ( i=0; i<ncolors; ++i ) { + Uint8 c = (256 * i / ncolors); + xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c); + xcmap[i].red = ramp[0*256+c]; + xcmap[i].green = ramp[1*256+c]; + xcmap[i].blue = ramp[2*256+c]; + xcmap[i].flags = (DoRed|DoGreen|DoBlue); + } + XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); + XSync(GFX_Display, False); + + return(0); + +#else + SDL_SetError("Gamma correction not supported on this visual"); + return(-1); + +#endif +} + +static void DestroyScreen(_THIS) +{ + if(currently_fullscreen) + { + if(this->hidden->dbuffer) + { + extern struct MsgPort *safeport,*dispport; + + this->hidden->dbuffer=0; + + if(safeport) + { + while(GetMsg(safeport)!=NULL); + DeleteMsgPort(safeport); + } + if(dispport) + { + while(GetMsg(dispport)!=NULL); + DeleteMsgPort(dispport); + } + + this->hidden->SB[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL; + this->hidden->SB[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL; + + if(this->hidden->SB[1]) + FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); + if(this->hidden->SB[0]) + FreeScreenBuffer(SDL_Display,this->hidden->SB[0]); + + + this->hidden->SB[0]=this->hidden->SB[1]=NULL; + + if(SDL_RastPort && SDL_RastPort != &SDL_Display->RastPort) + SDL_free(SDL_RastPort); + + SDL_RastPort=NULL; + } + CloseScreen(GFX_Display); + currently_fullscreen=0; + } + else if(GFX_Display) + UnlockPubScreen(NULL,GFX_Display); + + GFX_Display = NULL; +} + +static int CGX_Available(void) +{ + struct Library *l; + + l = OpenLibrary("cybergraphics.library",0L); + + if ( l != NULL ) { + D(bug("CGX video device AVAILABLE\n")); + CloseLibrary(l); + } + D(else bug("**CGX video device UNAVAILABLE\n")); + + return(l != NULL); +} + +static void CGX_DeleteDevice(SDL_VideoDevice *device) +{ + if ( device ) { + if ( device->hidden ) { + SDL_free(device->hidden); + } + if ( device->gl_data ) { + SDL_free(device->gl_data); + } + SDL_free(device); + } +} + +static SDL_VideoDevice *CGX_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + SDL_memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + SDL_malloc((sizeof *device->hidden)); + device->gl_data = (struct SDL_PrivateGLData *) + SDL_malloc((sizeof *device->gl_data)); + } + if ( (device == NULL) || (device->hidden == NULL) || + (device->gl_data == NULL) ) { + D(bug("Unable to create video device!\n")); + SDL_OutOfMemory(); + CGX_DeleteDevice(device); + return(0); + } + SDL_memset(device->hidden, 0, sizeof(*device->hidden)); + SDL_memset(device->gl_data, 0, sizeof(*device->gl_data)); + + /* Set the driver flags */ + device->handles_any_size = 1; + + /* Set the function pointers */ + device->VideoInit = CGX_VideoInit; + device->ListModes = CGX_ListModes; + device->SetVideoMode = CGX_SetVideoMode; + device->ToggleFullScreen = CGX_ToggleFullScreen; + device->UpdateMouse = CGX_UpdateMouse; + device->SetColors = CGX_SetColors; + device->UpdateRects = NULL; + device->VideoQuit = CGX_VideoQuit; + device->AllocHWSurface = CGX_AllocHWSurface; + device->CheckHWBlit = CGX_CheckHWBlit; + device->FillHWRect = CGX_FillHWRect; + device->SetHWColorKey = CGX_SetHWColorKey; + device->SetHWAlpha = NULL; + device->LockHWSurface = CGX_LockHWSurface; + device->UnlockHWSurface = CGX_UnlockHWSurface; + device->FlipHWSurface = CGX_FlipHWSurface; + device->FreeHWSurface = CGX_FreeHWSurface; + device->SetGamma = CGX_SetGamma; + device->GetGamma = CGX_GetGamma; + device->SetGammaRamp = CGX_SetGammaRamp; + device->GetGammaRamp = NULL; +#if SDL_VIDEO_OPENGL + device->GL_LoadLibrary = CGX_GL_LoadLibrary; + device->GL_GetProcAddress = CGX_GL_GetProcAddress; + device->GL_GetAttribute = CGX_GL_GetAttribute; + device->GL_MakeCurrent = CGX_GL_MakeCurrent; + device->GL_SwapBuffers = CGX_GL_SwapBuffers; +#endif + device->SetIcon = CGX_SetIcon; + device->SetCaption = CGX_SetCaption; + device->IconifyWindow = NULL; /* CGX_IconifyWindow; */ + device->GrabInput = NULL /* CGX_GrabInput*/; + device->GetWMInfo = CGX_GetWMInfo; + device->FreeWMCursor = amiga_FreeWMCursor; + device->CreateWMCursor = amiga_CreateWMCursor; + device->ShowWMCursor = amiga_ShowWMCursor; + device->WarpWMCursor = amiga_WarpWMCursor; + device->CheckMouseMode = amiga_CheckMouseMode; + device->InitOSKeymap = amiga_InitOSKeymap; + device->PumpEvents = amiga_PumpEvents; + + device->free = CGX_DeleteDevice; + + return device; +} + +VideoBootStrap CGX_bootstrap = { + "CGX", "AmigaOS CyberGraphics", CGX_Available, CGX_CreateDevice +}; + +Uint32 MakeBitMask(_THIS,int type,int format,int *bpp) +{ + D(if(type==0)bug("REAL pixel format: ")); + + if(this->hidden->depth==*bpp) + { + + switch(format) + { + case PIXFMT_LUT8: + D(if(type==0)bug("LUT8\n")); + return 0; + case PIXFMT_BGR15: + case PIXFMT_RGB15PC: + switch(type) + { + case 0: + D(bug("RGB15PC/BGR15\n")); + return 31; + case 1: + return 992; + case 2: + return 31744; + } + case PIXFMT_RGB15: + case PIXFMT_BGR15PC: + switch(type) + { + case 0: + D(bug("RGB15/BGR15PC\n")); + return 31744; + case 1: + return 992; + case 2: + return 31; + } + case PIXFMT_BGR16PC: + case PIXFMT_RGB16: + switch(type) + { + case 0: + D(bug("RGB16PC\n")); + return 63488; + case 1: + return 2016; + case 2: + return 31; + } + case PIXFMT_BGR16: + case PIXFMT_RGB16PC: + switch(type) + { + case 0: + D(bug("RGB16PC/BGR16\n")); + return 31; + case 1: + return 2016; + case 2: + return 63488; + } + + case PIXFMT_RGB24: + switch(type) + { + case 0: + D(bug("RGB24/BGR24\n")); + return 0xff0000; + case 1: + return 0xff00; + case 2: + return 0xff; + } + case PIXFMT_BGR24: + switch(type) + { + case 0: + D(bug("BGR24\n")); + return 0xff; + case 1: + return 0xff00; + case 2: + return 0xff0000; + } + case PIXFMT_ARGB32: + switch(type) + { + case 0: + D(bug("ARGB32\n")); + return 0xff0000; + case 1: + return 0xff00; + case 2: + return 0xff; + } + case PIXFMT_BGRA32: + switch(type) + { + case 0: + D(bug("BGRA32\n")); + return 0xff00; + case 1: + return 0xff0000; + case 2: + return 0xff000000; + } + case PIXFMT_RGBA32: + switch(type) + { + case 0: + D(bug("RGBA32\n")); + return 0xff000000; + case 1: + return 0xff0000; + case 2: + return 0xff00; + } + default: + D(bug("Unknown pixel format! Default to 24bit\n")); + return (Uint32) (255<<(type*8)); + } + } + else + { + D(if(type==0)bug("DIFFERENT from screen.\nAllocated screen format: ")); + + switch(*bpp) + { + case 32: + D(if(type==0) bug("RGBA32\n")); + switch(type) + { + case 0: + return 0xff000000; + case 1: + return 0xff0000; + case 2: + return 0xff00; + } + break; + case 24: +use_truecolor: + switch(type) + { + case 0: + D(bug("RGB24\n")); + return 0xff0000; + case 1: + return 0xff00; + case 2: + return 0xff; + } + case 16: + case 15: + D(if(type==0) bug("Not supported, switching to 24bit!\n")); + *bpp=24; + goto use_truecolor; + break; + default: + D(if(type==0)bug("This is a chunky display\n")); +// For chunky display mask is always 0; + return 0; + } + } + return 0; +} + +static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + int i; + struct Library *RTGBase; + + D(bug("VideoInit... Opening libraries\n")); + + if(!IntuitionBase) { + if( !(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L))) { + SDL_SetError("Couldn't open intuition V39+"); + return -1; + } + } + + if(!GfxBase) { + if( !(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L))) { + SDL_SetError("Couldn't open graphics V39+"); + return -1; + } + } + + if(!CyberGfxBase) { + if( !(CyberGfxBase=OpenLibrary("cybergraphics.library",40L))) { + SDL_SetError("Couldn't open cybergraphics."); + return(-1); + } + } + + if(RTGBase=OpenLibrary("libs:picasso96/rtg.library",0L)) { + extern int use_picasso96; + + CloseLibrary(RTGBase); + use_picasso96=1; + } + + D(bug("Library intialized, locking screen...\n")); + + SDL_Display = LockPubScreen(NULL); + + if ( SDL_Display == NULL ) { + D(bug("Cannot lock display...\n")); + SDL_SetError("Couldn't lock the display"); + return(-1); + } + this->info.current_w = SDL_Display->Width; + this->info.current_h = SDL_Display->Height; + + D(bug("Checking if we are using a CGX native display...\n")); + + if(!IsCyberModeID(GetVPModeID(&SDL_Display->ViewPort))) + { + Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,SDL_Display->Width, + CYBRBIDTG_NominalHeight,SDL_Display->Height, + CYBRBIDTG_Depth,8, + TAG_DONE); + + D(bug("Default visual is not CGX native!\n")); + + UnlockPubScreen(NULL,SDL_Display); + + GFX_Display=NULL; + + if(okid!=INVALID_ID) + { + GFX_Display=OpenScreenTags(NULL, + SA_Width,SDL_Display->Width, + SA_Height,SDL_Display->Height, + SA_Depth,8,SA_Quiet,TRUE, + SA_ShowTitle,FALSE, + SA_DisplayID,okid, + TAG_DONE); + } + + if(!GFX_Display) + { + SDL_SetError("Unable to open a suited CGX display"); + return -1; + } + else SDL_Display=GFX_Display; + + } + else GFX_Display = SDL_Display; + + + /* See whether or not we need to swap pixels */ + + swap_pixels = 0; + +// Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente + + if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { + swap_pixels = 1; + } + + D(bug("Before GetVideoModes....\n")); + + /* Get the available video modes */ + if(CGX_GetVideoModes(this) < 0) + return -1; + + /* Determine the default screen depth: + Use the default visual (or at least one with the same depth) */ + + for(i = 0; i < this->hidden->nvisuals; i++) + if(this->hidden->visuals[i].depth == GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)) + break; + if(i == this->hidden->nvisuals) { + /* default visual was useless, take the deepest one instead */ + i = 0; + } + SDL_Visual = this->hidden->visuals[i].visual; + +// SDL_XColorMap = SDL_DisplayColormap; + + this->hidden->depth = this->hidden->visuals[i].depth; + D(bug("Init: Setting screen depth to: %ld\n",this->hidden->depth)); + vformat->BitsPerPixel = this->hidden->visuals[i].depth; /* this->hidden->visuals[i].bpp; */ + + { + int form; + APTR handle; + struct DisplayInfo info; + + if(!(handle=FindDisplayInfo(this->hidden->visuals[i].visual))) + { + D(bug("Unable to get visual info...\n")); + return -1; + } + + if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL)) { + D(bug("Unable to get visual info data...\n")); + return -1; + } + + form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual); + +// In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask + + if ( vformat->BitsPerPixel > 8 ) + { + vformat->Rmask = MakeBitMask(this,0,form,&this->hidden->depth); + vformat->Gmask = MakeBitMask(this,1,form,&this->hidden->depth); + vformat->Bmask = MakeBitMask(this,2,form,&this->hidden->depth); + } + } + + /* See if we have been passed a window to use */ +/* SDL_windowid = SDL_getenv("SDL_WINDOWID"); */ + SDL_windowid=NULL; + + /* Create the blank cursor */ + SDL_BlankCursor = AllocMem(16,MEMF_CHIP|MEMF_CLEAR); + + /* Fill in some window manager capabilities */ + this->info.wm_available = 1; + this->info.blit_hw = 1; + this->info.blit_hw_CC = 1; + this->info.blit_sw = 1; + this->info.blit_fill = 1; + this->info.video_mem=2000000; // Not always true but almost any Amiga card has this memory! + + this->hidden->same_format=0; + SDL_RastPort=&SDL_Display->RastPort; + /* We're done! */ + D(bug("End of CGX_VideoInit\n")); + + return(0); +} + +void CGX_DestroyWindow(_THIS, SDL_Surface *screen) +{ + D(bug("Destroy Window...\n")); + + if ( ! SDL_windowid ) { + /* Hide the managed window */ + int was_fullscreen=0; + + /* Clean up OpenGL */ + if ( screen ) { + screen->flags &= ~(SDL_OPENGL|SDL_OPENGLBLIT); + } + + if ( screen && (screen->flags & SDL_FULLSCREEN) ) { + was_fullscreen=1; + screen->flags &= ~SDL_FULLSCREEN; +// CGX_LeaveFullScreen(this); tolto x crash + } + + /* Destroy the output window */ + if ( SDL_Window ) { + CloseWindow(SDL_Window); + SDL_Window=NULL; + } + + /* Free the colormap entries */ + if ( SDL_XPixels ) { + int numcolors; + unsigned long pixel; + + if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen) + { + numcolors = 1<<this->screen->format->BitsPerPixel; + + if(numcolors>256) + numcolors=256; + + if(!was_fullscreen&&this->hidden->depth==8) + { + for ( pixel=0; pixel<numcolors; pixel++ ) + { + if(SDL_XPixels[pixel]>=0) + ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]); + } + } + } + SDL_free(SDL_XPixels); + SDL_XPixels = NULL; + } + } +} + +static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags) +{ + if ( flags & SDL_RESIZABLE ) { + WindowLimits(SDL_Window, 32, 32,4096,4096); + } else { + WindowLimits(SDL_Window, w,h,w,h); + } + if ( flags & SDL_FULLSCREEN ) { + flags&=~SDL_RESIZABLE; + } else if ( SDL_getenv("SDL_VIDEO_CENTERED") ) { + int display_w, display_h; + + display_w = SDL_Display->Width; + display_h = SDL_Display->Height; + ChangeWindowBox(SDL_Window,(display_w - w - SDL_Window->BorderLeft-SDL_Window->BorderRight)/2, + (display_h - h - SDL_Window->BorderTop-SDL_Window->BorderBottom)/2, + w+SDL_Window->BorderLeft+SDL_Window->BorderRight, + h+SDL_Window->BorderTop+SDL_Window->BorderBottom); + } +} + +int CGX_CreateWindow(_THIS, SDL_Surface *screen, + int w, int h, int bpp, Uint32 flags) +{ +#if 0 + int i, depth; + Uint32 vis; +#endif + D(bug("CGX_CreateWindow\n")); + + /* If a window is already present, destroy it and start fresh */ + if ( SDL_Window ) { + CGX_DestroyWindow(this, screen); + } + + /* See if we have been given a window id */ + if ( SDL_windowid ) { + SDL_Window = (struct Window *)atol(SDL_windowid); + } else { + SDL_Window = 0; + } + + /* find out which visual we are going to use */ +#if 0 +/* questo l'ho spostato nell'apertura dello schermo, in quanto su Amiga le finestre + hanno il pixel mode degli schermi. + */ + /*if ( flags & SDL_OPENGL ) { + SDL_SetError("OpenGL not supported by the Amiga SDL!"); + return -1; + } + else {*/ + for ( i = 0; i < this->hidden->nvisuals; i++ ) { + if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ + break; + } + if ( i == this->hidden->nvisuals ) { + SDL_SetError("No matching visual for requested depth"); + return -1; /* should never happen */ + } + vis = this->hidden->visuals[i].visual; + depth = this->hidden->visuals[i].depth; +// } + SDL_Visual = vis; + this->hidden->depth = depth; + D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); +#endif + + /* Allocate the new pixel format for this video mode */ + { + Uint32 form; + APTR handle; + struct DisplayInfo info; + + if(!(handle=FindDisplayInfo(SDL_Visual))) + return -1; + + if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL)) + return -1; + + form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual); + + if(flags&SDL_HWSURFACE) + { + if(bpp!=this->hidden->depth) + { + bpp=this->hidden->depth; + D(bug("Accel forces bpp to be equal (%ld)\n",bpp)); + } + } + + D(bug("BEFORE screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth)); + +/* With this call if needed I'll revert the wanted bpp to a bpp best suited for the display, actually occurs + only with requested format 15/16bit and display format != 15/16bit + */ + + if ( ! SDL_ReallocFormat(screen, bpp, + MakeBitMask(this,0,form,&bpp), MakeBitMask(this,1,form,&bpp), MakeBitMask(this,2,form,&bpp), 0) ) + return -1; + + D(bug("AFTER screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth)); + + } + + /* Create the appropriate colormap */ +/* + if ( SDL_XColorMap != SDL_DisplayColormap ) { + XFreeColormap(SDL_Display, SDL_XColorMap); + } +*/ + if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) { + int ncolors,i; + D(bug("XPixels palette allocation...\n")); + + /* Allocate the pixel flags */ + + if(bpp==8) + ncolors=256; + else + ncolors = 1 << screen->format->BitsPerPixel; + + SDL_XPixels = (Sint32 *)SDL_malloc(ncolors * sizeof(Sint32)); + + if(SDL_XPixels == NULL) { + SDL_OutOfMemory(); + return -1; + } + + + for(i=0;i<ncolors;i++) + SDL_XPixels[i]=-1; + + /* always allocate a private colormap on non-default visuals */ + if(bpp==8) + flags |= SDL_HWPALETTE; + + if ( flags & SDL_HWPALETTE ) + screen->flags |= SDL_HWPALETTE; + } + + /* resize the (possibly new) window manager window */ + + /* Create (or use) the X11 display window */ + + if ( !SDL_windowid ) { + if( flags & SDL_FULLSCREEN ) + { + SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h, + WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE, + WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE, + WA_CustomScreen,(ULONG)SDL_Display, + TAG_DONE); + + D(bug("Opening backdrop window %ldx%ld on display %lx!\n",w,h,SDL_Display)); + } + else + { + /* Create GimmeZeroZero window when OpenGL is used */ + unsigned long gzz = FALSE; + if( flags & SDL_OPENGL ) { + gzz = TRUE; + } + + SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h, + WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP | ((flags&SDL_NOFRAME) ? 0 : (WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR | ((flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0))), + WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE, + WA_PubScreen,(ULONG)SDL_Display, + WA_GimmeZeroZero, gzz, + TAG_DONE); + D(bug("Opening WB window of size: %ldx%ld!\n",w,h)); + } + + if(!SDL_Window) + return -1; + } + + this->hidden->BytesPerPixel=GetCyberMapAttr(SDL_Window->RPort->BitMap,CYBRMATTR_BPPIX); + + if(screen->flags & SDL_DOUBLEBUF) + { + if(SDL_RastPort=SDL_malloc(sizeof(struct RastPort))) + { + InitRastPort(SDL_RastPort); + SDL_RastPort->BitMap=this->hidden->SB[1]->sb_BitMap; + } + else + return -1; + } + else SDL_RastPort=SDL_Window->RPort; + + if(flags&SDL_HWSURFACE) + screen->flags|=SDL_HWSURFACE; + + if( !SDL_windowid ) { + CGX_SetSizeHints(this, w, h, flags); + } + + /* Set our colormaps when not setting a GL mode */ +/* + if ( ! (flags & SDL_OPENGL) ) { + XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap); + } +*/ + + /* Map them both and go fullscreen, if requested */ + if ( ! SDL_windowid ) { + if ( flags & SDL_FULLSCREEN ) { + screen->flags |= SDL_FULLSCREEN; + currently_fullscreen=1; +// CGX_EnterFullScreen(this); Ci siamo gia'! + } else { + screen->flags &= ~SDL_FULLSCREEN; + } + } + screen->w = w; + screen->h = h; + screen->pitch = SDL_CalculatePitch(screen); + CGX_ResizeImage(this, screen, flags); + + /* Make OpenGL Context if needed*/ + if(flags & SDL_OPENGL) { + if(this->gl_data->gl_active == 0) { + if(CGX_GL_Init(this) < 0) + return -1; + else + screen->flags |= SDL_OPENGL; + } + else { + if(CGX_GL_Update(this) < 0) + return -1; + else + screen->flags |= SDL_OPENGL; + } + } +} + +int CGX_ResizeWindow(_THIS, + SDL_Surface *screen, int w, int h, Uint32 flags) +{ + D(bug("CGX_ResizeWindow\n")); + + if ( ! SDL_windowid ) { + /* Resize the window manager window */ + CGX_SetSizeHints(this, w, h, flags); + + ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight, + h+SDL_Window->BorderTop+SDL_Window->BorderBottom); + + screen->w = w; + screen->h = h; + screen->pitch = SDL_CalculatePitch(screen); + CGX_ResizeImage(this, screen, flags); + } + return(0); +} + +static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + Uint32 saved_flags; + int needcreate=0; + + D(bug("CGX_SetVideoMode current:%lx\n",current)); + + /* Lock the event thread, in multi-threading environments */ + SDL_Lock_EventThread(); + +// Check if the window needs to be closed or can be resized + + if( (flags&SDL_FULLSCREEN) || (current && current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))) + needcreate=1; + +// Check if we need to close an already existing videomode... + + if(current && current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN)) { + unsigned long i; + D(bug("Destroying image, window & screen!\n")); + + CGX_DestroyImage(this,current); + CGX_DestroyWindow(this,current); + DestroyScreen(this); + GFX_Display=SDL_Display=LockPubScreen(NULL); + + bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); + + for ( i = 0; i < this->hidden->nvisuals; i++ ) { + if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ + break; + } + if ( i == this->hidden->nvisuals ) { + SDL_SetError("No matching visual for requested depth"); + return NULL; /* should never happen */ + } + SDL_Visual = this->hidden->visuals[i].visual; + + D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); + + } + /* Check the combination of flags we were passed */ + if ( flags & SDL_FULLSCREEN ) { + int i; + + /* Clear fullscreen flag if not supported */ + if ( SDL_windowid ) { + flags &= ~SDL_FULLSCREEN; + } + else if(current && current->flags&SDL_FULLSCREEN ) { + if(current->w!=width || + current->h!=height || + (this->hidden && this->hidden->depth!=bpp)) + { + D(bug("Deleting previous window...\n")); + CGX_DestroyImage(this,current); + CGX_DestroyWindow(this,current); + DestroyScreen(this); + goto buildnewscreen; + } + } + else +buildnewscreen: + { + Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,width, + CYBRBIDTG_NominalHeight,height, + CYBRBIDTG_Depth,bpp, + TAG_DONE); + + GFX_Display=NULL; + + D(bug("Opening screen...\n")); + + if(okid!=INVALID_ID) + GFX_Display=OpenScreenTags(NULL, + SA_Width,width, + SA_Height,height, + SA_Quiet,TRUE,SA_ShowTitle,FALSE, + SA_Depth,bpp, + SA_DisplayID,okid, + TAG_DONE); + + if(!GFX_Display) { + GFX_Display=SDL_Display; + flags &= ~SDL_FULLSCREEN; + flags &= ~SDL_DOUBLEBUF; + } + else { + UnlockPubScreen(NULL,SDL_Display); + SDL_Display=GFX_Display; + + D(bug("Screen opened.\n")); + + if(flags&SDL_DOUBLEBUF) { + int ok=0; + D(bug("Start of DBuffering allocations...\n")); + + if(this->hidden->SB[0]=AllocScreenBuffer(SDL_Display,NULL,SB_SCREEN_BITMAP)) { + + if(this->hidden->SB[1]=AllocScreenBuffer(SDL_Display,NULL,0L)) { + extern struct MsgPort *safeport,*dispport; + + safeport=CreateMsgPort(); + dispport=CreateMsgPort(); + + if(!safeport || !dispport) { + if(safeport) { + DeleteMsgPort(safeport); + safeport=NULL; + } + if(dispport) { + DeleteMsgPort(dispport); + dispport=NULL; + } + FreeScreenBuffer(SDL_Display,this->hidden->SB[0]); + FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); + } + else { + extern ULONG safe_sigbit,disp_sigbit; + int i; + + safe_sigbit=1L<< safeport->mp_SigBit; + disp_sigbit=1L<< dispport->mp_SigBit; + + for(i=0;i<2;i++) { + this->hidden->SB[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=safeport; + this->hidden->SB[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=dispport; + } + + ok=1; + D(bug("Dbuffering enabled!\n")); + this->hidden->dbuffer=1; + current->flags|=SDL_DOUBLEBUF; + } + } + else { + FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); + this->hidden->SB[0]=NULL; + } + } + + if(!ok) + flags&=~SDL_DOUBLEBUF; + } + } + + if(GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)==bpp) + this->hidden->same_format=1; + } + + bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); + D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); + + for ( i = 0; i < this->hidden->nvisuals; i++ ) + if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ + break; + + if ( i == this->hidden->nvisuals ) { + SDL_SetError("No matching visual for requested depth"); + return NULL; /* should never happen */ + } + SDL_Visual = this->hidden->visuals[i].visual; + + } + + /* Set up the X11 window */ + saved_flags = current->flags; + + if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL) + && bpp == current->format->BitsPerPixel && !needcreate) { + if (CGX_ResizeWindow(this, current, width, height, flags) < 0) { + current = NULL; + goto done; + } + } else { + if (CGX_CreateWindow(this,current,width,height,bpp,flags) < 0) { + current = NULL; + goto done; + } + } + +#if 0 + /* Set up the new mode framebuffer */ + if ( ((current->w != width) || (current->h != height)) || + ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) { + current->w = width; + current->h = height; + current->pitch = SDL_CalculatePitch(current); + CGX_ResizeImage(this, current, flags); + } +#endif + + current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it + + done: + /* Release the event thread */ + SDL_Unlock_EventThread(); + + /* We're done! */ + return(current); +} + +static int CGX_ToggleFullScreen(_THIS, int on) +{ + Uint32 event_thread; + + /* Don't switch if we don't own the window */ + if ( SDL_windowid ) { + return(0); + } + + /* Don't lock if we are the event thread */ + event_thread = SDL_EventThreadID(); + if ( event_thread && (SDL_ThreadID() == event_thread) ) { + event_thread = 0; + } + if ( event_thread ) { + SDL_Lock_EventThread(); + } + if ( on ) { + this->screen->flags |= SDL_FULLSCREEN; + CGX_EnterFullScreen(this); + } else { + this->screen->flags &= ~SDL_FULLSCREEN; + CGX_LeaveFullScreen(this); + } + + CGX_RefreshDisplay(this); + if ( event_thread ) { + SDL_Unlock_EventThread(); + } + + SDL_ResetKeyboard(); + + return(1); +} + +static void SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b, unsigned char *c) +{ + switch(fmt) + { + case PIXFMT_BGR15: + case PIXFMT_RGB15PC: + { + Uint16 *t=(Uint16 *)c; + *t=(r>>3) | ((g>>3)<<5) | ((b>>3)<<10) ; + } + break; + case PIXFMT_RGB15: + case PIXFMT_BGR15PC: + { + Uint16 *t=(Uint16 *)c; + *t=(b>>3) | ((g>>3)<<5) | ((r>>3)<<10) ; + } + break; + case PIXFMT_BGR16PC: + case PIXFMT_RGB16: + { + Uint16 *t=(Uint16 *)c; + *t=(b>>3) | ((g>>2)<<5) | ((r>>3)<<11) ; + } + break; + case PIXFMT_BGR16: + case PIXFMT_RGB16PC: + { + Uint16 *t=(Uint16 *)c; + *t=(r>>3) | ((g>>2)<<5) | ((b>>3)<<11) ; + } + break; + case PIXFMT_RGB24: + c[0]=r; + c[1]=g; + c[2]=b; + c[3]=0; + break; + case PIXFMT_BGR24: + c[0]=b; + c[1]=g; + c[2]=r; + c[3]=0; + break; + case PIXFMT_ARGB32: + c[0]=0; + c[1]=r; + c[2]=g; + c[3]=b; + break; + case PIXFMT_BGRA32: + c[0]=b; + c[1]=g; + c[2]=r; + c[3]=0; + break; + case PIXFMT_RGBA32: + c[0]=r; + c[1]=g; + c[2]=b; + c[3]=0; + break; + + default: + D(bug("Error, SetSingleColor with PIXFMT %ld!\n",fmt)); + } +} + +/* Update the current mouse state and position */ +static void CGX_UpdateMouse(_THIS) +{ + /* Lock the event thread, in multi-threading environments */ + SDL_Lock_EventThread(); + + if(currently_fullscreen) + { + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX, SDL_Display->MouseY); + } + else + { + if( SDL_Display->MouseX>=(SDL_Window->LeftEdge+SDL_Window->BorderLeft) && SDL_Display->MouseX<(SDL_Window->LeftEdge+SDL_Window->Width-SDL_Window->BorderRight) && + SDL_Display->MouseY>=(SDL_Window->TopEdge+SDL_Window->BorderLeft) && SDL_Display->MouseY<(SDL_Window->TopEdge+SDL_Window->Height-SDL_Window->BorderBottom) + ) + { + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX-SDL_Window->LeftEdge-SDL_Window->BorderLeft, + SDL_Display->MouseY-SDL_Window->TopEdge-SDL_Window->BorderTop); + } + else + { + SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + } + } + SDL_Unlock_EventThread(); +} + +static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + int i; + + /* Check to make sure we have a colormap allocated */ + + /* It's easy if we have a hidden colormap */ + if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen ) + { + ULONG xcmap[256*3+2]; + + xcmap[0]=(ncolors<<16); + xcmap[0]+=firstcolor; + +// D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors)); + + for ( i=0; i<ncolors; i++ ) { + xcmap[i*3+1] = colors[i+firstcolor].r<<24; + xcmap[i*3+2] = colors[i+firstcolor].g<<24; + xcmap[i*3+3] = colors[i+firstcolor].b<<24; + } + xcmap[ncolors*3+1]=0; + LoadRGB32(&GFX_Display->ViewPort,xcmap); + } else { +// XPixels are not needed on 8bit screen with hwpalette + unsigned long pixel; + + if ( SDL_XPixels == NULL ) { + D(bug("SetColors without colormap!")); + return(0); + } + + if(this->hidden->depth==8) + { +// In this case I have to unalloc and realloc the full palette + D(bug("Obtaining %ld colors on the screen\n",ncolors)); + + /* Free existing allocated colors */ + for ( pixel=0; pixel<this->screen->format->palette->ncolors; ++pixel ) { + if(SDL_XPixels[pixel]>=0) + ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]); + } + + /* Try to allocate all the colors */ + for ( i=0; i<this->screen->format->palette->ncolors; ++i ) { + SDL_XPixels[i]=ObtainBestPenA(GFX_Display->ViewPort.ColorMap,colors[i].r<<24,colors[i].g<<24,colors[i].b<<24,NULL); + } + } + else + { +#ifndef USE_CGX_WRITELUTPIXEL + Uint32 fmt; + D(bug("Preparing a conversion pixel table...\n")); + + fmt=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT); + + for(i=0;i<ncolors;i++) + { + SetSingleColor(fmt,colors[firstcolor+i].r,colors[firstcolor+i].g,colors[firstcolor+i].b,(unsigned char *)&SDL_XPixels[firstcolor+i]); + } +#else +// D(bug("Executing XPixel(%lx) remapping: (from %ld, %ld colors) first: r%ld g%ld b%ld\n",SDL_XPixels,firstcolor,ncolors,colors[firstcolor].r,colors[firstcolor].g,colors[firstcolor].b)); + for(i=0;i<ncolors;i++) + SDL_XPixels[i+firstcolor]=(colors[firstcolor+i].r<<16)+(colors[firstcolor+i].g<<8)+colors[firstcolor+i].b; +#endif + } + } + +// Actually it cannot fail! + + return 1; +} + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +static void CGX_VideoQuit(_THIS) +{ + /* Shutdown everything that's still up */ + /* The event thread should be done, so we can touch SDL_Display */ + D(bug("CGX_VideoQuit\n")); + + if ( SDL_Display != NULL ) { + /* Clean up OpenGL */ + if(this->gl_data->gl_active == 1) { + CGX_GL_Quit(this); + } + /* Start shutting down the windows */ + D(bug("Destroying image...\n")); + CGX_DestroyImage(this, this->screen); + D(bug("Destroying window...\n")); + CGX_DestroyWindow(this, this->screen); +// Otherwise SDL_VideoQuit will try to free it! + SDL_VideoSurface=NULL; + + CGX_FreeVideoModes(this); + + /* Free that blank cursor */ + if ( SDL_BlankCursor != NULL ) { + FreeMem(SDL_BlankCursor,16); + SDL_BlankCursor = NULL; + } + + /* Close the X11 graphics connection */ + this->hidden->same_format=0; + + D(bug("Destroying screen...\n")); + + if ( GFX_Display != NULL ) + DestroyScreen(this); + + /* Close the X11 display connection */ + SDL_Display = NULL; + + /* Unload GL library after X11 shuts down */ + } + + D(bug("Closing libraries...\n")); + + if( CyberGfxBase) { + CloseLibrary(CyberGfxBase); + CyberGfxBase=NULL; + } + + if (IntuitionBase) { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase=NULL; + } + if (GfxBase) { + CloseLibrary((struct Library *)GfxBase); + GfxBase=NULL; + } + + if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { + /* Direct screen access, no memory buffer */ + this->screen->pixels = NULL; + } + D(bug("End of CGX_VideoQuit.\n")); + +} + |