[commit] r2149 - Add ExternalForm patches from Josh.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit] r2149 - Add ExternalForm patches from Josh.

commits-3
 
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;
+}