Mercurial > sdl-ios-xcode
view src/video/ggi/SDL_ggivideo.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | 8d9bb0cf2c2a |
children | 4da1ee79c9af |
line wrap: on
line source
/* 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" /* GGI-based SDL video driver implementation. */ #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <ggi/ggi.h> #include <ggi/gii.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_ggivideo.h" #include "SDL_ggimouse_c.h" #include "SDL_ggievents_c.h" struct private_hwdata { ggi_visual_t vis; }; ggi_visual_t VIS; /* Initialization/Query functions */ static int GGI_VideoInit (_THIS, SDL_PixelFormat * vformat); static SDL_Rect **GGI_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags); static SDL_Surface *GGI_SetVideoMode (_THIS, SDL_Surface * current, int width, int height, int bpp, Uint32 flags); static int GGI_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors); static void GGI_VideoQuit (_THIS); /* Hardware surface functions */ static int GGI_AllocHWSurface (_THIS, SDL_Surface * surface); static int GGI_LockHWSurface (_THIS, SDL_Surface * surface); static void GGI_UnlockHWSurface (_THIS, SDL_Surface * surface); static void GGI_FreeHWSurface (_THIS, SDL_Surface * surface); /* GGI driver bootstrap functions */ static int GGI_Available (void) { ggi_visual_t *vis; vis = NULL; if (ggiInit () == 0) { vis = ggiOpen (NULL); if (vis != NULL) { ggiClose (vis); } } return (vis != NULL); } static void GGI_DeleteDevice (SDL_VideoDevice * device) { SDL_free (device->hidden); SDL_free (device); } static SDL_VideoDevice * GGI_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)); } if ((device == NULL) || (device->hidden == NULL)) { SDL_OutOfMemory (); if (device) { SDL_free (device); } return (0); } SDL_memset (device->hidden, 0, (sizeof *device->hidden)); /* Set the function pointers */ device->VideoInit = GGI_VideoInit; device->ListModes = GGI_ListModes; device->SetVideoMode = GGI_SetVideoMode; device->SetColors = GGI_SetColors; device->UpdateRects = NULL; device->VideoQuit = GGI_VideoQuit; device->AllocHWSurface = GGI_AllocHWSurface; device->CheckHWBlit = NULL; device->FillHWRect = NULL; device->SetHWColorKey = NULL; device->SetHWAlpha = NULL; device->LockHWSurface = GGI_LockHWSurface; device->UnlockHWSurface = GGI_UnlockHWSurface; device->FlipHWSurface = NULL; device->FreeHWSurface = GGI_FreeHWSurface; device->SetCaption = NULL; device->SetIcon = NULL; device->IconifyWindow = NULL; device->GrabInput = NULL; device->GetWMInfo = NULL; device->InitOSKeymap = GGI_InitOSKeymap; device->PumpEvents = GGI_PumpEvents; device->free = GGI_DeleteDevice; return device; } VideoBootStrap GGI_bootstrap = { "ggi", "General Graphics Interface (GGI)", GGI_Available, GGI_CreateDevice }; static SDL_Rect video_mode; static SDL_Rect *SDL_modelist[4] = { NULL, NULL, NULL, NULL }; int GGI_VideoInit (_THIS, SDL_PixelFormat * vformat) { ggi_mode mode = { 1, {GGI_AUTO, GGI_AUTO}, {GGI_AUTO, GGI_AUTO}, {0, 0}, GT_AUTO, {GGI_AUTO, GGI_AUTO} }; struct private_hwdata *priv; ggi_color pal[256], map[256]; const ggi_directbuffer *db; int err, num_bufs; ggi_pixel white, black; priv = SDL_malloc (sizeof (struct private_hwdata)); if (priv == NULL) { SDL_SetError ("Unhandled GGI mode type!\n"); GGI_VideoQuit (NULL); } if (ggiInit () != 0) { SDL_SetError ("Unable to initialize GGI!\n"); GGI_VideoQuit (NULL); } VIS = ggiOpen (NULL); if (VIS == NULL) { SDL_SetError ("Unable to open default GGI visual!\n"); ggiExit (); GGI_VideoQuit (NULL); } ggiSetFlags (VIS, GGIFLAG_ASYNC); /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ ggiCheckMode (VIS, &mode); /* At this point we should have a valid mode - try to set it */ err = ggiSetMode (VIS, &mode); /* If we couldn't set _any_ modes, something is very wrong */ if (err) { SDL_SetError ("Can't set a mode!\n"); ggiClose (VIS); ggiExit (); GGI_VideoQuit (NULL); } /* Determine the current screen size */ this->info.current_w = mode.virt.x; this->info.current_h = mode.virt.y; /* Set a palette for palletized modes */ if (GT_SCHEME (mode.graphtype) == GT_PALETTE) { ggiSetColorfulPalette (VIS); ggiGetPalette (VIS, 0, 1 << vformat->BitsPerPixel, pal); } /* Now we try to get the DirectBuffer info, which determines whether * SDL can access hardware surfaces directly. */ num_bufs = ggiDBGetNumBuffers (VIS); if (num_bufs > 0) { db = ggiDBGetBuffer (VIS, 0); /* Only handle one DB for now */ vformat->BitsPerPixel = db->buffer.plb.pixelformat->depth; vformat->Rmask = db->buffer.plb.pixelformat->red_mask; vformat->Gmask = db->buffer.plb.pixelformat->green_mask; vformat->Bmask = db->buffer.plb.pixelformat->blue_mask; /* Fill in our hardware acceleration capabilities */ this->info.wm_available = 0; this->info.hw_available = 1; this->info.video_mem = db->buffer.plb.stride * mode.virt.y; } video_mode.x = 0; video_mode.y = 0; video_mode.w = mode.virt.x; video_mode.h = mode.virt.y; SDL_modelist[((vformat->BitsPerPixel + 7) / 8) - 1] = &video_mode; /* We're done! */ return (0); } static SDL_Rect ** GGI_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags) { return (&SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]); } /* Various screen update functions available */ static void GGI_DirectUpdate (_THIS, int numrects, SDL_Rect * rects); SDL_Surface * GGI_SetVideoMode (_THIS, SDL_Surface * current, int width, int height, int bpp, Uint32 flags) { ggi_mode mode = { 1, {GGI_AUTO, GGI_AUTO}, {GGI_AUTO, GGI_AUTO}, {0, 0}, GT_AUTO, {GGI_AUTO, GGI_AUTO} }; const ggi_directbuffer *db; ggi_color pal[256]; int err; fprintf (stderr, "GGI_SetVideoMode()\n"); mode.visible.x = mode.virt.x = width; mode.visible.y = mode.virt.y = height; /* Translate requested SDL bit depth into a GGI mode */ switch (bpp) { case 1: mode.graphtype = GT_1BIT; break; case 2: mode.graphtype = GT_2BIT; break; case 4: mode.graphtype = GT_4BIT; break; case 8: mode.graphtype = GT_8BIT; break; case 15: mode.graphtype = GT_15BIT; break; case 16: mode.graphtype = GT_16BIT; break; case 24: mode.graphtype = GT_24BIT; break; case 32: mode.graphtype = GT_32BIT; break; default: SDL_SetError ("Unknown SDL bit depth, using GT_AUTO....\n"); mode.graphtype = GT_AUTO; } /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ ggiCheckMode (VIS, &mode); /* At this point we should have a valid mode - try to set it */ err = ggiSetMode (VIS, &mode); /* If we couldn't set _any_ modes, something is very wrong */ if (err) { SDL_SetError ("Can't set a mode!\n"); ggiClose (VIS); ggiExit (); GGI_VideoQuit (NULL); } /* Set a palette for palletized modes */ if (GT_SCHEME (mode.graphtype) == GT_PALETTE) { ggiSetColorfulPalette (VIS); ggiGetPalette (VIS, 0, 1 << bpp, pal); } db = ggiDBGetBuffer (VIS, 0); /* Set up the new mode framebuffer */ current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); current->w = mode.virt.x; current->h = mode.virt.y; current->pitch = db->buffer.plb.stride; current->pixels = db->read; /* Set the blit function */ this->UpdateRects = GGI_DirectUpdate; /* We're done */ return (current); } static int GGI_AllocHWSurface (_THIS, SDL_Surface * surface) { return (-1); } static void GGI_FreeHWSurface (_THIS, SDL_Surface * surface) { return; } static int GGI_LockHWSurface (_THIS, SDL_Surface * surface) { return (0); } static void GGI_UnlockHWSurface (_THIS, SDL_Surface * surface) { return; } static void GGI_DirectUpdate (_THIS, int numrects, SDL_Rect * rects) { int i; /* ggiFlush(VIS); */ for (i = 0; i < numrects; i++) { ggiFlushRegion (VIS, rects[i].x, rects[i].y, rects[i].w, rects[i].h); } return; } int GGI_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors) { int i; ggi_color pal[256]; /* Set up the colormap */ for (i = 0; i < ncolors; i++) { pal[i].r = (colors[i].r << 8) | colors[i].r; pal[i].g = (colors[i].g << 8) | colors[i].g; pal[i].b = (colors[i].b << 8) | colors[i].b; } ggiSetPalette (VIS, firstcolor, ncolors, pal); return 1; } void GGI_VideoQuit (_THIS) { } void GGI_FinalQuit (void) { } /* vi: set ts=4 sw=4 expandtab: */