diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 2001-11-27 17:44:08 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2001-11-27 17:44:08 +0000 |
| commit | 2b85bf81680e2243ef5a5daf85d9eb04321c7278 (patch) | |
| tree | dc7d3e1cdbd44ed10b358412098b73d24b64d143 | |
| parent | 4dc5732a3e0f376786d1d6b788e5cf601439e890 (diff) | |
Preliminary commit of my MacOS X work.
**** THIS CODE COMPILES BUT DOES NOT WORK. ****
TODO: fix event handling - getting blank windows, etc.
TODO: re-port OpenGL code.
TODO: add support for images with alpha.
TODO: add support for more then just beeps in fl_beep().
TODO: other stuff I'm sure...
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1765 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
58 files changed, 3604 insertions, 440 deletions
@@ -1,5 +1,5 @@ // -// "$Id: Fl.H,v 1.8.2.11.2.3 2001/11/03 05:11:33 easysw Exp $" +// "$Id: Fl.H,v 1.8.2.11.2.4 2001/11/27 17:44:06 easysw Exp $" // // Main header file for the Fast Light Tool Kit (FLTK). // @@ -159,13 +159,13 @@ public: static FL_EXPORT void paste(Fl_Widget &receiver); // screen size: -#if defined(WIN32) +#if defined(WIN32) || defined(__APPLE__) static FL_EXPORT int x(); static FL_EXPORT int y(); #else static FL_EXPORT int x() {return 0;} static FL_EXPORT int y() {return 0;} -#endif /* WIN32 */ +#endif /* WIN32 || __APPLE__ */ static FL_EXPORT int w(); static FL_EXPORT int h(); @@ -220,5 +220,5 @@ public: #endif // -// End of "$Id: Fl.H,v 1.8.2.11.2.3 2001/11/03 05:11:33 easysw Exp $". +// End of "$Id: Fl.H,v 1.8.2.11.2.4 2001/11/27 17:44:06 easysw Exp $". // diff --git a/FL/Fl_Sys_Menu_Bar.H b/FL/Fl_Sys_Menu_Bar.H new file mode 100644 index 000000000..a1cf92185 --- /dev/null +++ b/FL/Fl_Sys_Menu_Bar.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Sys_Menu_Bar.H,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// MacOS system menu bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +#ifndef Fl_Sys_Menu_Bar_H +#define Fl_Sys_Menu_Bar_H + +#include "Fl_Menu_Bar.H" + +class Fl_Sys_Menu_Bar : public Fl_Menu_Bar { +protected: + FL_EXPORT void draw(); +public: +//FL_EXPORT int handle(int); + Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0) + : Fl_Menu_Bar(x,y,w,h,l) {} + FL_EXPORT void menu(const Fl_Menu_Item *m); +// FL_EXPORT Fl_Menu_Item* picked(const Fl_Menu_Item* v); +}; + +#endif + +// +// End of "$Id: Fl_Sys_Menu_Bar.H,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// diff --git a/FL/mac.H b/FL/mac.H new file mode 100644 index 000000000..4aa179947 --- /dev/null +++ b/FL/mac.H @@ -0,0 +1,125 @@ +// +// "$Id: mac.H,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// Mac header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +// Do not directly include this file, instead use <FL/x.H>. It will +// include this file if "__APPLE__" is defined. This is to encourage +// portability of even the system-specific code... + + +#ifndef FL_MAC_H +# define FL_MAC_H + +// Standard MacOS Carbon API includes... +# include <Carbon/Carbon.h> + +// Now make some fixes to the headers... +# undef check // Dunno where this comes from... + +// Some random X equivalents +typedef WindowPtr Window; +struct XPoint { int x, y; }; +struct XRectangle {int x, y, width, height;}; +typedef RgnHandle Fl_Region; +void fl_clip_region(Fl_Region); +inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { + Fl_Region R = NewRgn(); + SetRectRgn(R, x, y, x+w, y+h); + return R; +} +inline void XDestroyRegion(Fl_Region r) { + DisposeRgn(r); +} + +# define XDestroyWindow(a,b) DisposeWindow(b) +# define XMapWindow(a,b) ShowWindow(b) +# define XUnmapWindow(a,b) HideWindow(b) + +# include "Fl_Window.H" + +// This object contains all mac-specific stuff about a window: +// WARNING: this object is highly subject to change! +class Fl_X +{ +public: + Window xid; // Mac WindowPtr + GWorldPtr other_xid; // pointer for offscreen bitmaps (doublebuffer) + Fl_Window *w; // FLTK window for + Fl_Region region; + Fl_Region subRegion; // region for this specific subwindow + Fl_X *next; + Fl_X *xidChildren, *xidNext; + int wait_for_expose; + //+ int backbuffer_bad; + CursHandle cursor; + static Fl_X* first; + static Fl_X* i(const Fl_Window* w) {return w->i;} + static int fake_X_wm(const Fl_Window*,int&,int&,int&,int&,int&); + static void make(Fl_Window*); + static void MacGrowWindow(WindowPtr xid, const EventRecord &macevent); + static void MacDragWindow(WindowPtr xid, const EventRecord &macevent); + static int MacModifiers(const EventRecord &macevent, unsigned short prev); + void flush(); +}; + +inline Window fl_xid(const Fl_Window*w) +{ + return Fl_X::i(w)->xid; +} + +extern CursHandle fl_default_cursor; + +extern struct Fl_XMap { + RGBColor rgb; + ulong pen; +} *fl_current_xmap; + +extern FL_EXPORT void *fl_display; //++ read yourself into multiple screen support! +extern FL_EXPORT Window fl_window; +extern FL_EXPORT Handle fl_system_menu; +extern FL_EXPORT class Fl_Sys_Menu_Bar *fl_sys_menu_bar; + +typedef GWorldPtr Fl_Offscreen; + +extern Fl_Offscreen fl_create_offscreen(int w, int h); +extern void fl_copy_offscreen(int x,int y,int w,int h, Fl_Offscreen gWorld, int srcx,int srcy); +extern void fl_delete_offscreen(Fl_Offscreen gWorld); +extern void fl_begin_offscreen(Fl_Offscreen gWorld); +extern void fl_end_offscreen(); + +typedef GrafPtr Fl_Bitmask; + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +extern void fl_open_display(); + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); + +#endif // !FL_MAC_H + +// +// End of "$Id: mac.H,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// + diff --git a/FL/win32.H b/FL/win32.H index 5927dccb1..3c6b8955f 100644 --- a/FL/win32.H +++ b/FL/win32.H @@ -1,5 +1,5 @@ // -// "$Id: win32.H,v 1.15.2.3.2.2 2001/11/19 20:59:59 easysw Exp $" +// "$Id: win32.H,v 1.15.2.3.2.3 2001/11/27 17:44:06 easysw Exp $" // // WIN32 header file for the Fast Light Tool Kit (FLTK). // @@ -42,13 +42,13 @@ typedef HWND Window; typedef POINT XPoint; struct XRectangle {int x, y, width, height;}; -typedef HRGN Region; -FL_EXPORT void fl_clip_region(Region); -inline Region XRectangleRegion(int x, int y, int w, int h) { +typedef HRGN Fl_Region; +FL_EXPORT void fl_clip_region(Fl_Region); +inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { return CreateRectRgn(x,y,x+w,y+h); } -inline void XDestroyRegion(Region r) {DeleteObject(r);} -inline void XClipBox(Region r,XRectangle* rect) { +inline void XDestroyRegion(Fl_Region r) {DeleteObject(r);} +inline void XClipBox(Fl_Region r,XRectangle* rect) { RECT win_rect; GetRgnBox(r,&win_rect); rect->x=win_rect.left; rect->y=win_rect.top; @@ -67,7 +67,7 @@ public: Window xid; HBITMAP other_xid; // for double-buffered windows Fl_Window* w; - Region region; + Fl_Region region; Fl_X *next; int wait_for_expose; HDC private_dc; // used for OpenGL @@ -129,5 +129,5 @@ extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); // -// End of "$Id: win32.H,v 1.15.2.3.2.2 2001/11/19 20:59:59 easysw Exp $". +// End of "$Id: win32.H,v 1.15.2.3.2.3 2001/11/27 17:44:06 easysw Exp $". // @@ -1,5 +1,5 @@ // -// "$Id: x.H,v 1.10.2.8.2.1 2001/11/18 20:52:27 easysw Exp $" +// "$Id: x.H,v 1.10.2.8.2.2 2001/11/27 17:44:06 easysw Exp $" // // X11 header file for the Fast Light Tool Kit (FLTK). // @@ -29,26 +29,28 @@ // systems. #ifndef Fl_X_H -#define Fl_X_H - -#include "Enumerations.H" - -#ifdef WIN32 - -#include "win32.H" - -#else - -#if defined(_ABIN32) || defined(_ABI64) // fix for broken SGI Irix X .h files -#pragma set woff 3322 -#endif -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#if defined(_ABIN32) || defined(_ABI64) -#pragma reset woff 3322 -#endif -#include <X11/Xatom.h> -#include "Fl_Window.H" +# define Fl_X_H + +# include "Enumerations.H" + +# ifdef WIN32 +# include "win32.H" +# elif defined(__APPLE__) +# include "mac.H" +# else +# if defined(_ABIN32) || defined(_ABI64) // fix for broken SGI Irix X .h files +# pragma set woff 3322 +# endif +# include <X11/Xlib.h> +# include <X11/Xutil.h> +# if defined(_ABIN32) || defined(_ABI64) +# pragma reset woff 3322 +# endif +# include <X11/Xatom.h> +# include "Fl_Window.H" + +// Mirror X definition of Region to Fl_Region, for portability... +typedef Region Fl_Region FL_EXPORT void fl_open_display(); FL_EXPORT void fl_open_display(Display*); @@ -66,8 +68,8 @@ extern FL_EXPORT Window fl_window; extern FL_EXPORT XFontStruct* fl_xfont; FL_EXPORT ulong fl_xpixel(Fl_Color i); FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b); -FL_EXPORT void fl_clip_region(Region); -FL_EXPORT Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx +FL_EXPORT void fl_clip_region(Fl_Region); +FL_EXPORT Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx // feed events into fltk: FL_EXPORT int fl_handle(const XEvent&); @@ -81,14 +83,14 @@ typedef ulong Fl_Offscreen; #define fl_create_offscreen(w,h) \ XCreatePixmap(fl_display, fl_window, w, h, fl_visual->depth) // begin/end are macros that save the old state in local variables: -#define fl_begin_offscreen(pixmap) \ +# define fl_begin_offscreen(pixmap) \ Window _sw=fl_window; fl_window=pixmap; fl_push_no_clip() -#define fl_end_offscreen() \ +# define fl_end_offscreen() \ fl_pop_clip(); fl_window = _sw -#define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \ +# define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \ XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y) -#define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap) +# define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap) // Bitmap masks typedef ulong Fl_Bitmask; @@ -104,7 +106,7 @@ public: Window xid; Window other_xid; Fl_Window *w; - Region region; + Fl_Region region; Fl_X *next; char wait_for_expose; char backbuffer_bad; // used for XDBE @@ -127,9 +129,9 @@ FL_EXPORT Fl_Window* fl_find(Window xid); extern FL_EXPORT char fl_override_redirect; // hack into Fl_X::make_xid() extern FL_EXPORT int fl_background_pixel; // hack into Fl_X::make_xid() -#endif +# endif #endif // -// End of "$Id: x.H,v 1.10.2.8.2.1 2001/11/18 20:52:27 easysw Exp $". +// End of "$Id: x.H,v 1.10.2.8.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/configure.in b/configure.in index 022db43c5..8ae0da43d 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl -*- sh -*- dnl the "configure" script is made from this by running GNU "autoconf" dnl -dnl "$Id: configure.in,v 1.33.2.31.2.26 2001/11/22 13:56:10 easysw Exp $" +dnl "$Id: configure.in,v 1.33.2.31.2.27 2001/11/27 17:44:05 easysw Exp $" dnl dnl Configuration script for the Fast Light Tool Kit (FLTK). dnl @@ -219,6 +219,7 @@ AC_CHECK_HEADER(png.h, dnl Restore original LIBS settings... LIBS="$SAVELIBS" +dnl Check for standard graphics API and OpenGL... EXEEXT= HLINKS= @@ -244,6 +245,20 @@ case $uname in GLDEMOS="" fi ;; + Darwin*) + # MacOS X uses Carbon for graphics... + LIBS="$LIBS -framework Carbon -framework ApplicationServices" + if test x$enable_gl != xno; then + AC_DEFINE(HAVE_GL); + AC_DEFINE(HAVE_GL_GLU_H); + GLLIB="-framework OpenGL" + else + LINKFLTKGL="" + GLLIBNAME="" + GLDSONAME="" + GLDEMOS="" + fi + ;; *) dnl Check for X11... AC_PATH_XTRA @@ -311,11 +326,6 @@ case $uname in else ac_cv_have_overlay=no fi) - - if test x$ac_cv_have_overlay = xyes; then - AC_DEFINE(HAVE_OVERLAY) - fi - ;; esac AC_SUBST(EXEEXT) @@ -325,7 +335,7 @@ AC_SUBST(GLLIB) dnl Figure out the appropriate formatted man page extension... case "$uname" in - FreeBSD* | NetBSD* | OpenBSD*) + *BSD* | Darwin*) # *BSD CAT1EXT=0 CAT3EXT=0 @@ -349,7 +359,7 @@ dnl Fix "mandir" variable... if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"; then case "$uname" in *BSD* | Darwin* | Linux*) - # *BSD + # *BSD, Darwin, and Linux mandir="\${prefix}/share/man" ;; IRIX*) @@ -532,5 +542,5 @@ AC_OUTPUT(makeinclude fltk-config FL/Makefile) chmod +x fltk-config dnl -dnl End of "$Id: configure.in,v 1.33.2.31.2.26 2001/11/22 13:56:10 easysw Exp $". +dnl End of "$Id: configure.in,v 1.33.2.31.2.27 2001/11/27 17:44:05 easysw Exp $". dnl diff --git a/src/Fl.cxx b/src/Fl.cxx index 0c6d31b0d..4189ea792 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl.cxx,v 1.24.2.41.2.7 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl.cxx,v 1.24.2.41.2.8 2001/11/27 17:44:06 easysw Exp $" // // Main event handling code for the Fast Light Tool Kit (FLTK). // @@ -86,7 +86,7 @@ struct Timeout { static Timeout* first_timeout, *free_timeout; #ifndef WIN32 -#include <sys/time.h> +# include <sys/time.h> #endif // I avoid the overhead of getting the current time when we have no @@ -299,7 +299,11 @@ Fl_X* Fl_X::first; Fl_Window* fl_find(Window xid) { Fl_X *window; for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) +#ifdef __APPLE__ + if (window->xid == xid && !window->w->window()) { +#else if (window->xid == xid) { +#endif // __APPLE__ if (window != Fl_X::first && !Fl::modal()) { // make this window be first to speed up searches // this is not done if modal is true to avoid messing up modal stack @@ -343,9 +347,10 @@ void Fl::flush() { if (x->region) {XDestroyRegion(x->region); x->region = 0;} } } + #ifdef WIN32 GdiFlush(); -#else +#elif !defined(__APPLE__) if (fl_display) XFlush(fl_display); #endif } @@ -630,6 +635,16 @@ void Fl_Window::hide() { Fl_X** pp = &Fl_X::first; for (; *pp != x; pp = &(*pp)->next) if (!*pp) return; *pp = x->next; + +#ifdef __APPLE__ + // remove all childwindow links + for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next ) + { + if ( pc->xidNext == x ) pc->xidNext = x->xidNext; + if ( pc->xidChildren == x ) pc->xidChildren = x->xidNext; + } +#endif // __APPLE__ + i = 0; // recursively remove any subwindows: @@ -660,6 +675,9 @@ void Fl_Window::hide() { fl_window = (HWND)-1; fl_gc = 0; } +#elif defined(__APPLE__) + //++ MacOS needs a simulation of focus events?! DONT! + Fl::handle(FL_UNFOCUS, this); #else if (x->region) XDestroyRegion(x->region); #endif @@ -770,14 +788,19 @@ void Fl_Widget::damage(uchar flags, int X, int Y, int W, int H) { if (window->damage()) { // if we already have damage we must merge with existing region: if (i->region) { -#ifndef WIN32 - XRectangle R; - R.x = X; R.y = Y; R.width = W; R.height = H; - XUnionRectWithRegion(&R, i->region, i->region); -#else +#ifdef WIN32 Region R = XRectangleRegion(X, Y, W, H); CombineRgn(i->region, i->region, R, RGN_OR); XDestroyRegion(R); +#elif defined(__APPLE__) + Fl_Region R = NewRgn(); + SetRectRgn(R, X, Y, X+W, Y+H); + UnionRgn(R, i->region, i->region); + DisposeRgn(R); +#else + XRectangle R; + R.x = X; R.y = Y; R.width = W; R.height = H; + XUnionRectWithRegion(&R, i->region, i->region); #endif } window->damage_ |= flags; @@ -798,5 +821,5 @@ void Fl_Window::flush() { } // -// End of "$Id: Fl.cxx,v 1.24.2.41.2.7 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl.cxx,v 1.24.2.41.2.8 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Bitmap.cxx b/src/Fl_Bitmap.cxx index f57f35256..272067ddf 100644 --- a/src/Fl_Bitmap.cxx +++ b/src/Fl_Bitmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.6 2001/11/24 02:46:19 easysw Exp $" +// "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.7 2001/11/27 17:44:06 easysw Exp $" // // Bitmap drawing routines for the Fast Light Tool Kit (FLTK). // @@ -31,7 +31,54 @@ #include <FL/Fl_Bitmap.H> #include <string.h> -#ifdef WIN32 // Windows bitmask functions... +#ifdef __APPLE__ // MacOS bitmask functions +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { + Rect srcRect; + RgnHandle r = NewRgn(); + srcRect.left = 0; srcRect.right = w; + srcRect.top = 0; srcRect.bottom = h; + GrafPtr savePort; + GrafPtr newPort; + + GetPort(&savePort); // remember the current port + + newPort = CreateNewPort(); + + SetPortBounds(newPort, &srcRect); // make bitmap the size of the bounds that caller supplied + RectRgn( GetPortClipRegion(newPort, r), &srcRect ); + RectRgn( GetPortVisibleRegion(newPort, r), &srcRect ); + DisposeRgn(r); + + //++ rowBytes is size of row, it must be rounded up to an even number of bytes +// int rowBytes = newPort->portBits.rowBytes = (( w + 15 ) >> 4 ) << 1; +// int rowBytesSrc = (( w + 7 ) >> 3 ); +// newPort->portBits.baseAddr = NewPtr( rowBytes * h ); +// if ( !newPort->portBits.baseAddr ) +// { +// SetPort(savePort); +// ClosePort(newPort); +// DisposePtr((Ptr)newPort); +// return 0L; +// } +// +// static uchar reverse[16] = /* Bit reversal lookup table */ +// { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, +// 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; +// uchar *dst = (uchar*)newPort->portBits.baseAddr; +// const uchar *src = array; +// int rowPatch = ( rowBytes!=rowBytesSrc ) ? 1 : 0 ; +// for ( int j=0; j<h; j++,dst+=rowPatch ) +// for ( int i=0; i<rowBytesSrc; i++,src++ ) +// *dst++ = (reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f); + + SetPort(savePort); + return newPort; /* tell caller we succeeded! */ +} + +void fl_delete_bitmask(Fl_Bitmask id) { + if (id) DisposePort(id); +} +#elif defined(WIN32) // Windows bitmask functions... // 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing... static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) { // we need to pad the lines out to words & swap the bits @@ -158,7 +205,7 @@ Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { void fl_delete_bitmask(Fl_Bitmask bm) { fl_delete_offscreen((Fl_Offscreen)bm); } -#endif // WIN32 +#endif // __APPLE__ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { if (!array) { @@ -185,6 +232,20 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { // secret bitblt code found in old MSWindows reference manual: BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); DeleteDC(tempdc); +#elif defined(__APPLE__) + if (!id) id = fl_create_bitmask(w(), h(), array); + GrafPtr dstPort; + GetPort( &dstPort ); + Rect dst; + dst.left = X; dst.right = X+W; + dst.top = Y; dst.bottom = Y+H; + CopyBits( + GetPortBitMapForCopyBits((GrafPtr)id), + GetPortBitMapForCopyBits(dstPort), + GetPortBounds((GrafPtr)id, 0), + &dst, + srcOr, + 0L); #else if (!id) id = fl_create_bitmask(w(), h(), array); @@ -277,6 +338,7 @@ Fl_Image *Fl_Bitmap::copy(int W, int H) { return new_image; } + // -// End of "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.6 2001/11/24 02:46:19 easysw Exp $". +// End of "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.7 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx index dd60ba903..6e2a741bc 100644 --- a/src/Fl_Double_Window.cxx +++ b/src/Fl_Double_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Double_Window.cxx,v 1.12.2.4 2001/01/22 15:13:39 easysw Exp $" +// "$Id: Fl_Double_Window.cxx,v 1.12.2.4.2.1 2001/11/27 17:44:06 easysw Exp $" // // Double-buffered window code for the Fast Light Tool Kit (FLTK). // @@ -59,7 +59,7 @@ static int can_xdbe() { #endif void Fl_Double_Window::show() { -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) if (!shown()) { // don't set the background pixel fl_open_display(); Fl_X::make_xid(this); @@ -94,6 +94,82 @@ void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) extern void fl_restore_clip(); +#elif defined(__APPLE__) + +/** + * Mac: + */ +GWorldPtr fl_create_offscreen(int w, int h) { + GWorldPtr gw; + Rect bounds; + bounds.left=0; bounds.right=w; bounds.top=0; bounds.bottom=h; + QDErr err = NewGWorld(&gw, 0, &bounds, 0L, 0L, useTempMem); + if ( err == -108 ) + { } +// fl_message( "The application memory is low. Please increase the initial memory assignment.\n" ); + if (err!=noErr || gw==0L) return 0L; + return gw; +} + +/** + * Mac: + */ +void fl_copy_offscreen(int x,int y,int w,int h,GWorldPtr gWorld,int srcx,int srcy) { + Rect src; + src.top = srcy; src.left = srcx; src.bottom = srcy+h; src.right = srcx+w; + Rect dst; + GrafPtr dstPort; GetPort(&dstPort); + dst.top = y; dst.left = x; dst.bottom = y+h; dst.right = x+w; + RGBColor rgb; + rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; + RGBBackColor( &rgb ); + rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; + RGBForeColor( &rgb ); + CopyBits(GetPortBitMapForCopyBits(gWorld), GetPortBitMapForCopyBits(dstPort), &src, &dst, srcCopy, 0L); +} + +/** + * Mac: + */ +void fl_delete_offscreen(GWorldPtr gWorld) { + DisposeGWorld(gWorld); +} + +static GrafPtr prevPort; +static GDHandle prevGD; + +/** + * Mac: + */ +void fl_begin_offscreen(GWorldPtr gWorld) { + GetGWorld( &prevPort, &prevGD ); + if ( gWorld ) + { + SetGWorld( gWorld, 0L ); + PixMapHandle pm = GetGWorldPixMap(gWorld); + LockPixels(pm); + fl_window = (Window)prevPort; + SetPort( (GrafPtr)fl_window ); + } + fl_push_no_clip(); +} + +/** + * Mac: + */ +void fl_end_offscreen() { + GWorldPtr currPort; + GDHandle currGD; + GetGWorld( &currPort, &currGD ); + fl_pop_clip(); + PixMapHandle pm = GetGWorldPixMap(currPort); + UnlockPixels(pm); + fl_window = (Window)prevPort; + SetGWorld( prevPort, prevGD ); +} + +extern void fl_restore_clip(); + #endif // Fl_Overlay_Window relies on flush(1) copying the back buffer to the @@ -149,6 +225,13 @@ void Fl_Double_Window::flush(int eraseoverlay) { draw(); DeleteDC(fl_gc); fl_gc = _sgc; +#elif defined(__APPLE__) + if ( myi->other_xid ) fl_begin_offscreen( myi->other_xid ); + fl_restore_clip(); // duplicate region into new gc + draw(); + if ( myi->other_xid ) fl_end_offscreen(); + } else { + fl_clip_region( 0 ); #else // X: fl_window = myi->other_xid; draw(); @@ -192,5 +275,5 @@ Fl_Double_Window::~Fl_Double_Window() { } // -// End of "$Id: Fl_Double_Window.cxx,v 1.12.2.4 2001/01/22 15:13:39 easysw Exp $". +// End of "$Id: Fl_Double_Window.cxx,v 1.12.2.4.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Font.H b/src/Fl_Font.H index 425d00dc3..3652c4a1e 100644 --- a/src/Fl_Font.H +++ b/src/Fl_Font.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Font.H,v 1.6.2.3 2001/01/22 15:13:39 easysw Exp $" +// "$Id: Fl_Font.H,v 1.6.2.3.2.1 2001/11/27 17:44:06 easysw Exp $" // // Font definitions for the Fast Light Tool Kit (FLTK). // @@ -39,14 +39,20 @@ class Fl_FontSize { public: Fl_FontSize *next; // linked list for this Fl_Fontdesc -#ifndef WIN32 - XFontStruct* font; // X font information - FL_EXPORT Fl_FontSize(const char* xfontname); -#else +#ifdef WIN32 HFONT fid; int width[256]; TEXTMETRIC metr; FL_EXPORT Fl_FontSize(const char* fontname, int size); +#elif defined(__APPLE__) + FL_EXPORT Fl_FontSize(const char* fontname, int size); + short font, face, size; + short ascent, descent; + short width[256]; + bool knowMetrics; +#else + XFontStruct* font; // X font information + FL_EXPORT Fl_FontSize(const char* xfontname); #endif int minsize; // smallest point size that should use this int maxsize; // largest point size that should use this @@ -78,5 +84,5 @@ FL_EXPORT char *fl_find_fontsize(char *name); #endif // -// End of "$Id: Fl_Font.H,v 1.6.2.3 2001/01/22 15:13:39 easysw Exp $". +// End of "$Id: Fl_Font.H,v 1.6.2.3.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Gl_Choice.H b/src/Fl_Gl_Choice.H index 2fd10c967..82dad8f20 100644 --- a/src/Fl_Gl_Choice.H +++ b/src/Fl_Gl_Choice.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.H,v 1.4.2.6 2001/03/14 17:20:01 spitzak Exp $" +// "$Id: Fl_Gl_Choice.H,v 1.4.2.6.2.1 2001/11/27 17:44:06 easysw Exp $" // // OpenGL definitions for the Fast Light Tool Kit (FLTK). // @@ -55,11 +55,14 @@ // Warning: whatever GLContext is defined to must take exactly the same // space in a structure as a void*!!! #ifdef WIN32 -# include <FL/gl.h> -# define GLContext HGLRC +# include <FL/gl.h> +# define GLContext HGLRC +#elif defined(__APPLE__) +# include <OpenGL.h> +# define GLContext CGLContextObj #else -# include <GL/glx.h> -# define GLContext GLXContext +# include <GL/glx.h> +# define GLContext GLXContext #endif // Describes crap needed to create a GLContext. @@ -71,6 +74,8 @@ public: #ifdef WIN32 int pixelformat; // the visual to use PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing +#elif defined(__APPLE__) + //++ #else XVisualInfo *vis; // the visual to use Colormap colormap; // a colormap for that visual @@ -87,6 +92,10 @@ class Fl_Window; GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); +#elif defined(__APPLE__) + +//++ + #else GLContext fl_create_gl_context(XVisualInfo* vis); @@ -105,5 +114,5 @@ void fl_delete_gl_context(GLContext); #endif // -// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.6 2001/03/14 17:20:01 spitzak Exp $". +// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.6.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx index ca485b2a5..fe5d702b0 100644 --- a/src/Fl_Gl_Choice.cxx +++ b/src/Fl_Gl_Choice.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.7.2.1 2001/11/17 18:29:05 easysw Exp $" +// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.7.2.2 2001/11/27 17:44:06 easysw Exp $" // // OpenGL visual selection code for the Fast Light Tool Kit (FLTK). // @@ -43,7 +43,11 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) { if (g->mode == mode && g->alist == alist) return g; -#ifndef WIN32 +#ifdef __APPLE__ + + //++ later + +#elif !defined(WIN32) const int *blist; int list[32]; @@ -142,6 +146,8 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) { #ifdef WIN32 g->pixelformat = pixelformat; g->pfd = chosen_pfd; +#elif defined(__APPLE__) + //++ later #else g->vis = vis; @@ -180,6 +186,27 @@ GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int lay return context; } +#elif defined(__APPLE__) +GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { + GLContext context; + GLint attrib[5] = {AGL_RGBA, //++ replace with requested data! + AGL_DOUBLEBUFFER, + AGL_DEPTH_SIZE, 16, + AGL_NONE }; + AGLPixelFormat fmt; + fmt = aglChoosePixelFormat(NULL, 0, attrib); + context = aglCreateContext(fmt, fl_first_context); + if ( !fl_first_context ) fl_first_context = (GLXContext)context; + aglDestroyPixelFormat( fmt ); + if ( parent() ) { + CGrafPort *port = (CGrafPort*)fl_xid(this); + GLint rect[] = { x(), port->portRect.bottom-h()-y(), w(), h() }; + aglSetInteger( (GLXContext)context, AGL_BUFFER_RECT, rect ); + aglEnable( (GLXContext)context, AGL_BUFFER_RECT ); + } + aglSetDrawable((GLXContext)context, (CGrafPort*)fl_xid(window)); + return (context); +} #else GLContext fl_create_gl_context(XVisualInfo* vis) { @@ -199,6 +226,15 @@ void fl_set_gl_context(Fl_Window* w, GLContext context) { cached_window = w; #ifdef WIN32 wglMakeCurrent(Fl_X::i(w)->private_dc, context); +#elif defined(__APPLE__) + if ( w->parent() ) { //: resize our GL buffer rectangle + CGrafPort *port = (CGrafPort*)fl_xid(w); + GLint rect[] = { w->x(), port->portRect.bottom-w->h()-w->y(), w->w(), w->h() }; + aglSetInteger( c, AGL_BUFFER_RECT, rect ); + aglEnable( c, AGL_BUFFER_RECT ); + } + aglSetDrawable(c, (CGrafPort*)fl_xid(w)); //++ here or in Fl_Gl_Window::make_current creation part? + aglSetCurrentContext(c); #else glXMakeCurrent(fl_display, fl_xid(w), context); #endif @@ -210,6 +246,8 @@ void fl_no_gl_context() { cached_window = 0; #ifdef WIN32 wglMakeCurrent(0, 0); +#elif defined(__APPLE__) + aglSetCurrentContext(0); #else glXMakeCurrent(fl_display, 0, 0); #endif @@ -220,6 +258,10 @@ void fl_delete_gl_context(GLContext context) { if (context != first_context) { #ifdef WIN32 wglDeleteContext(context); +#elif defined(__APPLE) + aglSetCurrentContext(NULL); + aglSetDrawable((AGLContext)context, NULL); + aglDestroyContext((AGLContext)context); #else glXDestroyContext(fl_display, context); #endif @@ -229,5 +271,5 @@ void fl_delete_gl_context(GLContext context) { #endif // -// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.7.2.1 2001/11/17 18:29:05 easysw Exp $". +// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.7.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index 690e78783..9e185ccf3 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Window.cxx,v 1.12.2.22 2001/07/18 08:11:02 spitzak Exp $" +// "$Id: Fl_Gl_Window.cxx,v 1.12.2.22.2.1 2001/11/27 17:44:06 easysw Exp $" // // OpenGL window code for the Fast Light Tool Kit (FLTK). // @@ -68,7 +68,7 @@ void Fl_Gl_Window::show() { g = Fl_Gl_Choice::find(mode_,alist); if (!g) {Fl::error("Insufficient GL support"); return;} } -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) Fl_X::make_xid(this, g->vis, g->colormap); if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show(); #endif @@ -85,7 +85,7 @@ void Fl_Gl_Window::invalidate() { int Fl_Gl_Window::mode(int m, const int *a) { if (m == mode_ && a == alist) return 0; -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) int oldmode = mode_; Fl_Gl_Choice* oldg = g; #endif @@ -93,7 +93,7 @@ int Fl_Gl_Window::mode(int m, const int *a) { mode_ = m; alist = a; if (shown()) { g = Fl_Gl_Choice::find(m, a); -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) // under X, if the visual changes we must make a new X window (yuck!): if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) { hide(); @@ -142,12 +142,14 @@ void Fl_Gl_Window::ortho() { void Fl_Gl_Window::swap_buffers() { #ifdef WIN32 -#if HAVE_GL_OVERLAY +# if HAVE_GL_OVERLAY // Do not swap the overlay, to match GLX: wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE); -#else +# else SwapBuffers(Fl_X::i(this)->private_dc); -#endif +# endif +#elif defined(__APPLE__) + aglSwapBuffers((AGLContext)context_); #else glXSwapBuffers(fl_display, fl_xid(this)); #endif @@ -191,6 +193,12 @@ void Fl_Gl_Window::flush() { } #endif +#ifdef __APPLE__ + //: clear previous clipping in this shared port + CGrafPort *port = (CGrafPort*)fl_xid(this); + SetRectRgn( port->clipRgn, 0, 0, 0x7fff, 0x7fff ); +#endif + make_current(); if (mode_ & FL_DOUBLE) { @@ -279,7 +287,14 @@ void Fl_Gl_Window::flush() { void Fl_Gl_Window::resize(int X,int Y,int W,int H) { if (W != w() || H != h()) { valid(0); -#ifndef WIN32 +#ifdef __APPLE__ + if ( parent() ) { //: resize our GL buffer rectangle + CGrafPort *port = (CGrafPort*)fl_xid(this); + GLint rect[] = { X, port->portRect.bottom-h()-y(), W, H }; + aglSetInteger( (GLXContext)context_, AGL_BUFFER_RECT, rect ); + aglEnable( (GLXContext)context_, AGL_BUFFER_RECT ); + } +#elif !defined(WIN32) if (!resizable() && overlay && overlay != this) ((Fl_Gl_Window*)overlay)->resize(0,0,W,H); #endif @@ -325,5 +340,5 @@ void Fl_Gl_Window::draw_overlay() {} #endif // -// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.22 2001/07/18 08:11:02 spitzak Exp $". +// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.22.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx index 8e227200b..7fc8857a5 100644 --- a/src/Fl_Image.cxx +++ b/src/Fl_Image.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Image.cxx,v 1.5.2.3.2.10 2001/11/26 18:56:26 easysw Exp $" +// "$Id: Fl_Image.cxx,v 1.5.2.3.2.11 2001/11/27 17:44:06 easysw Exp $" // // Image drawing code for the Fast Light Tool Kit (FLTK). // @@ -333,6 +333,9 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { } else { fl_copy_offscreen(X, Y, W, H, id, cx, cy); } +#elif defined(__APPLE__) + //+ Need to implement masking/alpha blend!!! + fl_copy_offscreen(X, Y, W, H, id, cx, cy); #else if (mask) { // I can't figure out how to combine a mask with existing region, @@ -364,5 +367,5 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) { // -// End of "$Id: Fl_Image.cxx,v 1.5.2.3.2.10 2001/11/26 18:56:26 easysw Exp $". +// End of "$Id: Fl_Image.cxx,v 1.5.2.3.2.11 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx index bf6e984d7..aac769590 100644 --- a/src/Fl_Pixmap.cxx +++ b/src/Fl_Pixmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.9 2001/11/24 02:46:19 easysw Exp $" +// "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.10 2001/11/27 17:44:06 easysw Exp $" // // Pixmap drawing code for the Fast Light Tool Kit (FLTK). // @@ -104,6 +104,29 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { } else { fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); } +#elif defined(__APPLE__) + if ( mask ) + { + Rect src, dst; + src.left = 0; src.right = w(); + src.top = 0; src.bottom = h(); + dst.left = X; dst.right = X+w(); + dst.top = Y; dst.bottom = Y+h(); + RGBColor rgb; + rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; + RGBBackColor( &rgb ); + rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; + RGBForeColor( &rgb ); + CopyMask( + GetPortBitMapForCopyBits((GrafPtr)id), + GetPortBitMapForCopyBits((GrafPtr)mask), + GetPortBitMapForCopyBits((GrafPtr)fl_window), + &src, &src, &dst); + } + else + { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); + } #else if (mask) { // I can't figure out how to combine a mask with existing region, @@ -342,7 +365,7 @@ void Fl_Pixmap::color_average(Fl_Color c, float i) { while (*p && !isspace(*p)) p++; } -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) if (fl_parse_color(p, r, g, b)) { #else XColor x; @@ -437,7 +460,7 @@ void Fl_Pixmap::desaturate() { while (*p && !isspace(*p)) p++; } -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) if (fl_parse_color(p, r, g, b)) { #else XColor x; @@ -462,5 +485,5 @@ void Fl_Pixmap::desaturate() { } // -// End of "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.9 2001/11/24 02:46:19 easysw Exp $". +// End of "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.10 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Scrollbar.cxx b/src/Fl_Scrollbar.cxx index d0779cc92..30121530e 100644 --- a/src/Fl_Scrollbar.cxx +++ b/src/Fl_Scrollbar.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scrollbar.cxx,v 1.7.2.14.2.4 2001/11/03 19:24:22 easysw Exp $" +// "$Id: Fl_Scrollbar.cxx,v 1.7.2.14.2.5 2001/11/27 17:44:06 easysw Exp $" // // Scroll bar widget for the Fast Light Tool Kit (FLTK). // @@ -125,7 +125,7 @@ int Fl_Scrollbar::handle(int event) { return Fl_Slider::handle(event, X,Y,W,H); case FL_MOUSEWHEEL : if (horizontal()) return 0; - handle_drag(clamp(value() + 3 * linesize_ * Fl::e_dy)); + handle_drag(clamp(value() + linesize_ * Fl::e_dy)); return 1; case FL_FOCUS : case FL_UNFOCUS : @@ -246,5 +246,5 @@ Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L) } // -// End of "$Id: Fl_Scrollbar.cxx,v 1.7.2.14.2.4 2001/11/03 19:24:22 easysw Exp $". +// End of "$Id: Fl_Scrollbar.cxx,v 1.7.2.14.2.5 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Sys_Menu_Bar.cxx b/src/Fl_Sys_Menu_Bar.cxx new file mode 100644 index 000000000..399b22c61 --- /dev/null +++ b/src/Fl_Sys_Menu_Bar.cxx @@ -0,0 +1,314 @@ +// +// "$Id: Fl_Sys_Menu_Bar.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +/** + * Tis code is a quick hack! It was written as a proove of concept. + * It has been tested on the "menubar" sample program and provides + * basic functionality. + * + * To use the System Menu Bar, simply replace the main Fl_Menu_Bar + * in an application with Fl_Sys_Menu_Bar. + * + * FLTK features not supported by the Mac System menu + * + * - no invisible menu items + * - no sybolic labels + * - embossed labels will be underlined instead + * - no font sizes + * - Shortcut Characters should be English alphanumeric only, no modifiers yet + * - no disable main menus + * - changes to menubar in run-time don't update! + * (disable, etc. - toggle and readio button do!) + * + * No care was taken to clean up the menu bar after destruction! + * ::menu(bar) should only be called once! + * Many other calls of the parent class don't work. + * Changing the menu items has no effect on the menu bar. + */ + +#include <FL/X.H> +#include <FL/Fl.H> +#include <FL/Fl_Sys_Menu_Bar.H> + +#include <string.h> +#include <stdio.h> +#include <ctype.h> + +typedef const Fl_Menu_Item *pFl_Menu_Item; + +/** + * copy the text of a menuitem into a buffer. + * Skip all '&' which would mark the shortcut in FLTK + * Skip all Mac control characters ('(', '<', ';', '^', '!' ) + */ +static void catMenuText( const char *src, char *dst ) +{ + char c; + while ( *dst ) + dst++; + if ( *src == '-' ) + src++; + while ( ( c = *src++ ) ) + { + if ( !strchr( "&(<;^!", c ) ) + *dst++ = c; + } + *dst = 0; +} + +/** + * append a marker to identify the menu font style + * <B, I, U, O, and S + */ +static void catMenuFont( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->labeltype_ && !m->labelfont_ ) + return; + while ( *dst ) + dst++; + + if ( m->labelfont_ & FL_BOLD ) + strcat( dst, "<B" ); + if ( m->labelfont_ & FL_ITALIC ) + strcat( dst, "<I" ); + //if ( m->labelfont_ & FL_UNDERLINE ) + // strcat( dst, "<U" ); + + if ( m->labeltype_ == FL_EMBOSSED_LABEL ) + strcat( dst, "<U" ); + else if ( m->labeltype_ == FL_ENGRAVED_LABEL ) + strcat( dst, "<O" ); + else if ( m->labeltype_ == FL_SHADOW_LABEL ) + strcat( dst, "<S" ); + //else if ( m->labeltype_ == FL_SYMBOL_LABEL ) + ; // not supported +} + +/** + * append a marker to identify the menu shortcut + * <B, I, U, O, and S +enum { +ÊÊÊÊkMenuNoModifiersÊÊÊÊÊÊÊÊ= 0, +ÊÊÊÊkMenuShiftModifierÊÊÊÊÊÊ= (1 << 0), +ÊÊÊÊkMenuOptionModifierÊÊÊÊÊ= (1 << 1), +ÊÊÊÊkMenuControlModifierÊÊÊÊ= (1 << 2), +ÊÊÊÊkMenuNoCommandModifierÊÊ= (1 << 3) +}; + */ +static void setShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( !m->shortcut_ ) + return; + char key = m->shortcut_ & 0xff; + if ( !isalnum( key ) ) + return; + char mod = m->shortcut_ & 0xff00; + + long macMod = kMenuNoModifiers; + if ( mod & FL_SHIFT ) macMod |= kMenuShiftModifier; + if ( mod & FL_CTRL ) macMod |= kMenuOptionModifier; + if ( !(mod & FL_ALT) ) macMod |= kMenuNoCommandModifier; + + SetItemCmd( mh, miCnt, key ); + SetMenuItemModifiers( mh, miCnt, macMod ); +} + +static void catMenuShortcut( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->shortcut_ ) + return; + char c = m->shortcut_ & 0xff; + if ( !isalnum( c & 0xff ) ) + return; + while ( *dst ) + dst++; + if ( m->shortcut_ & FL_ALT ) + { + sprintf( dst, "/%c", toupper( c ) ); + } + //if ( isalnum( mm->shortcut_ ) && !( mm->flags & FL_SUBMENU ) ) + //sprintf( buf+strlen(buf), "/%c", mm->shortcut_ ); +} + +static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( m->flags & FL_MENU_TOGGLE ) + { + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + } + else if ( m->flags & FL_MENU_RADIO ) + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); +} + +static void catMenuFlags( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->flags ) + return; + while ( *dst ) + dst++; + if ( m->flags & FL_MENU_INACTIVE ) + strcat( dst, "(" ); +} + +/** + * create a sub menu for a specific menu handle + */ +static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm ) +{ + char buf[255]; + int miCnt = 1; + while ( mm->text ) + { + MenuHandle smh; + buf[1] = 0; + catMenuFont( mm, buf+1 ); + catMenuShortcut( mm, buf+1 ); + catMenuText( mm->text, buf+1 ); + catMenuFlags( mm, buf+1 ); + if ( mm->flags & (FL_SUBMENU | FL_SUBMENU_POINTER) ) + { + cnt++; + smh = NewMenu( cnt, (unsigned char*)"\001 " ); + sprintf( buf+1+strlen(buf+1), "/\033!%c", cnt ); + } + if ( mm->flags & FL_MENU_DIVIDER ) + strcat( buf+1, ";-" ); + buf[0] = strlen( buf+1 ); + AppendMenu( mh, (unsigned char*)buf ); + // insert Appearanc manager functions here! + setMenuFlags( mh, miCnt, mm ); + SetMenuItemRefCon( mh, miCnt, (UInt32)mm ); + miCnt++; + if ( mm->flags & FL_MENU_DIVIDER ) + miCnt++; + if ( mm->flags & FL_SUBMENU ) + { + createSubMenu( smh, cnt, ++mm ); + } + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( mh, cnt, smm ); + } + mm++; + } + InsertMenu( mh, -1 ); +} + + +/** + * create a system menu bar using the given list of menu structs + * + * \author Matthias Melcher + * + * @param m list of Fl_Menu_Item + */ +void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) +{ + fl_open_display(); + Fl_Menu_Bar::menu( m ); + fl_sys_menu_bar = this; + + char buf[255]; + int cnt = 1; // first menu is no 2. no 1 is the Apple Menu + + const Fl_Menu_Item *mm = m; + for (;;) + { + if ( !mm->text ) + break; + buf[1] = 0; + catMenuText( mm->text, buf+1 ); + buf[0] = strlen( buf+1 ); + MenuHandle mh = NewMenu( ++cnt, (unsigned char*)buf ); + if ( mm->flags & FL_SUBMENU ) + createSubMenu( mh, cnt, ++mm ); + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( mh, cnt, smm ); + } + + InsertMenu( mh, 0 ); + if ( mm->flags & FL_MENU_INACTIVE ) DisableItem( mh, 0 ); + mm++; + } + DrawMenuBar(); +} + +/* +const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) { + Fl_menu_Item *ret = Fl_Menu_Bar::picked( v ); + + if ( m->flags & FL_MENU_TOGGLE ) + { + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + } + + return ret; +} +*/ + +void Fl_Sys_Menu_Bar::draw() { +/* -- nothing to do, system should take care of this + draw_box(); + if (!menu() || !menu()->text) return; + const Fl_Menu_Item* m; + int X = x()+6; + for (m=menu(); m->text; m = m->next()) { + int W = m->measure(0,this) + 16; + m->draw(X, y(), W, h(), this); + X += W; + } + */ +} + +/* +int Fl_Menu_Bar::handle(int event) { + const Fl_Menu_Item* v; + if (menu() && menu()->text) switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_PUSH: + v = 0; + J1: + v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); + picked(v); + return 1; + case FL_SHORTCUT: + if (visible_r()) { + v = menu()->find_shortcut(); + if (v && v->submenu()) goto J1; + } + return test_shortcut() != 0; + } + return 0; +} +*/ + +// +// End of "$Id: Fl_Sys_Menu_Bar.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// diff --git a/src/Fl_Text_Editor.cxx b/src/Fl_Text_Editor.cxx index 6e79891e3..2a5f52720 100644 --- a/src/Fl_Text_Editor.cxx +++ b/src/Fl_Text_Editor.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Editor.cxx,v 1.9.2.1 2001/08/04 12:21:33 easysw Exp $" +// "$Id: Fl_Text_Editor.cxx,v 1.9.2.2 2001/11/27 17:44:06 easysw Exp $" // // Copyright Mark Edel. Permission to distribute under the LGPL for // the FLTK library granted by Mark Edel. @@ -409,6 +409,7 @@ int Fl_Text_Editor::handle(int event) { switch (event) { case FL_FOCUS: show_cursor(mCursorOn); // redraws the cursor + take_focus(); return 1; case FL_UNFOCUS: @@ -437,5 +438,5 @@ int Fl_Text_Editor::handle(int event) { } // -// End of "$Id: Fl_Text_Editor.cxx,v 1.9.2.1 2001/08/04 12:21:33 easysw Exp $". +// End of "$Id: Fl_Text_Editor.cxx,v 1.9.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Window_fullscreen.cxx b/src/Fl_Window_fullscreen.cxx index 5872078a1..03dad78c4 100644 --- a/src/Fl_Window_fullscreen.cxx +++ b/src/Fl_Window_fullscreen.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window_fullscreen.cxx,v 1.5.2.3 2001/01/22 15:13:40 easysw Exp $" +// "$Id: Fl_Window_fullscreen.cxx,v 1.5.2.3.2.1 2001/11/27 17:44:06 easysw Exp $" // // Fullscreen window support for the Fast Light Tool Kit (FLTK). // @@ -47,6 +47,8 @@ void Fl_Window::border(int b) { #ifdef WIN32 // not yet implemented, but it's possible // for full fullscreen we have to make the window topmost as well +#elif defined(__APPLE__) + //++ #else if (shown()) Fl_X::i(this)->sendxjunk(); #endif @@ -71,5 +73,5 @@ void Fl_Window::fullscreen_off(int X,int Y,int W,int H) { } // -// End of "$Id: Fl_Window_fullscreen.cxx,v 1.5.2.3 2001/01/22 15:13:40 easysw Exp $". +// End of "$Id: Fl_Window_fullscreen.cxx,v 1.5.2.3.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_Window_iconize.cxx b/src/Fl_Window_iconize.cxx index 5019bf36b..92c1e8961 100644 --- a/src/Fl_Window_iconize.cxx +++ b/src/Fl_Window_iconize.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window_iconize.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl_Window_iconize.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:06 easysw Exp $" // // Window minification code for the Fast Light Tool Kit (FLTK). // @@ -34,6 +34,10 @@ void Fl_Window::iconize() { } else { #ifdef WIN32 ShowWindow(i->xid, SW_SHOWMINNOACTIVE); +#elif defined(__APPLE__) + //: http://developer.apple.com/techpubs/mac/Toolbox/Toolbox-254.html#HEADING254-0 + //++ see iconize, above is the WRONG CALL + //++ call "hide all" ZoomWindow(i->xid, inZoomIn, 0); #else XIconifyWindow(fl_display, i->xid, fl_screen); #endif @@ -41,5 +45,5 @@ void Fl_Window::iconize() { } // -// End of "$Id: Fl_Window_iconize.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl_Window_iconize.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_arg.cxx b/src/Fl_arg.cxx index b4fe0b0d4..0125df1e6 100644 --- a/src/Fl_arg.cxx +++ b/src/Fl_arg.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_arg.cxx,v 1.5.2.8.2.2 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl_arg.cxx,v 1.5.2.8.2.3 2001/11/27 17:44:06 easysw Exp $" // // Optional argument initialization code for the Fast Light Tool Kit (FLTK). // @@ -34,16 +34,16 @@ #include <ctype.h> #include <string.h> -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*); -#define NoValue 0x0000 -#define XValue 0x0001 -#define YValue 0x0002 -#define WidthValue 0x0004 -#define HeightValue 0x0008 -#define AllValues 0x000F -#define XNegative 0x0010 -#define YNegative 0x0020 +# define NoValue 0x0000 +# define XValue 0x0001 +# define YValue 0x0002 +# define WidthValue 0x0004 +# define HeightValue 0x0008 +# define AllValues 0x000F +# define XNegative 0x0010 +# define YNegative 0x0020 #endif static int match(const char *a, const char *match, int atleast = 1) { @@ -104,7 +104,7 @@ int Fl::arg(int argc, char **argv, int &i) { if (!flags) return 0; geometry = v; -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) } else if (match(s, "display")) { Fl::display(v); #endif @@ -187,24 +187,17 @@ void Fl_Window::show(int argc, char **argv) { Fl::get_system_colors(); // opens display! May call Fl::fatal() } -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) // set the command string, used by state-saving window managers: int j; int n=0; for (j=0; j<argc; j++) n += strlen(argv[j])+1; -#ifdef __GNUC__ - char buffer[n]; -#else char *buffer = new char[n]; -#endif char *p = buffer; for (j=0; j<argc; j++) for (const char *q = argv[j]; (*p++ = *q++);); XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0, (unsigned char *)buffer, p-buffer-1); -#ifndef __GNUC__ delete[] buffer; #endif -#endif - } // Calls useful for simple demo programs, with automatic help message: @@ -226,7 +219,7 @@ void Fl::args(int argc, char **argv) { int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg); } -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) /* the following function was stolen from the X sources as indicated. */ @@ -365,5 +358,5 @@ int XParseGeometry(const char* string, int* x, int* y, #endif // ifdef WIN32 // -// End of "$Id: Fl_arg.cxx,v 1.5.2.8.2.2 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl_arg.cxx,v 1.5.2.8.2.3 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_cutpaste.cxx b/src/Fl_cutpaste.cxx index 39bac69fd..aac16ec7f 100644 --- a/src/Fl_cutpaste.cxx +++ b/src/Fl_cutpaste.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_cutpaste.cxx,v 1.6.2.4.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl_cutpaste.cxx,v 1.6.2.4.2.2 2001/11/27 17:44:06 easysw Exp $" // // Cut/paste code for the Fast Light Tool Kit (FLTK). // @@ -30,13 +30,15 @@ // has no text editing fields or other things that call cut or paste. #ifdef WIN32 -#include "Fl_cutpaste_win32.cxx" +# include "Fl_cutpaste_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_cutpaste_mac.cxx" #else -#include <FL/Fl.H> -#include <FL/x.H> -#include <FL/Fl_Window.H> -#include <string.h> +# include <FL/Fl.H> +# include <FL/x.H> +# include <FL/Fl_Window.H> +# include <string.h> static char *selection_buffer; static int selection_length; @@ -158,5 +160,5 @@ void Fl::selection(Fl_Widget &owner, const char *stuff, int len) { #endif // -// End of "$Id: Fl_cutpaste.cxx,v 1.6.2.4.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl_cutpaste.cxx,v 1.6.2.4.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_cutpaste_mac.cxx b/src/Fl_cutpaste_mac.cxx new file mode 100644 index 000000000..98c7be24e --- /dev/null +++ b/src/Fl_cutpaste_mac.cxx @@ -0,0 +1,148 @@ +// +// "$Id: Fl_cutpaste_mac.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// MacOS cut/paste code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +// Implementation of cut and paste for MacOS. + +#include <FL/Fl.H> +#include <FL/mac.H> +#include <FL/Fl_Window.H> +#include <string.h> +/* +static char *selection_buffer; +static int selection_length; +static int selection_buffer_length; +static char beenhere; + +extern Fl_Widget *fl_selection_requestor; // widget doing request_paste() + +static int selection_xevent_handler(int) { + + switch (fl_xevent->type) { + + case SelectionNotify: { + if (!fl_selection_requestor) return 0; + static char *pastebuffer; + if (pastebuffer) {XFree(pastebuffer); pastebuffer = 0;} + if (fl_xevent->xselection.property != 0) { + Atom a; int f; unsigned long n,b; + if (!XGetWindowProperty(fl_display, + fl_xevent->xselection.requestor, + fl_xevent->xselection.property, + 0,100000,1,0,&a,&f,&n,&b, + (unsigned char**)&pastebuffer)) { + Fl::e_text = pastebuffer; + Fl::e_length = int(n); + fl_selection_requestor->handle(FL_PASTE); + } + }} + return 1; + + case SelectionClear: + Fl::selection_owner(0); + return 1; + + case SelectionRequest: { + XSelectionEvent e; + e.type = SelectionNotify; + e.display = fl_display; + e.requestor = fl_xevent->xselectionrequest.requestor; + e.selection = fl_xevent->xselectionrequest.selection; + e.target = fl_xevent->xselectionrequest.target; + e.time = fl_xevent->xselectionrequest.time; + if (fl_xevent->xselectionrequest.target != XA_STRING || !selection_length) { + e.property = 0; + } else { + e.property = fl_xevent->xselectionrequest.property; + } + if (e.property) { + XChangeProperty(fl_display, e.requestor, e.property, + XA_STRING, 8, 0, (unsigned char *)selection_buffer, + selection_length); + } + XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);} + return 1; + + default: + return 0; + } +} +*/ +//////////////////////////////////////////////////////////////// + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &/*receiver*/) { +/* //++ + if (selection_owner()) { + // We already have it, do it quickly without window server. + // Notice that the text is clobbered if set_selection is + // called in response to FL_PASTE! + Fl::e_text = selection_buffer; + Fl::e_length = selection_length; + receiver.handle(FL_PASTE); + return; + } + // otherwise get the window server to return it: + fl_selection_requestor = &receiver; + XConvertSelection(fl_display, XA_PRIMARY, XA_STRING, XA_PRIMARY, + fl_xid(Fl::first_window()), fl_event_time); + if (!beenhere) { + Fl::add_handler(selection_xevent_handler); + beenhere = 1; + } + */ +} + +//////////////////////////////////////////////////////////////// + +// call this when you create a selection: +void Fl::selection(Fl_Widget &/*owner*/, const char */*stuff*/, int /*len*/) { +/* //++ + if (!stuff || len<0) return; + if (len+1 > selection_buffer_length) { + delete[] selection_buffer; + selection_buffer = new char[len+100]; + selection_buffer_length = len+100; + } + memcpy(selection_buffer, stuff, len); + selection_buffer[len] = 0; // needed for direct paste + selection_length = len; + selection_owner(&owner); + static Window selxid; // window X thinks selection belongs to + if (!selxid) selxid = + XCreateSimpleWindow(fl_display, + RootWindow(fl_display, fl_screen), + 0,0,1,1,0,0,0); + XSetSelectionOwner(fl_display, XA_PRIMARY, selxid, fl_event_time); + if (!beenhere) { + Fl::add_handler(selection_xevent_handler); + beenhere = 1; + } + */ +} + + +// +// End of "$Id: Fl_cutpaste_mac.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// diff --git a/src/Fl_display.cxx b/src/Fl_display.cxx index da14e9082..c1324c33c 100644 --- a/src/Fl_display.cxx +++ b/src/Fl_display.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_display.cxx,v 1.4.2.3 2001/01/22 15:13:40 easysw Exp $" +// "$Id: Fl_display.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:06 easysw Exp $" // // Display function for the Fast Light Tool Kit (FLTK). // @@ -31,13 +31,17 @@ #include <string.h> void Fl::display(const char *d) { +#ifdef __APPLE__ + (void)d; +#else char *e = new char[strlen(d)+13]; strcpy(e,"DISPLAY="); strcpy(e+8,d); for (char *c = e+8; *c!=':'; c++) if (!*c) {strcpy(c,":0.0"); break;} putenv(e); +#endif // __APPLE__ } // -// End of "$Id: Fl_display.cxx,v 1.4.2.3 2001/01/22 15:13:40 easysw Exp $". +// End of "$Id: Fl_display.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_get_key.cxx b/src/Fl_get_key.cxx index 0a10fd6a3..2065a3654 100644 --- a/src/Fl_get_key.cxx +++ b/src/Fl_get_key.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_get_key.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl_get_key.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:06 easysw Exp $" // // Keyboard state routines for the Fast Light Tool Kit (FLTK). // @@ -24,15 +24,17 @@ // #ifdef WIN32 -#include "Fl_get_key_win32.cxx" +# include "Fl_get_key_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_get_key_mac.cxx" #else // Return the current state of a key. This is the X version. I identify // keys (mostly) by the X keysym. So this turns the keysym into a keycode // and looks it up in the X key bit vector, which Fl_x.cxx keeps track of. -#include <FL/Fl.H> -#include <FL/x.H> +# include <FL/Fl.H> +# include <FL/x.H> extern char fl_key_vector[32]; // in Fl_x.cxx @@ -40,13 +42,13 @@ int Fl::event_key(int k) { if (k > FL_Button && k <= FL_Button+8) return Fl::event_state(8<<(k-FL_Button)); int i; -#ifdef __sgi +# ifdef __sgi // get some missing PC keyboard keys: if (k == FL_Meta_L) i = 147; else if (k == FL_Meta_R) i = 148; else if (k == FL_Menu) i = 149; else -#endif +# endif i = XKeysymToKeycode(fl_display, k); return fl_key_vector[i/8] & (1 << (i%8)); } @@ -60,5 +62,5 @@ int Fl::get_key(int k) { #endif // -// End of "$Id: Fl_get_key.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl_get_key.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_get_key_mac.cxx b/src/Fl_get_key_mac.cxx new file mode 100644 index 000000000..223459048 --- /dev/null +++ b/src/Fl_get_key_mac.cxx @@ -0,0 +1,104 @@ +// +// "$Id: Fl_get_key_mac.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// MacOS keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +// Return the current state of a key. Keys are named by fltk symbols, +// which are actually X keysyms. So this has to translate to macOS +// symbols. + +#include <FL/Fl.H> +#include <FL/mac.H> + +// convert an FLTK (X) keysym to a MacOS symbol: +// See also the inverse converter in Fl_mac.cxx +// This table is in numeric order by FLTK symbol order for binary search: + +static const struct {unsigned short vk, fltk;} vktab[] = { + { 49, ' ' }, { 39, '\'' }, { 43, ',' }, { 27, '-' }, { 47, '.' }, { 44, '/' }, + { 29, '0' }, { 18, '1' }, { 19, '2' }, { 20, '3' }, + { 21, '4' }, { 23, '5' }, { 22, '6' }, { 26, '7' }, + { 28, '8' }, { 25, '9' }, { 41, ';' }, { 24, '=' }, + { 0, 'A' }, { 11, 'B' }, { 8, 'C' }, { 2, 'D' }, + { 14, 'E' }, { 3, 'F' }, { 5, 'G' }, { 4, 'H' }, + { 34, 'I' }, { 38, 'J' }, { 40, 'K' }, { 37, 'L' }, + { 46, 'M' }, { 45, 'N' }, { 31, 'O' }, { 35, 'P' }, + { 12, 'Q' }, { 15, 'R' }, { 1, 'S' }, { 17, 'T' }, + { 32, 'U' }, { 9, 'V' }, { 13, 'W' }, { 7, 'X' }, + { 16, 'Y' }, { 6, 'Z' }, + { 33, '[' }, { 30, ']' }, { 50, '`' }, { 42, '|' }, + { 51, FL_BackSpace }, { 48, FL_Tab }, { 36, FL_Enter }, { 0x72, FL_Pause }, + { 127, FL_Scroll_Lock }, { 53, FL_Escape }, { 0x73, FL_Home }, { 123, FL_Left }, + { 126, FL_Up }, { 124, FL_Right }, { 125, FL_Down }, { 0x74, FL_Page_Up }, + { 0x79, FL_Page_Down }, { 127, FL_End }, { 0x71, FL_Print }, { 127, FL_Insert }, + { 127, FL_Menu }, { 0x47, FL_Num_Lock }, + { 76, FL_KP_Enter }, { 67, FL_KP+'*' }, { 69, FL_KP+'+'}, { 78, FL_KP+'-' }, { 65, FL_KP+'.' }, { 75, FL_KP+'/' }, + { 82, FL_KP+'0' }, { 83, FL_KP+'1' }, { 84, FL_KP+'2' }, { 85, FL_KP+'3' }, + { 86, FL_KP+'4' }, { 87, FL_KP+'5' }, { 88, FL_KP+'6' }, { 89, FL_KP+'7' }, + { 91, FL_KP+'8' }, { 92, FL_KP+'9' }, { 81, FL_KP+'=' }, + { 0x7a, FL_F+1 }, { 0x78, FL_F+2 }, { 0x63, FL_F+3 }, { 0x76, FL_F+4 }, + { 0x60, FL_F+5 }, { 0x61, FL_F+6 }, { 0x62, FL_F+7 }, { 0x64, FL_F+8 }, + { 0x65, FL_F+9 }, { 0x6D, FL_F+10 }, { 0x67, FL_F+11 }, { 0x6f, FL_F+12 }, + { 56, FL_Shift_L }, { 56, FL_Shift_R }, { 55, FL_Control_L }, { 55, FL_Control_R }, + { 57, FL_Caps_Lock }, { 59, FL_Meta_L }, { 59, FL_Meta_R }, + { 58, FL_Alt_L }, { 58, FL_Alt_R }, // Fl_Help = 0x72 +}; + +static int fltk2mac(int fltk) { + int a = 0; + int b = sizeof(vktab)/sizeof(*vktab); + while (a < b) { + int c = (a+b)/2; + if (vktab[c].fltk == fltk) return vktab[c].vk; + if (vktab[c].fltk < fltk) a = c+1; else b = c; + } + return 127; +} + +//: returns true, if that key was pressed during the last event +int Fl::event_key(int k) { +//++ return GetKeyState(fltk2mac(k))&~1; + return get_key(k); //++ find a faster way?! +} + +#include <stdio.h> + +//: returns true, if that key is pressed right now +int Fl::get_key(int k) { + KeyMap foo; + GetKeys(foo); +#ifdef MAC_TEST_FOR_KEYCODES + static int cnt = 0; + if (cnt++>1024) { + cnt = 0; + printf("%08x %08x %08x %08x\n", (ulong*)(foo)[3], (ulong*)(foo)[2], (ulong*)(foo)[1], (ulong*)(foo)[0]); + } +#endif + int i = fltk2mac(k); + unsigned char *b = (unsigned char*)foo; + return (b[i>>3]>>(i&7))&1; +} + +// +// End of "$Id: Fl_get_key_mac.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx index 7fde64290..b98379655 100644 --- a/src/Fl_get_system_colors.cxx +++ b/src/Fl_get_system_colors.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_get_system_colors.cxx,v 1.6.2.7.2.1 2001/10/29 03:44:32 easysw Exp $" +// "$Id: Fl_get_system_colors.cxx,v 1.6.2.7.2.2 2001/11/27 17:44:06 easysw Exp $" // // System color support for the Fast Light Tool Kit (FLTK). // @@ -26,6 +26,7 @@ #include <FL/Fl.H> #include <FL/x.H> #include <FL/math.h> +#include <string.h> void Fl::background(uchar r, uchar g, uchar b) { // replace the gray ramp so that FL_GRAY is this color @@ -62,9 +63,9 @@ static void set_selection_color(uchar r, uchar g, uchar b) { Fl::set_color(FL_SELECTION_COLOR,r,g,b); } -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) -#include <stdio.h> +# include <stdio.h> // simulation of XParseColor: int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { if (*p == '#') p++; @@ -87,7 +88,9 @@ int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { r = R; g = G; b = B; return 1; } +#endif // WIN32 || __APPLE__ +#if defined(WIN32) static void getsyscolor(int what, const char* arg, void (*func)(uchar,uchar,uchar)) { @@ -110,6 +113,15 @@ void Fl::get_system_colors() { getsyscolor(COLOR_HIGHLIGHT, 0, set_selection_color); } +#elif defined(__APPLE__) +// MacOS X currently supports two color schemes - Blue and Graphite. +// Since we aren't emulating the Aqua interface (even if Apple would +// let us), we can stick with the defaults that FLTK has traditionally +// used... +void Fl::get_system_colors() +{ + fl_open_display(); +} #else // Read colors that KDE writes to the xrdb database. @@ -150,5 +162,5 @@ void Fl::get_system_colors() #endif // -// End of "$Id: Fl_get_system_colors.cxx,v 1.6.2.7.2.1 2001/10/29 03:44:32 easysw Exp $". +// End of "$Id: Fl_get_system_colors.cxx,v 1.6.2.7.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_grab.cxx b/src/Fl_grab.cxx index 0f2f82185..fee3d6f09 100644 --- a/src/Fl_grab.cxx +++ b/src/Fl_grab.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_grab.cxx,v 1.1.2.4.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl_grab.cxx,v 1.1.2.4.2.2 2001/11/27 17:44:06 easysw Exp $" // // Grab/release code for the Fast Light Tool Kit (FLTK). // @@ -50,6 +50,8 @@ void Fl::grab(Fl_Window* w) { #ifdef WIN32 SetActiveWindow(fl_capture = fl_xid(first_window())); SetCapture(fl_capture); +#elif defined(__APPLE__) + //++ #else XGrabPointer(fl_display, fl_xid(first_window()), @@ -75,6 +77,8 @@ void Fl::grab(Fl_Window* w) { #ifdef WIN32 fl_capture = 0; ReleaseCapture(); +#elif defined(__APPLE__) + //++ #else XUngrabKeyboard(fl_display, fl_event_time); XUngrabPointer(fl_display, fl_event_time); @@ -89,5 +93,5 @@ void Fl::grab(Fl_Window* w) { } // -// End of "$Id: Fl_grab.cxx,v 1.1.2.4.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl_grab.cxx,v 1.1.2.4.2.2 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx new file mode 100644 index 000000000..087795a27 --- /dev/null +++ b/src/Fl_mac.cxx @@ -0,0 +1,1158 @@ +// +// "$Id: Fl_mac.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// MacOS specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +// we don't need the following definition because we deliver only +// true mouse moves. On very slow systems however, this flag may +// still be useful. +#define CONSOLIDATE_MOTION 0 + +#include <config.h> +#include <FL/Fl.H> +#include <FL/x.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Sys_Menu_Bar.H> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +int fl_handle(const EventRef event); + +int fl_screen; +Handle fl_system_menu; +Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0; +CursHandle fl_default_cursor; +static CursPtr default_cursor_ptr; +static Cursor default_cursor; + +#if CONSOLIDATE_MOTION +static Fl_Window* send_motion; +extern Fl_Window* fl_xmousewin; +#endif + +/** + * we need these as temporary regions for correct subwindow clipping + */ +static RgnHandle flmFullRgn = 0L, flmSubRgn = 0L; +static Window flmFullXid = 0; +static SysEnvRec MacWorld; + + +/** + * Performance timer start + * - not finished, don't use + */ +static UnsignedWide _perfStart; +static void _startPerf() +{ + Microseconds( &_perfStart ); +} + +/** + * Performance timer end + * - not finished, don't use + */ +static unsigned int _endPerf() +{ + UnsignedWide _perfEnd; + Microseconds( &_perfEnd ); + // display the difference somehow - probably averaged + // if (msStart.hi==msEnd.hi) + // s1->value( (msEnd.lo-msStart.lo)/100.0 ); + + // get delta: + if ( _perfEnd.lo >= _perfStart.lo ) + _perfEnd.hi = _perfEnd.hi - _perfStart.hi; + else + _perfEnd.hi = (_perfEnd.hi - 1) - _perfStart.hi; + _perfEnd.lo = _perfEnd.lo - _perfStart.lo; + + // convert to double in micro seconds + +// static double kTwoPower32 = 4294967296.0; +// double t = (((double) _perfEnd.hi) * kTwoPower32) + _perfEnd.lo; +// UpTime(); +/* +AbsoluteTime startTime; +AbsoluteTime endTime; +AbsoluteTime elapsedTime; +Nanoseconds elapsedNanoseconds; // This is an UnsignedWide integer + +startTime = UpTime(); +DoMyOperation(); +endTime = UpTime(); +elapsedTime = SubAbsoluteFromAbsolute(endTime, startTime); +elapsedNanoseconds = AbsoluteToNanoseconds(elapsedTime); +*/ + return 0; +} + + +/** + * \todo This funtion is not yet implemented! + */ +void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v ) +{ +#pragma unused ( n ) +#pragma unused ( events ) +#pragma unused ( cb ) +#pragma unused ( v ) +} + + +/** + * \todo This funtion is not yet implemented! + */ +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) +{ +#pragma unused ( fd ) +#pragma unused ( cb ) +#pragma unused ( v ) +} + + +/** + * \todo This funtion is not yet implemented! + */ +void Fl::remove_fd(int n, int events) +{ +#pragma unused ( n ) +#pragma unused ( events ) +} + + +/** + * \todo This funtion is not yet implemented! + */ +void Fl::remove_fd(int n) +{ + remove_fd(n, -1); +} + + +/** + * \todo check if there is actually a message pending! + */ +int fl_ready() +{ + return 1; +} + + +/** + * This function iss the central event handler. + * It reads events from the event queue using the given maximum time + * Funny enough, it returns the same time that it got as the argument. + */ +static double do_queued_events( double time = 0.0 ) +{ + static bool been_here = 0; + static RgnHandle rgn; + + // initialize events and a region that enables mouse move events + if (!been_here) { + rgn = NewRgn(); + Point mp; + GetMouse(&mp); + SetRectRgn(rgn, mp.h, mp.v, mp.h, mp.v); + SetEventMask(everyEvent); + //++ SystemEventMask ( MouseUp ) + been_here = 1; + } + + EventRef ev; + while ( ReceiveNextEvent(0, NULL, time, true, &ev) ) + { + fl_handle(ev); //: handle the nullEvent to get mouse up events +// SetRectRgn(rgn, ev.where.h, ev.where.v, ev.where.h+1, ev.where.v+1 ); + } + +#if CONSOLIDATE_MOTION + if (send_motion && send_motion == fl_xmousewin) { + send_motion = 0; + Fl::handle(FL_MOVE, fl_xmousewin); + } +#endif + return time; +} + + +/** + * This public function handles all events. It wait a maximum of + * 'time' secods for an event. It returns the same time that was given + * in the argument! + * + * \TODO: there is no socket handling in this code whatsoever + */ +double fl_wait( double time ) +{ + return do_queued_events( time ); +} + + +/** + * \todo not yet implemented! + */ +static void fd_callback(int,void *) +{ + do_queued_events(); +} + + +/** + * Handle the mac typical topline menubar + */ +static void HandleMenu( long mResult ) +{ + short item, menu ; + MenuHandle mHandle ; +// Str255 itemName; + UInt32 ref; + + item = LoWord( mResult ) ; + menu = HiWord( mResult ) ; + mHandle = GetMenuHandle( menu ) ; + + switch (menu) + { + case 0: + break; + case 1: // Apple (this menu should be defined in the resource of your application) +// GetMenuItemText( GetMenuHandle( 1 ), item, itemName ); +// OpenDeskAcc( itemName ); + break; + default: + if ( !item ) break; + GetMenuItemRefCon( mHandle, item, &ref ); + if ( ref && fl_sys_menu_bar ) + { + Fl_Menu_Item *m = (Fl_Menu_Item*)ref; + fl_sys_menu_bar->picked( m ); + if ( m->flags & FL_MENU_TOGGLE ) + SetItemMark( mHandle, item, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + if ( m->flags & FL_MENU_RADIO ) + { + Fl_Menu_Item* j = m; + int i = item; + for (;;) { + if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines + j++; i++; + if (!j->text || !j->radio()) break; // stop after group + SetItemMark( mHandle, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + j = m-1; i = item-1; + for (;i>0;j--,i--) { + if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break; + SetItemMark( mHandle, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + SetItemMark( mHandle, item, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + } + } + HiliteMenu( 0 ); +} + + +/** + * initialize the Mac toolboxes and set the default menubar + */ +void fl_open_display() { + static char beenHereDoneThat = 0; + if ( !beenHereDoneThat ) { + beenHereDoneThat = 1; + + //++ open all macintosh services +// InitGraf(&qd.thePort); /* init Quickdraw and global variables */ +// InitFonts(); +// InitWindows(); +// InitMenus(); +// InitCursor(); +// TEInit(); + FlushEvents(everyEvent, 0); +// InitDialogs( nil ); + + MoreMasters(); +// MaxApplZone(); + +// SysEnvirons( 1, &MacWorld ); + + // OK, this is just ridiculous... + GetQDGlobalsArrow(&default_cursor); + default_cursor_ptr = &default_cursor; + fl_default_cursor = &default_cursor_ptr; + + FlushEvents(everyEvent,0); + + flmFullRgn = NewRgn(); // here we remember our overall damage + flmSubRgn = NewRgn(); // used to clip subwindows out of the parent windows redraw + + // create a minimal menu bar (\todo "about app", "FLTK settings") + // Any FLTK application may replace this menu later with its own bar. + fl_system_menu = GetNewMBar( 1 ); + if ( fl_system_menu ) { + SetMenuBar( fl_system_menu ); + AppendResMenu( GetMenuHandle( 1 ), 'DRVR' ); + } + + DrawMenuBar(); + } +} + + +/** + * get rid of allocated resources + */ +void fl_close_display() { + DisposeRgn( flmFullRgn ); + DisposeRgn( flmSubRgn ); + //++ close all mac services +} + + +/** + * smallest x ccordinate in screen space + */ +int Fl::x() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.left; +} + + +/** + * smallest y ccordinate in screen space + */ +int Fl::y() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.top + 20; // 20 pixel menu bar? +} + + +/** + * screen width (single monitor!?) + */ +int Fl::w() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.right - r.bounds.left; +} + + +/** + * screen height (single monitor!?) + */ +int Fl::h() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.bottom - r.bounds.top - 20; +} + + +/** + * get the current mouse pointer world coordinates + */ +void Fl::get_mouse(int &x, int &y) +{ + fl_open_display(); + Point loc; + GetMouse( &loc ); + LocalToGlobal( &loc ); + x = loc.h; + y = loc.v; +} + + +/************************** event conversion stuff ***********************/ + +const EventRecord* fl_macevent; // the current mac event +ulong fl_event_time; // the last timestamp from an x event +char fl_key_vector[32]; // used by Fl::get_key() + +// Record event mouse position and state from an XEvent: + +static int px, py; +static ulong ptime; + +/** + * convert Mac modifiers to FLTK + */ +static void set_shift_states(const EventRecord &macevent) +{ + ulong state = Fl::e_state & 0xff000000; + if (macevent.modifiers&shiftKey) state |= FL_SHIFT; + if ( (macevent.modifiers&controlKey) && (macevent.modifiers&btnState) ) state |= FL_META; // try to fetch the right mouse button + if (macevent.modifiers&optionKey) state |= FL_ALT; + if (macevent.modifiers&cmdKey) state |= FL_CTRL; + if (macevent.modifiers&alphaLock) state |= FL_CAPS_LOCK; + state |= FL_NUM_LOCK; //++ always num keypad on Mac? + Fl::e_state = state; +} + +/** + * set the FLTK mouse status variables + */ +static void set_event_xy(const EventRecord &macevent) +{ +#if CONSOLIDATE_MOTION + send_motion = 0; +#endif + Fl::e_x_root = macevent.where.h; + Fl::e_y_root = macevent.where.v; + Point g = macevent.where; + GlobalToLocal(&g); + Fl::e_x = g.h; + Fl::e_y = g.v; + if (macevent.what!=osEvt) set_shift_states(macevent); + fl_event_time = macevent.when; + if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3 + || fl_event_time >= ptime+GetDblTime()) + Fl::e_is_click = 0; +} + +/** + * Mac keyboard lookup table + */ +static unsigned short macKeyLookUp[128] = +{ + 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', + 'c', 'v', 0, 'b', 'q', 'w', 'e', 'r', + + 'y', 't', '1', '2', '3', '4', '6', '5', + '=', '9', '7', '-', '8', '0', ']', 'o', + + 'u', '[', 'i', 'p', FL_Enter, 'l', 'j', '\'', + 'k', ';', '\\', ',', '/', 'n', 'm', '.', + + FL_Tab, ' ', '`', FL_BackSpace, 0, FL_Escape, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, FL_KP+'.', 0, FL_KP+'*', 0, FL_KP+'+', 0, FL_Num_Lock, + 0, 0, 0, FL_KP+'/', FL_KP_Enter, 0, FL_KP+'-', 0, + + 0, FL_KP+'=', FL_KP+'0', FL_KP+'1', FL_KP+'2', FL_KP+'3', FL_KP+'4', FL_KP+'5', + FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0, + + FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11, + 0, 0, 0, 0, 0, FL_F+10, 0, FL_F+12, + + 0, 0, FL_Pause, FL_Home, FL_Page_Up, 0, FL_F+4, 0, + FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0, +}; + + +/** + * convert Mac keystrokes to FLTK + */ +unsigned short mac2fltk(ulong macKey) +{ + unsigned short cc = macKeyLookUp[(macKey>>8)&0x7f]; + if (cc) return cc; + return macKey&0xff; +} + + +/** + * handle double and triple clicks + */ +static inline void checkdouble() +{ + if (Fl::e_is_click == Fl::e_keysym) + Fl::e_clicks++; + else { + Fl::e_clicks = 0; + Fl::e_is_click = Fl::e_keysym; + } + px = Fl::e_x_root; + py = Fl::e_y_root; + ptime = fl_event_time; +} + +/************************** Mac Window System stuff ***********************/ + +static Fl_Window* resize_from_system; +Fl_Window* fl_find(Window); + + +/** + * user is in the process of resizing the window + */ +void Fl_X::MacGrowWindow(WindowPtr xid, const EventRecord &macevent) +{ + Fl_Window *win = fl_find(xid); + if (!win) return; + while ( win->window() ) win = (Fl_Window*)win->window(); + Rect limit; + limit.top = win->minh; limit.left = win->minw; + limit.bottom = win->maxh?win->maxh:Fl::h(); limit.right = win->maxw?win->maxw:Fl::w(); + unsigned int grow = GrowWindow(xid, macevent.where, &limit); + if (grow==0) return; + win->resize(win->x(), win->y(), grow&0xffff, grow>>16); +} + + +/** + * user is in the process of resizing the window + */ +void Fl_X::MacDragWindow(WindowPtr xid, const EventRecord &macevent) +{ + BitMap bm; + + GetQDGlobalsScreenBits(&bm); + DragWindow(xid, macevent.where, &(bm.bounds)); + Fl_Window *win = fl_find(xid); + if (!win) return; + Point pt; pt.h = 0; pt.v = 0; + SetPort((GrafPtr)xid); SetOrigin(0, 0); LocalToGlobal(&pt); + win->resize( pt.h, pt.v, win->w(), win->h() ); + //++ win->x(pt.h); win->y(pt.v); +} + + +//++ actually this function should be part of 'set_shift_states' +//++ because pressing down SHIFT, then another key while the event queue is full +//++ while actually generate the SHIFT event AFTER the key event! +//++ (at least no events are lost in the process) +int Fl_X::MacModifiers(const EventRecord &macevent, unsigned short prev) +{ + Fl_Window *window = fl_find(FrontWindow()); + if (!window) return 0; + Fl::e_length = 0; + unsigned short now = macevent.modifiers; + set_shift_states(macevent); //++ will 'break' if multiple keys are released between 0 events + unsigned short m = now^prev; + if (m&cmdKey && now&cmdKey) { Fl::e_keysym = FL_Control_L; Fl::handle(FL_KEYBOARD, window); } + if (m&shiftKey && now&shiftKey) { Fl::e_keysym = FL_Shift_L; Fl::handle(FL_KEYBOARD, window); } + if (m&optionKey && now&optionKey) { Fl::e_keysym = FL_Alt_L; Fl::handle(FL_KEYBOARD, window); } + if ( ((m&controlKey)&&(m&btnState)) && ((now&controlKey)&&(now&btnState)) ) { Fl::e_keysym = FL_Meta_L; Fl::handle(FL_KEYBOARD, window); } + //: caps lock generates keyboard event only on key-down + if (m&alphaLock) { Fl::e_keysym = FL_Caps_Lock; Fl::handle(FL_KEYBOARD, window); } + return 1; +} + + +/** + * Initialize the given port for redraw and call the windw's flush() to actually draw the content + */ +void Fl_X::flush() +{ + w->flush(); + SetOrigin( 0, 0 ); +} + + +/** + * Handle all clipping and redraw for the given port + * There are two different callers for this event: + * 1: the OS can request a redraw and provides all clipping itself + * 2: Fl::flush() wants all redraws now + */ +void handleUpdateEvent( WindowPtr xid ) +{ + Fl_Window *window = fl_find( xid ); + if ( !window ) return; + SetPort( (GrafPtr)xid ); + Fl_X *i = Fl_X::i( window ); + i->wait_for_expose = 0; //++ what about this flag?! + if ( window->damage() ) { + if ( i->region ) { + InvalWindowRgn( xid, i->region ); + } + } + if ( i->region ) { // no region, so the sytem will take the update region from the OS + DisposeRgn( i->region ); + i->region = 0; + } + BeginUpdate( xid ); + + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) + { + cx->w->clear_damage(window->damage()|FL_DAMAGE_EXPOSE); + cx->flush(); + cx->w->clear_damage(); + } + window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE); + i->flush(); + window->clear_damage(); + + EndUpdate( xid ); +} + + +/** + * dispatch all mac events + */ +int fl_handle(const EventRef event) +{ + UInt32 eventclass, eventkind; + static char buffer[5]; + static unsigned short prevMod = 0; + static WindowPtr prevMouseDownXid; + WindowPtr xid; +// int event = 0; + Fl_Window *window = 0L; + eventclass = GetEventClass(event); + eventkind = GetEventKind(event); + memcpy(buffer, &eventclass, 4); + buffer[4] = '\0'; + printf("fl_event(): class = %s, kind = %d\n", buffer, eventkind); +#if 0 + switch (macevent.what) + { + case mouseDown: { + // handle the differnt mouseDown events in various areas of the screen + int part = FindWindow(macevent.where, &xid); + prevMouseDownXid = xid; + switch (part) { + case inDesk: break; + case inMenuBar: HandleMenu(MenuSelect(macevent.where)); break; +// case inSysWindow: SystemClick(&macevent, xid); break; + case inContent: { + if (xid!=FrontWindow()) SelectWindow( xid ); //{ SelectWindow(xid); return 1; } + window = fl_find(xid); + if (!window) break; + SetPort((GrafPtr)xid); SetOrigin(0, 0); + Fl::e_keysym = FL_Button+((macevent.modifiers&controlKey)?3:1); //++ simulate three button using modifiers + set_event_xy(macevent); checkdouble(); + Fl::e_state |= ((macevent.modifiers&controlKey)?FL_BUTTON3:FL_BUTTON1); + return Fl::handle(FL_PUSH, window); } + case inDrag: Fl_X::MacDragWindow(xid, macevent); break; + case inGrow: Fl_X::MacGrowWindow(xid, macevent); break; + case inGoAway: + if (TrackGoAway(xid, macevent.where)) Fl::handle(FL_CLOSE, fl_find(xid)); + break; + case inZoomIn: case inZoomOut: +// if (TrackBox(xid, event.where, part)) DoZoomWindow(xid, part); + break; + } + break; } + case mouseUp: { + xid = FrontWindow(); + window = fl_find( xid ); + if (!window) break; + SetPort((GrafPtr)xid); + SetOrigin(0, 0); + Fl::e_keysym = FL_Button+((Fl::e_state&FL_BUTTON1)?1:3); // macevent.modifiers ... + set_event_xy(macevent); + Fl::e_state &= ~(FL_BUTTON1|FL_BUTTON3); +// if (!Fl::grab()) ReleaseCapture(); + return Fl::handle(FL_RELEASE, window); } + case nullEvent: { //: idle events - who came up with that idea? + if (macevent.modifiers&0xff00 == prevMod) break; + int ret = Fl_X::MacModifiers(macevent, prevMod); + prevMod = macevent.modifiers&0xff00; + return ret; } + case keyUp: + //: bit0..7 message = keycode, 8..15 virtual, 16..23 ADB + //:: keyup does NOT GET CALLED in CW debug mode!! + case keyDown: + case autoKey: { + window = fl_find(FrontWindow()); + if (!window) break; + unsigned short cc = mac2fltk(macevent.message); + unsigned char cm = macevent.message; + Fl::e_keysym = cc; + set_shift_states(macevent); + if (macevent.what==keyUp) { + Fl::e_length = 0; buffer[0] = 0; + } else { + Fl::e_text = buffer; + if (cc<0x100) { + //++ please check the Mac specific 'option+key' special characters + //++ handle the control key to generate control characters + //if (Fl::e_state&FL_CTRL && cm>=32 && cm<64) buffer[0] = cm-32; else + buffer[0] = cm; + } else if (cc>=FL_KP && cc<=FL_KP_Last) { + buffer[0] = cc-FL_KP; //++ remapped num keys: macevent.message; + } else { + buffer[0] = 0; + } + if (cc==FL_Escape) buffer[0]=27; + else if (cc==FL_BackSpace) buffer[0]=0x08; + else if (cc==FL_Tab) buffer[0]=0x09; + Fl::e_length = (buffer[0]?1:0); + return Fl::handle(FL_KEYBOARD, window); + } + break; + } + case activateEvt: + window = fl_find((WindowPtr)(macevent.message)); + if (!window) break; + if (macevent.modifiers & activeFlag) { + return Fl::handle(FL_FOCUS, window); + } else { + return Fl::handle(FL_UNFOCUS, window); + } + break; + case updateEvt: + xid = (WindowPtr)macevent.message; + handleUpdateEvent( xid ); + break; + case diskEvt: + break; + case osEvt: //: contains mouse move events + switch ( (macevent.message>>24)&0xff ) { + case suspendResumeMessage: + window = fl_find(FrontWindow()); + if (!window) break; + SetEventMask(everyEvent); //++ currentMask | keyUpEvent + //++ mac users will expect that all windows switch to inactive + if (macevent.message & resumeFlag) { + return Fl::handle(FL_FOCUS, window); + } else { + return Fl::handle(FL_UNFOCUS, window); + } + break; + case mouseMovedMessage: + if (Fl::e_x_root==macevent.where.h && Fl::e_y_root==macevent.where.v) break; + xid = FrontWindow(); + window = fl_find( xid ); + if (!window) break; + SetPort((GrafPtr)xid); SetOrigin(0, 0); + set_event_xy(macevent); + #if CONSOLIDATE_MOTION + send_motion = fl_xmousewin = window; + return 0; + #else + return Fl::handle( (macevent.modifiers & btnState)?FL_MOVE:FL_DRAG, window); + #endif +// if (!Fl::grab()) ReleaseCapture(); + } + break; + //++ get null events to grab changes in the modifier keys (shift down, etc.) + case kHighLevelEvent: + AEProcessAppleEvent(&macevent); + break; + } +#endif // 0 + return 1; +} + +//////////////////////////////////////////////////////////////// +// This function gets the dimensions of the top/left borders and +// the title bar, if there is one, based on the FL_BORDER, FL_MODAL +// and FL_NONMODAL flags, and on the window's size range. +// It returns the following values: +// +// value | border | title bar +// 0 | none | no +// 1 | fix | yes +// 2 | size | yes +// 3 | dialog | dialog (currently not used) + +int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { + int W, H, xoff, yoff, dx, dy; + int ret = bx = by = bt = 0; + if (w->border() && !w->parent()) { + if (w->maxw != w->minw || w->maxh != w->minh) { + ret = 2; + bx = 6; //++ GetSystemMetrics(SM_CXSIZEFRAME); + by = 6; //++ get Mac window frame size GetSystemMetrics(SM_CYSIZEFRAME); + } else { + ret = 1; + bx = 6; //++ GetSystemMetrics(SM_CXFIXEDFRAME); + by = 6; //++ GetSystemMetrics(SM_CYFIXEDFRAME); + } + bt = 22; //++ GetSystemMetrics(SM_CYCAPTION); + } + //The coordinates of the whole window, including non-client area + xoff = bx; + yoff = by + bt; + dx = 2*bx; + dy = 2*by + bt; + X = w->x()-xoff; + Y = w->y()-yoff; + W = w->w()+dx; + H = w->h()+dy; + + //Proceed to positioning the window fully inside the screen, if possible + //Make border's lower right corner visible + if (Fl::w() < X+W) X = Fl::w() - W; + if (Fl::h() < Y+H) Y = Fl::h() - H; + //Make border's upper left corner visible + if (X<0) X = 0; + if (Y<0) Y = 0; + //Make client area's lower right corner visible + if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx; + if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy; + //Make client area's upper left corner visible + if (X+xoff < 0) X = -xoff; + if (Y+yoff < 0) Y = -yoff; + //Return the client area's top left corner in (X,Y) + X+=xoff; + Y+=yoff; + + return ret; +} + + +//////////////////////////////////////////////////////////////// +// Innards of Fl_Window::create() + +bool fl_show_iconic; // true if called from iconize() +int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR +const Fl_Window* fl_modal_for; // parent of modal() window + +/** + * go ahead, create that (sub)window + */ +void Fl_X::make(Fl_Window* w) +{ + static int xyPos = 24; + if ( w->parent() ) // create a subwindow + { + Fl_Group::current(0); +// int xp = w->x(); +// int yp = w->y(); +// int wp = w->w(); +// int hp = w->h(); + //++ now we have to do completely different stuff here! + //++ mac has no concept of a window in a window! + + Rect wRect; + wRect.top = w->y(); + wRect.left = w->x(); + wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1; + wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1; + // our subwindow needs this structure to know about its clipping. + Fl_X* x = new Fl_X; + x->other_xid = 0; + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + Fl_Window *win = w->window(); + Fl_X *xo = Fl_X::i(win); + x->xidNext = xo->xidChildren; + x->xidChildren = 0L; + xo->xidChildren = x; + x->xid = fl_xid(win); + x->w = w; w->i = x; + x->wait_for_expose = 0; + x->next = Fl_X::first; // must be in the list for ::flush() + Fl_X::first = x; + w->set_visible(); + w->handle(FL_SHOW); + w->redraw(); // force draw to happen + fl_show_iconic = 0; + //++ hmmm, this should maybe set by the activate event?! + Fl::handle(FL_FOCUS, w); + //++ if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); } + } + else // create a desktop window + { + Fl_Group::current(0); + fl_open_display(); + int winclass = kDocumentWindowClass; +// int winattr = kCloseBoxAttribute | kCollapseBoxAttribute | kWindowStandardHandlerAttribute; +// int winattr = kWindowStandardHandlerAttribute; + int winattr = 0; + int xp = w->x(); + int yp = w->y(); + int wp = w->w(); + int hp = w->h(); + if (!w->size_range_set) { + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); +// winattr |= kWindowFullZoomAttribute | kWindowResizeableAttribute; + winattr |= kWindowFullZoomAttribute; + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + } + int xwm = xp, ywm = yp, bt, bx, by; + if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) winclass = kFloatingWindowClass; + else if (w->modal()) winclass = kModalWindowClass; + else if (w->non_modal()) winclass = kToolbarWindowClass; + if (by+bt) { + //++ if (!w->non_modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX; + wp += 2*bx; + hp += 2*by+bt; + } + if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) { + w->x(xyPos+Fl::x()); w->y(xyPos+Fl::y()); + xyPos += 24; + if (xyPos>200) xyPos = 24; + } else { + if (!Fl::grab()) { + xp = xwm; yp = ywm; + w->x(xp);w->y(yp); + } + xp -= bx; + yp -= by+bt; + } + + if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* w = Fl_X::first->w; + while (w->parent()) w = w->window(); + //++parent = fl_xid(w); + } + + Rect wRect; + wRect.top = w->y(); + wRect.left = w->x(); + wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1; + wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1; + + const char *name = w->label(); + Str255 pTitle; + if (name) { pTitle[0] = strlen(name); memcpy(pTitle+1, name, pTitle[0]); } + else pTitle[0]=0; + + Fl_X* x = new Fl_X; + x->other_xid = 0; // room for doublebuffering image map //++ OS X: the OS always doublebuffers! + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->xidChildren = 0; + x->xidNext = 0; + CreateNewWindow(winclass, winattr, &wRect, &(x->xid)); + SetWTitle(x->xid, pTitle); + x->w = w; w->i = x; + x->wait_for_expose = 1; + x->next = Fl_X::first; + Fl_X::first = x; + if (w->resizable()) DrawGrowIcon(x->xid); + w->set_visible(); + w->handle(FL_SHOW); + w->redraw(); // force draw to happen + TransitionWindow( x->xid, kWindowZoomTransitionEffect, kWindowShowTransitionAction, 0 ); + ShowWindow( x->xid ); + fl_show_iconic = 0; + //++ hmmm, this should maybe set by the activate event?! + Fl::handle(FL_FOCUS, w); + //++ if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); } + } +} + +void Fl_Window::size_range_() { + size_range_set = 1; +} + +//////////////////////////////////////////////////////////////// + +//++ make this run with Unix filenames +// returns pointer to the filename, or null if name ends with ':' +const char *filename_name( const char *name ) +{ + const char *p, *q; + for ( p = q = name ; *p ; ) + { + if ( ( p[0] == ':' ) && ( p[1] == ':' ) ) + { + q = p+2; + p++; + } + else if (p[0] == '/') + q = p + 1; + p++; + } + return q; +} + +/** + * set the window title bar + * \todo make the titlebar icon work! + */ +void Fl_Window::label(const char *name,const char */*iname*/) { + Fl_Widget::label(name); + Str255 pTitle; + + if (name) { pTitle[0] = strlen(name); memcpy(pTitle+1, name, pTitle[0]); } + else pTitle[0] = 0; + + if (shown() || i) SetWTitle(fl_xid(this), pTitle); +} + +//////////////////////////////////////////////////////////////// +// Implement the virtual functions for the base Fl_Window class: + +// Display can *look* faster (it isn't really faster) if X's background +// color is used to erase the window. In fltk 2.0 the only way to +// prevent this is to set the box to FL_NO_BOX. +// +// Drawing should really be faster if FL_FRAME_ONLY is passed to the +// box drawing function, since X has already erased the interior. But +// on XFree86 (and prehaps all X's) this has a problem if the window +// is resized while a save-behind window is atop it. The previous +// contents are restored to the area, but this assummes the area is +// cleared to background color. So I had to give up on this... +/* +void Fl_Window::create() { + Fl_X::create(this); +} +*/ +Window fl_window; +Fl_Window *Fl_Window::current_; + + +void Fl_Window::show() { + if (!shown() || !i) { + Fl_X::make(this); + } else { + //++ do we need to do grab and icon handling here? + /*if (!fl_capture)*/ BringToFront(i->xid); + } +} + + +void Fl_Window::resize(int X,int Y,int W,int H) { + int is_a_resize = (W != w() || H != h()); + if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION); + else if (!is_a_resize) return; + // change the viewport first, so children (namely OpenGL) can resize correctly + if ( (!parent()) && shown()) { + MoveWindow(i->xid, X, Y, 0); + if (is_a_resize) { + SizeWindow(i->xid, W>0 ? W : 1, H>0 ? H : 1, 1); +// Rect all; all.top=-32000; all.bottom=32000; all.left=-32000; all.right=32000; +// InvalRect(&all); + } + } + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) {redraw(); if (!parent()) i->wait_for_expose = 1; } + } else { + x(X); y(Y); + } +} + +Fl_Region fl_window_region = 0; + +/** + * make all drawing go into this window (called by subclass flush() impl.) + */ +void Fl_Window::make_current() +{ + if ( !fl_window_region ) + fl_window_region = NewRgn(); + //- printf(" make current: 0x%08x\n", this); + fl_window = i->xid; + current_ = this; + + SetPort((GrafPtr)(i->xid)); + + int xp = 0, yp = 0; + Fl_Window *win = this; + while ( win ) + { + if ( !win->window() ) + break; + xp += win->x(); + yp += win->y(); + win = (Fl_Window*)win->window(); + } + SetOrigin( -xp, -yp ); //++ how do we handle doublebuffering here? + + //+++ here we should set the clip to all except the subwindows + //++ first of all, there seems to be some leftovers from an old operation + SetRectRgn( fl_window_region, 0, 0, w(), h() ); + // remove all subwindows from the clip + + //+++ for performance reasons: we don't have to create this unless the child windows moved + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) + { + Fl_Region r = NewRgn(); + Fl_Window *cw = cx->w; + SetRectRgn( r, cw->x() - xp, cw->y() - yp, + cw->x() + cw->w() - xp, cw->y() + cw->h() - yp ); + DiffRgn( fl_window_region, r, fl_window_region ); + DisposeRgn( r ); + } + + fl_clip_region( 0 ); + CopyRgn( fl_window_region, GetPortClipRegion((GrafPtr)(i->xid), 0) ); // for Fl_GL_Window + return; +} + + +/** + * This block contains a collection of ideas to improve and carbonize the Mac port + * + * I found a note stating that in order to receive the + * MouseUp event I need to set some SystemEvent Mask. + * Although I do receive them, it might still be smart to look into this! + * + * I have to solve the subwindow linking problem (links + * get corrupted when widows get reparented or closed) + * + * The current subwindow inking allows only one level of + * subwindowing (which was correct for the first layout). + * I have to change it for arbitrary depths. + * + * There is supposedly a nice library out for Berkeley sockets. + * Check out www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html + * (Those Swiss people in Zuerich have the longest links :-) + * + * Alternative timers: + * - GetTicks(): TickCount(): simple, unreliable, 60th of a second + * - Microseconds(): about 1ms + * - UpTime(): nano second resultion, only PCI machines (ah well) + */ + +/* ---- sample hires timer (up to 20 microseconds!) +double MicrosecondToDouble(register const UnsignedWide *epochPtr) +{ + register double result; + + result = (((double) epochPtr->hi) * kTwoPower32) + epochPtr->lo; + return (result); +} + +void MicrosecondDelta(register const UnsignedWide *startPtr, + register const UnsignedWide *endPtr, + register SignedWide *resultPtr) +{ + if (endPtr->lo >= startPtr->lo) + resultPtr->hi = endPtr->hi - startPtr->hi; + else + resultPtr->hi = (endPtr->hi - 1) - startPtr->hi; + + resultPtr->lo = endPtr->lo - startPtr->lo; +} +*/ + +/* ---- sample UpTime() timer +AbsoluteTime startTime; +AbsoluteTime endTime; +AbsoluteTime elapsedTime; +Nanoseconds elapsedNanoseconds; + +startTime = UpTime(); +DoMyOperation(); +endTime = UpTime(); +elapsedTime = SubAbsoluteFromAbsolute(endTime, startTime); +elapsedNanoseconds = AbsoluteToNanoseconds(elapsedTime); +*/ + +// +// End of "$Id: Fl_mac.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// + diff --git a/src/Fl_own_colormap.cxx b/src/Fl_own_colormap.cxx index e13396dd5..53ea13146 100644 --- a/src/Fl_own_colormap.cxx +++ b/src/Fl_own_colormap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_own_colormap.cxx,v 1.4.2.3 2001/01/22 15:13:40 easysw Exp $" +// "$Id: Fl_own_colormap.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:06 easysw Exp $" // // Private colormap support for the Fast Light Tool Kit (FLTK). // @@ -41,6 +41,10 @@ void Fl::own_colormap() {} +#elif defined(__APPLE__) +// MacOS X always provides a TrueColor interface... + +void Fl::own_colormap() {} #else // X version @@ -73,5 +77,5 @@ void Fl::own_colormap() { #endif // -// End of "$Id: Fl_own_colormap.cxx,v 1.4.2.3 2001/01/22 15:13:40 easysw Exp $". +// End of "$Id: Fl_own_colormap.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_visual.cxx b/src/Fl_visual.cxx index ea8b1c8ed..82621eefb 100644 --- a/src/Fl_visual.cxx +++ b/src/Fl_visual.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_visual.cxx,v 1.7.2.4 2001/01/22 15:13:40 easysw Exp $" +// "$Id: Fl_visual.cxx,v 1.7.2.4.2.1 2001/11/27 17:44:06 easysw Exp $" // // Visual support for the Fast Light Tool Kit (FLTK). // @@ -38,6 +38,14 @@ int Fl::visual(int flags) { if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0; return 1; } +#elif defined(__APPLE__) + +//++ later +int Fl::visual(int flags) { + (void)flags; + return 1; +} + #else #if USE_XDBE @@ -107,5 +115,5 @@ int Fl::visual(int flags) { #endif // -// End of "$Id: Fl_visual.cxx,v 1.7.2.4 2001/01/22 15:13:40 easysw Exp $". +// End of "$Id: Fl_visual.cxx,v 1.7.2.4.2.1 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index bb0010f8b..5788181d6 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_x.cxx,v 1.24.2.24.2.6 2001/11/22 15:35:01 easysw Exp $" +// "$Id: Fl_x.cxx,v 1.24.2.24.2.7 2001/11/27 17:44:06 easysw Exp $" // // X specific code for the Fast Light Tool Kit (FLTK). // @@ -24,56 +24,57 @@ // #ifdef WIN32 -#include "Fl_win32.cxx" +# include "Fl_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_mac.cxx" #else -#define CONSOLIDATE_MOTION 1 +# define CONSOLIDATE_MOTION 1 /**** Define this if your keyboard lacks a backspace key... ****/ /* #define BACKSPACE_HACK 1 */ -#include <config.h> -#include <FL/Fl.H> -#include <FL/x.H> -#include <FL/Fl_Window.H> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> +# include <config.h> +# include <FL/Fl.H> +# include <FL/x.H> +# include <FL/Fl_Window.H> +# include <ctype.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +# include <unistd.h> +# include <sys/time.h> //////////////////////////////////////////////////////////////// // interface to poll/select call: -#if USE_POLL +# if USE_POLL -#include <poll.h> +# include <poll.h> static pollfd *pollfds = 0; -#else - -#if HAVE_SYS_SELECT_H -# include <sys/select.h> -#endif /* HAVE_SYS_SELECT_H */ +# else +# if HAVE_SYS_SELECT_H +# include <sys/select.h> +# endif /* HAVE_SYS_SELECT_H */ // The following #define is only needed for HP-UX 9.x and earlier: //#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e)) static fd_set fdsets[3]; static int maxfd; -#define POLLIN 1 -#define POLLOUT 4 -#define POLLERR 8 +# define POLLIN 1 +# define POLLOUT 4 +# define POLLERR 8 -#endif /* USE_POLL */ +# endif /* USE_POLL */ static int nfds = 0; static int fd_array_size = 0; struct FD { -#if !USE_POLL +# if !USE_POLL int fd; short events; -#endif +# endif void (*cb)(int, void*); void* arg; }; @@ -93,7 +94,7 @@ void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { if (!temp) return; fd = temp; -#if USE_POLL +# if USE_POLL pollfd *tpoll; if (!pollfds) tpoll = (pollfd*)malloc(fd_array_size*sizeof(pollfd)); @@ -101,21 +102,21 @@ void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { if (!tpoll) return; pollfds = tpoll; -#endif +# endif } fd[i].cb = cb; fd[i].arg = v; -#if USE_POLL +# if USE_POLL pollfds[i].fd = n; pollfds[i].events = events; -#else +# else fd[i].fd = n; fd[i].events = events; if (events & POLLIN) FD_SET(n, &fdsets[0]); if (events & POLLOUT) FD_SET(n, &fdsets[1]); if (events & POLLERR) FD_SET(n, &fdsets[2]); if (n > maxfd) maxfd = n; -#endif +# endif } void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { @@ -125,57 +126,57 @@ void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { void Fl::remove_fd(int n, int events) { int i,j; for (i=j=0; i<nfds; i++) { -#if USE_POLL +# if USE_POLL if (pollfds[i].fd == n) { int e = pollfds[i].events & ~events; if (!e) continue; // if no events left, delete this fd pollfds[j].events = e; } -#else +# else if (fd[i].fd == n) { int e = fd[i].events & ~events; if (!e) continue; // if no events left, delete this fd fd[i].events = e; } -#endif +# endif // move it down in the array if necessary: if (j<i) { fd[j] = fd[i]; -#if USE_POLL +# if USE_POLL pollfds[j] = pollfds[i]; -#endif +# endif } j++; } nfds = j; -#if !USE_POLL +# if !USE_POLL if (events & POLLIN) FD_CLR(n, &fdsets[0]); if (events & POLLOUT) FD_CLR(n, &fdsets[1]); if (events & POLLERR) FD_CLR(n, &fdsets[2]); if (n == maxfd) maxfd--; -#endif +# endif } void Fl::remove_fd(int n) { remove_fd(n, -1); } -#if CONSOLIDATE_MOTION +# if CONSOLIDATE_MOTION static Fl_Window* send_motion; extern Fl_Window* fl_xmousewin; -#endif +# endif static void do_queued_events() { while (XEventsQueued(fl_display,QueuedAfterReading)) { XEvent xevent; XNextEvent(fl_display, &xevent); fl_handle(xevent); } -#if CONSOLIDATE_MOTION +# if CONSOLIDATE_MOTION if (send_motion && send_motion == fl_xmousewin) { send_motion = 0; Fl::handle(FL_MOVE, fl_xmousewin); } -#endif +# endif } // This is never called with time_to_wait < 0.0: @@ -188,42 +189,42 @@ int fl_wait(double time_to_wait) { // so we must check for already-read events: if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;} -#if !USE_POLL +# if !USE_POLL fd_set fdt[3]; fdt[0] = fdsets[0]; fdt[1] = fdsets[1]; fdt[2] = fdsets[2]; -#endif +# endif int n; if (time_to_wait < 2147483.648) { -#if USE_POLL +# if USE_POLL n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5)); -#else +# else timeval t; t.tv_sec = int(time_to_wait); t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec)); n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t); -#endif +# endif } else { -#if USE_POLL +# if USE_POLL n = ::poll(pollfds, nfds, -1); -#else +# else n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0); -#endif +# endif } if (n > 0) { for (int i=0; i<nfds; i++) { -#if USE_POLL +# if USE_POLL if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg); -#else +# else int f = fd[i].fd; short revents = 0; if (FD_ISSET(f,&fdt[0])) revents |= POLLIN; if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT; if (FD_ISSET(f,&fdt[2])) revents |= POLLERR; if (fd[i].events & revents) fd[i].cb(f, fd[i].arg); -#endif +# endif } } return n; @@ -232,9 +233,9 @@ int fl_wait(double time_to_wait) { // fl_ready() is just like fl_wait(0.0) except no callbacks are done: int fl_ready() { if (XQLength(fl_display)) return 1; -#if USE_POLL +# if USE_POLL return ::poll(pollfds, nfds, 0); -#else +# else timeval t; t.tv_sec = 0; t.tv_usec = 0; @@ -243,7 +244,7 @@ int fl_ready() { fdt[1] = fdsets[1]; fdt[2] = fdsets[2]; return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t); -#endif +# endif } //////////////////////////////////////////////////////////////// @@ -304,9 +305,9 @@ void fl_open_display(Display* d) { fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num); fl_colormap = DefaultColormap(fl_display,fl_screen); -#if !USE_COLORMAP +# if !USE_COLORMAP Fl::visual(FL_RGB); -#endif +# endif } void fl_close_display() { @@ -346,19 +347,19 @@ static int px, py; static ulong ptime; static void set_event_xy() { -#if CONSOLIDATE_MOTION +# if CONSOLIDATE_MOTION send_motion = 0; -#endif +# endif Fl::e_x_root = fl_xevent->xbutton.x_root; Fl::e_x = fl_xevent->xbutton.x; Fl::e_y_root = fl_xevent->xbutton.y_root; Fl::e_y = fl_xevent->xbutton.y; Fl::e_state = fl_xevent->xbutton.state << 16; fl_event_time = fl_xevent->xbutton.time; -#ifdef __sgi +# ifdef __sgi // get the meta key off PC keyboards: if (fl_key_vector[18]&0x18) Fl::e_state |= FL_META; -#endif +# endif // turn off is_click if enough time or mouse movement has passed: if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3 || fl_event_time >= ptime+1000) @@ -434,12 +435,12 @@ int fl_handle(const XEvent& xevent) case Expose: Fl_X::i(window)->wait_for_expose = 0; -#if 0 +# if 0 // try to keep windows on top even if WM_TRANSIENT_FOR does not work: // opaque move/resize window managers do not like this, so I disabled it. if (Fl::first_window()->non_modal() && window != Fl::first_window()) Fl::first_window()->show(); -#endif +# endif case GraphicsExpose: window->damage(FL_DAMAGE_EXPOSE, xevent.xexpose.x, xevent.xexpose.y, @@ -464,13 +465,13 @@ int fl_handle(const XEvent& xevent) case MotionNotify: set_event_xy(); -#if CONSOLIDATE_MOTION +# if CONSOLIDATE_MOTION send_motion = fl_xmousewin = window; return 0; -#else +# else event = FL_MOVE; break; -#endif +# endif case ButtonRelease: Fl::e_keysym = FL_Button + xevent.xbutton.button; @@ -518,7 +519,7 @@ int fl_handle(const XEvent& xevent) // keyup events just get the unshifted keysym: keysym = XKeycodeToKeysym(fl_display, keycode, 0); } -#ifdef __sgi +# ifdef __sgi // You can plug a microsoft keyboard into an sgi but the extra shift // keys are not translated. Make them translate like XFree86 does: if (!keysym) switch(keycode) { @@ -526,8 +527,8 @@ int fl_handle(const XEvent& xevent) case 148: keysym = FL_Meta_R; break; case 149: keysym = FL_Menu; break; } -#endif -#if BACKSPACE_HACK +# endif +# if BACKSPACE_HACK // Attempt to fix keyboards that send "delete" for the key in the // upper-right corner of the main keyboard. But it appears that // very few of these remain? @@ -536,7 +537,7 @@ int fl_handle(const XEvent& xevent) if (keysym == FL_Delete) keysym = FL_BackSpace; else if (keysym == FL_BackSpace) got_backspace = 1; } -#endif +# endif // We have to get rid of the XK_KP_function keys, because they are // not produced on Windoze and thus case statements tend not to check // for them. There are 15 of these in the range 0xff91 ... 0xff9f @@ -936,5 +937,5 @@ void Fl_Window::make_current() { #endif // -// End of "$Id: Fl_x.cxx,v 1.24.2.24.2.6 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: Fl_x.cxx,v 1.24.2.24.2.7 2001/11/27 17:44:06 easysw Exp $". // diff --git a/src/Makefile b/src/Makefile index 6b7a920bb..12f9e70b8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.18.2.14.2.20 2001/11/24 18:07:57 easysw Exp $" +# "$Id: Makefile,v 1.18.2.14.2.21 2001/11/27 17:44:07 easysw Exp $" # # Library makefile for the Fast Light Tool Kit (FLTK). # @@ -221,8 +221,20 @@ depend: # $(MAKEDEPEND) -I.. $(CXXFLAGS) $(CPPFILES) $(CFILES) > makedepend makedepend -Y -I.. -f makedepend $(CPPFILES) $(GLCPPFILES) $(CFILES) +# Automatically generated dependencies... include makedepend +# These dependencies aren't part of the makedepend file since +# they are part of the WIN32 and MacOS code base... +Fl_cutpaste.o: Fl_cutpaste_mac.cxx Fl_cutpaste_win32.cxx +Fl_get_key.o: Fl_get_key_mac.cxx Fl_get_key_win32.cxx +Fl_x.o: Fl_mac.cxx Fl_win32.cxx +fl_color.o: fl_color_mac.cxx fl_color_win32.cxx +fl_draw_image.o: fl_draw_image_mac.cxx fl_draw_image_win32.cxx +fl_font.o: fl_font_mac.cxx fl_font_win32.cxx +fl_set_fonts.o: fl_set_fonts_mac.cxx fl_set_fonts_win32.cxx + + ################################################################ install: $(LIBNAME) $(DSONAME) $(GLLIBNAME) $(GLDSONAME) @@ -284,5 +296,5 @@ uninstall: # -# End of "$Id: Makefile,v 1.18.2.14.2.20 2001/11/24 18:07:57 easysw Exp $". +# End of "$Id: Makefile,v 1.18.2.14.2.21 2001/11/27 17:44:07 easysw Exp $". # diff --git a/src/fl_arci.cxx b/src/fl_arci.cxx index b5a6576fe..7ea47f2f9 100644 --- a/src/fl_arci.cxx +++ b/src/fl_arci.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_arci.cxx,v 1.4.2.5 2001/01/22 15:13:40 easysw Exp $" +// "$Id: fl_arci.cxx,v 1.4.2.5.2.1 2001/11/27 17:44:07 easysw Exp $" // // Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK). // @@ -47,6 +47,10 @@ void fl_arc(int x,int y,int w,int h,double a1,double a2) { int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); +#elif defined(__APPLE__) + Rect r; r.left=x; r.right=x+w; r.top=y; r.bottom=y+h; + a1 = a2-a1; a2 = 450-a2; + FrameArc(&r, a2, a1); #else XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); #endif @@ -62,11 +66,15 @@ void fl_pie(int x,int y,int w,int h,double a1,double a2) { int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); SelectObject(fl_gc, fl_brush()); Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); +#elif defined(__APPLE__) + Rect r; r.left=x; r.right=x+w; r.top=y; r.bottom=y+h; + a1 = a2-a1; a2 = 450-a2; + PaintArc(&r, a2, a1); #else XFillArc(fl_display, fl_window, fl_gc, x,y,w,h, int(a1*64),int((a2-a1)*64)); #endif } // -// End of "$Id: fl_arci.cxx,v 1.4.2.5 2001/01/22 15:13:40 easysw Exp $". +// End of "$Id: fl_arci.cxx,v 1.4.2.5.2.1 2001/11/27 17:44:07 easysw Exp $". // diff --git a/src/fl_ask.cxx b/src/fl_ask.cxx index 3107ba0f5..171a50896 100644 --- a/src/fl_ask.cxx +++ b/src/fl_ask.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_ask.cxx,v 1.8.2.8.2.3 2001/11/25 16:38:11 easysw Exp $" +// "$Id: fl_ask.cxx,v 1.8.2.8.2.4 2001/11/27 17:44:08 easysw Exp $" // // Standard dialog functions for the Fast Light Tool Kit (FLTK). // @@ -90,7 +90,8 @@ static int innards(const char* fmt, va_list ap, if (!strcmp(fmt,"%s")) { message->label(va_arg(ap, const char*)); } else { - vsnprintf(buffer, 1024, fmt, ap); + //: matt: MacOS provides two equally named vsnprintf's... + ::vsnprintf(buffer, 1024, fmt, ap); message->label(buffer); } Fl_Font f = (Fl_Font)fl_message_font_; @@ -144,6 +145,15 @@ void fl_beep(int type) { MessageBeep(MB_ICONERROR); break; } +#elif defined(__APPLE__) + switch (type) { + case FL_BEEP_DEFAULT : + case FL_BEEP_ERROR : + SysBeep( 30 ); + break; + default : + break; + } #else switch (type) { case FL_BEEP_DEFAULT : @@ -249,5 +259,5 @@ const char *fl_password(const char *fmt, const char *defstr, ...) { } // -// End of "$Id: fl_ask.cxx,v 1.8.2.8.2.3 2001/11/25 16:38:11 easysw Exp $". +// End of "$Id: fl_ask.cxx,v 1.8.2.8.2.4 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_color.cxx b/src/fl_color.cxx index a64d7a93a..1873c1870 100644 --- a/src/fl_color.cxx +++ b/src/fl_color.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_color.cxx,v 1.12.2.5.2.3 2001/11/22 15:35:01 easysw Exp $" +// "$Id: fl_color.cxx,v 1.12.2.5.2.4 2001/11/27 17:44:08 easysw Exp $" // // Color functions for the Fast Light Tool Kit (FLTK). // @@ -26,7 +26,9 @@ // Implementation of fl_color(i), fl_color(r,g,b). #ifdef WIN32 -#include "fl_color_win32.cxx" +# include "fl_color_win32.cxx" +#elif defined(__APPLE__) +# include "fl_color_mac.cxx" #else // Also code to look at the X visual and figure out the best way to turn @@ -36,10 +38,10 @@ // being used to index arrays. So I always copy them to an integer // before use. -#include "Fl_XColor.H" -#include <FL/Fl.H> -#include <FL/x.H> -#include <FL/fl_draw.H> +# include "Fl_XColor.H" +# include <FL/Fl.H> +# include <FL/x.H> +# include <FL/fl_draw.H> //////////////////////////////////////////////////////////////// // figure_out_visual() calculates masks & shifts for generating @@ -52,12 +54,12 @@ static uchar beenhere; static void figure_out_visual() { beenhere = 1; if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){ -#if USE_COLORMAP +# if USE_COLORMAP fl_redmask = 0; return; -#else +# else Fl::fatal("Requires true color visual"); -#endif +# endif } // get the bit masks into a more useful form: @@ -93,16 +95,16 @@ static unsigned fl_cmap[256] = { #include "fl_cmap.h" // this is a file produced by "cmap.cxx": }; -#if HAVE_OVERLAY +# if HAVE_OVERLAY Fl_XColor fl_xmap[2][256]; uchar fl_overlay; Colormap fl_overlay_colormap; XVisualInfo* fl_overlay_visual; ulong fl_transparent_pixel; -#else +# else Fl_XColor fl_xmap[1][256]; -#define fl_overlay 0 -#endif +# define fl_overlay 0 +# endif //////////////////////////////////////////////////////////////// // Get an rgb color. This is easy for a truecolor visual. For @@ -113,7 +115,7 @@ Fl_XColor fl_xmap[1][256]; ulong fl_xpixel(uchar r,uchar g,uchar b) { if (!beenhere) figure_out_visual(); -#if USE_COLORMAP +# if USE_COLORMAP if (!fl_redmask) { // find closest entry in the colormap: Fl_Color i = @@ -125,7 +127,7 @@ ulong fl_xpixel(uchar r,uchar g,uchar b) { fl_cmap[i] = (r<<24)|(g<<16)|(b<<8); return fl_xpixel(i); // allocate an X color } -#endif +# endif return (((r&fl_redmask) << fl_redshift)+ ((g&fl_greenmask)<<fl_greenshift)+ @@ -145,7 +147,7 @@ void fl_color(uchar r,uchar g,uchar b) { // calculate what color is actually on the screen for a mask: static inline uchar realcolor(uchar color, uchar mask) { -#if 0 +# if 0 // accurate version if the display has linear gamma, but fl_draw_image // works better with the simpler version on most screens... uchar m = mask; @@ -157,9 +159,9 @@ static inline uchar realcolor(uchar color, uchar mask) { result |= color&m; } return result; -#else +# else return (color&mask) | (~mask)&(mask>>1); -#endif +# endif } ulong fl_xpixel(Fl_Color i) { @@ -171,13 +173,13 @@ ulong fl_xpixel(Fl_Color i) { uchar r,g,b; {unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);} -#if USE_COLORMAP +# if USE_COLORMAP Colormap colormap = fl_colormap; -#if HAVE_OVERLAY +# if HAVE_OVERLAY if (fl_overlay) colormap = fl_overlay_colormap; else -#endif +# endif if (fl_redmask) { -#endif +# endif // return color for a truecolor visual: xmap.mapped = 2; // 2 prevents XFreeColor from being called xmap.r = realcolor(r, fl_redmask); @@ -188,17 +190,17 @@ ulong fl_xpixel(Fl_Color i) { ((g&fl_greenmask)<<fl_greenshift)+ ((b&fl_bluemask)<< fl_blueshift) ) >> fl_extrashift; -#if USE_COLORMAP +# if USE_COLORMAP } -#if HAVE_OVERLAY +# if HAVE_OVERLAY static XColor* ac[2]; XColor*& allcolors = ac[fl_overlay]; static int nc[2]; int& numcolors = nc[fl_overlay]; -#else +# else static XColor *allcolors; static int numcolors; -#endif +# endif // I don't try to allocate colors with XAllocColor once it fails // with any color. It is possible that it will work, since a color @@ -218,9 +220,9 @@ ulong fl_xpixel(Fl_Color i) { // I only read the colormap once. Again this is due to the slowness // of round-trips to the X server, even though other programs may alter // the colormap after this and make decisions here wrong. -#if HAVE_OVERLAY +# if HAVE_OVERLAY if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else -#endif +# endif numcolors = fl_visual->colormap_size; if (!allcolors) allcolors = new XColor[numcolors]; for (int p = numcolors; p--;) allcolors[p].pixel = p; @@ -231,9 +233,9 @@ ulong fl_xpixel(Fl_Color i) { int mindist = 0x7FFFFFFF; unsigned int bestmatch = 0; for (unsigned int n = numcolors; n--;) { -#if HAVE_OVERLAY +# if HAVE_OVERLAY if (fl_overlay && n == fl_transparent_pixel) continue; -#endif +# endif XColor &a = allcolors[n]; int d, t; t = int(r)-int(a.red>>8); d = t*t; @@ -263,7 +265,7 @@ ulong fl_xpixel(Fl_Color i) { xmap.g = p.green>>8; xmap.b = p.blue>>8; return xmap.pixel; -#endif +# endif } Fl_Color fl_color_; @@ -279,20 +281,20 @@ void fl_color(Fl_Color i) { } void Fl::free_color(Fl_Color i, int overlay) { -#if HAVE_OVERLAY -#else +# if HAVE_OVERLAY +# else if (overlay) return; -#endif +# endif if (fl_xmap[overlay][i].mapped) { -#if USE_COLORMAP -#if HAVE_OVERLAY +# if USE_COLORMAP +# if HAVE_OVERLAY Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap; -#else +# else Colormap colormap = fl_colormap; -#endif +# endif if (fl_xmap[overlay][i].mapped == 1) XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0); -#endif +# endif fl_xmap[overlay][i].mapped = 0; } } @@ -300,9 +302,9 @@ void Fl::free_color(Fl_Color i, int overlay) { void Fl::set_color(Fl_Color i, unsigned c) { if (fl_cmap[i] != c) { free_color(i,0); -#if HAVE_OVERLAY +# if HAVE_OVERLAY free_color(i,1); -#endif +# endif fl_cmap[i] = c; } } @@ -370,5 +372,5 @@ Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { } // -// End of "$Id: fl_color.cxx,v 1.12.2.5.2.3 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: fl_color.cxx,v 1.12.2.5.2.4 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_color_mac.cxx b/src/fl_color_mac.cxx new file mode 100644 index 000000000..895c6ccbf --- /dev/null +++ b/src/fl_color_mac.cxx @@ -0,0 +1,89 @@ +// +// "$Id: fl_color_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $" +// +// MacOS color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +// The fltk "colormap". This allows ui colors to be stored in 8-bit +// locations, and provides a level of indirection so that global color +// changes can be made. Not to be confused with the X colormap, which +// I try to hide completely. + +// MacOS - matt: the macintosh port does not support colormaps + +#include <config.h> +#include <FL/Fl.H> +#include <FL/mac.H> +#include <FL/fl_draw.H> + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +// Translations to mac data structures: +Fl_XMap fl_xmap[256]; + +Fl_XMap* fl_current_xmap; + +Fl_Color fl_color_; + +void fl_color(Fl_Color i) { + fl_color_ = i; + int index; + uchar r, g, b; + if (i & 0xFFFFFF00) { + // translate rgb colors into color index + r = i>>24; + g = i>>16; + b = i>> 8; + } else { + // translate index into rgb: + index = i; + unsigned c = fl_cmap[i]; + r = c>>24; + g = c>>16; + b = c>> 8; + } + RGBColor rgb; + rgb.red = (r<<8)|r; + rgb.green = (g<<8)|g; + rgb.blue = (b<<8)|b; + RGBForeColor(&rgb); +} + +void fl_color(uchar r, uchar g, uchar b) { + RGBColor rgb; + rgb.red = (r<<8)|r; + rgb.green = (g<<8)|g; + rgb.blue = (b<<8)|b; + RGBForeColor(&rgb); +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + fl_cmap[i] = c; + } +} + +// +// End of "$Id: fl_color_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $". +// diff --git a/src/fl_cursor.cxx b/src/fl_cursor.cxx index aa7249e25..af9676cc7 100644 --- a/src/fl_cursor.cxx +++ b/src/fl_cursor.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_cursor.cxx,v 1.6.2.6 2001/01/22 15:13:40 easysw Exp $" +// "$Id: fl_cursor.cxx,v 1.6.2.6.2.1 2001/11/27 17:44:08 easysw Exp $" // // Mouse cursor support for the Fast Light Tool Kit (FLTK). // @@ -32,8 +32,8 @@ #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/x.H> -#ifndef WIN32 -#include <X11/cursorfont.h> +#if !defined(WIN32) && !defined(__APPLE__) +# include <X11/cursorfont.h> #endif #include <FL/fl_draw.H> @@ -95,6 +95,46 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) { SetCursor(i->cursor); } +#elif defined(__APPLE__) + +static Cursor crsrNS = +{ + { 0x0000, 0x0180, 0x03c0, 0x07e0, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x0180, 0x0180, 0x0180, 0x07e0, 0x03c0, 0x0180, 0x0000 }, + { 0x0180, 0x03c0, 0x07e0, 0x0ff0, 0x0ff0, 0x03c0, 0x03c0, 0x03c0, + 0x03c0, 0x03c0, 0x03c0, 0x0ff0, 0x0ff0, 0x07e0, 0x03c0, 0x0180 }, + { 8, 8 } +}, *crsrNSptr = &crsrNS; + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) { + if (!shown()) return; + switch (c) { + case FL_CURSOR_CROSS: i->cursor = GetCursor( crossCursor ); break; + case FL_CURSOR_WAIT: i->cursor = GetCursor( watchCursor ); break; + case FL_CURSOR_NS: i->cursor = &crsrNSptr; break; + case FL_CURSOR_INSERT: //++ the following shapes are missing... + case FL_CURSOR_HELP: + case FL_CURSOR_HAND: + case FL_CURSOR_MOVE: + case FL_CURSOR_N: + case FL_CURSOR_S: + case FL_CURSOR_NE: + case FL_CURSOR_SW: + case FL_CURSOR_NESW: + case FL_CURSOR_E: + case FL_CURSOR_W: + case FL_CURSOR_WE: + case FL_CURSOR_SE: + case FL_CURSOR_NW: + case FL_CURSOR_NWSE: + case FL_CURSOR_ARROW: + case FL_CURSOR_DEFAULT: + default: + i->cursor = fl_default_cursor; break; + } + SetCursor( *i->cursor ); +} + #else // I like the MSWindows resize cursors, so I duplicate them here: @@ -184,5 +224,5 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { #endif // -// End of "$Id: fl_cursor.cxx,v 1.6.2.6 2001/01/22 15:13:40 easysw Exp $". +// End of "$Id: fl_cursor.cxx,v 1.6.2.6.2.1 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_draw_image.cxx b/src/fl_draw_image.cxx index 15102f52c..c54b2aed1 100644 --- a/src/fl_draw_image.cxx +++ b/src/fl_draw_image.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image.cxx,v 1.5.2.6.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: fl_draw_image.cxx,v 1.5.2.6.2.2 2001/11/27 17:44:08 easysw Exp $" // // Image drawing routines for the Fast Light Tool Kit (FLTK). // @@ -34,7 +34,9 @@ // defeat some of the shortcuts in translating the image for X. #ifdef WIN32 -#include "fl_draw_image_win32.cxx" +# include "fl_draw_image_win32.cxx" +#elif defined(__APPLE__) +# include "fl_draw_image_mac.cxx" #else // A list of assumptions made about the X display: @@ -55,11 +57,11 @@ //////////////////////////////////////////////////////////////// -#include <FL/Fl.H> -#include <FL/fl_draw.H> -#include <FL/x.H> -#include "Fl_XColor.H" -#include <string.h> +# include <FL/Fl.H> +# include <FL/fl_draw.H> +# include <FL/x.H> +# include "Fl_XColor.H" +# include <string.h> static XImage i; // template used to pass info to X static int bytes_per_pixel; @@ -72,7 +74,7 @@ static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta); static int dir; // direction-alternator static int ri,gi,bi; // saved error-diffusion value -#if USE_COLORMAP +# if USE_COLORMAP //////////////////////////////////////////////////////////////// // 8-bit converter with error diffusion @@ -134,22 +136,22 @@ static void mono8_converter(const uchar *from, uchar *to, int w, int delta) { ri = r; gi = g; bi = b; } -#endif +# endif //////////////////////////////////////////////////////////////// // 16 bit TrueColor converters with error diffusion // Cray computers have no 16-bit type, so we use character pointers // (which may be slow) -#ifdef U16 -#define OUTTYPE U16 -#define OUTSIZE 1 -#define OUTASSIGN(v) *t = v -#else -#define OUTTYPE uchar -#define OUTSIZE 2 -#define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt) -#endif +# ifdef U16 +# define OUTTYPE U16 +# define OUTSIZE 1 +# define OUTASSIGN(v) *t = v +# else +# define OUTTYPE uchar +# define OUTSIZE 2 +# define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt) +# endif static void color16_converter(const uchar *from, uchar *to, int w, int delta) { OUTTYPE *t = (OUTTYPE *)to; @@ -288,24 +290,24 @@ static void rrr_converter(const uchar *from, uchar *to, int w, int delta) { //////////////////////////////////////////////////////////////// // 32bit TrueColor converters on a 32 or 64-bit machine: -#ifdef U64 -#define STORETYPE U64 -#if WORDS_BIGENDIAN -#define INNARDS32(f) \ +# ifdef U64 +# define STORETYPE U64 +# if WORDS_BIGENDIAN +# define INNARDS32(f) \ U64 *t = (U64*)to; \ int w1 = (w+1)/2; \ for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);} -#else -#define INNARDS32(f) \ +# else +# define INNARDS32(f) \ U64 *t = (U64*)to; \ int w1 = (w+1)/2; \ for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;} -#endif -#else -#define STORETYPE U32 -#define INNARDS32(f) \ +# endif +# else +# define STORETYPE U32 +# define INNARDS32(f) \ U32 *t = (U32*)to; for (; w--; from += delta) *t++ = f -#endif +# endif static void rgbx_converter(const uchar *from, uchar *to, int w, int delta) { INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8)); @@ -374,7 +376,7 @@ static void figure_out_visual() { scanline_add = n-1; scanline_mask = -n; -#if USE_COLORMAP +# if USE_COLORMAP if (bytes_per_pixel == 1) { converter = color8_converter; mono_converter = mono8_converter; @@ -382,7 +384,7 @@ static void figure_out_visual() { } if (!fl_visual->red_mask) Fl::fatal("Can't do %d bits_per_pixel colormap",i.bits_per_pixel); -#endif +# endif // otherwise it is a TrueColor visual: @@ -395,11 +397,11 @@ static void figure_out_visual() { case 2: // All 16-bit TrueColor visuals are supported on any machine with // 24 or more bits per integer. -#ifdef U16 +# ifdef U16 ::i.byte_order = WORDS_BIGENDIAN; -#else +# else ::i.byte_order = 1; -#endif +# endif if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) { converter = c565_converter; mono_converter = m565_converter; @@ -450,7 +452,7 @@ static void figure_out_visual() { } -#define MAXBUFFER 0x40000 // 256k +# define MAXBUFFER 0x40000 // 256k static void innards(const uchar *buf, int X, int Y, int W, int H, int delta, int linedelta, int mono, @@ -478,15 +480,15 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, // This can set bytes_per_line negative if image is bottom-to-top // I tested it on Linux, but it may fail on other Xlib implementations: if (buf && ( -#if 0 // set this to 1 to allow 32-bit shortcut +# if 0 // set this to 1 to allow 32-bit shortcut delta == 4 && -#if WORDS_BIGENDIAN +# if WORDS_BIGENDIAN conv == rgbx_converter -#else +# else conv == xbgr_converter -#endif +# endif || -#endif +# endif conv == rgb_converter && delta==3 ) && !(linedelta&scanline_add)) { i.data = (char *)(buf+delta*dx+linedelta*dy); @@ -522,11 +524,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k); } } else { -#ifdef __GNUC__ - STORETYPE linebuf[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)]; -#else STORETYPE* linebuf = new STORETYPE[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)]; -#endif for (int j=0; j<h; ) { STORETYPE *to = buffer; int k; @@ -537,9 +535,8 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k); } -#ifndef __GNUC__ + delete[] linebuf; -#endif } } } @@ -573,5 +570,5 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { #endif // -// End of "$Id: fl_draw_image.cxx,v 1.5.2.6.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: fl_draw_image.cxx,v 1.5.2.6.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_draw_image_mac.cxx b/src/fl_draw_image_mac.cxx new file mode 100644 index 000000000..7a7cf4663 --- /dev/null +++ b/src/fl_draw_image_mac.cxx @@ -0,0 +1,364 @@ +// +// "$Id: fl_draw_image_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $" +// +// MacOS image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +//////////////////////////////////////////////////////////////// + +#include <config.h> +#include <FL/Fl.H> +#include <FL/fl_draw.H> +#include <FL/x.H> + +#define MAXBUFFER 0x40000 // 256k + +/** + * draw an image based on the input parameters + * + * buf: image source data + * X, Y: position (in buffer?!) + * W, H: size of picture (in pixel?) + * delta: distance from pixel to pixel in buf in bytes + * linedelta: distance from line to line in buf in bytes + * mono: if set, pixel is one byte - if zero, pixel is 3 byte + * cb: callback to copy image data into (RGB?) buffer + * buf: pointer to first byte in image source + * x, y: position in buffer + * w: width (in bytes?) + * dst: destinaation buffer + * userdata: ? + */ +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int mono, + Fl_Draw_Image_Cb cb, void* userdata) +{ + if (!linedelta) linedelta = W*delta; + + // theoretically, if the current GPort permits, we could write + // directly into it, avoiding the temporary GWorld. For now I + // will go the safe way... . + char direct = 0; + GWorldPtr gw; + Rect bounds; + bounds.left=0; bounds.right=W; bounds.top=0; bounds.bottom=H; + QDErr err = NewGWorld( &gw, 32, &bounds, 0L, 0L, useTempMem ); + if (err==noErr && gw) { + PixMapHandle pm = GetGWorldPixMap( gw ); + if ( pm ) { + LockPixels( pm ); + if ( *pm ) { + uchar *base = (uchar*)GetPixBaseAddr( pm ); + if ( base ) { + PixMapPtr pmp = *pm; + // make absolutely sure that we can use a direct memory write to + // create the pixmap! + if ( pmp->pixelType == 16 || pmp->pixelSize == 32 || pmp->cmpCount == 3 || pmp->cmpSize == 8 ) { + int rowBytes = pmp->rowBytes & 0x3fff; + if ( cb ) + { + uchar *tmpBuf = new uchar[ W*delta ]; + if ( mono ) delta -= 1; else delta -= 3; + for ( int i=0; i<H; i++ ) + { + uchar *src = tmpBuf; + uchar *dst = base + i*rowBytes; + cb( userdata, 0, i, W, tmpBuf ); + if ( mono ) { + for ( int j=0; j<W; j++ ) + { uchar c = *src++; *dst++ = 0; *dst++ = c; *dst++ = c; *dst++ = c; src += delta; } + } else { + for ( int j=0; j<W; j++ ) + { *dst++ = 0; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; src += delta; } + } + } + delete[] tmpBuf; + } + else + { + if ( mono ) delta -= 1; else delta -= 3; + for ( int i=0; i<H; i++ ) + { + const uchar *src = buf+i*linedelta; + uchar *dst = base + i*rowBytes; + if ( mono ) { + for ( int j=0; j<W; j++ ) + { uchar c = *src++; *dst++ = 0; *dst++ = c; *dst++ = c; *dst++ = c; src += delta; } + } else { + for ( int j=0; j<W; j++ ) + { *dst++ = 0; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; src += delta; } + } + } + } + + fl_copy_offscreen( X, Y, W, H, gw, 0, 0 ); + direct = 1; + } + } + } + + UnlockPixels( pm ); + } + + DisposeGWorld( gw ); + } + + if ( direct ) + return; + + // following the very save (and very slow) way to write the image into the give port + if ( cb ) + { + uchar *tmpBuf = new uchar[ W*3 ]; + for ( int i=0; i<H; i++ ) + { + uchar *src = tmpBuf; + cb( userdata, 0, i, W, tmpBuf ); + for ( int j=0; j<W; j++ ) + { + if ( mono ) + { fl_color( src[0], src[0], src[0] ); src++; } + else + { fl_color( src[0], src[1], src[2] ); src+=3; } + MoveTo( X+j, Y+i ); + Line( 0, 0 ); + } + } + delete[] tmpBuf; + } + else + { + for ( int i=0; i<H; i++ ) + { + const uchar *src = buf+i*linedelta; + for ( int j=0; j<W; j++ ) + { + if ( mono ) + fl_color( src[0], src[0], src[0] ); + else + fl_color( src[0], src[1], src[2] ); + MoveTo( X+j, Y+i ); + Line( 0, 0 ); + src += delta; + } + } + } + +#ifdef __APPLE__ +//++ the above function does not support subregions yet +#ifdef later_we_do_this +// if (!linedelta) linedelta = W*delta; + + int x, y, w, h; + fl_clip_box(X,Y,W,H,x,y,w,h); + if (w<=0 || h<=0) return; + if (buf) buf += (x-X)*delta + (y-Y)*linedelta; + +// static U32 bmibuffer[256+12]; +// BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer); +// if (!bmi.bmiHeader.biSize) { +// bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type? +// bmi.bmiHeader.biPlanes = 1; +// bmi.bmiHeader.biCompression = BI_RGB; +// bmi.bmiHeader.biXPelsPerMeter = 0; +// bmi.bmiHeader.biYPelsPerMeter = 0; +// bmi.bmiHeader.biClrUsed = 0; +// bmi.bmiHeader.biClrImportant = 0; +// } +// if (mono) { +// for (int i=0; i<256; i++) { +// bmi.bmiColors[i].rgbBlue = i; +// bmi.bmiColors[i].rgbGreen = i; +// bmi.bmiColors[i].rgbRed = i; +// bmi.bmiColors[i].rgbReserved = i; +// } +// } +// bmi.bmiHeader.biWidth = w; +// bmi.bmiHeader.biBitCount = mono ? 8 : 24; + int pixelsize = mono ? 1 : 3; + int linesize = (pixelsize*w+3)&~3; + + static U32* buffer; + int blocking = h; + {int size = linesize*h; + if (size > MAXBUFFER) { + size = MAXBUFFER; + blocking = MAXBUFFER/linesize; + } + static long buffer_size; + if (size > buffer_size) { + delete[] buffer; + buffer_size = size; + buffer = new U32[(size+3)/4]; + }} +// bmi.bmiHeader.biHeight = blocking; + static U32* line_buffer; + if (!buf) { + int size = W*delta; + static int line_buf_size; + if (size > line_buf_size) { + delete[] line_buffer; + line_buf_size = size; + line_buffer = new U32[(size+3)/4]; + } + } + for (int j=0; j<h; ) { + int k; + for (k = 0; j<h && k<blocking; k++, j++) { + const uchar* from; + if (!buf) { // run the converter: + cb(userdata, x-X, y-Y+j, w, (uchar*)line_buffer); + from = (uchar*)line_buffer; + } else { + from = buf; + buf += linedelta; + } + uchar *to = (uchar*)buffer+(blocking-k-1)*linesize; + if (mono) { + for (int i=w; i--; from += delta) *to++ = *from; + } else { + for (int i=w; i--; from += delta, to += 3) { + uchar r = from[0]; + to[0] = from[2]; + to[1] = from[1]; + to[2] = r; + } + } + } +// SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, +// (LPSTR)((uchar*)buffer+(blocking-k)*linesize), +// &bmi, +// DIB_RGB_COLORS +// ); + } +#endif +#else + if (!linedelta) linedelta = W*delta; + + int x, y, w, h; + fl_clip_box(X,Y,W,H,x,y,w,h); + if (w<=0 || h<=0) return; + if (buf) buf += (x-X)*delta + (y-Y)*linedelta; + + static U32 bmibuffer[256+12]; + BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer); + if (!bmi.bmiHeader.biSize) { + bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type? + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + } + if (mono) { + for (int i=0; i<256; i++) { + bmi.bmiColors[i].rgbBlue = i; + bmi.bmiColors[i].rgbGreen = i; + bmi.bmiColors[i].rgbRed = i; + bmi.bmiColors[i].rgbReserved = i; + } + } + bmi.bmiHeader.biWidth = w; + bmi.bmiHeader.biBitCount = mono ? 8 : 24; + int pixelsize = mono ? 1 : 3; + int linesize = (pixelsize*w+3)&~3; + + static U32* buffer; + int blocking = h; + {int size = linesize*h; + if (size > MAXBUFFER) { + size = MAXBUFFER; + blocking = MAXBUFFER/linesize; + } + static long buffer_size; + if (size > buffer_size) { + delete[] buffer; + buffer_size = size; + buffer = new U32[(size+3)/4]; + }} + bmi.bmiHeader.biHeight = blocking; + static U32* line_buffer; + if (!buf) { + int size = W*delta; + static int line_buf_size; + if (size > line_buf_size) { + delete[] line_buffer; + line_buf_size = size; + line_buffer = new U32[(size+3)/4]; + } + } + for (int j=0; j<h; ) { + int k; + for (k = 0; j<h && k<blocking; k++, j++) { + const uchar* from; + if (!buf) { // run the converter: + cb(userdata, x-X, y-Y+j, w, (uchar*)line_buffer); + from = (uchar*)line_buffer; + } else { + from = buf; + buf += linedelta; + } + uchar *to = (uchar*)buffer+(blocking-k-1)*linesize; + if (mono) { + for (int i=w; i--; from += delta) *to++ = *from; + } else { + for (int i=w; i--; from += delta, to += 3) { + uchar r = from[0]; + to[0] = from[2]; + to[1] = from[1]; + to[2] = r; + } + } + } + SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, + (LPSTR)((uchar*)buffer+(blocking-k)*linesize), + &bmi, + DIB_RGB_COLORS + ); + } +#endif +} + +void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ + innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); +} +void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); +} +void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + innards(buf,x,y,w,h,d,l,1,0,0); +} +void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,1,cb,data); +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { + fl_color(r,g,b); + fl_rectf(x,y,w,h); +} + +// +// End of "$Id: fl_draw_image_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $". +// diff --git a/src/fl_draw_pixmap.cxx b/src/fl_draw_pixmap.cxx index 3e3b2b64d..65a766d3a 100644 --- a/src/fl_draw_pixmap.cxx +++ b/src/fl_draw_pixmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_pixmap.cxx,v 1.4.2.8.2.3 2001/11/22 15:35:01 easysw Exp $" +// "$Id: fl_draw_pixmap.cxx,v 1.4.2.8.2.4 2001/11/27 17:44:08 easysw Exp $" // // Pixmap drawing code for the Fast Light Tool Kit (FLTK). // @@ -131,7 +131,7 @@ static void cb2(void*v, int x, int y, int w, uchar* buf) { #endif -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) // this is in Fl_arg.cxx: extern int fl_parse_color(const char*, uchar&, uchar&, uchar&); #endif @@ -218,7 +218,7 @@ int fl_draw_pixmap(const char*const* di, int x, int y, Fl_Color bg) { c += 4; #endif #endif -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) if (fl_parse_color((const char*)p, c[0], c[1], c[2])) {; #else XColor x; @@ -273,5 +273,5 @@ int fl_draw_pixmap(const char*const* di, int x, int y, Fl_Color bg) { } // -// End of "$Id: fl_draw_pixmap.cxx,v 1.4.2.8.2.3 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: fl_draw_pixmap.cxx,v 1.4.2.8.2.4 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_font.cxx b/src/fl_font.cxx index fce2deeee..e88eaa8ce 100644 --- a/src/fl_font.cxx +++ b/src/fl_font.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font.cxx,v 1.9.2.5 2001/01/22 15:13:41 easysw Exp $" +// "$Id: fl_font.cxx,v 1.9.2.5.2.1 2001/11/27 17:44:08 easysw Exp $" // // Font selection code for the Fast Light Tool Kit (FLTK). // @@ -26,18 +26,20 @@ // Select fonts from the fltk font table. #ifdef WIN32 -#include "fl_font_win32.cxx" +# include "fl_font_win32.cxx" +#elif defined(__APPLE__) +# include "fl_font_mac.cxx" #else -#include <config.h> -#include <FL/Fl.H> -#include <FL/fl_draw.H> -#include <FL/x.H> -#include "Fl_Font.H" +# include <config.h> +# include <FL/Fl.H> +# include <FL/fl_draw.H> +# include <FL/x.H> +# include "Fl_Font.H" -#include <ctype.h> -#include <stdlib.h> -#include <string.h> +# include <ctype.h> +# include <stdlib.h> +# include <string.h> Fl_FontSize::Fl_FontSize(const char* name) { font = XLoadQueryFont(fl_display, name); @@ -45,15 +47,15 @@ Fl_FontSize::Fl_FontSize(const char* name) { Fl::warning("bad font: %s", name); font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash } -#if HAVE_GL +# if HAVE_GL listbase = 0; -#endif +# endif } Fl_FontSize* fl_fontsize; Fl_FontSize::~Fl_FontSize() { -#if HAVE_GL +# if HAVE_GL // Delete list created by gl_draw(). This is not done by this code // as it will link in GL unnecessarily. There should be some kind // of "free" routine pointer, or a subclass? @@ -63,7 +65,7 @@ Fl_FontSize::~Fl_FontSize() { // int base = 0; int size = 256; // glDeleteLists(listbase+base,size); // } -#endif +# endif if (this == fl_fontsize) fl_fontsize = 0; XFreeFont(fl_display, font); } @@ -293,5 +295,5 @@ void fl_draw(const char* str, int x, int y) { #endif // -// End of "$Id: fl_font.cxx,v 1.9.2.5 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: fl_font.cxx,v 1.9.2.5.2.1 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx new file mode 100644 index 000000000..5d8e61247 --- /dev/null +++ b/src/fl_font_mac.cxx @@ -0,0 +1,176 @@ +// +// "$Id: fl_font_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $" +// +// MacOS font selection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +//: MeasureText, FontMetrics, WidthTabHandle, GetSysFont, SysFontSize +//: TextSize, TextFont +//: GetFNum (theName: Str255; VAR familyID: Integer); +//: FUNCTION FMSwapFont (inRec: FMInput): FMOutPtr; + + +#include <config.h> +#include <FL/Fl.H> +#include <FL/fl_draw.H> +#include <FL/mac.H> +#include "Fl_Font.h" + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +Fl_FontSize::Fl_FontSize(const char* name, int Size) { + knowMetrics = 0; + switch (*name++) { + case 'I': face = italic; break; + case 'P': face = italic | bold; break; + case 'B': face = bold; break; + default: face = 0; break; + } + unsigned char fn[80]; + fn[0] = strlen(name); strcpy((char*)(fn+1), name); + GetFNum(fn, &font); + size = Size; + FMInput fIn = { font, size, face, 0, 0, { 1, 1}, { 1, 1} }; + FMOutput *fOut = FMSwapFont(&fIn); + ascent = fOut->ascent; //: the following three lines give only temporary aproimations + descent = fOut->descent; + for (int i=0; i<256; i++) width[i] = fOut->widMax; +#if HAVE_GL + listbase = 0; +#endif + minsize = maxsize = size; +} + +Fl_FontSize* fl_fontsize = 0L; + +Fl_FontSize::~Fl_FontSize() { +/* +#if HAVE_GL +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +#endif + */ + if (this == fl_fontsize) fl_fontsize = 0; +} + +//////////////////////////////////////////////////////////////// + +static Fl_Fontdesc built_in_table[] = { +{" Arial"}, +{"BArial"}, +{"IArial"}, +{"PArial"}, +{" Courier New"}, +{"BCourier New"}, +{"ICourier New"}, +{"PCourier New"}, +{" Times New Roman"}, +{"BTimes New Roman"}, +{"ITimes New Roman"}, +{"PTimes New Roman"}, +{" Symbol"}, +{" Chicago"}, +{"BChicago"}, +{" Webdings"}, +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +void fl_font(Fl_FontSize* s) { + fl_fontsize = s; + SetPort( (GrafPtr)fl_window ); + TextFont(fl_fontsize->font); //: select font into current QuickDraw GC + TextFace(fl_fontsize->face); + TextSize(fl_fontsize->size); + if (!fl_fontsize->knowMetrics) { //: get the true metrics for the currnet GC (fails on multiple monitors with different dpi's!) + FontInfo fi; GetFontInfo(&fi); + fl_fontsize->ascent = fi.ascent; + fl_fontsize->descent = fi.descent; + FMetricRec mr; FontMetrics(&mr); + short *f = (short*)*mr.wTabHandle; //: get the char size table + for (int i=0; i<256; i++) fl_fontsize->width[i] = f[2*i]; + fl_fontsize->knowMetrics = 1; + } +} + +static Fl_FontSize* find(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use 0 if fnum undefined + Fl_FontSize* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + f = new Fl_FontSize(s->name, size); + f->next = s->first; + s->first = f; + return f; +} + +//////////////////////////////////////////////////////////////// +// Public interface: + + +void fl_font(int fnum, int size) { + fl_font(find(fnum, size)); +} + +int fl_height() { + return fl_fontsize->ascent+fl_fontsize->descent; +} + +int fl_descent() { + return fl_fontsize->descent; +} + +double fl_width(const char* c) { + int n = strlen( c ); + return (double)TextWidth( c, 0, n ); +} + +double fl_width(const char* c, int n) { + return (double)TextWidth( c, 0, n ); +} + +double fl_width(uchar c) { + return (double)TextWidth( &c, 0, 1 ); +} + +void fl_draw(const char* str, int n, int x, int y) { + MoveTo(x, y); + DrawText(str, 0, n); +} + +void fl_draw(const char* str, int x, int y) { + fl_draw(str, strlen(str), x, y); +} + +// +// End of "$Id: fl_font_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $". +// diff --git a/src/fl_line_style.cxx b/src/fl_line_style.cxx index 85ea8d485..05901b29d 100644 --- a/src/fl_line_style.cxx +++ b/src/fl_line_style.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_line_style.cxx,v 1.3.2.3.2.5 2001/10/19 17:02:57 easysw Exp $" +// "$Id: fl_line_style.cxx,v 1.3.2.3.2.6 2001/11/27 17:44:08 easysw Exp $" // // Line style code for the Fast Light Tool Kit (FLTK). // @@ -54,6 +54,9 @@ void fl_line_style(int style, int width, char* dashes) { HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen); DeleteObject(oldpen); fl_current_xmap->pen = newpen; +#elif defined(__APPLE__) + //++ + // Use PenPat, PenSize #else int ndashes = dashes ? strlen(dashes) : 0; // emulate the WIN32 dash patterns on X @@ -90,5 +93,5 @@ void fl_line_style(int style, int width, char* dashes) { // -// End of "$Id: fl_line_style.cxx,v 1.3.2.3.2.5 2001/10/19 17:02:57 easysw Exp $". +// End of "$Id: fl_line_style.cxx,v 1.3.2.3.2.6 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_overlay.cxx b/src/fl_overlay.cxx index e37609a61..d6a013dd5 100644 --- a/src/fl_overlay.cxx +++ b/src/fl_overlay.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_overlay.cxx,v 1.4.2.3 2001/01/22 15:13:41 easysw Exp $" +// "$Id: fl_overlay.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:08 easysw Exp $" // // Overlay support for the Fast Light Tool Kit (FLTK). // @@ -38,6 +38,10 @@ static void draw_current_rect() { int old = SetROP2(fl_gc, R2_NOT); fl_rect(px, py, pw, ph); SetROP2(fl_gc, old); +#elif defined(__APPLE__) + PenMode( patXor ); + fl_rect(px, py, pw, ph); + PenMode( patCopy ); #else XSetFunction(fl_display, fl_gc, GXxor); XSetForeground(fl_display, fl_gc, 0xffffffff); @@ -62,5 +66,5 @@ void fl_overlay_rect(int x, int y, int w, int h) { } // -// End of "$Id: fl_overlay.cxx,v 1.4.2.3 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: fl_overlay.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx index 0181b3c2a..822961a7b 100644 --- a/src/fl_rect.cxx +++ b/src/fl_rect.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_rect.cxx,v 1.10.2.4.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: fl_rect.cxx,v 1.10.2.4.2.2 2001/11/27 17:44:08 easysw Exp $" // // Rectangle drawing routines for the Fast Light Tool Kit (FLTK). // @@ -40,6 +40,10 @@ void fl_rect(int x, int y, int w, int h) { LineTo(fl_gc, x+w-1, y+h-1); LineTo(fl_gc, x, y+h-1); LineTo(fl_gc, x, y); +#elif defined(__APPLE__) + Rect rect; + SetRect(&rect, x, y, x+w, y+h); + FrameRect(&rect); #else XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1); #endif @@ -52,6 +56,10 @@ void fl_rectf(int x, int y, int w, int h) { rect.left = x; rect.top = y; rect.right = x + w; rect.bottom = y + h; FillRect(fl_gc, &rect, fl_brush()); +#elif defined(__APPLE__) + Rect rect; + SetRect(&rect, x, y, x+w, y+h); + PaintRect(&rect); #else if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h); #endif @@ -60,6 +68,8 @@ void fl_rectf(int x, int y, int w, int h) { void fl_xyline(int x, int y, int x1) { #ifdef WIN32 MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y); +#elif defined(__APPLE__) + MoveTo(x, y); LineTo(x1, y); #else XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y); #endif @@ -72,6 +82,10 @@ void fl_xyline(int x, int y, int x1, int y2) { MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1, y); LineTo(fl_gc, x1, y2); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x1, y); + LineTo(x1, y2); #else XPoint p[3]; p[0].x = x; p[0].y = p[1].y = y; @@ -88,6 +102,11 @@ void fl_xyline(int x, int y, int x1, int y2, int x3) { LineTo(fl_gc, x1, y); LineTo(fl_gc, x1, y2); LineTo(fl_gc, x3, y2); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x1, y); + LineTo(x1, y2); + LineTo(x3, y2); #else XPoint p[4]; p[0].x = x; p[0].y = p[1].y = y; @@ -102,6 +121,8 @@ void fl_yxline(int x, int y, int y1) { if (y1 < y) y1--; else y1++; MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); +#elif defined(__APPLE__) + MoveTo(x, y); LineTo(x, y1); #else XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1); #endif @@ -114,6 +135,10 @@ void fl_yxline(int x, int y, int y1, int x2) { MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); LineTo(fl_gc, x2, y1); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x, y1); + LineTo(x2, y1); #else XPoint p[3]; p[0].x = p[1].x = x; p[0].y = y; @@ -130,6 +155,11 @@ void fl_yxline(int x, int y, int y1, int x2, int y3) { LineTo(fl_gc, x, y1); LineTo(fl_gc, x2, y1); LineTo(fl_gc, x2, y3); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x, y1); + LineTo(x2, y1); + LineTo(x2, y3); #else XPoint p[4]; p[0].x = p[1].x = x; p[0].y = y; @@ -146,6 +176,9 @@ void fl_line(int x, int y, int x1, int y1) { // Draw the last point *again* because the GDI line drawing // functions will not draw the last point ("it's a feature!"...) SetPixel(fl_gc, x1, y1, fl_RGB()); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x1, y1); #else XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1); #endif @@ -159,6 +192,10 @@ void fl_line(int x, int y, int x1, int y1, int x2, int y2) { // Draw the last point *again* because the GDI line drawing // functions will not draw the last point ("it's a feature!"...) SetPixel(fl_gc, x2, y2, fl_RGB()); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x1, y1); + LineTo(x2, y2); #else XPoint p[3]; p[0].x = x; p[0].y = y; @@ -174,6 +211,11 @@ void fl_loop(int x, int y, int x1, int y1, int x2, int y2) { LineTo(fl_gc, x1, y1); LineTo(fl_gc, x2, y2); LineTo(fl_gc, x, y); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x1, y1); + LineTo(x2, y2); + LineTo(x, y); #else XPoint p[4]; p[0].x = x; p[0].y = y; @@ -191,6 +233,12 @@ void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { LineTo(fl_gc, x2, y2); LineTo(fl_gc, x3, y3); LineTo(fl_gc, x, y); +#elif defined(__APPLE__) + MoveTo(x, y); + LineTo(x1, y1); + LineTo(x2, y2); + LineTo(x3, y3); + LineTo(x, y); #else XPoint p[5]; p[0].x = x; p[0].y = y; @@ -210,6 +258,14 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) { #ifdef WIN32 SelectObject(fl_gc, fl_brush()); Polygon(fl_gc, p, 3); +#elif defined(__APPLE__) + PolyHandle poly = OpenPoly(); + MoveTo(x, y); + LineTo(x1, y1); + LineTo(x2, y2); + ClosePoly(); + PaintPoly(poly); + KillPoly(poly); #else p[3].x = x; p[3].y = y; XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0); @@ -226,6 +282,15 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { #ifdef WIN32 SelectObject(fl_gc, fl_brush()); Polygon(fl_gc, p, 4); +#elif defined(__APPLE__) + PolyHandle poly = OpenPoly(); + MoveTo(x, y); + LineTo(x1, y1); + LineTo(x2, y2); + LineTo(x3, y3); + ClosePoly(); + PaintPoly(poly); + KillPoly(poly); #else p[4].x = x; p[4].y = y; XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0); @@ -236,6 +301,8 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { void fl_point(int x, int y) { #ifdef WIN32 SetPixel(fl_gc, x, y, fl_RGB()); +#elif defined(__APPLE__) + MoveTo(x, y); Line(0, 0); #else XDrawPoint(fl_display, fl_window, fl_gc, x, y); #endif @@ -245,28 +312,44 @@ void fl_point(int x, int y) { #define STACK_SIZE 10 #define STACK_MAX (STACK_SIZE - 1) -static Region rstack[STACK_SIZE]; +static Fl_Region rstack[STACK_SIZE]; static int rstackptr=0; int fl_clip_state_number=0; // used by gl_begin.cxx to update GL clip -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) // Missing X call: (is this the fastest way to init a 1-rectangle region?) // MSWindows equivalent exists, implemented inline in win32.H -Region XRectangleRegion(int x, int y, int w, int h) { +Fl_Region XRectangleRegion(int x, int y, int w, int h) { XRectangle R; R.x = x; R.y = y; R.width = w; R.height = h; - Region r = XCreateRegion(); + Fl_Region r = XCreateRegion(); XUnionRectWithRegion(&R, r, r); return r; } #endif +#ifdef __APPLE__ +extern Fl_Region fl_window_region; +#endif + // undo any clobbering of clip done by your program: void fl_restore_clip() { fl_clip_state_number++; - Region r = rstack[rstackptr]; + Fl_Region r = rstack[rstackptr]; #ifdef WIN32 SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared +#elif defined(__APPLE__) +# if 1 + CopyRgn( fl_window_region, GetPortClipRegion((GrafPtr)fl_window, 0) ); + if ( r ) + SectRgn( GetPortClipRegion((GrafPtr)fl_window, 0), r, GetPortClipRegion((GrafPtr)fl_window, 0) ); +# else + if (r) SetClip(r); + else { + Rect rect; rect.left=0; rect.top=0; rect.right=0x7fff; rect.bottom=0x7fff; + ClipRect(&rect); + } +# endif #else if (r) XSetRegion(fl_display, fl_gc, r); else XSetClipMask(fl_display, fl_gc, 0); @@ -274,8 +357,8 @@ void fl_restore_clip() { } // Replace the top of the clip stack: -void fl_clip_region(Region r) { - Region oldr = rstack[rstackptr]; +void fl_clip_region(Fl_Region r) { + Fl_Region oldr = rstack[rstackptr]; if (oldr) XDestroyRegion(oldr); rstack[rstackptr] = r; fl_restore_clip(); @@ -283,25 +366,30 @@ void fl_clip_region(Region r) { // Intersect & push a new clip rectangle: void fl_clip(int x, int y, int w, int h) { - Region r; + Fl_Region r; if (w > 0 && h > 0) { r = XRectangleRegion(x,y,w,h); - Region current = rstack[rstackptr]; + Fl_Region current = rstack[rstackptr]; if (current) { -#ifndef WIN32 - Region temp = XCreateRegion(); +#ifdef WIN32 + CombineRgn(r,r,current,RGN_AND); +#elif defined(__APPLE__) + SectRgn(r, current, r); +#else + Fl_Region temp = XCreateRegion(); XIntersectRegion(current, r, temp); XDestroyRegion(r); r = temp; -#else - CombineRgn(r,r,current,RGN_AND); #endif } } else { // make empty clip region: -#ifndef WIN32 - r = XCreateRegion(); -#else +#ifdef WIN32 r = CreateRectRgn(0,0,0,0); +#elif defined(__APPLE__) + r = NewRgn(); + SetEmptyRgn(r); +#else + r = XCreateRegion(); #endif } if (rstackptr < STACK_MAX) rstack[++rstackptr] = r; @@ -317,7 +405,7 @@ void fl_push_no_clip() { // pop back to previous clip: void fl_pop_clip() { if (rstackptr > 0) { - Region oldr = rstack[rstackptr--]; + Fl_Region oldr = rstack[rstackptr--]; if (oldr) XDestroyRegion(oldr); } fl_restore_clip(); @@ -327,48 +415,34 @@ void fl_pop_clip() { int fl_not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0 || x > Fl_Window::current()->w() || y > Fl_Window::current()->h()) return 0; - Region r = rstack[rstackptr]; -#ifndef WIN32 - return r ? XRectInRegion(r, x, y, w, h) : 1; -#else + Fl_Region r = rstack[rstackptr]; +#ifdef WIN32 if (!r) return 1; RECT rect; rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; return RectInRegion(r,&rect); +#elif defined(__APPLE__) + if (!r) return 1; + Rect rect; + rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + return RectInRgn(&rect, r); +#else + return r ? XRectInRegion(r, x, y, w, h) : 1; #endif } // return rectangle surrounding intersection of this rectangle and clip: int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; - Region r = rstack[rstackptr]; + Fl_Region r = rstack[rstackptr]; if (!r) return 0; -#ifndef WIN32 - switch (XRectInRegion(r, x, y, w, h)) { - case 0: // completely outside - W = H = 0; - return 2; - case 1: // completely inside: - return 0; - default: // partial: - break; - } - Region rr = XRectangleRegion(x,y,w,h); - Region temp = XCreateRegion(); - XIntersectRegion(r, rr, temp); - XRectangle rect; - XClipBox(temp, &rect); - X = rect.x; Y = rect.y; W = rect.width; H = rect.height; - XDestroyRegion(temp); - XDestroyRegion(rr); - return 1; -#else +#ifdef WIN32 // The win32 API makes no distinction between partial and complete // intersection, so we have to check for partial intersection ourselves. // However, given that the regions may be composite, we have to do // some voodoo stuff... - Region rr = XRectangleRegion(x,y,w,h); - Region temp = CreateRectRgn(0,0,0,0); + Fl_Region rr = XRectangleRegion(x,y,w,h); + Fl_Region temp = CreateRectRgn(0,0,0,0); int ret; if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint W = H = 0; @@ -384,9 +458,41 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ DeleteObject(temp); DeleteObject(rr); return ret; +#elif defined(__APPLE__) + RgnHandle rr = NewRgn(); + SetRectRgn( rr, x, y, x+w, y+h ); + SectRgn( r, rr, rr ); + Rect *rp = GetRegionBounds(rr, 0); + X = rp->left; + Y = rp->top; + W = rp->right - X; + H = rp->bottom - Y; + DisposeRgn( rr ); + if ( H==0 ) return 2; + if ( h==H && w==W ) return 0; + return 0; +#else + switch (XRectInRegion(r, x, y, w, h)) { + case 0: // completely outside + W = H = 0; + return 2; + case 1: // completely inside: + return 0; + default: // partial: + break; + } + Fl_Region rr = XRectangleRegion(x,y,w,h); + Fl_Region temp = XCreateRegion(); + XIntersectRegion(r, rr, temp); + XRectangle rect; + XClipBox(temp, &rect); + X = rect.x; Y = rect.y; W = rect.width; H = rect.height; + XDestroyRegion(temp); + XDestroyRegion(rr); + return 1; #endif } // -// End of "$Id: fl_rect.cxx,v 1.10.2.4.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: fl_rect.cxx,v 1.10.2.4.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_scroll_area.cxx b/src/fl_scroll_area.cxx index 931888bb6..632e094d2 100644 --- a/src/fl_scroll_area.cxx +++ b/src/fl_scroll_area.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_scroll_area.cxx,v 1.4.2.3 2001/01/22 15:13:41 easysw Exp $" +// "$Id: fl_scroll_area.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:08 easysw Exp $" // // Scrolling routines for the Fast Light Tool Kit (FLTK). // @@ -71,6 +71,13 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY); // NYI: need to redraw areas that the source of BitBlt was bad due to // overlapped windows, probably similar to X version: +#elif defined(__APPLE__) + Rect src = { src_y, src_x, src_y+src_h, src_x+src_w }; + Rect dst = { dest_y, dest_x, dest_y+src_h, dest_x+src_w }; + static RGBColor bg = { 0xffff, 0xffff, 0xffff }; RGBBackColor( &bg ); + static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg ); + CopyBits( GetPortBitMapForCopyBits((GrafPtr)fl_window), + GetPortBitMapForCopyBits((GrafPtr)fl_window), &src, &dst, srcCopy, 0L); #else XCopyArea(fl_display, fl_window, fl_window, fl_gc, src_x, src_y, src_w, src_h, dest_x, dest_y); @@ -89,5 +96,5 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, } // -// End of "$Id: fl_scroll_area.cxx,v 1.4.2.3 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: fl_scroll_area.cxx,v 1.4.2.3.2.1 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_set_font.cxx b/src/fl_set_font.cxx index 6d0e93da5..b41c8b6f6 100644 --- a/src/fl_set_font.cxx +++ b/src/fl_set_font.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_set_font.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: fl_set_font.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:08 easysw Exp $" // // Font utilities for the Fast Light Tool Kit (FLTK). // @@ -53,7 +53,7 @@ void Fl::set_font(Fl_Font fnum, const char* name) { Fl_Fontdesc* s = fl_fonts+fnum; if (s->name) { if (!strcmp(s->name, name)) {s->name = name; return;} -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist); #endif for (Fl_FontSize* f = s->first; f;) { @@ -62,7 +62,7 @@ void Fl::set_font(Fl_Font fnum, const char* name) { s->first = 0; } s->name = name; -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) s->xlist = 0; #endif s->first = 0; @@ -71,5 +71,5 @@ void Fl::set_font(Fl_Font fnum, const char* name) { const char* Fl::get_font(Fl_Font fnum) {return fl_fonts[fnum].name;} // -// End of "$Id: fl_set_font.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: fl_set_font.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_set_fonts.cxx b/src/fl_set_fonts.cxx index a5c30dcfd..6c8dee8a9 100644 --- a/src/fl_set_fonts.cxx +++ b/src/fl_set_fonts.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.1 2001/11/26 20:13:29 easysw Exp $" +// "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.2 2001/11/27 17:44:08 easysw Exp $" // // More font utilities for the Fast Light Tool Kit (FLTK). // @@ -29,7 +29,9 @@ // and bold italic. #ifdef WIN32 -#include "fl_set_fonts_win32.cxx" +# include "fl_set_fonts_win32.cxx" +#elif defined(__APPLE__) +# include "fl_set_fonts_mac.cxx" #else // Standard X fonts are matched by a pattern that is always of @@ -55,12 +57,12 @@ // and can identify any font on X that way. You may want to write your // own system of font management and not use this code. -#include <FL/Fl.H> -#include <FL/x.H> -#include "Fl_Font.H" -#include <ctype.h> -#include <string.h> -#include <stdlib.h> +# include <FL/Fl.H> +# include <FL/x.H> +# include "Fl_Font.H" +# include <ctype.h> +# include <string.h> +# include <stdlib.h> // turn word N of a X font name into either some attribute bits // (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that @@ -335,5 +337,5 @@ int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { #endif // -// End of "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.1 2001/11/26 20:13:29 easysw Exp $". +// End of "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_set_fonts_mac.cxx b/src/fl_set_fonts_mac.cxx new file mode 100644 index 000000000..c7bf04203 --- /dev/null +++ b/src/fl_set_fonts_mac.cxx @@ -0,0 +1,93 @@ +// +// "$Id: fl_set_fonts_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $" +// +// MacOS font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +#include <FL/Fl.H> +#include <FL/mac.H> +#include "Fl_Font.H" +#include <ctype.h> +#include <string.h> +#include <stdlib.h> + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + const char* p = fl_fonts[fnum].name; + if (!p || !*p) {if (ap) *ap = 0; return "";} + int type; + switch (*p) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + if (!type) return p+1; + static char *buffer; if (!buffer) buffer = new char[128]; + strcpy(buffer, p+1); + if (type & FL_BOLD) strcat(buffer, " bold"); + if (type & FL_ITALIC) strcat(buffer, " italic"); + return buffer; +} + +static int fl_free_font = FL_FREE_FONT; +/* +static int CALLBACK enumcb(ENUMLOGFONT FAR *lpelf, + NEWTEXTMETRIC FAR *lpntm, int FontType, LPARAM p) { + if (!p && lpelf->elfLogFont.lfCharSet != ANSI_CHARSET) return 1; + char *n = (char*)(lpelf->elfFullName); + for (int i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts + if (!strcmp(Fl::get_font_name((Fl_Font)i),n)) return 1; + char buffer[128]; + strcpy(buffer+1, n); + buffer[0] = ' '; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + if (lpelf->elfLogFont.lfWeight <= 400) + buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + if (lpelf->elfLogFont.lfWeight <= 400) + buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + return 1; +} +*/ +Fl_Font Fl::set_fonts(const char* xstarname) { +#pragma unused ( xstarname ) +//++ EnumFontFamilies(fl_gc, NULL, (FONTENUMPROC)enumcb, xstarname != 0); + return (Fl_Font)fl_free_font; +} + +int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { +#pragma unused ( fnum ) + // pretend all fonts are scalable (most are and I don't know how + // to tell anyways) + static int array[1]; + sizep = array; + return 1; +} + +// +// End of "$Id: fl_set_fonts_mac.cxx,v 1.1.2.1 2001/11/27 17:44:08 easysw Exp $". +// diff --git a/src/fl_shortcut.cxx b/src/fl_shortcut.cxx index 711b11ce6..2129de7aa 100644 --- a/src/fl_shortcut.cxx +++ b/src/fl_shortcut.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_shortcut.cxx,v 1.4.2.9 2001/01/22 15:13:41 easysw Exp $" +// "$Id: fl_shortcut.cxx,v 1.4.2.9.2.1 2001/11/27 17:44:08 easysw Exp $" // // Shortcut support routines for the Fast Light Tool Kit (FLTK). // @@ -45,7 +45,7 @@ #include <FL/fl_draw.H> #include <ctype.h> #include <string.h> -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) #include <FL/x.H> #endif @@ -74,7 +74,7 @@ int Fl::test_shortcut(int shortcut) { return 0; } -#ifdef WIN32 // if not X +#if defined(WIN32) || defined(__APPLE__) // if not X // This table must be in numeric order by fltk (X) keysym number: struct Keyname {int key; const char* name;}; static Keyname table[] = { @@ -115,12 +115,20 @@ const char * fl_shortcut_label(int shortcut) { static char buf[20]; char *p = buf; if (!shortcut) {*p = 0; return buf;} +#ifdef __APPLE__ + //++ to avoid getting stoned and feathered by mac users we should replace the text with the correct symbols + if (shortcut & FL_SHIFT) {strcpy(p,"shift+"); p += 6;} //: Mac hollow up arrow + if (shortcut & FL_META) {strcpy(p,"ctrl+"); p += 6;} //: Mac 'cotrol' + if (shortcut & FL_ALT) {strcpy(p,"option+"); p += 4;} //: Mac 'Option' or fancy switch symbol + if (shortcut & FL_CTRL) {strcpy(p,"cmd+"); p += 4;} //: Mac Apple or Curlyflour +#else if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;} if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;} if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} +#endif // __APPLE__ int key = shortcut & 0xFFFF; -#ifdef WIN32 // if not X +#if defined(WIN32) || defined(__APPLE__) // if not X if (key >= FL_F && key <= FL_F_Last) { *p++ = 'F'; if (key > FL_F+9) *p++ = (key-FL_F)/10+'0'; @@ -192,5 +200,5 @@ int Fl_Widget::test_shortcut() { } // -// End of "$Id: fl_shortcut.cxx,v 1.4.2.9 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: fl_shortcut.cxx,v 1.4.2.9.2.1 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/fl_vertex.cxx b/src/fl_vertex.cxx index c2f65aed1..27b9faf59 100644 --- a/src/fl_vertex.cxx +++ b/src/fl_vertex.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_vertex.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: fl_vertex.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:08 easysw Exp $" // // Portable drawing routines for the Fast Light Tool Kit (FLTK). // @@ -123,6 +123,8 @@ void fl_vertex(double x,double y) { void fl_end_points() { #ifdef WIN32 for (int i=0; i<n; i++) SetPixel(fl_gc, p[i].x, p[i].y, fl_RGB()); +#elif defined(__APPLE__) + for (int i=0; i<n; i++) { MoveTo(p[i].x, p[i].y); Line(0, 0); } #else if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0); #endif @@ -131,6 +133,10 @@ void fl_end_points() { void fl_end_line() { #ifdef WIN32 if (n>1) Polyline(fl_gc, p, n); +#elif defined(__APPLE__) + if (n<=1) return; + MoveTo(p[0].x, p[0].y); + for (int i=1; i<n; i++) LineTo(p[i].x, p[i].y); #else if (n>1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0); #endif @@ -153,6 +159,14 @@ void fl_end_polygon() { SelectObject(fl_gc, fl_brush()); Polygon(fl_gc, p, n); } +#elif defined(__APPLE__) + if (n<=1) return; + PolyHandle ph = OpenPoly(); + MoveTo(p[0].x, p[0].y); + for (int i=1; i<n; i++) LineTo(p[i].x, p[i].y); + ClosePoly(); + PaintPoly(ph); + KillPoly(ph); #else if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0); #endif @@ -192,6 +206,14 @@ void fl_end_complex_polygon() { SelectObject(fl_gc, fl_brush()); PolyPolygon(fl_gc, p, counts, numcount); } +#elif defined(__APPLE__) + if (n<=1) return; + PolyHandle ph = OpenPoly(); + MoveTo(p[0].x, p[0].y); + for (int i=1; i<n; i++) LineTo(p[i].x, p[i].y); + ClosePoly(); + PaintPoly(ph); + KillPoly(ph); #else if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0); #endif @@ -216,6 +238,9 @@ void fl_circle(double x, double y,double r) { Pie(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); } else Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); +#elif defined(__APPLE__) + Rect rt; rt.left=llx; rt.right=llx+w; rt.top=lly; rt.bottom=lly+h; + (what == POLYGON ? PaintOval : FrameOval)(&rt); #else (what == POLYGON ? XFillArc : XDrawArc) (fl_display, fl_window, fl_gc, llx, lly, w, h, 0, 360*64); @@ -223,5 +248,5 @@ void fl_circle(double x, double y,double r) { } // -// End of "$Id: fl_vertex.cxx,v 1.5.2.3.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: fl_vertex.cxx,v 1.5.2.3.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx index 3532b7d2b..881d31966 100644 --- a/src/gl_draw.cxx +++ b/src/gl_draw.cxx @@ -1,5 +1,5 @@ // -// "$Id: gl_draw.cxx,v 1.7.2.5.2.1 2001/11/22 15:35:01 easysw Exp $" +// "$Id: gl_draw.cxx,v 1.7.2.5.2.2 2001/11/27 17:44:08 easysw Exp $" // // OpenGL drawing support routines for the Fast Light Tool Kit (FLTK). // @@ -53,6 +53,8 @@ void gl_font(int fontid, int size) { fl_fontsize->listbase = glGenLists(256); wglUseFontBitmaps(fl_gc, base, size, fl_fontsize->listbase+base); SelectObject(fl_gc, oldFid); +#elif defined(__APPLE__) + //++ #else int base = fl_xfont->min_char_or_byte2; int size = fl_xfont->max_char_or_byte2-base+1; @@ -155,5 +157,5 @@ void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) { #endif // -// End of "$Id: gl_draw.cxx,v 1.7.2.5.2.1 2001/11/22 15:35:01 easysw Exp $". +// End of "$Id: gl_draw.cxx,v 1.7.2.5.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/src/gl_start.cxx b/src/gl_start.cxx index 6135c5740..1340eedce 100644 --- a/src/gl_start.cxx +++ b/src/gl_start.cxx @@ -1,5 +1,5 @@ // -// "$Id: gl_start.cxx,v 1.6.2.5.2.1 2001/11/22 15:35:02 easysw Exp $" +// "$Id: gl_start.cxx,v 1.6.2.5.2.2 2001/11/27 17:44:08 easysw Exp $" // // OpenGL context routines for the Fast Light Tool Kit (FLTK). // @@ -61,12 +61,14 @@ void gl_start() { #ifdef WIN32 if (!gl_choice) Fl::gl_visual(0); context = fl_create_gl_context(Fl_Window::current(), gl_choice); +#elif defined(__APPLE__) + //++ #else context = fl_create_gl_context(fl_visual); #endif } fl_set_gl_context(Fl_Window::current(), context); -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) glXWaitX(); #endif if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) { @@ -93,7 +95,7 @@ void gl_start() { void gl_finish() { glFlush(); -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) glXWaitGL(); #endif } @@ -103,6 +105,8 @@ int Fl::gl_visual(int mode, int *alist) { if (!c) return 0; #ifdef WIN32 gl_choice = c; +#elif defined(__APPLE__) + //++ #else fl_visual = c->vis; fl_colormap = c->colormap; @@ -113,5 +117,5 @@ int Fl::gl_visual(int mode, int *alist) { #endif // -// End of "$Id: gl_start.cxx,v 1.6.2.5.2.1 2001/11/22 15:35:02 easysw Exp $". +// End of "$Id: gl_start.cxx,v 1.6.2.5.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/test/color_chooser.cxx b/test/color_chooser.cxx index 6178ec745..4e87a68c8 100644 --- a/test/color_chooser.cxx +++ b/test/color_chooser.cxx @@ -1,5 +1,5 @@ // -// "$Id: color_chooser.cxx,v 1.6.2.3.2.1 2001/08/05 23:58:54 easysw Exp $" +// "$Id: color_chooser.cxx,v 1.6.2.3.2.2 2001/11/27 17:44:08 easysw Exp $" // // Color chooser test program for the Fast Light Tool Kit (FLTK). // @@ -35,7 +35,7 @@ #include <stdlib.h> #include <stdio.h> -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) #include "list_visuals.cxx" #endif @@ -115,7 +115,7 @@ int main(int argc, char ** argv) { " - : default visual\n" " r : call Fl::visual(FL_RGB)\n" " c : call Fl::own_colormap()\n",argv[0]); -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) printf(" # : use this visual with an empty colormap:\n"); list_visuals(); #endif @@ -127,7 +127,7 @@ int main(int argc, char ** argv) { } else if (argv[i][0] == 'c') { Fl::own_colormap(); } else if (argv[i][0] != '-') { -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) int visid = atoi(argv[i]); fl_open_display(); XVisualInfo templt; int num; @@ -138,7 +138,7 @@ int main(int argc, char ** argv) { fl_visual->visual, AllocNone); fl_xpixel(FL_BLACK); // make sure black is allocated #else - Fl::fatal("Visual id's not supported on MSWindows"); + Fl::fatal("Visual id's not supported on MSWindows or MacOS."); #endif } window.show(argc,argv); @@ -146,5 +146,5 @@ int main(int argc, char ** argv) { } // -// End of "$Id: color_chooser.cxx,v 1.6.2.3.2.1 2001/08/05 23:58:54 easysw Exp $". +// End of "$Id: color_chooser.cxx,v 1.6.2.3.2.2 2001/11/27 17:44:08 easysw Exp $". // diff --git a/test/image.cxx b/test/image.cxx index 3a7baebbe..1d49c584b 100644 --- a/test/image.cxx +++ b/test/image.cxx @@ -1,5 +1,5 @@ // -// "$Id: image.cxx,v 1.6.2.3.2.5 2001/11/24 18:07:57 easysw Exp $" +// "$Id: image.cxx,v 1.6.2.3.2.6 2001/11/27 17:44:08 easysw Exp $" // // Fl_Image test program for the Fast Light Tool Kit (FLTK). // @@ -80,7 +80,7 @@ void button_cb(Fl_Widget *,void *) { } #include <FL/x.H> -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) #include "list_visuals.cxx" #endif @@ -96,7 +96,7 @@ int arg(int argc, char **argv, int &i) { } int main(int argc, char **argv) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) int i = 1; Fl::args(argc,argv,i,arg); @@ -155,5 +155,5 @@ int main(int argc, char **argv) { } // -// End of "$Id: image.cxx,v 1.6.2.3.2.5 2001/11/24 18:07:57 easysw Exp $". +// End of "$Id: image.cxx,v 1.6.2.3.2.6 2001/11/27 17:44:08 easysw Exp $". // diff --git a/test/list_visuals.cxx b/test/list_visuals.cxx index a45bc3bcf..d00ee050a 100644 --- a/test/list_visuals.cxx +++ b/test/list_visuals.cxx @@ -1,12 +1,12 @@ // -// "$Id: list_visuals.cxx,v 1.5.2.3 2001/01/22 15:13:41 easysw Exp $" +// "$Id: list_visuals.cxx,v 1.5.2.3.2.1 2001/11/27 17:44:08 easysw Exp $" // // Visual list utility for the Fast Light Tool Kit (FLTK). // // List all the visuals on the screen, and dumps anything interesting // about them to stdout. // -// Does not use fltk. +// Does not use FLTK. // // This file may be #included in another program to make a function to // call to list the visuals. Fl.H must be included first to indicate this. @@ -31,7 +31,7 @@ // Please report all bugs and problems to "fltk-bugs@fltk.org". // -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) #include <FL/Fl.H> #include <FL/fl_message.H> @@ -235,5 +235,5 @@ int main(int argc, char **argv) { #endif // -// End of "$Id: list_visuals.cxx,v 1.5.2.3 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: list_visuals.cxx,v 1.5.2.3.2.1 2001/11/27 17:44:08 easysw Exp $". // diff --git a/test/tiled_image.cxx b/test/tiled_image.cxx index cb132edef..a888fc99f 100644 --- a/test/tiled_image.cxx +++ b/test/tiled_image.cxx @@ -1,5 +1,5 @@ // -// "$Id: tiled_image.cxx,v 1.1.2.1 2001/11/24 18:07:58 easysw Exp $" +// "$Id: tiled_image.cxx,v 1.1.2.2 2001/11/27 17:44:08 easysw Exp $" // // Fl_Tiled_Image test program for the Fast Light Tool Kit (FLTK). // @@ -42,7 +42,7 @@ void button_cb(Fl_Widget *,void *) { } #include <FL/x.H> -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) #include "list_visuals.cxx" #endif @@ -58,7 +58,7 @@ int arg(int argc, char **argv, int &i) { } int main(int argc, char **argv) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(__APPLE__) int i = 1; Fl::args(argc,argv,i,arg); @@ -99,5 +99,5 @@ int main(int argc, char **argv) { } // -// End of "$Id: tiled_image.cxx,v 1.1.2.1 2001/11/24 18:07:58 easysw Exp $". +// End of "$Id: tiled_image.cxx,v 1.1.2.2 2001/11/27 17:44:08 easysw Exp $". // |
