[Vm-dev] [commit] r2149 - Add ExternalForm patches from Josh.

commits at squeakvm.org commits at squeakvm.org
Thu Feb 11 08:23:28 UTC 2010


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:   andreasr at wdi.disney.com
-*   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;
+}



More information about the Vm-dev mailing list