📄 sdl_romvideo.c
字号:
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_romvideo.c,v 1.4 2002/04/22 21:38:05 wmay Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
#if TARGET_API_MAC_CARBON
#include <Carbon.h>
/* The fullscreen code requires the QuickTime framework, and the window
is still at the back on MacOS X, which is where this code is needed.
*/
#if USE_QUICKTIME
#include <QuickTime/Movies.h>
#endif
#else
#include <LowMem.h>
#include <Gestalt.h>
#include <Devices.h>
#include <DiskInit.h>
#include <QDOffscreen.h>
#endif
#include "SDL_video.h"
#include "SDL_error.h"
#include "SDL_syswm.h"
#include "SDL_sysvideo.h"
#include "SDL_romvideo.h"
#include "SDL_macgl_c.h"
#include "SDL_macwm_c.h"
#include "SDL_macmouse_c.h"
#include "SDL_macevents_c.h"
/* Initialization/Query functions */
static int ROM_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *ROM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int ROM_SetColors(_THIS, int firstcolor, int ncolors,
SDL_Color *colors);
static void ROM_VideoQuit(_THIS);
/* Hardware surface functions */
static int ROM_AllocHWSurface(_THIS, SDL_Surface *surface);
static int ROM_LockHWSurface(_THIS, SDL_Surface *surface);
static void ROM_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void ROM_FreeHWSurface(_THIS, SDL_Surface *surface);
#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
/* Saved state for the menu bar */
static RgnHandle gSaveGrayRgn = nil;
static short gSaveMenuBar = 0;
static Boolean gSaveCSVis = true;
#if powerc
/* Mixed mode glue to activate the 68K emulator and twiddle a register */
#define ONEWORDSTUB(p1) \
{ 0x41FA, 0x0010, 0x209F, (p1), 0x41FA, \
0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
#define TWOWORDSTUB(p1,p2) \
{ 0x41FA, 0x0012, 0x209F, (p1), (p2), 0x41FA, \
0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
#define THREEWORDSTUB(p1,p2,p3) \
{ 0x41FA, 0x0014, 0x209F, (p1), (p2), (p3), 0x41FA, \
0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
/* ControlStrip inline glue for PowerPC */
static pascal Boolean SBIsControlStripVisible(void)
{
static short procData[] = TWOWORDSTUB(0x7000, 0xAAF2);
ProcInfoType procInfo = kD0DispatchedPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode);
return((Boolean) CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x00));
}
static pascal void SBShowHideControlStrip(Boolean showIt)
{
static short procData[] = THREEWORDSTUB(0x303C, 0x0101, 0xAAF2);
ProcInfoType procInfo = kD0DispatchedPascalStackBased
| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
| DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean)));
CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x01, showIt);
}
#endif /* powerc */
#endif /* !TARGET_API_MAC_CARBON */
/* Macintosh toolbox driver bootstrap functions */
static int ROM_Available(void)
{
return(1);
}
static void ROM_DeleteDevice(SDL_VideoDevice *device)
{
free(device->hidden);
free(device);
}
static SDL_VideoDevice *ROM_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
if ( device ) {
memset(device, 0, (sizeof *device));
device->hidden = (struct SDL_PrivateVideoData *)
malloc((sizeof *device->hidden));
}
if ( (device == NULL) || (device->hidden == NULL) ) {
SDL_OutOfMemory();
if ( device ) {
free(device);
}
return(0);
}
memset(device->hidden, 0, (sizeof *device->hidden));
/* Set the function pointers */
device->VideoInit = ROM_VideoInit;
device->ListModes = ROM_ListModes;
device->SetVideoMode = ROM_SetVideoMode;
device->SetColors = ROM_SetColors;
device->UpdateRects = NULL;
device->VideoQuit = ROM_VideoQuit;
device->AllocHWSurface = ROM_AllocHWSurface;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
device->SetHWColorKey = NULL;
device->SetHWAlpha = NULL;
device->LockHWSurface = ROM_LockHWSurface;
device->UnlockHWSurface = ROM_UnlockHWSurface;
device->FlipHWSurface = NULL;
device->FreeHWSurface = ROM_FreeHWSurface;
#ifdef HAVE_OPENGL
device->GL_MakeCurrent = Mac_GL_MakeCurrent;
device->GL_SwapBuffers = Mac_GL_SwapBuffers;
#endif
device->SetCaption = Mac_SetCaption;
device->SetIcon = NULL;
device->IconifyWindow = NULL;
device->GrabInput = NULL;
device->GetWMInfo = NULL;
device->FreeWMCursor = Mac_FreeWMCursor;
device->CreateWMCursor = Mac_CreateWMCursor;
device->ShowWMCursor = Mac_ShowWMCursor;
device->WarpWMCursor = Mac_WarpWMCursor;
device->InitOSKeymap = Mac_InitOSKeymap;
device->PumpEvents = Mac_PumpEvents;
device->free = ROM_DeleteDevice;
return device;
}
VideoBootStrap TOOLBOX_bootstrap = {
"toolbox", "MacOS ROM Toolbox",
ROM_Available, ROM_CreateDevice
};
static int ROM_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
long info;
/* Check out some things about the system */
Gestalt(gestaltQuickdrawVersion, &info);
if ( info == gestaltOriginalQD ) {
SDL_SetError("Color Quickdraw not available");
return(-1);
}
/* Start ROMintosh events */
Mac_InitEvents(this);
/* Get a handle to the main monitor */
SDL_Display = GetMainDevice();
/* Determine pixel format */
vformat->BitsPerPixel = (**(**SDL_Display).gdPMap).pixelSize;
switch (vformat->BitsPerPixel) {
case 16: /* 5-5-5 RGB */
vformat->Rmask = 0x00007c00;
vformat->Gmask = 0x000003e0;
vformat->Bmask = 0x0000001f;
break;
default:
break;
}
/* Create our palette */
SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8);
if ( SDL_CTab == nil ) {
SDL_OutOfMemory();
return(-1);
}
(**SDL_CTab).ctSeed = GetCTSeed();
(**SDL_CTab).ctFlags = 0;
(**SDL_CTab).ctSize = 255;
CTabChanged(SDL_CTab);
SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0);
/* Get a list of available fullscreen modes */
SDL_modelist = (SDL_Rect **)malloc((1+1)*sizeof(SDL_Rect *));
if ( SDL_modelist ) {
SDL_modelist[0] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
if ( SDL_modelist[0] ) {
SDL_modelist[0]->x = 0;
SDL_modelist[0]->y = 0;
SDL_modelist[0]->w = (**SDL_Display).gdRect.right;
SDL_modelist[0]->h = (**SDL_Display).gdRect.bottom;
}
SDL_modelist[1] = NULL;
}
/* Fill in some window manager capabilities */
this->info.wm_available = 1;
/* We're done! */
return(0);
}
static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
if ( this->screen->format->BitsPerPixel == format->BitsPerPixel ) {
if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
return(SDL_modelist);
} else {
return((SDL_Rect **)-1);
}
} else {
return((SDL_Rect **)0);
}
}
static void ROM_HideMenuBar(_THIS)
{
#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
RgnHandle drawRgn = nil;
RgnHandle tempRgn = nil;
RgnHandle grayRgn = nil;
WindowPtr window = nil;
GDHandle gd = nil;
GrafPtr savePort;
long response;
short height;
EventRecord theEvent;
height = GetMBarHeight();
if ( height > 0 ) {
tempRgn = NewRgn();
drawRgn = NewRgn();
gSaveGrayRgn = NewRgn();
if ( ! tempRgn || ! drawRgn || ! gSaveGrayRgn ) {
goto CLEANUP;
}
grayRgn = GetGrayRgn(); /* No need to check for this */
GetPort(&savePort);
/* Hide the control strip if it's present, and record its
previous position into the dirty region for redrawing.
This isn't necessary, but may help catch stray bits. */
CopyRgn(grayRgn, tempRgn);
if (!Gestalt(gestaltControlStripAttr, &response) &&
(response & (1L << gestaltControlStripExists))) {
gSaveCSVis = SBIsControlStripVisible();
if (gSaveCSVis)
SBShowHideControlStrip(false);
}
DiffRgn(grayRgn, tempRgn, drawRgn);
/* Save the gray region once the control strip is hidden*/
CopyRgn(grayRgn, gSaveGrayRgn);
/* Change the menu height in lowmem */
gSaveMenuBar = height;
LMSetMBarHeight(0);
/* Walk the monitor rectangles, and combine any pieces that
aren't in GrayRgn: menubar, round corners, fake floaters. */
for(gd = GetDeviceList(); gd; gd = GetNextDevice(gd))
{
if (!TestDeviceAttribute(gd, screenDevice)) continue;
if (!TestDeviceAttribute(gd, screenActive)) continue;
RectRgn(tempRgn, &(*gd)->gdRect); /* Get the whole screen */
DiffRgn(tempRgn, grayRgn, tempRgn); /* Subtract out GrayRgn */
UnionRgn(tempRgn, drawRgn, drawRgn);/* Combine all the bits */
}
/* Add the bits into the GrayRgn */
UnionRgn(drawRgn, grayRgn, grayRgn);
/* Modify the vis regions of exposed windows */
window = (FrontWindow()) ? FrontWindow() : (WindowPtr) -1L;
PaintBehind(window, drawRgn);
CalcVisBehind(window, drawRgn);
SetPort(savePort);
/* Yield time so that floaters can catch up */
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
EventAvail(0, &theEvent);
}
CLEANUP:
if (tempRgn) DisposeRgn(tempRgn);
if (drawRgn) DisposeRgn(drawRgn);
#endif /* !TARGET_API_MAC_CARBON */
}
static void ROM_ShowMenuBar(_THIS)
{
#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
RgnHandle drawRgn = nil;
RgnHandle menuRgn = nil;
RgnHandle tempRgn = nil;
RgnHandle grayRgn = nil;
WindowPtr window = nil;
GrafPtr wMgrPort;
GrafPtr savePort;
Rect menuRect;
long response;
short height;
EventRecord theEvent;
RGBColor saveRGB;
RGBColor blackRGB = { 0, 0, 0 };
height = GetMBarHeight();
if ((height <= 0) && (gSaveMenuBar > 0)) {
drawRgn = NewRgn();
menuRgn = NewRgn();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -