Initial Autotools and FLTK support

With this commit, SolveSpace gains an Autotools build system and a new
platform-dependent backend implemented using the FLTK GUI toolkit. These
will allow the application to be built and run on Linux and other Unix-like
operating systems, and prospectively, MacOS X.

A number of new files have been added:

* Makefile.am: Automake makefile template; this contains some experimental
  support for MinGW and MSVC++ builds that needs further development

* ac-aux/ax_fltk.m4: Autoconf M4 macro to locate and query the system's
  installation of FLTK; this will eventually be contributed to the GNU
  Autoconf Archive

* autogen.sh: Script to bootstrap the Autotools build system, usually for a
  tree just checked out from source control

* configure.ac: Source for the Autoconf configure script; note that this
  file specifies a version of 2.1, near the top

* fltk/fltkmain.cpp: Main FLTK backend implementation

* fltk/fltkutil.cpp: Utility functions for the FLTK backend

* fltk/xFl_Gl_Window_Group.{H,cxx}: Implementation of a new
  Fl_Gl_Window_Group widget for FLTK, needed to facilitate drawing FLTK
  widgets on top of OpenGL graphics as SolveSpace does. This has been
  submitted to the FLTK project for (hopefully) eventual upstream
  inclusion:

    http://www.fltk.org/str.php?L2992

The following minor changes are also a part of this commit:

* Makefile.msvc: Define PACKAGE_VERSION=2.1 for the benefit of
  solvespace.cpp in MSVC++ builds

* solvespace.cpp: In the About dialog text, use PACKAGE_VERSION rather than
  hard-coding the version of the program

* solvespace.h: Don't define the C99 integer types if
  HAVE_C99_INTEGER_TYPES is defined, to facilitate MinGW builds
pull/3/head
Daniel Richard G 2013-10-28 01:28:42 -04:00
parent 7ca137f5fe
commit c60e3dd34e
11 changed files with 2355 additions and 3 deletions

246
Makefile.am Normal file
View File

