The libslvs library and CDemo program can now be built by Autotools. A few
code changes were needed for this: C++ comments in C code had to be
converted, constraint.cpp required some massaging, and fltkutil.cpp needed
a stub for InitHeaps().
Place a pre-built copy of generated source files in src/built/, so that
users building SolveSpace from Git without the tools or setup necessary to
generate these can still complete the process.
Makefile.msvc: Use slashes consistently, and added rules to copy files from
src/built/ if needed
configure.ac: Check for presence of src/built/ at configure time
src/Makefile.am: Handle the generated *.table.h files together with
icon*.h; updated the source-generation rules so that the files are created
in builddir, not srcdir; added rules to copy files from src/built/ if
needed
This will allow checkouts of the SolveSpace source tree on Unix and Windows
to use the system's native line endings (i.e. LF vs. CRLF), while keeping
Unix line endings in the repository.
Created using the template at
https://help.github.com/articles/dealing-with-line-endings
The SolveSpace top-level directory was getting a bit cluttered, so
following the example of numerous other free-software projects, we move the
main application source into a subdirectory and adjust the build systems
accordingly.
Also, got rid of the obj/ directory in favor of creating it on the fly in
Makefile.msvc.
The .slvs file I/O code was using "*((type *)pointer) = value" type-punning
dereferences, which are syntactically unwieldy and prone to annoying modern
compilers. A union pointer is more elegant, and better expresses the
polymorphism at issue.
The bundled copies of LibPNG and zlib have been updated to the versions
shipped with FLTK (as these were convenient to build), and I've put in new
static libraries compiled with Visual Studio 2003 .NET. These libraries
link cleanly even with Visual Studio 2013 Express, so they should work for
just about every version of MSVC out there that can compile SolveSpace.
The MSVC makefile is also now a little nicer, and the SpaceWare Input
library header #includes have been adjusted to drop the si/ prefix (for
consistency with how LibPNG/zlib are handled).
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
This function previously returned an int32_t. Presuming that it measures
the length of time since the application was started, the 32-bit type would
cause the returned value to wrap from 2^31-1 to -2^31 after a little less
than twenty-five days.
* Added "Show Menu Bar" and "Full Screen" menu items, which will be
implemented in the FLTK interface. These are currently prevented from
appearing in the Win32 interface by the HAVE_FLTK and
HAVE_FLTK_FULLSCREEN macros.
* Moved the "Show Text Window" down below the "Show Toolbar" item, so that
"Show Menu Bar", "Show Toolbar" and "Show Text Window" are in the same
vertical order as their corresponding UI elements typically take on
* Added new platform-dependent routines to back the new menu items:
void ToggleMenuBar(void);
bool MenuBarIsVisible(void);
void ToggleFullScreen(void);
bool FullScreenIsActive(void);
These are stubs in the Win32 code.
* Fleshed out the system header #includes in solvespace.h, and moved them
to the top of the file per convention
* Rewrote the file dialog selection patterns in terms of macros that allow
them to expand to either the FLTK or Windows formats
* Don't use __stdcall in SSGL_CALLBACK, and make SSGL_CALLBACK 'extern "C"'
as OpenGL usually expects function pointers to point to C functions
The "glx" prefix on the names of SolveSpace's various GL helper routines
was confusingly similar to those used by official OpenGL-associated
libraries (e.g. "glu" used by the GL Utility library, and "glX" used by
GLX), and could thus give the erroneous impression that it represented a
system API rather than ordinary application logic. We thus rename these
routines to have an "ssgl" prefix, clearly identifying them with SolveSpace
while retaining some visual kinship to GL function names.
GCC and Clang's -Wfloat-equal warning notes that comparing floating-point
values with == or != may be questionable. But the few instances of these in
SolveSpace are defensibly correct (as discussed with Jonathan), so to keep
folks from getting nervous that a CAD application isn't handling its floats
correctly, we define an EXACT() macro inside which the -Wfloat-equal
warning is disabled. This macro will also serve as a source-code
annotation, like a comment but better.
(The warning is only disabled for Clang, alas, because GCC is particular
about where _Pragma() can be used. This isn't so bad, however, because the
warning is much easier to enable on Clang [thanks to -Weverything], whereas
with GCC it has to be requested explicitly.)
This commit consists of numerous small changes, none significant enough to
merit a commit on their own:
* Added extra braces to quash for-loop variable scoping issues for older
compilers (or "g++ -fno-for-scope")
* Appeased "unreachable code" warnings, spurious or otherwise
* Added casts to fix integer-variable signedness warnings
* Added a dummy virtual method to the VectorFileWriter class to silence the
-Wweak-vtables warning from Clang++
* Renamed some parameters in the Expr and GraphicsWindow classes to
eliminate "parameter shadows a field" warnings
* Removed an inert "0 ||" from a conditional, and changed a "&& 0" into an
"#if 0"
* Added missing elements to array/struct/class initializers to zap further
warnings
* Indented some cpp conditionals where appropriate
* Qualified some variables and functions as static to quiet "no previous
declaration" warnings
* toolbar.cpp needed to #include<icons-proto.h> to fix those same "no
previous declaration" warnings from icons.h
* Added some casts and const qualifiers to the Win32 code to address
warnings produced by g++ when compiling under MinGW
* Rewrote Cnf{Freeze,Thaw}Float() to use a union rather than pointer
aliasing; this makes g++ a lot happier
* Removed redundant #includes from win32/w32util.cpp
* With Jonathan's blessing, shortened the last line of the About dialog
text to better match the preceding lines
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
GraphicsWindow::menu[] previously recorded both item names (e.g. "Open...")
and accelerator labels ("Ctrl+O") in .label, and accelerator key/mask
values in .accel. Not only were the accelerator labels redundant given the
latter, they are not needed by GUI toolkits like FLTK, which generate them
from key/mask values.
So we remove the accelerator portion from each menu-item label, and define
a new MakeAcceleratorLabel() routine which takes a key/mask value and
returns the appropriate label. We make use of this new routine in
CreateGraphicsWindowMenus() and GraphicsWindow::ToolbarDrawOrHitTest().
* Added a comment header identifying the columns
* Added Ctrl-Q accelerator for "Exit", as this is standard
* Replaced a Latin-1 "degree" character with an octal escape, to avoid
source-file encoding issues
* Undefine (some of) the convenience macros used to define the table
(the method aliases are numerous and unlikely to collide with anything)
If we are to synthesize accelerator labels from values of
GraphicsWindow::menu[].accel, it will be more straightforward if
accelerators are represented in the same way that they appear in the menu.
(Windows does return the keystroke as VK_OEM_PERIOD with a Shift modifier,
so we add some special-case logic to recognize that.)
We can identify the "Open Recent" and "Import Recent" submenus just as
easily by looking at the value of the .id field (MNU_OPEN_RECENT and
MNU_GROUP_RECENT, respectively).
This commit contains a grab bag of minor changes not worth committing
individually:
* Replaced raw Latin-1 characters with octal escapes to avoid source-file
encoding issues
* Undefined some convenience macros after they've served their purpose
* Rewrote SEdge::From() to avoid confusing less-capable C++ compilers
* Have oops() print a newline at the end of its message
* Removed "static" keyword from the Bernstein() function definition, as it
has a non-static prototype in srf/surface.h
* Added casts (and changed a variable type) to quell warnings about integer
size and signedness
* Simplified an expression with our handy arraylen() macro
Some menu items in the menu-bar are toggles (each representing an option
that can be turned on or off independently), and some are 1-of-N selections
(e.g. mm or inches), like tuner buttons on a car radio. Windows can draw an
optional check-mark besides a menu item, and SolveSpace has been using this
feature to implement both kinds of menu items, with the backend logic
making them behave as a toggle or radio button as appropriate.
Other GUI platforms can draw proper radio-button menu items that are
distinct from toggles, however. To allow the platform-specific logic to
tell the two kinds of menu items apart, this change adds the
RadioMenuById() routine, and replaces the appropriate calls to
CheckMenuById() with it. (Note that nothing is changed in the Windows GUI
code; radio-menu items are still drawn with check-marks.)
The Valgrind tool can give a full accounting of what memory allocations
have yet to be free()d when the program exits. It is easier to find actual
memory leaks in the code if all non-leaked allocations are elided from that
accounting, which is most easily accomplished by free()ing them.
The "most" qualifier is there because some allocations are difficult/
impossible to free, as they are internal to libraries like OpenGL and Xft.
The best we can hope for is to cover all allocations made by SolveSpace
directly.
This function was returning ID{YES,NO,CANCEL}, which are specific to
Windows as return values for MessageBox(). These have been replaced with
SAVE_{YES,NO,CANCEL}, which we define ourselves.
Later versions of libpng (1.5.x) have made the png_info structure opaque,
breaking direct access to its fields. Fortunately, the library also
provides getter routines, and these are available in the more-widely-
deployed 1.2.x series.
FLTK's Fl_Input widget, instantiated as {Graphics,Text}EditControl, returns
a 'const char *' string. In order to handle this properly, several of
SolveSpace's internal routines needed to gain a "const" qualifier on the
edit-control string argument.
* Generate icons.h and icons-proto.h in the source directory instead of
obj/, so that pre-generated copies of these files can be distributed
without being blown away by "make clean"; also updated the source files
that #include these to reflect the new location
* Compilation rules rewritten as batch-mode inference rules
* Use Windows commands instead of Unix ones ("del" instead of "rm", "move"
instead of "mv", etc.)
* Sorted the object lists
* Use tabs to indent rule bodies
* Use "#!/usr/bin/env perl" instead of "#!/usr/bin/perl", as this is better
practice (it allows e.g. /usr/local/bin/perl to work when executing via
the shebang)
* Use "use strict" and "use warnings"
* Declare variables with "my" as required by "use strict"
* Take an optional "srcdir" argument so that the scripts can find the icon
files in a location other than ./icons/ -- this will make building
outside of the source tree possible in the future
* Add a "this is a generated file" banner to the output, so that it can be
clearly recognized as a machine-generated file that should not be
hand-edited
* Minor regex tweaks
Several MenuEntry elements in GraphicsWindow::menu[] were being initialized
with four items instead of the requisite five, due to a missing fourth
column (corresponding to the .accel field of MenuEntry). This change simply
adds zeroes as the missing column to the appropriate elements.
This addresses a grab bag of compiler grievances relating to C++ syntax,
type, and scope, as observed on Linux with g++ and Solaris with Sun
WorkShop 6.
Having e.g. GetWORD() return a WORD rather than int eliminates the need for
a cast when assigning to WORD variables. We use casts only when assigning
to a different (but same-sized) type.
Also, check for EOF explicitly when calling fgetc().
The compiler gets nervous when we (for example) pass in a size_t as an int
parameter, or assign an int to a char, or assign -1 to an unsigned type. By
adding appropriate casts, we inform the compiler that, yes, we know what
we're doing.
This change also upgrades a va_arg() type from char to int, as char is
always promoted to int when passed through '...'.