Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Lambermont <hans@lambermont.dyndns.org>2002-10-12 15:37:38 +0400
committerHans Lambermont <hans@lambermont.dyndns.org>2002-10-12 15:37:38 +0400
commit12315f4d0e0ae993805f141f64cb8c73c5297311 (patch)
tree59b45827cd8293cfb727758989c7a74b40183974 /intern/ghost/test
Initial revisionv2.25
Diffstat (limited to 'intern/ghost/test')
-rwxr-xr-xintern/ghost/test/Makefile86
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c543
-rwxr-xr-xintern/ghost/test/gears/GHOST_Test.cpp745
-rwxr-xr-xintern/ghost/test/gears/Makefile48
-rw-r--r--intern/ghost/test/make/msvc_6_0/gears.dsp102
-rw-r--r--intern/ghost/test/make/msvc_6_0/gears_C.dsp102
-rw-r--r--intern/ghost/test/make/msvc_6_0/ghost_test.dsw77
-rw-r--r--intern/ghost/test/multitest/Basic.c68
-rw-r--r--intern/ghost/test/multitest/Basic.h44
-rw-r--r--intern/ghost/test/multitest/EventToBuf.c236
-rw-r--r--intern/ghost/test/multitest/EventToBuf.h35
-rw-r--r--intern/ghost/test/multitest/GL.h43
-rw-r--r--intern/ghost/test/multitest/Makefile60
-rwxr-xr-xintern/ghost/test/multitest/MultiTest.c855
-rw-r--r--intern/ghost/test/multitest/ScrollBar.c145
-rw-r--r--intern/ghost/test/multitest/ScrollBar.h56
-rw-r--r--intern/ghost/test/multitest/Util.c73
-rw-r--r--intern/ghost/test/multitest/Util.h35
-rw-r--r--intern/ghost/test/multitest/WindowData.c60
-rw-r--r--intern/ghost/test/multitest/WindowData.h40
20 files changed, 3453 insertions, 0 deletions
diff --git a/intern/ghost/test/Makefile b/intern/ghost/test/Makefile
new file mode 100755
index 00000000000..bbd1988a778
--- /dev/null
+++ b/intern/ghost/test/Makefile
@@ -0,0 +1,86 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# GHOST test applications makefile.
+# This bounces to test application directories.
+#
+
+LIBNAME = ghost
+SOURCEDIR = intern/$(LIBNAME)/test
+DIR = $(OCGDIR)/$(SOURCEDIR)
+DIRS = gears
+
+include nan_subdirs.mk
+
+include nan_compile.mk
+include nan_link.mk
+
+OCGGHOST = $(OCGDIR)/intern/$(LIBNAME)
+GEARDIR = $(OCGGHOST)/test/$(DEBUG_DIR)gears.app
+
+LIBS = $(OCGGHOST)/$(DEBUG_DIR)libghost.a
+SLIBS += $(LCGDIR)/string/lib/libstring.a
+
+all debug:: $(LIBS)
+ @echo "****> linking $@ in $(SOURCEDIR)"
+ifeq ($(OS),darwin)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)gears $(DIR)/$(DEBUG_DIR)GHOST_Test.o $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+ @# set up directory structure for the OSX application bundle
+ @[ -d $(OCGGHOST)/test/ ] || mkdir $(OCGGHOST)/test/
+ @[ -d $(OCGGHOST)/test/debug ] || mkdir $(OCGGHOST)/test/debug
+ @[ -d $(GEARDIR) ] || mkdir $(GEARDIR)
+ @[ -d $(GEARDIR)/Contents ] || mkdir $(GEARDIR)/Contents
+ @[ -d $(GEARDIR)/Contents/MacOS ] || mkdir $(GEARDIR)/Contents/MacOS
+ @[ -d $(GEARDIR)/Contents/Resources ] || mkdir $(GEARDIR)/Contents/Resources
+ @[ -d $(GEARDIR)/Contents/Resources/English.lproj ] || mkdir $(GEARDIR)/Contents/Resources/English.lproj
+ @[ -d $(GEARDIR)/Contents/Resources/English.lproj/MainMenu.nib ] || mkdir $(GEARDIR)/Contents/Resources/English.lproj/MainMenu.nib
+ @# copy the files into the bundle directory tree
+ cp -f $(DIR)/$(DEBUG_DIR)gears $(GEARDIR)/Contents/MacOS
+ cp -f gears/resources/osx/PkgInfo $(GEARDIR)/Contents/
+ cp -f gears/resources/osx/Info.plist $(GEARDIR)/Contents/
+ cp -f gears/resources/osx/English.lproj/InfoPlist.strings $(GEARDIR)/Contents/Resources/English.lproj
+ cp -f gears/resources/osx/English.lproj/MainMenu.nib/classes.nib $(GEARDIR)/Contents/Resources/English.lproj
+ cp -f gears/resources/osx/English.lproj/MainMenu.nib/info.nib $(GEARDIR)/Contents/Resources/English.lproj
+ cp -f gears/resources/osx/English.lproj/MainMenu.nib/objects.nib $(GEARDIR)/Contents/Resources/English.lproj
+else
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)gears_cpp $(DIR)/$(DEBUG_DIR)GHOST_Test.o $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)gears_c $(DIR)/$(DEBUG_DIR)GHOST_C-Test.o $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+endif
+
+clean::
+ @# mac stuff. well ok, only the binary
+ @rm -f $(DIR)/gears $(DIR)/debug/gears
+ @# others
+ @rm -f $(DIR)/gears_c $(DIR)/debug/gears_c
+ @rm -f $(DIR)/gears_cpp $(DIR)/debug/gears_cpp
+
+test:: all
+ $(DIR)/gears_cpp
+ $(DIR)/gears_c
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
new file mode 100644
index 00000000000..16d8b421d5b
--- /dev/null
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -0,0 +1,543 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ *
+ * Simple test file for the GHOST library.
+ * The OpenGL gear code is taken from the Qt sample code which,
+ * in turn, is probably taken from somewhere as well.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "GHOST_C-api.h"
+
+#if defined(WIN32) || defined(__APPLE__)
+ #ifdef WIN32
+ #include <windows.h>
+ #include <GL/gl.h>
+ #else /* WIN32 */
+ /* __APPLE__ is defined */
+ #include <AGL/gl.h>
+ #endif /* WIN32 */
+#else /* defined(WIN32) || defined(__APPLE__) */
+ #include <GL/gl.h>
+#endif /* defined(WIN32) || defined(__APPLE__) */
+
+
+static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time);
+
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLfloat fAngle = 0.0;
+static int sExitRequested = 0;
+static GHOST_SystemHandle shSystem = NULL;
+static GHOST_WindowHandle sMainWindow = NULL;
+static GHOST_WindowHandle sSecondaryWindow = NULL;
+static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor;
+static GHOST_WindowHandle sFullScreenWindow = NULL;
+static GHOST_TimerTaskHandle sTestTimer;
+static GHOST_TimerTaskHandle sGearsTimer;
+
+
+static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
+{
+ printf("timer1, time=%d\n", (int)time);
+}
+
+
+static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+ const double pi = 3.14159264;
+
+ r0 = inner_radius;
+ r1 = (float)(outer_radius - tooth_depth/2.0);
+ r2 = (float)(outer_radius + tooth_depth/2.0);
+
+ da = (float)(2.0*pi / teeth / 4.0);
+
+ glShadeModel(GL_FLAT);
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = (float)(2.0*pi / teeth / 4.0);
+ for (i=0;i<teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = (float)(2.0*pi / teeth / 4.0);
+ for (i=0;i<teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5));
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5));
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
+ u = (float)(r2*cos(angle+da) - r1*cos(angle));
+ v = (float)(r2*sin(angle+da) - r1*sin(angle));
+ len = (float)(sqrt(u*u + v*v));
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5));
+ glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5));
+ glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5));
+ u = (float)(r1*cos(angle+3*da) - r2*cos(angle+2*da));
+ v = (float)(r1*sin(angle+3*da) - r2*sin(angle+2*da));
+ glNormal3f(v, -u, 0.0);
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
+ glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
+ }
+ glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(width*0.5));
+ glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(-width*0.5));
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = (float)(i * 2.0*pi / teeth);
+ glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
+ glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
+ }
+ glEnd();
+}
+
+
+
+static void drawGearGL(int id)
+{
+ static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
+ static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
+ static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
+ static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ switch (id)
+ {
+ case 1:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
+ gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ break;
+ case 2:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
+ gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ break;
+ case 3:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
+ gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ break;
+ default:
+ break;
+ }
+ glEnable(GL_NORMALIZE);
+}
+
+
+static void drawGL(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(fAngle, 0.0, 0.0, 1.0);
+ drawGearGL(1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2.0f, 0.0f);
+ glRotatef((float)(-2.0*fAngle-9.0), 0.0, 0.0, 1.0);
+ drawGearGL(2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 2.2f, -1.8f);
+ glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef((float)(2.0*fAngle-2.0), 0.0, 0.0, 1.0);
+ drawGearGL(3);
+ glPopMatrix();
+
+ glPopMatrix();
+}
+
+
+static void setViewPortGL(GHOST_WindowHandle hWindow)
+{
+ GHOST_RectangleHandle hRect = NULL;
+ GLfloat w, h;
+
+ GHOST_ActivateWindowDrawingContext(hWindow);
+ hRect = GHOST_GetClientBounds(hWindow);
+
+ w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
+ h = 1.0;
+
+ glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-w, w, -h, h, 5.0, 60.0);
+ /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+
+ glClearColor(.2f,0.0f,0.0f,0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ GHOST_DisposeRectangle(hRect);
+}
+
+
+
+int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
+{
+ int handled = 1;
+ int cursor;
+ int visibility;
+ GHOST_TEventKeyData* keyData = NULL;
+ GHOST_DisplaySetting setting;
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+
+ switch (GHOST_GetEventType(hEvent))
+ {
+ /*
+ case GHOST_kEventUnknown:
+ break;
+ case GHOST_kEventCursorButton:
+ break;
+ case GHOST_kEventCursorMove:
+ break;
+ */
+ case GHOST_kEventKeyUp:
+ break;
+
+ case GHOST_kEventKeyDown:
+ {
+ keyData = (GHOST_TEventKeyData*)GHOST_GetEventData(hEvent);
+ switch (keyData->key)
+ {
+ case GHOST_kKeyC:
+ {
+ cursor = sCursor;
+ cursor++;
+ if (cursor >= GHOST_kStandardCursorNumCursors)
+ {
+ cursor = GHOST_kStandardCursorFirstCursor;
+ }
+ sCursor = (GHOST_TStandardCursor)cursor;
+ GHOST_SetCursorShape(window, sCursor);
+ }
+ break;
+ case GHOST_kKeyF:
+ if (!GHOST_GetFullScreen(shSystem))
+ {
+ /* Begin fullscreen mode */
+ setting.bpp = 24;
+ setting.frequency = 85;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+
+ /*
+ setting.bpp = 16;
+ setting.frequency = 75;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+ */
+
+ sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting,
+ false /* stereo flag */);
+ }
+ else
+ {
+ GHOST_EndFullScreen(shSystem);
+ sFullScreenWindow = 0;
+ }
+ break;
+ case GHOST_kKeyH:
+ {
+ visibility = GHOST_GetCursorVisibility(window);
+ GHOST_SetCursorVisibility(window, !visibility);
+ }
+ break;
+ case GHOST_kKeyQ:
+ if (GHOST_GetFullScreen(shSystem))
+ {
+ GHOST_EndFullScreen(shSystem);
+ sFullScreenWindow = 0;
+ }
+ sExitRequested = 1;
+ case GHOST_kKeyT:
+ if (!sTestTimer)
+ {
+ sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
+ }
+ else
+ {
+ GHOST_RemoveTimer(shSystem, sTestTimer);
+ sTestTimer = 0;
+ }
+ break;
+ case GHOST_kKeyW:
+ {
+ if (sMainWindow)
+ {
+ char *title = GHOST_GetTitle(sMainWindow);
+ char *ntitle = malloc(strlen(title)+2);
+
+ sprintf(ntitle, "%s-", title);
+ GHOST_SetTitle(sMainWindow, ntitle);
+
+ free(ntitle);
+ free(title);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowClose:
+ {
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+ if (window == sMainWindow)
+ {
+ sExitRequested = 1;
+ }
+ else
+ {
+ if (sGearsTimer)
+ {
+ GHOST_RemoveTimer(shSystem, sGearsTimer);
+ sGearsTimer = 0;
+ }
+ GHOST_DisposeWindow(shSystem, window);
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowActivate:
+ handled = 0;
+ break;
+ case GHOST_kEventWindowDeactivate:
+ handled = 0;
+ break;
+ case GHOST_kEventWindowUpdate:
+ {
+ GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
+ if (!GHOST_ValidWindow(shSystem, window))
+ break;
+ //if (!m_fullScreenWindow)
+ {
+ setViewPortGL(window);
+ drawGL();
+ GHOST_SwapWindowBuffers(window);
+ }
+ }
+ break;
+
+ default:
+ handled = 0;
+ break;
+ }
+ return handled;
+}
+
+
+int main(int argc, char** argv)
+{
+ char* title1 = "gears - main window";
+ char* title2 = "gears - secondary window";
+ GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
+
+ /* Create the system */
+ shSystem = GHOST_CreateSystem();
+ GHOST_AddEventConsumer(shSystem, consumer);
+
+ if (shSystem)
+ {
+ /* Create the main window */
+ sMainWindow = GHOST_CreateWindow(shSystem,
+ title1,
+ 10,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL);
+ if (!sMainWindow)
+ {
+ printf("could not create main window\n");
+ exit(-1);
+ }
+
+ /* Create a secondary window */
+ sSecondaryWindow = GHOST_CreateWindow(shSystem,
+ title2,
+ 340,
+ 64,
+ 320,
+ 200,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL);
+ if (!sSecondaryWindow)
+ {
+ printf("could not create secondary window\n");
+ exit(-1);
+ }
+
+ /* Install a timer to have the gears running */
+ sGearsTimer = GHOST_InstallTimer(shSystem,
+ 0,
+ 10,
+ gearsTimerProc,
+ sMainWindow);
+
+ /* Enter main loop */
+ while (!sExitRequested)
+ {
+ if (!GHOST_ProcessEvents(shSystem, 0))
+ {
+#ifdef WIN32
+ /* If there were no events, be nice to other applications */
+ Sleep(10);
+#endif
+ }
+ GHOST_DispatchEvents(shSystem);
+ }
+ }
+
+ /* Dispose windows */
+ if (GHOST_ValidWindow(shSystem, sMainWindow))
+ {
+ GHOST_DisposeWindow(shSystem, sMainWindow);
+ }
+ if (GHOST_ValidWindow(shSystem, sSecondaryWindow))
+ {
+ GHOST_DisposeWindow(shSystem, sSecondaryWindow);
+ }
+
+ /* Dispose the system */
+ GHOST_DisposeSystem(shSystem);
+ GHOST_DisposeEventConsumer(consumer);
+
+ return 0;
+}
+
+
+static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
+{
+ GHOST_WindowHandle hWindow = NULL;
+ fAngle += 2.0;
+ view_roty += 1.0;
+ hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
+ if (GHOST_GetFullScreen(shSystem))
+ {
+ /* Running full screen */
+ GHOST_InvalidateWindow(sFullScreenWindow);
+ }
+ else
+ {
+ if (GHOST_ValidWindow(shSystem, hWindow))
+ {
+ GHOST_InvalidateWindow(hWindow);
+ }
+ }
+}
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
new file mode 100755
index 00000000000..a5459c9da9b
--- /dev/null
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -0,0 +1,745 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id$
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * Simple test file for the GHOST library.
+ * The OpenGL gear code is taken from the Qt sample code which,
+ * in turn, is probably taken from somewhere as well.
+ * @author Maarten Gribnau
+ * @date May 31, 2001
+ * Stereo code by Raymond de Vries, januari 2002
+ */
+
+#include <iostream>
+#include <math.h>
+
+#if defined(WIN32) || defined(__APPLE__)
+ #ifdef WIN32
+ #include <windows.h>
+ #include <atlbase.h>
+
+ #include <GL/gl.h>
+ #else // WIN32
+ // __APPLE__ is defined
+ #include <AGL/gl.h>
+ #endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
+ #include <GL/gl.h>
+#endif // defined(WIN32) || defined(__APPLE__)
+
+#include "STR_String.h"
+#include "GHOST_Rect.h"
+
+#include "GHOST_ISystem.h"
+#include "GHOST_IEvent.h"
+#include "GHOST_IEventConsumer.h"
+
+
+#define LEFT_EYE 0
+#define RIGHT_EYE 1
+
+static bool nVidiaWindows; // very dirty but hey, it's for testing only
+
+static void gearsTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
+
+static class Application* fApp;
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLfloat fAngle = 0.0;
+static GHOST_ISystem* fSystem = 0;
+
+
+void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
+ float zero_plane, float dist,
+ float eye);
+
+
+static void testTimerProc(GHOST_ITimerTask* /*task*/, GHOST_TUns64 time)
+{
+ std::cout << "timer1, time=" << (int)time << "\n";
+}
+
+
+static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth/2.0;
+ r2 = outer_radius + tooth_depth/2.0;
+
+ const double pi = 3.14159264;
+ da = 2.0*pi / teeth / 4.0;
+
+ glShadeModel(GL_FLAT);
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5);
+ glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5);
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), width*0.5);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5);
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5);
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), -width*0.5);
+ glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5);
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5);
+ glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5);
+ u = r2*cos(angle+da) - r1*cos(angle);
+ v = r2*sin(angle+da) - r1*sin(angle);
+ len = sqrt(u*u + v*v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), width*0.5);
+ glVertex3f(r2*cos(angle+da), r2*sin(angle+da), -width*0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5);
+ glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5);
+ u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
+ v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5);
+ glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ }
+ glVertex3f(r1*cos(0.0), r1*sin(0.0), width*0.5);
+ glVertex3f(r1*cos(0.0), r1*sin(0.0), -width*0.5);
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0.0);
+ glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5);
+ glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5);
+ }
+ glEnd();
+}
+
+
+
+static void drawGearGL(int id)
+{
+ static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
+ static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
+ static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
+ static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ switch (id)
+ {
+ case 1:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
+ gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ break;
+ case 2:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
+ gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ break;
+ case 3:
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
+ gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ break;
+ default:
+ break;
+ }
+ glEnable(GL_NORMALIZE);
+}
+
+
+void RenderCamera()
+{
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+}
+
+
+void RenderScene()
+{
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(fAngle, 0.0, 0.0, 1.0);
+ drawGearGL(1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1f, -2.0f, 0.0f);
+ glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0);
+ drawGearGL(2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1f, 2.2f, -1.8f);
+ glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0);
+ drawGearGL(3);
+ glPopMatrix();
+}
+
+
+static void View(GHOST_IWindow* window, bool stereo, int eye = 0)
+{
+ window->activateDrawingContext();
+ GHOST_Rect bnds;
+ int noOfScanlines = 0, lowerScanline;
+ int verticalBlankingInterval = 32; // hard coded for testing purposes, display device dependant
+ float left, right, bottom, top;
+ float nearplane, farplane, zeroPlane, distance;
+ float eyeSeparation = 0.62;
+ window->getClientBounds(bnds);
+ GLfloat w = float(bnds.getWidth()) / float(bnds.getHeight());
+ GLfloat h = 1.0;
+
+ // viewport
+ if(stereo)
+ {
+ if(nVidiaWindows)
+ {
+ // handled by nVidia driver so act as normal (explicitly put here since
+ // it -is- stereo)
+ glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
+ }
+ else
+ { // generic cross platform above-below stereo
+ noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2;
+ switch(eye)
+ {
+ case LEFT_EYE:
+ // upper half of window
+ lowerScanline = bnds.getHeight() - noOfScanlines;
+ break;
+ case RIGHT_EYE:
+ // lower half of window
+ lowerScanline = 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ noOfScanlines = bnds.getHeight();
+ lowerScanline = 0;
+ }
+
+ glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines);
+
+ // projection
+ left = -6.0;
+ right = 6.0;
+ bottom = -4.8;
+ top = 4.8;
+ nearplane = 5.0;
+ farplane = 60.0;
+
+ if(stereo)
+ {
+ zeroPlane = 0.0;
+ distance = 14.5;
+ switch(eye)
+ {
+ case LEFT_EYE:
+ StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, -eyeSeparation / 2.0);
+ break;
+ case RIGHT_EYE:
+ StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, eyeSeparation / 2.0);
+ break;
+ }
+ }
+ else
+ {
+// left = -w;
+// right = w;
+// bottom = -h;
+// top = h;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(left, right, bottom, top, 5.0, 60.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+
+ }
+
+ glClearColor(.2f,0.0f,0.0f,0.0f);
+}
+
+
+void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
+ float zero_plane, float dist,
+ float eye)
+/* Perform the perspective projection for one eye's subfield.
+The projection is in the direction of the negative z axis.
+
+-6.0, 6.0, -4.8, 4.8,
+left, right, bottom, top = the coordinate range, in the plane of zero
+parallax setting, which will be displayed on the screen. The
+ratio between (right-left) and (top-bottom) should equal the aspect
+ratio of the display.
+
+6.0, -6.0,
+near, far = the z-coordinate values of the clipping planes.
+
+0.0,
+zero_plane = the z-coordinate of the plane of zero parallax setting.
+
+14.5,
+dist = the distance from the center of projection to the plane
+of zero parallax.
+
+-0.31
+eye = half the eye separation; positive for the right eye subfield,
+negative for the left eye subfield.
+*/
+{
+ float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw,
+ dx, dy, n_over_d;
+
+ dx = right - left;
+ dy = top - bottom;
+
+ xmid = (right + left) / 2.0;
+ ymid = (top + bottom) / 2.0;
+
+ clip_near = dist + zero_plane - nearplane;
+ clip_far = dist + zero_plane - farplane;
+
+ n_over_d = clip_near / dist;
+
+ topw = n_over_d * dy / 2.0;
+ bottomw = -topw;
+ rightw = n_over_d * (dx / 2.0 - eye);
+ leftw = n_over_d *(-dx / 2.0 - eye);
+
+ /* Need to be in projection mode for this. */
+ glLoadIdentity();
+ glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far);
+
+ glTranslatef(-xmid - eye, -ymid, -zero_plane - dist);
+ return;
+} /* stereoproj */
+
+
+class Application : public GHOST_IEventConsumer {
+public:
+ Application(GHOST_ISystem* system);
+ ~Application(void);
+ virtual bool processEvent(GHOST_IEvent* event);
+
+ GHOST_ISystem* m_system;
+ GHOST_IWindow* m_mainWindow;
+ GHOST_IWindow* m_secondaryWindow;
+ GHOST_IWindow* m_fullScreenWindow;
+ GHOST_ITimerTask* m_gearsTimer, *m_testTimer;
+ GHOST_TStandardCursor m_cursor;
+ bool m_exitRequested;
+
+ bool stereo;
+};
+
+
+Application::Application(GHOST_ISystem* system)
+ : m_system(system), m_mainWindow(0), m_secondaryWindow(0), m_fullScreenWindow(0),
+ m_gearsTimer(0), m_testTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor),
+ m_exitRequested(false), stereo(false)
+{
+ fApp = this;
+
+ // Create the main window
+ STR_String title1 ("gears - main window");
+ m_mainWindow = system->createWindow(title1, 10, 64, 320, 200, GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL, true /* stereo flag */);
+
+ if (!m_mainWindow) {
+ std::cout << "could not create main window\n";
+ exit(-1);
+ }
+
+ // Create a secondary window
+ STR_String title2 ("gears - secondary window");
+ m_secondaryWindow = system->createWindow(title2, 340, 64, 320, 200, GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL, false /* stereo flag */);
+ if (!m_secondaryWindow) {
+ cout << "could not create secondary window\n";
+ exit(-1);
+ }
+
+ // Install a timer to have the gears running
+ m_gearsTimer = system->installTimer(0 /*delay*/, 20/*interval*/, gearsTimerProc, m_mainWindow);
+}
+
+
+Application::~Application(void)
+{
+ // Dispose windows
+ if (m_system->validWindow(m_mainWindow)) {
+ m_system->disposeWindow(m_mainWindow);
+ }
+ if (m_system->validWindow(m_secondaryWindow)) {
+ m_system->disposeWindow(m_secondaryWindow);
+ }
+}
+
+
+bool Application::processEvent(GHOST_IEvent* event)
+{
+ GHOST_IWindow* window = event->getWindow();
+ bool handled = true;
+
+ switch (event->getType()) {
+/* case GHOST_kEventUnknown:
+ break;
+ case GHOST_kEventCursorButton:
+ std::cout << "GHOST_kEventCursorButton"; break;
+ case GHOST_kEventCursorMove:
+ std::cout << "GHOST_kEventCursorMove"; break;
+*/
+ case GHOST_kEventKeyUp:
+ break;
+
+ case GHOST_kEventKeyDown:
+ {
+ GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*) event->getData();
+ switch (keyData->key) {
+ case GHOST_kKeyC:
+ {
+ int cursor = m_cursor;
+ cursor++;
+ if (cursor >= GHOST_kStandardCursorNumCursors) {
+ cursor = GHOST_kStandardCursorFirstCursor;
+ }
+ m_cursor = (GHOST_TStandardCursor)cursor;
+ window->setCursorShape(m_cursor);
+ }
+ break;
+
+ case GHOST_kKeyE:
+ {
+ int x = 200, y= 200;
+ m_system->setCursorPosition(x,y);
+ break;
+ }
+
+ case GHOST_kKeyF:
+ if (!m_system->getFullScreen()) {
+ // Begin fullscreen mode
+ GHOST_DisplaySetting setting;
+
+ setting.bpp = 16;
+ setting.frequency = 50;
+ setting.xPixels = 640;
+ setting.yPixels = 480;
+ m_system->beginFullScreen(setting, &m_fullScreenWindow, false /* stereo flag */);
+ }
+ else {
+ m_system->endFullScreen();
+ m_fullScreenWindow = 0;
+ }
+ break;
+
+ case GHOST_kKeyH:
+ window->setCursorVisibility(!window->getCursorVisibility());
+ break;
+
+ case GHOST_kKeyM:
+ {
+ bool down = false;
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftShift,down);
+ if (down) {
+ std::cout << "left shift down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightShift,down);
+ if (down) {
+ std::cout << "right shift down\n"; }
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftAlt,down);
+ if (down) {
+ std::cout << "left Alt down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightAlt,down);
+ if (down) {
+ std::cout << "right Alt down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyLeftControl,down);
+ if (down) {
+ std::cout << "left control down\n";
+ }
+ m_system->getModifierKeyState(GHOST_kModifierKeyRightControl,down);
+ if (down) {
+ std::cout << "right control down\n";
+ }
+ }
+ break;
+
+ case GHOST_kKeyQ:
+ if (m_system->getFullScreen())
+ {
+ m_system->endFullScreen();
+ m_fullScreenWindow = 0;
+ }
+ m_exitRequested = true;
+ break;
+
+ case GHOST_kKeyS: // toggle mono and stereo
+ if(stereo)
+ stereo = false;
+ else
+ stereo = true;
+ break;
+
+ case GHOST_kKeyT:
+ if (!m_testTimer) {
+ m_testTimer = m_system->installTimer(0, 1000, testTimerProc);
+ }
+
+ else {
+ m_system->removeTimer(m_testTimer);
+ m_testTimer = 0;
+ }
+
+ break;
+
+ case GHOST_kKeyW:
+ if (m_mainWindow)
+ {
+ STR_String title;
+ m_mainWindow->getTitle(title);
+ title += "-";
+ m_mainWindow->setTitle(title);
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowClose:
+ {
+ GHOST_IWindow* window = event->getWindow();
+ if (window == m_mainWindow) {
+ m_exitRequested = true;
+ }
+ else {
+ m_system->disposeWindow(window);
+ }
+ }
+ break;
+
+ case GHOST_kEventWindowActivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowDeactivate:
+ handled = false;
+ break;
+
+ case GHOST_kEventWindowUpdate:
+ {
+ GHOST_IWindow* window = event->getWindow();
+ if(!m_system->validWindow(window))
+ break;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if(stereo)
+ {
+ View(window, stereo, LEFT_EYE);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+
+ View(window, stereo, RIGHT_EYE);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+ }
+ else
+ {
+ View(window, stereo);
+ glPushMatrix();
+ RenderCamera();
+ RenderScene();
+ glPopMatrix();
+ }
+ window->swapBuffers();
+ }
+ break;
+
+ default:
+ handled = false;
+ break;
+ }
+ return handled;
+}
+
+
+int main(int /*argc*/, char** /*argv*/)
+{
+ nVidiaWindows = false;
+// nVidiaWindows = true;
+
+#ifdef WIN32
+ /* Set a couple of settings in the registry for the nVidia detonator driver.
+ * So this is very specific...
+ */
+ if(nVidiaWindows)
+ {
+ LONG lresult;
+ HKEY hkey = 0;
+ DWORD dwd = 0;
+ unsigned char buffer[128];
+
+ CRegKey regkey;
+ DWORD keyValue;
+// lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable");
+ lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
+ KEY_ALL_ACCESS );
+
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully opened key\n");
+#if 0
+ lresult = regkey.QueryValue(&keyValue, "StereoEnable");
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully queried key\n");
+#endif
+ lresult = regkey.SetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
+ "1");
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully set value for key\n");
+ regkey.Close();
+ if(lresult == ERROR_SUCCESS)
+ printf("Succesfully closed key\n");
+// regkey.Write("2");
+ }
+#endif // WIN32
+
+ // Create the system
+ GHOST_ISystem::createSystem();
+ fSystem = GHOST_ISystem::getSystem();
+
+ if (fSystem) {
+ // Create an application object
+ Application app (fSystem);
+
+ // Add the application as event consumer
+ fSystem->addEventConsumer(&app);
+
+ // Enter main loop
+ while (!app.m_exitRequested) {
+ //printf("main: loop\n");
+ fSystem->processEvents(true);
+ fSystem->dispatchEvents();
+ }
+ }
+
+ // Dispose the system
+ GHOST_ISystem::disposeSystem();
+
+ return 0;
+}
+
+
+static void gearsTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 /*time*/)
+{
+ fAngle += 2.0;
+ view_roty += 1.0;
+ GHOST_IWindow* window = (GHOST_IWindow*)task->getUserData();
+ if (fApp->m_fullScreenWindow) {
+ // Running full screen
+ fApp->m_fullScreenWindow->invalidate();
+ }
+ else {
+ if (fSystem->validWindow(window)) {
+ window->invalidate();
+ }
+ }
+}
diff --git a/intern/ghost/test/gears/Makefile b/intern/ghost/test/gears/Makefile
new file mode 100755
index 00000000000..b7966b4d157
--- /dev/null
+++ b/intern/ghost/test/gears/Makefile
@@ -0,0 +1,48 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# GHOST gears test application Makefile
+#
+
+LIBNAME = gearstest
+DIR = $(OCGDIR)/intern/ghost/test
+
+# we don't want a library here, only object files:
+ALLTARGETS = $(OBJS)
+
+include nan_compile.mk
+
+CFLAGS += $(LEVEL_2_C_WARNINGS)
+CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I../..
+
diff --git a/intern/ghost/test/make/msvc_6_0/gears.dsp b/intern/ghost/test/make/msvc_6_0/gears.dsp
new file mode 100644
index 00000000000..3e809a6b604
--- /dev/null
+++ b/intern/ghost/test/make/msvc_6_0/gears.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="gears" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=gears - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "gears.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "gears.mak" CFG="gears - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "gears - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "gears - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "gears - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../.." /I "../../../../string" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "gears - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../.." /I "../../../../string" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "gears - Win32 Release"
+# Name "gears - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\gears\GHOST_Test.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/intern/ghost/test/make/msvc_6_0/gears_C.dsp b/intern/ghost/test/make/msvc_6_0/gears_C.dsp
new file mode 100644
index 00000000000..5972d123268
--- /dev/null
+++ b/intern/ghost/test/make/msvc_6_0/gears_C.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="gears_C" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=gears_C - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "gears_C.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "gears_C.mak" CFG="gears_C - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "gears_C - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "gears_C - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "gears_C - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../.." /I "../../../../string" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "gears_C - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Intermediate_Dir "../../../../../../obj/windows/intern/ghost/test/debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../.." /I "../../../../string" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 glu32.lib opengl32.lib user32.lib gdi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "gears_C - Win32 Release"
+# Name "gears_C - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE="..\..\gears\GHOST_C-Test.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/intern/ghost/test/make/msvc_6_0/ghost_test.dsw b/intern/ghost/test/make/msvc_6_0/ghost_test.dsw
new file mode 100644
index 00000000000..03bf5eb5c9a
--- /dev/null
+++ b/intern/ghost/test/make/msvc_6_0/ghost_test.dsw
@@ -0,0 +1,77 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "gears"=.\gears.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name ghost
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name string
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "gears_C"=.\gears_C.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name ghost
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name string
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "ghost"=..\..\..\make\msvc\ghost.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "string"=..\..\..\..\string\make\msvc_6_0\string.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/intern/ghost/test/multitest/Basic.c b/intern/ghost/test/multitest/Basic.c
new file mode 100644
index 00000000000..c26cf7c92ca
--- /dev/null
+++ b/intern/ghost/test/multitest/Basic.c
@@ -0,0 +1,68 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "Basic.h"
+
+
+int min_i(int a, int b) {
+ return (a<b)?a:b;
+}
+int max_i(int a, int b) {
+ return (b<a)?a:b;
+}
+int clamp_i(int val, int min, int max) {
+ return min_i(max_i(val, min), max);
+}
+
+float min_f(float a, float b) {
+ return (a<b)?a:b;
+}
+float max_f(float a, float b) {
+ return (b<a)?a:b;
+}
+float clamp_f(float val, float min, float max) {
+ return min_f(max_f(val, min), max);
+}
+
+void rect_copy(int dst[2][2], int src[2][2]) {
+ dst[0][0]= src[0][0], dst[0][1]= src[0][1];
+ dst[1][0]= src[1][0], dst[1][1]= src[1][1];
+}
+int rect_contains_pt(int rect[2][2], int pt[2]){
+ return ((rect[0][0] <= pt[0] && pt[0] <= rect[1][0]) &&
+ (rect[0][1] <= pt[1] && pt[1] <= rect[1][1]));
+}
+int rect_width(int rect[2][2]) {
+ return (rect[1][0]-rect[0][0]);
+}
+int rect_height(int rect[2][2]) {
+ return (rect[1][1]-rect[0][1]);
+}
diff --git a/intern/ghost/test/multitest/Basic.h b/intern/ghost/test/multitest/Basic.h
new file mode 100644
index 00000000000..f81f4684bcc
--- /dev/null
+++ b/intern/ghost/test/multitest/Basic.h
@@ -0,0 +1,44 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+int min_i (int a, int b);
+
+int max_i (int a, int b);
+int clamp_i (int val, int min, int max);
+
+float min_f (float a, float b);
+float max_f (float a, float b);
+float clamp_f (float val, float min, float max);
+
+void rect_copy (int dst[2][2], int src[2][2]);
+int rect_contains_pt (int rect[2][2], int pt[2]);
+int rect_width (int rect[2][2]);
+int rect_height (int rect[2][2]);
diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c
new file mode 100644
index 00000000000..950d80a2468
--- /dev/null
+++ b/intern/ghost/test/multitest/EventToBuf.c
@@ -0,0 +1,236 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "GHOST_C-api.h"
+#include "EventToBuf.h"
+
+char *eventtype_to_string(GHOST_TEventType type) {
+ switch(type) {
+ case GHOST_kEventCursorMove: return "CursorMove";
+ case GHOST_kEventButtonDown: return "ButtonDown";
+ case GHOST_kEventButtonUp: return "ButtonUp";
+
+ case GHOST_kEventKeyDown: return "KeyDown";
+ case GHOST_kEventKeyUp: return "KeyUp";
+
+ case GHOST_kEventQuit: return "Quit";
+
+ case GHOST_kEventWindowClose: return "WindowClose";
+ case GHOST_kEventWindowActivate: return "WindowActivate";
+ case GHOST_kEventWindowDeactivate: return "WindowDeactivate";
+ case GHOST_kEventWindowUpdate: return "WindowUpdate";
+ case GHOST_kEventWindowSize: return "WindowSize";
+ default:
+ return "<invalid>";
+ }
+}
+
+static char *keytype_to_string(GHOST_TKey key) {
+#define K(key) case GHOST_k##key: return #key;
+ switch (key) {
+ K(KeyBackSpace);
+ K(KeyTab);
+ K(KeyLinefeed);
+ K(KeyClear);
+ K(KeyEnter);
+
+ K(KeyEsc);
+ K(KeySpace);
+ K(KeyQuote);
+ K(KeyComma);
+ K(KeyMinus);
+ K(KeyPeriod);
+ K(KeySlash);
+
+ K(Key0);
+ K(Key1);
+ K(Key2);
+ K(Key3);
+ K(Key4);
+ K(Key5);
+ K(Key6);
+ K(Key7);
+ K(Key8);
+ K(Key9);
+
+ K(KeySemicolon);
+ K(KeyEqual);
+
+ K(KeyA);
+ K(KeyB);
+ K(KeyC);
+ K(KeyD);
+ K(KeyE);
+ K(KeyF);
+ K(KeyG);
+ K(KeyH);
+ K(KeyI);
+ K(KeyJ);
+ K(KeyK);
+ K(KeyL);
+ K(KeyM);
+ K(KeyN);
+ K(KeyO);
+ K(KeyP);
+ K(KeyQ);
+ K(KeyR);
+ K(KeyS);
+ K(KeyT);
+ K(KeyU);
+ K(KeyV);
+ K(KeyW);
+ K(KeyX);
+ K(KeyY);
+ K(KeyZ);
+
+ K(KeyLeftBracket);
+ K(KeyRightBracket);
+ K(KeyBackslash);
+ K(KeyAccentGrave);
+
+ K(KeyLeftShift);
+ K(KeyRightShift);
+ K(KeyLeftControl);
+ K(KeyRightControl);
+ K(KeyLeftAlt);
+ K(KeyRightAlt);
+ K(KeyCommand);
+
+ K(KeyCapsLock);
+ K(KeyNumLock);
+ K(KeyScrollLock);
+
+ K(KeyLeftArrow);
+ K(KeyRightArrow);
+ K(KeyUpArrow);
+ K(KeyDownArrow);
+
+ K(KeyPrintScreen);
+ K(KeyPause);
+
+ K(KeyInsert);
+ K(KeyDelete);
+ K(KeyHome);
+ K(KeyEnd);
+ K(KeyUpPage);
+ K(KeyDownPage);
+
+ K(KeyNumpad0);
+ K(KeyNumpad1);
+ K(KeyNumpad2);
+ K(KeyNumpad3);
+ K(KeyNumpad4);
+ K(KeyNumpad5);
+ K(KeyNumpad6);
+ K(KeyNumpad7);
+ K(KeyNumpad8);
+ K(KeyNumpad9);
+ K(KeyNumpadPeriod);
+ K(KeyNumpadEnter);
+ K(KeyNumpadPlus);
+ K(KeyNumpadMinus);
+ K(KeyNumpadAsterisk);
+ K(KeyNumpadSlash);
+
+ K(KeyF1);
+ K(KeyF2);
+ K(KeyF3);
+ K(KeyF4);
+ K(KeyF5);
+ K(KeyF6);
+ K(KeyF7);
+ K(KeyF8);
+ K(KeyF9);
+ K(KeyF10);
+ K(KeyF11);
+ K(KeyF12);
+ K(KeyF13);
+ K(KeyF14);
+ K(KeyF15);
+ K(KeyF16);
+ K(KeyF17);
+ K(KeyF18);
+ K(KeyF19);
+ K(KeyF20);
+ K(KeyF21);
+ K(KeyF22);
+ K(KeyF23);
+ K(KeyF24);
+
+ default:
+ return "KeyUnknown";
+ }
+#undef K
+}
+
+void event_to_buf(GHOST_EventHandle evt, char buf[128]) {
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+ double time= (double) ((GHOST_TInt64) GHOST_GetEventTime(evt))/1000;
+ GHOST_WindowHandle win= GHOST_GetEventWindow(evt);
+ void *data= GHOST_GetEventData(evt);
+ char *pos= buf;
+
+ pos+= sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type));
+ if (win) {
+ char *s= GHOST_GetTitle(win);
+ pos+= sprintf(pos, " - win: %s", s);
+ free(s);
+ } else {
+ pos+= sprintf(pos, " - sys evt");
+ }
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd= data;
+ pos+= sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd= data;
+ pos+= sprintf(pos, " - but: %d", bd->button);
+ break;
+ }
+
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= data;
+ pos+= sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key);
+ if (kd->ascii) pos+= sprintf(pos, " ascii: '%c' (%d)", kd->ascii, kd->ascii);
+ break;
+ }
+ }
+}
diff --git a/intern/ghost/test/multitest/EventToBuf.h b/intern/ghost/test/multitest/EventToBuf.h
new file mode 100644
index 00000000000..be6f37d869b
--- /dev/null
+++ b/intern/ghost/test/multitest/EventToBuf.h
@@ -0,0 +1,35 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+char *eventtype_to_string(GHOST_TEventType type);
+
+void event_to_buf(GHOST_EventHandle evt, char buf[128]);
+
diff --git a/intern/ghost/test/multitest/GL.h b/intern/ghost/test/multitest/GL.h
new file mode 100644
index 00000000000..b395627d1d8
--- /dev/null
+++ b/intern/ghost/test/multitest/GL.h
@@ -0,0 +1,43 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#if defined(WIN32) || defined(__APPLE__)
+
+ #ifdef WIN32
+ #include <windows.h>
+ #include <GL/gl.h>
+ #else // WIN32
+ // __APPLE__ is defined
+ #include <AGL/gl.h>
+ #endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
+ #include <GL/gl.h>
+#endif // defined(WIN32) || defined(__APPLE__)
diff --git a/intern/ghost/test/multitest/Makefile b/intern/ghost/test/multitest/Makefile
new file mode 100644
index 00000000000..a424a397502
--- /dev/null
+++ b/intern/ghost/test/multitest/Makefile
@@ -0,0 +1,60 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+# GHOST gears test application Makefile
+#
+
+DIR = $(OCGDIR)/intern/ghost/test
+
+# we don't want a library here, only object files:
+ALLTARGETS = $(OBJS)
+
+include nan_compile.mk
+include nan_link.mk
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_BMFONT)/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../..
+
+OCGGHOST = $(OCGDIR)/intern/ghost
+
+LIBS = $(OCGGHOST)/$(DEBUG_DIR)libghost.a
+SLIBS += $(LCGDIR)/string/lib/libstring.a
+SLIBS += $(LCGDIR)/bmfont/lib/libbmfont.a
+SLIBS += $(LCGDIR)/guardedalloc/lib/libguardedalloc.a
+
+all::
+ @echo "- link $(DIR)/$(DEBUG_DIR)multitest -"
+ @$(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)multitest $(OBJS) $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
new file mode 100755
index 00000000000..c78d9045022
--- /dev/null
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -0,0 +1,855 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+
+#pragma warning(disable: 4244 4305)
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "GL.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "GHOST_C-api.h"
+#include "BMF_Api.h"
+
+#include "Util.h"
+#include "Basic.h"
+#include "ScrollBar.h"
+#include "EventToBuf.h"
+
+#include "WindowData.h"
+
+/***/
+
+typedef struct _MultiTestApp MultiTestApp;
+typedef struct _LoggerWindow LoggerWindow;
+
+void loggerwindow_log(LoggerWindow *lw, char *line);
+
+void multitestapp_toggle_extra_window(MultiTestApp *app);
+void multitestapp_free_extrawindow(MultiTestApp *app);
+LoggerWindow *multitestapp_get_logger(MultiTestApp *app);
+GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app);
+void multitestapp_exit(MultiTestApp *app);
+
+/**/
+
+void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, float *col, int width) {
+ int ltidx= (side/2)%4;
+ int dkidx= (ltidx + 1 + (side&1))%4;
+ int i, corner;
+
+ glBegin(GL_LINES);
+ for (i=0; i<width; i++) {
+ float ltf= pow(lt[i], 1.0/2.2), dkf= pow(dk[i], 1.0/2.2);
+ float stf= (dkidx>ltidx)?dkf:ltf;
+ int lx= rect[1][0]-i-1;
+ int ly= rect[0][1]+i;
+
+ glColor3f(col[0]*stf, col[1]*stf, col[2]*stf);
+ for (corner=0; corner<4; corner++) {
+ int x= (corner==0 || corner==1)?(rect[0][0]+i):(rect[1][0]-i-1);
+ int y= (corner==0 || corner==3)?(rect[0][1]+i):(rect[1][1]-i-1);
+
+ if (ltidx==corner)
+ glColor3f(col[0]*ltf, col[1]*ltf, col[2]*ltf);
+ if (dkidx==corner)
+ glColor3f(col[0]*dkf, col[1]*dkf, col[2]*dkf);
+
+ glVertex2i(lx, ly);
+ glVertex2i(lx= x, ly= y);
+ }
+ }
+ glEnd();
+
+ glColor3fv(col);
+ glRecti(rect[0][0]+width, rect[0][1]+width, rect[1][0]-width, rect[1][1]-width);
+}
+
+void rect_bevel_smooth(int rect[2][2], int width) {
+ float *lt= malloc(sizeof(*lt)*width);
+ float *dk= malloc(sizeof(*dk)*width);
+ float col[4];
+ int i;
+
+ for (i=0; i<width; i++) {
+ float v= width-1?((float) i/(width-1)):0;
+ lt[i]= 1.2 + (1.0-1.2)*v;
+ dk[i]= 0.2 + (1.0-0.2)*v;
+ }
+
+ glGetFloatv(GL_CURRENT_COLOR, col);
+
+ rect_bevel_side(rect, 3, lt, dk, col, width);
+
+ free(lt);
+ free(dk);
+}
+
+ /*
+ * MainWindow
+ */
+
+typedef struct {
+ MultiTestApp *app;
+
+ GHOST_WindowHandle win;
+
+ int size[2];
+
+ int lmouse[2], lmbut[3];
+
+ int tmouse[2];
+} MainWindow;
+
+static void mainwindow_log(MainWindow *mw, char *str) {
+ loggerwindow_log(multitestapp_get_logger(mw->app), str);
+}
+
+static void mainwindow_do_draw(MainWindow *mw) {
+ GHOST_ActivateWindowDrawingContext(mw->win);
+
+ if (mw->lmbut[0]) {
+ glClearColor(0.5, 0.5, 0.5, 1);
+ } else {
+ glClearColor(1, 1, 1, 1);
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.5, 0.6, 0.8);
+ glRecti(mw->tmouse[0]-5, mw->tmouse[1]-5, mw->tmouse[0]+5, mw->tmouse[1]+5);
+
+ GHOST_SwapWindowBuffers(mw->win);
+}
+
+static void mainwindow_do_reshape(MainWindow *mw) {
+ GHOST_RectangleHandle bounds= GHOST_GetClientBounds(mw->win);
+
+ GHOST_ActivateWindowDrawingContext(mw->win);
+
+ mw->size[0]= GHOST_GetWidthRectangle(bounds);
+ mw->size[1]= GHOST_GetHeightRectangle(bounds);
+
+ glViewport(0, 0, mw->size[0], mw->size[1]);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press) {
+ switch(key) {
+ case GHOST_kKeyC:
+ if (press)
+ GHOST_SetCursorShape(mw->win, (GHOST_TStandardCursor) (rand()%(GHOST_kStandardCursorNumCursors)));
+ break;
+ case GHOST_kKeyLeftBracket:
+ if (press)
+ GHOST_SetCursorVisibility(mw->win, 0);
+ break;
+ case GHOST_kKeyRightBracket:
+ if (press)
+ GHOST_SetCursorVisibility(mw->win, 1);
+ break;
+ case GHOST_kKeyE:
+ if (press)
+ multitestapp_toggle_extra_window(mw->app);
+ break;
+ case GHOST_kKeyQ:
+ if (press)
+ multitestapp_exit(mw->app);
+ break;
+ case GHOST_kKeyT:
+ if (press)
+ mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
+ break;
+ case GHOST_kKeyR:
+ if (press) {
+ int i;
+
+ mainwindow_log(mw, "Invalidating window 10 times");
+ for (i=0; i<10; i++)
+ GHOST_InvalidateWindow(mw->win);
+ }
+ break;
+ case GHOST_kKeyF11:
+ if (press) {
+ GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom);
+ }
+ break;
+ }
+}
+
+static void mainwindow_do_move(MainWindow *mw, int x, int y) {
+ mw->lmouse[0]= x, mw->lmouse[1]= y;
+
+ if (mw->lmbut[0]) {
+ mw->tmouse[0]= x, mw->tmouse[1]= y;
+ GHOST_InvalidateWindow(mw->win);
+ }
+}
+
+static void mainwindow_do_button(MainWindow *mw, int which, int press) {
+ if (which==GHOST_kButtonMaskLeft) {
+ mw->lmbut[0]= press;
+ mw->tmouse[0]= mw->lmouse[0], mw->tmouse[1]= mw->lmouse[1];
+ GHOST_InvalidateWindow(mw->win);
+ } else if (which==GHOST_kButtonMaskLeft) {
+ mw->lmbut[1]= press;
+ } else if (which==GHOST_kButtonMaskLeft) {
+ mw->lmbut[2]= press;
+ }
+}
+
+static void mainwindow_handle(void *priv, GHOST_EventHandle evt) {
+ MainWindow *mw= priv;
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+ char buf[256];
+
+ event_to_buf(evt, buf);
+ mainwindow_log(mw, buf);
+
+ switch (type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd= GHOST_GetEventData(evt);
+ int x, y;
+ GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y);
+ mainwindow_do_move(mw, x, mw->size[1]-y-1);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd= GHOST_GetEventData(evt);
+ mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown));
+ break;
+ }
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
+ mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventWindowUpdate:
+ mainwindow_do_draw(mw);
+ break;
+ case GHOST_kEventWindowSize:
+ mainwindow_do_reshape(mw);
+ break;
+ }
+}
+
+/**/
+
+static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) {
+ MainWindow *mw= GHOST_GetTimerTaskUserData(task);
+ char buf[64];
+
+ sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time)/1000);
+ mainwindow_log(mw, buf);
+}
+
+MainWindow *mainwindow_new(MultiTestApp *app) {
+ GHOST_SystemHandle sys= multitestapp_get_system(app);
+ GHOST_WindowHandle win;
+
+ win= GHOST_CreateWindow(sys, "MultiTest:Main", 40, 40, 400, 400, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL);
+
+ if (win) {
+ MainWindow *mw= MEM_callocN(sizeof(*mw), "mainwindow_new");
+ mw->app= app;
+ mw->win= win;
+
+ GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
+
+ GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
+
+ return mw;
+ } else {
+ return NULL;
+ }
+}
+
+void mainwindow_free(MainWindow *mw) {
+ GHOST_SystemHandle sys= multitestapp_get_system(mw->app);
+
+ windowdata_free(GHOST_GetWindowUserData(mw->win));
+ GHOST_DisposeWindow(sys, mw->win);
+ MEM_freeN(mw);
+}
+
+ /*
+ * LoggerWindow
+ */
+
+struct _LoggerWindow {
+ MultiTestApp *app;
+
+ GHOST_WindowHandle win;
+
+ BMF_Font *font;
+ int fonttexid;
+ int fontheight;
+
+ int size[2];
+
+ int ndisplines;
+ int textarea[2][2];
+ ScrollBar *scroll;
+
+ char **loglines;
+ int nloglines, logsize;
+
+ int lmbut[3];
+ int lmouse[2];
+};
+
+#define SCROLLBAR_PAD 2
+#define SCROLLBAR_WIDTH 14
+#define TEXTAREA_PAD 2
+static void loggerwindow_recalc_regions(LoggerWindow *lw) {
+ int nscroll[2][2];
+
+ nscroll[0][0]= SCROLLBAR_PAD;
+ nscroll[0][1]= SCROLLBAR_PAD;
+ nscroll[1][0]= nscroll[0][0] + SCROLLBAR_WIDTH;
+ nscroll[1][1]= lw->size[1] - SCROLLBAR_PAD - 1;
+
+ lw->textarea[0][0]= nscroll[1][0] + TEXTAREA_PAD;
+ lw->textarea[0][1]= TEXTAREA_PAD;
+ lw->textarea[1][0]= lw->size[0] - TEXTAREA_PAD - 1;
+ lw->textarea[1][1]= lw->size[1] - TEXTAREA_PAD - 1;
+
+ lw->ndisplines= (lw->textarea[1][1]-lw->textarea[0][1])/lw->fontheight;
+
+ scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines);
+ scrollbar_set_rect(lw->scroll, nscroll);
+}
+
+static void loggerwindow_setup_window_gl(LoggerWindow *lw) {
+ glViewport(0, 0, lw->size[0], lw->size[1]);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+static void loggerwindow_do_reshape(LoggerWindow *lw) {
+ GHOST_RectangleHandle bounds= GHOST_GetClientBounds(lw->win);
+
+ GHOST_ActivateWindowDrawingContext(lw->win);
+
+ lw->size[0]= GHOST_GetWidthRectangle(bounds);
+ lw->size[1]= GHOST_GetHeightRectangle(bounds);
+
+ loggerwindow_recalc_regions(lw);
+ loggerwindow_setup_window_gl(lw);
+}
+
+static void loggerwindow_do_draw(LoggerWindow *lw) {
+ int i, ndisplines, startline;
+ int sb_rect[2][2], sb_thumb[2][2];
+
+ GHOST_ActivateWindowDrawingContext(lw->win);
+
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.8, 0.8, 0.8);
+ rect_bevel_smooth(lw->textarea, 4);
+
+ scrollbar_get_rect(lw->scroll, sb_rect);
+ scrollbar_get_thumb(lw->scroll, sb_thumb);
+
+ glColor3f(0.6, 0.6, 0.6);
+ rect_bevel_smooth(sb_rect, 1);
+
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ glColor3f(0.6, 0.7, 0.5);
+ } else {
+ glColor3f(0.9, 0.9, 0.92);
+ }
+ rect_bevel_smooth(sb_thumb, 1);
+
+ startline= scrollbar_get_thumbpos(lw->scroll)*(lw->nloglines-1);
+ ndisplines= min_i(lw->ndisplines, lw->nloglines-startline);
+
+ if (lw->fonttexid!=-1) {
+ glBindTexture(GL_TEXTURE_2D, lw->fonttexid);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ }
+ glColor3f(0, 0, 0);
+ for (i=0; i<ndisplines; i++) {
+ /* stored in reverse order */
+ char *line= lw->loglines[(lw->nloglines-1)-(i+startline)];
+ int x_pos= lw->textarea[0][0] + 4;
+ int y_pos= lw->textarea[0][1] + 4 + i*lw->fontheight;
+
+ if (lw->fonttexid==-1) {
+ glRasterPos2i(x_pos, y_pos);
+ BMF_DrawString(lw->font, line);
+ } else {
+ BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0);
+ }
+ }
+ if (lw->fonttexid!=-1) {
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ }
+
+ GHOST_SwapWindowBuffers(lw->win);
+}
+
+static void loggerwindow_do_move(LoggerWindow *lw, int x, int y) {
+ lw->lmouse[0]= x, lw->lmouse[1]= y;
+
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ scrollbar_keep_scrolling(lw->scroll, y);
+ GHOST_InvalidateWindow(lw->win);
+ }
+}
+
+static void loggerwindow_do_button(LoggerWindow *lw, int which, int press) {
+ if (which==GHOST_kButtonMaskLeft) {
+ lw->lmbut[0]= press;
+
+ if (press) {
+ if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
+ scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
+ GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
+ GHOST_InvalidateWindow(lw->win);
+ }
+ } else {
+ if (scrollbar_is_scrolling(lw->scroll)) {
+ scrollbar_stop_scrolling(lw->scroll);
+ GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault);
+ GHOST_InvalidateWindow(lw->win);
+ }
+ }
+ } else if (which==GHOST_kButtonMaskMiddle) {
+ lw->lmbut[1]= press;
+ } else if (which==GHOST_kButtonMaskRight) {
+ lw->lmbut[2]= press;
+ }
+}
+
+static void loggerwindow_do_key(LoggerWindow *lw, GHOST_TKey key, int press) {
+ switch (key) {
+ case GHOST_kKeyQ:
+ if (press)
+ multitestapp_exit(lw->app);
+ break;
+ }
+}
+
+static void loggerwindow_handle(void *priv, GHOST_EventHandle evt) {
+ LoggerWindow *lw= priv;
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+
+ switch(type) {
+ case GHOST_kEventCursorMove: {
+ GHOST_TEventCursorData *cd= GHOST_GetEventData(evt);
+ int x, y;
+ GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y);
+ loggerwindow_do_move(lw, x, lw->size[1]-y-1);
+ break;
+ }
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp: {
+ GHOST_TEventButtonData *bd= GHOST_GetEventData(evt);
+ loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown));
+ break;
+ }
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
+ loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventWindowUpdate:
+ loggerwindow_do_draw(lw);
+ break;
+ case GHOST_kEventWindowSize:
+ loggerwindow_do_reshape(lw);
+ break;
+ }
+}
+
+/**/
+
+LoggerWindow *loggerwindow_new(MultiTestApp *app) {
+ GHOST_SystemHandle sys= multitestapp_get_system(app);
+ GHOST_TUns32 screensize[2];
+ GHOST_WindowHandle win;
+
+ GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
+ win= GHOST_CreateWindow(sys, "MultiTest:Logger", 40, screensize[1]-432, 800, 300, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL);
+
+ if (win) {
+ LoggerWindow *lw= MEM_callocN(sizeof(*lw), "loggerwindow_new");
+ int bbox[2][2];
+ lw->app= app;
+ lw->win= win;
+
+ lw->font= BMF_GetFont(BMF_kScreen12);
+ lw->fonttexid= BMF_GetFontTexture(lw->font);
+
+ BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]);
+ lw->fontheight= rect_height(bbox);
+
+ lw->nloglines= lw->logsize= 0;
+ lw->loglines= MEM_mallocN(sizeof(*lw->loglines)*lw->nloglines, "loglines");
+
+ lw->scroll= scrollbar_new(2, 40);
+
+ GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));
+
+ loggerwindow_do_reshape(lw);
+
+ return lw;
+ } else {
+ return NULL;
+ }
+}
+
+void loggerwindow_log(LoggerWindow *lw, char *line) {
+ if (lw->nloglines==lw->logsize) {
+ lw->loglines= memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
+ }
+
+ lw->loglines[lw->nloglines++]= string_dup(line);
+ scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines);
+
+ GHOST_InvalidateWindow(lw->win);
+}
+
+void loggerwindow_free(LoggerWindow *lw) {
+ GHOST_SystemHandle sys= multitestapp_get_system(lw->app);
+ int i;
+
+ for (i=0; i<lw->nloglines; i++) {
+ MEM_freeN(lw->loglines[i]);
+ }
+ MEM_freeN(lw->loglines);
+
+ windowdata_free(GHOST_GetWindowUserData(lw->win));
+ GHOST_DisposeWindow(sys, lw->win);
+ MEM_freeN(lw);
+}
+
+ /*
+ * ExtraWindow
+ */
+
+
+typedef struct {
+ MultiTestApp *app;
+
+ GHOST_WindowHandle win;
+
+ int size[2];
+} ExtraWindow;
+
+static void extrawindow_do_draw(ExtraWindow *ew) {
+ GHOST_ActivateWindowDrawingContext(ew->win);
+
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.8, 0.8, 0.8);
+ glRecti(10, 10, ew->size[0]-10, ew->size[1]-10);
+
+ GHOST_SwapWindowBuffers(ew->win);
+}
+
+static void extrawindow_do_reshape(ExtraWindow *ew) {
+ GHOST_RectangleHandle bounds= GHOST_GetClientBounds(ew->win);
+
+ GHOST_ActivateWindowDrawingContext(ew->win);
+
+ ew->size[0]= GHOST_GetWidthRectangle(bounds);
+ ew->size[1]= GHOST_GetHeightRectangle(bounds);
+
+ glViewport(0, 0, ew->size[0], ew->size[1]);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1);
+ glTranslatef(0.375, 0.375, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press) {
+ switch (key) {
+ case GHOST_kKeyE:
+ if (press)
+ multitestapp_toggle_extra_window(ew->app);
+ break;
+ }
+}
+
+static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time) {
+ GHOST_TUns8 bitmap[16][2];
+ GHOST_TUns8 mask[16][2];
+ double ftime= (double) ((GHOST_TInt64) time)/1000;
+ float angle= fmod(ftime, 1.0) * 3.1415*2;
+ int i;
+
+ memset(&bitmap, 0, sizeof(bitmap));
+ memset(&mask, 0, sizeof(mask));
+
+ bitmap[0][0] |= mask[0][0] |= 0xF;
+ bitmap[1][0] |= mask[1][0] |= 0xF;
+ bitmap[2][0] |= mask[2][0] |= 0xF;
+ bitmap[3][0] |= mask[3][0] |= 0xF;
+
+ for (i=0; i<7; i++) {
+ int x = 7 + cos(angle)*i;
+ int y = 7 + sin(angle)*i;
+
+ mask[y][x/8] |= (1 << (x%8));
+ }
+ for (i=0; i<64; i++) {
+ float v= (i/63.0) * 3.1415*2;
+ int x = 7 + cos(v)*7;
+ int y = 7 + sin(v)*7;
+
+ mask[y][x/8] |= (1 << (x%8));
+ }
+
+ GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0);
+}
+
+static void extrawindow_handle(void *priv, GHOST_EventHandle evt) {
+ ExtraWindow *ew= priv;
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+ char buf[256];
+
+ event_to_buf(evt, buf);
+ loggerwindow_log(multitestapp_get_logger(ew->app), buf);
+
+ switch (type) {
+ case GHOST_kEventKeyDown:
+ case GHOST_kEventKeyUp: {
+ GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
+ extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown));
+ break;
+ }
+
+ case GHOST_kEventCursorMove: {
+ extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt));
+ break;
+ }
+
+ case GHOST_kEventWindowClose:
+ multitestapp_free_extrawindow(ew->app);
+ break;
+ case GHOST_kEventWindowUpdate:
+ extrawindow_do_draw(ew);
+ break;
+ case GHOST_kEventWindowSize:
+ extrawindow_do_reshape(ew);
+ break;
+ }
+}
+
+/**/
+
+ExtraWindow *extrawindow_new(MultiTestApp *app) {
+ GHOST_SystemHandle sys= multitestapp_get_system(app);
+ GHOST_WindowHandle win;
+
+ win= GHOST_CreateWindow(sys, "MultiTest:Extra", 500, 40, 400, 400, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL);
+
+ if (win) {
+ ExtraWindow *ew= MEM_callocN(sizeof(*ew), "mainwindow_new");
+ ew->app= app;
+ ew->win= win;
+
+ GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
+
+ return ew;
+ } else {
+ return NULL;
+ }
+}
+
+void extrawindow_free(ExtraWindow *ew) {
+ GHOST_SystemHandle sys= multitestapp_get_system(ew->app);
+
+ windowdata_free(GHOST_GetWindowUserData(ew->win));
+ GHOST_DisposeWindow(sys, ew->win);
+ MEM_freeN(ew);
+}
+
+ /*
+ * MultiTestApp
+ */
+
+struct _MultiTestApp {
+ GHOST_SystemHandle sys;
+ MainWindow *main;
+ LoggerWindow *logger;
+ ExtraWindow *extra;
+
+ int exit;
+};
+
+static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data) {
+ MultiTestApp *app= data;
+ GHOST_WindowHandle win;
+
+ win= GHOST_GetEventWindow(evt);
+ if (win && !GHOST_ValidWindow(app->sys, win)) {
+ loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
+ return 1;
+ }
+
+ if (win) {
+ WindowData *wb= GHOST_GetWindowUserData(win);
+
+ windowdata_handle(wb, evt);
+ } else {
+ GHOST_TEventType type= GHOST_GetEventType(evt);
+
+ /* GHOST_kEventQuit are the only 'system' events,
+ * that is, events without a window.
+ */
+ switch(type) {
+ case GHOST_kEventQuit:
+ app->exit= 1;
+ break;
+
+ default:
+ fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type));
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/**/
+
+MultiTestApp *multitestapp_new(void) {
+ MultiTestApp *app= MEM_mallocN(sizeof(*app), "multitestapp_new");
+ GHOST_EventConsumerHandle consumer= GHOST_CreateEventConsumer(multitest_event_handler, app);
+
+ app->sys= GHOST_CreateSystem();
+ if (!app->sys)
+ fatal("Unable to create ghost system");
+
+ if (!GHOST_AddEventConsumer(app->sys, consumer))
+ fatal("Unable to add multitest event consumer ");
+
+ app->main= mainwindow_new(app);
+ if (!app->main)
+ fatal("Unable to create main window");
+
+ app->logger= loggerwindow_new(app);
+ if (!app->logger)
+ fatal("Unable to create logger window");
+
+ app->extra= NULL;
+ app->exit= 0;
+
+ return app;
+}
+
+LoggerWindow *multitestapp_get_logger(MultiTestApp *app) {
+ return app->logger;
+}
+
+GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) {
+ return app->sys;
+}
+
+void multitestapp_free_extrawindow(MultiTestApp *app) {
+ extrawindow_free(app->extra);
+ app->extra= NULL;
+}
+
+void multitestapp_toggle_extra_window(MultiTestApp *app) {
+ if (app->extra) {
+ multitestapp_free_extrawindow(app);
+ } else {
+ app->extra= extrawindow_new(app);
+ }
+}
+
+void multitestapp_exit(MultiTestApp *app) {
+ app->exit= 1;
+}
+
+void multitestapp_run(MultiTestApp *app) {
+ while (!app->exit) {
+ GHOST_ProcessEvents(app->sys, 1);
+ GHOST_DispatchEvents(app->sys);
+ }
+}
+
+void multitestapp_free(MultiTestApp *app) {
+ mainwindow_free(app->main);
+ loggerwindow_free(app->logger);
+ GHOST_DisposeSystem(app->sys);
+ MEM_freeN(app);
+}
+
+ /***/
+
+int main(int argc, char **argv) {
+ MultiTestApp *app= multitestapp_new();
+
+ multitestapp_run(app);
+ multitestapp_free(app);
+
+ return 0;
+}
diff --git a/intern/ghost/test/multitest/ScrollBar.c b/intern/ghost/test/multitest/ScrollBar.c
new file mode 100644
index 00000000000..cd690f6f14e
--- /dev/null
+++ b/intern/ghost/test/multitest/ScrollBar.c
@@ -0,0 +1,145 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "Basic.h"
+#include "ScrollBar.h"
+
+struct _ScrollBar {
+ int rect[2][2];
+ float thumbpos, thumbpct;
+
+ int inset;
+ int minthumb;
+
+ int scrolling;
+ float scrolloffs;
+};
+
+static int scrollbar_get_thumbH(ScrollBar *sb) {
+ int scrollable_h= rect_height(sb->rect) - 2*sb->inset;
+
+ return clamp_i(sb->thumbpct*scrollable_h, sb->minthumb, scrollable_h);
+}
+static int scrollbar_get_thumbableH(ScrollBar *sb) {
+ int scrollable_h= rect_height(sb->rect) - 2*sb->inset;
+ int thumb_h= scrollbar_get_thumbH(sb);
+
+ return scrollable_h - thumb_h;
+}
+
+static float scrollbar_co_to_pos(ScrollBar *sb, int yco) {
+ int thumb_h= scrollbar_get_thumbH(sb);
+ int thumbable_h= scrollbar_get_thumbableH(sb);
+ int thumbable_y= (sb->rect[0][1]+sb->inset) + thumb_h/2;
+
+ return (float) (yco-thumbable_y)/thumbable_h;
+}
+
+/**/
+
+ScrollBar *scrollbar_new(int inset, int minthumb) {
+ ScrollBar *sb= MEM_callocN(sizeof(*sb), "scrollbar_new");
+ sb->inset= inset;
+ sb->minthumb= minthumb;
+
+ return sb;
+}
+
+void scrollbar_get_thumb(ScrollBar *sb, int thumb_r[2][2]) {
+ int thumb_h= scrollbar_get_thumbH(sb);
+ int thumbable_h= scrollbar_get_thumbableH(sb);
+
+ thumb_r[0][0]= sb->rect[0][0]+sb->inset;
+ thumb_r[1][0]= sb->rect[1][0]-sb->inset;
+
+ thumb_r[0][1]= sb->rect[0][1]+sb->inset + sb->thumbpos*thumbable_h;
+ thumb_r[1][1]= thumb_r[0][1] + thumb_h;
+}
+
+int scrollbar_is_scrolling(ScrollBar *sb) {
+ return sb->scrolling;
+}
+int scrollbar_contains_pt(ScrollBar *sb, int pt[2]) {
+ return rect_contains_pt(sb->rect, pt);
+}
+
+void scrollbar_start_scrolling(ScrollBar *sb, int yco) {
+ int thumb_h_2= scrollbar_get_thumbH(sb)/2;
+ int thumbable_h= scrollbar_get_thumbableH(sb);
+ float npos= scrollbar_co_to_pos(sb, yco);
+
+ sb->scrolloffs= sb->thumbpos - npos;
+ if (fabs(sb->scrolloffs) >= (float) thumb_h_2/thumbable_h) {
+ sb->scrolloffs= 0.0;
+ }
+
+ sb->scrolling= 1;
+ sb->thumbpos= clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
+}
+void scrollbar_keep_scrolling(ScrollBar *sb, int yco) {
+ float npos= scrollbar_co_to_pos(sb, yco);
+
+ sb->thumbpos= clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
+}
+void scrollbar_stop_scrolling(ScrollBar *sb) {
+ sb->scrolling= 0;
+ sb->scrolloffs= 0.0;
+}
+
+void scrollbar_set_thumbpct(ScrollBar *sb, float pct) {
+ sb->thumbpct= pct;
+}
+void scrollbar_set_thumbpos(ScrollBar *sb, float pos) {
+ sb->thumbpos= clamp_f(pos, 0.0, 1.0);
+}
+void scrollbar_set_rect(ScrollBar *sb, int rect[2][2]) {
+ rect_copy(sb->rect, rect);
+}
+
+float scrollbar_get_thumbpct(ScrollBar *sb) {
+ return sb->thumbpct;
+}
+float scrollbar_get_thumbpos(ScrollBar *sb) {
+ return sb->thumbpos;
+}
+void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2]) {
+ rect_copy(rect_r, sb->rect);
+}
+
+void scrollbar_free(ScrollBar *sb) {
+ MEM_freeN(sb);
+}
diff --git a/intern/ghost/test/multitest/ScrollBar.h b/intern/ghost/test/multitest/ScrollBar.h
new file mode 100644
index 00000000000..30e49e8b531
--- /dev/null
+++ b/intern/ghost/test/multitest/ScrollBar.h
@@ -0,0 +1,56 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+typedef struct _ScrollBar ScrollBar;
+
+
+ /***/
+
+ScrollBar* scrollbar_new (int inset, int minthumb);
+
+int scrollbar_is_scrolling (ScrollBar *sb);
+int scrollbar_contains_pt (ScrollBar *sb, int pt[2]);
+
+void scrollbar_start_scrolling (ScrollBar *sb, int yco);
+void scrollbar_keep_scrolling (ScrollBar *sb, int yco);
+void scrollbar_stop_scrolling (ScrollBar *sb);
+
+void scrollbar_set_thumbpct (ScrollBar *sb, float pct);
+void scrollbar_set_thumbpos (ScrollBar *sb, float pos);
+void scrollbar_set_rect (ScrollBar *sb, int rect[2][2]);
+
+float scrollbar_get_thumbpct (ScrollBar *sb);
+float scrollbar_get_thumbpos (ScrollBar *sb);
+void scrollbar_get_rect (ScrollBar *sb, int rect_r[2][2]);
+
+void scrollbar_get_thumb (ScrollBar *sb, int thumb_r[2][2]);
+
+void scrollbar_free (ScrollBar *sb);
diff --git a/intern/ghost/test/multitest/Util.c b/intern/ghost/test/multitest/Util.c
new file mode 100644
index 00000000000..31e43f6f5da
--- /dev/null
+++ b/intern/ghost/test/multitest/Util.c
@@ -0,0 +1,73 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "Util.h"
+
+void* memdbl(void *mem, int *size_pr, int item_size) {
+ int cur_size= *size_pr;
+ int new_size= cur_size?(cur_size*2):1;
+ void *nmem= MEM_mallocN(new_size*item_size, "memdbl");
+
+ memcpy(nmem, mem, cur_size*item_size);
+ MEM_freeN(mem);
+
+ *size_pr= new_size;
+ return nmem;
+}
+
+char* string_dup(char *str) {
+ int len= strlen(str);
+ char *nstr= MEM_mallocN(len + 1, "string_dup");
+
+ memcpy(nstr, str, len+1);
+
+ return nstr;
+}
+
+void fatal(char *fmt, ...) {
+ va_list ap;
+
+ fprintf(stderr, "FATAL: ");
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+
+ exit(1);
+}
diff --git a/intern/ghost/test/multitest/Util.h b/intern/ghost/test/multitest/Util.h
new file mode 100644
index 00000000000..1146112c9c4
--- /dev/null
+++ b/intern/ghost/test/multitest/Util.h
@@ -0,0 +1,35 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+void* memdbl (void *mem, int *size_pr, int item_size);
+
+char* string_dup (char *str);
+void fatal (char *fmt, ...);
diff --git a/intern/ghost/test/multitest/WindowData.c b/intern/ghost/test/multitest/WindowData.c
new file mode 100644
index 00000000000..ee377c98b58
--- /dev/null
+++ b/intern/ghost/test/multitest/WindowData.c
@@ -0,0 +1,60 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+
+#include "MEM_guardedalloc.h"
+
+#include "GHOST_C-api.h"
+
+#include "WindowData.h"
+
+struct _WindowData {
+ void *data;
+ WindowDataHandler handler;
+};
+
+WindowData *windowdata_new(void *data, WindowDataHandler handler) {
+ WindowData *wb= MEM_mallocN(sizeof(*wb), "windowdata_new");
+ wb->data= data;
+ wb->handler= handler;
+
+ return wb;
+}
+
+void windowdata_handle(WindowData *wb, GHOST_EventHandle evt) {
+ wb->handler(wb->data, evt);
+}
+
+void windowdata_free(WindowData *wb) {
+ MEM_freeN(wb);
+}
diff --git a/intern/ghost/test/multitest/WindowData.h b/intern/ghost/test/multitest/WindowData.h
new file mode 100644
index 00000000000..a046c41d90c
--- /dev/null
+++ b/intern/ghost/test/multitest/WindowData.h
@@ -0,0 +1,40 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+typedef void (*WindowDataHandler)(void *priv, GHOST_EventHandle evt);
+
+typedef struct _WindowData WindowData;
+
+ /***/
+
+WindowData* windowdata_new (void *data, WindowDataHandler handler);
+void windowdata_handle (WindowData *wb, GHOST_EventHandle evt);
+void windowdata_free (WindowData *wb);