2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * CGX based SDL video driver implementation by Gabriele Greco
30 * gabriele.greco@aruba.it
38 #include <sys/ioctl.h>
41 #include <sys/fcntl.h>
46 #include "SDL_error.h"
47 #include "SDL_timer.h"
48 #include "SDL_thread.h"
49 #include "SDL_video.h"
50 #include "SDL_mouse.h"
51 #include "SDL_endian.h"
52 #include "SDL_sysvideo.h"
53 #include "SDL_pixels_c.h"
54 #include "SDL_events_c.h"
55 #include "SDL_cgxgl_c.h"
56 #include "SDL_cgxvideo.h"
57 #include "SDL_cgxwm_c.h"
58 #include "SDL_amigamouse_c.h"
59 #include "SDL_amigaevents_c.h"
60 #include "SDL_cgxmodes_c.h"
61 #include "SDL_cgximage_c.h"
62 #include "SDL_cgxyuv_c.h"
66 #include <proto/alib.h>
69 /* Initialization/Query functions */
70 static int CGX_VideoInit(_THIS
, SDL_PixelFormat
*vformat
);
71 static SDL_Surface
*CGX_SetVideoMode(_THIS
, SDL_Surface
*current
, int width
, int height
, int bpp
, Uint32 flags
);
72 static int CGX_ToggleFullScreen(_THIS
, int on
);
73 static void CGX_UpdateMouse(_THIS
);
74 static int CGX_SetColors(_THIS
, int firstcolor
, int ncolors
, SDL_Color
*colors
);
75 static void CGX_VideoQuit(_THIS
);
77 /* CGX driver bootstrap functions */
79 struct Library
*CyberGfxBase
=NULL
;
80 struct IntuitionBase
*IntuitionBase
=NULL
;
81 struct GfxBase
*GfxBase
=NULL
;
83 int CGX_SetGamma(_THIS
, float red
, float green
, float blue
)
85 SDL_SetError("Gamma correction not supported");
89 int CGX_GetGamma(_THIS
, float red
, float green
, float blue
)
91 SDL_SetError("Gamma correction not supported");
95 int CGX_SetGammaRamp(_THIS
, Uint16
*ramp
)
101 /* See if actually setting the gamma is supported */
102 if ( SDL_Visual
->class != DirectColor
) {
103 SDL_SetError("Gamma correction not supported on this visual");
107 /* Calculate the appropriate palette for the given gamma ramp */
108 ncolors
= SDL_Visual
->map_entries
;
109 for ( i
=0; i
<ncolors
; ++i
) {
110 Uint8 c
= (256 * i
/ ncolors
);
111 xcmap
[i
].pixel
= SDL_MapRGB(this->screen
->format
, c
, c
, c
);
112 xcmap
[i
].red
= ramp
[0*256+c
];
113 xcmap
[i
].green
= ramp
[1*256+c
];
114 xcmap
[i
].blue
= ramp
[2*256+c
];
115 xcmap
[i
].flags
= (DoRed
|DoGreen
|DoBlue
);
117 XStoreColors(GFX_Display
, SDL_XColorMap
, xcmap
, ncolors
);
118 XSync(GFX_Display
, False
);
123 SDL_SetError("Gamma correction not supported on this visual");
129 static void DestroyScreen(_THIS
)
131 if(currently_fullscreen
)
133 if(this->hidden
->dbuffer
)
135 extern struct MsgPort
*safeport
,*dispport
;
137 this->hidden
->dbuffer
=0;
141 while(GetMsg(safeport
)!=NULL
);
142 DeleteMsgPort(safeport
);
146 while(GetMsg(dispport
)!=NULL
);
147 DeleteMsgPort(dispport
);
150 this->hidden
->SB
[0]->sb_DBufInfo
->dbi_SafeMessage
.mn_ReplyPort
=
151 this->hidden
->SB
[0]->sb_DBufInfo
->dbi_DispMessage
.mn_ReplyPort
=NULL
;
152 this->hidden
->SB
[1]->sb_DBufInfo
->dbi_SafeMessage
.mn_ReplyPort
=
153 this->hidden
->SB
[1]->sb_DBufInfo
->dbi_DispMessage
.mn_ReplyPort
=NULL
;
155 if(this->hidden
->SB
[1])
156 FreeScreenBuffer(SDL_Display
,this->hidden
->SB
[1]);
157 if(this->hidden
->SB
[0])
158 FreeScreenBuffer(SDL_Display
,this->hidden
->SB
[0]);
161 this->hidden
->SB
[0]=this->hidden
->SB
[1]=NULL
;
163 if(SDL_RastPort
&& SDL_RastPort
!= &SDL_Display
->RastPort
)
168 CloseScreen(GFX_Display
);
169 currently_fullscreen
=0;
172 UnlockPubScreen(NULL
,GFX_Display
);
177 static int CGX_Available(void)
181 l
= OpenLibrary("cybergraphics.library",0L);
184 D(bug("CGX video device AVAILABLE\n"));
187 D(else bug("**CGX video device UNAVAILABLE\n"));
192 static void CGX_DeleteDevice(SDL_VideoDevice
*device
)
195 if ( device
->hidden
) {
196 free(device
->hidden
);
198 if ( device
->gl_data
) {
199 free(device
->gl_data
);
205 static SDL_VideoDevice
*CGX_CreateDevice(int devindex
)
207 SDL_VideoDevice
*device
;
209 /* Initialize all variables that we clean on shutdown */
210 device
= (SDL_VideoDevice
*)malloc(sizeof(SDL_VideoDevice
));
212 memset(device
, 0, (sizeof *device
));
213 device
->hidden
= (struct SDL_PrivateVideoData
*)
214 malloc((sizeof *device
->hidden
));
215 device
->gl_data
= (struct SDL_PrivateGLData
*)
216 malloc((sizeof *device
->gl_data
));
218 if ( (device
== NULL
) || (device
->hidden
== NULL
) ||
219 (device
->gl_data
== NULL
) ) {
220 D(bug("Unable to create video device!\n"));
222 CGX_DeleteDevice(device
);
225 memset(device
->hidden
, 0, sizeof(*device
->hidden
));
226 memset(device
->gl_data
, 0, sizeof(*device
->gl_data
));
228 /* Set the driver flags */
229 device
->handles_any_size
= 1;
231 /* Set the function pointers */
232 device
->VideoInit
= CGX_VideoInit
;
233 device
->ListModes
= CGX_ListModes
;
234 device
->SetVideoMode
= CGX_SetVideoMode
;
235 device
->ToggleFullScreen
= CGX_ToggleFullScreen
;
236 device
->UpdateMouse
= CGX_UpdateMouse
;
238 device
->CreateYUVOverlay
= X11_CreateYUVOverlay
;
240 device
->SetColors
= CGX_SetColors
;
241 device
->UpdateRects
= NULL
;
242 device
->VideoQuit
= CGX_VideoQuit
;
243 device
->AllocHWSurface
= CGX_AllocHWSurface
;
244 device
->CheckHWBlit
= CGX_CheckHWBlit
;
245 device
->FillHWRect
= CGX_FillHWRect
;
246 device
->SetHWColorKey
= CGX_SetHWColorKey
;
247 device
->SetHWAlpha
= NULL
;
248 device
->LockHWSurface
= CGX_LockHWSurface
;
249 device
->UnlockHWSurface
= CGX_UnlockHWSurface
;
250 device
->FlipHWSurface
= CGX_FlipHWSurface
;
251 device
->FreeHWSurface
= CGX_FreeHWSurface
;
252 device
->SetGamma
= CGX_SetGamma
;
253 device
->GetGamma
= CGX_GetGamma
;
254 device
->SetGammaRamp
= CGX_SetGammaRamp
;
255 device
->GetGammaRamp
= NULL
;
257 device
->GL_LoadLibrary
= CGX_GL_LoadLibrary
;
258 device
->GL_GetProcAddress
= CGX_GL_GetProcAddress
;
259 device
->GL_GetAttribute
= CGX_GL_GetAttribute
;
260 device
->GL_MakeCurrent
= CGX_GL_MakeCurrent
;
261 device
->GL_SwapBuffers
= CGX_GL_SwapBuffers
;
263 device
->SetIcon
= CGX_SetIcon
;
264 device
->SetCaption
= CGX_SetCaption
;
265 device
->IconifyWindow
= NULL
; /* CGX_IconifyWindow; */
266 device
->GrabInput
= NULL
/* CGX_GrabInput*/;
267 device
->GetWMInfo
= CGX_GetWMInfo
;
268 device
->FreeWMCursor
= amiga_FreeWMCursor
;
269 device
->CreateWMCursor
= amiga_CreateWMCursor
;
270 device
->ShowWMCursor
= amiga_ShowWMCursor
;
271 device
->WarpWMCursor
= amiga_WarpWMCursor
;
272 device
->CheckMouseMode
= amiga_CheckMouseMode
;
273 device
->InitOSKeymap
= amiga_InitOSKeymap
;
274 device
->PumpEvents
= amiga_PumpEvents
;
276 device
->free
= CGX_DeleteDevice
;
281 VideoBootStrap CGX_bootstrap
= {
282 "CGX", "AmigaOS CyberGraphics", CGX_Available
, CGX_CreateDevice
285 #include <aros/macros.h>
287 #warning FIXME: Endianess issues here. Temporarily used AROS_BE2WORD() to get around them
288 Uint32
MakeBitMask(_THIS
,int type
,int format
,int *bpp
)
290 if (this->hidden
->depth
==*bpp
) {
291 D(if(type
==0)bug("REAL pixel format: "));
295 D(if(type
==0)bug("LUT8\n"));
301 return AROS_BE2WORD(0x001f);
303 return AROS_BE2WORD(0x03e0);
305 return AROS_BE2WORD(0x7c00);
311 return AROS_BE2WORD(0x7c00);
313 return AROS_BE2WORD(0x03e0);
315 return AROS_BE2WORD(0x001f);
321 return AROS_BE2WORD(0x007c);
323 return AROS_BE2WORD(0xe003);
325 return AROS_BE2WORD(0x1f00);
331 return AROS_BE2WORD(0x1f00);
333 return AROS_BE2WORD(0xe003);
335 return AROS_BE2WORD(0x007c);
341 return AROS_BE2WORD(0xf800);
343 return AROS_BE2WORD(0x07e0);
345 return AROS_BE2WORD(0x001f);
351 return AROS_BE2WORD(0x001f);
353 return AROS_BE2WORD(0x07e0);
355 return AROS_BE2WORD(0xf800);
361 return AROS_BE2WORD(0x00f8);
363 return AROS_BE2WORD(0xe007);
365 return AROS_BE2WORD(0x1f00);
371 return AROS_BE2WORD(0x1f00);
373 return AROS_BE2WORD(0xe007);
375 return AROS_BE2WORD(0x00f8);
381 D(bug("RGB24/BGR24\n"));
382 return AROS_BE2LONG(0x00ff0000);
384 return AROS_BE2LONG(0x0000ff00);
386 return AROS_BE2LONG(0x000000ff);
392 return AROS_BE2LONG(0x000000ff);
394 return AROS_BE2LONG(0x0000ff00);
396 return AROS_BE2LONG(0x00ff0000);
402 return AROS_BE2LONG(0x00ff0000);
404 return AROS_BE2LONG(0x0000ff00);
406 return AROS_BE2LONG(0x000000ff);
412 return AROS_BE2LONG(0xff000000);
414 return AROS_BE2LONG(0x00ff0000);
416 return AROS_BE2LONG(0x0000ff00);
422 return AROS_BE2LONG(0x0000ff00);
424 return AROS_BE2LONG(0x00ff0000);
426 return AROS_BE2LONG(0xff000000);
429 D(bug("Unknown pixel format! Default to 24bit\n"));
430 return (Uint32
) (255<<(type
*8));
433 D(if(type
==0)bug("DIFFERENT from screen.\nAllocated screen format: "));
438 D(if(type
==0) bug("RGBA32\n"));
464 D(if(type
==0) bug("Not supported, switching to 24bit!\n"));
469 D(if(type
==0)bug("This is a chunky display\n"));
470 // For chunky display mask is always 0;
477 static int CGX_VideoInit(_THIS
, SDL_PixelFormat
*vformat
)
482 struct Library
*RTGBase
;
485 D(bug("VideoInit... Opening libraries\n"));
488 if( !(IntuitionBase
=(struct IntuitionBase
*)OpenLibrary("intuition.library",39L))) {
489 SDL_SetError("Couldn't open intuition V39+");
495 if( !(GfxBase
=(struct GfxBase
*)OpenLibrary("graphics.library",39L))) {
496 SDL_SetError("Couldn't open graphics V39+");
502 if( !(CyberGfxBase
=OpenLibrary("cybergraphics.library",40L))) {
503 SDL_SetError("Couldn't open cybergraphics.");
508 // check if P96 is present and if we don't need the fix
510 test
= getenv("USE_P96_FIX");
512 if(test
&& *test
!= '0') {
513 if(RTGBase
=OpenLibrary("libs:picasso96/rtg.library",0L)) {
514 extern int use_picasso96
;
516 CloseLibrary(RTGBase
);
522 D(bug("Library intialized, locking screen...\n"));
524 SDL_Display
= LockPubScreen(NULL
);
526 if ( SDL_Display
== NULL
) {
527 D(bug("Cannot lock display...\n"));
528 SDL_SetError("Couldn't lock the display");
532 D(bug("Checking if we are using a CGX native display...\n"));
534 if(!IsCyberModeID(GetVPModeID(&SDL_Display
->ViewPort
)))
536 Uint32 okid
=BestCModeIDTags(CYBRBIDTG_NominalWidth
,SDL_Display
->Width
,
537 CYBRBIDTG_NominalHeight
,SDL_Display
->Height
,
541 D(bug("Default visual is not CGX native!\n"));
543 UnlockPubScreen(NULL
,SDL_Display
);
549 GFX_Display
=OpenScreenTags(NULL
,
550 SA_Width
,SDL_Display
->Width
,
551 SA_Height
,SDL_Display
->Height
,
552 SA_Depth
,8,SA_Quiet
,TRUE
,
560 SDL_SetError("Unable to open a suited CGX display");
563 else SDL_Display
=GFX_Display
;
566 else GFX_Display
= SDL_Display
;
569 /* See whether or not we need to swap pixels */
573 // Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente
575 if ( SDL_BYTEORDER
== SDL_LIL_ENDIAN
) {
579 D(bug("Before GetVideoModes....\n"));
581 /* Get the available video modes */
582 if(CGX_GetVideoModes(this) < 0)
585 /* Determine the default screen depth:
586 Use the default visual (or at least one with the same depth) */
588 for(i
= 0; i
< this->hidden
->nvisuals
; i
++)
589 if(this->hidden
->visuals
[i
].depth
== GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_DEPTH
))
591 if(i
== this->hidden
->nvisuals
) {
592 /* default visual was useless, take the deepest one instead */
595 SDL_Visual
= this->hidden
->visuals
[i
].visual
;
597 // SDL_XColorMap = SDL_DisplayColormap;
599 this->hidden
->depth
= this->hidden
->visuals
[i
].depth
;
600 D(bug("Init: Setting screen depth to: %ld\n",this->hidden
->depth
));
601 vformat
->BitsPerPixel
= this->hidden
->visuals
[i
].depth
; /* this->hidden->visuals[i].bpp; */
604 int form
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,SDL_Visual
);
606 // In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask
608 if ( vformat
->BitsPerPixel
> 8 )
610 vformat
->Rmask
= MakeBitMask(this,0,form
,&this->hidden
->depth
);
611 vformat
->Gmask
= MakeBitMask(this,1,form
,&this->hidden
->depth
);
612 vformat
->Bmask
= MakeBitMask(this,2,form
,&this->hidden
->depth
);
616 /* See if we have been passed a window to use */
617 SDL_windowid
= getenv("SDL_WINDOWID");
618 // SDL_windowid=NULL;
620 /* Create the blank cursor */
621 SDL_BlankCursor
= AllocMem(16,MEMF_CHIP
|MEMF_CLEAR
);
623 /* Fill in some window manager capabilities */
624 this->info
.wm_available
= 1;
625 this->info
.blit_hw
= 1;
626 this->info
.blit_hw_CC
= 1;
627 this->info
.blit_sw
= 1;
628 this->info
.blit_fill
= 1;
629 this->info
.video_mem
=2000; // Not always true but almost any Amiga card has this memory!
631 this->hidden
->same_format
=0;
632 SDL_RastPort
=&SDL_Display
->RastPort
;
634 D(bug("End of CGX_VideoInit\n"));
639 void CGX_DestroyWindow(_THIS
, SDL_Surface
*screen
)
641 D(bug("Destroy Window...\n"));
643 if ( ! SDL_windowid
) {
644 /* Hide the managed window */
645 int was_fullscreen
=0;
647 /* Clean up OpenGL */
649 screen
->flags
&= ~(SDL_OPENGL
|SDL_OPENGLBLIT
);
652 if ( screen
&& (screen
->flags
& SDL_FULLSCREEN
) ) {
654 screen
->flags
&= ~SDL_FULLSCREEN
;
655 // CGX_LeaveFullScreen(this); tolto x crash
658 /* Destroy the output window */
660 CloseWindow(SDL_Window
);
664 /* Free the colormap entries */
669 if(this->screen
->format
&&this->hidden
->depth
==8&&!was_fullscreen
)
671 numcolors
= 1<<this->screen
->format
->BitsPerPixel
;
676 if(!was_fullscreen
&&this->hidden
->depth
==8)
678 for ( pixel
=0; pixel
<numcolors
; pixel
++ )
680 if(SDL_XPixels
[pixel
]>=0)
681 ReleasePen(GFX_Display
->ViewPort
.ColorMap
,SDL_XPixels
[pixel
]);
691 static void CGX_SetSizeHints(_THIS
, int w
, int h
, Uint32 flags
)
693 if ( flags
& SDL_RESIZABLE
) {
694 WindowLimits(SDL_Window
, 32, 32,4096,4096);
696 WindowLimits(SDL_Window
, w
,h
,w
,h
);
698 if ( flags
& SDL_FULLSCREEN
) {
699 flags
&=~SDL_RESIZABLE
;
700 } else if ( getenv("SDL_VIDEO_CENTERED") ) {
701 int display_w
, display_h
;
703 display_w
= SDL_Display
->Width
;
704 display_h
= SDL_Display
->Height
;
705 ChangeWindowBox(SDL_Window
,(display_w
- w
- SDL_Window
->BorderLeft
-SDL_Window
->BorderRight
)/2,
706 (display_h
- h
- SDL_Window
->BorderTop
-SDL_Window
->BorderBottom
)/2,
707 w
+SDL_Window
->BorderLeft
+SDL_Window
->BorderRight
,
708 h
+SDL_Window
->BorderTop
+SDL_Window
->BorderBottom
);
712 int CGX_CreateWindow(_THIS
, SDL_Surface
*screen
,
713 int w
, int h
, int bpp
, Uint32 flags
)
715 Uint32 form
, rb
, gb
, bb
;
717 D(bug("CGX_CreateWindow\n"));
719 /* If a window is already present, destroy it and start fresh */
721 CGX_DestroyWindow(this, screen
);
723 /* See if we have been given a window id */
725 SDL_Window
= (struct Window
*)atol(SDL_windowid
);
729 /* Allocate the new pixel format for this video mode */
731 form
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,SDL_Visual
);
733 if (flags
&SDL_HWSURFACE
&& bpp
!=this->hidden
->depth
) {
734 bpp
=this->hidden
->depth
;
735 D(bug("Accel forces bpp to be equal (%ld)\n",bpp
));
738 D(bug("BEFORE screen allocation: bpp:%ld (real:%ld)\n",bpp
,this->hidden
->depth
));
742 * With this call if needed I'll revert the wanted bpp to a bpp best
743 * suited for the display, actually occurs
744 * only with requested format 15/16bit and display format != 15/16bit
746 rb
= MakeBitMask(this,0,form
,&bpp
);
747 gb
= MakeBitMask(this,1,form
,&bpp
);
748 bb
= MakeBitMask(this,2,form
,&bpp
);
750 if ( ! SDL_ReallocFormat(screen
, 8 * GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_BPPIX
)
754 D(bug("AFTER screen allocation: bpp:%ld (real:%ld)\n",
756 this->hidden
->depth
));
759 /* Create the appropriate colormap */
760 if ( GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
, CYBRMATTR_PIXFMT
)
764 D(bug("XPixels palette allocation...\n"));
766 /* Allocate the pixel flags */
771 ncolors
= 1 << screen
->format
->BitsPerPixel
;
773 SDL_XPixels
= (Sint32
*)malloc(ncolors
* sizeof(Sint32
));
775 if(SDL_XPixels
== NULL
) {
781 for(i
=0;i
<ncolors
;i
++)
784 /* always allocate a private colormap on non-default visuals */
786 flags
|= SDL_HWPALETTE
;
788 if ( flags
& SDL_HWPALETTE
)
789 screen
->flags
|= SDL_HWPALETTE
;
792 /* resize the (possibly new) window manager window */
794 /* Create (or use) the X11 display window */
796 if ( !SDL_windowid
) {
797 if ( flags
& SDL_FULLSCREEN
) {
798 SDL_Window
= OpenWindowTags(NULL
,WA_Width
,w
,WA_Height
,h
,
799 WA_Flags
,WFLG_ACTIVATE
|WFLG_RMBTRAP
|WFLG_BORDERLESS
|WFLG_BACKDROP
|WFLG_REPORTMOUSE
,
800 WA_IDCMP
,IDCMP_RAWKEY
|IDCMP_MOUSEBUTTONS
|IDCMP_MOUSEMOVE
,
801 WA_CustomScreen
,(ULONG
)SDL_Display
,
804 D(bug("Opening backdrop window %ldx%ld on display %lx!\n",w
,h
,SDL_Display
));
807 /* Create GimmeZeroZero window when OpenGL is used */
808 unsigned long gzz
= FALSE
;
809 if( flags
& SDL_OPENGL
)
812 SDL_Window
= OpenWindowTags(NULL
,WA_InnerWidth
,w
,WA_InnerHeight
,h
,
813 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))),
814 WA_IDCMP
,IDCMP_RAWKEY
|IDCMP_CLOSEWINDOW
|IDCMP_MOUSEBUTTONS
|IDCMP_NEWSIZE
|IDCMP_MOUSEMOVE
,
815 WA_PubScreen
,(ULONG
)SDL_Display
,
816 WA_GimmeZeroZero
, gzz
,
818 D(bug("Opening WB window of size: %ldx%ld!\n",w
,h
));
825 this->hidden
->BytesPerPixel
=
826 GetCyberMapAttr(SDL_Window
->RPort
->BitMap
,CYBRMATTR_BPPIX
);
828 if(screen
->flags
& SDL_DOUBLEBUF
) {
829 if((SDL_RastPort
=malloc(sizeof(struct RastPort
)))) {
830 InitRastPort(SDL_RastPort
);
831 SDL_RastPort
->BitMap
=this->hidden
->SB
[1]->sb_BitMap
;
836 else SDL_RastPort
= SDL_Window
->RPort
;
838 if(flags
&SDL_HWSURFACE
)
839 screen
->flags
|=SDL_HWSURFACE
;
841 if( !SDL_windowid
) {
842 CGX_SetSizeHints(this, w
, h
, flags
);
847 /* Map them both and go fullscreen, if requested */
848 if ( ! SDL_windowid
) {
849 if ( flags
& SDL_FULLSCREEN
) {
850 screen
->flags
|= SDL_FULLSCREEN
;
851 currently_fullscreen
=1;
852 // CGX_EnterFullScreen(this); Ci siamo gia'!
854 screen
->flags
&= ~SDL_FULLSCREEN
;
859 screen
->pitch
= SDL_CalculatePitch(screen
);
860 CGX_ResizeImage(this, screen
, flags
);
862 /* Make OpenGL Context if needed*/
863 if(flags
& SDL_OPENGL
) {
864 if(this->gl_data
->gl_active
== 0) {
865 if(CGX_GL_Init(this) < 0)
868 screen
->flags
|= SDL_OPENGL
;
871 if(CGX_GL_Update(this) < 0)
874 screen
->flags
|= SDL_OPENGL
;
881 int CGX_ResizeWindow(_THIS
,
882 SDL_Surface
*screen
, int w
, int h
, Uint32 flags
)
884 D(bug("CGX_ResizeWindow\n"));
886 if ( ! SDL_windowid
) {
887 /* Resize the window manager window */
888 CGX_SetSizeHints(this, w
, h
, flags
);
892 ChangeWindowBox(SDL_Window
,SDL_Window
->LeftEdge
,SDL_Window
->TopEdge
,
893 w
+SDL_Window
->BorderLeft
+SDL_Window
->BorderRight
,
894 h
+SDL_Window
->BorderTop
+SDL_Window
->BorderBottom
);
898 screen
->pitch
= SDL_CalculatePitch(screen
);
899 CGX_ResizeImage(this, screen
, flags
);
905 static SDL_Surface
*CGX_SetVideoMode(_THIS
, SDL_Surface
*current
,
906 int width
, int height
, int bpp
, Uint32 flags
)
911 D(bug("CGX_SetVideoMode current:%lx\n",current
));
913 /* Lock the event thread, in multi-threading environments */
914 SDL_Lock_EventThread();
916 // Check if the window needs to be closed or can be resized
918 if( (flags
&SDL_FULLSCREEN
) || (current
&& current
->flags
&SDL_FULLSCREEN
&& !(flags
&SDL_FULLSCREEN
)))
921 // Check if we need to close an already existing videomode...
923 if(current
&& current
->flags
&SDL_FULLSCREEN
&& !(flags
&SDL_FULLSCREEN
)) {
925 D(bug("Destroying image, window & screen!\n"));
927 CGX_DestroyImage(this,current
);
928 CGX_DestroyWindow(this,current
);
930 GFX_Display
=SDL_Display
=LockPubScreen(NULL
);
932 bpp
=this->hidden
->depth
=GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_DEPTH
);
934 for ( i
= 0; i
< this->hidden
->nvisuals
; i
++ ) {
935 if ( this->hidden
->visuals
[i
].depth
== bpp
) /* era .depth */
938 if ( i
== this->hidden
->nvisuals
) {
939 SDL_SetError("No matching visual for requested depth");
940 return NULL
; /* should never happen */
942 SDL_Visual
= this->hidden
->visuals
[i
].visual
;
944 D(bug("Setting screen depth to: %ld\n",this->hidden
->depth
));
947 /* Check the combination of flags we were passed */
948 if ( flags
& SDL_FULLSCREEN
) {
951 /* Clear fullscreen flag if not supported */
952 if ( SDL_windowid
) {
953 flags
&= ~SDL_FULLSCREEN
;
955 else if (current
&& current
->flags
&SDL_FULLSCREEN
) {
956 if (current
->w
!= width
||
957 current
->h
!= height
||
958 (this->hidden
&& this->hidden
->depth
!=bpp
))
960 D(bug("Deleting previous window...\n"));
961 CGX_DestroyImage(this,current
);
962 CGX_DestroyWindow(this,current
);
970 Uint32 okid
=BestCModeIDTags(CYBRBIDTG_NominalWidth
,width
,
971 CYBRBIDTG_NominalHeight
,height
,
977 D(bug("Opening screen %dx%d/%d...\n", width
, height
, bpp
));
980 GFX_Display
=OpenScreenTags(NULL
,
983 SA_Quiet
,TRUE
,SA_ShowTitle
,FALSE
,
989 GFX_Display
= SDL_Display
;
990 flags
&= ~SDL_FULLSCREEN
;
991 flags
&= ~SDL_DOUBLEBUF
;
994 UnlockPubScreen(NULL
,SDL_Display
);
995 SDL_Display
=GFX_Display
;
997 D(bug("Screen opened: %d x %d.\n", GFX_Display
->Width
, GFX_Display
->Height
));
999 if(flags
&SDL_DOUBLEBUF
) {
1001 D(bug("Start of DBuffering allocations...\n"));
1003 if((this->hidden
->SB
[0]=AllocScreenBuffer(SDL_Display
,NULL
,SB_SCREEN_BITMAP
))) {
1005 if((this->hidden
->SB
[1]=AllocScreenBuffer(SDL_Display
,NULL
,0L))) {
1006 extern struct MsgPort
*safeport
,*dispport
;
1008 safeport
=CreateMsgPort();
1009 dispport
=CreateMsgPort();
1011 if(!safeport
|| !dispport
) {
1013 DeleteMsgPort(safeport
);
1017 DeleteMsgPort(dispport
);
1020 FreeScreenBuffer(SDL_Display
,this->hidden
->SB
[0]);
1021 FreeScreenBuffer(SDL_Display
,this->hidden
->SB
[1]);
1024 extern ULONG safe_sigbit
,disp_sigbit
;
1027 safe_sigbit
=1L<< safeport
->mp_SigBit
;
1028 disp_sigbit
=1L<< dispport
->mp_SigBit
;
1031 this->hidden
->SB
[i
]->sb_DBufInfo
->dbi_SafeMessage
.mn_ReplyPort
=safeport
;
1032 this->hidden
->SB
[i
]->sb_DBufInfo
->dbi_DispMessage
.mn_ReplyPort
=dispport
;
1036 D(bug("Dbuffering enabled!\n"));
1037 this->hidden
->dbuffer
=1;
1040 current
->flags
|=SDL_DOUBLEBUF
;
1044 FreeScreenBuffer(SDL_Display
,this->hidden
->SB
[1]);
1045 this->hidden
->SB
[0]=NULL
;
1050 flags
&= ~SDL_DOUBLEBUF
;
1054 D(bug("Screen bitmap: %ld (%ld), bpp %ld\n",
1055 GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_BPPIX
),
1056 GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_DEPTH
),
1059 if (bpp
== GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_BPPIX
) * 8) {
1060 this->hidden
->same_format
= 1; // XXX check also pixfmt?
1061 D(bug("SAME FORMAT bitmap -> Using RAW blits!\n"));
1065 bpp
=this->hidden
->depth
=
1066 GetCyberMapAttr(SDL_Display
->RastPort
.BitMap
,CYBRMATTR_DEPTH
);
1068 D(bug("Setting screen depth to: %ld\n",this->hidden
->depth
));
1070 for ( i
= 0; i
< this->hidden
->nvisuals
; i
++ )
1071 if ( this->hidden
->visuals
[i
].depth
== bpp
) /* era .depth */
1074 if ( i
== this->hidden
->nvisuals
) {
1075 SDL_SetError("No matching visual for requested depth");
1076 return NULL
; /* should never happen */
1078 SDL_Visual
= this->hidden
->visuals
[i
].visual
;
1082 /* Set up the X11 window */
1083 saved_flags
= current
->flags
;
1085 if (SDL_Window
&& (saved_flags
&SDL_OPENGL
) == (flags
&SDL_OPENGL
)
1086 && bpp
== current
->format
->BitsPerPixel
&& !needcreate
) {
1087 if (CGX_ResizeWindow(this, current
, width
, height
, flags
) < 0) {
1092 if (CGX_CreateWindow(this,current
,width
,height
,bpp
,flags
) < 0) {
1098 current
->flags
|= (flags
&SDL_RESIZABLE
); // Resizable only if the user asked it
1101 /* Release the event thread */
1102 SDL_Unlock_EventThread();
1108 static int CGX_ToggleFullScreen(_THIS
, int on
)
1110 Uint32 event_thread
;
1112 /* Don't switch if we don't own the window */
1113 if ( SDL_windowid
) {
1117 /* Don't lock if we are the event thread */
1118 event_thread
= SDL_EventThreadID();
1119 if ( event_thread
&& (SDL_ThreadID() == event_thread
) ) {
1122 if ( event_thread
) {
1123 SDL_Lock_EventThread();
1126 this->screen
->flags
|= SDL_FULLSCREEN
;
1127 CGX_EnterFullScreen(this);
1129 this->screen
->flags
&= ~SDL_FULLSCREEN
;
1130 CGX_LeaveFullScreen(this);
1133 CGX_RefreshDisplay(this);
1134 if ( event_thread
) {
1135 SDL_Unlock_EventThread();
1138 SDL_ResetKeyboard();
1143 /* Update the current mouse state and position */
1144 static void CGX_UpdateMouse(_THIS
)
1146 /* Lock the event thread, in multi-threading environments */
1147 SDL_Lock_EventThread();
1149 if(currently_fullscreen
)
1151 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS
);
1152 SDL_PrivateMouseMotion(0, 0, SDL_Display
->MouseX
, SDL_Display
->MouseY
);
1156 if( SDL_Display
->MouseX
>=(SDL_Window
->LeftEdge
+SDL_Window
->BorderLeft
) &&
1157 SDL_Display
->MouseX
<(SDL_Window
->LeftEdge
+SDL_Window
->Width
-SDL_Window
->BorderRight
) &&
1158 SDL_Display
->MouseY
>=(SDL_Window
->TopEdge
+SDL_Window
->BorderLeft
) &&
1159 SDL_Display
->MouseY
<(SDL_Window
->TopEdge
+SDL_Window
->Height
-SDL_Window
->BorderBottom
)
1162 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS
);
1163 SDL_PrivateMouseMotion(0, 0, SDL_Display
->MouseX
-SDL_Window
->LeftEdge
-SDL_Window
->BorderLeft
,
1164 SDL_Display
->MouseY
-SDL_Window
->TopEdge
-SDL_Window
->BorderTop
);
1168 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS
);
1171 SDL_Unlock_EventThread();
1174 static int CGX_SetColors(_THIS
, int firstcolor
, int ncolors
, SDL_Color
*colors
)
1178 /* Check to make sure we have a colormap allocated */
1180 /* It's easy if we have a hidden colormap */
1181 if ( (this->screen
->flags
& SDL_HWPALETTE
) && currently_fullscreen
)
1183 ULONG xcmap
[256*3+2];
1185 xcmap
[0]=(ncolors
<<16);
1186 xcmap
[0]+=firstcolor
;
1188 // D(bug("Setting %ld colors from color %ld on an HWPALETTE screen\n",ncolors,firstcolor));
1190 // per ora ho sostituito questo gli altri casi sono ancora da gestire
1192 for ( i
=0; i
<ncolors
; i
++ ) {
1193 xcmap
[i
*3+1] = colors
[i
].r
<<24;
1194 xcmap
[i
*3+2] = colors
[i
].g
<<24;
1195 xcmap
[i
*3+3] = colors
[i
].b
<<24;
1197 xcmap
[ncolors
*3+1]=0;
1198 LoadRGB32(&GFX_Display
->ViewPort
,xcmap
);
1200 // XPixels are not needed on 8bit screen with hwpalette
1201 unsigned long pixel
;
1203 if ( SDL_XPixels
== NULL
) {
1204 D(bug("SetColors without colormap!"));
1208 if(this->hidden
->depth
==8)
1210 // D(bug("Obtaining %ld colors on the screen\n",ncolors));
1212 for ( pixel
=firstcolor
; pixel
<ncolors
+firstcolor
; pixel
++ ) {
1213 if(SDL_XPixels
[pixel
]>=0)
1214 ReleasePen(GFX_Display
->ViewPort
.ColorMap
,SDL_XPixels
[pixel
]);
1217 /* Try to allocate all the colors */
1218 for ( i
=0; i
<ncolors
; i
++ ) {
1219 SDL_XPixels
[i
+firstcolor
]=ObtainBestPenA(GFX_Display
->ViewPort
.ColorMap
,colors
[i
].r
<<24,colors
[i
].g
<<24,colors
[i
].b
<<24,NULL
);
1224 // 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));
1225 for(i
=0;i
<ncolors
;i
++)
1226 SDL_XPixels
[i
+firstcolor
]=(colors
[i
].r
<<16)+(colors
[i
].g
<<8)+colors
[i
].b
;
1230 // Actually it cannot fail!
1235 /* Note: If we are terminated, this could be called in the middle of
1236 another SDL video routine -- notably UpdateRects.
1238 static void CGX_VideoQuit(_THIS
)
1240 /* Shutdown everything that's still up */
1241 /* The event thread should be done, so we can touch SDL_Display */
1242 D(bug("CGX_VideoQuit\n"));
1244 if ( SDL_Display
!= NULL
) {
1245 /* Clean up OpenGL */
1246 if(this->gl_data
->gl_active
== 1) {
1249 /* Start shutting down the windows */
1250 D(bug("Destroying image...\n"));
1251 CGX_DestroyImage(this, this->screen
);
1252 D(bug("Destroying window...\n"));
1253 CGX_DestroyWindow(this, this->screen
);
1254 // Otherwise SDL_VideoQuit will try to free it!
1255 SDL_VideoSurface
=NULL
;
1257 CGX_FreeVideoModes(this);
1259 /* Free that blank cursor */
1260 if ( SDL_BlankCursor
!= NULL
) {
1261 FreeMem(SDL_BlankCursor
,16);
1262 SDL_BlankCursor
= NULL
;
1265 /* Close the X11 graphics connection */
1266 this->hidden
->same_format
=0;
1268 D(bug("Destroying screen...\n"));
1270 if ( GFX_Display
!= NULL
)
1271 DestroyScreen(this);
1273 /* Close the X11 display connection */
1276 /* Unload GL library after X11 shuts down */
1279 D(bug("Closing libraries...\n"));
1282 CloseLibrary(CyberGfxBase
);
1286 if (IntuitionBase
) {
1287 CloseLibrary((struct Library
*)IntuitionBase
);
1291 CloseLibrary((struct Library
*)GfxBase
);
1295 if ( this->screen
&& (this->screen
->flags
& SDL_HWSURFACE
) ) {
1296 /* Direct screen access, no memory buffer */
1297 this->screen
->pixels
= NULL
;
1299 D(bug("End of CGX_VideoQuit.\n"));