comparison src/video/cybergfx/SDL_cgxvideo.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 75a95f82bc1f
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
4
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.
9
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.
14
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
18
19 Sam Lantinga
20 slouken@devolution.com
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28 /* CGX based SDL video driver implementation.
29 */
30
31 /*
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <sys/ioctl.h>
37 #ifdef MTRR_SUPPORT
38 #include <asm/mtrr.h>
39 #include <sys/fcntl.h>
40 #endif
41 */
42
43 #include "SDL.h"
44 #include "SDL_error.h"
45 #include "SDL_timer.h"
46 #include "SDL_thread.h"
47 #include "SDL_video.h"
48 #include "SDL_mouse.h"
49 #include "SDL_endian.h"
50 #include "SDL_sysvideo.h"
51 #include "SDL_pixels_c.h"
52 #include "SDL_events_c.h"
53 #include "SDL_cgxvideo.h"
54 #include "SDL_cgxwm_c.h"
55 #include "SDL_amigamouse_c.h"
56 #include "SDL_amigaevents_c.h"
57 #include "SDL_cgxmodes_c.h"
58 #include "SDL_cgximage_c.h"
59 #include "SDL_cgxyuv_c.h"
60 #include "SDL_cgxgl_c.h"
61
62 /* Initialization/Query functions */
63 static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat);
64 static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
65 static int CGX_ToggleFullScreen(_THIS, int on);
66 static void CGX_UpdateMouse(_THIS);
67 static int CGX_SetColors(_THIS, int firstcolor, int ncolors,
68 SDL_Color *colors);
69 static void CGX_VideoQuit(_THIS);
70
71 /* CGX driver bootstrap functions */
72
73 struct Library *CyberGfxBase=NULL;
74 struct IntuitionBase *IntuitionBase=NULL;
75 struct GfxBase *GfxBase=NULL;
76
77 static void DestroyScreen(_THIS)
78 {
79 if(currently_fullscreen)
80 {
81 if(this->hidden->dbuffer)
82 {
83 extern struct MsgPort *safeport,*dispport;
84
85 this->hidden->dbuffer=0;
86
87 if(safeport)
88 {
89 while(GetMsg(safeport)!=NULL);
90 DeleteMsgPort(safeport);
91 }
92 if(dispport)
93 {
94 while(GetMsg(dispport)!=NULL);
95 DeleteMsgPort(dispport);
96 }
97
98 this->hidden->SB[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL;
99 this->hidden->SB[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL;
100
101 if(this->hidden->SB[1])
102 FreeScreenBuffer(SDL_Display,this->hidden->SB[0]);
103 if(this->hidden->SB[0])
104 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
105
106
107 this->hidden->SB[0]=this->hidden->SB[1]=NULL;
108 free(SDL_RastPort);
109 SDL_RastPort=NULL;
110 this->hidden->dbuffer=0;
111 }
112 CloseScreen(GFX_Display);
113 }
114 else
115 UnlockPubScreen(NULL,GFX_Display);
116
117 GFX_Display = NULL;
118 }
119
120 static int CGX_Available(void)
121 {
122 struct Library *l;
123
124 l = OpenLibrary("cybergraphics.library",NULL);
125
126 if ( l != NULL ) {
127 CloseLibrary(l);
128 }
129 return(l != NULL);
130 }
131
132 static void CGX_DeleteDevice(SDL_VideoDevice *device)
133 {
134 if ( device ) {
135 if ( device->hidden ) {
136 free(device->hidden);
137 }
138 if ( device->gl_data ) {
139 free(device->gl_data);
140 }
141 free(device);
142 }
143 }
144
145 static SDL_VideoDevice *CGX_CreateDevice(int devindex)
146 {
147 SDL_VideoDevice *device;
148
149 /* Initialize all variables that we clean on shutdown */
150 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
151 if ( device ) {
152 memset(device, 0, (sizeof *device));
153 device->hidden = (struct SDL_PrivateVideoData *)
154 malloc((sizeof *device->hidden));
155 device->gl_data = (struct SDL_PrivateGLData *)
156 malloc((sizeof *device->gl_data));
157 }
158 if ( (device == NULL) || (device->hidden == NULL) ||
159 (device->gl_data == NULL) ) {
160 SDL_OutOfMemory();
161 CGX_DeleteDevice(device);
162 return(0);
163 }
164 memset(device->hidden, 0, (sizeof *device->hidden));
165 memset(device->gl_data, 0, (sizeof *device->gl_data));
166
167 /* Set the driver flags */
168 device->handles_any_size = 1;
169
170 /* Set the function pointers */
171 device->VideoInit = CGX_VideoInit;
172 device->ListModes = CGX_ListModes;
173 device->SetVideoMode = CGX_SetVideoMode;
174 device->ToggleFullScreen = CGX_ToggleFullScreen;
175 device->UpdateMouse = CGX_UpdateMouse;
176 device->SetColors = CGX_SetColors;
177 device->UpdateRects = NULL;
178 device->VideoQuit = CGX_VideoQuit;
179 device->AllocHWSurface = CGX_AllocHWSurface;
180 device->CheckHWBlit = CGX_CheckHWBlit;
181 device->FillHWRect = CGX_FillHWRect;
182 device->SetHWColorKey = CGX_SetHWColorKey;
183 device->SetHWAlpha = NULL;
184 device->LockHWSurface = CGX_LockHWSurface;
185 device->UnlockHWSurface = CGX_UnlockHWSurface;
186 device->FlipHWSurface = CGX_FlipHWSurface;
187 device->FreeHWSurface = CGX_FreeHWSurface;
188 #ifdef HAVE_OPENGL
189 device->GL_LoadLibrary = X11_GL_LoadLibrary;
190 device->GL_GetProcAddress = X11_GL_GetProcAddress;
191 device->GL_GetAttribute = X11_GL_GetAttribute;
192 device->GL_MakeCurrent = X11_GL_MakeCurrent;
193 device->GL_SwapBuffers = X11_GL_SwapBuffers;
194 #endif
195 device->SetCaption = CGX_SetCaption;
196 device->SetIcon = CGX_SetIcon;
197 device->IconifyWindow = NULL; /* CGX_IconifyWindow; */
198 device->GrabInput = NULL /* CGX_GrabInput*/;
199 device->GetWMInfo = CGX_GetWMInfo;
200 device->FreeWMCursor = amiga_FreeWMCursor;
201 device->CreateWMCursor = amiga_CreateWMCursor;
202 device->ShowWMCursor = amiga_ShowWMCursor;
203 device->WarpWMCursor = amiga_WarpWMCursor;
204 device->CheckMouseMode = amiga_CheckMouseMode;
205 device->InitOSKeymap = amiga_InitOSKeymap;
206 device->PumpEvents = amiga_PumpEvents;
207
208 device->free = CGX_DeleteDevice;
209
210 return device;
211 }
212
213 VideoBootStrap CGX_bootstrap = {
214 "CGX", "Amiga CyberGFX video",
215 CGX_Available, CGX_CreateDevice
216 };
217
218
219 Uint32 MakeBitMask(_THIS,int type,int format,int *bpp)
220 {
221 D(if(type==0)bug("REAL pixel format: "));
222
223 if(this->hidden->depth==*bpp)
224 {
225
226 switch(format)
227 {
228 case PIXFMT_LUT8:
229 D(if(type==0)bug("LUT8\n"));
230 return 0;
231 case PIXFMT_BGR15:
232 case PIXFMT_RGB15PC:
233 switch(type)
234 {
235 case 0:
236 D(bug("RGB15PC/BGR15\n"));
237 return 31;
238 case 1:
239 return 992;
240 case 2:
241 return 31744;
242 }
243 case PIXFMT_RGB15:
244 case PIXFMT_BGR15PC:
245 switch(type)
246 {
247 case 0:
248 D(bug("RGB15/BGR15PC\n"));
249 return 31744;
250 case 1:
251 return 992;
252 case 2:
253 return 31;
254 }
255 case PIXFMT_BGR16PC:
256 case PIXFMT_RGB16:
257 switch(type)
258 {
259 case 0:
260 D(bug("RGB16PC\n"));
261 return 63488;
262 case 1:
263 return 2016;
264 case 2:
265 return 31;
266 }
267 case PIXFMT_BGR16:
268 case PIXFMT_RGB16PC:
269 switch(type)
270 {
271 case 0:
272 D(bug("RGB16PC/BGR16\n"));
273 return 31;
274 case 1:
275 return 2016;
276 case 2:
277 return 63488;
278 }
279
280 case PIXFMT_RGB24:
281 switch(type)
282 {
283 case 0:
284 D(bug("RGB24/BGR24\n"));
285 return 0xff0000;
286 case 1:
287 return 0xff00;
288 case 2:
289 return 0xff;
290 }
291 case PIXFMT_BGR24:
292 switch(type)
293 {
294 case 0:
295 D(bug("BGR24\n"));
296 return 0xff;
297 case 1:
298 return 0xff00;
299 case 2:
300 return 0xff0000;
301 }
302 case PIXFMT_ARGB32:
303 switch(type)
304 {
305 case 0:
306 D(bug("ARGB32\n"));
307 return 0xff0000;
308 case 1:
309 return 0xff00;
310 case 2:
311 return 0xff;
312 }
313 case PIXFMT_BGRA32:
314 switch(type)
315 {
316 case 0:
317 D(bug("BGRA32\n"));
318 return 0xff00;
319 case 1:
320 return 0xff0000;
321 case 2:
322 return 0xff000000;
323 }
324 case PIXFMT_RGBA32:
325 switch(type)
326 {
327 case 0:
328 D(bug("RGBA32\n"));
329 return 0xff000000;
330 case 1:
331 return 0xff0000;
332 case 2:
333 return 0xff00;
334 }
335 default:
336 D(bug("Unknown pixel format! Default to 24bit\n"));
337 return (Uint32) (255<<(type*8));
338 }
339 }
340 else
341 {
342 D(if(type==0)bug("DIFFERENT from screen.\nAllocated screen format: "));
343
344 switch(*bpp)
345 {
346 case 32:
347 D(if(type==0) bug("RGBA32\n"));
348 switch(type)
349 {
350 case 0:
351 return 0xff000000;
352 case 1:
353 return 0xff0000;
354 case 2:
355 return 0xff00;
356 }
357 break;
358 case 24:
359 use_truecolor:
360 switch(type)
361 {
362 case 0:
363 D(bug("RGB24\n"));
364 return 0xff0000;
365 case 1:
366 return 0xff00;
367 case 2:
368 return 0xff;
369 }
370 case 16:
371 case 15:
372 D(if(type==0) bug("Not supported, switching to 24bit!\n"));
373 *bpp=24;
374 goto use_truecolor;
375 break;
376 default:
377 D(if(type==0)bug("This is a chunky display\n"));
378 // For chunky display mask is always 0;
379 return 0;
380 }
381 }
382 return 0;
383 }
384
385 static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat)
386 {
387 int i;
388
389 if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L)))
390 {
391 SDL_SetError("Couldn't open intuition V39+");
392 return -1;
393 }
394 if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L)))
395 {
396 SDL_SetError("Couldn't open graphics V39+");
397 return -1;
398 }
399 if(!(CyberGfxBase=OpenLibrary("cybergraphics.library",40L)))
400 {
401 SDL_SetError("Couldn't open cybergraphics.");
402 return(-1);
403 }
404
405 SDL_Display = LockPubScreen(NULL);
406
407 if ( SDL_Display == NULL ) {
408 SDL_SetError("Couldn't lock the display");
409 return(-1);
410 }
411
412 if(!IsCyberModeID(GetVPModeID(&SDL_Display->ViewPort)))
413 {
414 Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,SDL_Display->Width,
415 CYBRBIDTG_NominalHeight,SDL_Display->Height,
416 CYBRBIDTG_Depth,8,
417 TAG_DONE);
418
419 UnlockPubScreen(NULL,SDL_Display);
420
421 GFX_Display=NULL;
422
423 if(okid!=INVALID_ID)
424 {
425 GFX_Display=OpenScreenTags(NULL,
426 SA_Width,SDL_Display->Width,
427 SA_Height,SDL_Display->Height,
428 SA_Depth,8,SA_Quiet,TRUE,
429 SA_ShowTitle,FALSE,
430 SA_DisplayID,okid,
431 TAG_DONE);
432 }
433
434 if(!GFX_Display)
435 {
436 SDL_SetError("Unable to open a suited CGX display");
437 return -1;
438 }
439 else SDL_Display=GFX_Display;
440
441 }
442 else GFX_Display = SDL_Display;
443
444
445 /* See whether or not we need to swap pixels */
446
447 swap_pixels = 0;
448
449 // Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente
450
451 if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
452 swap_pixels = 1;
453 }
454
455 /* Get the available video modes */
456 if(CGX_GetVideoModes(this) < 0)
457 return -1;
458
459 /* Determine the default screen depth:
460 Use the default visual (or at least one with the same depth) */
461
462 for(i = 0; i < this->hidden->nvisuals; i++)
463 if(this->hidden->visuals[i].depth == GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH))
464 break;
465 if(i == this->hidden->nvisuals) {
466 /* default visual was useless, take the deepest one instead */
467 i = 0;
468 }
469 SDL_Visual = this->hidden->visuals[i].visual;
470
471 this->hidden->depth = this->hidden->visuals[i].depth;
472 D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
473 vformat->BitsPerPixel = this->hidden->visuals[i].depth; /* this->hidden->visuals[i].bpp; */
474
475 {
476 int form;
477 APTR handle;
478 struct DisplayInfo info;
479
480 if(!(handle=FindDisplayInfo(this->hidden->visuals[i].visual)))
481 return -1;
482
483 if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL))
484 return -1;
485
486 form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual);
487
488 // In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask
489
490 if ( vformat->BitsPerPixel > 8 )
491 {
492 vformat->Rmask = MakeBitMask(this,0,form,&this->hidden->depth);
493 vformat->Gmask = MakeBitMask(this,1,form,&this->hidden->depth);
494 vformat->Bmask = MakeBitMask(this,2,form,&this->hidden->depth);
495 }
496 }
497
498 /* Create the fullscreen and managed windows */
499 // create_aux_windows(this);
500
501 /* Create the blank cursor */
502 SDL_BlankCursor = AllocMem(16,MEMF_CHIP|MEMF_CLEAR);
503
504 /* Fill in some window manager capabilities */
505 this->info.wm_available = 1;
506 this->info.blit_hw = 1;
507 this->info.blit_hw_CC = 1;
508 this->info.blit_sw = 1;
509 this->info.blit_fill = 1;
510 this->info.video_mem=2000000; // Not always true but almost any Amiga card has this memory!
511
512 this->hidden->same_format=0;
513 SDL_RastPort=&SDL_Display->RastPort;
514 /* We're done! */
515 return(0);
516 }
517
518 void CGX_DestroyWindow(_THIS, SDL_Surface *screen)
519 {
520 /* Hide the managed window */
521 int was_fullscreen=0;
522
523 if ( screen && (screen->flags & SDL_FULLSCREEN) ) {
524 was_fullscreen=1;
525 screen->flags &= ~SDL_FULLSCREEN;
526 CGX_LeaveFullScreen(this);
527 }
528
529 /* Destroy the output window */
530 if ( SDL_Window ) {
531 CloseWindow(SDL_Window);
532 SDL_Window=NULL;
533 }
534
535 /* Free the colormap entries */
536 if ( SDL_XPixels ) {
537 int numcolors;
538 unsigned long pixel;
539
540 if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
541 {
542 numcolors = 1<<this->screen->format->BitsPerPixel;
543
544 if(numcolors>256)
545 numcolors=256;
546
547 if(!was_fullscreen&&this->hidden->depth==8)
548 {
549 for ( pixel=0; pixel<numcolors; pixel++ )
550 {
551 if(SDL_XPixels[pixel]>=0)
552 ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
553 }
554 }
555 }
556 free(SDL_XPixels);
557 SDL_XPixels = NULL;
558 }
559 }
560
561 static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags)
562 {
563 if ( flags & SDL_RESIZABLE ) {
564 WindowLimits(SDL_Window, 32, 32,4096,4096);
565 } else {
566 WindowLimits(SDL_Window, w,h,w,h);
567 }
568 if ( flags & SDL_FULLSCREEN ) {
569 flags&=~SDL_RESIZABLE;
570 } else if ( getenv("SDL_VIDEO_CENTERED") ) {
571 int display_w, display_h;
572
573 display_w = SDL_Display->Width;
574 display_h = SDL_Display->Height;
575 ChangeWindowBox(SDL_Window,(display_w - w - SDL_Window->BorderLeft-SDL_Window->BorderRight)/2,
576 (display_h - h - SDL_Window->BorderTop-SDL_Window->BorderBottom)/2,
577 w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
578 h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
579 }
580 }
581
582 int CGX_CreateWindow(_THIS, SDL_Surface *screen,
583 int w, int h, int bpp, Uint32 flags)
584 {
585 #if 0
586 int i, depth;
587 Uint32 vis;
588 #endif
589 /* If a window is already present, destroy it and start fresh */
590 if ( SDL_Window ) {
591 CGX_DestroyWindow(this, screen);
592 }
593 SDL_Window = 0;
594
595 /* find out which visual we are going to use */
596 #if 0
597 /* questo l'ho spostato nell'apertura dello schermo, in quanto su Amiga le finestre
598 hanno il pixel mode degli schermi.
599 */
600 if ( flags & SDL_OPENGL ) {
601 SDL_SetError("OpenGL not supported by the Amiga SDL!");
602 return -1;
603 }
604 else {
605 for ( i = 0; i < this->hidden->nvisuals; i++ ) {
606 if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
607 break;
608 }
609 if ( i == this->hidden->nvisuals ) {
610 SDL_SetError("No matching visual for requested depth");
611 return -1; /* should never happen */
612 }
613 vis = this->hidden->visuals[i].visual;
614 depth = this->hidden->visuals[i].depth;
615 }
616 SDL_Visual = vis;
617 this->hidden->depth = depth;
618 D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
619 #endif
620
621 /* Allocate the new pixel format for this video mode */
622 {
623 Uint32 form;
624 APTR handle;
625 struct DisplayInfo info;
626
627 if(!(handle=FindDisplayInfo(SDL_Visual)))
628 return -1;
629
630 if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL))
631 return -1;
632
633 form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual);
634
635 if(flags&SDL_HWSURFACE)
636 {
637 if(bpp!=this->hidden->depth)
638 {
639 bpp=this->hidden->depth;
640 D(bug("Accel forces bpp to be equal (%ld)\n",bpp));
641 }
642 }
643
644 D(bug("BEFORE screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth));
645
646 /* With this call if needed I'll revert the wanted bpp to a bpp best suited for the display, actually occurs
647 only with requested format 15/16bit and display format != 15/16bit
648 */
649
650 if ( ! SDL_ReallocFormat(screen, bpp,
651 MakeBitMask(this,0,form,&bpp), MakeBitMask(this,1,form,&bpp), MakeBitMask(this,2,form,&bpp), 0) )
652 return -1;
653
654 D(bug("AFTER screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth));
655
656 }
657
658 /* Create the appropriate colormap */
659 if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) {
660 int ncolors;
661 D(bug("Alloco XPixels x la palette...\n"));
662
663 /* Allocate the pixel flags */
664
665 if(bpp==8)
666 ncolors=256;
667 else
668 ncolors = 1 << screen->format->BitsPerPixel;
669
670 SDL_XPixels = (Sint32 *)malloc(ncolors * sizeof(Sint32));
671
672 if(SDL_XPixels == NULL) {
673 SDL_OutOfMemory();
674 return -1;
675 }
676
677 memset(SDL_XPixels, -1, ncolors * sizeof(Sint32));
678
679 /* always allocate a private colormap on non-default visuals */
680 if(bpp==8)
681 flags |= SDL_HWPALETTE;
682
683 if ( flags & SDL_HWPALETTE ) {
684 screen->flags |= SDL_HWPALETTE;
685 }
686 }
687
688 /* resize the (possibly new) window manager window */
689
690 /* Create (or use) the X11 display window */
691 if ( flags & SDL_OPENGL ) {
692 return(-1);
693 } else {
694 if(flags & SDL_FULLSCREEN)
695 SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h,
696 WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE,
697 WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
698 WA_CustomScreen,(ULONG)SDL_Display,
699 TAG_DONE);
700 else
701 SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h,
702 WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR| ((screen->flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0),
703 WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE,
704 WA_PubScreen,(ULONG)SDL_Display,
705 TAG_DONE);
706 }
707 /* Only manage our input if we own the window */
708 if(!SDL_Window)
709 return -1;
710
711 this->hidden->BytesPerPixel=GetCyberMapAttr(SDL_Window->RPort->BitMap,CYBRMATTR_BPPIX);
712
713 if(screen->flags & SDL_DOUBLEBUF)
714 {
715 if(SDL_RastPort=malloc(sizeof(struct RastPort)))
716 {
717 InitRastPort(SDL_RastPort);
718 SDL_RastPort->BitMap=this->hidden->SB[1]->sb_BitMap;
719 }
720 else
721 return -1;
722 }
723 else SDL_RastPort=SDL_Window->RPort;
724 #if 0
725
726 if(screen->flags & SDL_HWPALETTE) {
727 /* Since the full-screen window might have got a nonzero background
728 colour (0 is white on some displays), we should reset the
729 background to 0 here since that is what the user expects
730 with a private colormap */
731 SetAPen(SDL_Window->RPort,0);
732 RectFill(SDL_Window->RPort,SDL_Window->BorderLeft,SDL_Window->BorderTop,w+SDL_Window->BorderLeft,h+SDL_Window->BorderTop);
733 }
734 #endif
735
736 if(flags&SDL_HWSURFACE)
737 screen->flags|=SDL_HWSURFACE;
738
739 CGX_SetSizeHints(this, w, h, flags);
740 current_w = w;
741 current_h = h;
742
743 /* Map them both and go fullscreen, if requested */
744 if ( flags & SDL_FULLSCREEN ) {
745 screen->flags |= SDL_FULLSCREEN;
746 currently_fullscreen=1;
747 // CGX_EnterFullScreen(this); Ci siamo gia'!
748 } else {
749 screen->flags &= ~SDL_FULLSCREEN;
750 }
751 return(0);
752 }
753
754 int CGX_ResizeWindow(_THIS,
755 SDL_Surface *screen, int w, int h, Uint32 flags)
756 {
757 /* Resize the window manager window */
758 CGX_SetSizeHints(this, w, h, flags);
759 current_w = w;
760 current_h = h;
761
762 ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
763 h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
764
765 /* Resize the fullscreen and display windows */
766 if ( flags & SDL_FULLSCREEN ) {
767 if ( screen->flags & SDL_FULLSCREEN ) {
768 CGX_ResizeFullScreen(this);
769 } else {
770 screen->flags |= SDL_FULLSCREEN;
771 CGX_EnterFullScreen(this);
772 }
773 } else {
774 if ( screen->flags & SDL_FULLSCREEN ) {
775 screen->flags &= ~SDL_FULLSCREEN;
776 CGX_LeaveFullScreen(this);
777 }
778 }
779 return(0);
780 }
781
782 static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current,
783 int width, int height, int bpp, Uint32 flags)
784 {
785 Uint32 saved_flags;
786
787 /* Lock the event thread, in multi-threading environments */
788 SDL_Lock_EventThread();
789
790 // Check if we need to close an already existing videomode...
791
792 if(current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))
793 {
794 CGX_DestroyImage(this,current);
795 CGX_DestroyWindow(this,current);
796 DestroyScreen(this);
797 }
798 /* Check the combination of flags we were passed */
799 if ( flags & SDL_FULLSCREEN ) {
800 int i;
801
802 /* Clear fullscreen flag if not supported */
803 if(current->flags&SDL_FULLSCREEN )
804 {
805 if(current->w!=width ||
806 current->h!=height ||
807 this->hidden->depth!=bpp)
808 {
809 CGX_DestroyImage(this,current);
810 CGX_DestroyWindow(this,current);
811 DestroyScreen(this);
812 goto buildnewscreen;
813 }
814 }
815 else
816 buildnewscreen:
817 {
818 Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,width,
819 CYBRBIDTG_NominalHeight,height,
820 CYBRBIDTG_Depth,bpp,
821 TAG_DONE);
822
823 GFX_Display=NULL;
824
825 if(okid!=INVALID_ID)
826 {
827 GFX_Display=OpenScreenTags(NULL,
828 SA_Width,width,
829 SA_Height,height,
830 SA_Quiet,TRUE,SA_ShowTitle,FALSE,
831 SA_Depth,bpp,
832 SA_DisplayID,okid,
833 TAG_DONE);
834 }
835
836
837 if(!GFX_Display)
838 {
839 GFX_Display=SDL_Display;
840 flags &= ~SDL_FULLSCREEN;
841 flags &= ~SDL_DOUBLEBUF;
842 }
843 else
844 {
845 UnlockPubScreen(NULL,SDL_Display);
846 SDL_Display=GFX_Display;
847
848 if(flags&SDL_DOUBLEBUF)
849 {
850 int ok=0;
851
852 if(this->hidden->SB[0]=AllocScreenBuffer(SDL_Display,NULL,SB_SCREEN_BITMAP))
853 {
854 if(this->hidden->SB[1]=AllocScreenBuffer(SDL_Display,NULL,0L))
855 {
856 extern struct MsgPort *safeport,*dispport;
857
858 safeport=CreateMsgPort();
859 dispport=CreateMsgPort();
860
861 if(!safeport || !dispport)
862 {
863 if(safeport)
864 {
865 DeleteMsgPort(safeport);
866 safeport=NULL;
867 }
868 if(dispport)
869 {
870 DeleteMsgPort(dispport);
871 dispport=NULL;
872 }
873 FreeScreenBuffer(SDL_Display,this->hidden->SB[0]);
874 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
875 }
876 else
877 {
878 extern ULONG safe_sigbit,disp_sigbit;
879 int i;
880
881 safe_sigbit=1L<< safeport->mp_SigBit;
882 disp_sigbit=1L<< dispport->mp_SigBit;
883
884 for(i=0;i<2;i++)
885 {
886 this->hidden->SB[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=safeport;
887 this->hidden->SB[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=dispport;
888 }
889
890 ok=1;
891 D(bug("Dbuffering enabled!\n"));
892 this->hidden->dbuffer=1;
893 current->flags|=SDL_DOUBLEBUF;
894 }
895 }
896 else
897 {
898 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
899 this->hidden->SB[0]=NULL;
900 }
901 }
902
903 if(!ok)
904 {
905 flags&=~SDL_DOUBLEBUF;
906 }
907 }
908 }
909
910 if(GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)==bpp)
911 this->hidden->same_format=1;
912 }
913
914 bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH);
915 D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
916
917 for ( i = 0; i < this->hidden->nvisuals; i++ ) {
918 if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
919 break;
920 }
921 if ( i == this->hidden->nvisuals ) {
922 SDL_SetError("No matching visual for requested depth");
923 return NULL; /* should never happen */
924 }
925 SDL_Visual = this->hidden->visuals[i].visual;
926
927 }
928
929 /* Set up the X11 window */
930 saved_flags = current->flags;
931
932 if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)
933 && bpp == current->format->BitsPerPixel) {
934 if (CGX_ResizeWindow(this, current, width, height, flags) < 0) {
935 current = NULL;
936 goto done;
937 }
938 } else {
939 if (CGX_CreateWindow(this,current,width,height,bpp,flags) < 0) {
940 current = NULL;
941 goto done;
942 }
943 }
944
945 /* Set up the new mode framebuffer */
946 if ( ((current->w != width) || (current->h != height)) ||
947 ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
948 current->w = width;
949 current->h = height;
950 current->pitch = SDL_CalculatePitch(current);
951 CGX_ResizeImage(this, current, flags);
952 }
953 current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it
954
955 done:
956 /* Release the event thread */
957 SDL_Unlock_EventThread();
958
959 /* We're done! */
960 return(current);
961 }
962
963 static int CGX_ToggleFullScreen(_THIS, int on)
964 {
965 Uint32 event_thread;
966
967 /* Don't lock if we are the event thread */
968 event_thread = SDL_EventThreadID();
969 if ( event_thread && (SDL_ThreadID() == event_thread) ) {
970 event_thread = 0;
971 }
972 if ( event_thread ) {
973 SDL_Lock_EventThread();
974 }
975 if ( on ) {
976 this->screen->flags |= SDL_FULLSCREEN;
977 CGX_EnterFullScreen(this);
978 } else {
979 this->screen->flags &= ~SDL_FULLSCREEN;
980 CGX_LeaveFullScreen(this);
981 }
982 CGX_RefreshDisplay(this);
983 if ( event_thread ) {
984 SDL_Unlock_EventThread();
985 }
986 SDL_ResetKeyboard();
987 return(1);
988 }
989
990 static void SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b, unsigned char *c)
991 {
992 switch(fmt)
993 {
994 case PIXFMT_BGR15:
995 case PIXFMT_RGB15PC:
996 {
997 Uint16 *t=(Uint16 *)c;
998 *t=(r>>3) | ((g>>3)<<5) | ((b>>3)<<10) ;
999 }
1000 break;
1001 case PIXFMT_RGB15:
1002 case PIXFMT_BGR15PC:
1003 {
1004 Uint16 *t=(Uint16 *)c;
1005 *t=(b>>3) | ((g>>3)<<5) | ((r>>3)<<10) ;
1006 }
1007 break;
1008 case PIXFMT_BGR16PC:
1009 case PIXFMT_RGB16:
1010 {
1011 Uint16 *t=(Uint16 *)c;
1012 *t=(b>>3) | ((g>>2)<<5) | ((r>>3)<<11) ;
1013 }
1014 break;
1015 case PIXFMT_BGR16:
1016 case PIXFMT_RGB16PC:
1017 {
1018 Uint16 *t=(Uint16 *)c;
1019 *t=(r>>3) | ((g>>2)<<5) | ((b>>3)<<11) ;
1020 }
1021 break;
1022 case PIXFMT_RGB24:
1023 c[0]=r;
1024 c[1]=g;
1025 c[2]=b;
1026 c[3]=0;
1027 break;
1028 case PIXFMT_BGR24:
1029 c[0]=b;
1030 c[1]=g;
1031 c[2]=r;
1032 c[3]=0;
1033 break;
1034 case PIXFMT_ARGB32:
1035 c[0]=0;
1036 c[1]=r;
1037 c[2]=g;
1038 c[3]=b;
1039 break;
1040 case PIXFMT_BGRA32:
1041 c[0]=b;
1042 c[1]=g;
1043 c[2]=r;
1044 c[3]=0;
1045 break;
1046 case PIXFMT_RGBA32:
1047 c[0]=r;
1048 c[1]=g;
1049 c[2]=b;
1050 c[3]=0;
1051 break;
1052
1053 default:
1054 D(bug("Errore, SetSingleColor con PIXFMT %ld!\n",fmt));
1055 }
1056 }
1057
1058 /* Update the current mouse state and position */
1059 static void CGX_UpdateMouse(_THIS)
1060 {
1061 /* Lock the event thread, in multi-threading environments */
1062 SDL_Lock_EventThread();
1063
1064 if(currently_fullscreen)
1065 {
1066 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
1067 SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX, SDL_Display->MouseY);
1068 }
1069 else
1070 {
1071 if( SDL_Display->MouseX>=(SDL_Window->LeftEdge+SDL_Window->BorderLeft) && SDL_Display->MouseX<(SDL_Window->LeftEdge+SDL_Window->Width-SDL_Window->BorderRight) &&
1072 SDL_Display->MouseY>=(SDL_Window->TopEdge+SDL_Window->BorderLeft) && SDL_Display->MouseY<(SDL_Window->TopEdge+SDL_Window->Height-SDL_Window->BorderBottom)
1073 )
1074 {
1075 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
1076 SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX-SDL_Window->LeftEdge-SDL_Window->BorderLeft,
1077 SDL_Display->MouseY-SDL_Window->TopEdge-SDL_Window->BorderTop);
1078 }
1079 else
1080 {
1081 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
1082 }
1083 }
1084 SDL_Unlock_EventThread();
1085 }
1086
1087 static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
1088 {
1089 int i;
1090
1091 /* Check to make sure we have a colormap allocated */
1092
1093 // It's not needed to reload the whole palette each time on Amiga!
1094 // ncolors = this->screen->format->palette->ncolors;
1095
1096 /* It's easy if we have a hidden colormap */
1097 if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen )
1098 {
1099 ULONG xcmap[256*3+2];
1100
1101 xcmap[0]=(ncolors<<16);
1102 xcmap[0]+=firstcolor;
1103
1104 // D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors));
1105
1106 for ( i=0; i<ncolors; i++ ) {
1107 xcmap[i*3+1] = colors[i].r<<24;
1108 xcmap[i*3+2] = colors[i].g<<24;
1109 xcmap[i*3+3] = colors[i].b<<24;
1110 }
1111 xcmap[ncolors*3+1]=0;
1112 LoadRGB32(&GFX_Display->ViewPort,xcmap);
1113 } else {
1114 // XPixels are not needed on 8bit screen with hwpalette
1115 unsigned long pixel;
1116
1117 if ( SDL_XPixels == NULL ) {
1118 D(bug("SetColors without colormap!"));
1119 return(0);
1120 }
1121
1122 colors = this->screen->format->palette->colors;
1123 if(this->hidden->depth==8)
1124 {
1125 // In this case I have to unalloc and realloc the full palette
1126 D(bug("Obtaining %ld colors on the screen\n",ncolors));
1127
1128 /* Free existing allocated colors */
1129 for ( pixel=0; pixel<this->screen->format->palette->ncolors; ++pixel ) {
1130 if(SDL_XPixels[pixel]>=0)
1131 ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
1132 }
1133
1134 /* Try to allocate all the colors */
1135 for ( i=0; i<this->screen->format->palette->ncolors; ++i ) {
1136 SDL_XPixels[i]=ObtainBestPenA(GFX_Display->ViewPort.ColorMap,colors[i].r<<24,colors[i].g<<24,colors[i].b<<24,NULL);
1137 }
1138 }
1139 else
1140 {
1141 #ifndef USE_CGX_WRITELUTPIXEL
1142 Uint32 fmt;
1143 D(bug("Preparing a conversion pixel table...\n"));
1144
1145 fmt=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT);
1146
1147 for(i=0;i<ncolors;i++)
1148 {
1149 SetSingleColor(fmt,colors[firstcolor+i].r,colors[firstcolor+i].g,colors[firstcolor+i].b,(unsigned char *)&SDL_XPixels[firstcolor+i]);
1150 }
1151 #else
1152 // D(bug("Eseguo remap degli XPixel(%lx): (da %ld, %ld colori) primo: r%ld g%ld b%ld\n",SDL_XPixels,firstcolor,ncolors,colors[firstcolor].r,colors[firstcolor].g,colors[firstcolor].b));
1153 for(i=0;i<ncolors;i++)
1154 SDL_XPixels[i+firstcolor]=(colors[firstcolor+i].r<<16)+(colors[firstcolor+i].g<<8)+colors[firstcolor+i].b;
1155 #endif
1156 }
1157 }
1158
1159 // Actually it cannot fail!
1160
1161 return 1;
1162 }
1163
1164 /* Note: If we are terminated, this could be called in the middle of
1165 another SDL video routine -- notably UpdateRects.
1166 */
1167 static void CGX_VideoQuit(_THIS)
1168 {
1169 /* Shutdown everything that's still up */
1170 /* The event thread should be done, so we can touch SDL_Display */
1171 if ( SDL_Display != NULL ) {
1172 /* Clean up OpenGL */
1173
1174 /* Start shutting down the windows */
1175 CGX_DestroyImage(this, this->screen);
1176 CGX_DestroyWindow(this, this->screen);
1177 // Otherwise SDL_VideoQuit will try to free it!
1178 SDL_VideoSurface=NULL;
1179 CGX_FreeVideoModes(this);
1180
1181 /* Free that blank cursor */
1182 if ( SDL_BlankCursor != NULL ) {
1183 FreeMem(SDL_BlankCursor,16);
1184 SDL_BlankCursor = NULL;
1185 }
1186
1187 /* Close the X11 graphics connection */
1188 this->hidden->same_format=0;
1189
1190 if ( GFX_Display != NULL )
1191 DestroyScreen(this);
1192
1193 /* Close the X11 display connection */
1194 SDL_Display = NULL;
1195
1196 /* Unload GL library after X11 shuts down */
1197 }
1198
1199 if( CyberGfxBase)
1200 {
1201 CloseLibrary(CyberGfxBase);
1202 CyberGfxBase=NULL;
1203 }
1204
1205 if (IntuitionBase)
1206 {
1207 CloseLibrary((struct Library *)IntuitionBase);
1208 IntuitionBase=NULL;
1209 }
1210 if (GfxBase)
1211 {
1212 CloseLibrary((struct Library *)GfxBase);
1213 GfxBase=NULL;
1214 }
1215
1216 if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) {
1217 /* Direct screen access, no memory buffer */
1218 this->screen->pixels = NULL;
1219 }
1220 }
1221