|
From: Brenda L. <asp...@us...> - 2003-05-13 22:48:56
|
Update of /cvsroot/squeak/squeak/platforms/unix/vm-display-X11
In directory sc8-pr-cvs1:/tmp/cvs-serv30463/vm-display-X11
Added Files:
Makefile.in acinclude.m4 sqUnixMozilla.c sqUnixOpenGL.X11
sqUnixX11.c
Log Message:
Ian Piumarta's release 3.5-1devel
--- NEW FILE: Makefile.in ---
# Makefile for X11 Window System support -*- makefile -*-
#
# Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
# as listed elsewhere in this file.
# All rights reserved.
#
# You are NOT ALLOWED to distribute modified versions of this file
# under its original name. If you want to modify it and then make
# your modifications available publicly, rename the file first.
#
# This file is part of Unix Squeak.
#
# This file 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.
#
# You may use and/or distribute this file ONLY as part of Squeak, under
# the terms of the Squeak License as described in `LICENSE' in the base of
# this distribution, subject to the following additional restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not
# claim that you wrote the original software. If you use this software
# in a product, an acknowledgment to the original author(s) (and any
# other contributors mentioned herein) in the product documentation
# would be appreciated but is not required.
#
# 2. You must not distribute (or make publicly available by any
# means) a modified copy of this file unless you first rename it.
#
# 3. This notice must not be removed or altered in any source distribution.
#
# Using (or modifying this file for use) in any context other than Squeak
# changes these copyright conditions. Read the file `COPYING' in the
# directory `platforms/unix/doc' before proceeding with any such use.
#
# Author: ian...@in...
#
# Last edited: 2003-02-02 17:23:09 by piumarta on emilia.local.
[make_cfg]
[make_plg]
TARGET = vm-display-X11$a
OBJS = sqUnixX11$o sqUnixMozilla$o
XCFLAGS = $(X_CFLAGS)
XINCLUDES = [includes] $(X_INCLUDES) \
-I$(topdir)/platforms/Cross/plugins/FilePlugin \
-I$(topdir)/platforms/Cross/plugins/B3DAcceleratorPlugin \
-I$(topdir)/platforms/unix/plugins/B3DAcceleratorPlugin
$(TARGET) : $(OBJS) Makefile
$(LINK) $(TARGET) $(OBJS) $(X_LIBS)
$(RANLIB) $(TARGET)
[make_targets]
.force :
--- NEW FILE: acinclude.m4 ---
# -*- sh -*-
AC_ARG_WITH(x,
[ --without-x disable X Window System support [default=enabled]],
[have_x="$withval"],
[have_x="yes"])
###xxx FIXME (AGAIN): mandrake needs explicit -lpthread
VMLIBS=${LIBS}
VMCFLAGS=${CFLAGS}
VMCPPFLAGS=${CPPFLAGS}
VMINCLUDES=${INCLUDES}
if test "$have_x" = "yes"; then
AC_PATH_XTRA
LIBS="${X_PRE_LIBS} ${X_LIBS} ${X_EXTRA_LIBS} ${LIBS}"
# if test "${x_libraries}" != ""; then
# CFLAGS="${X_CFLAGS} ${CFLAGS} -L${x_libraries}"
# fi
if test "${x_includes}" != ""; then
CPPFLAGS="${CPPFLAGS} -I${x_includes}"
INCLUDES="${INCLUDES} -I${x_includes}"
X_INCLUDES="-I${x_includes}"
fi
AC_CHECK_LIB(X11, XOpenDisplay, [
AC_DEFINE(USE_X11, [1])
LIBS="${LIBS} -lX11"
AC_CHECK_LIB(Xext, XShmAttach)
if test "$have_gl" = ""; then have_gl="no"; fi
AC_CHECK_HEADERS(GL/gl.h, [
have_gl=yes
AC_DEFINE(USE_X11_GLX, [1])
AC_CHECK_LIB(GL,glIsEnabled)
])
],[
AC_PLUGIN_DISABLE
])
else
AC_PLUGIN_DISABLE
fi
X_LIBS=${LIBS}
AC_SUBST(X_LIBS)
X_CFLAGS=${CFLAGS}
AC_SUBST(X_CFLAGS)
X_CPPFLAGS=${CPPFLAGS}
AC_SUBST(X_CPPFLAGS)
X_INCLUDES=${INCLUDES}
AC_SUBST(X_INCLUDES)
LIBS=${VMLIBS}
CFLAGS=${VMCFLAGS}
CPPFLAGS=${VMCPPFLAGS}
INCLUDES=${VMINCLUDES}
--- NEW FILE: sqUnixMozilla.c ---
/* sqUnixMozilla.c -- support for Squeak Netscape plugin
*
* Author: Bert Freudenberg <be...@is...>
*
* Last edited: 2003-02-02 15:24:12 by piumarta on emilia.local.
*
* Originally based on Andreas Raab's sqWin32PluginSupport
*
* Notes: The plugin window handling stuff is in sqXWindow.c.
* browserProcessCommand() is called when data is available
*/
#include "sq.h"
#if defined(USE_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <unistd.h>
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
#include "FilePlugin.h"
#define DEBUG
#ifdef DEBUG
void DPRINT(char *format, ...)
{
static int debug= 42;
if (42 == debug)
debug= (NULL != getenv("NPSQUEAK_DEBUG"));
if (!debug)
{
return;
}
else
{
static FILE *file= 0;
if (!file)
{
file= fopen("/tmp/npsqueak.log", "a+");
}
if (file) {
va_list ap;
va_start(ap, format);
vfprintf(file, format, ap);
va_end(ap);
fflush(file);
}
}
}
#else
void DPRINT(char *, ...) { }
#endif
/* from sqXWindow.c */
extern Display* stDisplay;
extern Window stWindow;
extern Window browserWindow;
extern Window stParent;
extern int browserPipes[2];
/* from interpret.c */
int stackObjectValue(int);
int stackIntegerValue(int);
int isBytes(int);
int byteSizeOf(int);
void *firstIndexableField(int);
int push(int);
int pop(int);
int positive32BitIntegerFor(int);
int nilObject();
int instantiateClassindexableSize(int, int);
int classByteArray();
int failed();
int pushBool(int);
/* prototypes */
static void browserReceive(void *buf, size_t count);
static void browserSend(const void *buf, size_t count);
static void browserSendInt(int value);
static void browserReceiveData();
static void browserGetURLRequest(int id, char* url, int urlSize,
char* target, int targetSize);
#ifdef NOT_USED
static void browserPostURLRequest(int id, char* url, int urlSize,
char* target, int targetSize,
char* postData, int postDataSize);
#endif
typedef struct sqStreamRequest {
char *localName;
int semaIndex;
int state;
} sqStreamRequest;
#define MAX_REQUESTS 128
#define SQUEAK_READ 0
#define SQUEAK_WRITE 1
#define inBrowser\
(-1 != browserPipes[SQUEAK_READ])
#define CMD_BROWSER_WINDOW 1
#define CMD_GET_URL 2
#define CMD_POST_URL 3
#define CMD_RECEIVE_DATA 4
static sqStreamRequest *requests[MAX_REQUESTS];
/* primitives called from Squeak */
/*
primitivePluginBrowserReady
Return true if a connection to the browser
has been established. Only necessary if some
sort of asynchronous communications are used.
*/
int display_primitivePluginBrowserReady()
{
if (inBrowser)
{
pop(1);
pushBool(1);
}
else
primitiveFail();
return 1;
}
/*
primitivePluginRequestUrlStream: url with: semaIndex
Request a URL from the browser. Signal semaIndex
when the result of the request can be queried.
Returns a handle used in subsequent calls to plugin
stream functions.
Note: A request id is the index into requests[].
*/
int display_primitivePluginRequestURLStream()
{
sqStreamRequest *req;
int id, url, length, semaIndex;
if (!inBrowser) return primitiveFail();
DPRINT("VM: primitivePluginRequestURLStream()\n");
for (id=0; id<MAX_REQUESTS; id++) {
if (!requests[id]) break;
}
if (id >= MAX_REQUESTS) return primitiveFail();
semaIndex= stackIntegerValue(0);
url= stackObjectValue(1);
if (failed()) return 0;
if (!isBytes(url)) return primitiveFail();
req= calloc(1, sizeof(sqStreamRequest));
if (!req) return primitiveFail();
req->localName= NULL;
req->semaIndex= semaIndex;
req->state= -1;
requests[id]= req;
length= byteSizeOf(url);
browserGetURLRequest(id, firstIndexableField(url), length, NULL, 0);
pop(3);
push(positive32BitIntegerFor(id));
DPRINT("VM: request id: %i\n", id);
return 1;
}
/*
primitivePluginRequestURL: url target: target semaIndex: semaIndex
Request a URL into the given target.
*/
int display_primitivePluginRequestURL()
{
sqStreamRequest *req;
int url, urlLength;
int target, targetLength;
int id, semaIndex;
if (!browserWindow) return primitiveFail();
for (id=0; id<MAX_REQUESTS; id++) {
if (!requests[id]) break;
}
if (id >= MAX_REQUESTS) return primitiveFail();
semaIndex= stackIntegerValue(0);
target= stackObjectValue(1);
url= stackObjectValue(2);
if (failed()) return 0;
if (!isBytes(url) || !isBytes(target)) return primitiveFail();
urlLength= byteSizeOf(url);
targetLength= byteSizeOf(target);
req= calloc(1, sizeof(sqStreamRequest));
if(!req) return primitiveFail();
req->localName= NULL;
req->semaIndex= semaIndex;
req->state= -1;
requests[id]= req;
browserGetURLRequest(id, firstIndexableField(url), urlLength, firstIndexableField(target), targetLength);
pop(4);
push(positive32BitIntegerFor(id));
return 1;
}
/*
primitivePluginPostURL
*/
int display_primitivePluginPostURL()
{
fprintf(stderr, "primitivePluginPostURL() not yet implemented\n");
return primitiveFail();
}
/*
primitivePluginRequestFileHandle: id
After a URL file request has been successfully
completed, return a file handle for the received
data. Note: The file handle must be read-only for
security reasons.
*/
int display_primitivePluginRequestFileHandle()
{
sqStreamRequest *req;
int id, fileOop, openFn;
id= stackIntegerValue(0);
if (failed()) return 0;
if (id < 0 || id >= MAX_REQUESTS) return primitiveFail();
req= requests[id];
if (!req || !req->localName) return primitiveFail();
fileOop= nilObject();
if (req->localName)
{
DPRINT("VM: Creating file handle for %s\n", req->localName);
openFn= ioLoadFunctionFrom("fileOpenNamesizewritesecure", "FilePlugin");
if (!openFn)
{
DPRINT("VM: Couldn't load fileOpenName:size:write:secure: from FilePlugin!\n");
return primitiveFail();
}
fileOop= ((int (*) (char *, int, int, int)) openFn)
(req->localName, strlen(req->localName), 0 /* readonly */, 0 /* insecure */);
/* if file ends in a $, it was a temp link created by the plugin */
if ('$' == req->localName[strlen(req->localName) - 1])
{
DPRINT("VM: unlink %s\n", req->localName);
if (-1 == unlink(req->localName))
DPRINT("VM: unlink failed: %s\n", strerror(errno));
}
if (failed())
{
DPRINT("VM: file open failed\n");
return 0;
}
}
pop(2);
push(fileOop);
return 1;
}
/*
primitivePluginDestroyRequest: id
Destroy a request that has been issued before.
*/
int display_primitivePluginDestroyRequest()
{
sqStreamRequest *req;
int id;
id= stackIntegerValue(0);
if (id < 0 || id >= MAX_REQUESTS) return primitiveFail();
req= requests[id];
if (req) {
if (req->localName) free(req->localName);
free(req);
}
requests[id]= NULL;
pop(1);
return 1;
}
/*
primitivePluginRequestState: id
Return true if the operation was successfully completed.
Return false if the operation was aborted.
Return nil if the operation is still in progress.
*/
int display_primitivePluginRequestState()
{
sqStreamRequest *req;
int id;
id= stackIntegerValue(0);
if (id < 0 || id >= MAX_REQUESTS) return primitiveFail();
req= requests[id];
if (!req) return primitiveFail();
pop(2);
if (req->state == -1) push(nilObject());
else pushBool(req->state);
return 1;
}
/* helper functions */
static void browserReceive(void *buf, size_t count)
{
ssize_t n;
n= read(browserPipes[SQUEAK_READ], buf, count);
if (n == -1)
perror("Squeak read failed:");
if (n < count)
fprintf(stderr, "Squeak read too few data from pipe\n");
}
static void browserSend(const void *buf, size_t count)
{
ssize_t n;
n= write(browserPipes[SQUEAK_WRITE], buf, count);
if (n == -1)
perror("Squeak plugin write failed:");
if (n < count)
fprintf(stderr, "Squeak wrote too few data to pipe\n");
}
static void browserSendInt(int value)
{
browserSend(&value, 4);
}
/*
browserReceiveData:
Called in response to a CMD_RECEIVE_DATA message.
Retrieves the data file name and signals the semaphore.
*/
static void browserReceiveData()
{
char *localName= NULL;
int id, ok;
browserReceive(&id, 4);
browserReceive(&ok, 4);
DPRINT("VM: receiving data id: %i state %i\n", id, ok);
if (ok == 1) {
int length= 0;
browserReceive(&length, 4);
if (length) {
localName= malloc(length+1);
browserReceive(localName, length);
localName[length]= 0;
DPRINT("VM: got filename %s\n", localName);
}
}
if (id >= 0 && id < MAX_REQUESTS) {
sqStreamRequest *req= requests[id];
if (req) {
req->localName= localName;
req->state= ok;
DPRINT("VM: signaling semaphore, state=%i\n", ok);
/* synchronizedSignalSemaphoreWithIndex(req->semaIndex);*/
signalSemaphoreWithIndex(req->semaIndex);
}
}
}
/*
browserGetURLRequest:
Notify plugin to get the specified url into target
*/
static void browserGetURLRequest(int id, char* url, int urlSize,
char* target, int targetSize)
{
if (!inBrowser) {
fprintf(stderr, "Cannot submit URL request -- "
"there is no connection to a browser\n");
return;
}
browserSendInt(CMD_GET_URL);
browserSendInt(id);
browserSendInt(urlSize);
if (urlSize > 0)
browserSend(url, urlSize);
browserSendInt(targetSize);
if (targetSize > 0)
browserSend(target, targetSize);
}
/*
browserPostURLRequest:
Notify plugin to post data to the specified url and get result into target
*/
#ifdef NOT_USED
static void browserPostURLRequest(int id, char* url, int urlSize,
char* target, int targetSize,
char* postData, int postDataSize)
{
if (!inBrowser) {
fprintf(stderr, "Cannot submit URL post request -- "
"there is no connection to a browser\n");
return;
}
browserSendInt(CMD_POST_URL);
browserSendInt(id);
browserSendInt(urlSize);
if (urlSize > 0)
browserSend(url, urlSize);
browserSendInt(targetSize);
if (targetSize > 0)
browserSend(target, targetSize);
browserSendInt(postDataSize);
if (postDataSize > 0)
browserSend(postData, postDataSize);
}
#endif
/***************************************************************
* Functions called from sqXWindow.c
***************************************************************/
/*
browserProcessCommand:
Handle commands sent by the plugin.
*/
void browserProcessCommand(void)
{
static int firstTime= 1;
int cmd, n;
if (firstTime)
{
firstTime= 0;
/* enable non-blocking reads */
fcntl(browserPipes[SQUEAK_READ], F_SETFL, O_NONBLOCK);
}
DPRINT("VM: browserProcessCommand()\n");
n= read(browserPipes[SQUEAK_READ], &cmd, 4);
if (0 == n || (-1 == n && EAGAIN == errno))
return;
switch (cmd)
{
case CMD_RECEIVE_DATA:
/* Data is coming in */
browserReceiveData();
break;
case CMD_BROWSER_WINDOW:
/* Parent window has changed () */
browserReceive(&browserWindow, 4);
stParent= browserWindow;
DPRINT("VM: got browser window 0x%X\n", browserWindow);
break;
default:
fprintf(stderr, "Unknown command from Plugin: %i\n", cmd);
}
}
#else /* !defined(USE_X11) */
int display_primitivePluginBrowserReady() { return primitiveFail(); }
int display_primitivePluginRequestURLStream() { return primitiveFail(); }
int display_primitivePluginRequestURL() { return primitiveFail(); }
int display_primitivePluginPostURL() { return primitiveFail(); }
int display_primitivePluginRequestFileHandle() { return primitiveFail(); }
int display_primitivePluginDestroyRequest() { return primitiveFail(); }
int display_primitivePluginRequestState() { return primitiveFail(); }
#endif
--- NEW FILE: sqUnixOpenGL.X11 ---
/* sqUnixOpenGLX11.c -- support for accelerated 3D rendering under X11 -*- C -*-
*
* Author: Bert Freudenberg <be...@is...>
*
* Based on Andreas Raab's sqWin32OpenGL.c
*
* Last edited: 2003-01-31 22:40:39 by piumarta on emilia.local.
*
* History
* Nov 02: added TGraphicsTest conformant log support
* Oct 02: added Tea initialization support w/ stencil
* May 01: initial revision
*/
#include <sys/types.h>
#include "sqVirtualMachine.h"
#include "sqConfig.h"
#include "sqPlatformSpecific.h"
#include "B3DAcceleratorPlugin.h"
#if defined (B3DX_GL)
#include "sqUnixOpenGL.h"
#include <X11/X.h>
#include <stdio.h>
#include "sqOpenGLRenderer.h"
/* Plugin refs */
extern struct VirtualMachine *interpreterProxy;
static void printVisual(XVisualInfo* visinfo);
static void listVisuals();
static Display *stDisplay= NULL; /* Squeak's display */
static Window stWindow= 0; /* Squeak's main window */
static glRenderer *current= NULL;
static glRenderer allRenderer[MAX_RENDERER];
static int visualAttributes[]= {
GLX_STENCIL_SIZE, 0, /* filled in later - must be first item! */
GLX_ALPHA_SIZE, 1, /* filled in later - must be second item! */
GLX_RGBA, /* no indexed colors */
GLX_DOUBLEBUFFER, /* will swap */
GLX_LEVEL, 0, /* frame buffer, not overlay */
GLX_DEPTH_SIZE, 16, /* decent depth */
GLX_AUX_BUFFERS, 0, /* no aux buffers */
GLX_ACCUM_RED_SIZE, 0, /* no accumulation */
GLX_ACCUM_GREEN_SIZE, 0,
GLX_ACCUM_BLUE_SIZE, 0,
GLX_ACCUM_ALPHA_SIZE, 0,
None
};
static float blackLight[4]= { 0.0f, 0.0f, 0.0f, 0.0f };
/* Verbose level for debugging purposes:
0 - print NO information ever
1 - print critical debug errors
2 - print debug warnings
3 - print extra information
4 - print extra warnings
5 - print information about primitive execution
10 - print information about each vertex and face
*/
int verboseLevel= 1;
/*** create / destroy a renderer ***/
int glCreateRendererFlags(int x, int y, int w, int h, int flags)
{
glRenderer *renderer;
XVisualInfo* visinfo= 0;
int index= -1;
if (flags & ~(B3D_HARDWARE_RENDERER | B3D_SOFTWARE_RENDERER | B3D_STENCIL_BUFFER))
{
DPRINTF(1, (fp, "ERROR: Unsupported renderer flags (%d)\r", flags));
return -1;
}
if (flags & B3D_STENCIL_BUFFER)
visualAttributes[1]= 1;
else
visualAttributes[1]= 0;
/* find unused renderer */
{
int i;
for (i= 0; i < MAX_RENDERER; i++)
{
if (!allRenderer[i].used)
{
index= i;
break;
}
}
}
if (index == -1)
{
DPRINTF(1, (fp, "ERROR: Maximum number of renderers (%d) exceeded\r", MAX_RENDERER));
return 0;
}
renderer= &allRenderer[index];
renderer->used= True;
renderer->window= 0;
renderer->context= NULL;
DPRINTF(3, (fp, "---- Creating new renderer ----\r\r"));
/* sanity checks */
if (w < 0 || h < 0)
{
DPRINTF(1, (fp, "Negative extent (%i@%i)!\r", w, h));
goto FAILED;
}
/* choose visual and create context */
if (verboseLevel >= 3)
listVisuals();
{
visinfo= glXChooseVisual(stDisplay,
DefaultScreen(stDisplay),
visualAttributes);
if (!visinfo)
{
/* retry without alpha */
visualAttributes[3]= 0;
visinfo= glXChooseVisual(stDisplay,
DefaultScreen(stDisplay),
visualAttributes);
}
if (!visinfo)
{
DPRINTF(1, (fp, "No OpenGL visual found!\r"));
goto FAILED;
}
DPRINTF(3, (fp, "\r#### Selected GLX visual ID 0x%lx ####\r",
visinfo->visualid));
if (verboseLevel >= 3)
printVisual(visinfo);
renderer->context= glXCreateContext(stDisplay, visinfo, 0, GL_TRUE);
if (!renderer->context)
{
DPRINTF(1, (fp, "Creating GLX context failed!\r"));
goto FAILED;
}
DPRINTF(3, (fp, "\r#### Created GLX context ####\r" ));
/* create window */
{
XSetWindowAttributes attributes;
unsigned long valuemask= 0;
attributes.colormap= XCreateColormap(stDisplay,
DefaultRootWindow(stDisplay),
visinfo->visual,
AllocNone);
valuemask|= CWColormap;
attributes.background_pixel= BlackPixel(stDisplay, DefaultScreen(stDisplay));
valuemask|= CWBackPixel;
renderer->window= XCreateWindow(stDisplay, stWindow, x, y, w, h, 0,
visinfo->depth, InputOutput, visinfo->visual,
valuemask, &attributes);
if (!renderer->window)
{
DPRINTF(1, (fp, "Failed to create client window\r"));
goto FAILED;
}
XMapWindow(stDisplay, renderer->window);
}
DPRINTF(3, (fp, "\r#### Created window ####\r" ));
XFree(visinfo);
visinfo= 0;
}
/* Make the context current */
if (!glXMakeCurrent(stDisplay, renderer->window, renderer->context))
{
DPRINTF(1, (fp, "Failed to make context current\r"));
goto FAILED;
}
renderer->bufferRect[0]= x;
renderer->bufferRect[1]= y;
renderer->bufferRect[2]= w;
renderer->bufferRect[3]= h;
DPRINTF(3, (fp, "\r### Renderer created! ###\r"));
/* setup user context */
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glEnable(GL_DITHER);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, blackLight);
ERROR_CHECK;
return index;
FAILED:
/* do necessary cleanup */
DPRINTF(1, (fp, "OpenGL initialization failed\r"));
if (visinfo)
XFree(visinfo);
if (renderer->context)
glXDestroyContext(stDisplay, renderer->context);
if (renderer->window)
XDestroyWindow(stDisplay, renderer->window);
return -1;
}
int glDestroyRenderer(int handle)
{
glRenderer *renderer= glRendererFromHandle(handle);
DPRINTF(3, (fp, "\r--- Destroying renderer ---\r"));
if (!renderer)
return 1; /* already destroyed */
if (!glMakeCurrentRenderer(NULL))
return 0;
glXDestroyContext(stDisplay, renderer->context);
XDestroyWindow(stDisplay, renderer->window);
renderer->window= 0;
renderer->context= NULL;
renderer->used= False;
return 1;
}
/*** helpers ***/
glRenderer *glRendererFromHandle(int handle)
{
DPRINTF(7, (fp, "Looking for renderer id: %i\r", handle));
if (handle < 0 || handle >= MAX_RENDERER)
return NULL;
if (allRenderer[handle].used)
return allRenderer+handle;
return NULL;
}
int glIsOverlayRenderer(int handle)
{
/* we always use overlay renderers */
return 1;
}
int glSwapBuffers(glRenderer *renderer)
{
if (!renderer || !renderer->used)
return 0;
glXSwapBuffers(stDisplay, renderer->window);
return 1;
}
int glMakeCurrentRenderer(glRenderer *renderer)
{
if (current == renderer)
return 1;
if (renderer && !renderer->used)
return 0;
if (renderer)
{
if (!glXMakeCurrent(stDisplay, renderer->window, renderer->context))
{
DPRINTF(1, (fp, "Failed to make context current\r"));
return 0;
}
}
else
{
glXMakeCurrent(stDisplay, 0, NULL);
}
current= renderer;
return 1;
}
int glSetBufferRect(int handle, int x, int y, int w, int h)
{
glRenderer *renderer= glRendererFromHandle(handle);
if (!renderer || !glMakeCurrentRenderer(renderer))
return 0;
if (w < 1 || h < 1)
return 0;
XMoveResizeWindow(stDisplay, renderer->window, x, y, w, h);
renderer->bufferRect[0]= x;
renderer->bufferRect[1]= y;
renderer->bufferRect[2]= w;
renderer->bufferRect[3]= h;
return 1;
}
int glSetVerboseLevel(int level)
{
verboseLevel= level;
return 1;
}
int glGetIntPropertyOS(int handle, int prop)
{
GLint v;
glRenderer *renderer= glRendererFromHandle(handle);
if (!renderer || !glMakeCurrentRenderer(renderer))
return 0;
switch(prop) {
case 1: /* backface culling */
if (!glIsEnabled(GL_CULL_FACE)) return 0;
glGetIntegerv(GL_FRONT_FACE, &v);
if (v == GL_CW) return 1;
if (v == GL_CCW) return -1;
return 0;
case 2: /* polygon mode */
glGetIntegerv(GL_POLYGON_MODE, &v);
ERROR_CHECK;
return v;
case 3: /* point size */
glGetIntegerv(GL_POINT_SIZE, &v);
ERROR_CHECK;
return v;
case 4: /* line width */
glGetIntegerv(GL_LINE_WIDTH, &v);
ERROR_CHECK;
return v;
}
return 0;
}
int glSetIntPropertyOS(int handle, int prop, int value)
{
glRenderer *renderer= glRendererFromHandle(handle);
if (!renderer || !glMakeCurrentRenderer(renderer))
return 0;
switch(prop) {
case 1: /* backface culling */
if (!value) {
glDisable(GL_CULL_FACE);
ERROR_CHECK;
return 1;
}
glEnable(GL_CULL_FACE);
glFrontFace(value == 1 ? GL_CCW : GL_CW);
ERROR_CHECK;
return 1;
case 2: /* polygon mode */
if (value == 0) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
else if (value == 1) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else if (value == 2) glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
else return 0;
ERROR_CHECK;
return 1;
case 3: /* point size */
glPointSize(value);
ERROR_CHECK;
return 1;
case 4: /* line width */
glLineWidth(value);
ERROR_CHECK;
return 1;
}
return 0;
}
/* GLX_CONFIG_CAVEAT might not be supported */
/* but the test below is worded so it does not matter */
#ifndef GLX_CONFIG_CAVEAT
# define GLX_CONFIG_CAVEAT 0x20
# define GLX_SLOW_CONFIG 0x8001
#endif
static void printVisual(XVisualInfo* visinfo)
{
int isOpenGL;
glXGetConfig(stDisplay, visinfo, GLX_USE_GL, &isOpenGL);
if (isOpenGL)
{
int slow= 0;
int red, green, blue, alpha, stencil, depth;
glXGetConfig(stDisplay, visinfo, GLX_CONFIG_CAVEAT, &slow);
glXGetConfig(stDisplay, visinfo, GLX_RED_SIZE, &red);
glXGetConfig(stDisplay, visinfo, GLX_GREEN_SIZE, &green);
glXGetConfig(stDisplay, visinfo, GLX_BLUE_SIZE, &blue);
glXGetConfig(stDisplay, visinfo, GLX_ALPHA_SIZE, &alpha);
glXGetConfig(stDisplay, visinfo, GLX_STENCIL_SIZE, &stencil);
glXGetConfig(stDisplay, visinfo, GLX_DEPTH_SIZE, &depth);
if (slow != GLX_SLOW_CONFIG)
DPRINTF(3, (fp,"===> OpenGL visual\r"))
else
DPRINTF(3, (fp,"---> slow OpenGL visual\r"));
DPRINTF(3, (fp,"rgbaBits = %i+%i+%i+%i\r", red, green, blue, alpha));
DPRINTF(3, (fp,"stencilBits = %i\r", stencil));
DPRINTF(3, (fp,"depthBits = %i\r", depth));
}
}
static void listVisuals()
{
XVisualInfo* visinfo;
int nvisuals, i;
visinfo= XGetVisualInfo(stDisplay, VisualNoMask, NULL, &nvisuals);
for (i= 0; i < nvisuals; i++)
{
DPRINTF(3, (fp,"#### Checking pixel format (visual ID 0x%lx)\r", visinfo[i].visualid));
printVisual(&visinfo[i]);
}
XFree(visinfo);
}
/*** Module initializers ***/
int glInitialize(void)
{
int i, p;
int fn;
fn= interpreterProxy->ioLoadFunctionFrom("ioGetDisplay", NULL);
stDisplay= (fn ? ((Display *(*)(void))fn)() : 0);
if (!stDisplay)
{
DPRINTF(1,(fp,"ERROR: Failed to look up stDisplay\r"));
return 0;
}
fn= interpreterProxy->ioLoadFunctionFrom("ioGetWindow", NULL);
stWindow= (fn ? ((Window (*)(void))fn)() : 0);
if (!stWindow)
{
DPRINTF(1,(fp,"ERROR: Failed to look up stWindow\r"));
return 0;
}
for (i= 0; i < MAX_RENDERER; i++)
{
allRenderer[i].used= False;
}
return 1;
}
int glShutdown(void)
{
int i;
for (i=0; i< MAX_RENDERER; i++)
{
if (allRenderer[i].used)
{
glDestroyRenderer(i);
}
}
return 1;
}
#endif /* defined(B3DX_GL) */
--- NEW FILE: sqUnixX11.c ---
/* sqUnixX11.c -- support for display via the X Window System.
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* You are NOT ALLOWED to distribute modified versions of this file
* under its original name. If you want to modify it and then make
* your modifications available publicly, rename the file first.
*
* This file is part of Unix Squeak.
*
* This file 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.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following additional restrictions:
[...3895 lines suppressed...]
fprintf(stderr, "browser: window = 0x%x\n" browserWindow);
# endif
return 3;
}
else
n= 0; /* not recognised */
}
else
n= 0;
return n;
}
static void *display_makeInterface(void)
{
return &display_X11_itf;
}
#include "SqModule.h"
SqModuleDefine(display, X11);
|