@ -0,0 +1,246 @@
## Makefile.am
ACLOCAL_AMFLAGS = -I ac-aux
AM_CPPFLAGS = $(FLTK_CXXFLAGS)
if WIN32
AM_CPPFLAGS += \
-I$(srcdir)/extlib/libpng \
-I$(srcdir)/extlib/si \
-I$(srcdir)/extlib/zlib
endif
bin_PROGRAMS = solvespace
icons_src = \
icons.h \
icons-proto.h
BUILT_SOURCES = $(icons_src)
solvespace_SOURCES = \
$(icons_src) \
bsp.cpp \
clipboard.cpp \
confscreen.cpp \
constraint.cpp \
constrainteq.cpp \
describescreen.cpp \
draw.cpp \
drawconstraint.cpp \
drawentity.cpp \
dsc.h \
entity.cpp \
export.cpp \
exportstep.cpp \
exportvector.cpp \
expr.h \
expr.cpp \
file.cpp \
generate.cpp \
glhelper.cpp \
graphicswin.cpp \
group.cpp \
groupmesh.cpp \
mesh.cpp \
modify.cpp \
mouse.cpp \
polygon.h \
polygon.cpp \
request.cpp \
sketch.h \
solvespace.h \
solvespace.cpp \
style.cpp \
system.cpp \
textscreens.cpp \
textwin.cpp \
toolbar.cpp \
ttf.cpp \
ui.h \
undoredo.cpp \
util.cpp \
view.cpp \
srf/boolean.cpp \
srf/curve.cpp \
srf/merge.cpp \
srf/ratpoly.cpp \
srf/raycast.cpp \
srf/surface.h \
srf/surface.cpp \
srf/surfinter.cpp \
srf/triangulate.cpp
if HAVE_FLTK
solvespace_SOURCES += \
fltk/xFl_Gl_Window_Group.H \
fltk/xFl_Gl_Window_Group.cxx \
fltk/fltkmain.cpp \
fltk/fltkutil.cpp
solvespace_LDADD = $(FLTK_LDSTATICFLAGS) -lGLU
endif
if WIN32
solvespace_SOURCES += \
win32/freeze.h \
win32/freeze.cpp \
win32/w32main.cpp \
win32/w32util.cpp
if MINGW
solvespace_LDFLAGS = \
-llibpng \
-lzlib \
-luser32 -lgdi32 -lcomctl32 -ladvapi32 -lshell32 \
-lopengl32 -lglu32
else
solvespace_LDFLAGS = -link \
-libpath:$(srcdir)/extlib/libpng libpng.lib \
-libpath:$(srcdir)/extlib/zlib zlib.lib \
user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib \
opengl32.lib glu32.lib
endif # MINGW
endif # WIN32
icons = \
icon.ico \
icons/angle.png \
icons/arc.png \
icons/assemble.png \
icons/bezier.png \
icons/char-0-check-false.png \
icons/char-1-check-true.png \
icons/char-2-radio-false.png \
icons/char-3-radio-true.png \
icons/circle.png \
icons/constraint.png \
icons/construction.png \
icons/edges.png \
icons/equal.png \
icons/extrude.png \
icons/faces.png \
icons/hidden-lines.png \
icons/horiz.png \
icons/in3d.png \
icons/length.png \
icons/line.png \
icons/mesh.png \
icons/normal.png \
icons/ontoworkplane.png \
icons/other-supp.png \
icons/parallel.png \
icons/perpendicular.png \
icons/point.png \
icons/pointonx.png \
icons/rectangle.png \
icons/ref.png \
icons/same-orientation.png \
icons/shaded.png \
icons/sketch-in-3d.png \
icons/sketch-in-plane.png \
icons/step-rotate.png \
icons/step-translate.png \
icons/symmetric.png \
icons/tangent-arc.png \
icons/text.png \
icons/trim.png \
icons/vert.png \
icons/workplane.png
tables = \
bitmapextra.table.h \
bitmapfont.table.h \
font.table.h
exposed = \
exposed/CDemo.c \
exposed/DOC.txt \
exposed/Makefile \
exposed/VbDemo.vb \
exposed/lib.cpp \
exposed/slvs.h
EXTRA_DIST = \
$(icons) \
$(tables) \
$(exposed) \
COPYING.txt \
Makefile.msvc \
extlib/build-fltk.sh \
png2c.pl \
pngchar2c.pl \
tools/Makefile \
tools/ttf2c.cpp \
wishlist.txt \
win32/manifest.xml \
win32/resource.rc
optional_dist = \
extlib/libpng/png.h \
extlib/libpng/pngconf.h \
extlib/libpng/pnglibconf.h \
extlib/libpng/libpng.lib \
extlib/si/si.h \
extlib/si/siSync.h \
extlib/si/siSyncPriv.h \
extlib/si/siapp.h \
extlib/si/spwdata.h \
extlib/si/spwerror.h \
extlib/si/spwmacro.h \
extlib/si/siapp.lib \
extlib/zlib/zconf.h \
extlib/zlib/zlib.h \
extlib/zlib/zutil.h \
extlib/zlib/zlib.lib \
extlib/fltk-1.3.2-source.tar.gz
dist-hook:
for file in $(optional_dist); do \
test -f $(srcdir)/$$file || continue; \
dir=`dirname $$file`; \
test -d $(distdir)/$$dir || mkdir $(distdir)/$$dir || exit; \
cp -p $(srcdir)/$$file $(distdir)/$$file || exit; \
done
@if fgrep '/DPACKAGE_VERSION="\"$(PACKAGE_VERSION)\""' $(srcdir)/Makefile.msvc >/dev/null; \
then :; \
else \
echo 'error: /DPACKAGE_VERSION flag in Makefile.msvc is out-of-date'; \
echo '(current package version is $(PACKAGE_VERSION))'; \
exit 1; \
fi
if MAINTAINER_MODE
icons.h: $(icons) $(srcdir)/png2c.pl
$(PERL) $(srcdir)/png2c.pl $@ icons-proto.h $(srcdir)
icons-proto.h: icons.h
@exit 0
bitmapextra.table.h: $(icons) $(srcdir)/pngchar2c.pl
$(PERL) $(srcdir)/pngchar2c.pl $(srcdir) >$@.tmp
mv -f $@.tmp $@
endif # MAINTAINER_MODE
run-valgrind: solvespace$(EXEEXT)
@test -z "$$VALGRIND_OPTS" || echo VALGRIND_OPTS = $$VALGRIND_OPTS
valgrind \
--tool=memcheck \
--verbose \
--track-fds=yes \
--log-file=vg.%p.out \
--num-callers=50 \
--error-limit=no \
--read-var-info=yes \
--leak-check=full \
--leak-resolution=high \
--show-reachable=yes \
--track-origins=yes \
--malloc-fill=0xac \
--free-fill=0xde \
./solvespace$(EXEEXT)
## end Makefile.am

