mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 09:30:11 +01:00
initial check-in (post crash)
This commit is contained in:
parent
2d550f6ff1
commit
a4dcdcf0ff
68 changed files with 33991 additions and 0 deletions
121
src/glut/glx/Makefile.X11
Normal file
121
src/glut/glx/Makefile.X11
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# $Id: Makefile.X11,v 1.1 1999/08/19 14:00:01 brianp Exp $
|
||||
|
||||
# Makefile for GLUT
|
||||
#
|
||||
# NOTICE: The OpenGL Utility Toolkit (GLUT) distribution contains source
|
||||
# code published in a book titled "Programming OpenGL for the X Window
|
||||
# System" (ISBN: 0-201-48359-9) published by Addison-Wesley. The
|
||||
# programs and associated files contained in the distribution were
|
||||
# developed by Mark J. Kilgard and are Copyright 1994, 1995, 1996 by Mark
|
||||
# J. Kilgard (unless otherwise noted). The programs are not in the
|
||||
# public domain, but they are freely distributable without licensing
|
||||
# fees. These programs are provided without guarantee or warrantee
|
||||
# expressed or implied.
|
||||
#
|
||||
# GLUT source included with Mesa with permission from Mark Kilgard.
|
||||
|
||||
|
||||
# $Log: Makefile.X11,v $
|
||||
# Revision 1.1 1999/08/19 14:00:01 brianp
|
||||
# initial check-in (post crash)
|
||||
#
|
||||
|
||||
|
||||
##### MACROS #####
|
||||
|
||||
GLUT_MAJOR = 3
|
||||
GLUT_MINOR = 7
|
||||
|
||||
VPATH = RCS
|
||||
|
||||
INCDIR = ../include
|
||||
LIBDIR = ../lib
|
||||
|
||||
SOURCES = \
|
||||
glut_8x13.c \
|
||||
glut_9x15.c \
|
||||
glut_bitmap.c \
|
||||
glut_bwidth.c \
|
||||
glut_cindex.c \
|
||||
glut_cmap.c \
|
||||
glut_cursor.c \
|
||||
glut_dials.c \
|
||||
glut_dstr.c \
|
||||
glut_event.c \
|
||||
glut_ext.c \
|
||||
glut_fbc.c \
|
||||
glut_fullscrn.c \
|
||||
glut_gamemode.c \
|
||||
glut_get.c \
|
||||
glut_glxext.c \
|
||||
glut_hel10.c \
|
||||
glut_hel12.c \
|
||||
glut_hel18.c \
|
||||
glut_init.c \
|
||||
glut_input.c \
|
||||
glut_joy.c \
|
||||
glut_key.c \
|
||||
glut_keyctrl.c \
|
||||
glut_keyup.c \
|
||||
glut_menu.c \
|
||||
glut_menu2.c \
|
||||
glut_mesa.c \
|
||||
glut_modifier.c \
|
||||
glut_mroman.c \
|
||||
glut_overlay.c \
|
||||
glut_roman.c \
|
||||
glut_shapes.c \
|
||||
glut_space.c \
|
||||
glut_stroke.c \
|
||||
glut_swap.c \
|
||||
glut_swidth.c \
|
||||
glut_tablet.c \
|
||||
glut_teapot.c \
|
||||
glut_tr10.c \
|
||||
glut_tr24.c \
|
||||
glut_util.c \
|
||||
glut_vidresize.c \
|
||||
glut_warp.c \
|
||||
glut_win.c \
|
||||
glut_winmisc.c \
|
||||
layerutil.c
|
||||
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.c.o:
|
||||
$(CC) -c -I$(INCDIR) $(CFLAGS) $<
|
||||
|
||||
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
default:
|
||||
@echo "Specify a target configuration"
|
||||
|
||||
clean:
|
||||
-rm *.o *~
|
||||
|
||||
targets: $(LIBDIR)/$(GLUT_LIB)
|
||||
|
||||
# Make the library
|
||||
$(LIBDIR)/$(GLUT_LIB): $(OBJECTS)
|
||||
$(MAKELIB) $(GLUT_LIB) $(GLUT_MAJOR) $(GLUT_MINOR) $(OBJECTS)
|
||||
mv $(GLUT_LIB)* $(LIBDIR)
|
||||
|
||||
include ../Make-config
|
||||
|
||||
include depend
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Run 'make dep' to update the dependencies if you change what's included
|
||||
# by any source file.
|
||||
#
|
||||
dep: $(SOURCES)
|
||||
makedepend -fdepend -Y -I../include $(SOURCES)
|
||||
109
src/glut/glx/Makefile.cygnus
Normal file
109
src/glut/glx/Makefile.cygnus
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# Makefile.cygnus for Cygnus-Win32 target
|
||||
# /Stephane Rehel, November 16 1997
|
||||
|
||||
# Makefile for GLUT 3.6
|
||||
#
|
||||
# NOTICE: The OpenGL Utility Toolkit (GLUT) distribution contains source
|
||||
# code published in a book titled "Programming OpenGL for the X Window
|
||||
# System" (ISBN: 0-201-48359-9) published by Addison-Wesley. The
|
||||
# programs and associated files contained in the distribution were
|
||||
# developed by Mark J. Kilgard and are Copyright 1994, 1995, 1996 by Mark
|
||||
# J. Kilgard (unless otherwise noted). The programs are not in the
|
||||
# public domain, but they are freely distributable without licensing
|
||||
# fees. These programs are provided without guarantee or warrantee
|
||||
# expressed or implied.
|
||||
#
|
||||
# GLUT source included with Mesa with permission from Mark Kilgard.
|
||||
|
||||
|
||||
##### MACROS #####
|
||||
|
||||
GLUT_MAJOR = 3
|
||||
GLUT_MINOR = 6
|
||||
|
||||
VPATH = RCS
|
||||
|
||||
INCDIR = ../include
|
||||
LIBDIR = ../lib
|
||||
|
||||
SOURCES = \
|
||||
glut_8x13.c \
|
||||
glut_9x15.c \
|
||||
glut_bitmap.c \
|
||||
glut_bwidth.c \
|
||||
glut_cindex.c \
|
||||
glut_cmap.c \
|
||||
glut_cursor.c \
|
||||
glut_dials.c \
|
||||
glut_dstr.c \
|
||||
glut_event.c \
|
||||
glut_ext.c \
|
||||
glut_fullscrn.c \
|
||||
glut_get.c \
|
||||
glut_hel10.c \
|
||||
glut_hel12.c \
|
||||
glut_hel18.c \
|
||||
glut_init.c \
|
||||
glut_input.c \
|
||||
glut_mesa.c \
|
||||
glut_modifier.c \
|
||||
glut_mroman.c \
|
||||
glut_overlay.c \
|
||||
glut_roman.c \
|
||||
glut_shapes.c \
|
||||
glut_space.c \
|
||||
glut_stroke.c \
|
||||
glut_swap.c \
|
||||
glut_swidth.c \
|
||||
glut_tablet.c \
|
||||
glut_teapot.c \
|
||||
glut_tr10.c \
|
||||
glut_tr24.c \
|
||||
glut_util.c \
|
||||
glut_vidresize.c \
|
||||
glut_warp.c \
|
||||
glut_win.c \
|
||||
glut_winmisc.c \
|
||||
win32_x11.c \
|
||||
win32_glx.c \
|
||||
win32_menu.c \
|
||||
win32_util.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
|
||||
|
||||
##### RULES #####
|
||||
|
||||
.c.o:
|
||||
$(CC) -c -I$(INCDIR) $(CFLAGS) $<
|
||||
|
||||
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
default:
|
||||
@echo "Specify a target configuration"
|
||||
|
||||
clean:
|
||||
-rm *.o *~
|
||||
|
||||
targets: $(LIBDIR)/$(GLUT_LIB)
|
||||
|
||||
# Make the library
|
||||
$(LIBDIR)/$(GLUT_LIB): $(OBJECTS)
|
||||
$(MAKELIB) $(GLUT_LIB) $(GLUT_MAJOR) $(GLUT_MINOR) $(OBJECTS)
|
||||
mv $(GLUT_LIB)* $(LIBDIR)
|
||||
|
||||
include ../Make-config
|
||||
|
||||
include depend
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Run 'make dep' to update the dependencies if you change what's included
|
||||
# by any source file.
|
||||
#
|
||||
dep: $(SOURCES)
|
||||
makedepend -fdepend -Y -I../include $(SOURCES)
|
||||
189
src/glut/glx/Makefile.sgi
Normal file
189
src/glut/glx/Makefile.sgi
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#! smake
|
||||
#
|
||||
# Copyright (c) Mark J. Kilgard, 1995, 1998.
|
||||
#
|
||||
include $(ROOT)/usr/include/make/commondefs
|
||||
|
||||
# NOTE: In my GLUT development tree, many of the C source files for
|
||||
# GLUT are generated. For this reason, "make full_clobber" will remove
|
||||
# these generated C files, while "make clobber" will not.
|
||||
|
||||
TOP = ../..
|
||||
|
||||
TARGETS = libglut.a
|
||||
|
||||
LN = ln -s
|
||||
MV = mv
|
||||
RM = -rm -rf
|
||||
|
||||
HDRS = glutint.h glutstroke.h layerutil.h glutbitmap.h
|
||||
|
||||
SRCS = \
|
||||
glut_bitmap.c \
|
||||
glut_bwidth.c \
|
||||
glut_cindex.c \
|
||||
glut_cmap.c \
|
||||
glut_cursor.c \
|
||||
glut_dials.c \
|
||||
glut_dstr.c \
|
||||
glut_event.c \
|
||||
glut_ext.c \
|
||||
glut_fbc.c \
|
||||
glut_fullscrn.c \
|
||||
glut_gamemode.c \
|
||||
glut_get.c \
|
||||
glut_glxext.c \
|
||||
glut_init.c \
|
||||
glut_input.c \
|
||||
glut_joy.c \
|
||||
glut_key.c \
|
||||
glut_keyctrl.c \
|
||||
glut_keyup.c \
|
||||
glut_menu.c \
|
||||
glut_menu2.c \
|
||||
glut_mesa.c \
|
||||
glut_modifier.c \
|
||||
glut_overlay.c \
|
||||
glut_shapes.c \
|
||||
glut_space.c \
|
||||
glut_stroke.c \
|
||||
glut_swap.c \
|
||||
glut_swidth.c \
|
||||
glut_tablet.c \
|
||||
glut_teapot.c \
|
||||
glut_util.c \
|
||||
glut_vidresize.c \
|
||||
glut_warp.c \
|
||||
glut_win.c \
|
||||
glut_winmisc.c \
|
||||
layerutil.c
|
||||
|
||||
SRCSSEMIGENS = \
|
||||
glut_8x13.c \
|
||||
glut_9x15.c \
|
||||
glut_hel10.c \
|
||||
glut_hel12.c \
|
||||
glut_hel18.c \
|
||||
glut_mroman.c \
|
||||
glut_roman.c \
|
||||
glut_tr10.c \
|
||||
glut_tr24.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o) $(SRCSSEMIGENS:.c=.o)
|
||||
OTHERGENS = y.tab.c y.tab.h strokegen.c strokegen.h strokelex.c
|
||||
OTHERSRCS = strokegen.y strokelex.l stroke.h
|
||||
FONTS = Roman.stroke MonoRoman.stroke
|
||||
|
||||
# Uncomment the LCDEFS line below if you want to build a version of
|
||||
# libglut.a that avoids using the SGI "fast atoms" optimization
|
||||
# introduced in IRIX 6.3. This optimization eliminates serveral X server
|
||||
# round-trips. If you are building libglut.a on an IRIX 6.3 or later
|
||||
# machine and want a chance (no guarantees) that GLUT executables built
|
||||
# against your libglut.a will work on IRIX 6.2 machines, uncomment out
|
||||
# the LCDEFS line below. Otherwise, you'll get a run-time message about
|
||||
# "attempted access to unresolvable symbol in XXX: _XSGIFastInternAtom"
|
||||
#LCDEFS = -DNO_FAST_ATOMS
|
||||
|
||||
LCOPTS = -I$(TOP)/include -fullwarn
|
||||
LWOFF = ,813,852,827,826
|
||||
LDIRT = *~ $(OTHERGENS) strokegen *.bak hardcopy glutsrc.ps capturexfont *.pure dstr dstr.c *.gen
|
||||
|
||||
default: $(TARGETS)
|
||||
|
||||
sinclude ObjectType.mk
|
||||
|
||||
$(OBJS) : $(HDRS)
|
||||
|
||||
libglut.a : $(OBJS)
|
||||
$(RM) $@
|
||||
$(AR) crl $@ $(OBJS)
|
||||
|
||||
.ORDER : strokegen.h strokegen.c
|
||||
|
||||
strokegen.h strokegen.c : strokegen.y
|
||||
$(YACC) -d strokegen.y
|
||||
$(MV) y.tab.c strokegen.c
|
||||
$(MV) y.tab.h strokegen.h
|
||||
|
||||
# avoid warnings when compiling lex generated code
|
||||
strokegen.o : strokegen.c
|
||||
$(CC) $(CFLAGS) -woff 726,825,635,818,819,820,824,831,835,822,821,1167,1498,1116,1136,1174,1196,803 -c -MDupdate Makedepend strokegen.c
|
||||
|
||||
strokelex.c : strokelex.l
|
||||
$(LEX) strokelex.l
|
||||
$(MV) lex.yy.c strokelex.c
|
||||
|
||||
# avoid warnings when compiling lex generated code
|
||||
strokelex.o : strokelex.c
|
||||
$(CC) $(CFLAGS) -woff 831,825,817,835,702,819,635,824,822,1167,1498,1110,1196,1174,803 -c -MDupdate Makedepend strokelex.c
|
||||
|
||||
strokegen : strokegen.o strokelex.o
|
||||
$(CC) -o $@ $(LDFLAGS) strokegen.o strokelex.o -ll
|
||||
|
||||
capturexfont : capturexfont.o
|
||||
$(CC) -o $@ $(LDFLAGS) capturexfont.o -lX11
|
||||
|
||||
# glut_roman.c and glut_mroman.c are now checked in, but here are rules to generate them
|
||||
glut_roman.c.gen : Roman.stroke strokegen
|
||||
./strokegen -s glutStrokeRoman < Roman.stroke > $@
|
||||
glut_mroman.c.gen : MonoRoman.stroke strokegen
|
||||
./strokegen -s glutStrokeMonoRoman < MonoRoman.stroke > $@
|
||||
|
||||
glutsrc.ps : $(SRCS)
|
||||
$(RM) hardcopy
|
||||
mkdir -p hardcopy
|
||||
for i in $(SRCS) ;\
|
||||
do \
|
||||
grep -v CENTRY $$i | grep -v INDENT- > hardcopy/$$i; \
|
||||
done
|
||||
cd hardcopy ; enscript -p ../$@ -G -2r `echo $(SRCS) | fmt -1 | sort`
|
||||
$(RM) hardcopy
|
||||
|
||||
# The bitmap files can be generated using capturexfont, but because
|
||||
# they require a connection to an X server and potentially different
|
||||
# X servers have different fonts, these generated files are part
|
||||
# of the GLUT distribution.
|
||||
|
||||
9_BY_15 = -misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1
|
||||
8_BY_13 = -misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1
|
||||
TR10 = -adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1
|
||||
TR24 = -adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1
|
||||
HEL10 = -adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1
|
||||
HEL12 = -adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1
|
||||
HEL18 = -adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1
|
||||
|
||||
semigens : capturexfont
|
||||
./capturexfont $(9_BY_15) glutBitmap9By15 > glut_9x15.c.gen
|
||||
./capturexfont $(8_BY_13) glutBitmap8By13 > glut_8x13.c.gen
|
||||
./capturexfont $(TR10) glutBitmapTimesRoman10 > glut_tr10.c.gen
|
||||
./capturexfont $(TR24) glutBitmapTimesRoman24 > glut_tr24.c.gen
|
||||
./capturexfont $(HEL10) glutBitmapHelvetica10 > glut_hel10.c.gen
|
||||
./capturexfont $(HEL12) glutBitmapHelvetica12 > glut_hel12.c.gen
|
||||
./capturexfont $(HEL18) glutBitmapHelvetica18 > glut_hel18.c.gen
|
||||
|
||||
# unused test rule for test building 16-bit font
|
||||
JIS = -jis-fixed-medium-r-normal--24-230-75-75-c-240-jisx0208.1983-0
|
||||
glut_jis.c :
|
||||
./capturexfont $(JIS) glutBitmapJis > $@
|
||||
|
||||
sources: $(SRCS)
|
||||
|
||||
symcheck: libglut.a
|
||||
-nm -Bo libglut.a | grep -v ' d ' | grep -v ' T glut' | grep -v ' D glut' | grep -v ' U ' | grep -v ' T __glut' | grep -v ' t ' | grep -v ' b ' | grep -v ' D __glut' | grep -v ' B __glut'
|
||||
|
||||
dstr.c: glut_dstr.c
|
||||
ln -s glut_dstr.c $@
|
||||
|
||||
dstr: dstr.c glut_util.o glut_glxext.o
|
||||
$(RM) $@
|
||||
$(CC) -g -o $@ $(CFLAGS) -DTEST dstr.c glut_util.o glut_glxext.o -lGLU -lGL -lXext -lX11 -lm
|
||||
|
||||
./glut.h : glut.h
|
||||
./glutint.h : glutint.h
|
||||
./glutstroke.h : glutstroke.h
|
||||
./strokegen.h : strokegen.h
|
||||
./stroke.h : stroke.h
|
||||
./layerutil.h : layerutil.h
|
||||
strokelex.o: strokelex.c strokegen.h
|
||||
|
||||
include $(COMMONRULES)
|
||||
95
src/glut/glx/Makefile.win
Normal file
95
src/glut/glx/Makefile.win
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# Makefile for Win32
|
||||
|
||||
!include <win32.mak>
|
||||
|
||||
TOP = ../..
|
||||
|
||||
# NOTE: glut_menu.c and glut_glxext.c are NOT compiled into Win32 GLUT
|
||||
|
||||
SRCS = glut_8x13.c glut_9x15.c glut_bitmap.c glut_bwidth.c glut_cindex.c glut_cmap.c glut_cursor.c glut_dials.c glut_dstr.c glut_event.c glut_ext.c glut_fbc.c glut_fullscrn.c glut_gamemode.c glut_get.c glut_hel10.c glut_hel12.c glut_hel18.c glut_init.c glut_input.c glut_joy.c glut_key.c glut_keyctrl.c glut_keyup.c glut_mesa.c glut_modifier.c glut_mroman.c glut_overlay.c glut_roman.c glut_shapes.c glut_space.c glut_stroke.c glut_swap.c glut_swidth.c glut_tablet.c glut_teapot.c glut_tr10.c glut_tr24.c glut_util.c glut_vidresize.c glut_warp.c glut_win.c glut_winmisc.c win32_glx.c win32_menu.c win32_util.c win32_winproc.c win32_x11.c
|
||||
|
||||
all : glutdll install
|
||||
|
||||
!include "$(TOP)/glutwin32.mak"
|
||||
|
||||
glutdll : $(GLUTDLL)
|
||||
|
||||
!IFDEF NODEBUG
|
||||
OPTIMIZE_CFLAGS = -DNDEBUG
|
||||
!ENDIF
|
||||
|
||||
CFLAGS = $(cvarsdll) $(CFLAGS) $(OPTIMIZE_CFLAGS)
|
||||
LFLAGS = $(dlllflags) $(LFLAGS)
|
||||
|
||||
OBJS = $(SRCS:.c=.obj)
|
||||
MS_LIBS = $(MS_OPENGL) $(MS_GLU) winmm.lib $(guilibsdll)
|
||||
SGI_LIBS = $(SGI_OPENGL) $(SGI_GLU) winmm.lib $(guilibsdll)
|
||||
|
||||
glut32.dll : $(OBJS) glut.def
|
||||
$(link) $(LFLAGS) -out:glut32.dll -def:glut.def $(OBJS) $(MS_LIBS)
|
||||
|
||||
glut.dll : $(OBJS) glut.def
|
||||
$(link) $(LFLAGS) -out:glut.dll -def:glut.def $(OBJS) $(SGI_LIBS)
|
||||
|
||||
install : $(GLUTDLL)
|
||||
@echo "copying GLUT dynamic link library to system directory..."
|
||||
-copy $(GLUTDLL) $(DLLINSTALL)
|
||||
@echo "copying GLUT header file to include directory..."
|
||||
-copy ..\..\include\GL\glut.h $(INCLUDEINSTALL)
|
||||
@echo "copying GLUT import library to library directory..."
|
||||
-copy $(GLUTLIB) $(LIBINSTALL)
|
||||
|
||||
.c.obj :
|
||||
$(cc) $(CFLAGS) -I . $*.c
|
||||
|
||||
# explicit object dependencies for all source files
|
||||
|
||||
win32_glx.obj: win32_glx.c win32_glx.h
|
||||
win32_x11.obj: win32_x11.c win32_x11.h
|
||||
win32_menu.obj: win32_menu.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h
|
||||
win32_util.obj: win32_util.c glutint.h ..\..\include\GL\glutf90.h
|
||||
win32_winproc.obj: win32_winproc.c glutint.h ..\..\include\GL\glutf90.h
|
||||
|
||||
glut_mroman.obj: glut_mroman.c glutstroke.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_roman.obj: glut_roman.c glutstroke.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_hel12.obj: glut_hel12.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_8x13.obj: glut_8x13.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_hel18.obj: glut_hel18.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_9x15.obj: glut_9x15.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_tr10.obj: glut_tr10.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_hel10.obj: glut_hel10.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
glut_tr24.obj: glut_tr24.c glutbitmap.h glutint.h ..\..\include\GL\glutf90.h
|
||||
|
||||
glut_bitmap.obj: glut_bitmap.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_bwidth.obj: glut_bwidth.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_cindex.obj: glut_cindex.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_cmap.obj: glut_cmap.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_cursor.obj: glut_cursor.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_dials.obj: glut_dials.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_dstr.obj: glut_dstr.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_event.obj: glut_event.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_ext.obj: glut_ext.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_fullscrn.obj: glut_fullscrn.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_gamemode.obj: glut_gamemode.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_get.obj: glut_get.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_init.obj: glut_init.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_input.obj: glut_input.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_joy.obj: glut_joy.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_key.obj: glut_key.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_keyctrl.obj: glut_keyctrl.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_keyup.obj: glut_keyup.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_mesa.obj: glut_mesa.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_modifier.obj: glut_modifier.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_overlay.obj: glut_overlay.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_shapes.obj: glut_shapes.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_space.obj: glut_space.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_swap.obj: glut_swap.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_swidth.obj: glut_swidth.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_tablet.obj: glut_tablet.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_teapot.obj: glut_teapot.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_util.obj: glut_util.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_vidresize.obj: glut_vidresize.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_warp.obj: glut_warp.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
glut_win.obj: glut_win.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h
|
||||
glut_winmisc.obj: glut_winmisc.c glutint.h ..\..\include\GL\glutf90.h ..\..\include\GL\glut.h glutwin32.h win32_glx.h win32_x11.h
|
||||
|
||||
352
src/glut/glx/capturexfont.c
Normal file
352
src/glut/glx/capturexfont.c
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
/* capturexfont.c connects to an X server and downloads a
|
||||
bitmap font from which a C source file is generated,
|
||||
encoding the font for GLUT's use. Example usage:
|
||||
capturexfont.c 9x15 glutBitmap9By15 > glut_9x15.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <GL/gl.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#define MAX_GLYPHS_PER_GRAB 512 /* This is big enough for 2^9
|
||||
glyph character sets */
|
||||
|
||||
static void
|
||||
outputChar(int num, int width, int height,
|
||||
int xoff, int yoff, int advance, int data)
|
||||
{
|
||||
if (width == 0 || height == 0) {
|
||||
printf("#ifdef _WIN32\n");
|
||||
printf("/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with\n");
|
||||
printf(" a height or width of zero does not advance the raster position\n");
|
||||
printf(" as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */\n");
|
||||
printf("static const GLubyte ch%ddata[] = { 0x0 };\n", num);
|
||||
printf("static const BitmapCharRec ch%d = {", num);
|
||||
printf("%d,", 0);
|
||||
printf("%d,", 0);
|
||||
printf("%d,", xoff);
|
||||
printf("%d,", yoff);
|
||||
printf("%d,", advance);
|
||||
printf("ch%ddata", num);
|
||||
printf("};\n");
|
||||
printf("#else\n");
|
||||
}
|
||||
printf("static const BitmapCharRec ch%d = {", num);
|
||||
printf("%d,", width);
|
||||
printf("%d,", height);
|
||||
printf("%d,", xoff);
|
||||
printf("%d,", yoff);
|
||||
printf("%d,", advance);
|
||||
if (data) {
|
||||
printf("ch%ddata", num);
|
||||
} else {
|
||||
printf("0");
|
||||
}
|
||||
printf("};\n");
|
||||
if (width == 0 || height == 0) {
|
||||
printf("#endif\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Can't just use isprint because it only works for the range
|
||||
of ASCII characters (ie, TRUE for isascii) and capturexfont
|
||||
might be run on 16-bit fonts. */
|
||||
#define PRINTABLE(ch) (isascii(ch) ? isprint(ch) : 0)
|
||||
|
||||
void
|
||||
captureXFont(Display * dpy, Font font, char *xfont, char *name)
|
||||
{
|
||||
int first, last, count;
|
||||
int cnt, len;
|
||||
Pixmap offscreen;
|
||||
Window drawable;
|
||||
XFontStruct *fontinfo;
|
||||
XImage *image;
|
||||
GC xgc;
|
||||
XGCValues values;
|
||||
int width, height;
|
||||
int i, j, k;
|
||||
XCharStruct *charinfo;
|
||||
XChar2b character;
|
||||
GLubyte *bitmapData;
|
||||
int x, y;
|
||||
int spanLength;
|
||||
int charWidth, charHeight, maxSpanLength, pixwidth;
|
||||
int grabList[MAX_GLYPHS_PER_GRAB];
|
||||
int glyphsPerGrab = MAX_GLYPHS_PER_GRAB;
|
||||
int numToGrab;
|
||||
int rows, pages, byte1, byte2, index;
|
||||
int nullBitmap;
|
||||
|
||||
drawable = RootWindow(dpy, DefaultScreen(dpy));
|
||||
|
||||
fontinfo = XQueryFont(dpy, font);
|
||||
pages = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1;
|
||||
first = (fontinfo->min_byte1 << 8) + fontinfo->min_char_or_byte2;
|
||||
last = (fontinfo->max_byte1 << 8) + fontinfo->max_char_or_byte2;
|
||||
count = last - first + 1;
|
||||
|
||||
width = fontinfo->max_bounds.rbearing -
|
||||
fontinfo->min_bounds.lbearing;
|
||||
height = fontinfo->max_bounds.ascent +
|
||||
fontinfo->max_bounds.descent;
|
||||
/* 16-bit fonts have more than one row; indexing into
|
||||
per_char is trickier. */
|
||||
rows = fontinfo->max_byte1 - fontinfo->min_byte1 + 1;
|
||||
|
||||
maxSpanLength = (width + 7) / 8;
|
||||
/* For portability reasons we don't use alloca for
|
||||
bitmapData, but we could. */
|
||||
bitmapData = malloc(height * maxSpanLength);
|
||||
/* Be careful determining the width of the pixmap; the X
|
||||
protocol allows pixmaps of width 2^16-1 (unsigned short
|
||||
size) but drawing coordinates max out at 2^15-1 (signed
|
||||
short size). If the width is too large, we need to limit
|
||||
the glyphs per grab. */
|
||||
if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) {
|
||||
glyphsPerGrab = (1 << 15) / (8 * maxSpanLength);
|
||||
}
|
||||
pixwidth = glyphsPerGrab * 8 * maxSpanLength;
|
||||
offscreen = XCreatePixmap(dpy, drawable, pixwidth, height, 1);
|
||||
|
||||
values.font = font;
|
||||
values.background = 0;
|
||||
values.foreground = 0;
|
||||
xgc = XCreateGC(dpy, offscreen,
|
||||
GCFont | GCBackground | GCForeground, &values);
|
||||
XFillRectangle(dpy, offscreen, xgc, 0, 0,
|
||||
8 * maxSpanLength * glyphsPerGrab, height);
|
||||
XSetForeground(dpy, xgc, 1);
|
||||
|
||||
numToGrab = 0;
|
||||
if (fontinfo->per_char == NULL) {
|
||||
charinfo = &(fontinfo->min_bounds);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
spanLength = (charWidth + 7) / 8;
|
||||
}
|
||||
printf("\n/* GENERATED FILE -- DO NOT MODIFY */\n\n");
|
||||
printf("#include \"glutbitmap.h\"\n\n");
|
||||
for (i = first; count; i++, count--) {
|
||||
int undefined;
|
||||
if (rows == 1) {
|
||||
undefined = (fontinfo->min_char_or_byte2 > i ||
|
||||
fontinfo->max_char_or_byte2 < i);
|
||||
} else {
|
||||
byte2 = i & 0xff;
|
||||
byte1 = i >> 8;
|
||||
undefined = (fontinfo->min_char_or_byte2 > byte2 ||
|
||||
fontinfo->max_char_or_byte2 < byte2 ||
|
||||
fontinfo->min_byte1 > byte1 ||
|
||||
fontinfo->max_byte1 < byte1);
|
||||
|
||||
}
|
||||
if (undefined) {
|
||||
goto PossiblyDoGrab;
|
||||
}
|
||||
if (fontinfo->per_char != NULL) {
|
||||
if (rows == 1) {
|
||||
index = i - fontinfo->min_char_or_byte2;
|
||||
} else {
|
||||
byte2 = i & 0xff;
|
||||
byte1 = i >> 8;
|
||||
index =
|
||||
(byte1 - fontinfo->min_byte1) * pages +
|
||||
(byte2 - fontinfo->min_char_or_byte2);
|
||||
}
|
||||
charinfo = &(fontinfo->per_char[index]);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
if (charWidth == 0 || charHeight == 0) {
|
||||
if (charinfo->width != 0) {
|
||||
/* Still must move raster pos even if empty character
|
||||
|
||||
*/
|
||||
outputChar(i, 0, 0, 0, 0, charinfo->width, 0);
|
||||
}
|
||||
goto PossiblyDoGrab;
|
||||
}
|
||||
}
|
||||
grabList[numToGrab] = i;
|
||||
character.byte2 = i & 255;
|
||||
character.byte1 = i >> 8;
|
||||
|
||||
/* XXX We could use XDrawImageString16 which would also
|
||||
paint the backing rectangle but X server bugs in some
|
||||
scalable font rasterizers makes it more effective to do
|
||||
XFillRectangles to clear the pixmap and then
|
||||
XDrawImage16 for the text. */
|
||||
XDrawString16(dpy, offscreen, xgc,
|
||||
-charinfo->lbearing + 8 * maxSpanLength * numToGrab,
|
||||
charinfo->ascent, &character, 1);
|
||||
|
||||
numToGrab++;
|
||||
|
||||
PossiblyDoGrab:
|
||||
|
||||
if (numToGrab >= glyphsPerGrab || count == 1) {
|
||||
image = XGetImage(dpy, offscreen,
|
||||
0, 0, pixwidth, height, 1, XYPixmap);
|
||||
for (j = numToGrab - 1; j >= 0; j--) {
|
||||
if (fontinfo->per_char != NULL) {
|
||||
byte2 = grabList[j] & 0xff;
|
||||
byte1 = grabList[j] >> 8;
|
||||
index =
|
||||
(byte1 - fontinfo->min_byte1) * pages +
|
||||
(byte2 - fontinfo->min_char_or_byte2);
|
||||
charinfo = &(fontinfo->per_char[index]);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
spanLength = (charWidth + 7) / 8;
|
||||
}
|
||||
memset(bitmapData, 0, height * spanLength);
|
||||
for (y = 0; y < charHeight; y++) {
|
||||
for (x = 0; x < charWidth; x++) {
|
||||
if (XGetPixel(image, j * maxSpanLength * 8 + x,
|
||||
charHeight - 1 - y)) {
|
||||
/* Little endian machines (such as DEC Alpha)
|
||||
could benefit from reversing the bit order
|
||||
here and changing the GL_UNPACK_LSB_FIRST
|
||||
parameter in glutBitmapCharacter to GL_TRUE. */
|
||||
bitmapData[y * spanLength + x / 8] |=
|
||||
(1 << (7 - (x & 7)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PRINTABLE(grabList[j])) {
|
||||
printf("/* char: 0x%x '%c' */\n\n",
|
||||
grabList[j], grabList[j]);
|
||||
} else {
|
||||
printf("/* char: 0x%x */\n\n", grabList[j]);
|
||||
}
|
||||
|
||||
/* Determine if the bitmap is null. */
|
||||
nullBitmap = 1;
|
||||
len = (charinfo->ascent + charinfo->descent) *
|
||||
((charinfo->rbearing - charinfo->lbearing + 7) / 8);
|
||||
cnt = 0;
|
||||
while (cnt < len) {
|
||||
for (k = 0; k < 16 && cnt < len; k++, cnt++) {
|
||||
if (bitmapData[cnt] != 0) {
|
||||
nullBitmap = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!nullBitmap) {
|
||||
printf("static const GLubyte ch%ddata[] = {\n", grabList[j]);
|
||||
len = (charinfo->ascent + charinfo->descent) *
|
||||
((charinfo->rbearing - charinfo->lbearing + 7) / 8);
|
||||
cnt = 0;
|
||||
while (cnt < len) {
|
||||
for (k = 0; k < 16 && cnt < len; k++, cnt++) {
|
||||
printf("0x%x,", bitmapData[cnt]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
} else {
|
||||
charWidth = 0;
|
||||
charHeight = 0;
|
||||
}
|
||||
|
||||
outputChar(grabList[j], charWidth, charHeight,
|
||||
-charinfo->lbearing, charinfo->descent,
|
||||
charinfo->width, !nullBitmap);
|
||||
}
|
||||
XDestroyImage(image);
|
||||
numToGrab = 0;
|
||||
if (count > 0) {
|
||||
XSetForeground(dpy, xgc, 0);
|
||||
XFillRectangle(dpy, offscreen, xgc, 0, 0,
|
||||
8 * maxSpanLength * glyphsPerGrab, height);
|
||||
XSetForeground(dpy, xgc, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
XFreeGC(dpy, xgc);
|
||||
XFreePixmap(dpy, offscreen);
|
||||
/* For portability reasons we don't use alloca for
|
||||
bitmapData, but we could. */
|
||||
free(bitmapData);
|
||||
|
||||
printf("static const BitmapCharRec * const chars[] = {\n");
|
||||
for (i = first; i <= last; i++) {
|
||||
int undefined;
|
||||
byte2 = i & 0xff;
|
||||
byte1 = i >> 8;
|
||||
undefined = (fontinfo->min_char_or_byte2 > byte2 ||
|
||||
fontinfo->max_char_or_byte2 < byte2 ||
|
||||
fontinfo->min_byte1 > byte1 ||
|
||||
fontinfo->max_byte1 < byte1);
|
||||
if (undefined) {
|
||||
printf("0,\n");
|
||||
} else {
|
||||
if (fontinfo->per_char != NULL) {
|
||||
if (rows == 1) {
|
||||
index = i - fontinfo->min_char_or_byte2;
|
||||
} else {
|
||||
byte2 = i & 0xff;
|
||||
byte1 = i >> 8;
|
||||
index =
|
||||
(byte1 - fontinfo->min_byte1) * pages +
|
||||
(byte2 - fontinfo->min_char_or_byte2);
|
||||
}
|
||||
charinfo = &(fontinfo->per_char[index]);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
if (charWidth == 0 || charHeight == 0) {
|
||||
if (charinfo->width == 0) {
|
||||
printf("0,\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("&ch%d,\n", i);
|
||||
}
|
||||
}
|
||||
printf("};\n\n");
|
||||
printf("const BitmapFontRec %s = {\n", name);
|
||||
printf("\"%s\",\n", xfont);
|
||||
printf("%d,\n", last - first + 1);
|
||||
printf("%d,\n", first);
|
||||
printf("chars\n");
|
||||
printf("};\n\n");
|
||||
XFreeFont(dpy, fontinfo);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Display *dpy;
|
||||
Font font;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: capturexfont XFONT NAME\n");
|
||||
exit(1);
|
||||
}
|
||||
dpy = XOpenDisplay(NULL);
|
||||
if (dpy == NULL) {
|
||||
fprintf(stderr, "capturexfont: could not open X display\n");
|
||||
exit(1);
|
||||
}
|
||||
font = XLoadFont(dpy, argv[1]);
|
||||
if (font == None) {
|
||||
fprintf(stderr, "capturexfont: bad font\n");
|
||||
exit(1);
|
||||
}
|
||||
captureXFont(dpy, font, argv[1], argv[2]);
|
||||
XCloseDisplay(dpy);
|
||||
return 0;
|
||||
}
|
||||
127
src/glut/glx/descrip.mms
Normal file
127
src/glut/glx/descrip.mms
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# Makefile for GLUT for VMS
|
||||
# contributed by Jouk Jansen joukj@crys.chem.uva.nl
|
||||
|
||||
.first
|
||||
define gl [-.include.gl]
|
||||
|
||||
.include [-]mms-config.
|
||||
|
||||
##### MACROS #####
|
||||
GLUT_MAJOR = 3
|
||||
GLUT_MINOR = 7
|
||||
|
||||
VPATH = RCS
|
||||
|
||||
INCDIR = [-.include]
|
||||
LIBDIR = [-.lib]
|
||||
CFLAGS = /nowarn/include=$(INCDIR)/prefix=all
|
||||
|
||||
SOURCES = \
|
||||
glut_8x13.c \
|
||||
glut_9x15.c \
|
||||
glut_bitmap.c \
|
||||
glut_bwidth.c \
|
||||
glut_cindex.c \
|
||||
glut_cmap.c \
|
||||
glut_cursor.c \
|
||||
glut_dials.c \
|
||||
glut_dstr.c \
|
||||
glut_event.c \
|
||||
glut_ext.c \
|
||||
glut_fullscrn.c \
|
||||
glut_gamemode.c \
|
||||
glut_get.c \
|
||||
glut_glxext.c \
|
||||
glut_hel10.c \
|
||||
glut_hel12.c \
|
||||
glut_hel18.c \
|
||||
glut_init.c \
|
||||
glut_input.c \
|
||||
glut_joy.c \
|
||||
glut_key.c \
|
||||
glut_keyctrl.c \
|
||||
glut_keyup.c \
|
||||
glut_menu.c \
|
||||
glut_menu2.c \
|
||||
glut_mesa.c \
|
||||
glut_modifier.c \
|
||||
glut_mroman.c \
|
||||
glut_overlay.c \
|
||||
glut_roman.c \
|
||||
glut_shapes.c \
|
||||
glut_space.c \
|
||||
glut_stroke.c \
|
||||
glut_swap.c \
|
||||
glut_swidth.c \
|
||||
glut_tablet.c \
|
||||
glut_teapot.c \
|
||||
glut_tr10.c \
|
||||
glut_tr24.c \
|
||||
glut_util.c \
|
||||
glut_vidresize.c \
|
||||
glut_warp.c \
|
||||
glut_win.c \
|
||||
glut_winmisc.c \
|
||||
layerutil.c
|
||||
|
||||
OBJECTS = \
|
||||
glut_8x13.obj,\
|
||||
glut_9x15.obj,\
|
||||
glut_bitmap.obj,\
|
||||
glut_bwidth.obj,\
|
||||
glut_cindex.obj,\
|
||||
glut_cmap.obj,\
|
||||
glut_cursor.obj,\
|
||||
glut_dials.obj,\
|
||||
glut_dstr.obj,\
|
||||
glut_event.obj,\
|
||||
glut_ext.obj,\
|
||||
glut_fullscrn.obj,\
|
||||
glut_gamemode.obj,\
|
||||
glut_get.obj,\
|
||||
glut_glxext.obj,\
|
||||
glut_hel10.obj,\
|
||||
glut_hel12.obj,\
|
||||
glut_hel18.obj,\
|
||||
glut_init.obj,\
|
||||
glut_input.obj,\
|
||||
glut_joy.obj,\
|
||||
glut_key.obj,\
|
||||
glut_keyctrl.obj,\
|
||||
glut_keyup.obj,\
|
||||
glut_menu.obj,\
|
||||
glut_menu2.obj,\
|
||||
glut_mesa.obj,\
|
||||
glut_modifier.obj,\
|
||||
glut_mroman.obj,\
|
||||
glut_overlay.obj,\
|
||||
glut_roman.obj,\
|
||||
glut_shapes.obj,\
|
||||
glut_space.obj,\
|
||||
glut_stroke.obj,\
|
||||
glut_swap.obj,\
|
||||
glut_swidth.obj,\
|
||||
glut_tablet.obj,\
|
||||
glut_teapot.obj,\
|
||||
glut_tr10.obj,\
|
||||
glut_tr24.obj,\
|
||||
glut_util.obj,\
|
||||
glut_vidresize.obj,\
|
||||
glut_warp.obj,\
|
||||
glut_win.obj,\
|
||||
glut_winmisc.obj,\
|
||||
layerutil.obj
|
||||
|
||||
##### RULES #####
|
||||
|
||||
##### TARGETS #####
|
||||
|
||||
# Make the library:
|
||||
$(LIBDIR)$(GLUT_LIB) : $(OBJECTS)
|
||||
$(MAKELIB) $(GLUT_LIB) $(OBJECTS)
|
||||
rename $(GLUT_LIB)* $(LIBDIR)
|
||||
clean :
|
||||
delete *.obj;*
|
||||
purge
|
||||
|
||||
include mms_depend.
|
||||
103
src/glut/glx/fxglut.def
Normal file
103
src/glut/glx/fxglut.def
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
EXPORTS
|
||||
glutInit
|
||||
glutInitDisplayMode
|
||||
glutInitDisplayString
|
||||
glutInitWindowPosition
|
||||
glutInitWindowSize
|
||||
glutMainLoop
|
||||
glutCreateWindow
|
||||
glutCreateSubWindow
|
||||
glutDestroyWindow
|
||||
glutPostRedisplay
|
||||
glutSwapBuffers
|
||||
glutGetWindow
|
||||
glutSetWindow
|
||||
glutSetWindowTitle
|
||||
glutSetIconTitle
|
||||
glutPositionWindow
|
||||
glutReshapeWindow
|
||||
glutPopWindow
|
||||
glutPushWindow
|
||||
glutIconifyWindow
|
||||
glutShowWindow
|
||||
glutHideWindow
|
||||
glutFullScreen
|
||||
glutSetCursor
|
||||
glutWarpPointer
|
||||
glutEstablishOverlay
|
||||
glutRemoveOverlay
|
||||
glutUseLayer
|
||||
glutPostOverlayRedisplay
|
||||
glutShowOverlay
|
||||
glutHideOverlay
|
||||
glutCreateMenu
|
||||
glutDestroyMenu
|
||||
glutGetMenu
|
||||
glutSetMenu
|
||||
glutAddMenuEntry
|
||||
glutAddSubMenu
|
||||
glutChangeToMenuEntry
|
||||
glutChangeToSubMenu
|
||||
glutRemoveMenuItem
|
||||
glutAttachMenu
|
||||
glutDetachMenu
|
||||
glutDisplayFunc
|
||||
glutReshapeFunc
|
||||
glutKeyboardFunc
|
||||
glutMouseFunc
|
||||
glutMotionFunc
|
||||
glutPassiveMotionFunc
|
||||
glutEntryFunc
|
||||
glutVisibilityFunc
|
||||
glutIdleFunc
|
||||
glutTimerFunc
|
||||
glutMenuStateFunc
|
||||
glutSpecialFunc
|
||||
glutSpaceballMotionFunc
|
||||
glutSpaceballRotateFunc
|
||||
glutSpaceballButtonFunc
|
||||
glutButtonBoxFunc
|
||||
glutDialsFunc
|
||||
glutTabletMotionFunc
|
||||
glutTabletButtonFunc
|
||||
glutMenuStatusFunc
|
||||
glutOverlayDisplayFunc
|
||||
glutWindowStatusFunc
|
||||
glutSetColor
|
||||
glutGetColor
|
||||
glutCopyColormap
|
||||
glutGet
|
||||
glutDeviceGet
|
||||
glutExtensionSupported
|
||||
glutGetModifiers
|
||||
glutLayerGet
|
||||
glutBitmapCharacter
|
||||
glutBitmapWidth
|
||||
glutStrokeCharacter
|
||||
glutStrokeWidth
|
||||
glutBitmapLength
|
||||
glutStrokeLength
|
||||
glutWireSphere
|
||||
glutSolidSphere
|
||||
glutWireCone
|
||||
glutSolidCone
|
||||
glutWireCube
|
||||
glutSolidCube
|
||||
glutWireTorus
|
||||
glutSolidTorus
|
||||
glutWireDodecahedron
|
||||
glutSolidDodecahedron
|
||||
glutWireTeapot
|
||||
glutSolidTeapot
|
||||
glutWireOctahedron
|
||||
glutSolidOctahedron
|
||||
glutWireTetrahedron
|
||||
glutSolidTetrahedron
|
||||
glutWireIcosahedron
|
||||
glutSolidIcosahedron
|
||||
glutVideoResizeGet
|
||||
glutSetupVideoResizing
|
||||
glutStopVideoResizing
|
||||
glutVideoResize
|
||||
glutVideoPan
|
||||
glutReportErrors
|
||||
2073
src/glut/glx/glut_8x13.c
Normal file
2073
src/glut/glx/glut_8x13.c
Normal file
File diff suppressed because it is too large
Load diff
2075
src/glut/glx/glut_9x15.c
Normal file
2075
src/glut/glx/glut_9x15.c
Normal file
File diff suppressed because it is too large
Load diff
57
src/glut/glx/glut_bitmap.c
Normal file
57
src/glut/glx/glut_bitmap.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
#include "glutbitmap.h"
|
||||
|
||||
void APIENTRY
|
||||
glutBitmapCharacter(GLUTbitmapFont font, int c)
|
||||
{
|
||||
const BitmapCharRec *ch;
|
||||
BitmapFontPtr fontinfo;
|
||||
GLint swapbytes, lsbfirst, rowlength;
|
||||
GLint skiprows, skippixels, alignment;
|
||||
|
||||
#if defined(_WIN32)
|
||||
fontinfo = (BitmapFontPtr) __glutFont(font);
|
||||
#else
|
||||
fontinfo = (BitmapFontPtr) font;
|
||||
#endif
|
||||
|
||||
if (c < fontinfo->first ||
|
||||
c >= fontinfo->first + fontinfo->num_chars)
|
||||
return;
|
||||
ch = fontinfo->ch[c - fontinfo->first];
|
||||
if (ch) {
|
||||
/* Save current modes. */
|
||||
glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
|
||||
glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
|
||||
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
|
||||
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
|
||||
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||
/* Little endian machines (DEC Alpha for example) could
|
||||
benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE
|
||||
instead of GL_FALSE, but this would require changing the
|
||||
generated bitmaps too. */
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glBitmap(ch->width, ch->height, ch->xorig, ch->yorig,
|
||||
ch->advance, 0, ch->bitmap);
|
||||
/* Restore saved modes. */
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
||||
}
|
||||
}
|
||||
58
src/glut/glx/glut_bwidth.c
Normal file
58
src/glut/glx/glut_bwidth.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
#include "glutbitmap.h"
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutBitmapWidth(GLUTbitmapFont font, int c)
|
||||
{
|
||||
BitmapFontPtr fontinfo;
|
||||
const BitmapCharRec *ch;
|
||||
|
||||
#ifdef _WIN32
|
||||
fontinfo = (BitmapFontPtr) __glutFont(font);
|
||||
#else
|
||||
fontinfo = (BitmapFontPtr) font;
|
||||
#endif
|
||||
|
||||
if (c < fontinfo->first || c >= fontinfo->first + fontinfo->num_chars)
|
||||
return 0;
|
||||
ch = fontinfo->ch[c - fontinfo->first];
|
||||
if (ch)
|
||||
return ch->advance;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutBitmapLength(GLUTbitmapFont font, const unsigned char *string)
|
||||
{
|
||||
int c, length;
|
||||
BitmapFontPtr fontinfo;
|
||||
const BitmapCharRec *ch;
|
||||
|
||||
#ifdef _WIN32
|
||||
fontinfo = (BitmapFontPtr) __glutFont(font);
|
||||
#else
|
||||
fontinfo = (BitmapFontPtr) font;
|
||||
#endif
|
||||
|
||||
length = 0;
|
||||
for (; *string != '\0'; string++) {
|
||||
c = *string;
|
||||
if (c >= fontinfo->first && c < fontinfo->first + fontinfo->num_chars) {
|
||||
ch = fontinfo->ch[c - fontinfo->first];
|
||||
if (ch)
|
||||
length += ch->advance;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
252
src/glut/glx/glut_cindex.c
Normal file
252
src/glut/glx/glut_cindex.c
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "glutint.h"
|
||||
|
||||
#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
|
||||
{
|
||||
GLUTcolormap *cmap, *newcmap;
|
||||
XVisualInfo *vis;
|
||||
XColor color;
|
||||
int i;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
cmap = __glutCurrentWindow->colormap;
|
||||
vis = __glutCurrentWindow->vis;
|
||||
} else {
|
||||
cmap = __glutCurrentWindow->overlay->colormap;
|
||||
vis = __glutCurrentWindow->overlay->vis;
|
||||
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
|
||||
__glutWarning(
|
||||
"glutSetColor: cannot set color of overlay transparent index %d\n",
|
||||
ndx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmap) {
|
||||
__glutWarning("glutSetColor: current window is RGBA");
|
||||
return;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
if (ndx >= 256 || /* always assume 256 colors on Win32 */
|
||||
#else
|
||||
if (ndx >= vis->visual->map_entries ||
|
||||
#endif
|
||||
ndx < 0) {
|
||||
__glutWarning("glutSetColor: index %d out of range", ndx);
|
||||
return;
|
||||
}
|
||||
if (cmap->refcnt > 1) {
|
||||
newcmap = __glutAssociateNewColormap(vis);
|
||||
cmap->refcnt--;
|
||||
/* Wouldn't it be nice if XCopyColormapAndFree could be
|
||||
told not to free the old colormap's entries! */
|
||||
for (i = cmap->size - 1; i >= 0; i--) {
|
||||
if (i == ndx) {
|
||||
/* We are going to set this cell shortly! */
|
||||
continue;
|
||||
}
|
||||
if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
|
||||
color.pixel = i;
|
||||
newcmap->cells[i].component[GLUT_RED] =
|
||||
cmap->cells[i].component[GLUT_RED];
|
||||
color.red = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_RED];
|
||||
newcmap->cells[i].component[GLUT_GREEN] =
|
||||
cmap->cells[i].component[GLUT_GREEN];
|
||||
color.green = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_GREEN];
|
||||
newcmap->cells[i].component[GLUT_BLUE] =
|
||||
cmap->cells[i].component[GLUT_BLUE];
|
||||
color.blue = (GLfloat) 0xffff *
|
||||
cmap->cells[i].component[GLUT_BLUE];
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
#if defined(_WIN32)
|
||||
if (IsWindowVisible(__glutCurrentWindow->win)) {
|
||||
XHDC = __glutCurrentWindow->hdc;
|
||||
} else {
|
||||
XHDC = 0;
|
||||
}
|
||||
#endif
|
||||
XStoreColor(__glutDisplay, newcmap->cmap, &color);
|
||||
} else {
|
||||
/* Leave unallocated entries unallocated. */
|
||||
}
|
||||
}
|
||||
cmap = newcmap;
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
__glutCurrentWindow->colormap = cmap;
|
||||
__glutCurrentWindow->cmap = cmap->cmap;
|
||||
} else {
|
||||
__glutCurrentWindow->overlay->colormap = cmap;
|
||||
__glutCurrentWindow->overlay->cmap = cmap->cmap;
|
||||
}
|
||||
XSetWindowColormap(__glutDisplay,
|
||||
__glutCurrentWindow->renderWin, cmap->cmap);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
{
|
||||
GLUTwindow *toplevel;
|
||||
|
||||
toplevel = __glutToplevelOf(__glutCurrentWindow);
|
||||
if (toplevel->cmap != cmap->cmap) {
|
||||
__glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
color.pixel = ndx;
|
||||
red = CLAMP(red);
|
||||
cmap->cells[ndx].component[GLUT_RED] = red;
|
||||
color.red = (GLfloat) 0xffff *red;
|
||||
green = CLAMP(green);
|
||||
cmap->cells[ndx].component[GLUT_GREEN] = green;
|
||||
color.green = (GLfloat) 0xffff *green;
|
||||
blue = CLAMP(blue);
|
||||
cmap->cells[ndx].component[GLUT_BLUE] = blue;
|
||||
color.blue = (GLfloat) 0xffff *blue;
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
#if defined(_WIN32)
|
||||
if (IsWindowVisible(__glutCurrentWindow->win)) {
|
||||
XHDC = __glutCurrentWindow->hdc;
|
||||
} else {
|
||||
XHDC = 0;
|
||||
}
|
||||
#endif
|
||||
XStoreColor(__glutDisplay, cmap->cmap, &color);
|
||||
}
|
||||
|
||||
GLfloat APIENTRY
|
||||
glutGetColor(int ndx, int comp)
|
||||
{
|
||||
GLUTcolormap *colormap;
|
||||
XVisualInfo *vis;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
colormap = __glutCurrentWindow->colormap;
|
||||
vis = __glutCurrentWindow->vis;
|
||||
} else {
|
||||
colormap = __glutCurrentWindow->overlay->colormap;
|
||||
vis = __glutCurrentWindow->overlay->vis;
|
||||
if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
|
||||
__glutWarning("glutGetColor: requesting overlay transparent index %d\n",
|
||||
ndx);
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!colormap) {
|
||||
__glutWarning("glutGetColor: current window is RGBA");
|
||||
return -1.0;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)
|
||||
#else
|
||||
#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)
|
||||
#endif
|
||||
if (OUT_OF_RANGE_NDX(ndx)) {
|
||||
__glutWarning("glutGetColor: index %d out of range", ndx);
|
||||
return -1.0;
|
||||
}
|
||||
return colormap->cells[ndx].component[comp];
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutCopyColormap(int winnum)
|
||||
{
|
||||
GLUTwindow *window = __glutWindowList[winnum - 1];
|
||||
GLUTcolormap *oldcmap, *newcmap;
|
||||
XVisualInfo *dstvis;
|
||||
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
oldcmap = __glutCurrentWindow->colormap;
|
||||
dstvis = __glutCurrentWindow->vis;
|
||||
newcmap = window->colormap;
|
||||
} else {
|
||||
oldcmap = __glutCurrentWindow->overlay->colormap;
|
||||
dstvis = __glutCurrentWindow->overlay->vis;
|
||||
if (!window->overlay) {
|
||||
__glutWarning("glutCopyColormap: window %d has no overlay", winnum);
|
||||
return;
|
||||
}
|
||||
newcmap = window->overlay->colormap;
|
||||
}
|
||||
|
||||
if (!oldcmap) {
|
||||
__glutWarning("glutCopyColormap: destination colormap must be color index");
|
||||
return;
|
||||
}
|
||||
if (!newcmap) {
|
||||
__glutWarning(
|
||||
"glutCopyColormap: source colormap of window %d must be color index",
|
||||
winnum);
|
||||
return;
|
||||
}
|
||||
if (newcmap == oldcmap) {
|
||||
/* Source and destination are the same; now copy needed. */
|
||||
return;
|
||||
}
|
||||
#if !defined(_WIN32)
|
||||
/* Play safe: compare visual IDs, not Visual*'s. */
|
||||
if (newcmap->visual->visualid == oldcmap->visual->visualid) {
|
||||
#endif
|
||||
/* Visuals match! "Copy" by reference... */
|
||||
__glutFreeColormap(oldcmap);
|
||||
newcmap->refcnt++;
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
__glutCurrentWindow->colormap = newcmap;
|
||||
__glutCurrentWindow->cmap = newcmap->cmap;
|
||||
} else {
|
||||
__glutCurrentWindow->overlay->colormap = newcmap;
|
||||
__glutCurrentWindow->overlay->cmap = newcmap->cmap;
|
||||
}
|
||||
XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
|
||||
newcmap->cmap);
|
||||
#if !defined(_WIN32)
|
||||
__glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
|
||||
} else {
|
||||
GLUTcolormap *copycmap;
|
||||
XColor color;
|
||||
int i, last;
|
||||
|
||||
/* Visuals different - need a distinct X colormap! */
|
||||
copycmap = __glutAssociateNewColormap(dstvis);
|
||||
/* Wouldn't it be nice if XCopyColormapAndFree could be
|
||||
told not to free the old colormap's entries! */
|
||||
last = newcmap->size;
|
||||
if (last > copycmap->size) {
|
||||
last = copycmap->size;
|
||||
}
|
||||
for (i = last - 1; i >= 0; i--) {
|
||||
if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
|
||||
color.pixel = i;
|
||||
copycmap->cells[i].component[GLUT_RED] =
|
||||
newcmap->cells[i].component[GLUT_RED];
|
||||
color.red = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_RED];
|
||||
copycmap->cells[i].component[GLUT_GREEN] =
|
||||
newcmap->cells[i].component[GLUT_GREEN];
|
||||
color.green = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_GREEN];
|
||||
copycmap->cells[i].component[GLUT_BLUE] =
|
||||
newcmap->cells[i].component[GLUT_BLUE];
|
||||
color.blue = (GLfloat) 0xffff *
|
||||
newcmap->cells[i].component[GLUT_BLUE];
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
XStoreColor(__glutDisplay, copycmap->cmap, &color);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
395
src/glut/glx/glut_cmap.c
Normal file
395
src/glut/glx/glut_cmap.c
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* SunOS multithreaded assert() needs <stdio.h>. Lame. */
|
||||
#include <assert.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h> /* for XA_RGB_DEFAULT_MAP atom */
|
||||
#if defined(__vms)
|
||||
#include <Xmu/StdCmap.h> /* for XmuLookupStandardColormap */
|
||||
#else
|
||||
#include <X11/Xmu/StdCmap.h> /* for XmuLookupStandardColormap */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* SGI optimization introduced in IRIX 6.3 to avoid X server
|
||||
round trips for interning common X atoms. */
|
||||
#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
|
||||
#include <X11/SGIFastAtom.h>
|
||||
#else
|
||||
#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
|
||||
#endif
|
||||
|
||||
#include "glutint.h"
|
||||
#include "layerutil.h"
|
||||
|
||||
GLUTcolormap *__glutColormapList = NULL;
|
||||
|
||||
GLUTcolormap *
|
||||
__glutAssociateNewColormap(XVisualInfo * vis)
|
||||
{
|
||||
GLUTcolormap *cmap;
|
||||
int transparentPixel, i;
|
||||
unsigned long pixels[255];
|
||||
|
||||
cmap = (GLUTcolormap *) malloc(sizeof(GLUTcolormap));
|
||||
if (!cmap)
|
||||
__glutFatalError("out of memory.");
|
||||
#if defined(_WIN32)
|
||||
pixels[0] = 0; /* avoid compilation warnings on win32 */
|
||||
cmap->visual = 0;
|
||||
cmap->size = 256; /* always assume 256 on Win32 */
|
||||
#else
|
||||
cmap->visual = vis->visual;
|
||||
cmap->size = vis->visual->map_entries;
|
||||
#endif
|
||||
cmap->refcnt = 1;
|
||||
cmap->cells = (GLUTcolorcell *)
|
||||
malloc(sizeof(GLUTcolorcell) * cmap->size);
|
||||
if (!cmap->cells)
|
||||
__glutFatalError("out of memory.");
|
||||
/* make all color cell entries be invalid */
|
||||
for (i = cmap->size - 1; i >= 0; i--) {
|
||||
cmap->cells[i].component[GLUT_RED] = -1.0;
|
||||
cmap->cells[i].component[GLUT_GREEN] = -1.0;
|
||||
cmap->cells[i].component[GLUT_BLUE] = -1.0;
|
||||
}
|
||||
transparentPixel = __glutGetTransparentPixel(__glutDisplay, vis);
|
||||
if (transparentPixel == -1 || transparentPixel >= cmap->size) {
|
||||
|
||||
/* If there is no transparent pixel or if the transparent
|
||||
pixel is outside the range of valid colormap cells (HP
|
||||
can implement their overlays this smart way since their
|
||||
transparent pixel is 255), we can AllocAll the colormap.
|
||||
See note below. */
|
||||
|
||||
cmap->cmap = XCreateColormap(__glutDisplay,
|
||||
__glutRoot, cmap->visual, AllocAll);
|
||||
} else {
|
||||
|
||||
/* On machines where zero (or some other value in the range
|
||||
of 0 through map_entries-1), BadAlloc may be generated
|
||||
when an AllocAll overlay colormap is allocated since the
|
||||
transparent pixel precludes all the cells in the colormap
|
||||
being allocated (the transparent pixel is pre-allocated).
|
||||
So in this case, use XAllocColorCells to allocate
|
||||
map_entries-1 pixels (that is, all but the transparent
|
||||
pixel. */
|
||||
|
||||
#if defined(_WIN32)
|
||||
cmap->cmap = XCreateColormap(__glutDisplay,
|
||||
__glutRoot, 0, AllocNone);
|
||||
#else
|
||||
cmap->cmap = XCreateColormap(__glutDisplay,
|
||||
__glutRoot, vis->visual, AllocNone);
|
||||
XAllocColorCells(__glutDisplay, cmap->cmap, False, 0, 0,
|
||||
pixels, cmap->size - 1);
|
||||
#endif
|
||||
}
|
||||
cmap->next = __glutColormapList;
|
||||
__glutColormapList = cmap;
|
||||
return cmap;
|
||||
}
|
||||
|
||||
static GLUTcolormap *
|
||||
associateColormap(XVisualInfo * vis)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
GLUTcolormap *cmap = __glutColormapList;
|
||||
|
||||
while (cmap != NULL) {
|
||||
/* Play safe: compare visual IDs, not Visual*'s. */
|
||||
if (cmap->visual->visualid == vis->visual->visualid) {
|
||||
/* Already have created colormap for the visual. */
|
||||
cmap->refcnt++;
|
||||
return cmap;
|
||||
}
|
||||
cmap = cmap->next;
|
||||
}
|
||||
#endif
|
||||
return __glutAssociateNewColormap(vis);
|
||||
}
|
||||
|
||||
void
|
||||
__glutSetupColormap(XVisualInfo * vi, GLUTcolormap ** colormap, Colormap * cmap)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (vi->dwFlags & PFD_NEED_PALETTE || vi->iPixelType == PFD_TYPE_COLORINDEX) {
|
||||
*colormap = associateColormap(vi);
|
||||
*cmap = (*colormap)->cmap;
|
||||
} else {
|
||||
*colormap = NULL;
|
||||
*cmap = 0;
|
||||
}
|
||||
#else
|
||||
Status status;
|
||||
XStandardColormap *standardCmaps;
|
||||
int i, numCmaps;
|
||||
static Atom hpColorRecoveryAtom = -1;
|
||||
int isRGB, visualClass, rc;
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
visualClass = vi->c_class;
|
||||
#else
|
||||
visualClass = vi->class;
|
||||
#endif
|
||||
switch (visualClass) {
|
||||
case PseudoColor:
|
||||
/* Mesa might return a PseudoColor visual for RGB mode. */
|
||||
rc = glXGetConfig(__glutDisplay, vi, GLX_RGBA, &isRGB);
|
||||
if (rc == 0 && isRGB) {
|
||||
/* Must be Mesa. */
|
||||
*colormap = NULL;
|
||||
if (MaxCmapsOfScreen(DefaultScreenOfDisplay(__glutDisplay)) == 1
|
||||
&& vi->visual == DefaultVisual(__glutDisplay, __glutScreen)) {
|
||||
char *privateCmap = getenv("MESA_PRIVATE_CMAP");
|
||||
|
||||
if (privateCmap) {
|
||||
/* User doesn't want to share colormaps. */
|
||||
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
|
||||
vi->visual, AllocNone);
|
||||
} else {
|
||||
/* Share the root colormap. */
|
||||
*cmap = DefaultColormap(__glutDisplay, __glutScreen);
|
||||
}
|
||||
} else {
|
||||
/* Get our own PseudoColor colormap. */
|
||||
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
|
||||
vi->visual, AllocNone);
|
||||
}
|
||||
} else {
|
||||
/* CI mode, real GLX never returns a PseudoColor visual
|
||||
for RGB mode. */
|
||||
*colormap = associateColormap(vi);
|
||||
*cmap = (*colormap)->cmap;
|
||||
}
|
||||
break;
|
||||
case TrueColor:
|
||||
case DirectColor:
|
||||
*colormap = NULL; /* NULL if RGBA */
|
||||
|
||||
/* Hewlett-Packard supports a feature called "HP Color
|
||||
Recovery". Mesa has code to use HP Color Recovery. For
|
||||
Mesa to use this feature, the atom
|
||||
_HP_RGB_SMOOTH_MAP_LIST must be defined on the root
|
||||
window AND the colormap obtainable by XGetRGBColormaps
|
||||
for that atom must be set on the window. If that
|
||||
colormap is not set, the output will look stripy. */
|
||||
|
||||
if (hpColorRecoveryAtom == -1) {
|
||||
char *xvendor;
|
||||
|
||||
#define VENDOR_HP "Hewlett-Packard"
|
||||
|
||||
/* Only makes sense to make XInternAtom round-trip if we
|
||||
know that we are connected to an HP X server. */
|
||||
xvendor = ServerVendor(__glutDisplay);
|
||||
if (!strncmp(xvendor, VENDOR_HP, sizeof(VENDOR_HP) - 1)) {
|
||||
hpColorRecoveryAtom = XInternAtom(__glutDisplay, "_HP_RGB_SMOOTH_MAP_LIST", True);
|
||||
} else {
|
||||
hpColorRecoveryAtom = None;
|
||||
}
|
||||
}
|
||||
if (hpColorRecoveryAtom != None) {
|
||||
status = XGetRGBColormaps(__glutDisplay, __glutRoot,
|
||||
&standardCmaps, &numCmaps, hpColorRecoveryAtom);
|
||||
if (status == 1) {
|
||||
for (i = 0; i < numCmaps; i++) {
|
||||
if (standardCmaps[i].visualid == vi->visualid) {
|
||||
*cmap = standardCmaps[i].colormap;
|
||||
XFree(standardCmaps);
|
||||
return;
|
||||
}
|
||||
}
|
||||
XFree(standardCmaps);
|
||||
}
|
||||
}
|
||||
#ifndef SOLARIS_2_4_BUG
|
||||
/* Solaris 2.4 and 2.5 have a bug in their
|
||||
XmuLookupStandardColormap implementations. Please
|
||||
compile your Solaris 2.4 or 2.5 version of GLUT with
|
||||
-DSOLARIS_2_4_BUG to work around this bug. The symptom
|
||||
of the bug is that programs will get a BadMatch error
|
||||
from X_CreateWindow when creating a GLUT window because
|
||||
Solaris 2.4 and 2.5 create a corrupted RGB_DEFAULT_MAP
|
||||
property. Note that this workaround prevents Colormap
|
||||
sharing between applications, perhaps leading
|
||||
unnecessary colormap installations or colormap flashing.
|
||||
Sun fixed this bug in Solaris 2.6. */
|
||||
status = XmuLookupStandardColormap(__glutDisplay,
|
||||
vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP,
|
||||
/* replace */ False, /* retain */ True);
|
||||
if (status == 1) {
|
||||
status = XGetRGBColormaps(__glutDisplay, __glutRoot,
|
||||
&standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP);
|
||||
if (status == 1) {
|
||||
for (i = 0; i < numCmaps; i++) {
|
||||
if (standardCmaps[i].visualid == vi->visualid) {
|
||||
*cmap = standardCmaps[i].colormap;
|
||||
XFree(standardCmaps);
|
||||
return;
|
||||
}
|
||||
}
|
||||
XFree(standardCmaps);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* If no standard colormap but TrueColor, just make a
|
||||
private one. */
|
||||
/* XXX Should do a better job of internal sharing for
|
||||
privately allocated TrueColor colormaps. */
|
||||
/* XXX DirectColor probably needs ramps hand initialized! */
|
||||
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
|
||||
vi->visual, AllocNone);
|
||||
break;
|
||||
case StaticColor:
|
||||
case StaticGray:
|
||||
case GrayScale:
|
||||
/* Mesa supports these visuals */
|
||||
*colormap = NULL;
|
||||
*cmap = XCreateColormap(__glutDisplay, __glutRoot,
|
||||
vi->visual, AllocNone);
|
||||
break;
|
||||
default:
|
||||
__glutFatalError(
|
||||
"could not allocate colormap for visual type: %d.",
|
||||
visualClass);
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
static int
|
||||
findColormaps(GLUTwindow * window,
|
||||
Window * winlist, Colormap * cmaplist, int num, int max)
|
||||
{
|
||||
GLUTwindow *child;
|
||||
int i;
|
||||
|
||||
/* Do not allow more entries that maximum number of
|
||||
colormaps! */
|
||||
if (num >= max)
|
||||
return num;
|
||||
/* Is cmap for this window already on the list? */
|
||||
for (i = 0; i < num; i++) {
|
||||
if (cmaplist[i] == window->cmap)
|
||||
goto normalColormapAlreadyListed;
|
||||
}
|
||||
/* Not found on the list; add colormap and window. */
|
||||
winlist[num] = window->win;
|
||||
cmaplist[num] = window->cmap;
|
||||
num++;
|
||||
|
||||
normalColormapAlreadyListed:
|
||||
|
||||
/* Repeat above but for the overlay colormap if there one. */
|
||||
if (window->overlay) {
|
||||
if (num >= max)
|
||||
return num;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (cmaplist[i] == window->overlay->cmap)
|
||||
goto overlayColormapAlreadyListed;
|
||||
}
|
||||
winlist[num] = window->overlay->win;
|
||||
cmaplist[num] = window->overlay->cmap;
|
||||
num++;
|
||||
}
|
||||
overlayColormapAlreadyListed:
|
||||
|
||||
/* Recursively search children. */
|
||||
child = window->children;
|
||||
while (child) {
|
||||
num = findColormaps(child, winlist, cmaplist, num, max);
|
||||
child = child->siblings;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
void
|
||||
__glutEstablishColormapsProperty(GLUTwindow * window)
|
||||
{
|
||||
/* this routine is strictly X. Win32 doesn't need to do
|
||||
anything of this sort (but has to do other wacky stuff
|
||||
later). */
|
||||
static Atom wmColormapWindows = None;
|
||||
Window *winlist;
|
||||
Colormap *cmaplist;
|
||||
Status status;
|
||||
int maxcmaps, num;
|
||||
|
||||
assert(!window->parent);
|
||||
maxcmaps = MaxCmapsOfScreen(ScreenOfDisplay(__glutDisplay,
|
||||
__glutScreen));
|
||||
/* For portability reasons we don't use alloca for winlist
|
||||
and cmaplist, but we could. */
|
||||
winlist = (Window *) malloc(maxcmaps * sizeof(Window));
|
||||
cmaplist = (Colormap *) malloc(maxcmaps * sizeof(Colormap));
|
||||
num = findColormaps(window, winlist, cmaplist, 0, maxcmaps);
|
||||
if (num < 2) {
|
||||
/* Property no longer needed; remove it. */
|
||||
wmColormapWindows = XSGIFastInternAtom(__glutDisplay,
|
||||
"WM_COLORMAP_WINDOWS", SGI_XA_WM_COLORMAP_WINDOWS, False);
|
||||
if (wmColormapWindows == None) {
|
||||
__glutWarning("Could not intern X atom for WM_COLORMAP_WINDOWS.");
|
||||
return;
|
||||
}
|
||||
XDeleteProperty(__glutDisplay, window->win, wmColormapWindows);
|
||||
} else {
|
||||
status = XSetWMColormapWindows(__glutDisplay, window->win,
|
||||
winlist, num);
|
||||
/* XSetWMColormapWindows should always work unless the
|
||||
WM_COLORMAP_WINDOWS property cannot be intern'ed. We
|
||||
check to be safe. */
|
||||
if (status == False)
|
||||
__glutFatalError("XSetWMColormapWindows returned False.");
|
||||
}
|
||||
/* For portability reasons we don't use alloca for winlist
|
||||
and cmaplist, but we could. */
|
||||
free(winlist);
|
||||
free(cmaplist);
|
||||
}
|
||||
|
||||
GLUTwindow *
|
||||
__glutToplevelOf(GLUTwindow * window)
|
||||
{
|
||||
while (window->parent) {
|
||||
window = window->parent;
|
||||
}
|
||||
return window;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__glutFreeColormap(GLUTcolormap * cmap)
|
||||
{
|
||||
GLUTcolormap *cur, **prev;
|
||||
|
||||
cmap->refcnt--;
|
||||
if (cmap->refcnt == 0) {
|
||||
/* remove from colormap list */
|
||||
cur = __glutColormapList;
|
||||
prev = &__glutColormapList;
|
||||
while (cur) {
|
||||
if (cur == cmap) {
|
||||
*prev = cmap->next;
|
||||
break;
|
||||
}
|
||||
prev = &(cur->next);
|
||||
cur = cur->next;
|
||||
}
|
||||
/* actually free colormap */
|
||||
XFreeColormap(__glutDisplay, cmap->cmap);
|
||||
free(cmap->cells);
|
||||
free(cmap);
|
||||
}
|
||||
}
|
||||
|
||||
201
src/glut/glx/glut_cursor.c
Normal file
201
src/glut/glx/glut_cursor.c
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1995, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xatom.h> /* For XA_CURSOR */
|
||||
#include <X11/cursorfont.h>
|
||||
#endif
|
||||
|
||||
typedef struct _CursorTable {
|
||||
#if defined(_WIN32)
|
||||
char* glyph;
|
||||
#else
|
||||
int glyph;
|
||||
#endif
|
||||
Cursor cursor;
|
||||
} CursorTable;
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
static CursorTable cursorTable[] = {
|
||||
{XC_arrow, None}, /* GLUT_CURSOR_RIGHT_ARROW */
|
||||
{XC_top_left_arrow, None}, /* GLUT_CURSOR_LEFT_ARROW */
|
||||
{XC_hand1, None}, /* GLUT_CURSOR_INFO */
|
||||
{XC_pirate, None}, /* GLUT_CURSOR_DESTROY */
|
||||
{XC_question_arrow, None}, /* GLUT_CURSOR_HELP */
|
||||
{XC_exchange, None}, /* GLUT_CURSOR_CYCLE */
|
||||
{XC_spraycan, None}, /* GLUT_CURSOR_SPRAY */
|
||||
{XC_watch, None}, /* GLUT_CURSOR_WAIT */
|
||||
{XC_xterm, None}, /* GLUT_CURSOR_TEXT */
|
||||
{XC_crosshair, None}, /* GLUT_CURSOR_CROSSHAIR */
|
||||
{XC_sb_v_double_arrow, None}, /* GLUT_CURSOR_UP_DOWN */
|
||||
{XC_sb_h_double_arrow, None}, /* GLUT_CURSOR_LEFT_RIGHT */
|
||||
{XC_top_side, None}, /* GLUT_CURSOR_TOP_SIDE */
|
||||
{XC_bottom_side, None}, /* GLUT_CURSOR_BOTTOM_SIDE */
|
||||
{XC_left_side, None}, /* GLUT_CURSOR_LEFT_SIDE */
|
||||
{XC_right_side, None}, /* GLUT_CURSOR_RIGHT_SIDE */
|
||||
{XC_top_left_corner, None}, /* GLUT_CURSOR_TOP_LEFT_CORNER */
|
||||
{XC_top_right_corner, None}, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
|
||||
{XC_bottom_right_corner, None}, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
|
||||
{XC_bottom_left_corner, None}, /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#if !defined(_WIN32)
|
||||
static Cursor blankCursor = None;
|
||||
static Cursor fullCrosshairCusor = None;
|
||||
|
||||
/* SGI X server's support a special property called the
|
||||
_SGI_CROSSHAIR_CURSOR that when installed as a window's
|
||||
cursor, becomes a full screen crosshair cursor. SGI
|
||||
has special cursor generation hardware for this case. */
|
||||
static Cursor
|
||||
getFullCrosshairCursor(void)
|
||||
{
|
||||
Cursor cursor;
|
||||
Atom crosshairAtom, actualType;
|
||||
int rc, actualFormat;
|
||||
unsigned long n, left;
|
||||
unsigned long *value;
|
||||
|
||||
if (fullCrosshairCusor == None) {
|
||||
crosshairAtom = XInternAtom(__glutDisplay,
|
||||
"_SGI_CROSSHAIR_CURSOR", True);
|
||||
if (crosshairAtom != None) {
|
||||
value = 0; /* Make compiler happy. */
|
||||
rc = XGetWindowProperty(__glutDisplay, __glutRoot,
|
||||
crosshairAtom, 0, 1, False, XA_CURSOR, &actualType,
|
||||
&actualFormat, &n, &left, (unsigned char **) &value);
|
||||
if (rc == Success && actualFormat == 32 && n >= 1) {
|
||||
cursor = value[0];
|
||||
XFree(value);
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return XCreateFontCursor(__glutDisplay, XC_crosshair);
|
||||
}
|
||||
|
||||
/* X11 forces you to create a blank cursor if you want
|
||||
to disable the cursor. */
|
||||
static Cursor
|
||||
makeBlankCursor(void)
|
||||
{
|
||||
static char data[1] =
|
||||
{0};
|
||||
Cursor cursor;
|
||||
Pixmap blank;
|
||||
XColor dummy;
|
||||
|
||||
blank = XCreateBitmapFromData(__glutDisplay, __glutRoot,
|
||||
data, 1, 1);
|
||||
if (blank == None)
|
||||
__glutFatalError("out of memory.");
|
||||
cursor = XCreatePixmapCursor(__glutDisplay, blank, blank,
|
||||
&dummy, &dummy, 0, 0);
|
||||
XFreePixmap(__glutDisplay, blank);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
/* Win32 and X11 use this same function to accomplish
|
||||
fairly different tasks. X11 lets you just define the
|
||||
cursor for a window and the window system takes care
|
||||
of making sure that the window's cursor is installed
|
||||
when the mouse is in the window. Win32 requires the
|
||||
application to handle a WM_SETCURSOR message to install
|
||||
the right cursor when windows are entered. Think of
|
||||
the Win32 __glutSetCursor (called from __glutWindowProc)
|
||||
as "install cursor". Think of the X11 __glutSetCursor
|
||||
(called from glutSetCursor) as "define cursor". */
|
||||
void
|
||||
__glutSetCursor(GLUTwindow *window)
|
||||
{
|
||||
int cursor = window->cursor;
|
||||
Cursor xcursor;
|
||||
|
||||
if (cursor >= 0 &&
|
||||
cursor < sizeof(cursorTable) / sizeof(cursorTable[0])) {
|
||||
if (cursorTable[cursor].cursor == None) {
|
||||
cursorTable[cursor].cursor = XCreateFontCursor(__glutDisplay,
|
||||
cursorTable[cursor].glyph);
|
||||
}
|
||||
xcursor = cursorTable[cursor].cursor;
|
||||
} else {
|
||||
/* Special cases. */
|
||||
switch (cursor) {
|
||||
case GLUT_CURSOR_INHERIT:
|
||||
#if defined(_WIN32)
|
||||
while (window->parent) {
|
||||
window = window->parent;
|
||||
if (window->cursor != GLUT_CURSOR_INHERIT) {
|
||||
__glutSetCursor(window);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* XXX Default to an arrow cursor. Is this
|
||||
right or should we be letting the default
|
||||
window proc be installing some system cursor? */
|
||||
xcursor = cursorTable[0].cursor;
|
||||
if (xcursor == NULL) {
|
||||
xcursor =
|
||||
cursorTable[0].cursor =
|
||||
LoadCursor(NULL, cursorTable[0].glyph);
|
||||
}
|
||||
#else
|
||||
xcursor = None;
|
||||
#endif
|
||||
break;
|
||||
case GLUT_CURSOR_NONE:
|
||||
#if defined(_WIN32)
|
||||
xcursor = NULL;
|
||||
#else
|
||||
if (blankCursor == None) {
|
||||
blankCursor = makeBlankCursor();
|
||||
}
|
||||
xcursor = blankCursor;
|
||||
#endif
|
||||
break;
|
||||
case GLUT_CURSOR_FULL_CROSSHAIR:
|
||||
#if defined(_WIN32)
|
||||
xcursor = IDC_CROSS;
|
||||
#else
|
||||
if (fullCrosshairCusor == None) {
|
||||
fullCrosshairCusor = getFullCrosshairCursor();
|
||||
}
|
||||
xcursor = fullCrosshairCusor;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
XDefineCursor(__glutDisplay,
|
||||
window->win, xcursor);
|
||||
XFlush(__glutDisplay);
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutSetCursor(int cursor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
POINT point;
|
||||
|
||||
__glutCurrentWindow->cursor = cursor;
|
||||
/* Are we in the window right now? If so,
|
||||
install the cursor. */
|
||||
GetCursorPos(&point);
|
||||
if (__glutCurrentWindow->win == WindowFromPoint(point)) {
|
||||
__glutSetCursor(__glutCurrentWindow);
|
||||
}
|
||||
#else
|
||||
__glutCurrentWindow->cursor = cursor;
|
||||
__glutSetCursor(__glutCurrentWindow);
|
||||
#endif
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
26
src/glut/glx/glut_dials.c
Normal file
26
src/glut/glx/glut_dials.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
void APIENTRY
|
||||
glutButtonBoxFunc(GLUTbuttonBoxCB buttonBoxFunc)
|
||||
{
|
||||
__glutCurrentWindow->buttonBox = buttonBoxFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutDialsFunc(GLUTdialsCB dialsFunc)
|
||||
{
|
||||
__glutCurrentWindow->dials = dialsFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
}
|
||||
1627
src/glut/glx/glut_dstr.c
Normal file
1627
src/glut/glx/glut_dstr.c
Normal file
File diff suppressed because it is too large
Load diff
1353
src/glut/glx/glut_event.c
Normal file
1353
src/glut/glx/glut_event.c
Normal file
File diff suppressed because it is too large
Load diff
53
src/glut/glx/glut_ext.c
Normal file
53
src/glut/glx/glut_ext.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutExtensionSupported(const char *extension)
|
||||
{
|
||||
static const GLubyte *extensions = NULL;
|
||||
const GLubyte *start;
|
||||
GLubyte *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = (GLubyte *) strchr(extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return 0;
|
||||
|
||||
if (!extensions) {
|
||||
extensions = glGetString(GL_EXTENSIONS);
|
||||
}
|
||||
/* It takes a bit of care to be fool-proof about parsing the
|
||||
OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
etc. */
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
/* If your application crashes in the strstr routine below,
|
||||
you are probably calling glutExtensionSupported without
|
||||
having a current window. Calling glGetString without
|
||||
a current OpenGL context has unpredictable results.
|
||||
Please fix your program. */
|
||||
where = (GLubyte *) strstr((const char *) start, extension);
|
||||
if (!where)
|
||||
break;
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
start = terminator;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
164
src/glut/glx/glut_fbc.c
Normal file
164
src/glut/glx/glut_fbc.c
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
/* I appreciate the guidance from William Mitchell
|
||||
(mitchell@cam.nist.gov) in developing this friend interface
|
||||
for use by the f90gl package. See ../../README.fortran */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* FCB stands for Fortran CallBack. */
|
||||
|
||||
/* There is only one idleFunc, menuStateFunc, and menuStatusFunc, so they
|
||||
can be saved in the wrappers for Fortran rather than the C structures. */
|
||||
|
||||
/* Set a Fortran callback function. */
|
||||
|
||||
void APIENTRY
|
||||
__glutSetFCB(int which, void *func)
|
||||
{
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
switch (which) {
|
||||
case GLUT_FCB_DISPLAY:
|
||||
__glutCurrentWindow->fdisplay = (GLUTdisplayFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_RESHAPE:
|
||||
__glutCurrentWindow->freshape = (GLUTreshapeFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_MOUSE:
|
||||
__glutCurrentWindow->fmouse = (GLUTmouseFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_MOTION:
|
||||
__glutCurrentWindow->fmotion = (GLUTmotionFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_PASSIVE:
|
||||
__glutCurrentWindow->fpassive = (GLUTpassiveFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_ENTRY:
|
||||
__glutCurrentWindow->fentry = (GLUTentryFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_KEYBOARD:
|
||||
__glutCurrentWindow->fkeyboard = (GLUTkeyboardFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_KEYBOARD_UP:
|
||||
__glutCurrentWindow->fkeyboardUp = (GLUTkeyboardFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_WINDOW_STATUS:
|
||||
__glutCurrentWindow->fwindowStatus = (GLUTwindowStatusFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_VISIBILITY:
|
||||
__glutCurrentWindow->fvisibility = (GLUTvisibilityFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_SPECIAL:
|
||||
__glutCurrentWindow->fspecial = (GLUTspecialFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_SPECIAL_UP:
|
||||
__glutCurrentWindow->fspecialUp = (GLUTspecialFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_BUTTON_BOX:
|
||||
__glutCurrentWindow->fbuttonBox = (GLUTbuttonBoxFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_DIALS:
|
||||
__glutCurrentWindow->fdials = (GLUTdialsFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_SPACE_MOTION:
|
||||
__glutCurrentWindow->fspaceMotion = (GLUTspaceMotionFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_SPACE_ROTATE:
|
||||
__glutCurrentWindow->fspaceRotate = (GLUTspaceRotateFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_SPACE_BUTTON:
|
||||
__glutCurrentWindow->fspaceButton = (GLUTspaceButtonFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_TABLET_MOTION:
|
||||
__glutCurrentWindow->ftabletMotion = (GLUTtabletMotionFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_TABLET_BUTTON:
|
||||
__glutCurrentWindow->ftabletButton = (GLUTtabletButtonFCB) func;
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case GLUT_FCB_JOYSTICK:
|
||||
__glutCurrentWindow->fjoystick = (GLUTjoystickFCB) func;
|
||||
break;
|
||||
#endif
|
||||
case GLUT_FCB_OVERLAY_DISPLAY:
|
||||
__glutCurrentWindow->overlay->fdisplay = (GLUTdisplayFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_SELECT:
|
||||
__glutCurrentMenu->fselect = (GLUTselectFCB) func;
|
||||
break;
|
||||
case GLUT_FCB_TIMER:
|
||||
__glutNewTimer->ffunc = (GLUTtimerFCB) func;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get a Fortran callback function. */
|
||||
|
||||
void* APIENTRY
|
||||
__glutGetFCB(int which)
|
||||
{
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
switch (which) {
|
||||
case GLUT_FCB_DISPLAY:
|
||||
return (void *) __glutCurrentWindow->fdisplay;
|
||||
case GLUT_FCB_RESHAPE:
|
||||
return (void *) __glutCurrentWindow->freshape;
|
||||
case GLUT_FCB_MOUSE:
|
||||
return (void *) __glutCurrentWindow->fmouse;
|
||||
case GLUT_FCB_MOTION:
|
||||
return (void *) __glutCurrentWindow->fmotion;
|
||||
case GLUT_FCB_PASSIVE:
|
||||
return (void *) __glutCurrentWindow->fpassive;
|
||||
case GLUT_FCB_ENTRY:
|
||||
return (void *) __glutCurrentWindow->fentry;
|
||||
case GLUT_FCB_KEYBOARD:
|
||||
return (void *) __glutCurrentWindow->fkeyboard;
|
||||
case GLUT_FCB_KEYBOARD_UP:
|
||||
return (void *) __glutCurrentWindow->fkeyboardUp;
|
||||
case GLUT_FCB_WINDOW_STATUS:
|
||||
return (void *) __glutCurrentWindow->fwindowStatus;
|
||||
case GLUT_FCB_VISIBILITY:
|
||||
return (void *) __glutCurrentWindow->fvisibility;
|
||||
case GLUT_FCB_SPECIAL:
|
||||
return (void *) __glutCurrentWindow->fspecial;
|
||||
case GLUT_FCB_SPECIAL_UP:
|
||||
return (void *) __glutCurrentWindow->fspecialUp;
|
||||
case GLUT_FCB_BUTTON_BOX:
|
||||
return (void *) __glutCurrentWindow->fbuttonBox;
|
||||
case GLUT_FCB_DIALS:
|
||||
return (void *) __glutCurrentWindow->fdials;
|
||||
case GLUT_FCB_SPACE_MOTION:
|
||||
return (void *) __glutCurrentWindow->fspaceMotion;
|
||||
case GLUT_FCB_SPACE_ROTATE:
|
||||
return (void *) __glutCurrentWindow->fspaceRotate;
|
||||
case GLUT_FCB_SPACE_BUTTON:
|
||||
return (void *) __glutCurrentWindow->fspaceButton;
|
||||
case GLUT_FCB_TABLET_MOTION:
|
||||
return (void *) __glutCurrentWindow->ftabletMotion;
|
||||
case GLUT_FCB_TABLET_BUTTON:
|
||||
return (void *) __glutCurrentWindow->ftabletButton;
|
||||
case GLUT_FCB_JOYSTICK:
|
||||
#ifdef _WIN32
|
||||
return (void *) __glutCurrentWindow->fjoystick;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
case GLUT_FCB_OVERLAY_DISPLAY:
|
||||
return (void *) __glutCurrentWindow->overlay->fdisplay;
|
||||
case GLUT_FCB_SELECT:
|
||||
return (void *) __glutCurrentMenu->fselect;
|
||||
case GLUT_FCB_TIMER:
|
||||
return (void *) __glutTimerList->ffunc;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
52
src/glut/glx/glut_fullscrn.c
Normal file
52
src/glut/glx/glut_fullscrn.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1995, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdio.h> /* SunOS multithreaded assert() needs <stdio.h>. Lame. */
|
||||
#include <assert.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#endif
|
||||
|
||||
/* SGI optimization introduced in IRIX 6.3 to avoid X server
|
||||
round trips for interning common X atoms. */
|
||||
#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
|
||||
#include <X11/SGIFastAtom.h>
|
||||
#else
|
||||
#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
|
||||
#endif
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutFullScreen(void)
|
||||
{
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
#if !defined(_WIN32)
|
||||
if (__glutMotifHints == None) {
|
||||
__glutMotifHints = XSGIFastInternAtom(__glutDisplay, "_MOTIF_WM_HINTS",
|
||||
SGI_XA__MOTIF_WM_HINTS, 0);
|
||||
if (__glutMotifHints == None) {
|
||||
__glutWarning("Could not intern X atom for _MOTIF_WM_HINTS.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__glutCurrentWindow->desiredX = 0;
|
||||
__glutCurrentWindow->desiredY = 0;
|
||||
__glutCurrentWindow->desiredWidth = __glutScreenWidth;
|
||||
__glutCurrentWindow->desiredHeight = __glutScreenHeight;
|
||||
__glutCurrentWindow->desiredConfMask |= CWX | CWY | CWWidth | CWHeight;
|
||||
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_CONFIGURE_WORK | GLUT_FULL_SCREEN_WORK);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
674
src/glut/glx/glut_gamemode.c
Normal file
674
src/glut/glx/glut_gamemode.c
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
/* SGI optimization introduced in IRIX 6.3 to avoid X server
|
||||
round trips for interning common X atoms. */
|
||||
#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
|
||||
#include <X11/SGIFastAtom.h>
|
||||
#else
|
||||
#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
|
||||
#endif
|
||||
#endif /* not _WIN32 */
|
||||
|
||||
int __glutDisplaySettingsChanged = 0;
|
||||
static DisplayMode *dmodes, *currentDm = NULL;
|
||||
static int ndmodes = -1;
|
||||
GLUTwindow *__glutGameModeWindow = NULL;
|
||||
|
||||
#ifdef TEST
|
||||
static char *compstr[] =
|
||||
{
|
||||
"none", "=", "!=", "<=", ">=", ">", "<", "~"
|
||||
};
|
||||
static char *capstr[] =
|
||||
{
|
||||
"width", "height", "bpp", "hertz", "num"
|
||||
};
|
||||
#endif
|
||||
|
||||
void __cdecl
|
||||
__glutCloseDownGameMode(void)
|
||||
{
|
||||
if (__glutDisplaySettingsChanged) {
|
||||
#ifdef _WIN32
|
||||
/* Assumes that display settings have been changed, that
|
||||
is __glutDisplaySettingsChanged is true. */
|
||||
ChangeDisplaySettings(NULL, 0);
|
||||
#endif
|
||||
__glutDisplaySettingsChanged = 0;
|
||||
}
|
||||
__glutGameModeWindow = NULL;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutLeaveGameMode(void)
|
||||
{
|
||||
if (__glutGameModeWindow == NULL) {
|
||||
__glutWarning("not in game mode so cannot leave game mode");
|
||||
return;
|
||||
}
|
||||
__glutDestroyWindow(__glutGameModeWindow,
|
||||
__glutGameModeWindow);
|
||||
XFlush(__glutDisplay);
|
||||
__glutGameModeWindow = NULL;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Same values as from MSDN's SetDisp.c example. */
|
||||
#define MIN_WIDTH 400
|
||||
#define MIN_FREQUENCY 60
|
||||
|
||||
static void
|
||||
initGameModeSupport(void)
|
||||
{
|
||||
DEVMODE dm;
|
||||
DWORD mode;
|
||||
int i;
|
||||
|
||||
if (ndmodes >= 0) {
|
||||
/* ndmodes is initially -1 to indicate no
|
||||
dmodes allocated yet. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Determine how many display modes there are. */
|
||||
ndmodes = 0;
|
||||
mode = 0;
|
||||
while (EnumDisplaySettings(NULL, mode, &dm)) {
|
||||
if (dm.dmPelsWidth >= MIN_WIDTH &&
|
||||
(dm.dmDisplayFrequency == 0 ||
|
||||
dm.dmDisplayFrequency >= MIN_FREQUENCY)) {
|
||||
ndmodes++;
|
||||
}
|
||||
mode++;
|
||||
}
|
||||
|
||||
/* Allocate memory for a list of all the display modes. */
|
||||
dmodes = (DisplayMode*)
|
||||
malloc(ndmodes * sizeof(DisplayMode));
|
||||
|
||||
/* Now that we know how many display modes to expect,
|
||||
enumerate them again and save the information in
|
||||
the list we allocated above. */
|
||||
i = 0;
|
||||
mode = 0;
|
||||
while (EnumDisplaySettings(NULL, mode, &dm)) {
|
||||
/* Try to reject any display settings that seem unplausible. */
|
||||
if (dm.dmPelsWidth >= MIN_WIDTH &&
|
||||
(dm.dmDisplayFrequency == 0 ||
|
||||
dm.dmDisplayFrequency >= MIN_FREQUENCY)) {
|
||||
dmodes[i].devmode = dm;
|
||||
dmodes[i].valid = 1; /* XXX Not used for now. */
|
||||
dmodes[i].cap[DM_WIDTH] = dm.dmPelsWidth;
|
||||
dmodes[i].cap[DM_HEIGHT] = dm.dmPelsHeight;
|
||||
dmodes[i].cap[DM_PIXEL_DEPTH] = dm.dmBitsPerPel;
|
||||
if (dm.dmDisplayFrequency == 0) {
|
||||
/* Guess a reasonable guess. */
|
||||
/* Lame Windows 95 version of EnumDisplaySettings. */
|
||||
dmodes[i].cap[DM_HERTZ] = 60;
|
||||
} else {
|
||||
dmodes[i].cap[DM_HERTZ] = dm.dmDisplayFrequency;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
mode++;
|
||||
}
|
||||
|
||||
assert(i == ndmodes);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* X Windows version of initGameModeSupport. */
|
||||
static void
|
||||
initGameModeSupport(void)
|
||||
{
|
||||
if (ndmodes >= 0) {
|
||||
/* ndmodes is initially -1 to indicate no
|
||||
dmodes allocated yet. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Determine how many display modes there are. */
|
||||
ndmodes = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* This routine is based on similiar code in glut_dstr.c */
|
||||
static DisplayMode *
|
||||
findMatch(DisplayMode * dmodes, int ndmodes,
|
||||
Criterion * criteria, int ncriteria)
|
||||
{
|
||||
DisplayMode *found;
|
||||
int *bestScore, *thisScore;
|
||||
int i, j, numok, result, worse, better;
|
||||
|
||||
found = NULL;
|
||||
numok = 1; /* "num" capability is indexed from 1,
|
||||
not 0. */
|
||||
|
||||
/* XXX alloca canidate. */
|
||||
bestScore = (int *) malloc(ncriteria * sizeof(int));
|
||||
if (!bestScore) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
for (j = 0; j < ncriteria; j++) {
|
||||
/* Very negative number. */
|
||||
bestScore[j] = -32768;
|
||||
}
|
||||
|
||||
/* XXX alloca canidate. */
|
||||
thisScore = (int *) malloc(ncriteria * sizeof(int));
|
||||
if (!thisScore) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
|
||||
for (i = 0; i < ndmodes; i++) {
|
||||
if (dmodes[i].valid) {
|
||||
worse = 0;
|
||||
better = 0;
|
||||
|
||||
for (j = 0; j < ncriteria; j++) {
|
||||
int cap, cvalue, dvalue;
|
||||
|
||||
cap = criteria[j].capability;
|
||||
cvalue = criteria[j].value;
|
||||
if (cap == NUM) {
|
||||
dvalue = numok;
|
||||
} else {
|
||||
dvalue = dmodes[i].cap[cap];
|
||||
}
|
||||
#ifdef TEST
|
||||
if (verbose)
|
||||
printf(" %s %s %d to %d\n",
|
||||
capstr[cap], compstr[criteria[j].comparison], cvalue, dvalue);
|
||||
#endif
|
||||
switch (criteria[j].comparison) {
|
||||
case EQ:
|
||||
result = cvalue == dvalue;
|
||||
thisScore[j] = 1;
|
||||
break;
|
||||
case NEQ:
|
||||
result = cvalue != dvalue;
|
||||
thisScore[j] = 1;
|
||||
break;
|
||||
case LT:
|
||||
result = dvalue < cvalue;
|
||||
thisScore[j] = dvalue - cvalue;
|
||||
break;
|
||||
case GT:
|
||||
result = dvalue > cvalue;
|
||||
thisScore[j] = dvalue - cvalue;
|
||||
break;
|
||||
case LTE:
|
||||
result = dvalue <= cvalue;
|
||||
thisScore[j] = dvalue - cvalue;
|
||||
break;
|
||||
case GTE:
|
||||
result = (dvalue >= cvalue);
|
||||
thisScore[j] = dvalue - cvalue;
|
||||
break;
|
||||
case MIN:
|
||||
result = dvalue >= cvalue;
|
||||
thisScore[j] = cvalue - dvalue;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
if (verbose)
|
||||
printf(" result=%d score=%d bestScore=%d\n", result, thisScore[j], bestScore[j]);
|
||||
#endif
|
||||
|
||||
if (result) {
|
||||
if (better || thisScore[j] > bestScore[j]) {
|
||||
better = 1;
|
||||
} else if (thisScore[j] == bestScore[j]) {
|
||||
/* Keep looking. */
|
||||
} else {
|
||||
goto nextDM;
|
||||
}
|
||||
} else {
|
||||
if (cap == NUM) {
|
||||
worse = 1;
|
||||
} else {
|
||||
goto nextDM;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (better && !worse) {
|
||||
found = &dmodes[i];
|
||||
for (j = 0; j < ncriteria; j++) {
|
||||
bestScore[j] = thisScore[j];
|
||||
}
|
||||
}
|
||||
numok++;
|
||||
|
||||
nextDM:;
|
||||
|
||||
}
|
||||
}
|
||||
free(bestScore);
|
||||
free(thisScore);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses strings in the form of:
|
||||
* 800x600
|
||||
* 800x600:16
|
||||
* 800x600@60
|
||||
* 800x600:16@60
|
||||
* @60
|
||||
* :16
|
||||
* :16@60
|
||||
* NOTE that @ before : is not parsed.
|
||||
*/
|
||||
static int
|
||||
specialCaseParse(char *word, Criterion * criterion, int mask)
|
||||
{
|
||||
char *xstr, *response;
|
||||
int got;
|
||||
int width, height, bpp, hertz;
|
||||
|
||||
switch(word[0]) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
/* The WWWxHHH case. */
|
||||
if (mask & (1 << DM_WIDTH)) {
|
||||
return -1;
|
||||
}
|
||||
xstr = strpbrk(&word[1], "x");
|
||||
if (xstr) {
|
||||
width = (int) strtol(word, &response, 0);
|
||||
if (response == word || response[0] != 'x') {
|
||||
/* Not a valid number OR needs to be followed by 'x'. */
|
||||
return -1;
|
||||
}
|
||||
height = (int) strtol(&xstr[1], &response, 0);
|
||||
if (response == &xstr[1]) {
|
||||
/* Not a valid number. */
|
||||
return -1;
|
||||
}
|
||||
criterion[0].capability = DM_WIDTH;
|
||||
criterion[0].comparison = EQ;
|
||||
criterion[0].value = width;
|
||||
criterion[1].capability = DM_HEIGHT;
|
||||
criterion[1].comparison = EQ;
|
||||
criterion[1].value = height;
|
||||
got = specialCaseParse(response,
|
||||
&criterion[2], 1 << DM_WIDTH);
|
||||
if (got >= 0) {
|
||||
return got + 2;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
case ':':
|
||||
/* The :BPP case. */
|
||||
if (mask & (1 << DM_PIXEL_DEPTH)) {
|
||||
return -1;
|
||||
}
|
||||
bpp = (int) strtol(&word[1], &response, 0);
|
||||
if (response == &word[1]) {
|
||||
/* Not a valid number. */
|
||||
return -1;
|
||||
}
|
||||
criterion[0].capability = DM_PIXEL_DEPTH;
|
||||
criterion[0].comparison = EQ;
|
||||
criterion[0].value = bpp;
|
||||
got = specialCaseParse(response,
|
||||
&criterion[1], 1 << DM_WIDTH | 1 << DM_PIXEL_DEPTH);
|
||||
if (got >= 0) {
|
||||
return got + 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
case '@':
|
||||
/* The @HZ case. */
|
||||
if (mask & (1 << DM_HERTZ)) {
|
||||
return -1;
|
||||
}
|
||||
hertz = (int) strtol(&word[1], &response, 0);
|
||||
if (response == &word[1]) {
|
||||
/* Not a valid number. */
|
||||
return -1;
|
||||
}
|
||||
criterion[0].capability = DM_HERTZ;
|
||||
criterion[0].comparison = EQ;
|
||||
criterion[0].value = hertz;
|
||||
got = specialCaseParse(response,
|
||||
&criterion[1], ~DM_HERTZ);
|
||||
if (got >= 0) {
|
||||
return got + 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
case '\0':
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This routine is based on similiar code in glut_dstr.c */
|
||||
static int
|
||||
parseCriteria(char *word, Criterion * criterion)
|
||||
{
|
||||
char *cstr, *vstr, *response;
|
||||
int comparator, value;
|
||||
|
||||
cstr = strpbrk(word, "=><!~");
|
||||
if (cstr) {
|
||||
switch (cstr[0]) {
|
||||
case '=':
|
||||
comparator = EQ;
|
||||
vstr = &cstr[1];
|
||||
break;
|
||||
case '~':
|
||||
comparator = MIN;
|
||||
vstr = &cstr[1];
|
||||
break;
|
||||
case '>':
|
||||
if (cstr[1] == '=') {
|
||||
comparator = GTE;
|
||||
vstr = &cstr[2];
|
||||
} else {
|
||||
comparator = GT;
|
||||
vstr = &cstr[1];
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
if (cstr[1] == '=') {
|
||||
comparator = LTE;
|
||||
vstr = &cstr[2];
|
||||
} else {
|
||||
comparator = LT;
|
||||
vstr = &cstr[1];
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
if (cstr[1] == '=') {
|
||||
comparator = NEQ;
|
||||
vstr = &cstr[2];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
value = (int) strtol(vstr, &response, 0);
|
||||
if (response == vstr) {
|
||||
/* Not a valid number. */
|
||||
return -1;
|
||||
}
|
||||
*cstr = '\0';
|
||||
} else {
|
||||
comparator = NONE;
|
||||
}
|
||||
switch (word[0]) {
|
||||
case 'b':
|
||||
if (!strcmp(word, "bpp")) {
|
||||
criterion[0].capability = DM_PIXEL_DEPTH;
|
||||
if (comparator == NONE) {
|
||||
return -1;
|
||||
} else {
|
||||
criterion[0].comparison = comparator;
|
||||
criterion[0].value = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
case 'h':
|
||||
if (!strcmp(word, "height")) {
|
||||
criterion[0].capability = DM_HEIGHT;
|
||||
if (comparator == NONE) {
|
||||
return -1;
|
||||
} else {
|
||||
criterion[0].comparison = comparator;
|
||||
criterion[0].value = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!strcmp(word, "hertz")) {
|
||||
criterion[0].capability = DM_HERTZ;
|
||||
if (comparator == NONE) {
|
||||
return -1;
|
||||
} else {
|
||||
criterion[0].comparison = comparator;
|
||||
criterion[0].value = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
case 'n':
|
||||
if (!strcmp(word, "num")) {
|
||||
criterion[0].capability = DM_NUM;
|
||||
if (comparator == NONE) {
|
||||
return -1;
|
||||
} else {
|
||||
criterion[0].comparison = comparator;
|
||||
criterion[0].value = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
case 'w':
|
||||
if (!strcmp(word, "width")) {
|
||||
criterion[0].capability = DM_WIDTH;
|
||||
if (comparator == NONE) {
|
||||
return -1;
|
||||
} else {
|
||||
criterion[0].comparison = comparator;
|
||||
criterion[0].value = value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (comparator == NONE) {
|
||||
return specialCaseParse(word, criterion, 0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This routine is based on similiar code in glut_dstr.c */
|
||||
static Criterion *
|
||||
parseDisplayString(const char *display, int *ncriteria)
|
||||
{
|
||||
Criterion *criteria = NULL;
|
||||
int n, parsed;
|
||||
char *copy, *word;
|
||||
|
||||
copy = __glutStrdup(display);
|
||||
/* Attempt to estimate how many criteria entries should be
|
||||
needed. */
|
||||
n = 0;
|
||||
word = strtok(copy, " \t");
|
||||
while (word) {
|
||||
n++;
|
||||
word = strtok(NULL, " \t");
|
||||
}
|
||||
/* Allocate number of words of criteria. A word
|
||||
could contain as many as four criteria in the
|
||||
worst case. Example: 800x600:16@60 */
|
||||
criteria = (Criterion *) malloc(4 * n * sizeof(Criterion));
|
||||
if (!criteria) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
|
||||
/* Re-copy the copy of the display string. */
|
||||
strcpy(copy, display);
|
||||
|
||||
n = 0;
|
||||
word = strtok(copy, " \t");
|
||||
while (word) {
|
||||
parsed = parseCriteria(word, &criteria[n]);
|
||||
if (parsed >= 0) {
|
||||
n += parsed;
|
||||
} else {
|
||||
__glutWarning("Unrecognized game mode string word: %s (ignoring)\n", word);
|
||||
}
|
||||
word = strtok(NULL, " \t");
|
||||
}
|
||||
|
||||
free(copy);
|
||||
*ncriteria = n;
|
||||
return criteria;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutGameModeString(const char *string)
|
||||
{
|
||||
Criterion *criteria;
|
||||
int ncriteria;
|
||||
|
||||
initGameModeSupport();
|
||||
criteria = parseDisplayString(string, &ncriteria);
|
||||
currentDm = findMatch(dmodes, ndmodes, criteria, ncriteria);
|
||||
free(criteria);
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutEnterGameMode(void)
|
||||
{
|
||||
GLUTwindow *window;
|
||||
int width, height;
|
||||
Window win;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
__glutFatalUsage("entering game mode not allowed while menus in use");
|
||||
}
|
||||
if (__glutGameModeWindow) {
|
||||
/* Already in game mode, so blow away game mode
|
||||
window so apps can change resolutions. */
|
||||
window = __glutGameModeWindow;
|
||||
/* Setting the game mode window to NULL tricks
|
||||
the window destroy code into not undoing the
|
||||
screen display change since we plan on immediately
|
||||
doing another mode change. */
|
||||
__glutGameModeWindow = NULL;
|
||||
__glutDestroyWindow(window, window);
|
||||
}
|
||||
|
||||
/* Assume default screen size until we find out if we
|
||||
can actually change the display settings. */
|
||||
width = __glutScreenWidth;
|
||||
height = __glutScreenHeight;
|
||||
|
||||
if (currentDm) {
|
||||
#ifdef _WIN32
|
||||
LONG status;
|
||||
static int registered = 0;
|
||||
|
||||
status = ChangeDisplaySettings(¤tDm->devmode,
|
||||
CDS_FULLSCREEN);
|
||||
if (status == DISP_CHANGE_SUCCESSFUL) {
|
||||
__glutDisplaySettingsChanged = 1;
|
||||
width = currentDm->cap[DM_WIDTH];
|
||||
height = currentDm->cap[DM_HEIGHT];
|
||||
if (!registered) {
|
||||
atexit(__glutCloseDownGameMode);
|
||||
registered = 1;
|
||||
}
|
||||
} else {
|
||||
/* Switch back to default resolution. */
|
||||
ChangeDisplaySettings(NULL, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
window = __glutCreateWindow(NULL, 0, 0,
|
||||
width, height, /* game mode */ 1);
|
||||
win = window->win;
|
||||
|
||||
#if !defined(_WIN32)
|
||||
if (__glutMotifHints == None) {
|
||||
__glutMotifHints = XSGIFastInternAtom(__glutDisplay, "_MOTIF_WM_HINTS",
|
||||
SGI_XA__MOTIF_WM_HINTS, 0);
|
||||
if (__glutMotifHints == None) {
|
||||
__glutWarning("Could not intern X atom for _MOTIF_WM_HINTS.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Game mode window is a toplevel window. */
|
||||
XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1);
|
||||
#endif
|
||||
|
||||
/* Schedule the fullscreen property to be added and to
|
||||
make sure the window is configured right. Win32
|
||||
doesn't need this. */
|
||||
window->desiredX = 0;
|
||||
window->desiredY = 0;
|
||||
window->desiredWidth = width;
|
||||
window->desiredHeight = height;
|
||||
window->desiredConfMask |= CWX | CWY | CWWidth | CWHeight;
|
||||
#ifdef _WIN32
|
||||
/* Win32 does not want to use GLUT_FULL_SCREEN_WORK
|
||||
for game mode because we need to be maximizing
|
||||
the window in game mode, not just sizing it to
|
||||
take up the full screen. The Win32-ness of game
|
||||
mode happens when you pass 1 in the gameMode parameter
|
||||
to __glutCreateWindow above. A gameMode of creates
|
||||
a WS_POPUP window, not a standard WS_OVERLAPPEDWINDOW
|
||||
window. WS_POPUP ensures the taskbar is hidden. */
|
||||
__glutPutOnWorkList(window,
|
||||
GLUT_CONFIGURE_WORK);
|
||||
#else
|
||||
__glutPutOnWorkList(window,
|
||||
GLUT_CONFIGURE_WORK | GLUT_FULL_SCREEN_WORK);
|
||||
#endif
|
||||
|
||||
__glutGameModeWindow = window;
|
||||
return window->num + 1;
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutGameModeGet(GLenum mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case GLUT_GAME_MODE_ACTIVE:
|
||||
return __glutGameModeWindow != NULL;
|
||||
case GLUT_GAME_MODE_POSSIBLE:
|
||||
return currentDm != NULL;
|
||||
case GLUT_GAME_MODE_WIDTH:
|
||||
return currentDm ? currentDm->cap[DM_WIDTH] : -1;
|
||||
case GLUT_GAME_MODE_HEIGHT:
|
||||
return currentDm ? currentDm->cap[DM_HEIGHT] : -1;
|
||||
case GLUT_GAME_MODE_PIXEL_DEPTH:
|
||||
return currentDm ? currentDm->cap[DM_PIXEL_DEPTH] : -1;
|
||||
case GLUT_GAME_MODE_REFRESH_RATE:
|
||||
return currentDm ? currentDm->cap[DM_HERTZ] : -1;
|
||||
case GLUT_GAME_MODE_DISPLAY_CHANGED:
|
||||
return __glutDisplaySettingsChanged;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
216
src/glut/glx/glut_get.c
Normal file
216
src/glut/glx/glut_get.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h> /* SunOS 4 needs NULL defined for GETTIMEOFDAY macro. */
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutGet(GLenum param)
|
||||
{
|
||||
Window win, root;
|
||||
int x, y, value;
|
||||
unsigned int width, height, border, depth;
|
||||
|
||||
switch (param) {
|
||||
case GLUT_INIT_WINDOW_X:
|
||||
return __glutInitX;
|
||||
case GLUT_INIT_WINDOW_Y:
|
||||
return __glutInitY;
|
||||
case GLUT_INIT_WINDOW_WIDTH:
|
||||
return __glutInitWidth;
|
||||
case GLUT_INIT_WINDOW_HEIGHT:
|
||||
return __glutInitHeight;
|
||||
case GLUT_INIT_DISPLAY_MODE:
|
||||
return __glutDisplayMode;
|
||||
case GLUT_WINDOW_X:
|
||||
XTranslateCoordinates(__glutDisplay, __glutCurrentWindow->win,
|
||||
__glutRoot, 0, 0, &x, &y, &win);
|
||||
return x;
|
||||
case GLUT_WINDOW_Y:
|
||||
XTranslateCoordinates(__glutDisplay, __glutCurrentWindow->win,
|
||||
__glutRoot, 0, 0, &x, &y, &win);
|
||||
return y;
|
||||
case GLUT_WINDOW_WIDTH:
|
||||
if (!__glutCurrentWindow->reshape) {
|
||||
XGetGeometry(__glutDisplay, __glutCurrentWindow->win,
|
||||
&root, &x, &y,
|
||||
&width, &height, &border, &depth);
|
||||
return width;
|
||||
}
|
||||
return __glutCurrentWindow->width;
|
||||
case GLUT_WINDOW_HEIGHT:
|
||||
if (!__glutCurrentWindow->reshape) {
|
||||
XGetGeometry(__glutDisplay, __glutCurrentWindow->win,
|
||||
&root, &x, &y,
|
||||
&width, &height, &border, &depth);
|
||||
return height;
|
||||
}
|
||||
return __glutCurrentWindow->height;
|
||||
|
||||
#define GET_CONFIG(attrib) { \
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { \
|
||||
glXGetConfig(__glutDisplay, __glutCurrentWindow->vis, \
|
||||
attrib, &value); \
|
||||
} else { \
|
||||
glXGetConfig(__glutDisplay, __glutCurrentWindow->overlay->vis, \
|
||||
attrib, &value); \
|
||||
} \
|
||||
}
|
||||
|
||||
case GLUT_WINDOW_BUFFER_SIZE:
|
||||
GET_CONFIG(GLX_BUFFER_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_STENCIL_SIZE:
|
||||
GET_CONFIG(GLX_STENCIL_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_DEPTH_SIZE:
|
||||
GET_CONFIG(GLX_DEPTH_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_RED_SIZE:
|
||||
GET_CONFIG(GLX_RED_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_GREEN_SIZE:
|
||||
GET_CONFIG(GLX_GREEN_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_BLUE_SIZE:
|
||||
GET_CONFIG(GLX_BLUE_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_ALPHA_SIZE:
|
||||
GET_CONFIG(GLX_ALPHA_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_ACCUM_RED_SIZE:
|
||||
GET_CONFIG(GLX_ACCUM_RED_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_ACCUM_GREEN_SIZE:
|
||||
GET_CONFIG(GLX_ACCUM_GREEN_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_ACCUM_BLUE_SIZE:
|
||||
GET_CONFIG(GLX_ACCUM_BLUE_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
|
||||
GET_CONFIG(GLX_ACCUM_ALPHA_SIZE);
|
||||
return value;
|
||||
case GLUT_WINDOW_DOUBLEBUFFER:
|
||||
GET_CONFIG(GLX_DOUBLEBUFFER);
|
||||
return value;
|
||||
case GLUT_WINDOW_RGBA:
|
||||
GET_CONFIG(GLX_RGBA);
|
||||
return value;
|
||||
case GLUT_WINDOW_COLORMAP_SIZE:
|
||||
GET_CONFIG(GLX_RGBA);
|
||||
if (value) {
|
||||
return 0;
|
||||
} else {
|
||||
#if defined(_WIN32)
|
||||
/* KLUDGE: we always assume 256 colors in CI mode on
|
||||
Win32 */
|
||||
return 256;
|
||||
#else
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
return __glutCurrentWindow->vis->visual->map_entries;
|
||||
} else {
|
||||
return __glutCurrentWindow->overlay->vis->visual->map_entries;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
case GLUT_WINDOW_PARENT:
|
||||
return __glutCurrentWindow->parent ?
|
||||
__glutCurrentWindow->parent->num + 1 : 0;
|
||||
case GLUT_WINDOW_NUM_CHILDREN:
|
||||
{
|
||||
int num = 0;
|
||||
GLUTwindow *children = __glutCurrentWindow->children;
|
||||
|
||||
while (children) {
|
||||
num++;
|
||||
children = children->siblings;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
case GLUT_WINDOW_NUM_SAMPLES:
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) {
|
||||
GET_CONFIG(GLX_SAMPLES_SGIS);
|
||||
return value;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* Independent of GLX server support, multisampling not
|
||||
supported by GLX client-side. */
|
||||
return 0;
|
||||
#endif
|
||||
case GLUT_WINDOW_STEREO:
|
||||
GET_CONFIG(GLX_STEREO);
|
||||
return value;
|
||||
case GLUT_WINDOW_CURSOR:
|
||||
return __glutCurrentWindow->cursor;
|
||||
case GLUT_SCREEN_WIDTH:
|
||||
return DisplayWidth(__glutDisplay, __glutScreen);
|
||||
case GLUT_SCREEN_HEIGHT:
|
||||
return DisplayHeight(__glutDisplay, __glutScreen);
|
||||
case GLUT_SCREEN_WIDTH_MM:
|
||||
return DisplayWidthMM(__glutDisplay, __glutScreen);
|
||||
case GLUT_SCREEN_HEIGHT_MM:
|
||||
return DisplayHeightMM(__glutDisplay, __glutScreen);
|
||||
case GLUT_MENU_NUM_ITEMS:
|
||||
return __glutCurrentMenu->num;
|
||||
case GLUT_DISPLAY_MODE_POSSIBLE:
|
||||
{
|
||||
XVisualInfo *vi;
|
||||
Bool dummy, visAlloced;
|
||||
void *fbc;
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* Our fake glXChooseVisual (which is called by
|
||||
__glutDetermineVisual) needs an HDC to work with, so grab one
|
||||
from the "root" window. */
|
||||
XHDC = GetDC(GetDesktopWindow());
|
||||
#endif
|
||||
vi = __glutDetermineWindowVisual(&dummy, &visAlloced, &fbc);
|
||||
#if defined(_WIN32)
|
||||
ReleaseDC(GetDesktopWindow(), XHDC);
|
||||
#endif
|
||||
if (vi) {
|
||||
if (visAlloced)
|
||||
XFree(vi);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case GLUT_ELAPSED_TIME:
|
||||
{
|
||||
struct timeval elapsed, beginning, now;
|
||||
|
||||
__glutInitTime(&beginning);
|
||||
GETTIMEOFDAY(&now);
|
||||
TIMEDELTA(elapsed, now, beginning);
|
||||
/* Return elapsed milliseconds. */
|
||||
#if defined(__vms) && ( __VMS_VER < 70000000 )
|
||||
return (int) (elapsed.val / TICKS_PER_MILLISECOND);
|
||||
#else
|
||||
return (int) ((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000));
|
||||
#endif
|
||||
}
|
||||
case GLUT_WINDOW_FORMAT_ID:
|
||||
#if defined(_WIN32)
|
||||
return GetPixelFormat(__glutCurrentWindow->hdc);
|
||||
#else
|
||||
if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
|
||||
return (int) __glutCurrentWindow->vis->visualid;
|
||||
} else {
|
||||
return (int) __glutCurrentWindow->overlay->vis->visualid;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
__glutWarning("invalid glutGet parameter: %d", param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
48
src/glut/glx/glut_glxext.c
Normal file
48
src/glut/glx/glut_glxext.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "glutint.h"
|
||||
|
||||
#if defined(GLX_VERSION_1_1)
|
||||
int
|
||||
__glutIsSupportedByGLX(char *extension)
|
||||
{
|
||||
static const char *extensions = NULL;
|
||||
const char *start;
|
||||
char *where, *terminator;
|
||||
int major, minor;
|
||||
|
||||
glXQueryVersion(__glutDisplay, &major, &minor);
|
||||
/* Be careful not to call glXQueryExtensionsString if it
|
||||
looks like the server doesn't support GLX 1.1.
|
||||
Unfortunately, the original GLX 1.0 didn't have the notion
|
||||
of GLX extensions. */
|
||||
if ((major == 1 && minor >= 1) || (major > 1)) {
|
||||
if (!extensions)
|
||||
extensions = glXQueryExtensionsString(__glutDisplay, __glutScreen);
|
||||
/* It takes a bit of care to be fool-proof about parsing
|
||||
the GLX extensions string. Don't be fooled by
|
||||
sub-strings, etc. */
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
where = strstr(start, extension);
|
||||
if (!where)
|
||||
return 0;
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
start = terminator;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
1778
src/glut/glx/glut_hel10.c
Normal file
1778
src/glut/glx/glut_hel10.c
Normal file
File diff suppressed because it is too large
Load diff
1788
src/glut/glx/glut_hel12.c
Normal file
1788
src/glut/glx/glut_hel12.c
Normal file
File diff suppressed because it is too large
Load diff
1897
src/glut/glx/glut_hel18.c
Normal file
1897
src/glut/glx/glut_hel18.c
Normal file
File diff suppressed because it is too large
Load diff
364
src/glut/glx/glut_init.c
Normal file
364
src/glut/glx/glut_init.c
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#endif
|
||||
|
||||
/* SGI optimization introduced in IRIX 6.3 to avoid X server
|
||||
round trips for interning common X atoms. */
|
||||
#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
|
||||
#include <X11/SGIFastAtom.h>
|
||||
#else
|
||||
#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
|
||||
#endif
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* GLUT inter-file variables */
|
||||
/* *INDENT-OFF* */
|
||||
char *__glutProgramName = NULL;
|
||||
int __glutArgc = 0;
|
||||
char **__glutArgv = NULL;
|
||||
char *__glutGeometry = NULL;
|
||||
Display *__glutDisplay = NULL;
|
||||
int __glutScreen;
|
||||
Window __glutRoot;
|
||||
int __glutScreenHeight;
|
||||
int __glutScreenWidth;
|
||||
GLboolean __glutIconic = GL_FALSE;
|
||||
GLboolean __glutDebug = GL_FALSE;
|
||||
unsigned int __glutDisplayMode =
|
||||
GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
|
||||
char *__glutDisplayString = NULL;
|
||||
int __glutConnectionFD;
|
||||
XSizeHints __glutSizeHints = {0};
|
||||
int __glutInitWidth = 300, __glutInitHeight = 300;
|
||||
int __glutInitX = -1, __glutInitY = -1;
|
||||
GLboolean __glutForceDirect = GL_FALSE,
|
||||
__glutTryDirect = GL_TRUE;
|
||||
Atom __glutWMDeleteWindow;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#ifdef _WIN32
|
||||
void (__cdecl *__glutExitFunc)(int retval) = NULL;
|
||||
#endif
|
||||
|
||||
static Bool synchronize = False;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#include <float.h> /* For masking floating point exceptions. */
|
||||
#endif
|
||||
|
||||
void
|
||||
__glutOpenWin32Connection(char* display)
|
||||
{
|
||||
static char *classname;
|
||||
WNDCLASS wc;
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
/* Make sure we register the window only once. */
|
||||
if(classname)
|
||||
return;
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
/* Under certain conditions (e.g. while rendering solid surfaces with
|
||||
lighting enabled) Microsoft OpenGL libraries cause some illegal
|
||||
operations like floating point overflow or division by zero. The
|
||||
default behaviour of Microsoft compilers is to mask (ignore)
|
||||
floating point exceptions, while Borland compilers do not. The
|
||||
following function of Borland RTL allows to mask exceptions.
|
||||
Advice from Pier Giorgio Esposito (mc2172@mclink.it). */
|
||||
_control87(MCW_EM,MCW_EM);
|
||||
#endif
|
||||
|
||||
classname = "GLUT";
|
||||
|
||||
/* Clear (important!) and then fill in the window class structure. */
|
||||
memset(&wc, 0, sizeof(WNDCLASS));
|
||||
wc.style = CS_OWNDC;
|
||||
wc.lpfnWndProc = (WNDPROC)__glutWindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = LoadIcon(hInstance, "GLUT_ICON");
|
||||
wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = classname;
|
||||
|
||||
/* Fill in a default icon if one isn't specified as a resource. */
|
||||
if(!wc.hIcon)
|
||||
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||
|
||||
if(!RegisterClass(&wc)) {
|
||||
__glutFatalError("RegisterClass() failed:"
|
||||
"Cannot register GLUT window class.");
|
||||
}
|
||||
|
||||
__glutScreenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
__glutScreenHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
/* Set the root window to NULL because windows creates a top-level
|
||||
window when the parent is NULL. X creates a top-level window
|
||||
when the parent is the root window. */
|
||||
__glutRoot = NULL;
|
||||
|
||||
/* Set the display to 1 -- we shouldn't be using this anywhere
|
||||
(except as an argument to X calls). */
|
||||
__glutDisplay = (Display*)1;
|
||||
|
||||
/* There isn't any concept of multiple screens in Win32, therefore,
|
||||
we don't need to keep track of the screen we're on... it's always
|
||||
the same one. */
|
||||
__glutScreen = 0;
|
||||
}
|
||||
#else /* !_WIN32 */
|
||||
void
|
||||
__glutOpenXConnection(char *display)
|
||||
{
|
||||
int errorBase, eventBase;
|
||||
|
||||
__glutDisplay = XOpenDisplay(display);
|
||||
if (!__glutDisplay)
|
||||
__glutFatalError("could not open display: %s",
|
||||
XDisplayName(display));
|
||||
if (synchronize)
|
||||
XSynchronize(__glutDisplay, True);
|
||||
if (!glXQueryExtension(__glutDisplay, &errorBase, &eventBase))
|
||||
__glutFatalError(
|
||||
"OpenGL GLX extension not supported by display: %s",
|
||||
XDisplayName(display));
|
||||
__glutScreen = DefaultScreen(__glutDisplay);
|
||||
__glutRoot = RootWindow(__glutDisplay, __glutScreen);
|
||||
__glutScreenWidth = DisplayWidth(__glutDisplay, __glutScreen);
|
||||
__glutScreenHeight = DisplayHeight(__glutDisplay,
|
||||
__glutScreen);
|
||||
__glutConnectionFD = ConnectionNumber(__glutDisplay);
|
||||
__glutWMDeleteWindow = XSGIFastInternAtom(__glutDisplay,
|
||||
"WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
void
|
||||
__glutInitTime(struct timeval *beginning)
|
||||
{
|
||||
static int beenhere = 0;
|
||||
static struct timeval genesis;
|
||||
|
||||
if (!beenhere) {
|
||||
GETTIMEOFDAY(&genesis);
|
||||
beenhere = 1;
|
||||
}
|
||||
*beginning = genesis;
|
||||
}
|
||||
|
||||
static void
|
||||
removeArgs(int *argcp, char **argv, int numToRemove)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = numToRemove; argv[j]; i++, j++) {
|
||||
argv[i] = argv[j];
|
||||
}
|
||||
argv[i] = NULL;
|
||||
*argcp -= numToRemove;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutInit(int *argcp, char **argv)
|
||||
{
|
||||
char *display = NULL;
|
||||
char *str, *geometry = NULL;
|
||||
struct timeval unused;
|
||||
int i;
|
||||
|
||||
if (__glutDisplay) {
|
||||
__glutWarning("glutInit being called a second time.");
|
||||
return;
|
||||
}
|
||||
/* Determine temporary program name. */
|
||||
str = strrchr(argv[0], '/');
|
||||
if (str == NULL) {
|
||||
__glutProgramName = argv[0];
|
||||
} else {
|
||||
__glutProgramName = str + 1;
|
||||
}
|
||||
|
||||
/* Make private copy of command line arguments. */
|
||||
__glutArgc = *argcp;
|
||||
__glutArgv = (char **) malloc(__glutArgc * sizeof(char *));
|
||||
if (!__glutArgv)
|
||||
__glutFatalError("out of memory.");
|
||||
for (i = 0; i < __glutArgc; i++) {
|
||||
__glutArgv[i] = __glutStrdup(argv[i]);
|
||||
if (!__glutArgv[i])
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
|
||||
/* determine permanent program name */
|
||||
str = strrchr(__glutArgv[0], '/');
|
||||
if (str == NULL) {
|
||||
__glutProgramName = __glutArgv[0];
|
||||
} else {
|
||||
__glutProgramName = str + 1;
|
||||
}
|
||||
|
||||
/* parse arguments for standard options */
|
||||
for (i = 1; i < __glutArgc; i++) {
|
||||
if (!strcmp(__glutArgv[i], "-display")) {
|
||||
#if defined(_WIN32)
|
||||
__glutWarning("-display option not supported by Win32 GLUT.");
|
||||
#endif
|
||||
if (++i >= __glutArgc) {
|
||||
__glutFatalError(
|
||||
"follow -display option with X display name.");
|
||||
}
|
||||
display = __glutArgv[i];
|
||||
removeArgs(argcp, &argv[1], 2);
|
||||
} else if (!strcmp(__glutArgv[i], "-geometry")) {
|
||||
if (++i >= __glutArgc) {
|
||||
__glutFatalError(
|
||||
"follow -geometry option with geometry parameter.");
|
||||
}
|
||||
geometry = __glutArgv[i];
|
||||
removeArgs(argcp, &argv[1], 2);
|
||||
} else if (!strcmp(__glutArgv[i], "-direct")) {
|
||||
#if defined(_WIN32)
|
||||
__glutWarning("-direct option not supported by Win32 GLUT.");
|
||||
#endif
|
||||
if (!__glutTryDirect)
|
||||
__glutFatalError(
|
||||
"cannot force both direct and indirect rendering.");
|
||||
__glutForceDirect = GL_TRUE;
|
||||
removeArgs(argcp, &argv[1], 1);
|
||||
} else if (!strcmp(__glutArgv[i], "-indirect")) {
|
||||
#if defined(_WIN32)
|
||||
__glutWarning("-indirect option not supported by Win32 GLUT.");
|
||||
#endif
|
||||
if (__glutForceDirect)
|
||||
__glutFatalError(
|
||||
"cannot force both direct and indirect rendering.");
|
||||
__glutTryDirect = GL_FALSE;
|
||||
removeArgs(argcp, &argv[1], 1);
|
||||
} else if (!strcmp(__glutArgv[i], "-iconic")) {
|
||||
__glutIconic = GL_TRUE;
|
||||
removeArgs(argcp, &argv[1], 1);
|
||||
} else if (!strcmp(__glutArgv[i], "-gldebug")) {
|
||||
__glutDebug = GL_TRUE;
|
||||
removeArgs(argcp, &argv[1], 1);
|
||||
} else if (!strcmp(__glutArgv[i], "-sync")) {
|
||||
#if defined(_WIN32)
|
||||
__glutWarning("-sync option not supported by Win32 GLUT.");
|
||||
#endif
|
||||
synchronize = GL_TRUE;
|
||||
removeArgs(argcp, &argv[1], 1);
|
||||
} else {
|
||||
/* Once unknown option encountered, stop command line
|
||||
processing. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
__glutOpenWin32Connection(display);
|
||||
#else
|
||||
__glutOpenXConnection(display);
|
||||
#endif
|
||||
if (geometry) {
|
||||
int flags, x, y, width, height;
|
||||
|
||||
/* Fix bogus "{width|height} may be used before set"
|
||||
warning */
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
flags = XParseGeometry(geometry, &x, &y,
|
||||
(unsigned int *) &width, (unsigned int *) &height);
|
||||
if (WidthValue & flags) {
|
||||
/* Careful because X does not allow zero or negative
|
||||
width windows */
|
||||
if (width > 0)
|
||||
__glutInitWidth = width;
|
||||
}
|
||||
if (HeightValue & flags) {
|
||||
/* Careful because X does not allow zero or negative
|
||||
height windows */
|
||||
if (height > 0)
|
||||
__glutInitHeight = height;
|
||||
}
|
||||
glutInitWindowSize(__glutInitWidth, __glutInitHeight);
|
||||
if (XValue & flags) {
|
||||
if (XNegative & flags)
|
||||
x = DisplayWidth(__glutDisplay, __glutScreen) +
|
||||
x - __glutSizeHints.width;
|
||||
/* Play safe: reject negative X locations */
|
||||
if (x >= 0)
|
||||
__glutInitX = x;
|
||||
}
|
||||
if (YValue & flags) {
|
||||
if (YNegative & flags)
|
||||
y = DisplayHeight(__glutDisplay, __glutScreen) +
|
||||
y - __glutSizeHints.height;
|
||||
/* Play safe: reject negative Y locations */
|
||||
if (y >= 0)
|
||||
__glutInitY = y;
|
||||
}
|
||||
glutInitWindowPosition(__glutInitX, __glutInitY);
|
||||
}
|
||||
__glutInitTime(&unused);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void APIENTRY
|
||||
__glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int))
|
||||
{
|
||||
__glutExitFunc = exitfunc;
|
||||
glutInit(argcp, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutInitWindowPosition(int x, int y)
|
||||
{
|
||||
__glutInitX = x;
|
||||
__glutInitY = y;
|
||||
if (x >= 0 && y >= 0) {
|
||||
__glutSizeHints.x = x;
|
||||
__glutSizeHints.y = y;
|
||||
__glutSizeHints.flags |= USPosition;
|
||||
} else {
|
||||
__glutSizeHints.flags &= ~USPosition;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutInitWindowSize(int width, int height)
|
||||
{
|
||||
__glutInitWidth = width;
|
||||
__glutInitHeight = height;
|
||||
if (width > 0 && height > 0) {
|
||||
__glutSizeHints.width = width;
|
||||
__glutSizeHints.height = height;
|
||||
__glutSizeHints.flags |= USSize;
|
||||
} else {
|
||||
__glutSizeHints.flags &= ~USSize;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutInitDisplayMode(unsigned int mask)
|
||||
{
|
||||
__glutDisplayMode = mask;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
630
src/glut/glx/glut_input.c
Normal file
630
src/glut/glx/glut_input.c
Normal file
|
|
@ -0,0 +1,630 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#if defined(__vms)
|
||||
#include <X11/XInput.h>
|
||||
#else
|
||||
#include <X11/extensions/XInput.h>
|
||||
#endif
|
||||
#include <X11/Xutil.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h> /* Win32 Multimedia API header. */
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
int __glutNumDials = 0;
|
||||
int __glutNumSpaceballButtons = 0;
|
||||
int __glutNumButtonBoxButtons = 0;
|
||||
int __glutNumTabletButtons = 0;
|
||||
int __glutNumMouseButtons = 3; /* Good guess. */
|
||||
XDevice *__glutTablet = NULL;
|
||||
XDevice *__glutDials = NULL;
|
||||
XDevice *__glutSpaceball = NULL;
|
||||
|
||||
int __glutHasJoystick = 0;
|
||||
int __glutNumJoystickButtons = 0;
|
||||
int __glutNumJoystickAxes = 0;
|
||||
|
||||
#if !defined(_WIN32)
|
||||
typedef struct _Range {
|
||||
int min;
|
||||
int range;
|
||||
} Range;
|
||||
|
||||
#define NUM_SPACEBALL_AXIS 6
|
||||
#define NUM_TABLET_AXIS 2
|
||||
#define NUM_DIALS_AXIS 8
|
||||
|
||||
Range __glutSpaceballRange[NUM_SPACEBALL_AXIS];
|
||||
Range __glutTabletRange[NUM_TABLET_AXIS];
|
||||
int *__glutDialsResolution;
|
||||
|
||||
/* Safely assumes 0 is an illegal event type for X Input
|
||||
extension events. */
|
||||
int __glutDeviceMotionNotify = 0;
|
||||
int __glutDeviceButtonPress = 0;
|
||||
int __glutDeviceButtonPressGrab = 0;
|
||||
int __glutDeviceButtonRelease = 0;
|
||||
int __glutDeviceStateNotify = 0;
|
||||
|
||||
static int
|
||||
normalizeTabletPos(int axis, int rawValue)
|
||||
{
|
||||
assert(rawValue >= __glutTabletRange[axis].min);
|
||||
assert(rawValue <= __glutTabletRange[axis].min
|
||||
+ __glutTabletRange[axis].range);
|
||||
/* Normalize rawValue to between 0 and 4000. */
|
||||
return ((rawValue - __glutTabletRange[axis].min) * 4000) /
|
||||
__glutTabletRange[axis].range;
|
||||
}
|
||||
|
||||
static int
|
||||
normalizeDialAngle(int axis, int rawValue)
|
||||
{
|
||||
/* XXX Assumption made that the resolution of the device is
|
||||
number of clicks for one complete dial revolution. This
|
||||
is true for SGI's dial & button box. */
|
||||
return (rawValue * 360.0) / __glutDialsResolution[axis];
|
||||
}
|
||||
|
||||
static int
|
||||
normalizeSpaceballAngle(int axis, int rawValue)
|
||||
{
|
||||
assert(rawValue >= __glutSpaceballRange[axis].min);
|
||||
assert(rawValue <= __glutSpaceballRange[axis].min +
|
||||
__glutSpaceballRange[axis].range);
|
||||
/* Normalize rawValue to between -1800 and 1800. */
|
||||
return ((rawValue - __glutSpaceballRange[axis].min) * 3600) /
|
||||
__glutSpaceballRange[axis].range - 1800;
|
||||
}
|
||||
|
||||
static int
|
||||
normalizeSpaceballDelta(int axis, int rawValue)
|
||||
{
|
||||
assert(rawValue >= __glutSpaceballRange[axis].min);
|
||||
assert(rawValue <= __glutSpaceballRange[axis].min +
|
||||
__glutSpaceballRange[axis].range);
|
||||
/* Normalize rawValue to between -1000 and 1000. */
|
||||
return ((rawValue - __glutSpaceballRange[axis].min) * 2000) /
|
||||
__glutSpaceballRange[axis].range - 1000;
|
||||
}
|
||||
|
||||
static void
|
||||
queryTabletPos(GLUTwindow * window)
|
||||
{
|
||||
XDeviceState *state;
|
||||
XInputClass *any;
|
||||
XValuatorState *v;
|
||||
int i;
|
||||
|
||||
state = XQueryDeviceState(__glutDisplay, __glutTablet);
|
||||
any = state->data;
|
||||
for (i = 0; i < state->num_classes; i++) {
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
switch (any->c_class) {
|
||||
#else
|
||||
switch (any->class) {
|
||||
#endif
|
||||
case ValuatorClass:
|
||||
v = (XValuatorState *) any;
|
||||
if (v->num_valuators < 2)
|
||||
goto end;
|
||||
if (window->tabletPos[0] == -1)
|
||||
window->tabletPos[0] = normalizeTabletPos(0, v->valuators[0]);
|
||||
if (window->tabletPos[1] == -1)
|
||||
window->tabletPos[1] = normalizeTabletPos(1, v->valuators[1]);
|
||||
}
|
||||
any = (XInputClass *) ((char *) any + any->length);
|
||||
}
|
||||
end:
|
||||
XFreeDeviceState(state);
|
||||
}
|
||||
|
||||
static void
|
||||
tabletPosChange(GLUTwindow * window, int first, int count, int *data)
|
||||
{
|
||||
int i, value, genEvent = 0;
|
||||
|
||||
for (i = first; i < first + count; i++) {
|
||||
switch (i) {
|
||||
case 0: /* X axis */
|
||||
case 1: /* Y axis */
|
||||
value = normalizeTabletPos(i, data[i - first]);
|
||||
if (value != window->tabletPos[i]) {
|
||||
window->tabletPos[i] = value;
|
||||
genEvent = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (window->tabletPos[0] == -1 || window->tabletPos[1] == -1)
|
||||
queryTabletPos(window);
|
||||
if (genEvent)
|
||||
window->tabletMotion(window->tabletPos[0], window->tabletPos[1]);
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
int
|
||||
__glutProcessDeviceEvents(XEvent * event)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
GLUTwindow *window;
|
||||
|
||||
/* XXX Ugly code fan out. */
|
||||
|
||||
/* Can't use switch/case since X Input event types are
|
||||
dynamic. */
|
||||
|
||||
if (__glutDeviceMotionNotify && event->type == __glutDeviceMotionNotify) {
|
||||
XDeviceMotionEvent *devmot = (XDeviceMotionEvent *) event;
|
||||
|
||||
window = __glutGetWindow(devmot->window);
|
||||
if (window) {
|
||||
if (__glutTablet
|
||||
&& devmot->deviceid == __glutTablet->device_id
|
||||
&& window->tabletMotion) {
|
||||
tabletPosChange(window, devmot->first_axis, devmot->axes_count,
|
||||
devmot->axis_data);
|
||||
} else if (__glutDials
|
||||
&& devmot->deviceid == __glutDials->device_id
|
||||
&& window->dials) {
|
||||
int i, first = devmot->first_axis, count = devmot->axes_count;
|
||||
|
||||
for (i = first; i < first + count; i++)
|
||||
window->dials(i + 1,
|
||||
normalizeDialAngle(i, devmot->axis_data[i - first]));
|
||||
} else if (__glutSpaceball
|
||||
&& devmot->deviceid == __glutSpaceball->device_id) {
|
||||
/* XXX Assume that space ball motion events come in as
|
||||
all the first 6 axes. Assume first 3 axes are XYZ
|
||||
translations; second 3 axes are XYZ rotations. */
|
||||
if (devmot->first_axis == 0 && devmot->axes_count == 6) {
|
||||
if (window->spaceMotion)
|
||||
window->spaceMotion(
|
||||
normalizeSpaceballDelta(0, devmot->axis_data[0]),
|
||||
normalizeSpaceballDelta(1, devmot->axis_data[1]),
|
||||
normalizeSpaceballDelta(2, devmot->axis_data[2]));
|
||||
if (window->spaceRotate)
|
||||
window->spaceRotate(
|
||||
normalizeSpaceballAngle(3, devmot->axis_data[3]),
|
||||
normalizeSpaceballAngle(4, devmot->axis_data[4]),
|
||||
normalizeSpaceballAngle(5, devmot->axis_data[5]));
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} else if (__glutDeviceButtonPress
|
||||
&& event->type == __glutDeviceButtonPress) {
|
||||
XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event;
|
||||
|
||||
window = __glutGetWindow(devbtn->window);
|
||||
if (window) {
|
||||
if (__glutTablet
|
||||
&& devbtn->deviceid == __glutTablet->device_id
|
||||
&& window->tabletButton
|
||||
&& devbtn->first_axis == 0
|
||||
&& devbtn->axes_count == 2) {
|
||||
tabletPosChange(window, devbtn->first_axis, devbtn->axes_count,
|
||||
devbtn->axis_data);
|
||||
window->tabletButton(devbtn->button, GLUT_DOWN,
|
||||
window->tabletPos[0], window->tabletPos[1]);
|
||||
} else if (__glutDials
|
||||
&& devbtn->deviceid == __glutDials->device_id
|
||||
&& window->buttonBox) {
|
||||
window->buttonBox(devbtn->button, GLUT_DOWN);
|
||||
} else if (__glutSpaceball
|
||||
&& devbtn->deviceid == __glutSpaceball->device_id
|
||||
&& window->spaceButton) {
|
||||
window->spaceButton(devbtn->button, GLUT_DOWN);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} else if (__glutDeviceButtonRelease
|
||||
&& event->type == __glutDeviceButtonRelease) {
|
||||
XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event;
|
||||
|
||||
window = __glutGetWindow(devbtn->window);
|
||||
if (window) {
|
||||
if (__glutTablet
|
||||
&& devbtn->deviceid == __glutTablet->device_id
|
||||
&& window->tabletButton
|
||||
&& devbtn->first_axis == 0
|
||||
&& devbtn->axes_count == 2) {
|
||||
tabletPosChange(window, devbtn->first_axis, devbtn->axes_count,
|
||||
devbtn->axis_data);
|
||||
window->tabletButton(devbtn->button, GLUT_UP,
|
||||
window->tabletPos[0], window->tabletPos[1]);
|
||||
} else if (__glutDials
|
||||
&& devbtn->deviceid == __glutDials->device_id
|
||||
&& window->buttonBox) {
|
||||
window->buttonBox(devbtn->button, GLUT_UP);
|
||||
} else if (__glutSpaceball
|
||||
&& devbtn->deviceid == __glutSpaceball->device_id
|
||||
&& window->spaceButton) {
|
||||
window->spaceButton(devbtn->button, GLUT_UP);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
JOYINFOEX info;
|
||||
int njoyId = 0;
|
||||
int nConnected = 0;
|
||||
MMRESULT result;
|
||||
|
||||
/* Loop through all possible joystick IDs until we get the error
|
||||
JOYERR_PARMS. Count the number of times we get JOYERR_NOERROR
|
||||
indicating an installed joystick driver with a joystick currently
|
||||
attached to the port. */
|
||||
while ((result = joyGetPosEx(njoyId++,&info)) != JOYERR_PARMS) {
|
||||
if (result == JOYERR_NOERROR) {
|
||||
++nConnected; /* The count of connected joysticks. */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GLUTeventParser eventParser =
|
||||
{__glutProcessDeviceEvents, NULL};
|
||||
|
||||
static void
|
||||
addDeviceEventParser(void)
|
||||
{
|
||||
static Bool been_here = False;
|
||||
|
||||
if (been_here)
|
||||
return;
|
||||
been_here = True;
|
||||
__glutRegisterEventParser(&eventParser);
|
||||
}
|
||||
|
||||
static int
|
||||
probeDevices(void)
|
||||
{
|
||||
static Bool been_here = False;
|
||||
static int support;
|
||||
#if !defined(_WIN32)
|
||||
XExtensionVersion *version;
|
||||
XDeviceInfoPtr device_info, device;
|
||||
XAnyClassPtr any;
|
||||
XButtonInfoPtr b;
|
||||
XValuatorInfoPtr v;
|
||||
XAxisInfoPtr a;
|
||||
int num_dev, btns, dials;
|
||||
int i, j, k;
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
if (been_here) {
|
||||
return support;
|
||||
}
|
||||
been_here = True;
|
||||
|
||||
#if !defined(_WIN32)
|
||||
version = XGetExtensionVersion(__glutDisplay, "XInputExtension");
|
||||
/* Ugh. XInput extension API forces annoying cast of a pointer
|
||||
to a long so it can be compared with the NoSuchExtension
|
||||
value (#defined to 1). */
|
||||
if (version == NULL || ((long) version) == NoSuchExtension) {
|
||||
support = 0;
|
||||
return support;
|
||||
}
|
||||
XFree(version);
|
||||
device_info = XListInputDevices(__glutDisplay, &num_dev);
|
||||
if (device_info) {
|
||||
for (i = 0; i < num_dev; i++) {
|
||||
/* XXX These are SGI names for these devices;
|
||||
unfortunately, no good standard exists for standard
|
||||
types of X input extension devices. */
|
||||
|
||||
device = &device_info[i];
|
||||
any = (XAnyClassPtr) device->inputclassinfo;
|
||||
|
||||
if (!__glutSpaceball && !strcmp(device->name, "spaceball")) {
|
||||
v = NULL;
|
||||
b = NULL;
|
||||
for (j = 0; j < device->num_classes; j++) {
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
switch (any->c_class) {
|
||||
#else
|
||||
switch (any->class) {
|
||||
#endif
|
||||
case ButtonClass:
|
||||
b = (XButtonInfoPtr) any;
|
||||
btns = b->num_buttons;
|
||||
break;
|
||||
case ValuatorClass:
|
||||
v = (XValuatorInfoPtr) any;
|
||||
/* Sanity check: at least 6 valuators? */
|
||||
if (v->num_axes < NUM_SPACEBALL_AXIS)
|
||||
goto skip_device;
|
||||
a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
|
||||
for (k = 0; k < NUM_SPACEBALL_AXIS; k++, a++) {
|
||||
__glutSpaceballRange[k].min = a->min_value;
|
||||
__glutSpaceballRange[k].range = a->max_value - a->min_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
any = (XAnyClassPtr) ((char *) any + any->length);
|
||||
}
|
||||
if (v) {
|
||||
__glutSpaceball = XOpenDevice(__glutDisplay, device->id);
|
||||
if (__glutSpaceball) {
|
||||
__glutNumSpaceballButtons = btns;
|
||||
addDeviceEventParser();
|
||||
}
|
||||
}
|
||||
} else if (!__glutDials && !strcmp(device->name, "dial+buttons")) {
|
||||
v = NULL;
|
||||
b = NULL;
|
||||
for (j = 0; j < device->num_classes; j++) {
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
switch (any->c_class) {
|
||||
#else
|
||||
switch (any->class) {
|
||||
#endif
|
||||
case ButtonClass:
|
||||
b = (XButtonInfoPtr) any;
|
||||
btns = b->num_buttons;
|
||||
break;
|
||||
case ValuatorClass:
|
||||
v = (XValuatorInfoPtr) any;
|
||||
/* Sanity check: at least 8 valuators? */
|
||||
if (v->num_axes < NUM_DIALS_AXIS)
|
||||
goto skip_device;
|
||||
dials = v->num_axes;
|
||||
__glutDialsResolution = (int *) malloc(sizeof(int) * dials);
|
||||
a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
|
||||
for (k = 0; k < dials; k++, a++) {
|
||||
__glutDialsResolution[k] = a->resolution;
|
||||
}
|
||||
break;
|
||||
}
|
||||
any = (XAnyClassPtr) ((char *) any + any->length);
|
||||
}
|
||||
if (v) {
|
||||
__glutDials = XOpenDevice(__glutDisplay, device->id);
|
||||
if (__glutDials) {
|
||||
__glutNumButtonBoxButtons = btns;
|
||||
__glutNumDials = dials;
|
||||
addDeviceEventParser();
|
||||
}
|
||||
}
|
||||
} else if (!__glutTablet && !strcmp(device->name, "tablet")) {
|
||||
v = NULL;
|
||||
b = NULL;
|
||||
for (j = 0; j < device->num_classes; j++) {
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
switch (any->c_class) {
|
||||
#else
|
||||
switch (any->class) {
|
||||
#endif
|
||||
case ButtonClass:
|
||||
b = (XButtonInfoPtr) any;
|
||||
btns = b->num_buttons;
|
||||
break;
|
||||
case ValuatorClass:
|
||||
v = (XValuatorInfoPtr) any;
|
||||
/* Sanity check: exactly 2 valuators? */
|
||||
if (v->num_axes != NUM_TABLET_AXIS)
|
||||
goto skip_device;
|
||||
a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo));
|
||||
for (k = 0; k < NUM_TABLET_AXIS; k++, a++) {
|
||||
__glutTabletRange[k].min = a->min_value;
|
||||
__glutTabletRange[k].range = a->max_value - a->min_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
any = (XAnyClassPtr) ((char *) any + any->length);
|
||||
}
|
||||
if (v) {
|
||||
__glutTablet = XOpenDevice(__glutDisplay, device->id);
|
||||
if (__glutTablet) {
|
||||
__glutNumTabletButtons = btns;
|
||||
addDeviceEventParser();
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(device->name, "mouse")) {
|
||||
for (j = 0; j < device->num_classes; j++) {
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
if (any->c_class == ButtonClass) {
|
||||
#else
|
||||
if (any->class == ButtonClass) {
|
||||
#endif
|
||||
b = (XButtonInfoPtr) any;
|
||||
__glutNumMouseButtons = b->num_buttons;
|
||||
}
|
||||
any = (XAnyClassPtr) ((char *) any + any->length);
|
||||
}
|
||||
}
|
||||
skip_device:;
|
||||
}
|
||||
XFreeDeviceList(device_info);
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
__glutNumMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
|
||||
#endif /* !_WIN32 */
|
||||
/* X Input extension might be supported, but only if there is
|
||||
a tablet, dials, or spaceball do we claim devices are
|
||||
supported. */
|
||||
support = __glutTablet || __glutDials || __glutSpaceball;
|
||||
return support;
|
||||
}
|
||||
|
||||
void
|
||||
__glutUpdateInputDeviceMask(GLUTwindow * window)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
/* 5 (dial and buttons) + 5 (tablet locator and buttons) + 5
|
||||
(Spaceball buttons and axis) = 15 */
|
||||
XEventClass eventList[15];
|
||||
int rc, numEvents;
|
||||
|
||||
rc = probeDevices();
|
||||
if (rc) {
|
||||
numEvents = 0;
|
||||
if (__glutTablet) {
|
||||
if (window->tabletMotion) {
|
||||
DeviceMotionNotify(__glutTablet, __glutDeviceMotionNotify,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
if (window->tabletButton) {
|
||||
DeviceButtonPress(__glutTablet, __glutDeviceButtonPress,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
DeviceButtonPressGrab(__glutTablet, __glutDeviceButtonPressGrab,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
DeviceButtonRelease(__glutTablet, __glutDeviceButtonRelease,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
if (window->tabletMotion || window->tabletButton) {
|
||||
DeviceStateNotify(__glutTablet, __glutDeviceStateNotify,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
}
|
||||
if (__glutDials) {
|
||||
if (window->dials) {
|
||||
DeviceMotionNotify(__glutDials, __glutDeviceMotionNotify,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
if (window->buttonBox) {
|
||||
DeviceButtonPress(__glutDials, __glutDeviceButtonPress,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
DeviceButtonPressGrab(__glutDials, __glutDeviceButtonPressGrab,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
DeviceButtonRelease(__glutDials, __glutDeviceButtonRelease,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
if (window->dials || window->buttonBox) {
|
||||
DeviceStateNotify(__glutDials, __glutDeviceStateNotify,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
}
|
||||
if (__glutSpaceball) {
|
||||
if (window->spaceMotion || window->spaceRotate) {
|
||||
DeviceMotionNotify(__glutSpaceball, __glutDeviceMotionNotify,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
if (window->spaceButton) {
|
||||
DeviceButtonPress(__glutSpaceball, __glutDeviceButtonPress,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
DeviceButtonPressGrab(__glutSpaceball, __glutDeviceButtonPressGrab,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
DeviceButtonRelease(__glutSpaceball, __glutDeviceButtonRelease,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
if (window->spaceMotion || window->spaceRotate || window->spaceButton) {
|
||||
DeviceStateNotify(__glutSpaceball, __glutDeviceStateNotify,
|
||||
eventList[numEvents]);
|
||||
numEvents++;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (window->children) {
|
||||
GLUTwindow *child = window->children;
|
||||
|
||||
do {
|
||||
XChangeDeviceDontPropagateList(__glutDisplay, child->win,
|
||||
numEvents, eventList, AddToList);
|
||||
child = child->siblings;
|
||||
} while (child);
|
||||
}
|
||||
#endif
|
||||
XSelectExtensionEvent(__glutDisplay, window->win,
|
||||
eventList, numEvents);
|
||||
if (window->overlay) {
|
||||
XSelectExtensionEvent(__glutDisplay, window->overlay->win,
|
||||
eventList, numEvents);
|
||||
}
|
||||
} else {
|
||||
/* X Input extension not supported; no chance for exotic
|
||||
input devices. */
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutDeviceGet(GLenum param)
|
||||
{
|
||||
probeDevices();
|
||||
switch (param) {
|
||||
case GLUT_HAS_KEYBOARD:
|
||||
case GLUT_HAS_MOUSE:
|
||||
/* Assume window system always has mouse and keyboard. */
|
||||
return 1;
|
||||
case GLUT_HAS_SPACEBALL:
|
||||
return __glutSpaceball != NULL;
|
||||
case GLUT_HAS_DIAL_AND_BUTTON_BOX:
|
||||
return __glutDials != NULL;
|
||||
case GLUT_HAS_TABLET:
|
||||
return __glutTablet != NULL;
|
||||
case GLUT_NUM_MOUSE_BUTTONS:
|
||||
return __glutNumMouseButtons;
|
||||
case GLUT_NUM_SPACEBALL_BUTTONS:
|
||||
return __glutNumSpaceballButtons;
|
||||
case GLUT_NUM_BUTTON_BOX_BUTTONS:
|
||||
return __glutNumButtonBoxButtons;
|
||||
case GLUT_NUM_DIALS:
|
||||
return __glutNumDials;
|
||||
case GLUT_NUM_TABLET_BUTTONS:
|
||||
return __glutNumTabletButtons;
|
||||
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
|
||||
return __glutCurrentWindow->ignoreKeyRepeat;
|
||||
#ifndef _WIN32
|
||||
case GLUT_DEVICE_KEY_REPEAT:
|
||||
{
|
||||
XKeyboardState state;
|
||||
|
||||
XGetKeyboardControl(__glutDisplay, &state);
|
||||
return state.global_auto_repeat;
|
||||
}
|
||||
case GLUT_JOYSTICK_POLL_RATE:
|
||||
return 0;
|
||||
#else
|
||||
case GLUT_DEVICE_KEY_REPEAT:
|
||||
/* Win32 cannot globally disable key repeat. */
|
||||
return GLUT_KEY_REPEAT_ON;
|
||||
case GLUT_JOYSTICK_POLL_RATE:
|
||||
return __glutCurrentWindow->joyPollInterval;
|
||||
#endif
|
||||
case GLUT_HAS_JOYSTICK:
|
||||
return __glutHasJoystick;
|
||||
case GLUT_JOYSTICK_BUTTONS:
|
||||
return __glutNumJoystickButtons;
|
||||
case GLUT_JOYSTICK_AXES:
|
||||
return __glutNumJoystickAxes;
|
||||
default:
|
||||
__glutWarning("invalid glutDeviceGet parameter: %d", param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
80
src/glut/glx/glut_joy.c
Normal file
80
src/glut/glx/glut_joy.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1997, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h> /* Win32 Multimedia API header. */
|
||||
#endif
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutJoystickFunc(GLUTjoystickCB joystickFunc, int pollInterval)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (joystickFunc && (pollInterval > 0)) {
|
||||
if (__glutCurrentWindow->entryState == WM_SETFOCUS) {
|
||||
MMRESULT result;
|
||||
|
||||
/* Capture joystick focus if current window has
|
||||
focus now. */
|
||||
result = joySetCapture(__glutCurrentWindow->win,
|
||||
JOYSTICKID1, 0, TRUE);
|
||||
if (result == JOYERR_NOERROR) {
|
||||
(void) joySetThreshold(JOYSTICKID1, pollInterval);
|
||||
}
|
||||
}
|
||||
__glutCurrentWindow->joyPollInterval = pollInterval;
|
||||
} else {
|
||||
/* Release joystick focus if current window has
|
||||
focus now. */
|
||||
if (__glutCurrentWindow->joystick
|
||||
&& (__glutCurrentWindow->joyPollInterval > 0)
|
||||
&& (__glutCurrentWindow->entryState == WM_SETFOCUS)) {
|
||||
(void) joyReleaseCapture(JOYSTICKID1);
|
||||
}
|
||||
__glutCurrentWindow->joyPollInterval = 0;
|
||||
}
|
||||
__glutCurrentWindow->joystick = joystickFunc;
|
||||
#else
|
||||
/* XXX No support currently for X11 joysticks. */
|
||||
#endif
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutForceJoystickFunc(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (__glutCurrentWindow->joystick) {
|
||||
JOYINFOEX jix;
|
||||
MMRESULT res;
|
||||
int x, y, z;
|
||||
|
||||
/* Poll the joystick. */
|
||||
jix.dwSize = sizeof(jix);
|
||||
jix.dwFlags = JOY_RETURNALL;
|
||||
res = joyGetPosEx(JOYSTICKID1,&jix);
|
||||
if (res == JOYERR_NOERROR) {
|
||||
|
||||
/* Convert to int for scaling. */
|
||||
x = jix.dwXpos;
|
||||
y = jix.dwYpos;
|
||||
z = jix.dwZpos;
|
||||
|
||||
#define SCALE(v) ((int) ((v - 32767)/32.768))
|
||||
|
||||
__glutCurrentWindow->joystick(jix.dwButtons,
|
||||
SCALE(x), SCALE(y), SCALE(z));
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* XXX No support currently for X11 joysticks. */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
29
src/glut/glx/glut_key.c
Normal file
29
src/glut/glx/glut_key.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutKeyboardFunc(GLUTkeyboardCB keyboardFunc)
|
||||
{
|
||||
__glutChangeWindowEventMask(KeyPressMask,
|
||||
keyboardFunc != NULL || __glutCurrentWindow->special != NULL);
|
||||
__glutCurrentWindow->keyboard = keyboardFunc;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSpecialFunc(GLUTspecialCB specialFunc)
|
||||
{
|
||||
__glutChangeWindowEventMask(KeyPressMask,
|
||||
specialFunc != NULL || __glutCurrentWindow->keyboard != NULL);
|
||||
__glutCurrentWindow->special = specialFunc;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
29
src/glut/glx/glut_keyctrl.c
Normal file
29
src/glut/glx/glut_keyctrl.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutIgnoreKeyRepeat(int ignore)
|
||||
{
|
||||
__glutCurrentWindow->ignoreKeyRepeat = ignore;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSetKeyRepeat(int repeatMode)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
XKeyboardControl values;
|
||||
|
||||
/* GLUT's repeatMode #define's match the Xlib API values. */
|
||||
values.auto_repeat_mode = repeatMode;
|
||||
XChangeKeyboardControl(__glutDisplay, KBAutoRepeatMode, &values);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
29
src/glut/glx/glut_keyup.c
Normal file
29
src/glut/glx/glut_keyup.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutKeyboardUpFunc(GLUTkeyboardCB keyboardUpFunc)
|
||||
{
|
||||
__glutChangeWindowEventMask(KeyReleaseMask,
|
||||
keyboardUpFunc != NULL || __glutCurrentWindow->specialUp != NULL);
|
||||
__glutCurrentWindow->keyboardUp = keyboardUpFunc;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSpecialUpFunc(GLUTspecialCB specialUpFunc)
|
||||
{
|
||||
__glutChangeWindowEventMask(KeyReleaseMask,
|
||||
specialUpFunc != NULL || __glutCurrentWindow->keyboardUp != NULL);
|
||||
__glutCurrentWindow->specialUp = specialUpFunc;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
1010
src/glut/glx/glut_menu.c
Normal file
1010
src/glut/glx/glut_menu.c
Normal file
File diff suppressed because it is too large
Load diff
185
src/glut/glx/glut_menu2.c
Normal file
185
src/glut/glx/glut_menu2.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
/* glut_menu2.c implements the little used GLUT menu calls in
|
||||
a distinct file from glut_menu.c for slim static linking. */
|
||||
|
||||
/* The Win32 GLUT file win32_menu.c completely re-implements all
|
||||
the menuing functionality implemented. This file is used only by
|
||||
the X Window System version of GLUT. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "glutint.h"
|
||||
#include "layerutil.h"
|
||||
|
||||
/* CENTRY */
|
||||
/* DEPRICATED, use glutMenuStatusFunc instead. */
|
||||
void APIENTRY
|
||||
glutMenuStateFunc(GLUTmenuStateCB menuStateFunc)
|
||||
{
|
||||
__glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc)
|
||||
{
|
||||
__glutMenuStatusFunc = menuStatusFunc;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutDestroyMenu(int menunum)
|
||||
{
|
||||
GLUTmenu *menu = __glutGetMenuByNum(menunum);
|
||||
GLUTmenuItem *item, *next;
|
||||
|
||||
if (__glutMappedMenu)
|
||||
__glutMenuModificationError();
|
||||
assert(menu->id == menunum - 1);
|
||||
XDestroySubwindows(__glutDisplay, menu->win);
|
||||
XDestroyWindow(__glutDisplay, menu->win);
|
||||
__glutMenuList[menunum - 1] = NULL;
|
||||
/* free all menu entries */
|
||||
item = menu->list;
|
||||
while (item) {
|
||||
assert(item->menu == menu);
|
||||
next = item->next;
|
||||
free(item->label);
|
||||
free(item);
|
||||
item = next;
|
||||
}
|
||||
if (__glutCurrentMenu == menu) {
|
||||
__glutCurrentMenu = NULL;
|
||||
}
|
||||
free(menu);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutChangeToMenuEntry(int num, const char *label, int value)
|
||||
{
|
||||
GLUTmenuItem *item;
|
||||
int i;
|
||||
|
||||
if (__glutMappedMenu)
|
||||
__glutMenuModificationError();
|
||||
i = __glutCurrentMenu->num;
|
||||
item = __glutCurrentMenu->list;
|
||||
while (item) {
|
||||
if (i == num) {
|
||||
if (item->isTrigger) {
|
||||
/* If changing a submenu trigger to a menu entry, we
|
||||
need to account for submenus. */
|
||||
item->menu->submenus--;
|
||||
}
|
||||
free(item->label);
|
||||
__glutSetMenuItem(item, label, value, False);
|
||||
return;
|
||||
}
|
||||
i--;
|
||||
item = item->next;
|
||||
}
|
||||
__glutWarning("Current menu has no %d item.", num);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutChangeToSubMenu(int num, const char *label, int menu)
|
||||
{
|
||||
GLUTmenuItem *item;
|
||||
int i;
|
||||
|
||||
if (__glutMappedMenu)
|
||||
__glutMenuModificationError();
|
||||
i = __glutCurrentMenu->num;
|
||||
item = __glutCurrentMenu->list;
|
||||
while (item) {
|
||||
if (i == num) {
|
||||
if (!item->isTrigger) {
|
||||
/* If changing a menu entry to as submenu trigger, we
|
||||
need to account for submenus. */
|
||||
item->menu->submenus++;
|
||||
}
|
||||
free(item->label);
|
||||
__glutSetMenuItem(item, label, /* base 0 */ menu - 1, True);
|
||||
return;
|
||||
}
|
||||
i--;
|
||||
item = item->next;
|
||||
}
|
||||
__glutWarning("Current menu has no %d item.", num);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutRemoveMenuItem(int num)
|
||||
{
|
||||
GLUTmenuItem *item, **prev, *remaining;
|
||||
int pixwidth, i;
|
||||
|
||||
if (__glutMappedMenu)
|
||||
__glutMenuModificationError();
|
||||
i = __glutCurrentMenu->num;
|
||||
prev = &__glutCurrentMenu->list;
|
||||
item = __glutCurrentMenu->list;
|
||||
/* If menu item is removed, the menu's pixwidth may need to
|
||||
be recomputed. */
|
||||
pixwidth = 1;
|
||||
while (item) {
|
||||
if (i == num) {
|
||||
/* If this menu item's pixwidth is as wide as the menu's
|
||||
pixwidth, removing this menu item will necessitate
|
||||
shrinking the menu's pixwidth. */
|
||||
if (item->pixwidth >= __glutCurrentMenu->pixwidth) {
|
||||
/* Continue recalculating menu pixwidth, first skipping
|
||||
the removed item. */
|
||||
remaining = item->next;
|
||||
while (remaining) {
|
||||
if (remaining->pixwidth > pixwidth) {
|
||||
pixwidth = remaining->pixwidth;
|
||||
}
|
||||
remaining = remaining->next;
|
||||
}
|
||||
__glutCurrentMenu->pixwidth = pixwidth;
|
||||
}
|
||||
__glutCurrentMenu->num--;
|
||||
__glutCurrentMenu->managed = False;
|
||||
|
||||
/* Patch up menu's item list. */
|
||||
*prev = item->next;
|
||||
|
||||
free(item->label);
|
||||
free(item);
|
||||
return;
|
||||
}
|
||||
if (item->pixwidth > pixwidth) {
|
||||
pixwidth = item->pixwidth;
|
||||
}
|
||||
i--;
|
||||
prev = &item->next;
|
||||
item = item->next;
|
||||
}
|
||||
__glutWarning("Current menu has no %d item.", num);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutDetachMenu(int button)
|
||||
{
|
||||
if (__glutMappedMenu)
|
||||
__glutMenuModificationError();
|
||||
if (__glutCurrentWindow->menu[button] > 0) {
|
||||
__glutCurrentWindow->buttonUses--;
|
||||
__glutChangeWindowEventMask(ButtonPressMask | ButtonReleaseMask,
|
||||
__glutCurrentWindow->buttonUses > 0);
|
||||
__glutCurrentWindow->menu[button] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
57
src/glut/glx/glut_mesa.c
Normal file
57
src/glut/glx/glut_mesa.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1996. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "glutint.h"
|
||||
|
||||
int __glutMesaSwapHackSupport = 0; /* Not supported until
|
||||
proven otherwise. */
|
||||
|
||||
/* Use the "Mesa swap hack" if reasonable if and only if
|
||||
MESA_SWAP_HACK is set to something whose first character is
|
||||
not "N" or "n" AND "Brian Paul" is the vendor string AND
|
||||
"Mesa X11"* (or "Mesa" for backward compatibility) is the
|
||||
renderer string.
|
||||
|
||||
Anyone who modifies Mesa so that glXSwapBuffers does not
|
||||
simply blit the previously rendered back buffer should
|
||||
change either their vendor or renderer string to avoid
|
||||
confusing GLUT. */
|
||||
|
||||
void
|
||||
__glutDetermineMesaSwapHackSupport(void)
|
||||
{
|
||||
static int doneAlready = 0;
|
||||
char *env, *vendor, *renderer;
|
||||
|
||||
if (doneAlready)
|
||||
return;
|
||||
env = getenv("MESA_SWAP_HACK");
|
||||
if (env) {
|
||||
if ((env[0] != 'n') && (env[0] != 'N')) {
|
||||
vendor = (char *) glGetString(GL_VENDOR);
|
||||
renderer = (char *) glGetString(GL_RENDERER);
|
||||
|
||||
/* Old versions of X11 Mesa uses the renderer string
|
||||
"Mesa"; Brian plans to start using "Mesa X11" to
|
||||
distinguish the X version of Mesa from other flavor
|
||||
such as Windows or 3Dfx. */
|
||||
|
||||
#define MESA_X11 "Mesa X11"
|
||||
|
||||
/* XXX At some point in the future, eliminate the
|
||||
backward compatibility for the old "Mesa" renderer
|
||||
string. */
|
||||
|
||||
if (!strcmp(vendor, "Brian Paul") && (!strcmp(renderer, "Mesa") ||
|
||||
!strncmp(renderer, MESA_X11, sizeof(MESA_X11) - 1)))
|
||||
__glutMesaSwapHackSupport = 1;
|
||||
}
|
||||
}
|
||||
doneAlready = 1;
|
||||
}
|
||||
31
src/glut/glx/glut_modifier.c
Normal file
31
src/glut/glx/glut_modifier.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutGetModifiers(void)
|
||||
{
|
||||
int modifiers;
|
||||
|
||||
if(__glutModifierMask == (unsigned int) ~0) {
|
||||
__glutWarning(
|
||||
"glutCurrentModifiers: do not call outside core input callback.");
|
||||
return 0;
|
||||
}
|
||||
modifiers = 0;
|
||||
if(__glutModifierMask & (ShiftMask|LockMask))
|
||||
modifiers |= GLUT_ACTIVE_SHIFT;
|
||||
if(__glutModifierMask & ControlMask)
|
||||
modifiers |= GLUT_ACTIVE_CTRL;
|
||||
if(__glutModifierMask & Mod1Mask)
|
||||
modifiers |= GLUT_ACTIVE_ALT;
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
2451
src/glut/glx/glut_mroman.c
Normal file
2451
src/glut/glx/glut_mroman.c
Normal file
File diff suppressed because it is too large
Load diff
607
src/glut/glx/glut_overlay.c
Normal file
607
src/glut/glx/glut_overlay.c
Normal file
|
|
@ -0,0 +1,607 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h> /* for XA_RGB_DEFAULT_MAP atom */
|
||||
#if defined (__vms)
|
||||
#include <Xmu/StdCmap.h> /* for XmuLookupStandardColormap */
|
||||
#else
|
||||
#include <X11/Xmu/StdCmap.h> /* for XmuLookupStandardColormap */
|
||||
#endif
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
#include "glutint.h"
|
||||
#include "layerutil.h"
|
||||
|
||||
static Criterion requiredOverlayCriteria[] =
|
||||
{
|
||||
{LEVEL, EQ, 1}, /* This entry gets poked in
|
||||
determineOverlayVisual. */
|
||||
{TRANSPARENT, EQ, 1},
|
||||
{XPSEUDOCOLOR, EQ, 1},
|
||||
{RGBA, EQ, 0},
|
||||
{BUFFER_SIZE, GTE, 1}
|
||||
};
|
||||
static int numRequiredOverlayCriteria = sizeof(requiredOverlayCriteria) / sizeof(Criterion);
|
||||
static int requiredOverlayCriteriaMask =
|
||||
(1 << LEVEL) | (1 << TRANSPARENT) | (1 << XSTATICGRAY) | (1 << RGBA) | (1 << CI_MODE);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
static int
|
||||
checkOverlayAcceptability(XVisualInfo * vi, unsigned int mode)
|
||||
{
|
||||
int value;
|
||||
|
||||
/* Must support OpenGL. */
|
||||
glXGetConfig(__glutDisplay, vi, GLX_USE_GL, &value);
|
||||
if (!value)
|
||||
return 1;
|
||||
|
||||
/* Must be color index. */
|
||||
glXGetConfig(__glutDisplay, vi, GLX_RGBA, &value);
|
||||
if (value)
|
||||
return 1;
|
||||
|
||||
/* Must match single/double buffering request. */
|
||||
glXGetConfig(__glutDisplay, vi, GLX_DOUBLEBUFFER, &value);
|
||||
if (GLUT_WIND_IS_DOUBLE(mode) != (value != 0))
|
||||
return 1;
|
||||
|
||||
/* Must match mono/stereo request. */
|
||||
glXGetConfig(__glutDisplay, vi, GLX_STEREO, &value);
|
||||
if (GLUT_WIND_IS_STEREO(mode) != (value != 0))
|
||||
return 1;
|
||||
|
||||
/* Alpha and accumulation buffers incompatible with color
|
||||
index. */
|
||||
if (GLUT_WIND_HAS_ALPHA(mode) || GLUT_WIND_HAS_ACCUM(mode))
|
||||
return 1;
|
||||
|
||||
/* Look for depth buffer if requested. */
|
||||
glXGetConfig(__glutDisplay, vi, GLX_DEPTH_SIZE, &value);
|
||||
if (GLUT_WIND_HAS_DEPTH(mode) && (value <= 0))
|
||||
return 1;
|
||||
|
||||
/* Look for stencil buffer if requested. */
|
||||
glXGetConfig(__glutDisplay, vi, GLX_STENCIL_SIZE, &value);
|
||||
if (GLUT_WIND_HAS_STENCIL(mode) && (value <= 0))
|
||||
return 1;
|
||||
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
/* XXX Multisampled overlay color index?? Pretty unlikely. */
|
||||
/* Look for multisampling if requested. */
|
||||
if (__glutIsSupportedByGLX("GLX_SGIS_multisample"))
|
||||
glXGetConfig(__glutDisplay, vi, GLX_SAMPLES_SGIS, &value);
|
||||
else
|
||||
value = 0;
|
||||
if (GLUT_WIND_IS_MULTISAMPLE(mode) && (value <= 0))
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static XVisualInfo *
|
||||
getOverlayVisualInfoCI(unsigned int mode)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
XLayerVisualInfo *vi;
|
||||
XLayerVisualInfo template;
|
||||
XVisualInfo *goodVisual, *returnVisual;
|
||||
int nitems, i, j, bad;
|
||||
|
||||
/* The GLX 1.0 glXChooseVisual is does not permit queries
|
||||
based on pixel transparency (and GLX_BUFFER_SIZE uses
|
||||
"smallest that meets" its requirement instead of "largest
|
||||
that meets" that GLUT wants. So, GLUT implements its own
|
||||
visual selection routine for color index overlays. */
|
||||
|
||||
/* Try three overlay layers. */
|
||||
for (i = 1; i <= 3; i++) {
|
||||
template.vinfo.screen = __glutScreen;
|
||||
template.vinfo.class = PseudoColor;
|
||||
template.layer = i;
|
||||
template.type = TransparentPixel;
|
||||
vi = __glutXGetLayerVisualInfo(__glutDisplay,
|
||||
VisualTransparentType | VisualScreenMask | VisualClassMask | VisualLayerMask,
|
||||
&template, &nitems);
|
||||
if (vi) {
|
||||
/* Check list for acceptable visual meeting requirements
|
||||
of requested display mode. */
|
||||
for (j = 0; j < nitems; j++) {
|
||||
bad = checkOverlayAcceptability(&vi[j].vinfo, mode);
|
||||
if (bad) {
|
||||
/* Set vi[j].vinfo.visual to mark it unacceptable. */
|
||||
vi[j].vinfo.visual = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look through list to find deepest acceptable visual. */
|
||||
goodVisual = NULL;
|
||||
for (j = 0; j < nitems; j++) {
|
||||
if (vi[j].vinfo.visual) {
|
||||
if (goodVisual == NULL) {
|
||||
goodVisual = &vi[j].vinfo;
|
||||
} else {
|
||||
if (goodVisual->depth < vi[j].vinfo.depth) {
|
||||
goodVisual = &vi[j].vinfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If a visual is found, clean up and return the visual. */
|
||||
if (goodVisual) {
|
||||
returnVisual = (XVisualInfo *) malloc(sizeof(XVisualInfo));
|
||||
if (returnVisual) {
|
||||
*returnVisual = *goodVisual;
|
||||
}
|
||||
XFree(vi);
|
||||
return returnVisual;
|
||||
}
|
||||
XFree(vi);
|
||||
}
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static XVisualInfo *
|
||||
getOverlayVisualInfoRGB(unsigned int mode)
|
||||
{
|
||||
|
||||
/* XXX For now, transparent RGBA overlays are not supported
|
||||
by GLUT. RGBA overlays raise difficult questions about
|
||||
what the transparent pixel (really color) value should be.
|
||||
|
||||
Color index overlay transparency is "easy" because the
|
||||
transparent pixel value does not affect displayable colors
|
||||
(except for stealing one color cell) since colors are
|
||||
determined by indirection through a colormap, and because
|
||||
it is uncommon for arbitrary pixel values in color index to
|
||||
be "calculated" (as can occur with a host of RGBA operations
|
||||
like lighting, blending, etc) so it is easy to avoid the
|
||||
transparent pixel value.
|
||||
|
||||
Since it is typically easy to avoid the transparent pixel
|
||||
value in color index mode, if GLUT tells the programmer what
|
||||
pixel is transparent, then most program can easily avoid
|
||||
generating that pixel value except when they intend
|
||||
transparency. GLUT returns whatever transparent pixel value
|
||||
is provided by the system through glutGet(
|
||||
GLUT_TRANSPARENT_INDEX).
|
||||
|
||||
Theory versus practice for RGBA overlay transparency: In
|
||||
theory, the reasonable thing is enabling overlay transparency
|
||||
when an overlay pixel's destination alpha is 0 because this
|
||||
allows overlay transparency to be controlled via alpha and all
|
||||
visibile colors are permited, but no hardware I am aware of
|
||||
supports this practice (and it requires destination alpha which
|
||||
is typically optional and quite uncommon for overlay windows!).
|
||||
|
||||
In practice, the choice of transparent pixel value is typically
|
||||
"hardwired" into most graphics hardware to a single pixel value.
|
||||
SGI hardware uses true black (0,0,0) without regard for the
|
||||
destination alpha. This is far from ideal because true black (a
|
||||
common color that is easy to accidently generate) can not be
|
||||
generated in an RGBA overlay. I am not sure what other vendors
|
||||
do.
|
||||
|
||||
Pragmatically, most of the typical things you want to do in the
|
||||
overlays can be done in color index (rubber banding, pop-up
|
||||
menus, etc.). One solution for GLUT would be to simply
|
||||
"advertise" what RGB triple (or possibly RGBA quadruple or simply
|
||||
A alone) generates transparency. The problem with this approach
|
||||
is that it forces programmers to avoid whatever arbitrary color
|
||||
various systems decide is transparent. This is a difficult
|
||||
burden to place on programmers that want to portably make use of
|
||||
overlays.
|
||||
|
||||
To actually support transparent RGBA overlays, there are really
|
||||
two reaonsable options. ONE: Simply mandate that true black is
|
||||
the RGBA overlay transparent color (what IRIS GL did). This is
|
||||
nice for programmers since only one option, nice for existing SGI
|
||||
hardware, bad for anyone (including SGI) who wants to improve
|
||||
upon "true black" RGB transparency.
|
||||
|
||||
Or TWO: Provide a set of queriable "transparency types" (like
|
||||
"true black" or "alpha == 0" or "true white" or even a queriable
|
||||
transparent color). This is harder for programmers, OK for
|
||||
existing SGI hardware, and it leaves open the issue of what other
|
||||
modes are reasonable.
|
||||
|
||||
Option TWO seems the more general approach, but since hardware
|
||||
designers will likely only implement a single mode (this is a
|
||||
scan out issue where bandwidth is pressing issue), codifying
|
||||
multiple speculative approaches nobody may ever implement seems
|
||||
silly. And option ONE fiats a suboptimal solution.
|
||||
|
||||
Therefore, I defer any decision of how GLUT should support RGBA
|
||||
overlay transparency and leave support for it unimplemented.
|
||||
Nobody has been pressing me for RGBA overlay transparency (though
|
||||
people have requested color index overlay transparency
|
||||
repeatedly). Geez, if you read this far you are either really
|
||||
bored or maybe actually interested in this topic. Anyway, if
|
||||
you have ideas (particularly if you plan on implementing a
|
||||
hardware scheme for RGBA overlay transparency), I'd be
|
||||
interested.
|
||||
|
||||
For the record, SGI's expiremental Framebufer Configuration
|
||||
experimental GLX extension uses option TWO. Transparency modes
|
||||
for "none" and "RGB" are defined (others could be defined later).
|
||||
What RGB value is the transparent one must be queried.
|
||||
|
||||
I was hoping GLUT could have something that required less work
|
||||
from the programmer to use portably. -mjk */
|
||||
|
||||
__glutWarning("RGBA overlays are not supported by GLUT (for now).");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static XVisualInfo *
|
||||
getOverlayVisualInfo(unsigned int mode)
|
||||
{
|
||||
/* XXX GLUT_LUMINANCE not implemented for GLUT 3.0. */
|
||||
if (GLUT_WIND_IS_LUMINANCE(mode))
|
||||
return NULL;
|
||||
|
||||
if (GLUT_WIND_IS_RGB(mode))
|
||||
return getOverlayVisualInfoRGB(mode);
|
||||
else
|
||||
return getOverlayVisualInfoCI(mode);
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
/* The GLUT overlay can come and go, and the overlay window has
|
||||
a distinct X window ID. Logically though, GLUT treats the
|
||||
normal and overlay windows as a unified window. In
|
||||
particular, X input events typically go to the overlay window
|
||||
since it is "on top of" the normal window. When an overlay
|
||||
window ID is destroyed (due to glutRemoveOverlay or a call to
|
||||
glutEstablishOverlay when an overlay already exists), we
|
||||
still keep track of the overlay window ID until we get back a
|
||||
DestroyNotify event for the overlay window. Otherwise, we
|
||||
could lose track of X input events sent to a destroyed
|
||||
overlay. To avoid this, we keep the destroyed overlay window
|
||||
ID on a "stale window" list. This lets us properly route X
|
||||
input events generated on destroyed overlay windows to the
|
||||
proper GLUT window. */
|
||||
static void
|
||||
addStaleWindow(GLUTwindow * window, Window win)
|
||||
{
|
||||
GLUTstale *entry;
|
||||
|
||||
entry = (GLUTstale *) malloc(sizeof(GLUTstale));
|
||||
if (!entry)
|
||||
__glutFatalError("out of memory");
|
||||
entry->window = window;
|
||||
entry->win = win;
|
||||
entry->next = __glutStaleWindowList;
|
||||
__glutStaleWindowList = entry;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
__glutFreeOverlay(GLUToverlay * overlay)
|
||||
{
|
||||
if (overlay->visAlloced)
|
||||
XFree(overlay->vis);
|
||||
XDestroyWindow(__glutDisplay, overlay->win);
|
||||
glXDestroyContext(__glutDisplay, overlay->ctx);
|
||||
if (overlay->colormap) {
|
||||
/* Only color index overlays have colormap data structure. */
|
||||
__glutFreeColormap(overlay->colormap);
|
||||
}
|
||||
free(overlay);
|
||||
}
|
||||
|
||||
static XVisualInfo *
|
||||
determineOverlayVisual(int *treatAsSingle, Bool * visAlloced, void **fbc)
|
||||
{
|
||||
if (__glutDisplayString) {
|
||||
XVisualInfo *vi;
|
||||
int i;
|
||||
|
||||
/* __glutDisplayString should be NULL except if
|
||||
glutInitDisplayString has been called to register a
|
||||
different display string. Calling glutInitDisplayString
|
||||
means using a string instead of an integer mask determine
|
||||
|
||||
the visual to use. Using the function pointer variable
|
||||
__glutDetermineVisualFromString below avoids linking in
|
||||
the code for implementing glutInitDisplayString (ie,
|
||||
glut_dstr.o) unless glutInitDisplayString gets called by
|
||||
the application. */
|
||||
|
||||
assert(__glutDetermineVisualFromString);
|
||||
|
||||
/* Try three overlay layers. */
|
||||
*visAlloced = False;
|
||||
*fbc = NULL;
|
||||
for (i = 1; i <= 3; i++) {
|
||||
requiredOverlayCriteria[0].value = i;
|
||||
vi = __glutDetermineVisualFromString(__glutDisplayString, treatAsSingle,
|
||||
requiredOverlayCriteria, numRequiredOverlayCriteria,
|
||||
requiredOverlayCriteriaMask, fbc);
|
||||
if (vi) {
|
||||
return vi;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
*visAlloced = True;
|
||||
*fbc = NULL;
|
||||
return __glutDetermineVisual(__glutDisplayMode,
|
||||
treatAsSingle, getOverlayVisualInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutEstablishOverlay(void)
|
||||
{
|
||||
GLUToverlay *overlay;
|
||||
GLUTwindow *window;
|
||||
XSetWindowAttributes wa;
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
||||
GLXFBConfigSGIX fbc;
|
||||
#else
|
||||
void *fbc;
|
||||
#endif
|
||||
|
||||
/* Register a routine to free an overlay with glut_win.c;
|
||||
this keeps glut_win.c from pulling in all of
|
||||
glut_overlay.c when no overlay functionality is used by
|
||||
the application. */
|
||||
__glutFreeOverlayFunc = __glutFreeOverlay;
|
||||
|
||||
window = __glutCurrentWindow;
|
||||
|
||||
/* Allow for an existant overlay to be re-established perhaps
|
||||
if you wanted a different display mode. */
|
||||
if (window->overlay) {
|
||||
#if !defined(_WIN32)
|
||||
addStaleWindow(window, window->overlay->win);
|
||||
#endif
|
||||
__glutFreeOverlay(window->overlay);
|
||||
}
|
||||
overlay = (GLUToverlay *) malloc(sizeof(GLUToverlay));
|
||||
if (!overlay)
|
||||
__glutFatalError("out of memory.");
|
||||
|
||||
overlay->vis = determineOverlayVisual(&overlay->treatAsSingle,
|
||||
&overlay->visAlloced, (void **) &fbc);
|
||||
if (!overlay->vis) {
|
||||
__glutFatalError("lacks overlay support.");
|
||||
}
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
||||
if (fbc) {
|
||||
window->ctx = glXCreateContextWithConfigSGIX(__glutDisplay, fbc,
|
||||
GLX_RGBA_TYPE_SGIX, None, __glutTryDirect);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
overlay->ctx = glXCreateContext(__glutDisplay, overlay->vis,
|
||||
None, __glutTryDirect);
|
||||
}
|
||||
if (!overlay->ctx) {
|
||||
__glutFatalError(
|
||||
"failed to create overlay OpenGL rendering context.");
|
||||
}
|
||||
#if !defined(_WIN32)
|
||||
overlay->isDirect = glXIsDirect(__glutDisplay, overlay->ctx);
|
||||
if (__glutForceDirect) {
|
||||
if (!overlay->isDirect) {
|
||||
__glutFatalError("direct rendering not possible.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
__glutSetupColormap(overlay->vis, &overlay->colormap, &overlay->cmap);
|
||||
overlay->transparentPixel = __glutGetTransparentPixel(__glutDisplay,
|
||||
overlay->vis);
|
||||
wa.colormap = overlay->cmap;
|
||||
wa.background_pixel = overlay->transparentPixel;
|
||||
wa.event_mask = window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK;
|
||||
wa.border_pixel = 0;
|
||||
#if defined(_WIN32)
|
||||
/* XXX Overlays not supported in Win32 yet. */
|
||||
#else
|
||||
overlay->win = XCreateWindow(__glutDisplay,
|
||||
window->win,
|
||||
0, 0, window->width, window->height, 0,
|
||||
overlay->vis->depth, InputOutput, overlay->vis->visual,
|
||||
CWBackPixel | CWBorderPixel | CWEventMask | CWColormap,
|
||||
&wa);
|
||||
#endif
|
||||
if (window->children) {
|
||||
/* Overlay window must be lowered below any GLUT
|
||||
subwindows. */
|
||||
XLowerWindow(__glutDisplay, overlay->win);
|
||||
}
|
||||
XMapWindow(__glutDisplay, overlay->win);
|
||||
overlay->shownState = 1;
|
||||
|
||||
overlay->display = NULL;
|
||||
|
||||
/* Make sure a reshape gets delivered. */
|
||||
window->forceReshape = True;
|
||||
|
||||
#if !defined(_WIN32)
|
||||
__glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
|
||||
#endif
|
||||
|
||||
window->overlay = overlay;
|
||||
glutUseLayer(GLUT_OVERLAY);
|
||||
|
||||
if (overlay->treatAsSingle) {
|
||||
glDrawBuffer(GL_FRONT);
|
||||
glReadBuffer(GL_FRONT);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutRemoveOverlay(void)
|
||||
{
|
||||
GLUTwindow *window = __glutCurrentWindow;
|
||||
GLUToverlay *overlay = __glutCurrentWindow->overlay;
|
||||
|
||||
if (!window->overlay)
|
||||
return;
|
||||
|
||||
/* If using overlay, switch to the normal layer. */
|
||||
if (window->renderWin == overlay->win) {
|
||||
glutUseLayer(GLUT_NORMAL);
|
||||
}
|
||||
#if !defined(_WIN32)
|
||||
addStaleWindow(window, overlay->win);
|
||||
#endif
|
||||
__glutFreeOverlay(overlay);
|
||||
window->overlay = NULL;
|
||||
#if !defined(_WIN32)
|
||||
__glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
|
||||
#endif
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutUseLayer(GLenum layer)
|
||||
{
|
||||
GLUTwindow *window = __glutCurrentWindow;
|
||||
|
||||
switch (layer) {
|
||||
case GLUT_NORMAL:
|
||||
#ifdef _WIN32
|
||||
window->renderDc = window->hdc;
|
||||
#endif
|
||||
window->renderWin = window->win;
|
||||
window->renderCtx = window->ctx;
|
||||
break;
|
||||
case GLUT_OVERLAY:
|
||||
/* Did you crash here? Calling glutUseLayer(GLUT_OVERLAY)
|
||||
without an overlay established is erroneous. Fix your
|
||||
code. */
|
||||
#ifdef _WIN32
|
||||
window->renderDc = window->overlay->hdc;
|
||||
#endif
|
||||
window->renderWin = window->overlay->win;
|
||||
window->renderCtx = window->overlay->ctx;
|
||||
break;
|
||||
default:
|
||||
__glutWarning("glutUseLayer: unknown layer, %d.", layer);
|
||||
break;
|
||||
}
|
||||
__glutSetWindow(window);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutPostOverlayRedisplay(void)
|
||||
{
|
||||
__glutPostRedisplay(__glutCurrentWindow, GLUT_OVERLAY_REDISPLAY_WORK);
|
||||
}
|
||||
|
||||
/* The advantage of this routine is that it saves the cost of a
|
||||
glutSetWindow call (entailing an expensive OpenGL context
|
||||
switch), particularly useful when multiple windows need
|
||||
redisplays posted at the same times. */
|
||||
void APIENTRY
|
||||
glutPostWindowOverlayRedisplay(int win)
|
||||
{
|
||||
__glutPostRedisplay(__glutWindowList[win - 1], GLUT_OVERLAY_REDISPLAY_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutOverlayDisplayFunc(GLUTdisplayCB displayFunc)
|
||||
{
|
||||
if (!__glutCurrentWindow->overlay) {
|
||||
__glutWarning("glutOverlayDisplayFunc: window has no overlay established");
|
||||
return;
|
||||
}
|
||||
__glutCurrentWindow->overlay->display = displayFunc;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutHideOverlay(void)
|
||||
{
|
||||
if (!__glutCurrentWindow->overlay) {
|
||||
__glutWarning("glutHideOverlay: window has no overlay established");
|
||||
return;
|
||||
}
|
||||
XUnmapWindow(__glutDisplay, __glutCurrentWindow->overlay->win);
|
||||
__glutCurrentWindow->overlay->shownState = 0;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutShowOverlay(void)
|
||||
{
|
||||
if (!__glutCurrentWindow->overlay) {
|
||||
__glutWarning("glutShowOverlay: window has no overlay established");
|
||||
return;
|
||||
}
|
||||
XMapWindow(__glutDisplay, __glutCurrentWindow->overlay->win);
|
||||
__glutCurrentWindow->overlay->shownState = 1;
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutLayerGet(GLenum param)
|
||||
{
|
||||
switch (param) {
|
||||
case GLUT_OVERLAY_POSSIBLE:
|
||||
{
|
||||
XVisualInfo *vi;
|
||||
Bool dummy, visAlloced;
|
||||
void *fbc;
|
||||
|
||||
vi = determineOverlayVisual(&dummy, &visAlloced, &fbc);
|
||||
if (vi) {
|
||||
if (visAlloced)
|
||||
XFree(vi);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case GLUT_LAYER_IN_USE:
|
||||
return __glutCurrentWindow->renderWin != __glutCurrentWindow->win;
|
||||
case GLUT_HAS_OVERLAY:
|
||||
return __glutCurrentWindow->overlay != NULL;
|
||||
case GLUT_TRANSPARENT_INDEX:
|
||||
if (__glutCurrentWindow->overlay) {
|
||||
return __glutCurrentWindow->overlay->transparentPixel;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
case GLUT_NORMAL_DAMAGED:
|
||||
/* __glutWindowDamaged is used so the damage state within
|
||||
the window (or overlay belwo) can be cleared before
|
||||
calling a display callback so on return, the state does
|
||||
not have to be cleared (since upon return from the
|
||||
callback the window could be destroyed (or layer
|
||||
removed). */
|
||||
return (__glutCurrentWindow->workMask & GLUT_REPAIR_WORK)
|
||||
|| __glutWindowDamaged;
|
||||
case GLUT_OVERLAY_DAMAGED:
|
||||
if (__glutCurrentWindow->overlay) {
|
||||
return (__glutCurrentWindow->workMask & GLUT_OVERLAY_REPAIR_WORK)
|
||||
|| __glutWindowDamaged;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
__glutWarning("invalid glutLayerGet param: %d", param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
2451
src/glut/glx/glut_roman.c
Normal file
2451
src/glut/glx/glut_roman.c
Normal file
File diff suppressed because it is too large
Load diff
596
src/glut/glx/glut_shapes.c
Normal file
596
src/glut/glx/glut_shapes.c
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
|
||||
|
||||
/**
|
||||
(c) Copyright 1993, Silicon Graphics, Inc.
|
||||
|
||||
ALL RIGHTS RESERVED
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
for any purpose and without fee is hereby granted, provided
|
||||
that the above copyright notice appear in all copies and that
|
||||
both the copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Silicon
|
||||
Graphics, Inc. not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission.
|
||||
|
||||
THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
|
||||
"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
|
||||
OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
|
||||
EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
|
||||
ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
|
||||
INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
|
||||
SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
|
||||
NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
|
||||
OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
US Government Users Restricted Rights
|
||||
|
||||
Use, duplication, or disclosure by the Government is subject to
|
||||
restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
|
||||
(c)(1)(ii) of the Rights in Technical Data and Computer
|
||||
Software clause at DFARS 252.227-7013 and/or in similar or
|
||||
successor clauses in the FAR or the DOD or NASA FAR
|
||||
Supplement. Unpublished-- rights reserved under the copyright
|
||||
laws of the United States. Contractor/manufacturer is Silicon
|
||||
Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
|
||||
94039-7311.
|
||||
|
||||
OpenGL(TM) is a trademark of Silicon Graphics, Inc.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "glutint.h"
|
||||
|
||||
/* Some <math.h> files do not define M_PI... */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
static GLUquadricObj *quadObj;
|
||||
|
||||
#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
|
||||
|
||||
static void
|
||||
initQuadObj(void)
|
||||
{
|
||||
quadObj = gluNewQuadric();
|
||||
if (!quadObj)
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
|
||||
{
|
||||
QUAD_OBJ_INIT();
|
||||
gluQuadricDrawStyle(quadObj, GLU_LINE);
|
||||
gluQuadricNormals(quadObj, GLU_SMOOTH);
|
||||
/* If we ever changed/used the texture or orientation state
|
||||
of quadObj, we'd need to change it to the defaults here
|
||||
with gluQuadricTexture and/or gluQuadricOrientation. */
|
||||
gluSphere(quadObj, radius, slices, stacks);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
|
||||
{
|
||||
QUAD_OBJ_INIT();
|
||||
gluQuadricDrawStyle(quadObj, GLU_FILL);
|
||||
gluQuadricNormals(quadObj, GLU_SMOOTH);
|
||||
/* If we ever changed/used the texture or orientation state
|
||||
of quadObj, we'd need to change it to the defaults here
|
||||
with gluQuadricTexture and/or gluQuadricOrientation. */
|
||||
gluSphere(quadObj, radius, slices, stacks);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutWireCone(GLdouble base, GLdouble height,
|
||||
GLint slices, GLint stacks)
|
||||
{
|
||||
QUAD_OBJ_INIT();
|
||||
gluQuadricDrawStyle(quadObj, GLU_LINE);
|
||||
gluQuadricNormals(quadObj, GLU_SMOOTH);
|
||||
/* If we ever changed/used the texture or orientation state
|
||||
of quadObj, we'd need to change it to the defaults here
|
||||
with gluQuadricTexture and/or gluQuadricOrientation. */
|
||||
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidCone(GLdouble base, GLdouble height,
|
||||
GLint slices, GLint stacks)
|
||||
{
|
||||
QUAD_OBJ_INIT();
|
||||
gluQuadricDrawStyle(quadObj, GLU_FILL);
|
||||
gluQuadricNormals(quadObj, GLU_SMOOTH);
|
||||
/* If we ever changed/used the texture or orientation state
|
||||
of quadObj, we'd need to change it to the defaults here
|
||||
with gluQuadricTexture and/or gluQuadricOrientation. */
|
||||
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
static void
|
||||
drawBox(GLfloat size, GLenum type)
|
||||
{
|
||||
static GLfloat n[6][3] =
|
||||
{
|
||||
{-1.0, 0.0, 0.0},
|
||||
{0.0, 1.0, 0.0},
|
||||
{1.0, 0.0, 0.0},
|
||||
{0.0, -1.0, 0.0},
|
||||
{0.0, 0.0, 1.0},
|
||||
{0.0, 0.0, -1.0}
|
||||
};
|
||||
static GLint faces[6][4] =
|
||||
{
|
||||
{0, 1, 2, 3},
|
||||
{3, 2, 6, 7},
|
||||
{7, 6, 5, 4},
|
||||
{4, 5, 1, 0},
|
||||
{5, 6, 2, 1},
|
||||
{7, 4, 0, 3}
|
||||
};
|
||||
GLfloat v[8][3];
|
||||
GLint i;
|
||||
|
||||
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
|
||||
v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
|
||||
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
|
||||
v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
|
||||
v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
|
||||
v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
|
||||
|
||||
for (i = 5; i >= 0; i--) {
|
||||
glBegin(type);
|
||||
glNormal3fv(&n[i][0]);
|
||||
glVertex3fv(&v[faces[i][0]][0]);
|
||||
glVertex3fv(&v[faces[i][1]][0]);
|
||||
glVertex3fv(&v[faces[i][2]][0]);
|
||||
glVertex3fv(&v[faces[i][3]][0]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireCube(GLdouble size)
|
||||
{
|
||||
drawBox(size, GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidCube(GLdouble size)
|
||||
{
|
||||
drawBox(size, GL_QUADS);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
static void
|
||||
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
|
||||
{
|
||||
int i, j;
|
||||
GLfloat theta, phi, theta1;
|
||||
GLfloat cosTheta, sinTheta;
|
||||
GLfloat cosTheta1, sinTheta1;
|
||||
GLfloat ringDelta, sideDelta;
|
||||
|
||||
ringDelta = 2.0 * M_PI / rings;
|
||||
sideDelta = 2.0 * M_PI / nsides;
|
||||
|
||||
theta = 0.0;
|
||||
cosTheta = 1.0;
|
||||
sinTheta = 0.0;
|
||||
for (i = rings - 1; i >= 0; i--) {
|
||||
theta1 = theta + ringDelta;
|
||||
cosTheta1 = cos(theta1);
|
||||
sinTheta1 = sin(theta1);
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
phi = 0.0;
|
||||
for (j = nsides; j >= 0; j--) {
|
||||
GLfloat cosPhi, sinPhi, dist;
|
||||
|
||||
phi += sideDelta;
|
||||
cosPhi = cos(phi);
|
||||
sinPhi = sin(phi);
|
||||
dist = R + r * cosPhi;
|
||||
|
||||
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
|
||||
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
|
||||
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
|
||||
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
|
||||
}
|
||||
glEnd();
|
||||
theta = theta1;
|
||||
cosTheta = cosTheta1;
|
||||
sinTheta = sinTheta1;
|
||||
}
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
|
||||
GLint nsides, GLint rings)
|
||||
{
|
||||
glPushAttrib(GL_POLYGON_BIT);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
doughnut(innerRadius, outerRadius, nsides, rings);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
|
||||
GLint nsides, GLint rings)
|
||||
{
|
||||
doughnut(innerRadius, outerRadius, nsides, rings);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
static GLfloat dodec[20][3];
|
||||
|
||||
static void
|
||||
initDodecahedron(void)
|
||||
{
|
||||
GLfloat alpha, beta;
|
||||
|
||||
alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
|
||||
beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
|
||||
2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
|
||||
/* *INDENT-OFF* */
|
||||
dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
|
||||
dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
|
||||
dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
|
||||
dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
|
||||
dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
|
||||
dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
|
||||
dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
|
||||
dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
|
||||
dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
|
||||
dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
|
||||
dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
|
||||
dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
|
||||
dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
|
||||
dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
|
||||
dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
|
||||
dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
|
||||
dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
|
||||
dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
|
||||
dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
|
||||
dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
}
|
||||
|
||||
#define DIFF3(_a,_b,_c) { \
|
||||
(_c)[0] = (_a)[0] - (_b)[0]; \
|
||||
(_c)[1] = (_a)[1] - (_b)[1]; \
|
||||
(_c)[2] = (_a)[2] - (_b)[2]; \
|
||||
}
|
||||
|
||||
static void
|
||||
crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
|
||||
{
|
||||
GLfloat p[3]; /* in case prod == v1 or v2 */
|
||||
|
||||
p[0] = v1[1] * v2[2] - v2[1] * v1[2];
|
||||
p[1] = v1[2] * v2[0] - v2[2] * v1[0];
|
||||
p[2] = v1[0] * v2[1] - v2[0] * v1[1];
|
||||
prod[0] = p[0];
|
||||
prod[1] = p[1];
|
||||
prod[2] = p[2];
|
||||
}
|
||||
|
||||
static void
|
||||
normalize(GLfloat v[3])
|
||||
{
|
||||
GLfloat d;
|
||||
|
||||
d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
if (d == 0.0) {
|
||||
__glutWarning("normalize: zero length vector");
|
||||
v[0] = d = 1.0;
|
||||
}
|
||||
d = 1 / d;
|
||||
v[0] *= d;
|
||||
v[1] *= d;
|
||||
v[2] *= d;
|
||||
}
|
||||
|
||||
static void
|
||||
pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
|
||||
{
|
||||
GLfloat n0[3], d1[3], d2[3];
|
||||
|
||||
DIFF3(dodec[a], dodec[b], d1);
|
||||
DIFF3(dodec[b], dodec[c], d2);
|
||||
crossprod(d1, d2, n0);
|
||||
normalize(n0);
|
||||
|
||||
glBegin(shadeType);
|
||||
glNormal3fv(n0);
|
||||
glVertex3fv(&dodec[a][0]);
|
||||
glVertex3fv(&dodec[b][0]);
|
||||
glVertex3fv(&dodec[c][0]);
|
||||
glVertex3fv(&dodec[d][0]);
|
||||
glVertex3fv(&dodec[e][0]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void
|
||||
dodecahedron(GLenum type)
|
||||
{
|
||||
static int inited = 0;
|
||||
|
||||
if (inited == 0) {
|
||||
inited = 1;
|
||||
initDodecahedron();
|
||||
}
|
||||
pentagon(0, 1, 9, 16, 5, type);
|
||||
pentagon(1, 0, 3, 18, 7, type);
|
||||
pentagon(1, 7, 11, 10, 9, type);
|
||||
pentagon(11, 7, 18, 19, 6, type);
|
||||
pentagon(8, 17, 16, 9, 10, type);
|
||||
pentagon(2, 14, 15, 6, 19, type);
|
||||
pentagon(2, 13, 12, 4, 14, type);
|
||||
pentagon(2, 19, 18, 3, 13, type);
|
||||
pentagon(3, 0, 5, 12, 13, type);
|
||||
pentagon(6, 15, 8, 10, 11, type);
|
||||
pentagon(4, 17, 8, 15, 14, type);
|
||||
pentagon(4, 12, 5, 16, 17, type);
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireDodecahedron(void)
|
||||
{
|
||||
dodecahedron(GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidDodecahedron(void)
|
||||
{
|
||||
dodecahedron(GL_TRIANGLE_FAN);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
static void
|
||||
recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
|
||||
GLenum shadeType)
|
||||
{
|
||||
GLfloat q0[3], q1[3];
|
||||
|
||||
DIFF3(n1, n2, q0);
|
||||
DIFF3(n2, n3, q1);
|
||||
crossprod(q0, q1, q1);
|
||||
normalize(q1);
|
||||
|
||||
glBegin(shadeType);
|
||||
glNormal3fv(q1);
|
||||
glVertex3fv(n1);
|
||||
glVertex3fv(n2);
|
||||
glVertex3fv(n3);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void
|
||||
subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
|
||||
GLenum shadeType)
|
||||
{
|
||||
int depth;
|
||||
GLfloat w0[3], w1[3], w2[3];
|
||||
GLfloat l;
|
||||
int i, j, k, n;
|
||||
|
||||
depth = 1;
|
||||
for (i = 0; i < depth; i++) {
|
||||
for (j = 0; i + j < depth; j++) {
|
||||
k = depth - i - j;
|
||||
for (n = 0; n < 3; n++) {
|
||||
w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
|
||||
w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
|
||||
/ depth;
|
||||
w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
|
||||
/ depth;
|
||||
}
|
||||
l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
|
||||
w0[0] /= l;
|
||||
w0[1] /= l;
|
||||
w0[2] /= l;
|
||||
l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
|
||||
w1[0] /= l;
|
||||
w1[1] /= l;
|
||||
w1[2] /= l;
|
||||
l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
|
||||
w2[0] /= l;
|
||||
w2[1] /= l;
|
||||
w2[2] /= l;
|
||||
recorditem(w1, w0, w2, shadeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drawtriangle(int i, GLfloat data[][3], int ndx[][3],
|
||||
GLenum shadeType)
|
||||
{
|
||||
GLfloat *x0, *x1, *x2;
|
||||
|
||||
x0 = data[ndx[i][0]];
|
||||
x1 = data[ndx[i][1]];
|
||||
x2 = data[ndx[i][2]];
|
||||
subdivide(x0, x1, x2, shadeType);
|
||||
}
|
||||
|
||||
/* octahedron data: The octahedron produced is centered at the
|
||||
origin and has radius 1.0 */
|
||||
static GLfloat odata[6][3] =
|
||||
{
|
||||
{1.0, 0.0, 0.0},
|
||||
{-1.0, 0.0, 0.0},
|
||||
{0.0, 1.0, 0.0},
|
||||
{0.0, -1.0, 0.0},
|
||||
{0.0, 0.0, 1.0},
|
||||
{0.0, 0.0, -1.0}
|
||||
};
|
||||
|
||||
static int ondex[8][3] =
|
||||
{
|
||||
{0, 4, 2},
|
||||
{1, 2, 4},
|
||||
{0, 3, 4},
|
||||
{1, 4, 3},
|
||||
{0, 2, 5},
|
||||
{1, 5, 2},
|
||||
{0, 5, 3},
|
||||
{1, 3, 5}
|
||||
};
|
||||
|
||||
static void
|
||||
octahedron(GLenum shadeType)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
drawtriangle(i, odata, ondex, shadeType);
|
||||
}
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireOctahedron(void)
|
||||
{
|
||||
octahedron(GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidOctahedron(void)
|
||||
{
|
||||
octahedron(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
/* icosahedron data: These numbers are rigged to make an
|
||||
icosahedron of radius 1.0 */
|
||||
|
||||
#define X .525731112119133606
|
||||
#define Z .850650808352039932
|
||||
|
||||
static GLfloat idata[12][3] =
|
||||
{
|
||||
{-X, 0, Z},
|
||||
{X, 0, Z},
|
||||
{-X, 0, -Z},
|
||||
{X, 0, -Z},
|
||||
{0, Z, X},
|
||||
{0, Z, -X},
|
||||
{0, -Z, X},
|
||||
{0, -Z, -X},
|
||||
{Z, X, 0},
|
||||
{-Z, X, 0},
|
||||
{Z, -X, 0},
|
||||
{-Z, -X, 0}
|
||||
};
|
||||
|
||||
static int index[20][3] =
|
||||
{
|
||||
{0, 4, 1},
|
||||
{0, 9, 4},
|
||||
{9, 5, 4},
|
||||
{4, 5, 8},
|
||||
{4, 8, 1},
|
||||
{8, 10, 1},
|
||||
{8, 3, 10},
|
||||
{5, 3, 8},
|
||||
{5, 2, 3},
|
||||
{2, 7, 3},
|
||||
{7, 10, 3},
|
||||
{7, 6, 10},
|
||||
{7, 11, 6},
|
||||
{11, 0, 6},
|
||||
{0, 1, 6},
|
||||
{6, 1, 10},
|
||||
{9, 0, 11},
|
||||
{9, 11, 2},
|
||||
{9, 2, 5},
|
||||
{7, 2, 11},
|
||||
};
|
||||
|
||||
static void
|
||||
icosahedron(GLenum shadeType)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 19; i >= 0; i--) {
|
||||
drawtriangle(i, idata, index, shadeType);
|
||||
}
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireIcosahedron(void)
|
||||
{
|
||||
icosahedron(GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidIcosahedron(void)
|
||||
{
|
||||
icosahedron(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
|
||||
/* tetrahedron data: */
|
||||
|
||||
#define T 1.73205080756887729
|
||||
|
||||
static GLfloat tdata[4][3] =
|
||||
{
|
||||
{T, T, T},
|
||||
{T, -T, -T},
|
||||
{-T, T, -T},
|
||||
{-T, -T, T}
|
||||
};
|
||||
|
||||
static int tndex[4][3] =
|
||||
{
|
||||
{0, 1, 3},
|
||||
{2, 1, 0},
|
||||
{3, 2, 0},
|
||||
{1, 2, 3}
|
||||
};
|
||||
|
||||
static void
|
||||
tetrahedron(GLenum shadeType)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 3; i >= 0; i--)
|
||||
drawtriangle(i, tdata, tndex, shadeType);
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWireTetrahedron(void)
|
||||
{
|
||||
tetrahedron(GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSolidTetrahedron(void)
|
||||
{
|
||||
tetrahedron(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
35
src/glut/glx/glut_space.c
Normal file
35
src/glut/glx/glut_space.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
void APIENTRY
|
||||
glutSpaceballMotionFunc(GLUTspaceMotionCB spaceMotionFunc)
|
||||
{
|
||||
__glutCurrentWindow->spaceMotion = spaceMotionFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSpaceballRotateFunc(GLUTspaceRotateCB spaceRotateFunc)
|
||||
{
|
||||
__glutCurrentWindow->spaceRotate = spaceRotateFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSpaceballButtonFunc(GLUTspaceButtonCB spaceButtonFunc)
|
||||
{
|
||||
__glutCurrentWindow->spaceButton = spaceButtonFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
}
|
||||
42
src/glut/glx/glut_stroke.c
Normal file
42
src/glut/glx/glut_stroke.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
#include "glutstroke.h"
|
||||
|
||||
void APIENTRY
|
||||
glutStrokeCharacter(GLUTstrokeFont font, int c)
|
||||
{
|
||||
const StrokeCharRec *ch;
|
||||
const StrokeRec *stroke;
|
||||
const CoordRec *coord;
|
||||
StrokeFontPtr fontinfo;
|
||||
int i, j;
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
fontinfo = (StrokeFontPtr) __glutFont(font);
|
||||
#else
|
||||
fontinfo = (StrokeFontPtr) font;
|
||||
#endif
|
||||
|
||||
if (c < 0 || c >= fontinfo->num_chars)
|
||||
return;
|
||||
ch = &(fontinfo->ch[c]);
|
||||
if (ch) {
|
||||
for (i = ch->num_strokes, stroke = ch->stroke;
|
||||
i > 0; i--, stroke++) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (j = stroke->num_coords, coord = stroke->coord;
|
||||
j > 0; j--, coord++) {
|
||||
glVertex2f(coord->x, coord->y);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glTranslatef(ch->right, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
47
src/glut/glx/glut_swap.c
Normal file
47
src/glut/glx/glut_swap.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutSwapBuffers(void)
|
||||
{
|
||||
GLUTwindow *window = __glutCurrentWindow;
|
||||
|
||||
if (window->renderWin == window->win) {
|
||||
if (__glutCurrentWindow->treatAsSingle) {
|
||||
/* Pretend the double buffered window is single buffered,
|
||||
so treat glutSwapBuffers as a no-op. */
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (__glutCurrentWindow->overlay->treatAsSingle) {
|
||||
/* Pretend the double buffered overlay is single
|
||||
buffered, so treat glutSwapBuffers as a no-op. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* For the MESA_SWAP_HACK. */
|
||||
window->usedSwapBuffers = 1;
|
||||
|
||||
SWAP_BUFFERS_LAYER(__glutCurrentWindow);
|
||||
|
||||
/* I considered putting the window being swapped on the
|
||||
GLUT_FINISH_WORK work list because you could call
|
||||
glutSwapBuffers from an idle callback which doesn't call
|
||||
__glutSetWindow which normally adds indirect rendering
|
||||
windows to the GLUT_FINISH_WORK work list. Not being put
|
||||
on the list could lead to the buffering up of multiple
|
||||
redisplays and buffer swaps and hamper interactivity. I
|
||||
consider this an application bug due to not using
|
||||
glutPostRedisplay to trigger redraws. If
|
||||
glutPostRedisplay were used, __glutSetWindow would be
|
||||
called and a glFinish to throttle buffering would occur. */
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
58
src/glut/glx/glut_swidth.c
Normal file
58
src/glut/glx/glut_swidth.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1995. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
#include "glutstroke.h"
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutStrokeWidth(GLUTstrokeFont font, int c)
|
||||
{
|
||||
StrokeFontPtr fontinfo;
|
||||
const StrokeCharRec *ch;
|
||||
|
||||
#if defined(_WIN32)
|
||||
fontinfo = (StrokeFontPtr) __glutFont(font);
|
||||
#else
|
||||
fontinfo = (StrokeFontPtr) font;
|
||||
#endif
|
||||
|
||||
if (c < 0 || c >= fontinfo->num_chars)
|
||||
return 0;
|
||||
ch = &(fontinfo->ch[c]);
|
||||
if (ch)
|
||||
return ch->right;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutStrokeLength(GLUTstrokeFont font, const unsigned char *string)
|
||||
{
|
||||
int c, length;
|
||||
StrokeFontPtr fontinfo;
|
||||
const StrokeCharRec *ch;
|
||||
|
||||
#if defined(_WIN32)
|
||||
fontinfo = (StrokeFontPtr) __glutFont(font);
|
||||
#else
|
||||
fontinfo = (StrokeFontPtr) font;
|
||||
#endif
|
||||
|
||||
length = 0;
|
||||
for (; *string != '\0'; string++) {
|
||||
c = *string;
|
||||
if (c >= 0 && c < fontinfo->num_chars) {
|
||||
ch = &(fontinfo->ch[c]);
|
||||
if (ch)
|
||||
length += ch->right;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
33
src/glut/glx/glut_tablet.c
Normal file
33
src/glut/glx/glut_tablet.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
void APIENTRY
|
||||
glutTabletMotionFunc(GLUTtabletMotionCB tabletMotionFunc)
|
||||
{
|
||||
__glutCurrentWindow->tabletMotion = tabletMotionFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
/* If deinstalling callback, invalidate tablet position. */
|
||||
if (tabletMotionFunc == NULL) {
|
||||
__glutCurrentWindow->tabletPos[0] = -1;
|
||||
__glutCurrentWindow->tabletPos[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutTabletButtonFunc(GLUTtabletButtonCB tabletButtonFunc)
|
||||
{
|
||||
__glutCurrentWindow->tabletButton = tabletButtonFunc;
|
||||
__glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask;
|
||||
__glutPutOnWorkList(__glutCurrentWindow,
|
||||
GLUT_DEVICE_MASK_WORK);
|
||||
}
|
||||
210
src/glut/glx/glut_teapot.c
Normal file
210
src/glut/glx/glut_teapot.c
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/**
|
||||
(c) Copyright 1993, Silicon Graphics, Inc.
|
||||
|
||||
ALL RIGHTS RESERVED
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
for any purpose and without fee is hereby granted, provided
|
||||
that the above copyright notice appear in all copies and that
|
||||
both the copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Silicon
|
||||
Graphics, Inc. not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission.
|
||||
|
||||
THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
|
||||
"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
|
||||
OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
|
||||
EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
|
||||
ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
|
||||
INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
|
||||
SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
|
||||
NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
|
||||
OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
US Government Users Restricted Rights
|
||||
|
||||
Use, duplication, or disclosure by the Government is subject to
|
||||
restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
|
||||
(c)(1)(ii) of the Rights in Technical Data and Computer
|
||||
Software clause at DFARS 252.227-7013 and/or in similar or
|
||||
successor clauses in the FAR or the DOD or NASA FAR
|
||||
Supplement. Unpublished-- rights reserved under the copyright
|
||||
laws of the United States. Contractor/manufacturer is Silicon
|
||||
Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
|
||||
94039-7311.
|
||||
|
||||
OpenGL(TM) is a trademark of Silicon Graphics, Inc.
|
||||
*/
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* Rim, body, lid, and bottom data must be reflected in x and
|
||||
y; handle and spout data across the y axis only. */
|
||||
|
||||
static int patchdata[][16] =
|
||||
{
|
||||
/* rim */
|
||||
{102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15},
|
||||
/* body */
|
||||
{12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27},
|
||||
{24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40},
|
||||
/* lid */
|
||||
{96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101,
|
||||
101, 0, 1, 2, 3,},
|
||||
{0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112,
|
||||
113, 114, 115, 116, 117},
|
||||
/* bottom */
|
||||
{118, 118, 118, 118, 124, 122, 119, 121, 123, 126,
|
||||
125, 120, 40, 39, 38, 37},
|
||||
/* handle */
|
||||
{41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
|
||||
53, 54, 55, 56},
|
||||
{53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
||||
28, 65, 66, 67},
|
||||
/* spout */
|
||||
{68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83},
|
||||
{80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
|
||||
92, 93, 94, 95}
|
||||
};
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
static float cpdata[][3] =
|
||||
{
|
||||
{0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0,
|
||||
-0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125},
|
||||
{0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375,
|
||||
0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375,
|
||||
2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84,
|
||||
2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875},
|
||||
{1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75,
|
||||
1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35},
|
||||
{0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2,
|
||||
0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12,
|
||||
0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225},
|
||||
{1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225},
|
||||
{1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0,
|
||||
-1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5,
|
||||
-0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3,
|
||||
2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0,
|
||||
2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0,
|
||||
2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8},
|
||||
{-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3,
|
||||
-0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3,
|
||||
1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2,
|
||||
-0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0,
|
||||
1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0,
|
||||
0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66,
|
||||
0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1},
|
||||
{2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7,
|
||||
-0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0,
|
||||
2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375},
|
||||
{3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475},
|
||||
{3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4},
|
||||
{2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0,
|
||||
3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8,
|
||||
3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4,
|
||||
-0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0,
|
||||
2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4,
|
||||
2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3,
|
||||
2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4},
|
||||
{0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425,
|
||||
-0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425,
|
||||
0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075},
|
||||
{0.84, -1.5, 0.075}
|
||||
};
|
||||
|
||||
static float tex[2][2][2] =
|
||||
{
|
||||
{ {0, 0},
|
||||
{1, 0}},
|
||||
{ {0, 1},
|
||||
{1, 1}}
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static void
|
||||
teapot(GLint grid, GLdouble scale, GLenum type)
|
||||
{
|
||||
float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
|
||||
long i, j, k, l;
|
||||
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT);
|
||||
glEnable(GL_AUTO_NORMAL);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glEnable(GL_MAP2_VERTEX_3);
|
||||
glEnable(GL_MAP2_TEXTURE_COORD_2);
|
||||
glPushMatrix();
|
||||
glRotatef(270.0, 1.0, 0.0, 0.0);
|
||||
glScalef(0.5 * scale, 0.5 * scale, 0.5 * scale);
|
||||
glTranslatef(0.0, 0.0, -1.5);
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
|
||||
q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
|
||||
if (l == 1)
|
||||
q[j][k][l] *= -1.0;
|
||||
if (i < 6) {
|
||||
r[j][k][l] =
|
||||
cpdata[patchdata[i][j * 4 + (3 - k)]][l];
|
||||
if (l == 0)
|
||||
r[j][k][l] *= -1.0;
|
||||
s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
|
||||
if (l == 0)
|
||||
s[j][k][l] *= -1.0;
|
||||
if (l == 1)
|
||||
s[j][k][l] *= -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2,
|
||||
&tex[0][0][0]);
|
||||
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
|
||||
&p[0][0][0]);
|
||||
glMapGrid2f(grid, 0.0, 1.0, grid, 0.0, 1.0);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
|
||||
&q[0][0][0]);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
if (i < 6) {
|
||||
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
|
||||
&r[0][0][0]);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
|
||||
&s[0][0][0]);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
}
|
||||
}
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutSolidTeapot(GLdouble scale)
|
||||
{
|
||||
teapot(7, scale, GL_FILL);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutWireTeapot(GLdouble scale)
|
||||
{
|
||||
teapot(10, scale, GL_LINE);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
1777
src/glut/glx/glut_tr10.c
Normal file
1777
src/glut/glx/glut_tr10.c
Normal file
File diff suppressed because it is too large
Load diff
2060
src/glut/glx/glut_tr24.c
Normal file
2060
src/glut/glx/glut_tr24.c
Normal file
File diff suppressed because it is too large
Load diff
86
src/glut/glx/glut_util.c
Normal file
86
src/glut/glx/glut_util.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* strdup is actually not a standard ANSI C or POSIX routine
|
||||
so implement a private one for GLUT. OpenVMS does not have a
|
||||
strdup; Linux's standard libc doesn't declare strdup by default
|
||||
(unless BSD or SVID interfaces are requested). */
|
||||
char *
|
||||
__glutStrdup(const char *string)
|
||||
{
|
||||
char *copy;
|
||||
|
||||
copy = (char*) malloc(strlen(string) + 1);
|
||||
if (copy == NULL)
|
||||
return NULL;
|
||||
strcpy(copy, string);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void
|
||||
__glutWarning(char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "GLUT: Warning in %s: ",
|
||||
__glutProgramName ? __glutProgramName : "(unamed)");
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutReportErrors(void)
|
||||
{
|
||||
GLenum error;
|
||||
|
||||
while ((error = glGetError()) != GL_NO_ERROR)
|
||||
__glutWarning("GL error: %s", gluErrorString(error));
|
||||
}
|
||||
/* ENDCENTRY */
|
||||
|
||||
void
|
||||
__glutFatalError(char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "GLUT: Fatal Error in %s: ",
|
||||
__glutProgramName ? __glutProgramName : "(unamed)");
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
putc('\n', stderr);
|
||||
#ifdef _WIN32
|
||||
if (__glutExitFunc) {
|
||||
__glutExitFunc(1);
|
||||
}
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
__glutFatalUsage(char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "GLUT: Fatal API Usage in %s: ",
|
||||
__glutProgramName ? __glutProgramName : "(unamed)");
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
putc('\n', stderr);
|
||||
abort();
|
||||
}
|
||||
230
src/glut/glx/glut_vidresize.c
Normal file
230
src/glut/glx/glut_vidresize.c
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1996. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sgi
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* Grumble. The IRIX 6.3 and early IRIX 6.4 OpenGL headers
|
||||
support the video resize extension, but failed to define
|
||||
GLX_SGIX_video_resize. */
|
||||
#ifdef GLX_SYNC_FRAME_SGIX
|
||||
#define GLX_SGIX_video_resize 1
|
||||
#endif
|
||||
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
static int canVideoResize = -1;
|
||||
static int videoResizeChannel;
|
||||
#else
|
||||
static int canVideoResize = 0;
|
||||
#endif
|
||||
static int videoResizeInUse = 0;
|
||||
static int dx = -1, dy = -1, dw = -1, dh = -1;
|
||||
|
||||
/* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a
|
||||
bug where programs seg-fault when they attempt video
|
||||
resizing from an indirect OpenGL context (either local or
|
||||
over a network). */
|
||||
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
|
||||
static volatile int errorCaught;
|
||||
|
||||
/* ARGSUSED */
|
||||
static
|
||||
catchXSGIvcErrors(Display * dpy, XErrorEvent * event)
|
||||
{
|
||||
errorCaught = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* CENTRY */
|
||||
int APIENTRY
|
||||
glutVideoResizeGet(GLenum param)
|
||||
{
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
if (canVideoResize < 0) {
|
||||
canVideoResize = __glutIsSupportedByGLX("GLX_SGIX_video_resize");
|
||||
if (canVideoResize) {
|
||||
#if __sgi
|
||||
/* This is a hack because IRIX 6.2, 6.3, and some 6.4
|
||||
versions were released with GLX_SGIX_video_resize
|
||||
being advertised by the X server though the video
|
||||
resize extension is not actually supported. We try to
|
||||
determine if the libGL.so we are using actually has a
|
||||
video resize entrypoint before we try to use the
|
||||
feature. */
|
||||
void (*func) (void);
|
||||
void *glxDso = dlopen("libGL.so", RTLD_LAZY);
|
||||
|
||||
func = (void (*)(void)) dlsym(glxDso, "glXQueryChannelDeltasSGIX");
|
||||
if (!func) {
|
||||
canVideoResize = 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
char *channelString;
|
||||
int (*handler) (Display *, XErrorEvent *);
|
||||
|
||||
channelString = getenv("GLUT_VIDEO_RESIZE_CHANNEL");
|
||||
videoResizeChannel = channelString ? atoi(channelString) : 0;
|
||||
|
||||
/* Work around another annoying problem with SGI's
|
||||
GLX_SGIX_video_resize implementation. Early IRIX
|
||||
6.4 OpenGL's advertise the extension and have the
|
||||
video resize API, but an XSGIvc X protocol errors
|
||||
result trying to use the API. Set up an error
|
||||
handler to intercept what would otherwise be a fatal
|
||||
error. If an error was recieved, do not report that
|
||||
video resize is possible. */
|
||||
handler = XSetErrorHandler(catchXSGIvcErrors);
|
||||
|
||||
errorCaught = 0;
|
||||
|
||||
glXQueryChannelDeltasSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, &dx, &dy, &dw, &dh);
|
||||
|
||||
/* glXQueryChannelDeltasSGIX is an inherent X server
|
||||
round-trip so we know we will have gotten either the
|
||||
correct reply or and error by this time. */
|
||||
XSetErrorHandler(handler);
|
||||
|
||||
/* Still yet another work around. In IRIX 6.4 betas,
|
||||
glXQueryChannelDeltasSGIX will return as if it
|
||||
succeeded, but the values are filled with junk.
|
||||
Watch to make sure the delta variables really make
|
||||
sense. */
|
||||
if (errorCaught ||
|
||||
dx < 0 || dy < 0 || dw < 0 || dh < 0 ||
|
||||
dx > 2048 || dy > 2048 || dw > 2048 || dh > 2048) {
|
||||
canVideoResize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* GLX_SGIX_video_resize */
|
||||
|
||||
switch (param) {
|
||||
case GLUT_VIDEO_RESIZE_POSSIBLE:
|
||||
return canVideoResize;
|
||||
case GLUT_VIDEO_RESIZE_IN_USE:
|
||||
return videoResizeInUse;
|
||||
case GLUT_VIDEO_RESIZE_X_DELTA:
|
||||
return dx;
|
||||
case GLUT_VIDEO_RESIZE_Y_DELTA:
|
||||
return dy;
|
||||
case GLUT_VIDEO_RESIZE_WIDTH_DELTA:
|
||||
return dw;
|
||||
case GLUT_VIDEO_RESIZE_HEIGHT_DELTA:
|
||||
return dh;
|
||||
case GLUT_VIDEO_RESIZE_X:
|
||||
case GLUT_VIDEO_RESIZE_Y:
|
||||
case GLUT_VIDEO_RESIZE_WIDTH:
|
||||
case GLUT_VIDEO_RESIZE_HEIGHT:
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
if (videoResizeInUse) {
|
||||
int x, y, width, height;
|
||||
|
||||
glXQueryChannelRectSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, &x, &y, &width, &height);
|
||||
switch (param) {
|
||||
case GLUT_VIDEO_RESIZE_X:
|
||||
return x;
|
||||
case GLUT_VIDEO_RESIZE_Y:
|
||||
return y;
|
||||
case GLUT_VIDEO_RESIZE_WIDTH:
|
||||
return width;
|
||||
case GLUT_VIDEO_RESIZE_HEIGHT:
|
||||
return height;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
default:
|
||||
__glutWarning("invalid glutVideoResizeGet parameter: %d", param);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSetupVideoResizing(void)
|
||||
{
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
|
||||
glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, __glutCurrentWindow->win);
|
||||
videoResizeInUse = 1;
|
||||
} else
|
||||
#endif
|
||||
__glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n");
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutStopVideoResizing(void)
|
||||
{
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) {
|
||||
if (videoResizeInUse) {
|
||||
glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, None);
|
||||
videoResizeInUse = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void APIENTRY
|
||||
glutVideoResize(int x, int y, int width, int height)
|
||||
{
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
if (videoResizeInUse) {
|
||||
#ifdef GLX_SYNC_SWAP_SGIX
|
||||
/* glXChannelRectSyncSGIX introduced in a patch to IRIX
|
||||
6.2; the original unpatched IRIX 6.2 behavior is always
|
||||
GLX_SYNC_SWAP_SGIX. */
|
||||
glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, GLX_SYNC_SWAP_SGIX);
|
||||
#endif
|
||||
glXChannelRectSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, x, y, width, height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void APIENTRY
|
||||
glutVideoPan(int x, int y, int width, int height)
|
||||
{
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize)
|
||||
if (videoResizeInUse) {
|
||||
#ifdef GLX_SYNC_FRAME_SGIX
|
||||
/* glXChannelRectSyncSGIX introduced in a patch to IRIX
|
||||
6.2; the original unpatched IRIX 6.2 behavior is always
|
||||
GLX_SYNC_SWAP_SGIX. We just ignore that we cannot
|
||||
accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2;
|
||||
this means you'd need a glutSwapBuffers to actually
|
||||
realize the video resize. */
|
||||
glXChannelRectSyncSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, GLX_SYNC_FRAME_SGIX);
|
||||
#endif
|
||||
glXChannelRectSGIX(__glutDisplay, __glutScreen,
|
||||
videoResizeChannel, x, y, width, height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
23
src/glut/glx/glut_warp.c
Normal file
23
src/glut/glx/glut_warp.c
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1996, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutWarpPointer(int x, int y)
|
||||
{
|
||||
XWarpPointer(__glutDisplay, None, __glutCurrentWindow->win,
|
||||
0, 0, 0, 0, x, y);
|
||||
XFlush(__glutDisplay);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
1007
src/glut/glx/glut_win.c
Normal file
1007
src/glut/glx/glut_win.c
Normal file
File diff suppressed because it is too large
Load diff
120
src/glut/glx/glut_winmisc.c
Normal file
120
src/glut/glx/glut_winmisc.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h> /* for XA_STRING atom */
|
||||
#endif
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* CENTRY */
|
||||
void APIENTRY
|
||||
glutSetWindowTitle(const char *title)
|
||||
{
|
||||
XTextProperty textprop;
|
||||
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
textprop.value = (unsigned char *) title;
|
||||
textprop.encoding = XA_STRING;
|
||||
textprop.format = 8;
|
||||
textprop.nitems = strlen(title);
|
||||
XSetWMName(__glutDisplay,
|
||||
__glutCurrentWindow->win, &textprop);
|
||||
XFlush(__glutDisplay);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSetIconTitle(const char *title)
|
||||
{
|
||||
XTextProperty textprop;
|
||||
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
IGNORE_IN_GAME_MODE();
|
||||
textprop.value = (unsigned char *) title;
|
||||
textprop.encoding = XA_STRING;
|
||||
textprop.format = 8;
|
||||
textprop.nitems = strlen(title);
|
||||
XSetWMIconName(__glutDisplay,
|
||||
__glutCurrentWindow->win, &textprop);
|
||||
XFlush(__glutDisplay);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutPositionWindow(int x, int y)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredX = x;
|
||||
__glutCurrentWindow->desiredY = y;
|
||||
__glutCurrentWindow->desiredConfMask |= CWX | CWY;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutReshapeWindow(int w, int h)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
if (w <= 0 || h <= 0)
|
||||
__glutWarning("glutReshapeWindow: non-positive width or height not allowed");
|
||||
|
||||
__glutCurrentWindow->desiredWidth = w;
|
||||
__glutCurrentWindow->desiredHeight = h;
|
||||
__glutCurrentWindow->desiredConfMask |= CWWidth | CWHeight;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutPopWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredStack = Above;
|
||||
__glutCurrentWindow->desiredConfMask |= CWStackMode;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutPushWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredStack = Below;
|
||||
__glutCurrentWindow->desiredConfMask |= CWStackMode;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutIconifyWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
assert(!__glutCurrentWindow->parent);
|
||||
__glutCurrentWindow->desiredMapState = IconicState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutShowWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredMapState = NormalState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutHideWindow(void)
|
||||
{
|
||||
IGNORE_IN_GAME_MODE();
|
||||
__glutCurrentWindow->desiredMapState = WithdrawnState;
|
||||
__glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK);
|
||||
}
|
||||
|
||||
/* ENDCENTRY */
|
||||
32
src/glut/glx/glutbitmap.h
Normal file
32
src/glut/glx/glutbitmap.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __glutbitmap_h__
|
||||
#define __glutbitmap_h__
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#define GLUT_NO_LIB_PRAGMA /* Avoid auto library linking when building
|
||||
the GLUT library itself. */
|
||||
#include <GL/glut.h>
|
||||
|
||||
typedef struct {
|
||||
const GLsizei width;
|
||||
const GLsizei height;
|
||||
const GLfloat xorig;
|
||||
const GLfloat yorig;
|
||||
const GLfloat advance;
|
||||
const GLubyte *bitmap;
|
||||
} BitmapCharRec, *BitmapCharPtr;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const int num_chars;
|
||||
const int first;
|
||||
const BitmapCharRec * const *ch;
|
||||
} BitmapFontRec, *BitmapFontPtr;
|
||||
|
||||
typedef void *GLUTbitmapFont;
|
||||
|
||||
#endif /* __glutbitmap_h__ */
|
||||
772
src/glut/glx/glutint.h
Normal file
772
src/glut/glx/glutint.h
Normal file
|
|
@ -0,0 +1,772 @@
|
|||
#ifndef __glutint_h__
|
||||
#define __glutint_h__
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#if defined(__CYGWIN32__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#define SUPPORT_FORTRAN /* With GLUT 3.7, everyone supports Fortran. */
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "glutwin32.h"
|
||||
#else
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
/* added by BrianP: */
|
||||
#define APIENTRY GLAPIENTRY
|
||||
#define __cdecl GLAPIENTRY
|
||||
#define CDECL GLAPIENTRY
|
||||
|
||||
|
||||
#define GLUT_BUILDING_LIB /* Building the GLUT library itself. */
|
||||
|
||||
/* GLUT_BUILDING_LIB is used by <GL/glut.h> to 1) not #pragma link
|
||||
with the GLUT library, and 2) avoid the Win32 atexit hack. */
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
/* This must be done after <GL/gl.h> is included. MESA is defined
|
||||
if the <GL/gl.h> is supplied by Brian Paul's Mesa library. */
|
||||
#if defined(MESA) && defined(_WIN32)
|
||||
/* Mesa implements "wgl" versions of GDI entry points needed for
|
||||
using OpenGL. Map these "wgl" versions to the GDI names via
|
||||
macros. */
|
||||
GLAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd);
|
||||
GLAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd);
|
||||
GLAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc);
|
||||
GLAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd);
|
||||
GLAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc);
|
||||
GLAPI HGLRC GLWINAPI wglCreateContext(HDC hdc);
|
||||
GLAPI BOOL GLWINAPI wglDeleteContext(HGLRC hglrc);
|
||||
GLAPI HGLRC GLWINAPI wglGetCurrentContext(VOID);
|
||||
GLAPI HDC GLWINAPI wglGetCurrentDC(VOID);
|
||||
GLAPI BOOL GLWINAPI wglMakeCurrent(HDC hdc,HGLRC hglrc);
|
||||
#define ChoosePixelFormat wglChoosePixelFormat
|
||||
#define DescribePixelFormat wglDescribePixelFormat
|
||||
#define GetPixelFormat wglGetPixelFormat
|
||||
#define SetPixelFormat wglSetPixelFormat
|
||||
#define SwapBuffers wglSwapBuffers
|
||||
#define GetCurrentContext wglGetCurrentContext
|
||||
#define GetCurrentDC wglGetCurrentDC
|
||||
#define MakeCurrent wglMakeCurrent
|
||||
#define CreateContext wglCreateContext
|
||||
#define DeleteContext wglDeleteContext
|
||||
#endif /* MESA */
|
||||
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
#include <GL/glutf90.h>
|
||||
#endif
|
||||
|
||||
#ifdef __vms
|
||||
#if ( __VMS_VER < 70000000 )
|
||||
struct timeval {
|
||||
__int64 val;
|
||||
};
|
||||
extern int sys$gettim(struct timeval *);
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__vms) && ( __VMS_VER < 70000000 )
|
||||
|
||||
/* For VMS6.2 or lower :
|
||||
One TICK on VMS is 100 nanoseconds; 0.1 microseconds or
|
||||
0.0001 milliseconds. This means that there are 0.01
|
||||
ticks/ns, 10 ticks/us, 10,000 ticks/ms and 10,000,000
|
||||
ticks/second. */
|
||||
|
||||
#define TICKS_PER_MILLISECOND 10000
|
||||
#define TICKS_PER_SECOND 10000000
|
||||
|
||||
#define GETTIMEOFDAY(_x) (void) sys$gettim (_x);
|
||||
|
||||
#define ADD_TIME(dest, src1, src2) { \
|
||||
(dest).val = (src1).val + (src2).val; \
|
||||
}
|
||||
|
||||
#define TIMEDELTA(dest, src1, src2) { \
|
||||
(dest).val = (src1).val - (src2).val; \
|
||||
}
|
||||
|
||||
#define IS_AFTER(t1, t2) ((t2).val > (t1).val)
|
||||
|
||||
#define IS_AT_OR_AFTER(t1, t2) ((t2).val >= (t1).val)
|
||||
|
||||
#else
|
||||
#if defined(SVR4) && !defined(sun) /* Sun claims SVR4, but
|
||||
wants 2 args. */
|
||||
#define GETTIMEOFDAY(_x) gettimeofday(_x)
|
||||
#else
|
||||
#define GETTIMEOFDAY(_x) gettimeofday(_x, NULL)
|
||||
#endif
|
||||
#define ADD_TIME(dest, src1, src2) { \
|
||||
if(((dest).tv_usec = \
|
||||
(src1).tv_usec + (src2).tv_usec) >= 1000000) { \
|
||||
(dest).tv_usec -= 1000000; \
|
||||
(dest).tv_sec = (src1).tv_sec + (src2).tv_sec + 1; \
|
||||
} else { \
|
||||
(dest).tv_sec = (src1).tv_sec + (src2).tv_sec; \
|
||||
if(((dest).tv_sec >= 1) && (((dest).tv_usec <0))) { \
|
||||
(dest).tv_sec --;(dest).tv_usec += 1000000; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#define TIMEDELTA(dest, src1, src2) { \
|
||||
if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) { \
|
||||
(dest).tv_usec += 1000000; \
|
||||
(dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1; \
|
||||
} else { \
|
||||
(dest).tv_sec = (src1).tv_sec - (src2).tv_sec; \
|
||||
} \
|
||||
}
|
||||
#define IS_AFTER(t1, t2) \
|
||||
(((t2).tv_sec > (t1).tv_sec) || \
|
||||
(((t2).tv_sec == (t1).tv_sec) && \
|
||||
((t2).tv_usec > (t1).tv_usec)))
|
||||
#define IS_AT_OR_AFTER(t1, t2) \
|
||||
(((t2).tv_sec > (t1).tv_sec) || \
|
||||
(((t2).tv_sec == (t1).tv_sec) && \
|
||||
((t2).tv_usec >= (t1).tv_usec)))
|
||||
#endif
|
||||
|
||||
#define IGNORE_IN_GAME_MODE() \
|
||||
{ if (__glutGameModeWindow) return; }
|
||||
|
||||
#define GLUT_WIND_IS_RGB(x) (((x) & GLUT_INDEX) == 0)
|
||||
#define GLUT_WIND_IS_INDEX(x) (((x) & GLUT_INDEX) != 0)
|
||||
#define GLUT_WIND_IS_SINGLE(x) (((x) & GLUT_DOUBLE) == 0)
|
||||
#define GLUT_WIND_IS_DOUBLE(x) (((x) & GLUT_DOUBLE) != 0)
|
||||
#define GLUT_WIND_HAS_ACCUM(x) (((x) & GLUT_ACCUM) != 0)
|
||||
#define GLUT_WIND_HAS_ALPHA(x) (((x) & GLUT_ALPHA) != 0)
|
||||
#define GLUT_WIND_HAS_DEPTH(x) (((x) & GLUT_DEPTH) != 0)
|
||||
#define GLUT_WIND_HAS_STENCIL(x) (((x) & GLUT_STENCIL) != 0)
|
||||
#define GLUT_WIND_IS_MULTISAMPLE(x) (((x) & GLUT_MULTISAMPLE) != 0)
|
||||
#define GLUT_WIND_IS_STEREO(x) (((x) & GLUT_STEREO) != 0)
|
||||
#define GLUT_WIND_IS_LUMINANCE(x) (((x) & GLUT_LUMINANCE) != 0)
|
||||
#define GLUT_MAP_WORK (1 << 0)
|
||||
#define GLUT_EVENT_MASK_WORK (1 << 1)
|
||||
#define GLUT_REDISPLAY_WORK (1 << 2)
|
||||
#define GLUT_CONFIGURE_WORK (1 << 3)
|
||||
#define GLUT_COLORMAP_WORK (1 << 4)
|
||||
#define GLUT_DEVICE_MASK_WORK (1 << 5)
|
||||
#define GLUT_FINISH_WORK (1 << 6)
|
||||
#define GLUT_DEBUG_WORK (1 << 7)
|
||||
#define GLUT_DUMMY_WORK (1 << 8)
|
||||
#define GLUT_FULL_SCREEN_WORK (1 << 9)
|
||||
#define GLUT_OVERLAY_REDISPLAY_WORK (1 << 10)
|
||||
#define GLUT_REPAIR_WORK (1 << 11)
|
||||
#define GLUT_OVERLAY_REPAIR_WORK (1 << 12)
|
||||
|
||||
/* Frame buffer capability macros and types. */
|
||||
#define RGBA 0
|
||||
#define BUFFER_SIZE 1
|
||||
#define DOUBLEBUFFER 2
|
||||
#define STEREO 3
|
||||
#define AUX_BUFFERS 4
|
||||
#define RED_SIZE 5 /* Used as mask bit for
|
||||
"color selected". */
|
||||
#define GREEN_SIZE 6
|
||||
#define BLUE_SIZE 7
|
||||
#define ALPHA_SIZE 8
|
||||
#define DEPTH_SIZE 9
|
||||
#define STENCIL_SIZE 10
|
||||
#define ACCUM_RED_SIZE 11 /* Used as mask bit for
|
||||
"acc selected". */
|
||||
#define ACCUM_GREEN_SIZE 12
|
||||
#define ACCUM_BLUE_SIZE 13
|
||||
#define ACCUM_ALPHA_SIZE 14
|
||||
#define LEVEL 15
|
||||
|
||||
#define NUM_GLXCAPS (LEVEL + 1)
|
||||
|
||||
#define XVISUAL (NUM_GLXCAPS + 0)
|
||||
#define TRANSPARENT (NUM_GLXCAPS + 1)
|
||||
#define SAMPLES (NUM_GLXCAPS + 2)
|
||||
#define XSTATICGRAY (NUM_GLXCAPS + 3) /* Used as
|
||||
mask bit
|
||||
for "any
|
||||
visual type
|
||||
selected". */
|
||||
#define XGRAYSCALE (NUM_GLXCAPS + 4)
|
||||
#define XSTATICCOLOR (NUM_GLXCAPS + 5)
|
||||
#define XPSEUDOCOLOR (NUM_GLXCAPS + 6)
|
||||
#define XTRUECOLOR (NUM_GLXCAPS + 7)
|
||||
#define XDIRECTCOLOR (NUM_GLXCAPS + 8)
|
||||
#define SLOW (NUM_GLXCAPS + 9)
|
||||
#define CONFORMANT (NUM_GLXCAPS + 10)
|
||||
|
||||
#define NUM_CAPS (NUM_GLXCAPS + 11)
|
||||
|
||||
/* Frame buffer capablities that don't have a corresponding
|
||||
FrameBufferMode entry. These get used as mask bits. */
|
||||
#define NUM (NUM_CAPS + 0)
|
||||
#define RGBA_MODE (NUM_CAPS + 1)
|
||||
#define CI_MODE (NUM_CAPS + 2)
|
||||
#define LUMINANCE_MODE (NUM_CAPS + 3)
|
||||
|
||||
#define NONE 0
|
||||
#define EQ 1
|
||||
#define NEQ 2
|
||||
#define LTE 3
|
||||
#define GTE 4
|
||||
#define GT 5
|
||||
#define LT 6
|
||||
#define MIN 7
|
||||
|
||||
typedef struct _Criterion {
|
||||
int capability;
|
||||
int comparison;
|
||||
int value;
|
||||
} Criterion;
|
||||
|
||||
typedef struct _FrameBufferMode {
|
||||
XVisualInfo *vi;
|
||||
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
||||
|
||||
/* fbc is non-NULL when the XVisualInfo* is not OpenGL-capable
|
||||
(ie, GLX_USE_GL is false), but the SGIX_fbconfig extension shows
|
||||
the visual's fbconfig is OpenGL-capable. The reason for this is typically
|
||||
an RGBA luminance fbconfig such as 16-bit StaticGray that could
|
||||
not be advertised as a GLX visual since StaticGray visuals are
|
||||
required (by the GLX specification) to be color index. The
|
||||
SGIX_fbconfig allows StaticGray visuals to instead advertised as
|
||||
fbconfigs that can provide RGBA luminance support. */
|
||||
|
||||
GLXFBConfigSGIX fbc;
|
||||
#endif
|
||||
int valid;
|
||||
int cap[NUM_CAPS];
|
||||
} FrameBufferMode;
|
||||
|
||||
/* DisplayMode capability macros for game mode. */
|
||||
#define DM_WIDTH 0 /* "width" */
|
||||
#define DM_HEIGHT 1 /* "height" */
|
||||
#define DM_PIXEL_DEPTH 2 /* "bpp" (bits per pixel) */
|
||||
#define DM_HERTZ 3 /* "hertz" */
|
||||
#define DM_NUM 4 /* "num" */
|
||||
|
||||
#define NUM_DM_CAPS (DM_NUM+1)
|
||||
|
||||
typedef struct _DisplayMode {
|
||||
#ifdef _WIN32
|
||||
DEVMODE devmode;
|
||||
#else
|
||||
/* XXX The X Window System does not have a standard
|
||||
mechanism for display setting changes. On SGI
|
||||
systems, GLUT could use the XSGIvc (SGI X video
|
||||
control extension). Perhaps this can be done in
|
||||
a future release of GLUT. */
|
||||
#endif
|
||||
int valid;
|
||||
int cap[NUM_DM_CAPS];
|
||||
} DisplayMode;
|
||||
|
||||
/* GLUT function types */
|
||||
typedef void (GLUTCALLBACK *GLUTdisplayCB) (void);
|
||||
typedef void (GLUTCALLBACK *GLUTreshapeCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTkeyboardCB) (unsigned char, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTmouseCB) (int, int, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTmotionCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTpassiveCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTentryCB) (int);
|
||||
typedef void (GLUTCALLBACK *GLUTvisibilityCB) (int);
|
||||
typedef void (GLUTCALLBACK *GLUTwindowStatusCB) (int);
|
||||
typedef void (GLUTCALLBACK *GLUTidleCB) (void);
|
||||
typedef void (GLUTCALLBACK *GLUTtimerCB) (int);
|
||||
typedef void (GLUTCALLBACK *GLUTmenuStateCB) (int); /* DEPRICATED. */
|
||||
typedef void (GLUTCALLBACK *GLUTmenuStatusCB) (int, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTselectCB) (int);
|
||||
typedef void (GLUTCALLBACK *GLUTspecialCB) (int, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTspaceMotionCB) (int, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTspaceRotateCB) (int, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTspaceButtonCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTdialsCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTbuttonBoxCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTtabletMotionCB) (int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTtabletButtonCB) (int, int, int, int);
|
||||
typedef void (GLUTCALLBACK *GLUTjoystickCB) (unsigned int buttonMask, int x, int y, int z);
|
||||
|
||||
typedef struct _GLUTcolorcell GLUTcolorcell;
|
||||
struct _GLUTcolorcell {
|
||||
/* GLUT_RED, GLUT_GREEN, GLUT_BLUE */
|
||||
GLfloat component[3];
|
||||
};
|
||||
|
||||
typedef struct _GLUTcolormap GLUTcolormap;
|
||||
struct _GLUTcolormap {
|
||||
Visual *visual; /* visual of the colormap */
|
||||
Colormap cmap; /* X colormap ID */
|
||||
int refcnt; /* number of windows using colormap */
|
||||
int size; /* number of cells in colormap */
|
||||
int transparent; /* transparent pixel, or -1 if opaque */
|
||||
GLUTcolorcell *cells; /* array of cells */
|
||||
GLUTcolormap *next; /* next colormap in list */
|
||||
};
|
||||
|
||||
typedef struct _GLUTwindow GLUTwindow;
|
||||
typedef struct _GLUToverlay GLUToverlay;
|
||||
struct _GLUTwindow {
|
||||
int num; /* Small integer window id (0-based). */
|
||||
|
||||
/* Window system related state. */
|
||||
#if defined(_WIN32)
|
||||
int pf; /* Pixel format. */
|
||||
HDC hdc; /* Window's Win32 device context. */
|
||||
#endif
|
||||
Window win; /* X window for GLUT window */
|
||||
GLXContext ctx; /* OpenGL context GLUT glut window */
|
||||
XVisualInfo *vis; /* visual for window */
|
||||
Bool visAlloced; /* if vis needs deallocate on destroy */
|
||||
Colormap cmap; /* RGB colormap for window; None if CI */
|
||||
GLUTcolormap *colormap; /* colormap; NULL if RGBA */
|
||||
GLUToverlay *overlay; /* overlay; NULL if no overlay */
|
||||
#if defined(_WIN32)
|
||||
HDC renderDc; /* Win32's device context for rendering. */
|
||||
#endif
|
||||
Window renderWin; /* X window for rendering (might be
|
||||
overlay) */
|
||||
GLXContext renderCtx; /* OpenGL context for rendering (might
|
||||
be overlay) */
|
||||
/* GLUT settable or visible window state. */
|
||||
int width; /* window width in pixels */
|
||||
int height; /* window height in pixels */
|
||||
int cursor; /* cursor name */
|
||||
int visState; /* visibility state (-1 is unknown) */
|
||||
int shownState; /* if window mapped */
|
||||
int entryState; /* entry state (-1 is unknown) */
|
||||
#define GLUT_MAX_MENUS 3
|
||||
|
||||
int menu[GLUT_MAX_MENUS]; /* attatched menu nums */
|
||||
/* Window relationship state. */
|
||||
GLUTwindow *parent; /* parent window */
|
||||
GLUTwindow *children; /* list of children */
|
||||
GLUTwindow *siblings; /* list of siblings */
|
||||
/* Misc. non-API visible (hidden) state. */
|
||||
Bool treatAsSingle; /* treat this window as single-buffered
|
||||
(it might be "fake" though) */
|
||||
Bool forceReshape; /* force reshape before display */
|
||||
#if !defined(_WIN32)
|
||||
Bool isDirect; /* if direct context (X11 only) */
|
||||
#endif
|
||||
Bool usedSwapBuffers; /* if swap buffers used last display */
|
||||
long eventMask; /* mask of X events selected for */
|
||||
int buttonUses; /* number of button uses, ref cnt */
|
||||
int tabletPos[2]; /* tablet position (-1 is invalid) */
|
||||
/* Work list related state. */
|
||||
unsigned int workMask; /* mask of window work to be done */
|
||||
GLUTwindow *prevWorkWin; /* link list of windows to work on */
|
||||
Bool desiredMapState; /* how to mapped window if on map work
|
||||
list */
|
||||
Bool ignoreKeyRepeat; /* if window ignores autorepeat */
|
||||
int desiredConfMask; /* mask of desired window configuration
|
||||
*/
|
||||
int desiredX; /* desired X location */
|
||||
int desiredY; /* desired Y location */
|
||||
int desiredWidth; /* desired window width */
|
||||
int desiredHeight; /* desired window height */
|
||||
int desiredStack; /* desired window stack */
|
||||
/* Per-window callbacks. */
|
||||
GLUTdisplayCB display; /* redraw */
|
||||
GLUTreshapeCB reshape; /* resize (width,height) */
|
||||
GLUTmouseCB mouse; /* mouse (button,state,x,y) */
|
||||
GLUTmotionCB motion; /* motion (x,y) */
|
||||
GLUTpassiveCB passive; /* passive motion (x,y) */
|
||||
GLUTentryCB entry; /* window entry/exit (state) */
|
||||
GLUTkeyboardCB keyboard; /* keyboard (ASCII,x,y) */
|
||||
GLUTkeyboardCB keyboardUp; /* keyboard up (ASCII,x,y) */
|
||||
GLUTwindowStatusCB windowStatus; /* window status */
|
||||
GLUTvisibilityCB visibility; /* visibility */
|
||||
GLUTspecialCB special; /* special key */
|
||||
GLUTspecialCB specialUp; /* special up key */
|
||||
GLUTbuttonBoxCB buttonBox; /* button box */
|
||||
GLUTdialsCB dials; /* dials */
|
||||
GLUTspaceMotionCB spaceMotion; /* Spaceball motion */
|
||||
GLUTspaceRotateCB spaceRotate; /* Spaceball rotate */
|
||||
GLUTspaceButtonCB spaceButton; /* Spaceball button */
|
||||
GLUTtabletMotionCB tabletMotion; /* tablet motion */
|
||||
GLUTtabletButtonCB tabletButton; /* tablet button */
|
||||
#ifdef _WIN32
|
||||
GLUTjoystickCB joystick; /* joystick */
|
||||
int joyPollInterval; /* joystick polling interval */
|
||||
#endif
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
GLUTdisplayFCB fdisplay; /* Fortran display */
|
||||
GLUTreshapeFCB freshape; /* Fortran reshape */
|
||||
GLUTmouseFCB fmouse; /* Fortran mouse */
|
||||
GLUTmotionFCB fmotion; /* Fortran motion */
|
||||
GLUTpassiveFCB fpassive; /* Fortran passive */
|
||||
GLUTentryFCB fentry; /* Fortran entry */
|
||||
GLUTkeyboardFCB fkeyboard; /* Fortran keyboard */
|
||||
GLUTkeyboardFCB fkeyboardUp; /* Fortran keyboard up */
|
||||
GLUTwindowStatusFCB fwindowStatus; /* Fortran window status */
|
||||
GLUTvisibilityFCB fvisibility; /* Fortran visibility */
|
||||
GLUTspecialFCB fspecial; /* special key */
|
||||
GLUTspecialFCB fspecialUp; /* special key up */
|
||||
GLUTbuttonBoxFCB fbuttonBox; /* button box */
|
||||
GLUTdialsFCB fdials; /* dials */
|
||||
GLUTspaceMotionFCB fspaceMotion; /* Spaceball motion */
|
||||
GLUTspaceRotateFCB fspaceRotate; /* Spaceball rotate */
|
||||
GLUTspaceButtonFCB fspaceButton; /* Spaceball button */
|
||||
GLUTtabletMotionFCB ftabletMotion; /* tablet motion */
|
||||
GLUTtabletButtonFCB ftabletButton; /* tablet button */
|
||||
#ifdef _WIN32
|
||||
GLUTjoystickFCB fjoystick; /* joystick */
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _GLUToverlay {
|
||||
#if defined(_WIN32)
|
||||
int pf;
|
||||
HDC hdc;
|
||||
#endif
|
||||
Window win;
|
||||
GLXContext ctx;
|
||||
XVisualInfo *vis; /* visual for window */
|
||||
Bool visAlloced; /* if vis needs deallocate on destroy */
|
||||
Colormap cmap; /* RGB colormap for window; None if CI */
|
||||
GLUTcolormap *colormap; /* colormap; NULL if RGBA */
|
||||
int shownState; /* if overlay window mapped */
|
||||
Bool treatAsSingle; /* treat as single-buffered */
|
||||
#if !defined(_WIN32)
|
||||
Bool isDirect; /* if direct context */
|
||||
#endif
|
||||
int transparentPixel; /* transparent pixel value */
|
||||
GLUTdisplayCB display; /* redraw */
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
GLUTdisplayFCB fdisplay; /* redraw */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _GLUTstale GLUTstale;
|
||||
struct _GLUTstale {
|
||||
GLUTwindow *window;
|
||||
Window win;
|
||||
GLUTstale *next;
|
||||
};
|
||||
|
||||
extern GLUTstale *__glutStaleWindowList;
|
||||
|
||||
#define GLUT_OVERLAY_EVENT_FILTER_MASK \
|
||||
(ExposureMask | \
|
||||
StructureNotifyMask | \
|
||||
EnterWindowMask | \
|
||||
LeaveWindowMask)
|
||||
#define GLUT_DONT_PROPAGATE_FILTER_MASK \
|
||||
(ButtonReleaseMask | \
|
||||
ButtonPressMask | \
|
||||
KeyPressMask | \
|
||||
KeyReleaseMask | \
|
||||
PointerMotionMask | \
|
||||
Button1MotionMask | \
|
||||
Button2MotionMask | \
|
||||
Button3MotionMask)
|
||||
#define GLUT_HACK_STOP_PROPAGATE_MASK \
|
||||
(KeyPressMask | \
|
||||
KeyReleaseMask)
|
||||
|
||||
typedef struct _GLUTmenu GLUTmenu;
|
||||
typedef struct _GLUTmenuItem GLUTmenuItem;
|
||||
struct _GLUTmenu {
|
||||
int id; /* small integer menu id (0-based) */
|
||||
Window win; /* X window for the menu */
|
||||
GLUTselectCB select; /* function of menu */
|
||||
GLUTmenuItem *list; /* list of menu entries */
|
||||
int num; /* number of entries */
|
||||
#if !defined(_WIN32)
|
||||
Bool managed; /* are the InputOnly windows size
|
||||
validated? */
|
||||
Bool searched; /* help detect menu loops */
|
||||
int pixheight; /* height of menu in pixels */
|
||||
int pixwidth; /* width of menu in pixels */
|
||||
#endif
|
||||
int submenus; /* number of submenu entries */
|
||||
GLUTmenuItem *highlighted; /* pointer to highlighted menu
|
||||
entry, NULL not highlighted */
|
||||
GLUTmenu *cascade; /* currently cascading this menu */
|
||||
GLUTmenuItem *anchor; /* currently anchored to this entry */
|
||||
int x; /* current x origin relative to the
|
||||
root window */
|
||||
int y; /* current y origin relative to the
|
||||
root window */
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
GLUTselectFCB fselect; /* function of menu */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _GLUTmenuItem {
|
||||
Window win; /* InputOnly X window for entry */
|
||||
GLUTmenu *menu; /* menu entry belongs to */
|
||||
Bool isTrigger; /* is a submenu trigger? */
|
||||
int value; /* value to return for selecting this
|
||||
entry; doubles as submenu id
|
||||
(0-base) if submenu trigger */
|
||||
#if defined(_WIN32)
|
||||
UINT unique; /* unique menu item id (Win32 only) */
|
||||
#endif
|
||||
char *label; /* __glutStrdup'ed label string */
|
||||
int len; /* length of label string */
|
||||
int pixwidth; /* width of X window in pixels */
|
||||
GLUTmenuItem *next; /* next menu entry on list for menu */
|
||||
};
|
||||
|
||||
typedef struct _GLUTtimer GLUTtimer;
|
||||
struct _GLUTtimer {
|
||||
GLUTtimer *next; /* list of timers */
|
||||
struct timeval timeout; /* time to be called */
|
||||
GLUTtimerCB func; /* timer (value) */
|
||||
int value; /* return value */
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
GLUTtimerFCB ffunc; /* Fortran timer */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _GLUTeventParser GLUTeventParser;
|
||||
struct _GLUTeventParser {
|
||||
int (*func) (XEvent *);
|
||||
GLUTeventParser *next;
|
||||
};
|
||||
|
||||
/* Declarations to implement glutFullScreen support with
|
||||
mwm/4Dwm. */
|
||||
|
||||
/* The following X property format is defined in Motif 1.1's
|
||||
Xm/MwmUtils.h, but GLUT should not depend on that header
|
||||
file. Note: Motif 1.2 expanded this structure with
|
||||
uninteresting fields (to GLUT) so just stick with the
|
||||
smaller Motif 1.1 structure. */
|
||||
typedef struct {
|
||||
#define MWM_HINTS_DECORATIONS 2
|
||||
long flags;
|
||||
long functions;
|
||||
long decorations;
|
||||
long input_mode;
|
||||
} MotifWmHints;
|
||||
|
||||
/* Make current and buffer swap macros. */
|
||||
#ifdef _WIN32
|
||||
#define MAKE_CURRENT_LAYER(window) \
|
||||
{ \
|
||||
HGLRC currentContext = GetCurrentContext(); \
|
||||
HDC currentDc = GetCurrentDC(); \
|
||||
\
|
||||
if (currentContext != window->renderCtx \
|
||||
|| currentDc != window->renderDc) { \
|
||||
MakeCurrent(window->renderDc, window->renderCtx); \
|
||||
} \
|
||||
}
|
||||
#define MAKE_CURRENT_WINDOW(window) \
|
||||
{ \
|
||||
HGLRC currentContext = GetCurrentContext(); \
|
||||
HDC currentDc = GetCurrentDC(); \
|
||||
\
|
||||
if (currentContext != window->ctx || currentDc != window->hdc) { \
|
||||
MakeCurrent(window->hdc, window->ctx); \
|
||||
} \
|
||||
}
|
||||
#define MAKE_CURRENT_OVERLAY(overlay) \
|
||||
MakeCurrent(overlay->hdc, overlay->ctx)
|
||||
#define UNMAKE_CURRENT() \
|
||||
MakeCurrent(NULL, NULL)
|
||||
#define SWAP_BUFFERS_WINDOW(window) \
|
||||
SwapBuffers(window->hdc)
|
||||
#define SWAP_BUFFERS_LAYER(window) \
|
||||
SwapBuffers(window->renderDc)
|
||||
#else
|
||||
#define MAKE_CURRENT_LAYER(window) \
|
||||
glXMakeCurrent(__glutDisplay, window->renderWin, window->renderCtx)
|
||||
#define MAKE_CURRENT_WINDOW(window) \
|
||||
glXMakeCurrent(__glutDisplay, window->win, window->ctx)
|
||||
#define MAKE_CURRENT_OVERLAY(overlay) \
|
||||
glXMakeCurrent(__glutDisplay, overlay->win, overlay->ctx)
|
||||
#define UNMAKE_CURRENT() \
|
||||
glXMakeCurrent(__glutDisplay, None, NULL)
|
||||
#define SWAP_BUFFERS_WINDOW(window) \
|
||||
glXSwapBuffers(__glutDisplay, window->win)
|
||||
#define SWAP_BUFFERS_LAYER(window) \
|
||||
glXSwapBuffers(__glutDisplay, window->renderWin)
|
||||
#endif
|
||||
|
||||
/* private variables from glut_event.c */
|
||||
extern GLUTwindow *__glutWindowWorkList;
|
||||
extern int __glutWindowDamaged;
|
||||
#ifdef SUPPORT_FORTRAN
|
||||
extern GLUTtimer *__glutTimerList;
|
||||
extern GLUTtimer *__glutNewTimer;
|
||||
#endif
|
||||
extern GLUTmenu *__glutMappedMenu;
|
||||
|
||||
extern void (*__glutUpdateInputDeviceMaskFunc) (GLUTwindow *);
|
||||
#if !defined(_WIN32)
|
||||
extern void (*__glutMenuItemEnterOrLeave)(GLUTmenuItem * item,
|
||||
int num, int type);
|
||||
extern void (*__glutFinishMenu)(Window win, int x, int y);
|
||||
extern void (*__glutPaintMenu)(GLUTmenu * menu);
|
||||
extern void (*__glutStartMenu)(GLUTmenu * menu,
|
||||
GLUTwindow * window, int x, int y, int x_win, int y_win);
|
||||
extern GLUTmenu * (*__glutGetMenuByNum)(int menunum);
|
||||
extern GLUTmenuItem * (*__glutGetMenuItem)(GLUTmenu * menu,
|
||||
Window win, int *which);
|
||||
extern GLUTmenu * (*__glutGetMenu)(Window win);
|
||||
#endif
|
||||
|
||||
/* private variables from glut_init.c */
|
||||
extern Atom __glutWMDeleteWindow;
|
||||
extern Display *__glutDisplay;
|
||||
extern unsigned int __glutDisplayMode;
|
||||
extern char *__glutDisplayString;
|
||||
extern XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle,
|
||||
Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc);
|
||||
extern GLboolean __glutDebug;
|
||||
extern GLboolean __glutForceDirect;
|
||||
extern GLboolean __glutIconic;
|
||||
extern GLboolean __glutTryDirect;
|
||||
extern Window __glutRoot;
|
||||
extern XSizeHints __glutSizeHints;
|
||||
extern char **__glutArgv;
|
||||
extern char *__glutProgramName;
|
||||
extern int __glutArgc;
|
||||
extern int __glutConnectionFD;
|
||||
extern int __glutInitHeight;
|
||||
extern int __glutInitWidth;
|
||||
extern int __glutInitX;
|
||||
extern int __glutInitY;
|
||||
extern int __glutScreen;
|
||||
extern int __glutScreenHeight;
|
||||
extern int __glutScreenWidth;
|
||||
extern Atom __glutMotifHints;
|
||||
extern unsigned int __glutModifierMask;
|
||||
#ifdef _WIN32
|
||||
extern void (__cdecl *__glutExitFunc)(int retval);
|
||||
#endif
|
||||
|
||||
/* private variables from glut_menu.c */
|
||||
extern GLUTmenuItem *__glutItemSelected;
|
||||
extern GLUTmenu **__glutMenuList;
|
||||
extern void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);
|
||||
extern void __glutMenuModificationError(void);
|
||||
extern void __glutSetMenuItem(GLUTmenuItem * item,
|
||||
const char *label, int value, Bool isTrigger);
|
||||
|
||||
/* private variables from glut_win.c */
|
||||
extern GLUTwindow **__glutWindowList;
|
||||
extern GLUTwindow *__glutCurrentWindow;
|
||||
extern GLUTwindow *__glutMenuWindow;
|
||||
extern GLUTmenu *__glutCurrentMenu;
|
||||
extern int __glutWindowListSize;
|
||||
extern void (*__glutFreeOverlayFunc) (GLUToverlay *);
|
||||
extern XVisualInfo *__glutDetermineWindowVisual(Bool * treatAsSingle,
|
||||
Bool * visAlloced, void **fbc);
|
||||
|
||||
/* private variables from glut_mesa.c */
|
||||
extern int __glutMesaSwapHackSupport;
|
||||
|
||||
/* private variables from glut_gamemode.c */
|
||||
extern GLUTwindow *__glutGameModeWindow;
|
||||
|
||||
/* private routines from glut_cindex.c */
|
||||
extern GLUTcolormap * __glutAssociateNewColormap(XVisualInfo * vis);
|
||||
extern void __glutFreeColormap(GLUTcolormap *);
|
||||
|
||||
/* private routines from glut_cmap.c */
|
||||
extern void __glutSetupColormap(
|
||||
XVisualInfo * vi,
|
||||
GLUTcolormap ** colormap,
|
||||
Colormap * cmap);
|
||||
#if !defined(_WIN32)
|
||||
extern void __glutEstablishColormapsProperty(
|
||||
GLUTwindow * window);
|
||||
extern GLUTwindow *__glutToplevelOf(GLUTwindow * window);
|
||||
#endif
|
||||
|
||||
/* private routines from glut_cursor.c */
|
||||
extern void __glutSetCursor(GLUTwindow *window);
|
||||
|
||||
/* private routines from glut_event.c */
|
||||
extern void __glutPutOnWorkList(GLUTwindow * window,
|
||||
int work_mask);
|
||||
extern void __glutRegisterEventParser(GLUTeventParser * parser);
|
||||
extern void __glutPostRedisplay(GLUTwindow * window, int layerMask);
|
||||
|
||||
/* private routines from glut_init.c */
|
||||
#if !defined(_WIN32)
|
||||
extern void __glutOpenXConnection(char *display);
|
||||
#else
|
||||
extern void __glutOpenWin32Connection(char *display);
|
||||
#endif
|
||||
extern void __glutInitTime(struct timeval *beginning);
|
||||
|
||||
/* private routines for glut_menu.c (or win32_menu.c) */
|
||||
#if defined(_WIN32)
|
||||
extern GLUTmenu *__glutGetMenu(Window win);
|
||||
extern GLUTmenu *__glutGetMenuByNum(int menunum);
|
||||
extern GLUTmenuItem *__glutGetMenuItem(GLUTmenu * menu,
|
||||
Window win, int *which);
|
||||
extern void __glutStartMenu(GLUTmenu * menu,
|
||||
GLUTwindow * window, int x, int y, int x_win, int y_win);
|
||||
extern void __glutFinishMenu(Window win, int x, int y);
|
||||
#endif
|
||||
extern void __glutSetMenu(GLUTmenu * menu);
|
||||
|
||||
/* private routines from glut_util.c */
|
||||
extern char * __glutStrdup(const char *string);
|
||||
extern void __glutWarning(char *format,...);
|
||||
extern void __glutFatalError(char *format,...);
|
||||
extern void __glutFatalUsage(char *format,...);
|
||||
|
||||
/* private routines from glut_win.c */
|
||||
extern GLUTwindow *__glutGetWindow(Window win);
|
||||
extern void __glutChangeWindowEventMask(long mask, Bool add);
|
||||
extern XVisualInfo *__glutDetermineVisual(
|
||||
unsigned int mode,
|
||||
Bool * fakeSingle,
|
||||
XVisualInfo * (getVisualInfo) (unsigned int));
|
||||
extern XVisualInfo *__glutGetVisualInfo(unsigned int mode);
|
||||
extern void __glutSetWindow(GLUTwindow * window);
|
||||
extern void __glutReshapeFunc(GLUTreshapeCB reshapeFunc,
|
||||
int callingConvention);
|
||||
extern void GLUTCALLBACK __glutDefaultReshape(int, int);
|
||||
extern GLUTwindow *__glutCreateWindow(
|
||||
GLUTwindow * parent,
|
||||
int x, int y, int width, int height, int gamemode);
|
||||
extern void __glutDestroyWindow(
|
||||
GLUTwindow * window,
|
||||
GLUTwindow * initialWindow);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
/* private routines from glut_glxext.c */
|
||||
extern int __glutIsSupportedByGLX(char *);
|
||||
#endif
|
||||
|
||||
/* private routines from glut_input.c */
|
||||
extern void __glutUpdateInputDeviceMask(GLUTwindow * window);
|
||||
|
||||
/* private routines from glut_mesa.c */
|
||||
extern void __glutDetermineMesaSwapHackSupport(void);
|
||||
|
||||
/* private routines from glut_gameglut.c */
|
||||
extern void GLUTAPIENTRYV __glutCloseDownGameMode(void);
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* private routines from win32_*.c */
|
||||
extern LONG WINAPI __glutWindowProc(HWND win, UINT msg, WPARAM w, LPARAM l);
|
||||
extern HDC XHDC;
|
||||
#endif
|
||||
|
||||
#endif /* __glutint_h__ */
|
||||
42
src/glut/glx/glutstroke.h
Normal file
42
src/glut/glx/glutstroke.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef __glutstroke_h__
|
||||
#define __glutstroke_h__
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#if defined(_WIN32)
|
||||
#pragma warning (disable:4244) /* disable bogus conversion warnings */
|
||||
#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} CoordRec, *CoordPtr;
|
||||
|
||||
typedef struct {
|
||||
int num_coords;
|
||||
const CoordRec *coord;
|
||||
} StrokeRec, *StrokePtr;
|
||||
|
||||
typedef struct {
|
||||
int num_strokes;
|
||||
const StrokeRec *stroke;
|
||||
float center;
|
||||
float right;
|
||||
} StrokeCharRec, *StrokeCharPtr;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int num_chars;
|
||||
const StrokeCharRec *ch;
|
||||
float top;
|
||||
float bottom;
|
||||
} StrokeFontRec, *StrokeFontPtr;
|
||||
|
||||
typedef void *GLUTstrokeFont;
|
||||
|
||||
#endif /* __glutstroke_h__ */
|
||||
48
src/glut/glx/glutwin32.h
Normal file
48
src/glut/glx/glutwin32.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef __glutwin32_h__
|
||||
#define __glutwin32_h__
|
||||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "win32_x11.h"
|
||||
#include "win32_glx.h"
|
||||
|
||||
/* We have to undef some things because Microsoft likes to pollute the
|
||||
global namespace. */
|
||||
#undef TRANSPARENT
|
||||
|
||||
/* Win32 "equivalent" cursors - eventually, the X glyphs should be
|
||||
converted to Win32 cursors -- then they will look the same */
|
||||
#define XC_arrow IDC_ARROW
|
||||
#define XC_top_left_arrow IDC_ARROW
|
||||
#define XC_hand1 IDC_SIZEALL
|
||||
#define XC_pirate IDC_NO
|
||||
#define XC_question_arrow IDC_HELP
|
||||
#define XC_exchange IDC_NO
|
||||
#define XC_spraycan IDC_SIZEALL
|
||||
#define XC_watch IDC_WAIT
|
||||
#define XC_xterm IDC_IBEAM
|
||||
#define XC_crosshair IDC_CROSS
|
||||
#define XC_sb_v_double_arrow IDC_SIZENS
|
||||
#define XC_sb_h_double_arrow IDC_SIZEWE
|
||||
#define XC_top_side IDC_UPARROW
|
||||
#define XC_bottom_side IDC_SIZENS
|
||||
#define XC_left_side IDC_SIZEWE
|
||||
#define XC_right_side IDC_SIZEWE
|
||||
#define XC_top_left_corner IDC_SIZENWSE
|
||||
#define XC_top_right_corner IDC_SIZENESW
|
||||
#define XC_bottom_right_corner IDC_SIZENWSE
|
||||
#define XC_bottom_left_corner IDC_SIZENESW
|
||||
|
||||
#define XA_STRING 0
|
||||
|
||||
/* Private routines from win32_util.c */
|
||||
extern int gettimeofday(struct timeval* tp, void* tzp);
|
||||
extern void *__glutFont(void *font);
|
||||
extern int __glutGetTransparentPixel(Display *dpy, XVisualInfo *vinfo);
|
||||
extern void __glutAdjustCoords(Window parent, int *x, int *y, int *width, int *height);
|
||||
|
||||
#endif /* __glutwin32_h__ */
|
||||
201
src/glut/glx/layerutil.c
Normal file
201
src/glut/glx/layerutil.c
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1993, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
/* Based on XLayerUtil.c: Revision: 1.5 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "layerutil.h"
|
||||
|
||||
/* SGI optimization introduced in IRIX 6.3 to avoid X server
|
||||
round trips for interning common X atoms. */
|
||||
#include <X11/Xatom.h>
|
||||
#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)
|
||||
#include <X11/SGIFastAtom.h>
|
||||
#else
|
||||
#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)
|
||||
#endif
|
||||
|
||||
static Bool layersRead = False;
|
||||
static OverlayInfo **overlayInfoPerScreen;
|
||||
static unsigned long *numOverlaysPerScreen;
|
||||
|
||||
static void
|
||||
findServerOverlayVisualsInfo(Display * dpy)
|
||||
{
|
||||
static Atom overlayVisualsAtom;
|
||||
Atom actualType;
|
||||
Status status;
|
||||
unsigned long sizeData, bytesLeft;
|
||||
Window root;
|
||||
int actualFormat, numScreens, i;
|
||||
|
||||
if (layersRead == False) {
|
||||
overlayVisualsAtom = XSGIFastInternAtom(dpy,
|
||||
"SERVER_OVERLAY_VISUALS", SGI_XA_SERVER_OVERLAY_VISUALS, True);
|
||||
if (overlayVisualsAtom != None) {
|
||||
numScreens = ScreenCount(dpy);
|
||||
overlayInfoPerScreen = (OverlayInfo **)
|
||||
malloc(numScreens * sizeof(OverlayInfo *));
|
||||
numOverlaysPerScreen = (unsigned long *)
|
||||
malloc(numScreens * sizeof(unsigned long));
|
||||
if (overlayInfoPerScreen != NULL &&
|
||||
numOverlaysPerScreen != NULL) {
|
||||
for (i = 0; i < numScreens; i++) {
|
||||
root = RootWindow(dpy, i);
|
||||
status = XGetWindowProperty(dpy, root,
|
||||
overlayVisualsAtom, 0L, (long) 10000, False,
|
||||
overlayVisualsAtom, &actualType, &actualFormat,
|
||||
&sizeData, &bytesLeft,
|
||||
(unsigned char **) &overlayInfoPerScreen[i]);
|
||||
if (status != Success ||
|
||||
actualType != overlayVisualsAtom ||
|
||||
actualFormat != 32 || sizeData < 4)
|
||||
numOverlaysPerScreen[i] = 0;
|
||||
else
|
||||
/* Four 32-bit quantities per
|
||||
SERVER_OVERLAY_VISUALS entry. */
|
||||
numOverlaysPerScreen[i] = sizeData / 4;
|
||||
}
|
||||
layersRead = True;
|
||||
} else {
|
||||
if (overlayInfoPerScreen != NULL)
|
||||
free(overlayInfoPerScreen);
|
||||
if (numOverlaysPerScreen != NULL)
|
||||
free(numOverlaysPerScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)
|
||||
{
|
||||
int i, screen = vinfo->screen;
|
||||
OverlayInfo *overlayInfo;
|
||||
|
||||
findServerOverlayVisualsInfo(dpy);
|
||||
if (layersRead) {
|
||||
for (i = 0; i < numOverlaysPerScreen[screen]; i++) {
|
||||
overlayInfo = &overlayInfoPerScreen[screen][i];
|
||||
if (vinfo->visualid == overlayInfo->overlay_visual) {
|
||||
if (overlayInfo->transparent_type == TransparentPixel) {
|
||||
return (int) overlayInfo->value;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
XLayerVisualInfo *
|
||||
__glutXGetLayerVisualInfo(Display * dpy, long lvinfo_mask,
|
||||
XLayerVisualInfo * lvinfo_template, int *nitems_return)
|
||||
{
|
||||
XVisualInfo *vinfo;
|
||||
XLayerVisualInfo *layerInfo;
|
||||
int numVisuals, count, i, j;
|
||||
|
||||
vinfo = XGetVisualInfo(dpy, lvinfo_mask & VisualAllMask,
|
||||
&lvinfo_template->vinfo, nitems_return);
|
||||
if (vinfo == NULL)
|
||||
return NULL;
|
||||
numVisuals = *nitems_return;
|
||||
findServerOverlayVisualsInfo(dpy);
|
||||
layerInfo = (XLayerVisualInfo *)
|
||||
malloc(numVisuals * sizeof(XLayerVisualInfo));
|
||||
if (layerInfo == NULL) {
|
||||
XFree(vinfo);
|
||||
return NULL;
|
||||
}
|
||||
count = 0;
|
||||
for (i = 0; i < numVisuals; i++) {
|
||||
XVisualInfo *pVinfo = &vinfo[i];
|
||||
int screen = pVinfo->screen;
|
||||
OverlayInfo *overlayInfo = NULL;
|
||||
|
||||
overlayInfo = NULL;
|
||||
if (layersRead) {
|
||||
for (j = 0; j < numOverlaysPerScreen[screen]; j++)
|
||||
if (pVinfo->visualid ==
|
||||
overlayInfoPerScreen[screen][j].overlay_visual) {
|
||||
overlayInfo = &overlayInfoPerScreen[screen][j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lvinfo_mask & VisualLayerMask)
|
||||
if (overlayInfo == NULL) {
|
||||
if (lvinfo_template->layer != 0)
|
||||
continue;
|
||||
} else if (lvinfo_template->layer != overlayInfo->layer)
|
||||
continue;
|
||||
if (lvinfo_mask & VisualTransparentType)
|
||||
if (overlayInfo == NULL) {
|
||||
if (lvinfo_template->type != None)
|
||||
continue;
|
||||
} else if (lvinfo_template->type !=
|
||||
overlayInfo->transparent_type)
|
||||
continue;
|
||||
if (lvinfo_mask & VisualTransparentValue)
|
||||
if (overlayInfo == NULL)
|
||||
/* Non-overlay visuals have no sense of
|
||||
TransparentValue. */
|
||||
continue;
|
||||
else if (lvinfo_template->value != overlayInfo->value)
|
||||
continue;
|
||||
layerInfo[count].vinfo = *pVinfo;
|
||||
if (overlayInfo == NULL) {
|
||||
layerInfo[count].layer = 0;
|
||||
layerInfo[count].type = None;
|
||||
layerInfo[count].value = 0; /* meaningless */
|
||||
} else {
|
||||
layerInfo[count].layer = overlayInfo->layer;
|
||||
layerInfo[count].type = overlayInfo->transparent_type;
|
||||
layerInfo[count].value = overlayInfo->value;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
XFree(vinfo);
|
||||
*nitems_return = count;
|
||||
if (count == 0) {
|
||||
XFree(layerInfo);
|
||||
return NULL;
|
||||
} else
|
||||
return layerInfo;
|
||||
}
|
||||
|
||||
#if 0 /* Unused by GLUT. */
|
||||
Status
|
||||
__glutXMatchLayerVisualInfo(Display * dpy, int screen,
|
||||
int depth, int visualClass, int layer,
|
||||
XLayerVisualInfo * lvinfo_return)
|
||||
{
|
||||
XLayerVisualInfo *lvinfo;
|
||||
XLayerVisualInfo lvinfoTemplate;
|
||||
int nitems;
|
||||
|
||||
lvinfoTemplate.vinfo.screen = screen;
|
||||
lvinfoTemplate.vinfo.depth = depth;
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
lvinfoTemplate.vinfo.c_class = visualClass;
|
||||
#else
|
||||
lvinfoTemplate.vinfo.class = visualClass;
|
||||
#endif
|
||||
lvinfoTemplate.layer = layer;
|
||||
lvinfo = __glutXGetLayerVisualInfo(dpy,
|
||||
VisualScreenMask | VisualDepthMask |
|
||||
VisualClassMask | VisualLayerMask,
|
||||
&lvinfoTemplate, &nitems);
|
||||
if (lvinfo != NULL && nitems > 0) {
|
||||
*lvinfo_return = *lvinfo;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
55
src/glut/glx/layerutil.h
Normal file
55
src/glut/glx/layerutil.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef __layerutil_h__
|
||||
#define __layerutil_h__
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1993, 1994. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
/* Based on XLayerUtil.h: Revision: 1.3 */
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xmd.h>
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
/* Transparent type values */
|
||||
/* None 0 */
|
||||
#define TransparentPixel 1
|
||||
#define TransparentMask 2
|
||||
|
||||
/* layered visual info template flags */
|
||||
#define VisualLayerMask 0x200
|
||||
#define VisualTransparentType 0x400
|
||||
#define VisualTransparentValue 0x800
|
||||
#define VisualAllLayerMask 0xFFF
|
||||
|
||||
/* layered visual info structure */
|
||||
typedef struct _XLayerVisualInfo {
|
||||
XVisualInfo vinfo;
|
||||
long layer;
|
||||
long type;
|
||||
unsigned long value;
|
||||
} XLayerVisualInfo;
|
||||
|
||||
/* SERVER_OVERLAY_VISUALS property element */
|
||||
typedef struct _OverlayInfo {
|
||||
/* Avoid 64-bit portability problems by being careful to use
|
||||
longs due to the way XGetWindowProperty is specified. Note
|
||||
that these parameters are passed as CARD32s over X
|
||||
protocol. */
|
||||
long overlay_visual;
|
||||
long transparent_type;
|
||||
long value;
|
||||
long layer;
|
||||
} OverlayInfo;
|
||||
|
||||
extern int __glutGetTransparentPixel(Display *, XVisualInfo *);
|
||||
extern XLayerVisualInfo *__glutXGetLayerVisualInfo(Display *,
|
||||
long, XLayerVisualInfo *, int *);
|
||||
extern Status __glutXMatchLayerVisualInfo(Display *,
|
||||
int, int, int, int, XLayerVisualInfo *);
|
||||
|
||||
#endif /* __layerutil_h__ */
|
||||
72
src/glut/glx/mms_depend
Normal file
72
src/glut/glx/mms_depend
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# DO NOT DELETE
|
||||
|
||||
glut_8x13.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_9x15.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_bitmap.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_bitmap.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_bitmap.obj : glutbitmap.h
|
||||
glut_bwidth.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_bwidth.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_bwidth.obj : glutbitmap.h
|
||||
glut_cindex.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_cindex.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_cindex.obj : layerutil.h
|
||||
glut_cursor.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_cursor.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_dials.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_dials.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h [-.include.gl]glu.h
|
||||
glut_dstr.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_dstr.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h [-.include.gl]glu.h
|
||||
glut_event.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_event.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_ext.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_ext.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_fullscrn.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_fullscrn.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h
|
||||
glut_fullscrn.obj : [-.include.gl]glu.h
|
||||
glut_get.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_get.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_hel10.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_hel12.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_hel18.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_init.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_init.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_menu.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_menu.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h layerutil.h
|
||||
glut_mesa.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_mesa.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h [-.include.gl]glu.h
|
||||
glut_modifier.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_modifier.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h
|
||||
glut_modifier.obj : [-.include.gl]glu.h
|
||||
glut_mroman.obj : glutstroke.h
|
||||
glut_overlay.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_overlay.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_overlay.obj : layerutil.h
|
||||
glut_roman.obj : glutstroke.h
|
||||
glut_shapes.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_shapes.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_space.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_space.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h [-.include.gl]glu.h
|
||||
glut_stroke.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_stroke.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_stroke.obj : glutstroke.h
|
||||
glut_swidth.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_swidth.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_swidth.obj : glutstroke.h
|
||||
glut_tablet.obj : glutint.h [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_tablet.obj : [-.include.gl]xmesa.h [-.include.gl]glut.h [-.include.gl]glu.h
|
||||
glut_teapot.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_tr10.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_tr24.obj : glutbitmap.h [-.include.gl]gl.h
|
||||
glut_util.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_util.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_vidresize.obj : [-.include.gl]glx.h [-.include.gl]gl.h
|
||||
glut_vidresize.obj : [-.include.gl]xmesa.h glutint.h [-.include.gl]glut.h
|
||||
glut_vidresize.obj : [-.include.gl]glu.h
|
||||
glut_warp.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_warp.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_win.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_win.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
glut_winmisc.obj : [-.include.gl]glut.h [-.include.gl]gl.h [-.include.gl]glu.h
|
||||
glut_winmisc.obj : glutint.h [-.include.gl]glx.h [-.include.gl]xmesa.h
|
||||
layerutil.obj : layerutil.h
|
||||
134
src/glut/glx/stroke.h
Normal file
134
src/glut/glx/stroke.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/* $XConsortium: wfont.h,v 5.1 91/02/16 09:46:37 rws Exp $ */
|
||||
|
||||
/*****************************************************************
|
||||
Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Sun Microsystems,
|
||||
the X Consortium, and MIT not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific, written
|
||||
prior permission.
|
||||
|
||||
SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
|
||||
SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef WFONT_INCLUDED
|
||||
#define WFONT_INCLUDED
|
||||
|
||||
#define WFONT_MAGIC 0x813
|
||||
#define WFONT_MAGIC_PLUS 0x715
|
||||
#define WFONT_MAGIC_PEX 0x70686e74
|
||||
#define START_PROPS 0x100
|
||||
#define START_DISPATCH(_num_props) (START_PROPS + 160 * _num_props)
|
||||
#define START_PATH(_num_ch_, _num_props) (START_DISPATCH(_num_props) + sizeof(Dispatch) * _num_ch_)
|
||||
#define NUM_DISPATCH 128
|
||||
|
||||
typedef struct {
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
} Path_point2dpx;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} Path_point2df;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
} Path_point3di;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} Path_point3df;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
} Path_point4df;
|
||||
|
||||
typedef union {
|
||||
Path_point2dpx *pt2dpx;
|
||||
Path_point2df *pt2df;
|
||||
Path_point3di *pt3di;
|
||||
Path_point3df *pt3df;
|
||||
Path_point4df *pt4df;
|
||||
} Path_pt_ptr;
|
||||
|
||||
typedef enum {
|
||||
PATH_2DF,
|
||||
PATH_2DPX,
|
||||
PATH_3DF,
|
||||
PATH_3DI,
|
||||
PATH_4DF
|
||||
} Path_type;
|
||||
|
||||
typedef struct {
|
||||
int n_pts; /* number of points in the subpath */
|
||||
Path_pt_ptr pts; /* pointer to them */
|
||||
int closed; /* true if the subpath is closed */
|
||||
int dcmp_flag; /* flag for pgon dcmp, pgon type
|
||||
* and dcmped triangle type */
|
||||
} Path_subpath;
|
||||
|
||||
typedef struct {
|
||||
Path_type type; /* type of vertices in this path */
|
||||
int n_subpaths; /* number of subpaths */
|
||||
int n_vertices; /* total number of vertices */
|
||||
Path_subpath *subpaths; /* array of subpaths */
|
||||
} Path;
|
||||
|
||||
typedef Path *Path_handle;
|
||||
|
||||
typedef struct {
|
||||
char propname[80]; /* font property name */
|
||||
char propvalue[80]; /* font property value */
|
||||
} Property;
|
||||
|
||||
typedef struct {
|
||||
int magic; /* magic number */
|
||||
char name[80]; /* name of this font */
|
||||
float top, /* extreme values */
|
||||
bottom, max_width;
|
||||
int num_ch; /* no. of fonts in the set */
|
||||
int num_props; /* no. of font properties */
|
||||
Property *properties; /* array of properties */
|
||||
} Font_header;
|
||||
|
||||
typedef struct {
|
||||
float center, /* center of the character */
|
||||
right; /* right edge */
|
||||
long offset; /* offset in the file of the character
|
||||
* * description */
|
||||
} Dispatch;
|
||||
|
||||
typedef struct {
|
||||
float center, right;
|
||||
Path strokes;
|
||||
} Ch_font;
|
||||
|
||||
typedef struct {
|
||||
char name[80];
|
||||
float top, bottom, max_width;
|
||||
int num_ch; /* # characters in the font */
|
||||
Ch_font **ch_data;
|
||||
} Phg_font;
|
||||
|
||||
#endif /*WFONT_INCLUDED */
|
||||
256
src/glut/glx/win32_glx.c
Normal file
256
src/glut/glx/win32_glx.c
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "glutint.h"
|
||||
#include "win32_glx.h"
|
||||
|
||||
/* global current HDC */
|
||||
extern HDC XHDC;
|
||||
|
||||
GLXContext
|
||||
glXCreateContext(Display * display, XVisualInfo * visinfo,
|
||||
GLXContext share, Bool direct)
|
||||
{
|
||||
/* KLUDGE: GLX really expects a display pointer to be passed
|
||||
in as the first parameter, but Win32 needs an HDC instead,
|
||||
so BE SURE that the global XHDC is set before calling this
|
||||
routine. */
|
||||
HGLRC context;
|
||||
|
||||
context = CreateContext(XHDC);
|
||||
|
||||
#if 0
|
||||
/* XXX GLUT doesn't support it now, so don't worry about display list
|
||||
and texture object sharing. */
|
||||
if (share) {
|
||||
wglShareLists(share, context);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Since direct rendering is implicit, the direct flag is
|
||||
ignored. */
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
int
|
||||
glXGetConfig(Display * display, XVisualInfo * visual, int attrib, int *value)
|
||||
{
|
||||
if (!visual)
|
||||
return GLX_BAD_VISUAL;
|
||||
|
||||
switch (attrib) {
|
||||
case GLX_USE_GL:
|
||||
if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) {
|
||||
/* XXX Brad's Matrix Millenium II has problems creating
|
||||
color index windows in 24-bit mode (lead to GDI crash)
|
||||
and 32-bit mode (lead to black window). The cColorBits
|
||||
filed of the PIXELFORMATDESCRIPTOR returned claims to
|
||||
have 24 and 32 bits respectively of color indices. 2^24
|
||||
and 2^32 are ridiculously huge writable colormaps.
|
||||
Assume that if we get back a color index
|
||||
PIXELFORMATDESCRIPTOR with 24 or more bits, the
|
||||
PIXELFORMATDESCRIPTOR doesn't really work and skip it.
|
||||
-mjk */
|
||||
if (visual->iPixelType == PFD_TYPE_COLORINDEX
|
||||
&& visual->cColorBits >= 24) {
|
||||
*value = 0;
|
||||
} else {
|
||||
*value = 1;
|
||||
}
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
case GLX_BUFFER_SIZE:
|
||||
/* KLUDGE: if we're RGBA, return the number of bits/pixel,
|
||||
otherwise, return 8 (we guessed at 256 colors in CI
|
||||
mode). */
|
||||
if (visual->iPixelType == PFD_TYPE_RGBA)
|
||||
*value = visual->cColorBits;
|
||||
else
|
||||
*value = 8;
|
||||
break;
|
||||
case GLX_LEVEL:
|
||||
/* The bReserved flag of the pfd contains the
|
||||
overlay/underlay info. */
|
||||
*value = visual->bReserved;
|
||||
break;
|
||||
case GLX_RGBA:
|
||||
*value = visual->iPixelType == PFD_TYPE_RGBA;
|
||||
break;
|
||||
case GLX_DOUBLEBUFFER:
|
||||
*value = visual->dwFlags & PFD_DOUBLEBUFFER;
|
||||
break;
|
||||
case GLX_STEREO:
|
||||
*value = visual->dwFlags & PFD_STEREO;
|
||||
break;
|
||||
case GLX_AUX_BUFFERS:
|
||||
*value = visual->cAuxBuffers;
|
||||
break;
|
||||
case GLX_RED_SIZE:
|
||||
*value = visual->cRedBits;
|
||||
break;
|
||||
case GLX_GREEN_SIZE:
|
||||
*value = visual->cGreenBits;
|
||||
break;
|
||||
case GLX_BLUE_SIZE:
|
||||
*value = visual->cBlueBits;
|
||||
break;
|
||||
case GLX_ALPHA_SIZE:
|
||||
*value = visual->cAlphaBits;
|
||||
break;
|
||||
case GLX_DEPTH_SIZE:
|
||||
*value = visual->cDepthBits;
|
||||
break;
|
||||
case GLX_STENCIL_SIZE:
|
||||
*value = visual->cStencilBits;
|
||||
break;
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
*value = visual->cAccumRedBits;
|
||||
break;
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
*value = visual->cAccumGreenBits;
|
||||
break;
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
*value = visual->cAccumBlueBits;
|
||||
break;
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
*value = visual->cAccumAlphaBits;
|
||||
break;
|
||||
default:
|
||||
return GLX_BAD_ATTRIB;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XVisualInfo *
|
||||
glXChooseVisual(Display * display, int screen, int *attribList)
|
||||
{
|
||||
/* KLUDGE: since we need the HDC, MAKE SURE to set XHDC
|
||||
before calling this routine. */
|
||||
|
||||
int *p = attribList;
|
||||
int pf;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
PIXELFORMATDESCRIPTOR *match = NULL;
|
||||
int stereo = 0;
|
||||
|
||||
/* Avoid seg-faults. */
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR));
|
||||
pfd.nVersion = 1;
|
||||
|
||||
/* Defaults. */
|
||||
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
|
||||
pfd.iPixelType = PFD_TYPE_COLORINDEX;
|
||||
pfd.cColorBits = 32;
|
||||
pfd.cDepthBits = 0;
|
||||
|
||||
while (*p) {
|
||||
switch (*p) {
|
||||
case GLX_USE_GL:
|
||||
pfd.dwFlags |= PFD_SUPPORT_OPENGL;
|
||||
break;
|
||||
case GLX_BUFFER_SIZE:
|
||||
pfd.cColorBits = *(++p);
|
||||
break;
|
||||
case GLX_LEVEL:
|
||||
/* the bReserved flag of the pfd contains the
|
||||
overlay/underlay info. */
|
||||
pfd.bReserved = *(++p);
|
||||
break;
|
||||
case GLX_RGBA:
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
break;
|
||||
case GLX_DOUBLEBUFFER:
|
||||
pfd.dwFlags |= PFD_DOUBLEBUFFER;
|
||||
break;
|
||||
case GLX_STEREO:
|
||||
stereo = 1;
|
||||
pfd.dwFlags |= PFD_STEREO;
|
||||
break;
|
||||
case GLX_AUX_BUFFERS:
|
||||
pfd.cAuxBuffers = *(++p);
|
||||
break;
|
||||
case GLX_RED_SIZE:
|
||||
pfd.cRedBits = 8; /* Try to get the maximum. */
|
||||
++p;
|
||||
break;
|
||||
case GLX_GREEN_SIZE:
|
||||
pfd.cGreenBits = 8;
|
||||
++p;
|
||||
break;
|
||||
case GLX_BLUE_SIZE:
|
||||
pfd.cBlueBits = 8;
|
||||
++p;
|
||||
break;
|
||||
case GLX_ALPHA_SIZE:
|
||||
pfd.cAlphaBits = 8;
|
||||
++p;
|
||||
break;
|
||||
case GLX_DEPTH_SIZE:
|
||||
pfd.cDepthBits = 32;
|
||||
++p;
|
||||
break;
|
||||
case GLX_STENCIL_SIZE:
|
||||
pfd.cStencilBits = *(++p);
|
||||
break;
|
||||
case GLX_ACCUM_RED_SIZE:
|
||||
case GLX_ACCUM_GREEN_SIZE:
|
||||
case GLX_ACCUM_BLUE_SIZE:
|
||||
case GLX_ACCUM_ALPHA_SIZE:
|
||||
/* I believe that WGL only used the cAccumRedBits,
|
||||
cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields
|
||||
when returning info about the accumulation buffer precision.
|
||||
Only cAccumBits is used for requesting an accumulation
|
||||
buffer. */
|
||||
pfd.cAccumBits = 1;
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
||||
/* Let Win32 choose one for us. */
|
||||
pf = ChoosePixelFormat(XHDC, &pfd);
|
||||
if (pf > 0) {
|
||||
match = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR));
|
||||
DescribePixelFormat(XHDC, pf, sizeof(PIXELFORMATDESCRIPTOR), match);
|
||||
|
||||
/* ChoosePixelFormat is dumb in that it will return a pixel
|
||||
format that doesn't have stereo even if it was requested
|
||||
so we need to make sure that if stereo was selected, we
|
||||
got it. */
|
||||
if (stereo) {
|
||||
if (!(match->dwFlags & PFD_STEREO)) {
|
||||
free(match);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* XXX Brad's Matrix Millenium II has problems creating
|
||||
color index windows in 24-bit mode (lead to GDI crash)
|
||||
and 32-bit mode (lead to black window). The cColorBits
|
||||
filed of the PIXELFORMATDESCRIPTOR returned claims to
|
||||
have 24 and 32 bits respectively of color indices. 2^24
|
||||
and 2^32 are ridiculously huge writable colormaps.
|
||||
Assume that if we get back a color index
|
||||
PIXELFORMATDESCRIPTOR with 24 or more bits, the
|
||||
PIXELFORMATDESCRIPTOR doesn't really work and skip it.
|
||||
-mjk */
|
||||
if (match->iPixelType == PFD_TYPE_COLORINDEX
|
||||
&& match->cColorBits >= 24) {
|
||||
free(match);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
58
src/glut/glx/win32_glx.h
Normal file
58
src/glut/glx/win32_glx.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef __win32_glx_h__
|
||||
#define __win32_glx_h__
|
||||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "win32_x11.h"
|
||||
|
||||
/* Type definitions (conversions). */
|
||||
typedef HGLRC GLXContext;
|
||||
|
||||
#define GLX_USE_GL 1 /* support GLX rendering */
|
||||
#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */
|
||||
#define GLX_LEVEL 3 /* level in plane stacking */
|
||||
#define GLX_RGBA 4 /* true if RGBA mode */
|
||||
#define GLX_DOUBLEBUFFER 5 /* double buffering supported */
|
||||
#define GLX_STEREO 6 /* stereo buffering supported */
|
||||
#define GLX_AUX_BUFFERS 7 /* number of aux buffers */
|
||||
#define GLX_RED_SIZE 8 /* number of red component bits */
|
||||
#define GLX_GREEN_SIZE 9 /* number of green component bits */
|
||||
#define GLX_BLUE_SIZE 10 /* number of blue component bits */
|
||||
#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */
|
||||
#define GLX_DEPTH_SIZE 12 /* number of depth bits */
|
||||
#define GLX_STENCIL_SIZE 13 /* number of stencil bits */
|
||||
#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */
|
||||
#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */
|
||||
#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */
|
||||
#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */
|
||||
|
||||
#define GLX_BAD_ATTRIB 2
|
||||
#define GLX_BAD_VISUAL 4
|
||||
|
||||
/* Functions emulated by macros. */
|
||||
|
||||
#define glXDestroyContext(display, context) \
|
||||
wglDeleteContext(context)
|
||||
|
||||
/* Function prototypes. */
|
||||
|
||||
extern GLXContext glXCreateContext(
|
||||
Display* display,
|
||||
XVisualInfo* visinfo,
|
||||
GLXContext share,
|
||||
Bool direct);
|
||||
extern int glXGetConfig(
|
||||
Display* display,
|
||||
XVisualInfo* visual,
|
||||
int attrib,
|
||||
int* value);
|
||||
extern XVisualInfo* glXChooseVisual(
|
||||
Display* display,
|
||||
int screen,
|
||||
int* attribList);
|
||||
|
||||
#endif /* __win32_glx_h__ */
|
||||
532
src/glut/glx/win32_menu.c
Normal file
532
src/glut/glx/win32_menu.c
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
/* This file completely re-implements glut_menu.c and glut_menu2.c
|
||||
for Win32. Note that neither glut_menu.c nor glut_menu2.c are
|
||||
compiled into Win32 GLUT. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);
|
||||
GLUTmenu *__glutMappedMenu;
|
||||
GLUTwindow *__glutMenuWindow;
|
||||
GLUTmenuItem *__glutItemSelected;
|
||||
unsigned __glutMenuButton;
|
||||
|
||||
static GLUTmenu **menuList = NULL;
|
||||
static int menuListSize = 0;
|
||||
static UINT uniqueMenuHandler = 1;
|
||||
|
||||
/* DEPRICATED, use glutMenuStatusFunc instead. */
|
||||
void APIENTRY
|
||||
glutMenuStateFunc(GLUTmenuStateCB menuStateFunc)
|
||||
{
|
||||
__glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc)
|
||||
{
|
||||
__glutMenuStatusFunc = menuStatusFunc;
|
||||
}
|
||||
|
||||
void
|
||||
__glutSetMenu(GLUTmenu * menu)
|
||||
{
|
||||
__glutCurrentMenu = menu;
|
||||
}
|
||||
|
||||
static void
|
||||
unmapMenu(GLUTmenu * menu)
|
||||
{
|
||||
if (menu->cascade) {
|
||||
unmapMenu(menu->cascade);
|
||||
menu->cascade = NULL;
|
||||
}
|
||||
menu->anchor = NULL;
|
||||
menu->highlighted = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
__glutFinishMenu(Window win, int x, int y)
|
||||
{
|
||||
|
||||
unmapMenu(__glutMappedMenu);
|
||||
|
||||
/* XXX Put in a GdiFlush just in case. Probably unnecessary. -mjk */
|
||||
GdiFlush();
|
||||
|
||||
if (__glutMenuStatusFunc) {
|
||||
__glutSetWindow(__glutMenuWindow);
|
||||
__glutSetMenu(__glutMappedMenu);
|
||||
|
||||
/* Setting __glutMappedMenu to NULL permits operations that
|
||||
change menus or destroy the menu window again. */
|
||||
__glutMappedMenu = NULL;
|
||||
|
||||
__glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y);
|
||||
}
|
||||
/* Setting __glutMappedMenu to NULL permits operations that
|
||||
change menus or destroy the menu window again. */
|
||||
__glutMappedMenu = NULL;
|
||||
|
||||
/* If an item is selected and it is not a submenu trigger,
|
||||
generate menu callback. */
|
||||
if (__glutItemSelected && !__glutItemSelected->isTrigger) {
|
||||
__glutSetWindow(__glutMenuWindow);
|
||||
/* When menu callback is triggered, current menu should be
|
||||
set to the callback menu. */
|
||||
__glutSetMenu(__glutItemSelected->menu);
|
||||
__glutItemSelected->menu->select(__glutItemSelected->value);
|
||||
}
|
||||
__glutMenuWindow = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mapMenu(GLUTmenu * menu, int x, int y)
|
||||
{
|
||||
TrackPopupMenu(menu->win, TPM_LEFTALIGN |
|
||||
__glutMenuButton == TPM_RIGHTBUTTON ?
|
||||
TPM_RIGHTBUTTON : TPM_LEFTBUTTON,
|
||||
x, y, 0, __glutCurrentWindow->win, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
__glutStartMenu(GLUTmenu * menu, GLUTwindow * window,
|
||||
int x, int y, int x_win, int y_win)
|
||||
{
|
||||
assert(__glutMappedMenu == NULL);
|
||||
__glutMappedMenu = menu;
|
||||
__glutMenuWindow = window;
|
||||
__glutItemSelected = NULL;
|
||||
if (__glutMenuStatusFunc) {
|
||||
__glutSetMenu(menu);
|
||||
__glutSetWindow(window);
|
||||
__glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win);
|
||||
}
|
||||
mapMenu(menu, x, y);
|
||||
}
|
||||
|
||||
GLUTmenuItem *
|
||||
__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique)
|
||||
{
|
||||
GLUTmenuItem *item;
|
||||
int i;
|
||||
|
||||
i = menu->num;
|
||||
item = menu->list;
|
||||
while (item) {
|
||||
if (item->unique == unique) {
|
||||
return item;
|
||||
}
|
||||
if (item->isTrigger) {
|
||||
GLUTmenuItem *subitem;
|
||||
subitem = __glutGetUniqueMenuItem(menuList[item->value], unique);
|
||||
if (subitem) {
|
||||
return subitem;
|
||||
}
|
||||
}
|
||||
i--;
|
||||
item = item->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GLUTmenuItem *
|
||||
__glutGetMenuItem(GLUTmenu * menu, Window win, int *which)
|
||||
{
|
||||
GLUTmenuItem *item;
|
||||
int i;
|
||||
|
||||
i = menu->num;
|
||||
item = menu->list;
|
||||
while (item) {
|
||||
if (item->win == win) {
|
||||
*which = i;
|
||||
return item;
|
||||
}
|
||||
if (item->isTrigger) {
|
||||
GLUTmenuItem *subitem;
|
||||
|
||||
subitem = __glutGetMenuItem(menuList[item->value],
|
||||
win, which);
|
||||
if (subitem) {
|
||||
return subitem;
|
||||
}
|
||||
}
|
||||
i--;
|
||||
item = item->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GLUTmenu *
|
||||
__glutGetMenu(Window win)
|
||||
{
|
||||
GLUTmenu *menu;
|
||||
|
||||
menu = __glutMappedMenu;
|
||||
while (menu) {
|
||||
if (win == menu->win) {
|
||||
return menu;
|
||||
}
|
||||
menu = menu->cascade;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GLUTmenu *
|
||||
__glutGetMenuByNum(int menunum)
|
||||
{
|
||||
if (menunum < 1 || menunum > menuListSize) {
|
||||
return NULL;
|
||||
}
|
||||
return menuList[menunum - 1];
|
||||
}
|
||||
|
||||
static int
|
||||
getUnusedMenuSlot(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Look for allocated, unused slot. */
|
||||
for (i = 0; i < menuListSize; i++) {
|
||||
if (!menuList[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* Allocate a new slot. */
|
||||
menuListSize++;
|
||||
if (menuList) {
|
||||
menuList = (GLUTmenu **)
|
||||
realloc(menuList, menuListSize * sizeof(GLUTmenu *));
|
||||
} else {
|
||||
/* XXX Some realloc's do not correctly perform a malloc
|
||||
when asked to perform a realloc on a NULL pointer,
|
||||
though the ANSI C library spec requires this. */
|
||||
menuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *));
|
||||
}
|
||||
if (!menuList) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
menuList[menuListSize - 1] = NULL;
|
||||
return menuListSize - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
menuModificationError(void)
|
||||
{
|
||||
/* XXX Remove the warning after GLUT 3.0. */
|
||||
__glutWarning("The following is a new check for GLUT 3.0; update your code.");
|
||||
__glutFatalError("menu manipulation not allowed while menus in use.");
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutCreateMenu(GLUTselectCB selectFunc)
|
||||
{
|
||||
GLUTmenu *menu;
|
||||
int menuid;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
menuid = getUnusedMenuSlot();
|
||||
menu = (GLUTmenu *) malloc(sizeof(GLUTmenu));
|
||||
if (!menu) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
menu->id = menuid;
|
||||
menu->num = 0;
|
||||
menu->submenus = 0;
|
||||
menu->select = selectFunc;
|
||||
menu->list = NULL;
|
||||
menu->cascade = NULL;
|
||||
menu->highlighted = NULL;
|
||||
menu->anchor = NULL;
|
||||
menu->win = CreatePopupMenu();
|
||||
menuList[menuid] = menu;
|
||||
__glutSetMenu(menu);
|
||||
return menuid + 1;
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
__glutCreateMenuWithExit(GLUTselectCB selectFunc, void (__cdecl *exitfunc)(int))
|
||||
{
|
||||
__glutExitFunc = exitfunc;
|
||||
return glutCreateMenu(selectFunc);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutDestroyMenu(int menunum)
|
||||
{
|
||||
GLUTmenu *menu = __glutGetMenuByNum(menunum);
|
||||
GLUTmenuItem *item, *next;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
assert(menu->id == menunum - 1);
|
||||
DestroyMenu(menu->win);
|
||||
menuList[menunum - 1] = NULL;
|
||||
/* free all menu entries */
|
||||
item = menu->list;
|
||||
while (item) {
|
||||
assert(item->menu == menu);
|
||||
next = item->next;
|
||||
free(item->label);
|
||||
free(item);
|
||||
item = next;
|
||||
}
|
||||
if (__glutCurrentMenu == menu) {
|
||||
__glutCurrentMenu = NULL;
|
||||
}
|
||||
free(menu);
|
||||
}
|
||||
|
||||
int APIENTRY
|
||||
glutGetMenu(void)
|
||||
{
|
||||
if (__glutCurrentMenu) {
|
||||
return __glutCurrentMenu->id + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutSetMenu(int menuid)
|
||||
{
|
||||
GLUTmenu *menu;
|
||||
|
||||
if (menuid < 1 || menuid > menuListSize) {
|
||||
__glutWarning("glutSetMenu attempted on bogus menu.");
|
||||
return;
|
||||
}
|
||||
menu = menuList[menuid - 1];
|
||||
if (!menu) {
|
||||
__glutWarning("glutSetMenu attempted on bogus menu.");
|
||||
return;
|
||||
}
|
||||
__glutSetMenu(menu);
|
||||
}
|
||||
|
||||
static void
|
||||
setMenuItem(GLUTmenuItem * item, const char *label,
|
||||
int value, Bool isTrigger)
|
||||
{
|
||||
GLUTmenu *menu;
|
||||
|
||||
menu = item->menu;
|
||||
item->label = __glutStrdup(label);
|
||||
if (!item->label) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
item->isTrigger = isTrigger;
|
||||
item->len = (int) strlen(label);
|
||||
item->value = value;
|
||||
item->unique = uniqueMenuHandler++;
|
||||
if (isTrigger) {
|
||||
AppendMenu(menu->win, MF_POPUP, (UINT)item->win, label);
|
||||
} else {
|
||||
AppendMenu(menu->win, MF_STRING, item->unique, label);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutAddMenuEntry(const char *label, int value)
|
||||
{
|
||||
GLUTmenuItem *entry;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));
|
||||
if (!entry) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
entry->menu = __glutCurrentMenu;
|
||||
setMenuItem(entry, label, value, FALSE);
|
||||
__glutCurrentMenu->num++;
|
||||
entry->next = __glutCurrentMenu->list;
|
||||
__glutCurrentMenu->list = entry;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutAddSubMenu(const char *label, int menu)
|
||||
{
|
||||
GLUTmenuItem *submenu;
|
||||
GLUTmenu *popupmenu;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));
|
||||
if (!submenu) {
|
||||
__glutFatalError("out of memory.");
|
||||
}
|
||||
__glutCurrentMenu->submenus++;
|
||||
submenu->menu = __glutCurrentMenu;
|
||||
popupmenu = __glutGetMenuByNum(menu);
|
||||
if (popupmenu) {
|
||||
submenu->win = popupmenu->win;
|
||||
}
|
||||
setMenuItem(submenu, label, /* base 0 */ menu - 1, TRUE);
|
||||
__glutCurrentMenu->num++;
|
||||
submenu->next = __glutCurrentMenu->list;
|
||||
__glutCurrentMenu->list = submenu;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutChangeToMenuEntry(int num, const char *label, int value)
|
||||
{
|
||||
GLUTmenuItem *item;
|
||||
int i;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
i = __glutCurrentMenu->num;
|
||||
item = __glutCurrentMenu->list;
|
||||
while (item) {
|
||||
if (i == num) {
|
||||
if (item->isTrigger) {
|
||||
/* If changing a submenu trigger to a menu entry, we
|
||||
need to account for submenus. */
|
||||
item->menu->submenus--;
|
||||
/* Nuke the Win32 menu. */
|
||||
DestroyMenu(item->win);
|
||||
}
|
||||
free(item->label);
|
||||
|
||||
item->label = strdup(label);
|
||||
if (!item->label)
|
||||
__glutFatalError("out of memory");
|
||||
item->isTrigger = FALSE;
|
||||
item->len = (int) strlen(label);
|
||||
item->value = value;
|
||||
item->unique = uniqueMenuHandler++;
|
||||
ModifyMenu(__glutCurrentMenu->win, (UINT) i - 1,
|
||||
MF_BYPOSITION | MFT_STRING, item->unique, label);
|
||||
|
||||
return;
|
||||
}
|
||||
i--;
|
||||
item = item->next;
|
||||
}
|
||||
__glutWarning("Current menu has no %d item.", num);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutChangeToSubMenu(int num, const char *label, int menu)
|
||||
{
|
||||
GLUTmenu *popupmenu;
|
||||
GLUTmenuItem *item;
|
||||
int i;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
i = __glutCurrentMenu->num;
|
||||
item = __glutCurrentMenu->list;
|
||||
while (item) {
|
||||
if (i == num) {
|
||||
if (!item->isTrigger) {
|
||||
/* If changing a menu entry to as submenu trigger, we
|
||||
need to account for submenus. */
|
||||
item->menu->submenus++;
|
||||
item->win = CreatePopupMenu();
|
||||
}
|
||||
free(item->label);
|
||||
|
||||
item->label = strdup(label);
|
||||
if (!item->label)
|
||||
__glutFatalError("out of memory");
|
||||
item->isTrigger = TRUE;
|
||||
item->len = (int) strlen(label);
|
||||
item->value = menu - 1;
|
||||
item->unique = uniqueMenuHandler++;
|
||||
popupmenu = __glutGetMenuByNum(menu);
|
||||
if (popupmenu)
|
||||
item->win = popupmenu->win;
|
||||
ModifyMenu(__glutCurrentMenu->win, (UINT) i - 1,
|
||||
MF_BYPOSITION | MF_POPUP, (UINT) item->win, label);
|
||||
return;
|
||||
}
|
||||
i--;
|
||||
item = item->next;
|
||||
}
|
||||
__glutWarning("Current menu has no %d item.", num);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutRemoveMenuItem(int num)
|
||||
{
|
||||
GLUTmenuItem *item, **prev;
|
||||
int i;
|
||||
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
i = __glutCurrentMenu->num;
|
||||
prev = &__glutCurrentMenu->list;
|
||||
item = __glutCurrentMenu->list;
|
||||
while (item) {
|
||||
if (i == num) {
|
||||
/* Found the menu item in list to remove. */
|
||||
__glutCurrentMenu->num--;
|
||||
|
||||
/* Patch up menu's item list. */
|
||||
*prev = item->next;
|
||||
|
||||
RemoveMenu(__glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION);
|
||||
|
||||
free(item->label);
|
||||
free(item);
|
||||
return;
|
||||
}
|
||||
i--;
|
||||
prev = &item->next;
|
||||
item = item->next;
|
||||
}
|
||||
__glutWarning("Current menu has no %d item.", num);
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutAttachMenu(int button)
|
||||
{
|
||||
if (__glutCurrentWindow == __glutGameModeWindow) {
|
||||
__glutWarning("cannot attach menus in game mode.");
|
||||
return;
|
||||
}
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
if (__glutCurrentWindow->menu[button] < 1) {
|
||||
__glutCurrentWindow->buttonUses++;
|
||||
}
|
||||
__glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1;
|
||||
}
|
||||
|
||||
void APIENTRY
|
||||
glutDetachMenu(int button)
|
||||
{
|
||||
if (__glutMappedMenu) {
|
||||
menuModificationError();
|
||||
}
|
||||
if (__glutCurrentWindow->menu[button] > 0) {
|
||||
__glutCurrentWindow->buttonUses--;
|
||||
__glutCurrentWindow->menu[button] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
121
src/glut/glx/win32_util.c
Normal file
121
src/glut/glx/win32_util.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
|
||||
/* portions Copyright (c) Mark Kilgard, 1997, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
|
||||
#include "glutint.h"
|
||||
#include "glutstroke.h"
|
||||
#include "glutbitmap.h"
|
||||
#if defined(__CYGWIN32__)
|
||||
typedef MINMAXINFO* LPMINMAXINFO;
|
||||
#else
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
/* The following added by Paul Garceau <pgarceau@teleport.com> */
|
||||
#if defined(__MINGW32__)
|
||||
#include <time.h>
|
||||
#include <windows.h>
|
||||
struct timeval;
|
||||
#endif
|
||||
|
||||
extern StrokeFontRec glutStrokeRoman, glutStrokeMonoRoman;
|
||||
extern BitmapFontRec glutBitmap8By13, glutBitmap9By15, glutBitmapTimesRoman10, glutBitmapTimesRoman24, glutBitmapHelvetica10, glutBitmapHelvetica12, glutBitmapHelvetica18;
|
||||
|
||||
int
|
||||
gettimeofday(struct timeval* tp, void* tzp)
|
||||
{
|
||||
struct timeb tb;
|
||||
|
||||
ftime(&tb);
|
||||
tp->tv_sec = tb.time;
|
||||
tp->tv_usec = tb.millitm * 1000;
|
||||
|
||||
/* 0 indicates that the call succeeded. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* To get around the fact that Microsoft DLLs only allow functions
|
||||
to be exported and now data addresses (as Unix DSOs support), the
|
||||
GLUT API constants such as GLUT_STROKE_ROMAN have to get passed
|
||||
through a case statement to get mapped to the actual data structure
|
||||
address. */
|
||||
void*
|
||||
__glutFont(void *font)
|
||||
{
|
||||
switch((int)font) {
|
||||
case (int)GLUT_STROKE_ROMAN:
|
||||
return &glutStrokeRoman;
|
||||
case (int)GLUT_STROKE_MONO_ROMAN:
|
||||
return &glutStrokeMonoRoman;
|
||||
case (int)GLUT_BITMAP_9_BY_15:
|
||||
return &glutBitmap9By15;
|
||||
case (int)GLUT_BITMAP_8_BY_13:
|
||||
return &glutBitmap8By13;
|
||||
case (int)GLUT_BITMAP_TIMES_ROMAN_10:
|
||||
return &glutBitmapTimesRoman10;
|
||||
case (int)GLUT_BITMAP_TIMES_ROMAN_24:
|
||||
return &glutBitmapTimesRoman24;
|
||||
case (int)GLUT_BITMAP_HELVETICA_10:
|
||||
return &glutBitmapHelvetica10;
|
||||
case (int)GLUT_BITMAP_HELVETICA_12:
|
||||
return &glutBitmapHelvetica12;
|
||||
case (int)GLUT_BITMAP_HELVETICA_18:
|
||||
return &glutBitmapHelvetica18;
|
||||
}
|
||||
__glutFatalError("out of memory.");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo)
|
||||
{
|
||||
/* the transparent pixel on Win32 is always index number 0. So if
|
||||
we put this routine in this file, we can avoid compiling the
|
||||
whole of layerutil.c which is where this routine normally comes
|
||||
from. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
/* adjust the window rectangle because Win32 thinks that the x, y,
|
||||
width & height are the WHOLE window (including decorations),
|
||||
whereas GLUT treats the x, y, width & height as only the CLIENT
|
||||
area of the window. */
|
||||
rect.left = *x; rect.top = *y;
|
||||
rect.right = *x + *width; rect.bottom = *y + *height;
|
||||
|
||||
/* must adjust the coordinates according to the correct style
|
||||
because depending on the style, there may or may not be
|
||||
borders. */
|
||||
AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
|
||||
(parent ? WS_CHILD : WS_OVERLAPPEDWINDOW),
|
||||
FALSE);
|
||||
/* FALSE in the third parameter = window has no menu bar */
|
||||
|
||||
/* readjust if the x and y are offscreen */
|
||||
if(rect.left < 0) {
|
||||
*x = 0;
|
||||
} else {
|
||||
*x = rect.left;
|
||||
}
|
||||
|
||||
if(rect.top < 0) {
|
||||
*y = 0;
|
||||
} else {
|
||||
*y = rect.top;
|
||||
}
|
||||
|
||||
*width = rect.right - rect.left; /* adjusted width */
|
||||
*height = rect.bottom - rect.top; /* adjusted height */
|
||||
}
|
||||
|
||||
789
src/glut/glx/win32_winproc.c
Normal file
789
src/glut/glx/win32_winproc.c
Normal file
|
|
@ -0,0 +1,789 @@
|
|||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
/* portions Copyright (c) Mark Kilgard, 1997, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
|
||||
#include "glutint.h"
|
||||
#if defined(__CYGWIN32__)
|
||||
typedef MINMAXINFO* LPMINMAXINFO;
|
||||
#else
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <mmsystem.h> /* Win32 Multimedia API header. */
|
||||
#endif
|
||||
|
||||
extern unsigned __glutMenuButton;
|
||||
extern GLUTidleCB __glutIdleFunc;
|
||||
extern GLUTtimer *__glutTimerList;
|
||||
extern void handleTimeouts(void);
|
||||
extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique);
|
||||
static HMENU __glutHMenu;
|
||||
|
||||
void
|
||||
updateWindowState(GLUTwindow *window, int visState)
|
||||
{
|
||||
GLUTwindow* child;
|
||||
|
||||
/* XXX shownState and visState are the same in Win32. */
|
||||
window->shownState = visState;
|
||||
if (visState != window->visState) {
|
||||
if (window->windowStatus) {
|
||||
window->visState = visState;
|
||||
__glutSetWindow(window);
|
||||
window->windowStatus(visState);
|
||||
}
|
||||
}
|
||||
/* Since Win32 only sends an activate for the toplevel window,
|
||||
update the visibility for all the child windows. */
|
||||
child = window->children;
|
||||
while (child) {
|
||||
updateWindowState(child, visState);
|
||||
child = child->siblings;
|
||||
}
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
POINT point; /* Point structure. */
|
||||
PAINTSTRUCT ps; /* Paint structure. */
|
||||
LPMINMAXINFO minmax; /* Minimum/maximum info structure. */
|
||||
GLUTwindow* window; /* GLUT window associated with message. */
|
||||
GLUTmenu* menu; /* GLUT menu associated with message. */
|
||||
int x, y, width, height, key;
|
||||
int button = -1;
|
||||
|
||||
switch(msg) {
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
case WM_CLOSE:
|
||||
if (__glutExitFunc) {
|
||||
__glutExitFunc(0);
|
||||
}
|
||||
exit(0);
|
||||
break;
|
||||
#if 0
|
||||
case WM_DESTROY:
|
||||
/* XXX NVidia's NT OpenGL can have problems closing down
|
||||
its OpenGL internal data structures if we just allow
|
||||
the process to terminate without unbinding and deleting
|
||||
the windows context. Apparently, DirectDraw unloads
|
||||
before OPENGL32.DLL in the close down sequence, but
|
||||
NVidia's NT OpenGL needs DirectDraw to close down its
|
||||
data structures. */
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
if (window->ctx) {
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(window->ctx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
case WM_PAINT:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
BeginPaint(hwnd, &ps); /* Must have this for some Win32 reason. */
|
||||
EndPaint(hwnd, &ps);
|
||||
if (window->win == hwnd) {
|
||||
__glutPostRedisplay(window, GLUT_REPAIR_WORK);
|
||||
} else if (window->overlay && window->overlay->win == hwnd) {
|
||||
__glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (!window) {
|
||||
break;
|
||||
}
|
||||
/* Win32 is dumb and sends these messages only to the parent
|
||||
window. Therefore, find out if we're in a child window and
|
||||
call the child windows keyboard callback if we are. */
|
||||
if (window->parent) {
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
hwnd = ChildWindowFromPoint(hwnd, point);
|
||||
window = __glutGetWindow(hwnd);
|
||||
}
|
||||
if (window->specialUp || window->keyboardUp) {
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(window->win, &point);
|
||||
__glutSetWindow(window);
|
||||
__glutModifierMask = 0;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
|
||||
__glutModifierMask |= ShiftMask;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
|
||||
__glutModifierMask |= ControlMask;
|
||||
if (GetKeyState(VK_MENU) < 0)
|
||||
__glutModifierMask |= Mod1Mask;
|
||||
switch (wParam) {
|
||||
/* *INDENT-OFF* */
|
||||
case VK_F1: key = GLUT_KEY_F1; break;
|
||||
case VK_F2: key = GLUT_KEY_F2; break;
|
||||
case VK_F3: key = GLUT_KEY_F3; break;
|
||||
case VK_F4: key = GLUT_KEY_F4; break;
|
||||
case VK_F5: key = GLUT_KEY_F5; break;
|
||||
case VK_F6: key = GLUT_KEY_F6; break;
|
||||
case VK_F7: key = GLUT_KEY_F7; break;
|
||||
case VK_F8: key = GLUT_KEY_F8; break;
|
||||
case VK_F9: key = GLUT_KEY_F9; break;
|
||||
case VK_F10: key = GLUT_KEY_F10; break;
|
||||
case VK_F11: key = GLUT_KEY_F11; break;
|
||||
case VK_F12: key = GLUT_KEY_F12; break;
|
||||
case VK_LEFT: key = GLUT_KEY_LEFT; break;
|
||||
case VK_UP: key = GLUT_KEY_UP; break;
|
||||
case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
|
||||
case VK_DOWN: key = GLUT_KEY_DOWN; break;
|
||||
case VK_PRIOR: key = GLUT_KEY_PAGE_UP; break;
|
||||
case VK_NEXT: key = GLUT_KEY_PAGE_DOWN; break;
|
||||
case VK_HOME: key = GLUT_KEY_HOME; break;
|
||||
case VK_END: key = GLUT_KEY_END; break;
|
||||
case VK_INSERT: key = GLUT_KEY_INSERT; break;
|
||||
case VK_DELETE:
|
||||
/* Delete is an ASCII character. */
|
||||
if (window->keyboardUp) {
|
||||
window->keyboardUp((unsigned char) 127, point.x, point.y);
|
||||
}
|
||||
return 0;
|
||||
/* *INDENT-ON* */
|
||||
default:
|
||||
if (window->keyboardUp) {
|
||||
key = MapVirtualKey(wParam, 2); /* Map to ASCII. */
|
||||
if (isascii(key) && (key != 0)) {
|
||||
|
||||
/* XXX Attempt to determine modified ASCII character
|
||||
is quite incomplete. Digits, symbols, CapsLock,
|
||||
Ctrl, and numeric keypad are all ignored. Fix this. */
|
||||
|
||||
if (!(__glutModifierMask & ShiftMask))
|
||||
key = tolower(key);
|
||||
window->keyboardUp((unsigned char) key, point.x, point.y);
|
||||
}
|
||||
}
|
||||
__glutModifierMask = (unsigned int) ~0;
|
||||
return 0;
|
||||
}
|
||||
if (window->specialUp) {
|
||||
window->specialUp(key, point.x, point.y);
|
||||
}
|
||||
__glutModifierMask = (unsigned int) ~0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_SYSCHAR:
|
||||
case WM_CHAR:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (!window) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Bit 30 of lParam is set if key already held down. If
|
||||
we are ignoring auto repeated key strokes for the window, bail. */
|
||||
if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Win32 is dumb and sends these messages only to the parent
|
||||
window. Therefore, find out if we're in a child window and
|
||||
call the child windows keyboard callback if we are. */
|
||||
if (window->parent) {
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
hwnd = ChildWindowFromPoint(hwnd, point);
|
||||
window = __glutGetWindow(hwnd);
|
||||
}
|
||||
if (window->keyboard) {
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(window->win, &point);
|
||||
__glutSetWindow(window);
|
||||
__glutModifierMask = 0;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
|
||||
__glutModifierMask |= ShiftMask;
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
__glutModifierMask |= ControlMask;
|
||||
if (GetKeyState(VK_MENU) < 0)
|
||||
__glutModifierMask |= Mod1Mask;
|
||||
window->keyboard((unsigned char)wParam, point.x, point.y);
|
||||
__glutModifierMask = (unsigned int) ~0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (!window) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Bit 30 of lParam is set if key already held down. If
|
||||
we are ignoring auto repeated key strokes for the window, bail. */
|
||||
if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Win32 is dumb and sends these messages only to the parent
|
||||
window. Therefore, find out if we're in a child window and
|
||||
call the child windows keyboard callback if we are. */
|
||||
if (window->parent) {
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
hwnd = ChildWindowFromPoint(hwnd, point);
|
||||
window = __glutGetWindow(hwnd);
|
||||
}
|
||||
if (window->special) {
|
||||
switch (wParam) {
|
||||
/* *INDENT-OFF* */
|
||||
/* function keys */
|
||||
case VK_F1: key = GLUT_KEY_F1; break;
|
||||
case VK_F2: key = GLUT_KEY_F2; break;
|
||||
case VK_F3: key = GLUT_KEY_F3; break;
|
||||
case VK_F4: key = GLUT_KEY_F4; break;
|
||||
case VK_F5: key = GLUT_KEY_F5; break;
|
||||
case VK_F6: key = GLUT_KEY_F6; break;
|
||||
case VK_F7: key = GLUT_KEY_F7; break;
|
||||
case VK_F8: key = GLUT_KEY_F8; break;
|
||||
case VK_F9: key = GLUT_KEY_F9; break;
|
||||
case VK_F10: key = GLUT_KEY_F10; break;
|
||||
case VK_F11: key = GLUT_KEY_F11; break;
|
||||
case VK_F12: key = GLUT_KEY_F12; break;
|
||||
/* directional keys */
|
||||
case VK_LEFT: key = GLUT_KEY_LEFT; break;
|
||||
case VK_UP: key = GLUT_KEY_UP; break;
|
||||
case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
|
||||
case VK_DOWN: key = GLUT_KEY_DOWN; break;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
case VK_PRIOR:
|
||||
/* VK_PRIOR is Win32's Page Up */
|
||||
key = GLUT_KEY_PAGE_UP;
|
||||
break;
|
||||
case VK_NEXT:
|
||||
/* VK_NEXT is Win32's Page Down */
|
||||
key = GLUT_KEY_PAGE_DOWN;
|
||||
break;
|
||||
case VK_HOME:
|
||||
key = GLUT_KEY_HOME;
|
||||
break;
|
||||
case VK_END:
|
||||
key = GLUT_KEY_END;
|
||||
break;
|
||||
case VK_INSERT:
|
||||
key = GLUT_KEY_INSERT;
|
||||
break;
|
||||
case VK_DELETE:
|
||||
goto handleDelete;
|
||||
default:
|
||||
goto defproc;
|
||||
}
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(window->win, &point);
|
||||
__glutSetWindow(window);
|
||||
__glutModifierMask = 0;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
|
||||
__glutModifierMask |= ShiftMask;
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
__glutModifierMask |= ControlMask;
|
||||
if (GetKeyState(VK_MENU) < 0)
|
||||
__glutModifierMask |= Mod1Mask;
|
||||
window->special(key, point.x, point.y);
|
||||
__glutModifierMask = (unsigned int) ~0;
|
||||
} else if (window->keyboard) {
|
||||
/* Specially handle any keys that match ASCII values but
|
||||
do not generate Windows WM_SYSCHAR or WM_CHAR messages. */
|
||||
switch (wParam) {
|
||||
case VK_DELETE:
|
||||
handleDelete:
|
||||
/* Delete is an ASCII character. */
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(window->win, &point);
|
||||
__glutSetWindow(window);
|
||||
__glutModifierMask = 0;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
|
||||
__glutModifierMask |= ShiftMask;
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
__glutModifierMask |= ControlMask;
|
||||
if (GetKeyState(VK_MENU) < 0)
|
||||
__glutModifierMask |= Mod1Mask;
|
||||
window->keyboard((unsigned char) 127, point.x, point.y);
|
||||
__glutModifierMask = (unsigned int) ~0;
|
||||
return 0;
|
||||
default:
|
||||
/* Let the following WM_SYSCHAR or WM_CHAR message generate
|
||||
the keyboard callback. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
button = GLUT_LEFT_BUTTON;
|
||||
case WM_MBUTTONDOWN:
|
||||
if (button < 0)
|
||||
button = GLUT_MIDDLE_BUTTON;
|
||||
case WM_RBUTTONDOWN:
|
||||
if (button < 0)
|
||||
button = GLUT_RIGHT_BUTTON;
|
||||
|
||||
/* finish the menu if we get a button down message (user must have
|
||||
cancelled the menu). */
|
||||
if (__glutMappedMenu) {
|
||||
/* TODO: take this out once the menu on middle mouse stuff works
|
||||
properly. */
|
||||
if (button == GLUT_MIDDLE_BUTTON)
|
||||
return 0;
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
__glutItemSelected = NULL;
|
||||
__glutFinishMenu(hwnd, point.x, point.y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set the capture so we can get mouse events outside the window */
|
||||
SetCapture(hwnd);
|
||||
|
||||
/* Win32 doesn't return the same numbers as X does when the mouse
|
||||
goes beyond the upper or left side of the window. roll the
|
||||
Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
|
||||
x = LOWORD(lParam);
|
||||
y = HIWORD(lParam);
|
||||
if(x & 1 << 15) x -= (1 << 16);
|
||||
if(y & 1 << 15) y -= (1 << 16);
|
||||
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
menu = __glutGetMenuByNum(window->menu[button]);
|
||||
if (menu) {
|
||||
point.x = LOWORD(lParam); point.y = HIWORD(lParam);
|
||||
ClientToScreen(window->win, &point);
|
||||
__glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
|
||||
button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
|
||||
0x0001;
|
||||
__glutStartMenu(menu, window, point.x, point.y, x, y);
|
||||
} else if (window->mouse) {
|
||||
|
||||
__glutSetWindow(window);
|
||||
__glutModifierMask = 0;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on. */
|
||||
__glutModifierMask |= ShiftMask;
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
__glutModifierMask |= ControlMask;
|
||||
if (GetKeyState(VK_MENU) < 0)
|
||||
__glutModifierMask |= Mod1Mask;
|
||||
window->mouse(button, GLUT_DOWN, x, y);
|
||||
__glutModifierMask = (unsigned int)~0;
|
||||
} else {
|
||||
/* Stray mouse events. Ignore. */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
button = GLUT_LEFT_BUTTON;
|
||||
case WM_MBUTTONUP:
|
||||
if (button < 0)
|
||||
button = GLUT_MIDDLE_BUTTON;
|
||||
case WM_RBUTTONUP:
|
||||
if (button < 0)
|
||||
button = GLUT_RIGHT_BUTTON;
|
||||
|
||||
/* Bail out if we're processing a menu. */
|
||||
if (__glutMappedMenu) {
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
/* if we're getting the middle button up signal, then something
|
||||
on the menu was selected. */
|
||||
if (button == GLUT_MIDDLE_BUTTON) {
|
||||
return 0;
|
||||
/* For some reason, the code below always returns -1 even
|
||||
though the point IS IN THE ITEM! Therefore, just bail out if
|
||||
we get a middle mouse up. The user must select using the
|
||||
left mouse button. Stupid Win32. */
|
||||
#if 0
|
||||
int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
|
||||
if (item != -1)
|
||||
__glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
|
||||
else
|
||||
__glutItemSelected = NULL;
|
||||
__glutFinishMenu(hwnd, point.x, point.y);
|
||||
#endif
|
||||
} else {
|
||||
__glutItemSelected = NULL;
|
||||
__glutFinishMenu(hwnd, point.x, point.y);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Release the mouse capture. */
|
||||
ReleaseCapture();
|
||||
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window && window->mouse) {
|
||||
/* Win32 doesn't return the same numbers as X does when the
|
||||
mouse goes beyond the upper or left side of the window. roll
|
||||
the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
|
||||
x = LOWORD(lParam);
|
||||
y = HIWORD(lParam);
|
||||
if(x & 1 << 15) x -= (1 << 16);
|
||||
if(y & 1 << 15) y -= (1 << 16);
|
||||
|
||||
__glutSetWindow(window);
|
||||
__glutModifierMask = 0;
|
||||
if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
|
||||
__glutModifierMask |= ShiftMask;
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
__glutModifierMask |= ControlMask;
|
||||
if (GetKeyState(VK_MENU) < 0)
|
||||
__glutModifierMask |= Mod1Mask;
|
||||
window->mouse(button, GLUT_UP, x, y);
|
||||
__glutModifierMask = (unsigned int)~0;
|
||||
} else {
|
||||
/* Window might have been destroyed and all the
|
||||
events for the window may not yet be received. */
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_ENTERMENULOOP:
|
||||
/* KLUDGE: create a timer that fires every 100 ms when we start a
|
||||
menu so that we can still process the idle & timer events (that
|
||||
way, the timers will fire during a menu pick and so will the
|
||||
idle func. */
|
||||
SetTimer(hwnd, 1, 1, NULL);
|
||||
return 0;
|
||||
|
||||
case WM_TIMER:
|
||||
#if 0
|
||||
/* If the timer id is 2, then this is the timer that is set up in
|
||||
the main glut message processing loop, and we don't want to do
|
||||
anything but acknowledge that we got it. It is used to prevent
|
||||
CPU spiking when an idle function is installed. */
|
||||
if (wParam == 2)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* only worry about the idle function and the timeouts, since
|
||||
these are the only events we expect to process during
|
||||
processing of a menu. */
|
||||
/* we no longer process the idle functions (as outlined in the
|
||||
README), since drawing can't be done until the menu has
|
||||
finished...it's pretty lame when the animation goes on, but
|
||||
doesn't update, so you get this weird jerkiness. */
|
||||
#if 0
|
||||
if (__glutIdleFunc)
|
||||
__glutIdleFunc();
|
||||
#endif
|
||||
if (__glutTimerList)
|
||||
handleTimeouts();
|
||||
return 0;
|
||||
|
||||
case WM_EXITMENULOOP:
|
||||
/* nuke the above created timer...we don't need it anymore, since
|
||||
the menu is gone now. */
|
||||
KillTimer(hwnd, 1);
|
||||
return 0;
|
||||
|
||||
case WM_MENUSELECT:
|
||||
if (lParam != 0)
|
||||
__glutHMenu = (HMENU)lParam;
|
||||
return 0;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (__glutMappedMenu) {
|
||||
if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
|
||||
__glutItemSelected = NULL;
|
||||
else
|
||||
__glutItemSelected =
|
||||
__glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(hwnd, &point);
|
||||
__glutFinishMenu(hwnd, point.x, point.y);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (!__glutMappedMenu) {
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
/* If motion function registered _and_ buttons held *
|
||||
down, call motion function... */
|
||||
x = LOWORD(lParam);
|
||||
y = HIWORD(lParam);
|
||||
|
||||
/* Win32 doesn't return the same numbers as X does when the
|
||||
mouse goes beyond the upper or left side of the window.
|
||||
roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
|
||||
if(x & 1 << 15) x -= (1 << 16);
|
||||
if(y & 1 << 15) y -= (1 << 16);
|
||||
|
||||
if (window->motion && wParam &
|
||||
(MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
|
||||
__glutSetWindow(window);
|
||||
window->motion(x, y);
|
||||
}
|
||||
/* If passive motion function registered _and_
|
||||
buttons not held down, call passive motion
|
||||
function... */
|
||||
else if (window->passive &&
|
||||
((wParam &
|
||||
(MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
|
||||
0)) {
|
||||
__glutSetWindow(window);
|
||||
window->passive(x, y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Motion events are thrown away when a pop up menu is
|
||||
active. */
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_GETMINMAXINFO:
|
||||
/* this voodoo is brought to you by Win32 (again). It allows the
|
||||
window to be bigger than the screen, and smaller than 100x100
|
||||
(although it doesn't seem to help the y minimum). */
|
||||
minmax = (LPMINMAXINFO)lParam;
|
||||
minmax->ptMaxSize.x = __glutScreenWidth;
|
||||
minmax->ptMaxSize.y = __glutScreenHeight;
|
||||
minmax->ptMinTrackSize.x = 0;
|
||||
minmax->ptMinTrackSize.y = 0;
|
||||
minmax->ptMaxTrackSize.x = __glutScreenWidth +
|
||||
GetSystemMetrics(SM_CXSIZE) * 2;
|
||||
minmax->ptMaxTrackSize.y = __glutScreenHeight +
|
||||
GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
|
||||
return 0;
|
||||
|
||||
case WM_SIZE:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
width = LOWORD(lParam);
|
||||
height = HIWORD(lParam);
|
||||
if (width != window->width || height != window->height) {
|
||||
#if 0 /* Win32 GLUT does not support overlays for now. */
|
||||
if (window->overlay) {
|
||||
XResizeWindow(__glutDisplay, window->overlay->win, width, height);
|
||||
}
|
||||
#endif
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
__glutSetWindow(window);
|
||||
/* Do not execute OpenGL out of sequence with respect
|
||||
to the SetWindowPos request! */
|
||||
GdiFlush();
|
||||
window->reshape(width, height);
|
||||
window->forceReshape = FALSE;
|
||||
/* A reshape should be considered like posting a
|
||||
repair request. */
|
||||
__glutPostRedisplay(window, GLUT_REPAIR_WORK);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
/* If the cursor is not in the client area, then we want to send
|
||||
this message to the default window procedure ('cause its
|
||||
probably in the border or title, and we don't handle that
|
||||
cursor. otherwise, set our cursor. Win32 makes us set the
|
||||
cursor every time the mouse moves (DUMB!). */
|
||||
if(LOWORD(lParam) != HTCLIENT) {
|
||||
goto defproc;
|
||||
}
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
__glutSetCursor(window);
|
||||
}
|
||||
/* TODO: check out the info in DevStudio on WM_SETCURSOR in the
|
||||
DefaultAction section. */
|
||||
return 1;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
window->entryState = WM_SETFOCUS;
|
||||
if (window->entry) {
|
||||
__glutSetWindow(window);
|
||||
window->entry(GLUT_ENTERED);
|
||||
/* XXX Generation of fake passive notify? See how much
|
||||
work the X11 code does to support fake passive notify
|
||||
callbacks. */
|
||||
}
|
||||
if (window->joystick && __glutCurrentWindow) {
|
||||
if (__glutCurrentWindow->joyPollInterval > 0) {
|
||||
MMRESULT result;
|
||||
|
||||
/* Because Win32 will only let one window capture the
|
||||
joystick at a time, we must capture it when we get the
|
||||
focus and release it when we lose the focus. */
|
||||
result = joySetCapture(__glutCurrentWindow->win,
|
||||
JOYSTICKID1, 0, TRUE);
|
||||
if (result != JOYERR_NOERROR) {
|
||||
return 0;
|
||||
}
|
||||
(void) joySetThreshold(JOYSTICKID1,
|
||||
__glutCurrentWindow->joyPollInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window) {
|
||||
window->entryState = WM_KILLFOCUS;
|
||||
if (window->entry) {
|
||||
__glutSetWindow(window);
|
||||
window->entry(GLUT_LEFT);
|
||||
}
|
||||
if (window->joystick && __glutCurrentWindow) {
|
||||
if (__glutCurrentWindow->joyPollInterval > 0) {
|
||||
/* Because Win32 will only let one window capture the
|
||||
joystick at a time, we must capture it when we get the
|
||||
focus and release it when we lose the focus. */
|
||||
(void) joyReleaseCapture(JOYSTICKID1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case WM_ACTIVATE:
|
||||
window = __glutGetWindow(hwnd);
|
||||
/* Make sure we re-select the correct palette if needed. */
|
||||
if (LOWORD(wParam)) {
|
||||
PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
|
||||
}
|
||||
if (window) {
|
||||
int visState;
|
||||
|
||||
/* HIWORD(wParam) is the minimized flag. */
|
||||
visState = !HIWORD(wParam);
|
||||
updateWindowState(window, visState);
|
||||
}
|
||||
return 0;
|
||||
|
||||
/* Colour Palette Management */
|
||||
case WM_PALETTECHANGED:
|
||||
if (hwnd == (HWND)wParam) {
|
||||
/* Don't respond to the message that we sent! */
|
||||
break;
|
||||
}
|
||||
/* fall through to WM_QUERYNEWPALETTE */
|
||||
|
||||
case WM_QUERYNEWPALETTE:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window && window->colormap) {
|
||||
UnrealizeObject(window->colormap->cmap);
|
||||
SelectPalette(window->hdc, window->colormap->cmap, FALSE);
|
||||
RealizePalette(window->hdc);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case MM_JOY1MOVE:
|
||||
case MM_JOY1ZMOVE:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window->joystick) {
|
||||
JOYINFOEX jix;
|
||||
int x, y, z;
|
||||
|
||||
/* Because WIN32 only supports messages for X, Y, and Z
|
||||
translations, we must poll for the rest */
|
||||
jix.dwSize = sizeof(jix);
|
||||
jix.dwFlags = JOY_RETURNALL;
|
||||
joyGetPosEx(JOYSTICKID1,&jix);
|
||||
|
||||
#define SCALE(v) ((int) ((v - 32767)/32.768))
|
||||
|
||||
/* Convert to integer for scaling. */
|
||||
x = jix.dwXpos;
|
||||
y = jix.dwYpos;
|
||||
z = jix.dwZpos;
|
||||
window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case MM_JOY1BUTTONDOWN:
|
||||
case MM_JOY1BUTTONUP:
|
||||
window = __glutGetWindow(hwnd);
|
||||
if (window->joystick) {
|
||||
JOYINFOEX jix;
|
||||
|
||||
/* Because WIN32 only supports messages for X, Y, and Z
|
||||
translations, we must poll for the rest */
|
||||
jix.dwSize = sizeof(jix);
|
||||
jix.dwFlags = JOY_RETURNALL;
|
||||
joyGetPosEx(JOYSTICKID1,&jix);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
#if 0
|
||||
/* Miscellaneous messages (don't really need to enumerate them,
|
||||
but it's good to know what you're not getting sometimes). */
|
||||
case WM_DISPLAYCHANGE:
|
||||
break;
|
||||
case WM_NCHITTEST:
|
||||
/* This event is generated by every mouse move event. */
|
||||
goto defproc;
|
||||
case WM_NCMOUSEMOVE:
|
||||
goto defproc;
|
||||
case WM_NCACTIVATE:
|
||||
goto defproc;
|
||||
case WM_NCPAINT:
|
||||
goto defproc;
|
||||
case WM_NCCALCSIZE:
|
||||
goto defproc;
|
||||
case WM_NCCREATE:
|
||||
goto defproc;
|
||||
case WM_NCDESTROY:
|
||||
goto defproc;
|
||||
case WM_NCLBUTTONDOWN:
|
||||
goto defproc;
|
||||
case WM_SETTEXT:
|
||||
goto defproc;
|
||||
case WM_GETTEXT:
|
||||
goto defproc;
|
||||
case WM_ACTIVATEAPP:
|
||||
goto defproc;
|
||||
case WM_GETICON:
|
||||
goto defproc;
|
||||
case WM_ERASEBKGND:
|
||||
goto defproc;
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
goto defproc;
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
goto defproc;
|
||||
case WM_MOUSEACTIVATE:
|
||||
goto defproc;
|
||||
case WM_SHOWWINDOW:
|
||||
goto defproc;
|
||||
case WM_MOVING:
|
||||
goto defproc;
|
||||
case WM_MOVE:
|
||||
goto defproc;
|
||||
case WM_KEYUP:
|
||||
goto defproc;
|
||||
case WM_CAPTURECHANGED:
|
||||
goto defproc;
|
||||
case WM_SYSCOMMAND:
|
||||
goto defproc;
|
||||
case WM_ENTERSIZEMOVE:
|
||||
goto defproc;
|
||||
case WM_ENTERIDLE:
|
||||
goto defproc;
|
||||
#endif
|
||||
|
||||
default:
|
||||
goto defproc;
|
||||
}
|
||||
|
||||
defproc:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
400
src/glut/glx/win32_x11.c
Normal file
400
src/glut/glx/win32_x11.c
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
/* portions Copyright (c) Mark Kilgard, 1998. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include "glutint.h"
|
||||
|
||||
/* global variable that must be set for some functions to operate
|
||||
correctly. */
|
||||
HDC XHDC;
|
||||
|
||||
XVisualInfo*
|
||||
XGetVisualInfo(Display* display, long mask, XVisualInfo* template, int* nitems)
|
||||
{
|
||||
/* KLUDGE: this function needs XHDC to be set to the HDC currently
|
||||
being operated on before it is invoked! */
|
||||
|
||||
PIXELFORMATDESCRIPTOR* pfds;
|
||||
int i, n;
|
||||
|
||||
n = DescribePixelFormat(XHDC, 0, 0, NULL);
|
||||
pfds = (PIXELFORMATDESCRIPTOR*)malloc(sizeof(PIXELFORMATDESCRIPTOR) * n);
|
||||
memset(pfds, 0, sizeof(PIXELFORMATDESCRIPTOR) * n);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
DescribePixelFormat(XHDC, i + 1, sizeof(PIXELFORMATDESCRIPTOR), &pfds[i]);
|
||||
}
|
||||
|
||||
*nitems = n;
|
||||
return pfds;
|
||||
}
|
||||
|
||||
Colormap
|
||||
XCreateColormap(Display* display, Window root, Visual* visual, int alloc)
|
||||
{
|
||||
/* KLUDGE: this function needs XHDC to be set to the HDC currently
|
||||
being operated on before it is invoked! */
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
LOGPALETTE *logical;
|
||||
HPALETTE palette;
|
||||
int n;
|
||||
|
||||
/* grab the pixel format */
|
||||
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
DescribePixelFormat(XHDC, GetPixelFormat(XHDC),
|
||||
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
if (!(pfd.dwFlags & PFD_NEED_PALETTE ||
|
||||
pfd.iPixelType == PFD_TYPE_COLORINDEX))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = 1 << pfd.cColorBits;
|
||||
|
||||
/* allocate a bunch of memory for the logical palette (assume 256
|
||||
colors in a Win32 palette */
|
||||
logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
|
||||
sizeof(PALETTEENTRY) * n);
|
||||
memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
|
||||
|
||||
/* set the entries in the logical palette */
|
||||
logical->palVersion = 0x300;
|
||||
logical->palNumEntries = n;
|
||||
|
||||
/* start with a copy of the current system palette */
|
||||
GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]);
|
||||
|
||||
if (pfd.iPixelType == PFD_TYPE_RGBA) {
|
||||
int redMask = (1 << pfd.cRedBits) - 1;
|
||||
int greenMask = (1 << pfd.cGreenBits) - 1;
|
||||
int blueMask = (1 << pfd.cBlueBits) - 1;
|
||||
int i;
|
||||
|
||||
/* fill in an RGBA color palette */
|
||||
for (i = 0; i < n; ++i) {
|
||||
logical->palPalEntry[i].peRed =
|
||||
(((i >> pfd.cRedShift) & redMask) * 255) / redMask;
|
||||
logical->palPalEntry[i].peGreen =
|
||||
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
|
||||
logical->palPalEntry[i].peBlue =
|
||||
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
|
||||
logical->palPalEntry[i].peFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
palette = CreatePalette(logical);
|
||||
free(logical);
|
||||
|
||||
SelectPalette(XHDC, palette, FALSE);
|
||||
RealizePalette(XHDC);
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
void
|
||||
XAllocColorCells(Display* display, Colormap colormap, Bool contig,
|
||||
unsigned long plane_masks_return[], unsigned int nplanes,
|
||||
unsigned long pixels_return[], unsigned int npixels)
|
||||
{
|
||||
/* NOP -- we did all the allocating in XCreateColormap! */
|
||||
}
|
||||
|
||||
void
|
||||
XStoreColor(Display* display, Colormap colormap, XColor* color)
|
||||
{
|
||||
/* KLUDGE: set XHDC to 0 if the palette should NOT be realized after
|
||||
setting the color. set XHDC to the correct HDC if it should. */
|
||||
|
||||
PALETTEENTRY pe;
|
||||
|
||||
/* X11 stores color from 0-65535, Win32 expects them to be 0-256, so
|
||||
twiddle the bits ( / 256). */
|
||||
pe.peRed = color->red / 256;
|
||||
pe.peGreen = color->green / 256;
|
||||
pe.peBlue = color->blue / 256;
|
||||
|
||||
/* make sure we use this flag, otherwise the colors might get mapped
|
||||
to another place in the colormap, and when we glIndex() that
|
||||
color, it may have moved (argh!!) */
|
||||
pe.peFlags = PC_NOCOLLAPSE;
|
||||
|
||||
/* the pixel field of the XColor structure is the index into the
|
||||
colormap */
|
||||
SetPaletteEntries(colormap, color->pixel, 1, &pe);
|
||||
|
||||
if (XHDC) {
|
||||
UnrealizeObject(colormap);
|
||||
SelectPalette(XHDC, colormap, FALSE);
|
||||
RealizePalette(XHDC);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XSetWindowColormap(Display* display, Window window, Colormap colormap)
|
||||
{
|
||||
HDC hdc = GetDC(window);
|
||||
|
||||
/* if the third parameter is FALSE, the logical colormap is copied
|
||||
into the device palette when the application is in the
|
||||
foreground, if it is TRUE, the colors are mapped into the current
|
||||
palette in the best possible way. */
|
||||
SelectPalette(hdc, colormap, FALSE);
|
||||
RealizePalette(hdc);
|
||||
|
||||
/* note that we don't have to release the DC, since our window class
|
||||
uses the WC_OWNDC flag! */
|
||||
}
|
||||
|
||||
Bool
|
||||
XTranslateCoordinates(Display *display, Window src, Window dst,
|
||||
int src_x, int src_y,
|
||||
int* dest_x_return, int* dest_y_return,
|
||||
Window* child_return)
|
||||
{
|
||||
/* KLUDGE: this isn't really a translate coordinates into some other
|
||||
windows coordinate system...it only translates coordinates into the
|
||||
root window (screen) coordinate system. */
|
||||
|
||||
POINT point;
|
||||
|
||||
point.x = src_x;
|
||||
point.y = src_y;
|
||||
|
||||
ClientToScreen(src, &point);
|
||||
|
||||
*dest_x_return = point.x;
|
||||
*dest_y_return = point.y;
|
||||
|
||||
/* just to make compilers happy...we don't use the return value. */
|
||||
return True;
|
||||
}
|
||||
|
||||
Status
|
||||
XGetGeometry(Display* display, Window window, Window* root_return,
|
||||
int* x_return, int* y_return,
|
||||
unsigned int* width_return, unsigned int* height_return,
|
||||
unsigned int *border_width_return, unsigned int* depth_return)
|
||||
{
|
||||
/* KLUDGE: doesn't return the border_width or depth or root, x & y
|
||||
are in screen coordinates. */
|
||||
|
||||
RECT rect;
|
||||
POINT point;
|
||||
|
||||
GetClientRect(window, &rect);
|
||||
|
||||
point.x = 0;
|
||||
point.y = 0;
|
||||
ClientToScreen(window, &point);
|
||||
|
||||
*x_return = point.x;
|
||||
*y_return = point.y;
|
||||
*width_return = rect.right;
|
||||
*height_return = rect.bottom;
|
||||
|
||||
/* just to make compilers happy...we don't use the return value. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
DisplayWidthMM(Display* display, int screen)
|
||||
{
|
||||
int width;
|
||||
HWND hwnd = GetDesktopWindow();
|
||||
HDC hdc = GetDC(hwnd);
|
||||
|
||||
width = GetDeviceCaps(hdc, HORZSIZE);
|
||||
|
||||
/* make sure to release this DC (it's the desktops, not ours) */
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
int
|
||||
DisplayHeightMM(Display* display, int screen)
|
||||
{
|
||||
int height;
|
||||
HWND hwnd = GetDesktopWindow();
|
||||
HDC hdc = GetDC(hwnd);
|
||||
|
||||
height = GetDeviceCaps(hdc, VERTSIZE);
|
||||
|
||||
/* make sure to release this DC (it's the desktops, not ours) */
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void
|
||||
XWarpPointer(Display* display, Window src, Window dst,
|
||||
int src_x, int src_y, int src_width, int src_height,
|
||||
int dst_x, int dst_y)
|
||||
{
|
||||
/* KLUDGE: this isn't really a warp pointer into some other windows
|
||||
coordinate system...it only warps the pointer into the root window
|
||||
(screen) coordinate system. */
|
||||
|
||||
POINT point;
|
||||
|
||||
point.x = dst_x;
|
||||
point.y = dst_y;
|
||||
ClientToScreen(dst, &point);
|
||||
|
||||
SetCursorPos(point.x, point.y);
|
||||
}
|
||||
|
||||
int
|
||||
XPending(Display* display)
|
||||
{
|
||||
/* similar functionality...I don't think that it is exact, but this
|
||||
will have to do. */
|
||||
MSG msg;
|
||||
|
||||
return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
|
||||
}
|
||||
|
||||
/* the following function was stolen from the X sources as indicated. */
|
||||
|
||||
/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */
|
||||
/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
|
||||
|
||||
/*
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the name of M.I.T. not be used in advertising or
|
||||
publicity pertaining to distribution of the software without specific,
|
||||
written prior permission. M.I.T. makes no representations about the
|
||||
suitability of this software for any purpose. It is provided "as is"
|
||||
without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XParseGeometry parses strings of the form
|
||||
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
|
||||
* width, height, xoffset, and yoffset are unsigned integers.
|
||||
* Example: "=80x24+300-49"
|
||||
* The equal sign is optional.
|
||||
* It returns a bitmask that indicates which of the four values
|
||||
* were actually found in the string. For each value found,
|
||||
* the corresponding argument is updated; for each value
|
||||
* not found, the corresponding argument is left unchanged.
|
||||
*/
|
||||
|
||||
static int
|
||||
ReadInteger(char *string, char **NextString)
|
||||
{
|
||||
register int Result = 0;
|
||||
int Sign = 1;
|
||||
|
||||
if (*string == '+')
|
||||
string++;
|
||||
else if (*string == '-')
|
||||
{
|
||||
string++;
|
||||
Sign = -1;
|
||||
}
|
||||
for (; (*string >= '0') && (*string <= '9'); string++)
|
||||
{
|
||||
Result = (Result * 10) + (*string - '0');
|
||||
}
|
||||
*NextString = string;
|
||||
if (Sign >= 0)
|
||||
return (Result);
|
||||
else
|
||||
return (-Result);
|
||||
}
|
||||
|
||||
int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height)
|
||||
{
|
||||
int mask = NoValue;
|
||||
register char *strind;
|
||||
unsigned int tempWidth, tempHeight;
|
||||
int tempX, tempY;
|
||||
char *nextCharacter;
|
||||
|
||||
if ( (string == NULL) || (*string == '\0')) return(mask);
|
||||
if (*string == '=')
|
||||
string++; /* ignore possible '=' at beg of geometry spec */
|
||||
|
||||
strind = (char *)string;
|
||||
if (*strind != '+' && *strind != '-' && *strind != 'x') {
|
||||
tempWidth = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= WidthValue;
|
||||
}
|
||||
|
||||
if (*strind == 'x' || *strind == 'X') {
|
||||
strind++;
|
||||
tempHeight = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= HeightValue;
|
||||
}
|
||||
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempX = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return (0);
|
||||
strind = nextCharacter;
|
||||
mask |= XNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{ strind++;
|
||||
tempX = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= XValue;
|
||||
if ((*strind == '+') || (*strind == '-')) {
|
||||
if (*strind == '-') {
|
||||
strind++;
|
||||
tempY = -ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
mask |= YNegative;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
strind++;
|
||||
tempY = ReadInteger(strind, &nextCharacter);
|
||||
if (strind == nextCharacter)
|
||||
return(0);
|
||||
strind = nextCharacter;
|
||||
}
|
||||
mask |= YValue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If strind isn't at the end of the string the it's an invalid
|
||||
geometry specification. */
|
||||
|
||||
if (*strind != '\0') return (0);
|
||||
|
||||
if (mask & XValue)
|
||||
*x = tempX;
|
||||
if (mask & YValue)
|
||||
*y = tempY;
|
||||
if (mask & WidthValue)
|
||||
*width = tempWidth;
|
||||
if (mask & HeightValue)
|
||||
*height = tempHeight;
|
||||
return (mask);
|
||||
}
|
||||
319
src/glut/glx/win32_x11.h
Normal file
319
src/glut/glx/win32_x11.h
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
#ifndef __win32_x11_h__
|
||||
#define __win32_x11_h__
|
||||
|
||||
/* Copyright (c) Nate Robins, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees
|
||||
and is provided without guarantee or warrantee expressed or
|
||||
implied. This program is -not- in the public domain. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* Type definitions (conversions) */
|
||||
typedef int Visual; /* Win32 equivalent of X11 type */
|
||||
typedef HWND Window;
|
||||
typedef HPALETTE Colormap;
|
||||
typedef PIXELFORMATDESCRIPTOR XVisualInfo;
|
||||
typedef BOOL Bool;
|
||||
typedef MSG XEvent;
|
||||
typedef HDC Display;
|
||||
typedef HCURSOR Cursor;
|
||||
|
||||
typedef int Atom; /* dummies */
|
||||
typedef int XDevice;
|
||||
typedef int Status;
|
||||
|
||||
#define True TRUE /* Win32 equivalents of X11 booleans */
|
||||
#define False FALSE
|
||||
|
||||
#define None 0L /* universal null resource or null atom */
|
||||
|
||||
/* Input Event Masks. Used as event-mask window attribute and as arguments
|
||||
to Grab requests. Not to be confused with event names. */
|
||||
|
||||
#define NoEventMask 0L
|
||||
#define KeyPressMask (1L<<0)
|
||||
#define KeyReleaseMask (1L<<1)
|
||||
#define ButtonPressMask (1L<<2)
|
||||
#define ButtonReleaseMask (1L<<3)
|
||||
#define EnterWindowMask (1L<<4)
|
||||
#define LeaveWindowMask (1L<<5)
|
||||
#define PointerMotionMask (1L<<6)
|
||||
#define PointerMotionHintMask (1L<<7)
|
||||
#define Button1MotionMask (1L<<8)
|
||||
#define Button2MotionMask (1L<<9)
|
||||
#define Button3MotionMask (1L<<10)
|
||||
#define Button4MotionMask (1L<<11)
|
||||
#define Button5MotionMask (1L<<12)
|
||||
#define ButtonMotionMask (1L<<13)
|
||||
#define KeymapStateMask (1L<<14)
|
||||
#define ExposureMask (1L<<15)
|
||||
#define VisibilityChangeMask (1L<<16)
|
||||
#define StructureNotifyMask (1L<<17)
|
||||
#define ResizeRedirectMask (1L<<18)
|
||||
#define SubstructureNotifyMask (1L<<19)
|
||||
#define SubstructureRedirectMask (1L<<20)
|
||||
#define FocusChangeMask (1L<<21)
|
||||
#define PropertyChangeMask (1L<<22)
|
||||
#define ColormapChangeMask (1L<<23)
|
||||
#define OwnerGrabButtonMask (1L<<24)
|
||||
|
||||
/* Key masks. Used as modifiers to GrabButton and GrabKey, results of
|
||||
QueryPointer, state in various key-, mouse-, and button-related
|
||||
events. */
|
||||
|
||||
#define ShiftMask (1<<0)
|
||||
#define LockMask (1<<1)
|
||||
#define ControlMask (1<<2)
|
||||
#define Mod1Mask (1<<3)
|
||||
#define Mod2Mask (1<<4)
|
||||
#define Mod3Mask (1<<5)
|
||||
#define Mod4Mask (1<<6)
|
||||
#define Mod5Mask (1<<7)
|
||||
|
||||
/* Window classes used by CreateWindow */
|
||||
/* Note that CopyFromParent is already defined as 0 above */
|
||||
|
||||
#define InputOutput 1
|
||||
#define InputOnly 2
|
||||
|
||||
/* Window attributes for CreateWindow and ChangeWindowAttributes */
|
||||
|
||||
#define CWBackPixmap (1L<<0)
|
||||
#define CWBackPixel (1L<<1)
|
||||
#define CWBorderPixmap (1L<<2)
|
||||
#define CWBorderPixel (1L<<3)
|
||||
#define CWBitGravity (1L<<4)
|
||||
#define CWWinGravity (1L<<5)
|
||||
#define CWBackingStore (1L<<6)
|
||||
#define CWBackingPlanes (1L<<7)
|
||||
#define CWBackingPixel (1L<<8)
|
||||
#define CWOverrideRedirect (1L<<9)
|
||||
#define CWSaveUnder (1L<<10)
|
||||
#define CWEventMask (1L<<11)
|
||||
#define CWDontPropagate (1L<<12)
|
||||
#define CWColormap (1L<<13)
|
||||
#define CWCursor (1L<<14)
|
||||
|
||||
/* ConfigureWindow structure */
|
||||
|
||||
#define CWX (1<<0)
|
||||
#define CWY (1<<1)
|
||||
#define CWWidth (1<<2)
|
||||
#define CWHeight (1<<3)
|
||||
#define CWBorderWidth (1<<4)
|
||||
#define CWSibling (1<<5)
|
||||
#define CWStackMode (1<<6)
|
||||
|
||||
|
||||
/* Used in GetWindowAttributes reply */
|
||||
|
||||
#define IsUnmapped 0
|
||||
#define IsUnviewable 1
|
||||
#define IsViewable 2
|
||||
|
||||
/* Window stacking method (in configureWindow) */
|
||||
|
||||
#define Above 0
|
||||
#define Below 1
|
||||
#define TopIf 2
|
||||
#define BottomIf 3
|
||||
#define Opposite 4
|
||||
|
||||
/* For CreateColormap */
|
||||
|
||||
#define AllocNone 0 /* create map with no entries */
|
||||
#define AllocAll 1 /* allocate entire map writeable */
|
||||
|
||||
|
||||
/* Flags used in StoreNamedColor, StoreColors */
|
||||
|
||||
#define DoRed (1<<0)
|
||||
#define DoGreen (1<<1)
|
||||
#define DoBlue (1<<2)
|
||||
|
||||
/*
|
||||
* Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
|
||||
* value (x, y, width, height) was found in the parsed string.
|
||||
*/
|
||||
#define NoValue 0x0000
|
||||
#define XValue 0x0001
|
||||
#define YValue 0x0002
|
||||
#define WidthValue 0x0004
|
||||
#define HeightValue 0x0008
|
||||
#define AllValues 0x000F
|
||||
#define XNegative 0x0010
|
||||
#define YNegative 0x0020
|
||||
|
||||
/* flags argument in size hints */
|
||||
#define USPosition (1L << 0) /* user specified x, y */
|
||||
#define USSize (1L << 1) /* user specified width, height */
|
||||
|
||||
/* definitions for initial window state */
|
||||
#define WithdrawnState 0 /* for windows that are not mapped */
|
||||
#define NormalState 1 /* most applications want to start this way */
|
||||
#define IconicState 3 /* application wants to start as an icon */
|
||||
#define GameModeState 4 /* Win32 GLUT only (not in Xlib!). */
|
||||
|
||||
/* Type definitions */
|
||||
|
||||
typedef struct {
|
||||
unsigned int background_pixmap; /* background pixmap */
|
||||
unsigned long background_pixel; /* background pixel */
|
||||
unsigned long border_pixel; /* border pixel value */
|
||||
long event_mask; /* set of events that should be saved */
|
||||
long do_not_propagate_mask; /* set of events that should not propagate */
|
||||
Bool override_redirect; /* boolean value for override-redirect */
|
||||
Colormap colormap; /* color map to be associated with window */
|
||||
} XSetWindowAttributes;
|
||||
|
||||
typedef struct {
|
||||
unsigned long pixel;
|
||||
unsigned short red, green, blue;
|
||||
char flags; /* do_red, do_green, do_blue */
|
||||
} XColor;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *value; /* same as Property routines */
|
||||
Atom encoding; /* prop type */
|
||||
int format; /* prop data format: 8, 16, or 32 */
|
||||
unsigned long nitems; /* number of data items in value */
|
||||
} XTextProperty;
|
||||
|
||||
typedef struct {
|
||||
long flags; /* marks which fields in this structure are defined */
|
||||
int x, y; /* obsolete for new window mgrs, but clients */
|
||||
int width, height; /* should set so old wm's don't mess up */
|
||||
} XSizeHints;
|
||||
|
||||
/* Functions emulated by macros. */
|
||||
|
||||
#define XFreeColormap(display, colormap) \
|
||||
DeleteObject(colormap)
|
||||
|
||||
#define XCreateFontCursor(display, shape) \
|
||||
LoadCursor(NULL, shape)
|
||||
|
||||
#define XDefineCursor(display, window, cursor) \
|
||||
SetCursor(cursor)
|
||||
|
||||
#define XFlush(display) \
|
||||
/* Nothing. */
|
||||
|
||||
#define DisplayWidth(display, screen) \
|
||||
GetSystemMetrics(SM_CXSCREEN)
|
||||
|
||||
#define DisplayHeight(display, screen) \
|
||||
GetSystemMetrics(SM_CYSCREEN)
|
||||
|
||||
#define XMapWindow(display, window) \
|
||||
ShowWindow(window, SW_SHOWNORMAL)
|
||||
|
||||
#define XUnmapWindow(display, window) \
|
||||
ShowWindow(window, SW_HIDE)
|
||||
|
||||
#define XIconifyWindow(display, window, screen) \
|
||||
ShowWindow(window, SW_MINIMIZE)
|
||||
|
||||
#define XWithdrawWindow(display, window, screen) \
|
||||
ShowWindow(window, SW_HIDE)
|
||||
|
||||
#define XLowerWindow(display, window) \
|
||||
SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
|
||||
|
||||
#define XSetWMName(display, window, tp) \
|
||||
SetWindowText(window, (tp)->value)
|
||||
|
||||
/* There really isn't a way to set the icon name separate from the
|
||||
windows name in Win32, so, just set the windows name. */
|
||||
#define XSetWMIconName(display, window, tp) \
|
||||
XSetWMName(display, window, tp)
|
||||
|
||||
#define XDestroyWindow(display, window) \
|
||||
DestroyWindow(window)
|
||||
|
||||
/* Anything that needs to be freed was allocated with malloc in our
|
||||
fake X windows library for Win32, so free it with plain old
|
||||
free(). */
|
||||
#define XFree(data) \
|
||||
free(data)
|
||||
|
||||
/* Nothing to be done for this...the pointer is always 'ungrabbed'
|
||||
in Win32. */
|
||||
#define XUngrabPointer(display, time) \
|
||||
/* Nothing. */
|
||||
|
||||
/* Function prototypes. */
|
||||
|
||||
extern XVisualInfo* XGetVisualInfo(
|
||||
Display* display,
|
||||
long mask,
|
||||
XVisualInfo* ttemplate, /* Avoid class with C++ keyword. */
|
||||
int*nitems);
|
||||
|
||||
extern Colormap XCreateColormap(
|
||||
Display* display,
|
||||
Window root,
|
||||
Visual* visual,
|
||||
int alloc);
|
||||
|
||||
extern void XAllocColorCells(
|
||||
Display* display,
|
||||
Colormap colormap,
|
||||
Bool contig,
|
||||
unsigned long plane_masks_return[],
|
||||
unsigned int nplanes,
|
||||
unsigned long pixels_return[],
|
||||
unsigned int npixels);
|
||||
|
||||
extern void XStoreColor(
|
||||
Display* display,
|
||||
Colormap colormap,
|
||||
XColor* color);
|
||||
|
||||
extern void XSetWindowColormap(
|
||||
Display* display,
|
||||
Window window,
|
||||
Colormap colormap);
|
||||
|
||||
extern Bool XTranslateCoordinates(
|
||||
Display *display,
|
||||
Window src, Window dst,
|
||||
int src_x, int src_y,
|
||||
int* dest_x_return, int* dest_y_return,
|
||||
Window* child_return);
|
||||
|
||||
extern Status XGetGeometry(
|
||||
Display* display,
|
||||
Window window,
|
||||
Window* root_return,
|
||||
int* x_return, int* y_return,
|
||||
unsigned int* width_return, unsigned int* height_return,
|
||||
unsigned int *border_width_return,
|
||||
unsigned int* depth_return);
|
||||
|
||||
extern int DisplayWidthMM(
|
||||
Display* display,
|
||||
int screen);
|
||||
|
||||
extern int DisplayHeightMM(
|
||||
Display* display,
|
||||
int screen);
|
||||
|
||||
extern void XWarpPointer(
|
||||
Display* display,
|
||||
Window src, Window dst,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dst_x, int dst_y);
|
||||
|
||||
extern int XParseGeometry(
|
||||
char* string,
|
||||
int* x, int* y,
|
||||
unsigned int* width, unsigned int* height);
|
||||
|
||||
extern int XPending(
|
||||
Display* display);
|
||||
|
||||
#endif /* __win32_x11_h__ */
|
||||
Loading…
Add table
Reference in a new issue