Fix a few conversion bugs. For example, GLshort->GLfloat conversion
[mesa.git] / src / glut / dos / window.c
index c110715ebb38944c427ce7fe91cbeb47fae5f57c..610cf36dcc677b85ec019f12043f306e16855cc3 100644 (file)
-/*\r
- * Mesa 3-D graphics library\r
- * Version:  4.0\r
- * Copyright (C) 1995-1998  Brian Paul\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Library General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Library General Public\r
- * License along with this library; if not, write to the Free\r
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- */\r
-\r
-/*\r
- * DOS/DJGPP glut driver v0.2 for Mesa 4.0\r
- *\r
- *  Copyright (C) 2002 - Borca Daniel\r
- *  Email : dborca@yahoo.com\r
- *  Web   : http://www.geocities.com/dborca\r
- */\r
-\r
-\r
-#include "GL/glut.h"\r
-#include "GL/dmesa.h"\r
-#include "internal.h"\r
-\r
-\r
-\r
-static int window;\r
-\r
-static DMesaVisual  visual  = NULL;\r
-static DMesaContext context = NULL;\r
-static DMesaBuffer  buffer[MAX_WINDOWS];\r
-\r
-\r
-\r
-static void clean (void)\r
-{\r
- int i;\r
-\r
- for (i=0; i<MAX_WINDOWS; i++) {\r
-     glutDestroyWindow(i+1);\r
- }\r
- if (context) DMesaDestroyContext(context);\r
- if (visual)  DMesaDestroyVisual(visual);\r
-\r
- pc_close_stdout();\r
- pc_close_stderr();\r
-}\r
-\r
-\r
-\r
-int APIENTRY glutCreateWindow (const char *title)\r
-{\r
- int i;\r
-\r
- if (!visual) {\r
-    int screen_w = DEFAULT_WIDTH;\r
-    int screen_h = DEFAULT_HEIGHT;\r
-\r
-    if ((g_width<=640) && (g_height<=480)) {\r
-       screen_w = 640;\r
-       screen_h = 480;\r
-    } else if ((g_width<=800) && (g_height<=600)) {\r
-       screen_w = 800;\r
-       screen_h = 600;\r
-    } else if ((g_width<=1024) && (g_height<=768)) {\r
-       screen_w = 1024;\r
-       screen_h = 768;\r
-    }\r
-\r
-    if ((visual=DMesaCreateVisual(screen_w, screen_h, DEFAULT_BPP,\r
-                                  g_display_mode & GLUT_DOUBLE,\r
-                                  g_display_mode & GLUT_DEPTH  ?DEPTH_SIZE  :0,\r
-                                  g_display_mode & GLUT_STENCIL?STENCIL_SIZE:0,\r
-                                  g_display_mode & GLUT_ACCUM  ?ACCUM_SIZE  :0))==NULL) {\r
-       return 0;\r
-    }\r
-   \r
-    if ((context=DMesaCreateContext(visual, NULL))==NULL) {\r
-       DMesaDestroyVisual(visual);\r
-       return 0;\r
-    }\r
-    \r
-    pc_open_stdout();\r
-    pc_open_stderr();\r
-    pc_atexit(clean);\r
- }\r
-\r
- for (i=0; i<MAX_WINDOWS; i++) {\r
-     if (!buffer[i]) {\r
-        DMesaBuffer b;\r
-     \r
-        if ((b=DMesaCreateBuffer(visual, g_xpos, g_ypos, g_width, g_height))==NULL) {\r
-           return 0;\r
-        }\r
-        if (!DMesaMakeCurrent(context, b)) {\r
-           DMesaDestroyBuffer(b);\r
-           return 0;\r
-        }\r
-        if (g_mouse) {\r
-           pc_mouse_area(g_xpos, g_ypos, g_xpos + g_width - 1, g_ypos + g_height - 1);\r
-        }\r
-\r
-        buffer[window = i] = b;\r
-        return i+1;\r
-     }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-\r
-int APIENTRY glutCreateSubWindow (int win, int x, int y, int width, int height)\r
-{\r
- return GL_FALSE;\r
-}\r
-\r
-\r
-void APIENTRY glutDestroyWindow (int win)\r
-{\r
- if (buffer[win-1]) {\r
-    DMesaDestroyBuffer(buffer[win-1]);\r
-    buffer[win-1] = NULL;\r
- }\r
-}\r
-\r
-\r
-void APIENTRY glutPostRedisplay (void)\r
-{\r
- g_redisplay = GL_TRUE;\r
-}\r
-\r
-\r
-void APIENTRY glutSwapBuffers (void)\r
-{\r
- if (g_mouse) pc_scare_mouse();\r
- DMesaSwapBuffers(buffer[window]);\r
- if (g_mouse) pc_unscare_mouse();\r
-}\r
-\r
-\r
-int APIENTRY glutGetWindow (void)\r
-{\r
- return window + 1;\r
-}\r
-\r
-\r
-void APIENTRY glutSetWindow (int win)\r
-{\r
- window = win - 1;\r
-}\r
-\r
-\r
-void APIENTRY glutSetWindowTitle (const char *title)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutSetIconTitle (const char *title)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutPositionWindow (int x, int y)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutReshapeWindow (int width, int height)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutPopWindow (void)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutPushWindow (void)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutIconifyWindow (void)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutShowWindow (void)\r
-{\r
-}\r
-\r
-\r
-void APIENTRY glutHideWindow (void)\r
-{\r
-}\r
+/*
+ * DOS/DJGPP Mesa Utility Toolkit
+ * Version:  1.0
+ *
+ * Copyright (C) 2005  Daniel Borca   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * DANIEL BORCA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdio.h>
+
+#include "internal.h"
+
+
+static GLuint swaptime, swapcount;
+
+static DMesaVisual visual = NULL;
+
+GLUTwindow *_glut_current, *_glut_windows[MAX_WINDOWS];
+
+
+static void
+clean (void)
+{
+   int i;
+
+   for (i=1; i<=MAX_WINDOWS; i++) {
+      glutDestroyWindow(i);
+   }
+   if (visual) DMesaDestroyVisual(visual);
+
+   pc_close_stdout();
+   pc_close_stderr();
+}
+
+
+static GLUTwindow *
+_glut_window (int win)
+{
+   if (win > 0 && --win < MAX_WINDOWS) {
+      return _glut_windows[win];
+   }
+   return NULL;
+}
+
+
+int APIENTRY
+glutCreateWindow (const char *title)
+{
+   int i;
+   int m8width = (_glut_default.width + 7) & ~7;
+
+   if (!(_glut_default.mode & GLUT_DOUBLE)) {
+      return 0;
+   }
+    
+   /* We set the Visual once. This will be our desktop (graphic mode).
+    * We should do this in the `glutInit' code, but we don't have any idea
+    * about its geometry. Supposedly, when we are about to create one
+    * window, we have a slight idea about resolution.
+    */
+   if (!visual) {
+      if ((visual=DMesaCreateVisual(_glut_default.x + m8width, _glut_default.y + _glut_default.height, _glut_visual.bpp, _glut_visual.refresh,
+                                    GLUT_SINGLE,
+                                    !(_glut_default.mode & GLUT_INDEX),
+                                    (_glut_default.mode & GLUT_ALPHA  ) ? _glut_visual.alpha   : 0,
+                                    (_glut_default.mode & GLUT_DEPTH  ) ? _glut_visual.depth   : 0,
+                                    (_glut_default.mode & GLUT_STENCIL) ? _glut_visual.stencil : 0,
+                                    (_glut_default.mode & GLUT_ACCUM  ) ? _glut_visual.accum   : 0))==NULL) {
+         return 0;
+      }
+
+      DMesaGetIntegerv(DMESA_GET_SCREEN_SIZE, _glut_visual.geometry);
+      DMesaGetIntegerv(DMESA_GET_DRIVER_CAPS, &_glut_visual.flags);
+
+      /* Also hook stdio/stderr once */
+      pc_open_stdout();
+      pc_open_stderr();
+      pc_atexit(clean);
+   }
+
+   /* Search for an empty slot.
+    * Each window has its own rendering Context and its own Buffer.
+    */
+   for (i=0; i<MAX_WINDOWS; i++) {
+      if (_glut_windows[i] == NULL) {
+         DMesaContext c;
+         DMesaBuffer b;
+         GLUTwindow *w;
+
+         if ((w = (GLUTwindow *)calloc(1, sizeof(GLUTwindow))) == NULL) {
+            return 0;
+         }
+
+         /* Allocate the rendering Context. */
+         if ((c = DMesaCreateContext(visual, NULL)) == NULL) {
+            free(w);
+            return 0;
+         }
+
+         /* Allocate the Buffer (displayable area).
+          * We have to specify buffer size and position (inside the desktop).
+          */
+         if ((b = DMesaCreateBuffer(visual, _glut_default.x, _glut_default.y, m8width, _glut_default.height)) == NULL) {
+            DMesaDestroyContext(c);
+            free(w);
+            return 0;
+         }
+
+         /* Bind Buffer to Context and make the Context the current one. */
+         if (!DMesaMakeCurrent(c, b)) {
+            DMesaDestroyBuffer(b);
+            DMesaDestroyContext(c);
+            free(w);
+            return 0;
+         }
+
+         _glut_current = _glut_windows[i] = w;
+
+         w->num = ++i;
+         w->xpos = _glut_default.x;
+         w->ypos = _glut_default.y;
+         w->width = m8width;
+         w->height = _glut_default.height;
+         w->context = c;
+         w->buffer = b;
+
+         return i;
+      }
+   }
+
+   return 0;
+}
+
+
+int APIENTRY
+glutCreateSubWindow (int win, int x, int y, int width, int height)
+{
+   return GL_FALSE;
+}
+
+
+void APIENTRY
+glutDestroyWindow (int win)
+{
+   GLUTwindow *w = _glut_window(win);
+   if (w != NULL) {
+      if (w->destroy) {
+         w->destroy();
+      }
+      DMesaMakeCurrent(NULL, NULL);
+      DMesaDestroyBuffer(w->buffer);
+      DMesaDestroyContext(w->context);
+      free(w);
+      _glut_windows[win - 1] = NULL;
+   }
+}
+
+
+void APIENTRY
+glutPostRedisplay (void)
+{
+   _glut_current->redisplay = GL_TRUE;
+}
+
+
+void APIENTRY
+glutSwapBuffers (void)
+{
+   if (_glut_current->show_mouse) {
+      /* XXX scare mouse */
+      DMesaSwapBuffers(_glut_current->buffer);
+      /* XXX unscare mouse */
+   } else {
+      DMesaSwapBuffers(_glut_current->buffer);
+   }
+
+   if (_glut_fps) {
+      GLint t = glutGet(GLUT_ELAPSED_TIME);
+      swapcount++;
+      if (swaptime == 0)
+         swaptime = t;
+      else if (t - swaptime > _glut_fps) {
+         double time = 0.001 * (t - swaptime);
+         double fps = (double)swapcount / time;
+         fprintf(stderr, "GLUT: %d frames in %.2f seconds = %.2f FPS\n", swapcount, time, fps);
+         swaptime = t;
+         swapcount = 0;
+      }
+   }
+}
+
+
+int APIENTRY
+glutGetWindow (void)
+{
+   return _glut_current->num;
+}
+
+
+void APIENTRY
+glutSetWindow (int win)
+{
+   GLUTwindow *w = _glut_window(win);
+   if (w != NULL) {
+      _glut_current = w;
+      DMesaMakeCurrent(_glut_current->context, _glut_current->buffer);
+   }
+}
+
+
+void APIENTRY
+glutSetWindowTitle (const char *title)
+{
+}
+
+
+void APIENTRY
+glutSetIconTitle (const char *title)
+{
+}
+
+
+void APIENTRY
+glutPositionWindow (int x, int y)
+{
+   if (DMesaMoveBuffer(x, y)) {
+      _glut_current->xpos = x;
+      _glut_current->ypos = y;
+   }
+}
+
+
+void APIENTRY
+glutReshapeWindow (int width, int height)
+{ 
+   if (DMesaResizeBuffer(width, height)) {
+      _glut_current->width = width;
+      _glut_current->height = height;
+      if (_glut_current->reshape) {
+         _glut_current->reshape(width, height);
+      } else {
+         glViewport(0, 0, width, height);
+      }
+   }
+}
+
+
+void APIENTRY
+glutFullScreen (void)
+{
+}
+
+
+void APIENTRY
+glutPopWindow (void)
+{
+}
+
+
+void APIENTRY
+glutPushWindow (void)
+{
+}
+
+
+void APIENTRY
+glutIconifyWindow (void)
+{
+}
+
+
+void APIENTRY
+glutShowWindow (void)
+{
+}
+
+
+void APIENTRY
+glutHideWindow (void)
+{
+}
+
+
+void APIENTRY
+glutCloseFunc (GLUTdestroyCB destroy)
+{
+   _glut_current->destroy = destroy;
+}
+
+
+void APIENTRY
+glutPostWindowRedisplay (int win)
+{
+   GLUTwindow *w = _glut_window(win);
+   if (w != NULL) {
+      w->redisplay = GL_TRUE;
+   }
+}
+
+
+void * APIENTRY
+glutGetWindowData (void)
+{
+   return _glut_current->data;
+}
+
+
+void APIENTRY
+glutSetWindowData (void *data)
+{
+   _glut_current->data = data;
+}