View File

@ -3,7 +3,7 @@
HAVE_SPACEWARE_INPUT = 1
DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32
DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32 /DPACKAGE_VERSION="\"2.1\""
# Use the multi-threaded static libc because libpng and zlib do; not sure if anything bad
# happens if those mix, but don't want to risk it.
CXXFLAGS = /W3 /nologo /MT /D_DEBUG /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS /I. /Iextlib /Zi /EHs # /O2

179
ac-aux/ax_fltk.m4 Normal file
View File

@ -0,0 +1,179 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_fltk.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_FLTK(API-VERSION[,
# USE-OPTIONS[,
# ACTION-IF-FOUND[,
# ACTION-IF-NOT-FOUND]]])
#
# DESCRIPTION
#
# This macro checks for the presence of an installed copy of FLTK
# matching the specified API-VERSION (which can be "1.1", "1.3" and so
# on). If found, the following variables are set and AC_SUBST'ed with
# values obtained from the fltk-config script:
#
# FLTK_VERSION
# FLTK_API_VERSION
# FLTK_CC
# FLTK_CXX
# FLTK_OPTIM
# FLTK_CFLAGS
# FLTK_CXXFLAGS
# FLTK_LDFLAGS
# FLTK_LDSTATICFLAGS
# FLTK_LIBS
# FLTK_PREFIX
# FLTK_INCLUDEDIR
#
# USE-OPTIONS is a space-separated set of --use-* options to pass to the
# fltk-config script when populating the above variables.
#
# If you are using FLTK extensions (e.g. OpenGL support, extra image
# libraries, Forms compatibility), then you can specify a set of
# space-separated options like "--use-gl", "--use-images" etc. for
# USE-OPTIONS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a matching
# version of FLTK is found, and ACTION-IF-NOT-FOUND is a list of commands
# to run it if it is not found. If ACTION-IF-FOUND is not specified, the
# default action will define HAVE_FLTK.
#
# Please let the author(s) know if this macro fails on any platform, or
# if you have any other suggestions or comments.
#
# LICENSE
#
# Copyright (c) 2013 Daniel Richard G. <skunk@iSKUNK.ORG>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 0
AC_DEFUN([AX_FLTK], [
AC_LANG_PUSH([C++])
m4_bmatch([$1], [^[1-9]\.[0-9]$], [],
[m4_fatal([invalid FLTK API version "$1"])])
m4_bmatch([$2], [^\(\(--use-[a-z]+\)\( +--use-[a-z]+\)*\)?$], [],
[m4_fatal([invalid fltk-config use-options string "$2"])])
AC_ARG_WITH([fltk],
[AS_HELP_STRING([--with-fltk=PREFIX],
[use FLTK $1 libraries installed in PREFIX])])
case "_$with_fltk" in
_no)
FLTK_CONFIG=
;;
_|_yes)
AC_PATH_PROG([FLTK_CONFIG], [fltk-config])
;;
*)
AC_PATH_PROG([FLTK_CONFIG], [fltk-config], , [$with_fltk/bin])
;;
esac
FLTK_VERSION=
FLTK_API_VERSION=
FLTK_CC=
FLTK_CXX=
FLTK_OPTIM=
FLTK_CFLAGS=
FLTK_CXXFLAGS=
FLTK_LDFLAGS=
FLTK_LDSTATICFLAGS=
FLTK_LIBS=
FLTK_PREFIX=
FLTK_INCLUDEDIR=
have_fltk=no
if test -n "$FLTK_CONFIG"
then
FLTK_VERSION=`$FLTK_CONFIG --version`
FLTK_API_VERSION=`$FLTK_CONFIG --api-version`
AC_MSG_CHECKING([for FLTK API version $1])
if test "_$FLTK_API_VERSION" = "_$1"
then
have_fltk=yes
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fl_opt="$2"
FLTK_CC=`$FLTK_CONFIG $fl_opt --cc`
FLTK_CXX=`$FLTK_CONFIG $fl_opt --cxx`
FLTK_OPTIM=`$FLTK_CONFIG $fl_opt --optim`
FLTK_CFLAGS=`$FLTK_CONFIG $fl_opt --cflags`
FLTK_CXXFLAGS=`$FLTK_CONFIG $fl_opt --cxxflags`
FLTK_LDFLAGS=`$FLTK_CONFIG $fl_opt --ldflags`
FLTK_LDSTATICFLAGS=`$FLTK_CONFIG $fl_opt --ldstaticflags`
FLTK_LIBS=`$FLTK_CONFIG $fl_opt --libs`
FLTK_PREFIX=`$FLTK_CONFIG $fl_opt --prefix`
FLTK_INCLUDEDIR=`$FLTK_CONFIG $fl_opt --includedir`
fi
# Finally, execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND:
#
if test "$have_fltk" = yes
then
:
ifelse([$3], ,
[AC_DEFINE([HAVE_FLTK], [1], [Define if you have the FLTK libraries.])],
[$3])
else
:
$4
fi
AC_SUBST([FLTK_VERSION])
AC_SUBST([FLTK_API_VERSION])
AC_SUBST([FLTK_CC])
AC_SUBST([FLTK_CXX])
AC_SUBST([FLTK_OPTIM])
AC_SUBST([FLTK_CFLAGS])
AC_SUBST([FLTK_CXXFLAGS])
AC_SUBST([FLTK_LDFLAGS])
AC_SUBST([FLTK_LDSTATICFLAGS])
AC_SUBST([FLTK_LIBS])
AC_SUBST([FLTK_PREFIX])
AC_SUBST([FLTK_INCLUDEDIR])
AC_LANG_POP
])dnl AX_FLTK

