Author: andreas Date: 2010-02-11 00:23:28 -0800 (Thu, 11 Feb 2010) New Revision: 2149 Added: trunk/platforms/Cross/plugins/SqueakFFIPrims/sqManualSurface.c Modified: trunk/platforms/Cross/plugins/SqueakFFIPrims/sqFFI.h Log: Add ExternalForm patches from Josh. Modified: trunk/platforms/Cross/plugins/SqueakFFIPrims/sqFFI.h =================================================================== --- trunk/platforms/Cross/plugins/SqueakFFIPrims/sqFFI.h 2010-01-12 06:28:45 UTC (rev 2148) +++ trunk/platforms/Cross/plugins/SqueakFFIPrims/sqFFI.h 2010-02-11 08:23:28 UTC (rev 2149) @@ -6,7 +6,7 @@ * AUTHOR: Andreas Raab (ar) * ADDRESS: Walt Disney Imagineering, Glendale, CA * EMAIL: [hidden email] -* RCSID: $Id: sqFFI.h,v 1.1 2001/10/24 23:12:24 rowledge Exp $ +* RCSID: $Id$ * * NOTES: * @@ -128,5 +128,23 @@ /* return the float value from a previous call */ double ffiReturnFloatValue(void); +/* The following are for creating, manipulating, and detroying "manual surfaces". + These are surfaces that are managed by Squeak code, which has manual control + over the memory location where the image data is stored (the pointer used may + be obtained via FFI calls, or other means). + + Upon creation, no memory is allocated for the surface. Squeak code is + responsible for passing in a pointer to the memory to use. It is OK to set + the pointer to different values, or to NULL. If the pointer is NULL, then + BitBlt calls to ioLockSurface() will fail. + + createManualFunction() returns a non-negative surface ID if successful, and + -1 otherwise. The other return true for success, and false for failure. +*/ +#include "../SurfacePlugin/SurfacePlugin.h" +void initManualSurfaceFunctionPointers(fn_ioRegisterSurface reg, fn_ioUnregisterSurface unreg, fn_ioFindSurface find); +int createManualSurface(int width, int height, int rowPitch, int depth, int isMSB); +int destroyManualSurface(int surfaceID); +int setManualSurfacePointer(int surfaceID, void* ptr); #endif /* SQ_FFI_H */ Added: trunk/platforms/Cross/plugins/SqueakFFIPrims/sqManualSurface.c =================================================================== --- trunk/platforms/Cross/plugins/SqueakFFIPrims/sqManualSurface.c (rev 0) +++ trunk/platforms/Cross/plugins/SqueakFFIPrims/sqManualSurface.c 2010-02-11 08:23:28 UTC (rev 2149) @@ -0,0 +1,164 @@ +#include "sqFFI.h" +#include "sq.h" + +#include "sqVirtualMachine.h" +extern struct VirtualMachine* interpreterProxy; + +/* Need separate cases for GNU C and MSVC. */ +#ifdef DEBUG +#warning "DEBUG printing enabled" +#define DPRINTF(x) warnPrintf x +#elif defined(_DEBUG) +#pragma message ( "DEBUG printing enabled" ) +#define DPRINTF(x) warnPrintf x +#else +#define DPRINTF(x) +#endif + +#ifndef NULL +#define NULL 0 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +/* Don't want to mess with EXPORT status of functions in SurfacePlugin.c, + we use function-pointers here. */ +static fn_ioRegisterSurface registerSurface = NULL; +static fn_ioUnregisterSurface unregisterSurface = NULL; +static fn_ioFindSurface findSurface = NULL; +void initSurfacePluginFunctionPointers() +{ + registerSurface = (fn_ioRegisterSurface) interpreterProxy->ioLoadFunctionFrom("ioRegisterSurface","SurfacePlugin"); + unregisterSurface = (fn_ioUnregisterSurface) interpreterProxy->ioLoadFunctionFrom("ioUnregisterSurface","SurfacePlugin"); + findSurface = (fn_ioFindSurface) interpreterProxy->ioLoadFunctionFrom("ioFindSurface","SurfacePlugin"); +} + +/* This is the structure that represents a "manual surface". These are + created/destroyed by new primitives in this plugin. During it's life-time, + it may be touched directly from Squeak code to set/clear "ptr", and also + treated as a generic surface via BitBlt's use of the SurfacePlugin. */ +typedef struct { + int width; + int height; + int rowPitch; + int depth; + int isMSB; + void* ptr; + int isLocked; +} ManualSurface; + +/* Create the dispatch-table that SurfacePlugin will use to interact with + instances of "struct ManualSurface" */ +static int manualSurfaceGetFormat(ManualSurface* surface, int* width, int* height, int* depth, int* isMSB); +static void* manualSurfaceLock(ManualSurface* surface, int *pitch, int x, int y, int w, int h); +static int manualSurfaceUnlock(ManualSurface* surface, int x, int y, int w, int h); +static int manualSurfaceShow(ManualSurface* surface, int x, int y, int w, int h); +static sqSurfaceDispatch manualSurfaceDispatch = { + 1, + 0, + (fn_getSurfaceFormat) manualSurfaceGetFormat, + (fn_lockSurface) manualSurfaceLock, + (fn_unlockSurface) manualSurfaceUnlock, + (fn_showSurface) manualSurfaceShow +}; + +/* sqSurfaceDispatch functions *****************************************************************************/ + +int manualSurfaceGetFormat(ManualSurface* surface, int* width, int* height, int* depth, int* isMSB) { + *width = surface->width; + *height = surface->height; + *depth = surface->depth; + *isMSB = surface->isMSB; + DPRINTF(("Getting Surface Format: %lx %d %d %d %d\n", ((int) surface), *width, *height, *depth, *isMSB)); + return 1; +} + +void* manualSurfaceLock(ManualSurface* surface, int *pitch, int x, int y, int w, int h) { + /* Ideally, would be atomic. But it doens't matter for the forseeable future, + since it is only called via BitBlt primitives. */ + int wasLocked = surface->isLocked; + surface->isLocked = 1; + + /* Can't lock if it was already locked. */ + if (wasLocked) return NULL; + + /* If there is no pointer, the lock-attempt fails. */ + if (!surface->ptr) { + surface->isLocked = 0; + return NULL; + } + + /* Success! Return the pointer. */ + *pitch = surface->rowPitch; + DPRINTF(("Locked Surface: %lx Input Rect: %d %d %d %d Row Pitch: %d\n", ((int) surface), x, y, w, h, *pitch)); + return surface->ptr; +} + +int manualSurfaceUnlock(ManualSurface* surface, int x, int y, int w, int h) { + surface->isLocked = 0; + DPRINTF(("Unlocked Surface: %lx Rect: %d %d %d %d\n", ((int) surface), x, y, w, h)); + return 1; +} + +int manualSurfaceShow(ManualSurface* surface, int x, int y, int w, int h) { + /* Unsupported */ + return 0; +} + +/* primitive interface functions (i.e. called from Squeak) *********************************************/ + +/* Answer non-negative surfaceID if successful, and -1 for failure. */ +int createManualSurface(int width, int height, int rowPitch, int depth, int isMSB) { + ManualSurface* newSurface; + int surfaceID; + int result; + + if (width < 0) return -1; + if (height < 0) return -1; + if (rowPitch < (width*depth)/8) return -1; + if (depth < 1 || depth > 32) return -1; + if (!registerSurface) return -1; /* failure... couldn't init function-pointer */ + + newSurface = (ManualSurface*)malloc(sizeof(ManualSurface)); + if (!newSurface) return -1; + newSurface->width = width; + newSurface->height = height; + newSurface->rowPitch = rowPitch; + newSurface->depth = depth; + newSurface->isMSB = isMSB; + newSurface->ptr = NULL; + newSurface->isLocked = FALSE; + + result = registerSurface((int)newSurface, &manualSurfaceDispatch, &surfaceID); + if (!result) { + /* Failed to register surface. */ + free(newSurface); + return -1; + } + else { + return surfaceID; + } +} + +int destroyManualSurface(int surfaceID) { + if (!unregisterSurface) return 0; /* failure... couldn't init function-pointer */ + else return unregisterSurface(surfaceID); +} + +int setManualSurfacePointer(int surfaceID, void* ptr) { + int surfaceHandle; + ManualSurface *surface; + int result; + if (!findSurface) return FALSE; /* failure... couldn't init function-pointer */ + result = findSurface(surfaceID, NULL, &surfaceHandle); + if (!result) return FALSE; /* failed to find surface */ + surface = (ManualSurface*)surfaceHandle; + if (surface->isLocked) return FALSE; /* can't set pointer while surface is locked */ + surface->ptr = ptr; + DPRINTF(("Set Surface: %lx Pointer: %lx\n", surfaceID, ((int)ptr) )); + return TRUE; +} |
Free forum by Nabble | Edit this page |