blob: 610cf36dcc677b85ec019f12043f306e16855cc3 [file] [log] [blame]
/*
* 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;
}