10
autogen.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
set -ex
autoreconf --force --install --warnings=all
rm -f config.h.in~
rm -rf autom4te.cache
# EOF

136
configure.ac Normal file
View File

@ -0,0 +1,136 @@
## configure.ac
AC_PREREQ([2.59])
AC_INIT([SolveSpace], [2.1], [jwesthues@cq.cx], [solvespace])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([solvespace.cpp])
AC_CONFIG_AUX_DIR([ac-aux])
AC_CONFIG_MACRO_DIR([ac-aux])
AM_INIT_AUTOMAKE([1.9.6 foreign tar-ustar])
AM_MAINTAINER_MODE
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
dnl AC_PROG_MAKE_SET
AC_HEADER_STDC
AC_C_BIGENDIAN
AC_C_CONST
AC_C_INLINE
# Check for Libtool
#
dnl AC_DISABLE_SHARED
LT_INIT
# Do we have Perl?
#
AC_CHECK_PROG([PERL], [perl], [perl], [false])
# Check for headers that define integer types
#
AC_CHECK_HEADERS([inttypes.h stdint.h sys/socket.h])
# Check for various integer types
#
AC_TYPE_INT8_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_SSIZE_T
AC_DEFINE([HAVE_C99_INTEGER_TYPES], [1], [Define to 1 if (self-explanatory).])
# Check the size of various types
#
AC_CHECK_SIZEOF([char])
AC_CHECK_SIZEOF([short])
AC_CHECK_SIZEOF([int])
AC_CHECK_SIZEOF([long])
AC_CHECK_SIZEOF([float])
AC_CHECK_SIZEOF([double])
AC_CHECK_SIZEOF([long double])
AC_CHECK_SIZEOF([void *])
AC_CHECK_SIZEOF([size_t])
##
## Windows support
##
AC_EXEEXT
AC_OBJEXT
win32=no
AC_EGREP_CPP([SOLVESPACE_WIN32],dnl
[#if (defined(_MSC_VER) && defined(_WIN32)) || defined(__MINGW32__)
SOLVESPACE_WIN32
#endif], [win32=yes])
AM_CONDITIONAL([WIN32], [test "$win32" = yes])
mingw=no
AC_EGREP_CPP([SOLVESPACE_MINGW],dnl
[#if defined(__MINGW32__)
SOLVESPACE_MINGW
#endif], [mingw=yes])
AM_CONDITIONAL([MINGW], [test "$mingw" = yes])
AH_VERBATIM([MSVC_FLAGS], [#if defined(_MSC_VER) && defined(_WIN32)
# define _CRT_SECURE_NO_DEPRECATE 1
# define _CRT_SECURE_NO_WARNINGS 1
# define _WIN32_WINNT 0x500
# define _WIN32_IE _WIN32_WINNT
# define ISOLATION_AWARE_ENABLED 1
# define WIN32 1
# define WIN32_LEAN_AND_MEAN 1
#endif])
##
## FLTK
##
AX_FLTK([1.3], [--use-gl --use-images --use-forms])
AM_CONDITIONAL([HAVE_FLTK], [test "$have_fltk" = yes])
if test "$have_fltk" = yes
then
x=`echo "$FLTK_VERSION" | cut -d. -f1`
y=`echo "$FLTK_VERSION" | cut -d. -f2`
z=`echo "$FLTK_VERSION" | cut -d. -f3`
if test `expr 10000 '*' $x + 100 '*' $y + $z` -ge 10301
then
AC_DEFINE([HAVE_FLTK_FULLSCREEN], [1],
[Define to 1 if your copy of FLTK has proper fullscreen support.])
fi
fi
##
## Wrap it up
##
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
cat <<EOF
$PACKAGE-$VERSION configuration summary:
Install prefix ......... : ${prefix}
C++ preprocessor ....... : ${CXXCPP}
C++ compiler ........... : ${CXX}
Linker ................. : ${LD}
C preprocessor flags ... : ${CPPFLAGS}
C++ compiler flags ..... : ${CXXFLAGS}
Linker flags ........... : ${LDFLAGS}
Extra libraries ........ : ${LIBS}
EOF
## end configure.ac

1279
fltk/fltkmain.cpp Normal file

File diff suppressed because it is too large Load Diff

107
fltk/fltkutil.cpp Normal file
View File

@ -0,0 +1,107 @@
//-----------------------------------------------------------------------------
// Utility functions used by the FLTK port. Notably, our memory allocation;
// we use two separate allocators, one for long-lived stuff and one for
// stuff that gets freed after every regeneration of the model, to save us
// the trouble of freeing the latter explicitly.
//
// Copyright 2008-2013 Jonathan Westhues.
// Copyright 2013 Daniel Richard G. <skunk@iSKUNK.ORG>
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <FL/filename.H>
#include "solvespace.h"
void dbp(const char *str, ...)
{
va_list f;
static char buf[1024*50];
va_start(f, str);
vsnprintf(buf, sizeof(buf), str, f);
va_end(f);
fputs(buf, stderr);
}
void GetAbsoluteFilename(char *file)
{
char absoluteFile[PATH_MAX];
fl_filename_absolute(absoluteFile, sizeof(absoluteFile), file);
strcpy(file, absoluteFile);
}
//-----------------------------------------------------------------------------
// A separate heap, on which we allocate expressions. Maybe a bit faster,
// since fragmentation is less of a concern, and it also makes it possible
// to be sloppy with our memory management, and just free everything at once
// at the end.
//-----------------------------------------------------------------------------
typedef struct _AllocTempHeader AllocTempHeader;
typedef struct _AllocTempHeader {
AllocTempHeader *prev;
AllocTempHeader *next;
} AllocTempHeader;
static AllocTempHeader *Head = NULL;
void *AllocTemporary(size_t n)
{
AllocTempHeader *h =
(AllocTempHeader *)malloc(n + sizeof(AllocTempHeader));
h->prev = NULL;
h->next = Head;
Head = h;
return (void *)&h[1];
}
void FreeTemporary(void *p)
{
AllocTempHeader *h = (AllocTempHeader *)p - 1;
if(h->prev) {
h->prev->next = h->next;
} else {
Head = h->next;
}
if(h->next) h->next->prev = h->prev;
free(h);
}
void FreeAllTemporary(void)
{
AllocTempHeader *h = Head;
while(h) {
AllocTempHeader *f = h;
h = h->next;
free(f);
}
Head = NULL;
}
void *MemRealloc(void *p, size_t n) {
if(!p) {
return MemAlloc(n);
}
p = realloc(p, n);
if(!p) oops();
return p;
}
void *MemAlloc(size_t n) {
void *p = malloc(n);
if(!p) oops();
return p;
}
void MemFree(void *p) {
free(p);
}

103
fltk/xFl_Gl_Window_Group.H Normal file
View File

@ -0,0 +1,103 @@
//
// "$Id$"
//
// OpenGL window group widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
//
// Please report all bugs and problems on the following page:
//
// http://www.fltk.org/str.php
//
/* \file
Fl_Gl_Window_Group widget . */
#ifndef Fl_Gl_Window_Group_H
#define Fl_Gl_Window_Group_H
#include <FL/Fl_Gl_Window.H> //#include "Fl_Gl_Window.H"
#include <FL/x.H> //#include "x.H"
#define Fl_Gl_Window_Group xFl_Gl_Window_Group
class Fl_Gl_Window_Group_INTERNAL;
/**
The Fl_Gl_Window_Group widget is an extended form of Fl_Gl_Window that
can contain child widgets not specially modified to use OpenGL calls.
After the main OpenGL area is drawn, child widgets are each drawn into an
offscreen buffer (using the standard FLTK drawing routines), and then
copied into the OpenGL window using a textured quad.
*/
class FL_EXPORT Fl_Gl_Window_Group : public Fl_Gl_Window {
class Fl_Gl_Window_Group_INTERNAL *glstandin;
Fl_Offscreen offscr;
int offscr_w, offscr_h;
uchar *imgbuf;
GLContext children_context;
unsigned int texid;
void init(void);
void adjust_offscr(int w, int h);
public:
~Fl_Gl_Window_Group(void);
/**
Creates a new Fl_Gl_Window_Group widget using the given size and label string.
*/
Fl_Gl_Window_Group(int W, int H, const char *l=0)
: Fl_Gl_Window(W,H,l) {init();}
/**
Creates a new Fl_Gl_Window_Group widget using the given position,
size, and label string.
*/
Fl_Gl_Window_Group(int X, int Y, int W, int H, const char *l=0)
: Fl_Gl_Window(X,Y,W,H,l) {init();}
void show(void);
void hide(void);
void clear(void);
void flush(void);
/**
Handles the specified event.
This method only receives events that were not used by any of the child
widgets. Unlike most handle() methods, this should not call the
inherited handle() method, or else an infinite loop will result.
*/
virtual int handle_gl(int event);
protected:
void draw(void);
void draw_children(void);
void draw_child(Fl_Widget& widget);
/**
Draws the main OpenGL area of the Fl_Gl_Window_Group.
You \e \b must override the draw_gl() method.
*/
virtual void draw_gl(void);
};
#endif
//
// End of "$Id:$".
//

View File

@ -0,0 +1,292 @@
//
// "$Id$"
//
// OpenGL window group widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
//
// Please report all bugs and problems on the following page:
//
// http://www.fltk.org/str.php
//
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
//#include "Fl_Gl_Choice.H"
#if 1 //---------------- Extract from Fl_Gl_Choice.H
#ifdef WIN32
# include <FL/gl.h>
# define GLContext HGLRC
#elif defined(__APPLE_QUARTZ__)
# include <OpenGL/gl.h>
# include <AGL/agl.h>
# define GLContext AGLContext
#else
# include <GL/glx.h>
# define GLContext GLXContext
#endif
GLContext fl_create_gl_context(XVisualInfo*);
void fl_set_gl_context(Fl_Window*, GLContext);
void fl_delete_gl_context(GLContext);
#endif //----------------
#include <fltk/xFl_Gl_Window_Group.H> //#include <FL/Fl_Gl_Window_Group.H>
#include <FL/fl_draw.H>
#include <FL/gl.h>
#if 1 //HAVE_GL
#if !defined(GL_TEXTURE_RECTANGLE) && defined(WIN32)
# define GL_TEXTURE_RECTANGLE 0x84F5
#endif
#define Gl_Stand_In Fl_Gl_Window_Group_INTERNAL
#define RESET_FIELDS() \
imgbuf = NULL; \
offscr_w = -1; \
offscr_h = -1
class Gl_Stand_In : public Fl_Box {
Fl_Gl_Window_Group *glwg;
public:
Gl_Stand_In(int W, int H, Fl_Gl_Window_Group *w)
: Fl_Box(0, 0, W, H) {
glwg = w;
}
int handle(int event) { return glwg->handle_gl(event); }
protected:
void draw(void) { Fl::fatal("Never call this"); }
virtual void dummy(void);
};
void Gl_Stand_In::dummy(void) {}
void Fl_Gl_Window_Group::init(void) {
begin(); // Revert the end() in the Fl_Gl_Window constructor
glstandin = new Gl_Stand_In(w(), h(), this);
children_context = NULL;
texid = 0;
RESET_FIELDS();
}
Fl_Gl_Window_Group::~Fl_Gl_Window_Group(void) {
delete glstandin;
}
void Fl_Gl_Window_Group::adjust_offscr(int w, int h) {
if (imgbuf == NULL) {
// Find maximum width and height across all visible child widgets
// (except for the GL stand-in widget)
Fl_Widget*const* a = array();
for (int i = children(); i--;) {
Fl_Widget* o = a[i];
if (o == glstandin) continue;
if (!o->visible()) continue;
int cw = o->w();
int ch = o->h();
if (offscr_w < cw) offscr_w = cw;
if (offscr_h < ch) offscr_h = ch;
}
} else {
fl_delete_offscreen(offscr);
}
if (w > offscr_w) offscr_w = w;
if (h > offscr_h) offscr_h = h;
offscr = fl_create_offscreen(offscr_w, offscr_h);
int imgbuf_size = offscr_w * offscr_h * 3; // GL_RGB
imgbuf = (uchar *)realloc(imgbuf, (size_t)imgbuf_size);
}
void Fl_Gl_Window_Group::show() {
Fl_Gl_Window::show();
if (!children_context) {
children_context = fl_create_gl_context(fl_visual);
fl_set_gl_context(this, children_context);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_RECTANGLE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_RECTANGLE, texid);
make_current();
}
}
void Fl_Gl_Window_Group::hide() {
if (children_context) {
fl_set_gl_context(this, children_context);
glDeleteTextures(1, &texid);
texid = 0;
make_current();
fl_delete_gl_context(children_context);
children_context = NULL;
}
Fl_Gl_Window::hide();
}
/**
Deletes all child widgets from memory recursively.
This method differs from the remove() method in that it
affects all child widgets and deletes them from memory.
*/
void Fl_Gl_Window_Group::clear(void) {
if (imgbuf != NULL) {
fl_delete_offscreen(offscr);
free(imgbuf);
RESET_FIELDS();
}
remove(glstandin);
Fl_Gl_Window::clear();
add(glstandin);
}
int Fl_Gl_Window_Group::handle_gl(int event) {
// Override me
return 0;
}
void Fl_Gl_Window_Group::flush(void) {
// Fl_Window::make_current() does this, but not
// Fl_Gl_Window::make_current(), and we can't override make_current()
// and have Fl_Gl_Window::flush() call us
Fl_Window::make_current();
Fl_Gl_Window::make_current();
Fl_Gl_Window::flush();
}
void Fl_Gl_Window_Group::draw(void) {
if (damage()) {
draw_gl();
draw_children();
}
}
/**
Draws all children of the group.
*/
void Fl_Gl_Window_Group::draw_children(void) {
fl_set_gl_context(this, children_context);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0, w(), 0, h(), -1.0, 1.0);
glTranslatef(0.0, h(), 0.0);
glScalef(1.0, -1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w(), h());
Fl_Widget*const* a = array();
for (int i = children(); i--;) draw_child(**a++);
#if 1
int err = glGetError();
if (err != GL_NO_ERROR) {
Fl::warning("OpenGL error after drawing Fl_Gl_Window_Group children: 0x0%X", err);
}
#endif
make_current();
}
/**
This draws a child widget, if it is not clipped.
The damage bits are cleared after drawing.
*/
void Fl_Gl_Window_Group::draw_child(Fl_Widget& widget) {
if (&widget == glstandin) return;
if (!widget.visible() || widget.type() >= FL_WINDOW ||
!fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) return;
if (widget.w() > offscr_w || widget.h() > offscr_h) {
adjust_offscr(widget.w(), widget.h());
}
int widget_x = widget.x();
int widget_y = widget.y();
int widget_w = widget.w();
int widget_h = widget.h();
widget.position(0, 0);
fl_begin_offscreen(offscr);
fl_rectf(0, 0, widget_w, widget_h, FL_MAGENTA);
widget.clear_damage(FL_DAMAGE_ALL);
widget.draw();
widget.clear_damage();
fl_read_image(imgbuf, 0, 0, widget_w, widget_h);
fl_end_offscreen();
widget.position(widget_x, widget_y);
#ifdef USE_GLDRAWPIXELS // Note: glDrawPixels() is deprecated
glRasterPos2i(widget_x, widget_y);
glPixelZoom(1.0, -1.0);
glDrawPixels(widget_w, widget_h, GL_RGB, GL_UNSIGNED_BYTE, imgbuf);
#else // ! USE_GLDRAWPIXELS
glTexImage2D(
GL_TEXTURE_RECTANGLE,
0,
GL_RGB,
widget_w, widget_h,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
imgbuf);
#define CORNER(x,y) glTexCoord2f(x, y); glVertex2f(widget_x + x, widget_y + y)
glBegin(GL_QUADS);
CORNER(0, 0);
CORNER(widget_w, 0);
CORNER(widget_w, widget_h);
CORNER(0, widget_h);
glEnd();
#undef CORNER
#endif // ! USE_GLDRAWPIXELS
}
void Fl_Gl_Window_Group::draw_gl(void) {
Fl::fatal("Fl_Gl_Window_Group::draw_gl() *must* be overriden. Please refer to the documentation.");
}
#else // ! HAVE_GL
typedef int no_opengl_support;
#endif // ! HAVE_GL
//
// End of "$Id:$".
//

View File

@ -722,7 +722,7 @@ void SolveSpace::MenuHelp(int id) {
case GraphicsWindow::MNU_ABOUT:
Message(
"This is SolveSpace version 2.0.\n"
"This is SolveSpace version " PACKAGE_VERSION ".\n"
"\n"
"Built " __TIME__ " " __DATE__ ".\n"
"\n"

View File

@ -85,7 +85,7 @@ inline double ffabs(double v) { return (v > 0) ? v : (-v); }
#define isforname(c) (isalnum(c) || (c) == '_' || (c) == '-' || (c) == '#')
#ifdef WIN32
#if defined(WIN32) && !defined(HAVE_C99_INTEGER_TYPES)
// Define some useful C99 integer types.
typedef UINT64 uint64_t;
typedef INT64 int64_t;