ZynAddSubFX/FLTK: updated to SVN revision 6970
Updated FLTK to SVN revision 6970 of branch-1.3:
- Added Josef Vitu to CREDITS.
- Moved OS X code base to the more moder Cocoa toolkit thanks to the awesome work of Manolo Gouy (STR #2221). This is a big one! I tested all test applications under 32-bit autoconf and Xcode, and a few apps under 64bit intel. No PPC testing was done. Please verify this patch if you have the machine!
- Some fixes for the Cocoa port
- Xcode project was not building Cocoa code!
- Removed typedef that simply renamed char* to Fl_String, as discussed in the mailing list.
- Checked in SebHoll's API mods, fixed indents.
o Added user_data() to Fl_Tree_Item
o Added insert() and add() methods that allow specification of Fl_Tree_Prefs
o Changed Fl_Pixmap args to Fl_Image for more flexibility
o Fixes for positioning of items in the presence of user icons
o find_children() changed from protected -> public
- Small fixed to SebHoll's user_data() mods (init + copy ctor),
- Fumbeling about at the Cocoa implementation.
- Fix for Mac's "ALT" key symbol: saucepan right side up, pancake not on floor.
- Sorted Xcode source files (somewhat). Added Manolos patches to fix the Sys_Menu widget pointer.
- Patced antialised fonts for Cocoa builds
- Applied patch from dec 10th. It does not solve the problem that the About dialog drops behind the Sudoku window though...
- Applied the 'recap.zip' files to the Cocoa patch. About diaog now correct. Much other stuff should work better now. Exciting!
- New patches appliet for Cocoa port. Fixed(?) STR 2232 workaround for X11 keyrepeat bbbbuuuuuuggggg.
- Added Manolo Gouy to CREDITS for his great work on porting FLTK 1.3 on Mac OS X to Cocoa. (Also fixed some space/tab inconsistencies).
- Re-indented src/Fl_Input.cxx
- Trying to fix update rectangles and dnd in Cocoa. Currently, invalidating a rectangle does not work. This can be seen when dragging data within an application, for example.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
CHANGES IN FLTK 1.3.0
|
||||
|
||||
- Moved OS X code base to the more moder Cocoa toolkit thanks
|
||||
to the awesome work of Manolo Gouy (STR #2221)
|
||||
- Added template to generate new projects with Xcode.
|
||||
- Managing all Widget flags in a single location now (STR #2161)
|
||||
- Fixed all color related call to Fl_Color type (STR #2208)
|
||||
|
||||
@@ -12,7 +12,7 @@ CORE DEVELOPERS
|
||||
The following people do the day-to-day development of FLTK:
|
||||
|
||||
Fabien Costantini (fabien67@users.sf.net)
|
||||
Craig P. Earls
|
||||
Craig P. Earls
|
||||
Curtis Edwards (trilec@users.sourceforge.net)
|
||||
Gustavo Hime (hime@users.sourceforge.net)
|
||||
Talbot Hughes
|
||||
@@ -21,7 +21,7 @@ CORE DEVELOPERS
|
||||
James Dean Palmer (jamespalmer@users.sourceforge.net)
|
||||
Vincent Penne (vincentp@users.sourceforge.net)
|
||||
Bill Spitzak (spitzak@users.sourceforge.net)
|
||||
Michael Sweet (easysw@users.sourceforge.net)
|
||||
Michael Sweet (easysw@users.sourceforge.net)
|
||||
Carl Thompson (clip@users.sourceforge.net)
|
||||
Nafees Bin Zafar (nafees@users.sourceforge.net)
|
||||
|
||||
@@ -39,6 +39,7 @@ OTHER CONTRIBUTORS
|
||||
Yuri Fedorchenko
|
||||
George Garvey
|
||||
Duncan Gibson
|
||||
Manolo Gouy
|
||||
Mikael Hultgren
|
||||
Stuart Levy
|
||||
Howard Lightstone
|
||||
@@ -47,9 +48,10 @@ OTHER CONTRIBUTORS
|
||||
Alexander Rabi
|
||||
James Roth
|
||||
Albrecht Schlosser
|
||||
Andrea Suatoni
|
||||
Andrea Suatoni
|
||||
Paul Sydney
|
||||
Aaron Ucko
|
||||
Emanuele Vicentini
|
||||
Josef Vitu
|
||||
Jim Wilson
|
||||
Ken Yarnall
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/**
|
||||
This container widget lets you maneuver around a set of widgets much
|
||||
larger than your window. If the child widgets are larger than the size
|
||||
larger than your window. If the child widgets are larger than the size
|
||||
of this object then scrollbars will appear so that you can scroll over
|
||||
to them:
|
||||
\image html Fl_Scroll.gif
|
||||
@@ -73,8 +73,8 @@
|
||||
considered. The flags in hscrollbar however are ignored.
|
||||
|
||||
This widget can also be used to pan around a single child widget
|
||||
"canvas". This child widget should be of your own class, with a
|
||||
draw() method that draws the contents. The scrolling is done by
|
||||
"canvas". This child widget should be of your own class, with a
|
||||
draw() method that draws the contents. The scrolling is done by
|
||||
changing the x() and y() of the widget, so this child
|
||||
must use the x() and y() to position its drawing.
|
||||
To speed up drawing it should test fl_push_clip().
|
||||
@@ -86,7 +86,7 @@
|
||||
of individually-openable panels.
|
||||
|
||||
Fluid lets you create these, but you can only lay out objects that
|
||||
fit inside the Fl_Scroll without scrolling. Be sure to leave
|
||||
fit inside the Fl_Scroll without scrolling. Be sure to leave
|
||||
space for the scrollbars, as Fluid won't show these either.
|
||||
|
||||
<I>You cannot use Fl_Window as a child of this since the
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define Fl_Sys_Menu_Bar_H
|
||||
|
||||
#include "Fl_Menu_Bar.H"
|
||||
#include "x.H"
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
@@ -38,9 +39,13 @@ protected:
|
||||
public:
|
||||
Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0)
|
||||
: Fl_Menu_Bar(x,y,w,h,l) {
|
||||
deactivate(); // don't let the old area take events
|
||||
deactivate(); // don't let the old area take events
|
||||
fl_sys_menu_bar = this;
|
||||
}
|
||||
void menu(const Fl_Menu_Item *m);
|
||||
int add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0);
|
||||
void remove(int n);
|
||||
void replace(int rank, const char *name);
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
@@ -124,7 +124,7 @@ protected:
|
||||
\param[in] w, h size of the widget in pixels
|
||||
\param[in] label optional text for the widget label
|
||||
*/
|
||||
Fl_Widget(int x, int y, int w, int h, Fl_CString label=0L);
|
||||
Fl_Widget(int x, int y, int w, int h, const char *label=0L);
|
||||
|
||||
/** Internal use only. Use position(int,int), size(int,int) or resize(int,int,int,int) instead. */
|
||||
void x(int v) {x_ = v;}
|
||||
@@ -400,7 +400,7 @@ public:
|
||||
|
||||
/** Gets the current label text.
|
||||
\return a pointer to the current label text
|
||||
\see label(Fl_CString), copy_label(Fl_CString)
|
||||
\see label(const char *), copy_label(const char *)
|
||||
*/
|
||||
const char* label() const {return label_.value;}
|
||||
|
||||
@@ -426,10 +426,10 @@ public:
|
||||
\param[in] new_label the new label text
|
||||
\see label()
|
||||
*/
|
||||
void copy_label(Fl_CString new_label);
|
||||
void copy_label(const char *new_label);
|
||||
|
||||
/** Shortcut to set the label text and type in one call.
|
||||
\see label(FL_CString), labeltype(Fl_Labeltype)
|
||||
\see label(const char *), labeltype(Fl_Labeltype)
|
||||
*/
|
||||
void label(Fl_Labeltype a, const char* b) {label_.type = a; label_.value = b;}
|
||||
|
||||
@@ -842,7 +842,7 @@ public:
|
||||
/** Internal use only. */
|
||||
int test_shortcut();
|
||||
/** Internal use only. */
|
||||
static Fl_Shortcut label_shortcut(const char *t);
|
||||
static unsigned int label_shortcut(const char *t);
|
||||
/** Internal use only. */
|
||||
static int test_shortcut(const char*);
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ FL_EXPORT double fl_width(const char* txt, int n);
|
||||
/** Return the typographical width of a single character :
|
||||
\note if a valid fl_gc is NOT found then it uses the first window gc,
|
||||
or the screen gc if no fltk window is available when called. */
|
||||
FL_EXPORT double fl_width(Fl_Char);
|
||||
FL_EXPORT double fl_width(unsigned int);
|
||||
/** Determine the minimum pixel dimensions of a nul-terminated string.
|
||||
|
||||
Usage: given a string "txt" drawn using fl_draw(txt, x, y) you would determine
|
||||
@@ -441,8 +441,8 @@ FL_EXPORT int fl_measure_pixmap(const char* const* cdata, int &w, int &h);
|
||||
// other:
|
||||
FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
|
||||
void (*draw_area)(void*, int,int,int,int), void* data);
|
||||
FL_EXPORT const char* fl_shortcut_label(Fl_Shortcut shortcut);
|
||||
FL_EXPORT const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom);
|
||||
FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut);
|
||||
FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut, const char **eom);
|
||||
FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h);
|
||||
FL_EXPORT void fl_overlay_clear();
|
||||
FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE);
|
||||
|
||||
@@ -36,16 +36,71 @@
|
||||
|
||||
// Standard MacOS Carbon API includes...
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <config.h>
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
#ifndef MAC_OS_X_VERSION_10_3
|
||||
#define MAC_OS_X_VERSION_10_3 1030
|
||||
#endif
|
||||
#ifndef MAC_OS_X_VERSION_10_4
|
||||
#define MAC_OS_X_VERSION_10_4 1040
|
||||
#endif
|
||||
#ifndef MAC_OS_X_VERSION_10_5
|
||||
#define MAC_OS_X_VERSION_10_5 1050
|
||||
#endif
|
||||
#ifndef MAC_OS_X_VERSION_10_6
|
||||
#define MAC_OS_X_VERSION_10_6 1060
|
||||
#endif
|
||||
#ifndef MAC_OS_X_VERSION_MAX_ALLOWED
|
||||
#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_3
|
||||
#endif
|
||||
#endif //__APPLE_COCOA__
|
||||
|
||||
#ifndef CGFLOAT_DEFINED //appears with 10.5 in CGBase.h
|
||||
#if defined(__LP64__) && __LP64__
|
||||
typedef double CGFloat;
|
||||
#else
|
||||
typedef float CGFloat;
|
||||
#endif
|
||||
#endif //CGFLOAT_DEFINED
|
||||
|
||||
|
||||
// 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;};
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
|
||||
typedef void *Window; //this is really a pter to the subclass FLWindow of NSWindow
|
||||
typedef struct flCocoaRegion{
|
||||
int count;
|
||||
CGRect *rects;
|
||||
} *Fl_Region; // a region is the union of a series of rectangles
|
||||
inline Fl_Region XRectangleRegion(int x, int y, int w, int h) {
|
||||
Fl_Region R = (Fl_Region)malloc(sizeof(*R));
|
||||
R->count = 1;
|
||||
R->rects = (CGRect *)malloc(sizeof(CGRect));
|
||||
*(R->rects) = CGRectMake(x, y, w - 1, h - 1);
|
||||
return R;
|
||||
}
|
||||
inline void XDestroyRegion(Fl_Region r) {
|
||||
if(r) {
|
||||
free(r->rects);
|
||||
free(r);
|
||||
}
|
||||
}
|
||||
extern void *fl_default_cursor;
|
||||
extern void *fl_system_menu;
|
||||
typedef CGContextRef Fl_Offscreen;
|
||||
typedef CGImageRef Fl_Bitmask;
|
||||
|
||||
#else
|
||||
|
||||
typedef WindowRef Window;
|
||||
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);
|
||||
@@ -54,6 +109,14 @@ inline Fl_Region XRectangleRegion(int x, int y, int w, int h) {
|
||||
inline void XDestroyRegion(Fl_Region r) {
|
||||
DisposeRgn(r);
|
||||
}
|
||||
extern CursHandle fl_default_cursor;
|
||||
extern Handle fl_system_menu;
|
||||
typedef GWorldPtr Fl_Offscreen;
|
||||
typedef GWorldPtr Fl_Bitmask; // Carbon requires a 1-bit GWorld instead of a BitMap
|
||||
|
||||
#endif
|
||||
|
||||
void fl_clip_region(Fl_Region);
|
||||
|
||||
# include "Fl_Window.H"
|
||||
|
||||
@@ -62,15 +125,19 @@ inline void XDestroyRegion(Fl_Region r) {
|
||||
class Fl_X
|
||||
{
|
||||
public:
|
||||
Window xid; // Mac WindowPtr
|
||||
GWorldPtr other_xid; // pointer for offscreen bitmaps (doublebuffer)
|
||||
Window xid; // Cocoa: FLWindow* ; Carbon: WindowRef
|
||||
Fl_Offscreen 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; // linked tree to support subwindows
|
||||
Fl_X *xidChildren, *xidNext; // more subwindow tree
|
||||
int wait_for_expose;
|
||||
#ifdef __APPLE_COCOA__
|
||||
void *cursor; // is really NSCursor*
|
||||
#else
|
||||
CursHandle cursor;
|
||||
#endif
|
||||
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&);
|
||||
@@ -78,8 +145,10 @@ public:
|
||||
void flush();
|
||||
// Quartz additions:
|
||||
CGContextRef gc; // graphics context (NULL when using QD)
|
||||
#ifndef __APPLE_COCOA__
|
||||
static ATSUTextLayout atsu_layout; // windows share a global font
|
||||
static ATSUStyle atsu_style;
|
||||
#endif
|
||||
static void q_fill_context(); // fill a Quartz context with current FLTK state
|
||||
static void q_clear_clipping(); // remove all clipping from a Quartz context
|
||||
static void q_release_context(Fl_X *x=0); // free all resources associated with fl_gc
|
||||
@@ -87,18 +156,27 @@ public:
|
||||
static void q_end_image();
|
||||
};
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern void MacDestroyWindow(Fl_Window*,void *);
|
||||
extern void MacMapWindow(Fl_Window*,void *);
|
||||
extern void MacUnmapWindow(Fl_Window*,void *);
|
||||
extern WindowRef MACwindowRef(Fl_Window *w);
|
||||
extern Fl_Region MacRectRegionIntersect(Fl_Region current, int x,int y,int w, int h);
|
||||
extern void MacCollapseWindow(Window w);
|
||||
#else
|
||||
extern void MacDestroyWindow(Fl_Window*,WindowPtr);
|
||||
extern void MacMapWindow(Fl_Window*,WindowPtr);
|
||||
extern void MacUnmapWindow(Fl_Window*,WindowPtr);
|
||||
#endif
|
||||
|
||||
extern int MacUnlinkWindow(Fl_X*,Fl_X*start=0L);
|
||||
extern void fl_open_callback(void (*cb)(const char *));
|
||||
|
||||
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;
|
||||
@@ -107,10 +185,8 @@ extern struct Fl_XMap {
|
||||
extern FL_EXPORT void *fl_display;
|
||||
extern FL_EXPORT Window fl_window;
|
||||
extern FL_EXPORT CGContextRef fl_gc;
|
||||
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);
|
||||
@@ -118,7 +194,6 @@ extern void fl_delete_offscreen(Fl_Offscreen gWorld);
|
||||
extern void fl_begin_offscreen(Fl_Offscreen gWorld);
|
||||
extern void fl_end_offscreen();
|
||||
|
||||
typedef GWorldPtr Fl_Bitmask; // Carbon requires a 1-bit GWorld instead of a BitMap
|
||||
|
||||
extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data);
|
||||
extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data);
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
|
||||
#if defined(__APPLE__) && defined(__APPLE_COCOA__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif // DEBUG
|
||||
@@ -406,10 +410,17 @@ double Fl::wait(double time_to_wait) {
|
||||
// the idle function may turn off idle, we can then wait:
|
||||
if (idle) time_to_wait = 0.0;
|
||||
}
|
||||
#ifdef __APPLE_COCOA__
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
#endif
|
||||
flush();
|
||||
if (idle && !in_idle) // 'idle' may have been set within flush()
|
||||
time_to_wait = 0.0;
|
||||
return fl_wait(time_to_wait);
|
||||
double retval = fl_wait(time_to_wait);
|
||||
#ifdef __APPLE_COCOA__
|
||||
[pool release];
|
||||
#endif
|
||||
return retval;
|
||||
|
||||
#else
|
||||
|
||||
@@ -586,12 +597,13 @@ Fl_Window* fl_find(Window xid) {
|
||||
Fl_X *window;
|
||||
for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next)
|
||||
#if defined(WIN32) || defined(USE_X11)
|
||||
if (window->xid == xid) {
|
||||
if (window->xid == xid)
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (window->xid == xid && !window->w->window()) {
|
||||
if (window->xid == xid && !window->w->window())
|
||||
#else
|
||||
# error unsupported platform
|
||||
#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
|
||||
@@ -1278,7 +1290,11 @@ int Fl_Window::handle(int ev)
|
||||
#if defined(USE_X11) || defined(WIN32)
|
||||
XMapWindow(fl_display, fl_xid(this)); // extra map calls are harmless
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
MacMapWindow(this, fl_xid(this));
|
||||
#ifdef __APPLE_COCOA__
|
||||
MacMapWindow(this, i->xid);
|
||||
#else
|
||||
MacMapWindow(this, fl_xid(this));
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif // __APPLE__
|
||||
@@ -1300,7 +1316,11 @@ int Fl_Window::handle(int ev)
|
||||
#if defined(USE_X11) || defined(WIN32)
|
||||
XUnmapWindow(fl_display, fl_xid(this));
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
MacUnmapWindow(this, i->xid);
|
||||
#else
|
||||
MacUnmapWindow(this, fl_xid(this));
|
||||
#endif
|
||||
#else
|
||||
# error platform unsupported
|
||||
#endif
|
||||
@@ -1453,10 +1473,22 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) {
|
||||
CombineRgn(i->region, i->region, R, RGN_OR);
|
||||
XDestroyRegion(R);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
Fl_Region R = NewRgn();
|
||||
SetRectRgn(R, X, Y, X+W, Y+H);
|
||||
UnionRgn(R, i->region, i->region);
|
||||
DisposeRgn(R);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGRect arg = CGRectMake(X,Y,W - 1,H - 1);
|
||||
int j;//don't add a rectangle totally inside the Fl_Region
|
||||
for(j = 0; j < i->region->count; j++) {
|
||||
if(CGRectContainsRect(i->region->rects[j], arg)) break;
|
||||
}
|
||||
if( j >= i->region->count) {
|
||||
i->region->rects = (CGRect*)realloc(i->region->rects, (++(i->region->count)) * sizeof(CGRect));
|
||||
i->region->rects[i->region->count - 1] = arg;
|
||||
}
|
||||
#else
|
||||
Fl_Region R = NewRgn();
|
||||
SetRectRgn(R, X, Y, X+W, Y+H);
|
||||
UnionRgn(R, i->region, i->region);
|
||||
DisposeRgn(R);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -1480,8 +1512,12 @@ void Fl_Window::flush() {
|
||||
#ifdef WIN32
|
||||
# include "Fl_win32.cxx"
|
||||
#elif defined(__APPLE__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
# include "Fl_cocoa.mm"
|
||||
#else
|
||||
# include "Fl_mac.cxx"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// The following methods allow callbacks to schedule the deletion of
|
||||
|
||||
@@ -325,7 +325,11 @@ Fl_Bitmap::~Fl_Bitmap() {
|
||||
|
||||
void Fl_Bitmap::uncache() {
|
||||
if (id) {
|
||||
#if defined(__APPLE__) && defined(__APPLE_COCOA__)
|
||||
fl_delete_bitmask((Fl_Bitmask)id);
|
||||
#else
|
||||
fl_delete_bitmask((Fl_Offscreen)id);
|
||||
#endif
|
||||
id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ public:
|
||||
# elif defined(__APPLE_QUARTZ__)
|
||||
FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
ATSUTextLayout layout;
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
CTFontRef fontref;
|
||||
#endif
|
||||
ATSUStyle style;
|
||||
short ascent, descent, q_width;
|
||||
// short width[256];
|
||||
|
||||
@@ -57,6 +57,7 @@ void Fl_Input::draw() {
|
||||
int Fl_Input::shift_position(int p) {
|
||||
return position(p, Fl::event_state(FL_SHIFT) ? mark() : p);
|
||||
}
|
||||
|
||||
int Fl_Input::shift_up_down_position(int p) {
|
||||
return up_down_position(p, Fl::event_state(FL_SHIFT));
|
||||
}
|
||||
@@ -108,7 +109,7 @@ int Fl_Input::handle_key() {
|
||||
// the following line is not a true memory leak because the array is only
|
||||
// allocated once if required, and automatically freed when the program quits
|
||||
char *chars = (char*)malloc(len+1);
|
||||
legal_fp_chars = chars;
|
||||
legal_fp_chars = chars;
|
||||
strcpy(chars, standard_fp_chars);
|
||||
if (lc) {
|
||||
if (lc->decimal_point) strcat(chars, lc->decimal_point);
|
||||
@@ -126,11 +127,11 @@ int Fl_Input::handle_key() {
|
||||
|| (ascii >= '0' && ascii <= '9')
|
||||
|| (ip==1 && index(0)=='0' && (ascii=='x' || ascii == 'X'))
|
||||
|| (ip>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X')
|
||||
&& (ascii>='A'&& ascii<='F' || ascii>='a'&& ascii<='f'))
|
||||
&& (ascii>='A'&& ascii<='F' || ascii>='a'&& ascii<='f'))
|
||||
|| input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii))
|
||||
{
|
||||
if (readonly()) fl_beep();
|
||||
else replace(position(), mark(), &ascii, 1);
|
||||
if (readonly()) fl_beep();
|
||||
else replace(position(), mark(), &ascii, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -138,7 +139,7 @@ int Fl_Input::handle_key() {
|
||||
if (del || Fl::event_length()) {
|
||||
if (readonly()) fl_beep();
|
||||
else replace(position(), del ? position()-del : mark(),
|
||||
Fl::event_text(), Fl::event_length());
|
||||
Fl::event_text(), Fl::event_length());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -213,8 +214,8 @@ int Fl_Input::handle_key() {
|
||||
case FL_Page_Up:
|
||||
#ifdef __APPLE__
|
||||
if (mods==0) { // scroll text one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
repeat_num = linesPerPage();
|
||||
ascii = ctrl('P');
|
||||
} else if (mods==FL_ALT) { // move cursor one page
|
||||
@@ -231,8 +232,8 @@ int Fl_Input::handle_key() {
|
||||
if (mods==0) { // line up
|
||||
ascii = ctrl('P');
|
||||
} else if (mods==FL_CTRL) { // scroll text down one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
repeat_num = linesPerPage();
|
||||
ascii = ctrl('P');
|
||||
} else if (mods==FL_ALT) { // line start and up
|
||||
@@ -248,7 +249,7 @@ int Fl_Input::handle_key() {
|
||||
if (mods==0) { // line up
|
||||
ascii = ctrl('P');
|
||||
} else if (mods==FL_CTRL) { // scroll text down one line
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
ascii = ctrl('P');
|
||||
} else return 1;
|
||||
#endif
|
||||
@@ -256,8 +257,8 @@ int Fl_Input::handle_key() {
|
||||
case FL_Page_Down:
|
||||
#ifdef __APPLE__
|
||||
if (mods==0) { // scroll text one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
repeat_num = linesPerPage();
|
||||
ascii = ctrl('N');
|
||||
} else if (mods==FL_ALT) { // move cursor one page
|
||||
@@ -291,7 +292,7 @@ int Fl_Input::handle_key() {
|
||||
if (mods==0) { // line down
|
||||
ascii = ctrl('N');
|
||||
} else if (mods==FL_CTRL) { // scroll text up one line
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
ascii = ctrl('N');
|
||||
} else return 1;
|
||||
#endif
|
||||
@@ -299,8 +300,8 @@ int Fl_Input::handle_key() {
|
||||
case FL_Home:
|
||||
#ifdef __APPLE__
|
||||
if (mods==0) { // scroll display to the top
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
shift_position(0);
|
||||
return 1;
|
||||
} else return 1;
|
||||
@@ -316,8 +317,8 @@ int Fl_Input::handle_key() {
|
||||
case FL_End:
|
||||
#ifdef __APPLE__
|
||||
if (mods==0) { // scroll display to the bottom
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
// OS X scrolls the view, but does not move the cursor
|
||||
// Fl_Input has no scroll control, so instead we move the cursor by one page
|
||||
shift_position(size());
|
||||
return 1;
|
||||
} else return 1;
|
||||
@@ -483,170 +484,170 @@ int Fl_Input::handle(int event) {
|
||||
static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos;
|
||||
static Fl_Widget *dnd_save_focus;
|
||||
switch (event) {
|
||||
case FL_FOCUS:
|
||||
switch (Fl::event_key()) {
|
||||
case FL_Right:
|
||||
position(0);
|
||||
break;
|
||||
case FL_Left:
|
||||
position(size());
|
||||
break;
|
||||
case FL_Down:
|
||||
up_down_position(0);
|
||||
break;
|
||||
case FL_Up:
|
||||
up_down_position(line_start(size()));
|
||||
break;
|
||||
case FL_Tab:
|
||||
case 0xfe20: // XK_ISO_Left_Tab
|
||||
position(size(),0);
|
||||
break;
|
||||
default:
|
||||
position(position(),mark());// turns off the saved up/down arrow position
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FL_KEYBOARD:
|
||||
if (Fl::event_key() == FL_Tab && mark() != position()) {
|
||||
// Set the current cursor position to the end of the selection...
|
||||
if (mark() > position())
|
||||
position(mark());
|
||||
else
|
||||
position(position());
|
||||
return (1);
|
||||
} else {
|
||||
if (active_r() && window() && this == Fl::belowmouse())
|
||||
window()->cursor(FL_CURSOR_NONE);
|
||||
return handle_key();
|
||||
}
|
||||
|
||||
case FL_PUSH:
|
||||
if (Fl::dnd_text_ops()) {
|
||||
int oldpos = position(), oldmark = mark();
|
||||
Fl_Boxtype b = box();
|
||||
Fl_Input_::handle_mouse(
|
||||
x()+Fl::box_dx(b), y()+Fl::box_dy(b),
|
||||
w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
|
||||
newpos = position();
|
||||
position( oldpos, oldmark );
|
||||
if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT &&
|
||||
(newpos >= mark() && newpos < position() ||
|
||||
newpos >= position() && newpos < mark())) {
|
||||
// user clicked in the selection, may be trying to drag
|
||||
drag_start = newpos;
|
||||
return 1;
|
||||
case FL_FOCUS:
|
||||
switch (Fl::event_key()) {
|
||||
case FL_Right:
|
||||
position(0);
|
||||
break;
|
||||
case FL_Left:
|
||||
position(size());
|
||||
break;
|
||||
case FL_Down:
|
||||
up_down_position(0);
|
||||
break;
|
||||
case FL_Up:
|
||||
up_down_position(line_start(size()));
|
||||
break;
|
||||
case FL_Tab:
|
||||
case 0xfe20: // XK_ISO_Left_Tab
|
||||
position(size(),0);
|
||||
break;
|
||||
default:
|
||||
position(position(),mark());// turns off the saved up/down arrow position
|
||||
break;
|
||||
}
|
||||
drag_start = -1;
|
||||
}
|
||||
|
||||
if (Fl::focus() != this) {
|
||||
Fl::focus(this);
|
||||
handle(FL_FOCUS);
|
||||
}
|
||||
break;
|
||||
|
||||
case FL_DRAG:
|
||||
if (Fl::dnd_text_ops()) {
|
||||
if (drag_start >= 0) {
|
||||
if (Fl::event_is_click()) return 1; // debounce the mouse
|
||||
// save the position because sometimes we don't get DND_ENTER:
|
||||
dnd_save_position = position();
|
||||
dnd_save_mark = mark();
|
||||
// drag the data:
|
||||
copy(0); Fl::dnd();
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case FL_KEYBOARD:
|
||||
if (Fl::event_key() == FL_Tab && mark() != position()) {
|
||||
// Set the current cursor position to the end of the selection...
|
||||
if (mark() > position())
|
||||
position(mark());
|
||||
else
|
||||
position(position());
|
||||
return (1);
|
||||
} else {
|
||||
if (active_r() && window() && this == Fl::belowmouse())
|
||||
window()->cursor(FL_CURSOR_NONE);
|
||||
return handle_key();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FL_RELEASE:
|
||||
if (Fl::event_button() == 2) {
|
||||
Fl::event_is_click(0); // stop double click from picking a word
|
||||
Fl::paste(*this, 0);
|
||||
} else if (!Fl::event_is_click()) {
|
||||
// copy drag-selected text to the clipboard.
|
||||
copy(0);
|
||||
} else if (Fl::event_is_click() && drag_start >= 0) {
|
||||
// user clicked in the field and wants to reset the cursor position...
|
||||
position(drag_start, drag_start);
|
||||
drag_start = -1;
|
||||
} else if (Fl::event_clicks()) {
|
||||
// user double or triple clicked to select word or whole text
|
||||
copy(0);
|
||||
}
|
||||
|
||||
// For output widgets, do the callback so the app knows the user
|
||||
// did something with the mouse...
|
||||
if (readonly()) do_callback();
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_DND_ENTER:
|
||||
Fl::belowmouse(this); // send the leave events first
|
||||
dnd_save_position = position();
|
||||
dnd_save_mark = mark();
|
||||
dnd_save_focus = Fl::focus();
|
||||
if (dnd_save_focus != this) {
|
||||
Fl::focus(this);
|
||||
handle(FL_FOCUS);
|
||||
}
|
||||
// fall through:
|
||||
case FL_DND_DRAG:
|
||||
//int p = mouse_position(X, Y, W, H);
|
||||
|
||||
case FL_PUSH:
|
||||
if (Fl::dnd_text_ops()) {
|
||||
int oldpos = position(), oldmark = mark();
|
||||
Fl_Boxtype b = box();
|
||||
Fl_Input_::handle_mouse(
|
||||
x()+Fl::box_dx(b), y()+Fl::box_dy(b),
|
||||
w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
|
||||
newpos = position();
|
||||
position( oldpos, oldmark );
|
||||
if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT &&
|
||||
(newpos >= mark() && newpos < position() ||
|
||||
newpos >= position() && newpos < mark())) {
|
||||
// user clicked in the selection, may be trying to drag
|
||||
drag_start = newpos;
|
||||
return 1;
|
||||
}
|
||||
drag_start = -1;
|
||||
}
|
||||
|
||||
if (Fl::focus() != this) {
|
||||
Fl::focus(this);
|
||||
handle(FL_FOCUS);
|
||||
}
|
||||
break;
|
||||
|
||||
case FL_DRAG:
|
||||
if (Fl::dnd_text_ops()) {
|
||||
if (drag_start >= 0) {
|
||||
if (Fl::event_is_click()) return 1; // debounce the mouse
|
||||
// save the position because sometimes we don't get DND_ENTER:
|
||||
dnd_save_position = position();
|
||||
dnd_save_mark = mark();
|
||||
// drag the data:
|
||||
copy(0); Fl::dnd();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FL_RELEASE:
|
||||
if (Fl::event_button() == 2) {
|
||||
Fl::event_is_click(0); // stop double click from picking a word
|
||||
Fl::paste(*this, 0);
|
||||
} else if (!Fl::event_is_click()) {
|
||||
// copy drag-selected text to the clipboard.
|
||||
copy(0);
|
||||
} else if (Fl::event_is_click() && drag_start >= 0) {
|
||||
// user clicked in the field and wants to reset the cursor position...
|
||||
position(drag_start, drag_start);
|
||||
drag_start = -1;
|
||||
} else if (Fl::event_clicks()) {
|
||||
// user double or triple clicked to select word or whole text
|
||||
copy(0);
|
||||
}
|
||||
|
||||
// For output widgets, do the callback so the app knows the user
|
||||
// did something with the mouse...
|
||||
if (readonly()) do_callback();
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_DND_ENTER:
|
||||
Fl::belowmouse(this); // send the leave events first
|
||||
dnd_save_position = position();
|
||||
dnd_save_mark = mark();
|
||||
dnd_save_focus = Fl::focus();
|
||||
if (dnd_save_focus != this) {
|
||||
Fl::focus(this);
|
||||
handle(FL_FOCUS);
|
||||
}
|
||||
// fall through:
|
||||
case FL_DND_DRAG:
|
||||
//int p = mouse_position(X, Y, W, H);
|
||||
#if DND_OUT_XXXX
|
||||
if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark ||
|
||||
p>=dnd_save_mark && p<=dnd_save_position)) {
|
||||
position(dnd_save_position, dnd_save_mark);
|
||||
return 0;
|
||||
}
|
||||
if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark ||
|
||||
p>=dnd_save_mark && p<=dnd_save_position)) {
|
||||
position(dnd_save_position, dnd_save_mark);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
Fl_Boxtype b = box();
|
||||
Fl_Input_::handle_mouse(
|
||||
x()+Fl::box_dx(b), y()+Fl::box_dy(b),
|
||||
w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
|
||||
x()+Fl::box_dx(b), y()+Fl::box_dy(b),
|
||||
w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case FL_DND_LEAVE:
|
||||
position(dnd_save_position, dnd_save_mark);
|
||||
return 1;
|
||||
|
||||
case FL_DND_LEAVE:
|
||||
position(dnd_save_position, dnd_save_mark);
|
||||
#if DND_OUT_XXXX
|
||||
if (!focused())
|
||||
if (!focused())
|
||||
#endif
|
||||
if (dnd_save_focus != this) {
|
||||
Fl::focus(dnd_save_focus);
|
||||
handle(FL_UNFOCUS);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case FL_DND_RELEASE:
|
||||
take_focus();
|
||||
return 1;
|
||||
|
||||
/* TODO: this will scroll the area, but stop if the cursor would become invisible.
|
||||
That clipping happens in drawtext(). Do we change the clipping or should
|
||||
we move the cursor (ouch)?
|
||||
case FL_MOUSEWHEEL:
|
||||
if (Fl::e_dy > 0) {
|
||||
yscroll( yscroll() - Fl::e_dy*15 );
|
||||
} else if (Fl::e_dy < 0) {
|
||||
yscroll( yscroll() - Fl::e_dy*15 );
|
||||
}
|
||||
return 1;
|
||||
*/
|
||||
|
||||
if (dnd_save_focus != this) {
|
||||
Fl::focus(dnd_save_focus);
|
||||
handle(FL_UNFOCUS);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case FL_DND_RELEASE:
|
||||
take_focus();
|
||||
return 1;
|
||||
|
||||
/* TODO: this will scroll the area, but stop if the cursor would become invisible.
|
||||
That clipping happens in drawtext(). Do we change the clipping or should
|
||||
we move the cursor (ouch)?
|
||||
case FL_MOUSEWHEEL:
|
||||
if (Fl::e_dy > 0) {
|
||||
yscroll( yscroll() - Fl::e_dy*15 );
|
||||
} else if (Fl::e_dy < 0) {
|
||||
yscroll( yscroll() - Fl::e_dy*15 );
|
||||
}
|
||||
return 1;
|
||||
*/
|
||||
|
||||
}
|
||||
Fl_Boxtype b = box();
|
||||
return Fl_Input_::handletext(event,
|
||||
x()+Fl::box_dx(b), y()+Fl::box_dy(b),
|
||||
w()-Fl::box_dw(b), h()-Fl::box_dh(b));
|
||||
x()+Fl::box_dx(b), y()+Fl::box_dy(b),
|
||||
w()-Fl::box_dw(b), h()-Fl::box_dh(b));
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new Fl_Input widget using the given position, size,
|
||||
and label string. The default boxtype is FL_DOWN_BOX.
|
||||
*/
|
||||
Creates a new Fl_Input widget using the given position, size,
|
||||
and label string. The default boxtype is FL_DOWN_BOX.
|
||||
*/
|
||||
Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l)
|
||||
: Fl_Input_(X, Y, W, H, l) {
|
||||
}
|
||||
|
||||
@@ -1247,7 +1247,7 @@ int Fl_Input_::linesPerPage() {
|
||||
\param [in] i index into the value field
|
||||
\return the character at index \p i
|
||||
*/
|
||||
Fl_Char Fl_Input_::index(int i) const
|
||||
unsigned int Fl_Input_::index(int i) const
|
||||
{
|
||||
int len = 0;
|
||||
return fl_utf8decode(value_+i, value_+size_, &len);
|
||||
|
||||
@@ -235,7 +235,7 @@ int Fl_Menu_Item::add(
|
||||
^ - Control
|
||||
\endverbatim
|
||||
Text shortcuts are converted to integer shortcut by calling
|
||||
Fl_Shortcut fl_old_shortcut(const char*).
|
||||
unsigned int fl_old_shortcut(const char*).
|
||||
|
||||
\par callback
|
||||
The callback to invoke when this menu item is selected.
|
||||
|
||||
@@ -870,6 +870,16 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char
|
||||
"/%s/%s.prefs", vendor, application);
|
||||
for (char *s = filename; *s; s++) if (*s == '\\') *s = '/';
|
||||
#elif defined ( __APPLE__ )
|
||||
#ifdef __APPLE_COCOA__
|
||||
switch (root) {
|
||||
case SYSTEM:
|
||||
strcpy(filename, "/Library/Preferences");
|
||||
break;
|
||||
case USER:
|
||||
sprintf(filename, "%s/Library/Preferences", fl_getenv("HOME"));
|
||||
break;
|
||||
}
|
||||
#else
|
||||
FSSpec spec = { 0 };
|
||||
FSRef ref;
|
||||
OSErr err = fnfErr;
|
||||
@@ -885,6 +895,7 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char
|
||||
}
|
||||
FSpMakeFSRef( &spec, &ref );
|
||||
FSRefMakePath( &ref, (UInt8*)filename, FL_PATH_MAX );
|
||||
#endif
|
||||
snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename),
|
||||
"/%s/%s.prefs", vendor, application );
|
||||
#else
|
||||
|
||||
@@ -61,6 +61,12 @@
|
||||
#include "flstring.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern void *MACMenuOrItemOperation(const char *operation, ...);
|
||||
#define MenuHandle void *
|
||||
#endif
|
||||
|
||||
typedef const Fl_Menu_Item *pFl_Menu_Item;
|
||||
|
||||
@@ -69,7 +75,9 @@ typedef const Fl_Menu_Item *pFl_Menu_Item;
|
||||
* Skip all '&' which would mark the shortcut in FLTK
|
||||
* Skip all Mac control characters ('(', '<', ';', '^', '!' )
|
||||
*/
|
||||
static void catMenuText( const char *src, char *dst )
|
||||
|
||||
#ifndef __APPLE_COCOA__
|
||||
static void catMenuText( const char *src, char *dst )
|
||||
{
|
||||
char c;
|
||||
while ( *dst )
|
||||
@@ -88,6 +96,7 @@ static void catMenuText( const char *src, char *dst )
|
||||
* 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_ )
|
||||
@@ -110,11 +119,11 @@ static void catMenuFont( const Fl_Menu_Item *m, char *dst )
|
||||
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
|
||||
* <B, I, U, O, and S
|
||||
enum {
|
||||
kMenuNoModifiers = 0,
|
||||
kMenuShiftModifier = (1 << 0),
|
||||
@@ -122,7 +131,9 @@ enum {
|
||||
kMenuControlModifier = (1 << 2),
|
||||
kMenuNoCommandModifier = (1 << 3)
|
||||
};
|
||||
*/
|
||||
*/
|
||||
#endif
|
||||
|
||||
static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
|
||||
{
|
||||
if ( !m->shortcut_ )
|
||||
@@ -135,6 +146,11 @@ static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
|
||||
if ( !isalnum( key ) )
|
||||
return;
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
void *menuItem = MACMenuOrItemOperation("itemAtIndex", mh, miCnt);
|
||||
MACMenuOrItemOperation("setKeyEquivalent", menuItem, m->shortcut_ & 0xff );
|
||||
MACMenuOrItemOperation("setKeyEquivalentModifierMask", menuItem, m->shortcut_ );
|
||||
#else
|
||||
long macMod = kMenuNoCommandModifier;
|
||||
if ( m->shortcut_ & FL_META ) macMod = kMenuNoModifiers;
|
||||
if ( m->shortcut_ & FL_SHIFT || isupper(key) ) macMod |= kMenuShiftModifier;
|
||||
@@ -144,8 +160,10 @@ static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
|
||||
//SetMenuItemKeyGlyph( mh, miCnt, key );
|
||||
SetItemCmd( mh, miCnt, toupper(key) );
|
||||
SetMenuItemModifiers( mh, miCnt, macMod );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// this function needs to be verified before we compile it back in.
|
||||
static void catMenuShortcut( const Fl_Menu_Item *m, char *dst )
|
||||
@@ -166,16 +184,161 @@ static void catMenuShortcut( const Fl_Menu_Item *m, char *dst )
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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 );
|
||||
#ifdef __APPLE_COCOA__
|
||||
void *menuItem = MACMenuOrItemOperation("itemAtIndex", mh, miCnt);
|
||||
MACMenuOrItemOperation("setState", menuItem, m->flags & FL_MENU_VALUE );
|
||||
#else
|
||||
SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 );
|
||||
#endif
|
||||
}
|
||||
else if ( m->flags & FL_MENU_RADIO ) {
|
||||
#ifndef __APPLE_COCOA__
|
||||
SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
|
||||
#endif
|
||||
}
|
||||
else if ( m->flags & FL_MENU_RADIO )
|
||||
SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
|
||||
/**
|
||||
* create a sub menu for a specific menu handle
|
||||
*/
|
||||
static void createSubMenu( void * mh, pFl_Menu_Item &mm )
|
||||
{
|
||||
void *submenu;
|
||||
int miCnt, flags;
|
||||
|
||||
void *menuItem;
|
||||
submenu = MACMenuOrItemOperation("initWithTitle", mm->text);
|
||||
int cnt;
|
||||
MACMenuOrItemOperation("numberOfItems", mh, &cnt);
|
||||
cnt--;
|
||||
menuItem = MACMenuOrItemOperation("itemAtIndex", mh, cnt);
|
||||
MACMenuOrItemOperation("setSubmenu", menuItem, submenu);
|
||||
if ( mm->flags & FL_MENU_INACTIVE ) {
|
||||
MACMenuOrItemOperation("setEnabled", menuItem, 0);
|
||||
}
|
||||
mm++;
|
||||
|
||||
while ( mm->text )
|
||||
{
|
||||
int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu();
|
||||
MACMenuOrItemOperation("addNewItem", submenu, flRank, &miCnt);
|
||||
setMenuFlags( submenu, miCnt, mm );
|
||||
setMenuShortcut( submenu, miCnt, mm );
|
||||
if ( mm->flags & FL_MENU_INACTIVE ) {
|
||||
void *item = MACMenuOrItemOperation("itemAtIndex", submenu, miCnt);
|
||||
MACMenuOrItemOperation("setEnabled", item, 0);
|
||||
}
|
||||
flags = mm->flags;
|
||||
if ( mm->flags & FL_SUBMENU )
|
||||
{
|
||||
createSubMenu( submenu, mm );
|
||||
}
|
||||
else if ( mm->flags & FL_SUBMENU_POINTER )
|
||||
{
|
||||
const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
|
||||
createSubMenu( submenu, smm );
|
||||
}
|
||||
if ( flags & FL_MENU_DIVIDER ) {
|
||||
MACMenuOrItemOperation("addSeparatorItem", submenu);
|
||||
}
|
||||
mm++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void convertToMenuBar(const Fl_Menu_Item *mm)
|
||||
//convert a complete Fl_Menu_Item array into a series of menus in the top menu bar
|
||||
//ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW DATA
|
||||
{
|
||||
int count;//first, delete all existing system menus
|
||||
MACMenuOrItemOperation("numberOfItems", fl_system_menu, &count);
|
||||
for(int i = count - 1; i > 0; i--) {
|
||||
MACMenuOrItemOperation("removeItem", fl_system_menu, i);
|
||||
}
|
||||
//now convert FLTK stuff into MacOS menus
|
||||
for (;;)
|
||||
{
|
||||
if ( !mm || !mm->text )
|
||||
break;
|
||||
char visible = mm->visible() ? 1 : 0;
|
||||
int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu();
|
||||
MACMenuOrItemOperation("addNewItem", fl_system_menu, flRank, NULL);
|
||||
|
||||
if ( mm->flags & FL_SUBMENU )
|
||||
createSubMenu( fl_system_menu, mm );
|
||||
else if ( mm->flags & FL_SUBMENU_POINTER ) {
|
||||
const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
|
||||
createSubMenu( fl_system_menu, smm );
|
||||
}
|
||||
if ( visible ) {
|
||||
// InsertMenu( mh, 0 );
|
||||
}
|
||||
mm++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
convertToMenuBar(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the system menu bar a new menu item, with a title string, shortcut int,
|
||||
* callback, argument to the callback, and flags.
|
||||
*
|
||||
* @see Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
|
||||
*/
|
||||
int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
|
||||
{
|
||||
fl_open_display();
|
||||
int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags);
|
||||
convertToMenuBar(Fl_Menu_::menu());
|
||||
return rank;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove an item from the system menu bar
|
||||
*
|
||||
* @param rank the rank of the item to remove
|
||||
*/
|
||||
void Fl_Sys_Menu_Bar::remove(int rank)
|
||||
{
|
||||
Fl_Menu_::remove(rank);
|
||||
convertToMenuBar(Fl_Menu_::menu());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rename an item from the system menu bar
|
||||
*
|
||||
* @param rank the rank of the item to rename
|
||||
* @param name the new item name as a UTF8 string
|
||||
*/
|
||||
void Fl_Sys_Menu_Bar::replace(int rank, const char *name)
|
||||
{
|
||||
MACMenuOrItemOperation("renameItem", rank, name);
|
||||
fl_sys_menu_bar->Fl_Menu_::replace(rank, name);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void catMenuFlags( const Fl_Menu_Item *m, char *dst )
|
||||
{
|
||||
if ( !m->flags )
|
||||
@@ -184,7 +347,7 @@ static void catMenuFlags( const Fl_Menu_Item *m, char *dst )
|
||||
strcat( dst, "(" );
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* create a sub menu for a specific menu handle
|
||||
*/
|
||||
static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm )
|
||||
@@ -229,7 +392,7 @@ static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm )
|
||||
}
|
||||
InsertMenu( mh, -1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* create a system menu bar using the given list of menu structs
|
||||
@@ -243,9 +406,9 @@ 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 (;;)
|
||||
@@ -276,6 +439,8 @@ void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m)
|
||||
DrawMenuBar();
|
||||
}
|
||||
|
||||
#endif //__APPLE_COCOA__
|
||||
|
||||
/*
|
||||
const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) {
|
||||
Fl_menu_Item *ret = Fl_Menu_Bar::picked( v );
|
||||
@@ -290,42 +455,31 @@ const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) {
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
// equivalent (but totally different) crap for MSWindows is in Fl_win32.cxx
|
||||
#include "config.h"
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/x.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
@@ -125,6 +126,10 @@ void Fl_Window::draw() {
|
||||
int i;
|
||||
for (i=dx; i<12; i++) {
|
||||
fl_color(c[i&3]);
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern CGContextRef fl_gc;
|
||||
if(fl_gc)
|
||||
#endif
|
||||
fl_line(x1--, y1, x2, y2--);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,11 @@ void Fl_Window::iconize() {
|
||||
#ifdef WIN32
|
||||
ShowWindow(i->xid, SW_SHOWMINNOACTIVE);
|
||||
#elif defined(__APPLE__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
MacCollapseWindow((Window)i->xid);
|
||||
#else
|
||||
CollapseWindow( i->xid, true );
|
||||
#endif
|
||||
#else
|
||||
XIconifyWindow(fl_display, i->xid, fl_screen);
|
||||
#endif
|
||||
|
||||
@@ -88,13 +88,6 @@ int Fl::arg(int argc, char **argv, int &i) {
|
||||
if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;}
|
||||
s++; // point after the dash
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (!strncmp(s, "psn", 3)) {
|
||||
// Skip process serial number...
|
||||
i++;
|
||||
}
|
||||
else
|
||||
#endif // __APPLE__
|
||||
if (fl_match(s, "iconic")) {
|
||||
fl_show_iconic = 1;
|
||||
i++;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
//
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/x.H>
|
||||
|
||||
//
|
||||
// MRS: Uncomment the following define to get the original (pre-1.1.2)
|
||||
@@ -38,6 +39,15 @@
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
|
||||
static const char* const compose_pairs =
|
||||
" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "//00A0 ...
|
||||
"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss" //00C0 ...
|
||||
"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";//00E0 ...
|
||||
|
||||
#else
|
||||
|
||||
static const char* const compose_pairs =
|
||||
":A*A,C'E~N:O:U'a`a^a:a~a*a,c'e`e"
|
||||
"^e:e'i`i^i:i~n'o`o^o:o~o'u`u^u:u"
|
||||
@@ -48,6 +58,8 @@ static const char* const compose_pairs =
|
||||
"++..,,_\"%%^A^E'A:E`E'I^I:I`I'O^O"
|
||||
"mc`O'U^U`U||^ ~^_ u . * , ~-; v ";
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
static const char* const compose_pairs =
|
||||
|
||||
@@ -48,7 +48,12 @@ extern HWND fl_capture;
|
||||
|
||||
#ifdef __APPLE__
|
||||
// MacOS Carbon does not seem to have a mechanism to grab the mouse pointer
|
||||
extern WindowRef fl_capture;
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern void MACsetkeywindow(void *nsw);
|
||||
extern void *fl_capture;
|
||||
#else
|
||||
extern Window fl_capture;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void Fl::grab(Fl_Window* win) {
|
||||
@@ -58,8 +63,13 @@ void Fl::grab(Fl_Window* win) {
|
||||
SetActiveWindow(fl_capture = fl_xid(first_window()));
|
||||
SetCapture(fl_capture);
|
||||
#elif defined(__APPLE__)
|
||||
fl_capture = fl_xid( first_window() );
|
||||
SetUserFocusWindow( fl_capture );
|
||||
#ifdef __APPLE_COCOA__
|
||||
fl_capture = Fl_X::i(first_window())->xid;
|
||||
MACsetkeywindow(fl_capture);
|
||||
#else
|
||||
fl_capture = fl_xid( first_window() );
|
||||
SetUserFocusWindow( fl_capture );
|
||||
#endif
|
||||
#else
|
||||
XGrabPointer(fl_display,
|
||||
fl_xid(first_window()),
|
||||
@@ -87,7 +97,9 @@ void Fl::grab(Fl_Window* win) {
|
||||
ReleaseCapture();
|
||||
#elif defined(__APPLE__)
|
||||
fl_capture = 0;
|
||||
#ifndef __APPLE_COCOA__
|
||||
SetUserFocusWindow( (WindowRef)kUserFocusAuto );
|
||||
#endif
|
||||
#else
|
||||
XUngrabKeyboard(fl_display, fl_event_time);
|
||||
XUngrabPointer(fl_display, fl_event_time);
|
||||
|
||||
@@ -780,15 +780,6 @@ static inline void checkdouble() {
|
||||
|
||||
static Fl_Window* resize_bug_fix;
|
||||
|
||||
extern "C" {
|
||||
static Bool fake_keyup_test(Display*, XEvent* event, char* previous) {
|
||||
return
|
||||
event->type == KeyPress &&
|
||||
event->xkey.keycode == ((XKeyEvent*)previous)->keycode &&
|
||||
event->xkey.time == ((XKeyEvent*)previous)->time;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static char unknown[] = "<unknown>";
|
||||
@@ -1173,11 +1164,35 @@ int fl_handle(const XEvent& thisevent)
|
||||
// down, probably due to some back compatibility problem. Fortunately
|
||||
// we can detect this because the repeating KeyPress event is in
|
||||
// the queue, get it and execute it instead:
|
||||
XEvent temp;
|
||||
if (XCheckIfEvent(fl_display,&temp,fake_keyup_test,(char*)(&xevent))){
|
||||
xevent = temp;
|
||||
goto KEYPRESS;
|
||||
|
||||
// Bool XkbSetDetectableAutorepeat ( display, detectable, supported_rtrn )
|
||||
// Display * display ;
|
||||
// Bool detectable ;
|
||||
// Bool * supported_rtrn ;
|
||||
// ...would be the easy way to corrct this isuue. Unfortunatly, this call is also
|
||||
// broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009)
|
||||
|
||||
// Bogus KeyUp events are generated by repeated KeyDown events. One
|
||||
// neccessary condition is an identical key event pending right after
|
||||
// the bogus KeyUp.
|
||||
// The new code introduced Dec 2009 differs in that it only check the very
|
||||
// next event in the queue, not the entire queue of events.
|
||||
// This function wrongly detects a repeat key if a software keyboard
|
||||
// sends a burst of events containing two consecutive equal keys. However,
|
||||
// in every non-gaming situation, this is no problem because both KeyPress
|
||||
// events will cause the expected behavior.
|
||||
XEvent peekevent;
|
||||
if (XPending(fl_display)) {
|
||||
XPeekEvent(fl_display, &peekevent);
|
||||
if ( (peekevent.type == KeyPress) // must be a KeyPress event
|
||||
&& (peekevent.xkey.keycode == xevent.xkey.keycode) // must be the same key
|
||||
&& (peekevent.xkey.time == xevent.xkey.time) // must be sent at the exact same time
|
||||
) {
|
||||
XNextEvent(fl_display, &xevent);
|
||||
goto KEYPRESS;
|
||||
}
|
||||
}
|
||||
|
||||
event = FL_KEYUP;
|
||||
fl_key_vector[keycode/8] &= ~(1 << (keycode%8));
|
||||
// keyup events just get the unshifted keysym:
|
||||
|
||||
@@ -86,6 +86,9 @@ void fl_arc(int x,int y,int w,int h,double a1,double a2) {
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI;
|
||||
float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
if (w!=h) {
|
||||
CGContextSaveGState(fl_gc);
|
||||
CGContextTranslateCTM(fl_gc, cx, cy);
|
||||
@@ -97,6 +100,9 @@ void fl_arc(int x,int y,int w,int h,double a1,double a2) {
|
||||
CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1);
|
||||
}
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -136,6 +142,9 @@ void fl_pie(int x,int y,int w,int h,double a1,double a2) {
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI;
|
||||
float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f;
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
if (w!=h) {
|
||||
CGContextSaveGState(fl_gc);
|
||||
CGContextTranslateCTM(fl_gc, cx, cy);
|
||||
@@ -151,6 +160,9 @@ void fl_pie(int x,int y,int w,int h,double a1,double a2) {
|
||||
CGContextClosePath(fl_gc);
|
||||
}
|
||||
CGContextFillPath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
@@ -273,7 +273,8 @@ void fl_beep(int type) {
|
||||
switch (type) {
|
||||
case FL_BEEP_DEFAULT :
|
||||
case FL_BEEP_ERROR :
|
||||
SysBeep(30);
|
||||
// SysBeep(30);
|
||||
AlertSoundPlay();
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
|
||||
@@ -134,6 +134,113 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) {
|
||||
# error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern void *MACSetCursor(Fl_Cursor c);
|
||||
extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h);
|
||||
|
||||
|
||||
CGContextRef CreateHelpImage(void)
|
||||
{
|
||||
int w = 20, h = 20;
|
||||
Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
|
||||
fl_begin_offscreen(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
fl_rectf(0,0,w,h);
|
||||
fl_color(FL_BLACK);
|
||||
fl_font(FL_COURIER_BOLD, 20);
|
||||
fl_draw("?", 1, h-1);
|
||||
fl_end_offscreen();
|
||||
return (CGContextRef)off;
|
||||
}
|
||||
|
||||
CGContextRef CreateNoneImage(void)
|
||||
{
|
||||
int w = 20, h = 20;
|
||||
Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
|
||||
fl_begin_offscreen(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
fl_rectf(0,0,w,h);
|
||||
fl_end_offscreen();
|
||||
return (CGContextRef)off;
|
||||
}
|
||||
|
||||
CGContextRef CreateWatchImage(void)
|
||||
{
|
||||
int w, h, r = 5;
|
||||
w = 2*r+6;
|
||||
h = 4*r;
|
||||
Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
|
||||
fl_begin_offscreen(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
fl_rectf(0,0,w,h);
|
||||
CGContextTranslateCTM( (CGContextRef)off, w/2, h/2);
|
||||
fl_color(FL_WHITE);
|
||||
fl_circle(0, 0, r+1);
|
||||
fl_color(FL_BLACK);
|
||||
fl_rectf(-r*0.7, -r*1.7, 1.4*r, 3.4*r);
|
||||
fl_rectf(r-1, -1, 3, 3);
|
||||
fl_color(FL_WHITE);
|
||||
fl_pie(-r, -r, 2*r, 2*r, 0, 360);
|
||||
fl_color(FL_BLACK);
|
||||
fl_circle(0,0,r);
|
||||
fl_xyline(0, 0, -r*.7);
|
||||
fl_xyline(0, 0, 0, -r*.7);
|
||||
fl_end_offscreen();
|
||||
return (CGContextRef)off;
|
||||
}
|
||||
|
||||
CGContextRef CreateNESWImage(void)
|
||||
{
|
||||
int c = 7, r = 2*c;
|
||||
int w = r, h = r;
|
||||
Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
|
||||
fl_begin_offscreen(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
fl_rectf(0,0,w,h);
|
||||
CGContextTranslateCTM( (CGContextRef)off, 0, h);
|
||||
CGContextScaleCTM( (CGContextRef)off, 1, -1);
|
||||
fl_color(FL_BLACK);
|
||||
fl_polygon(0, 0, c, 0, 0, c);
|
||||
fl_polygon(r, r, r, r-c, r-c, r);
|
||||
fl_line_style(FL_SOLID, 2, 0);
|
||||
fl_line(0,1, r,r+1);
|
||||
fl_line_style(FL_SOLID, 0, 0);
|
||||
fl_end_offscreen();
|
||||
return (CGContextRef)off;
|
||||
}
|
||||
|
||||
CGContextRef CreateNWSEImage(void)
|
||||
{
|
||||
int c = 7, r = 2*c;
|
||||
int w = r, h = r;
|
||||
Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
|
||||
fl_begin_offscreen(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
fl_rectf(0,0,w,h);
|
||||
CGContextTranslateCTM( (CGContextRef)off, 0, h);
|
||||
CGContextScaleCTM( (CGContextRef)off, 1, -1);
|
||||
fl_color(FL_BLACK);
|
||||
fl_polygon(r-1, 0, r-1, c, r-1-c, 0);
|
||||
fl_polygon(-1, r, c-1, r, -1, r-c);
|
||||
fl_line_style(FL_SOLID, 2, 0);
|
||||
fl_line(r-1,1, -1,r+1);
|
||||
fl_line_style(FL_SOLID, 0, 0);
|
||||
fl_end_offscreen();
|
||||
return (CGContextRef)off;
|
||||
}
|
||||
|
||||
void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
|
||||
if (c == FL_CURSOR_DEFAULT) {
|
||||
c = cursor_default;
|
||||
}
|
||||
void *cursor = MACSetCursor( c );
|
||||
if (i) {
|
||||
i->cursor = cursor;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static Cursor crsrHAND =
|
||||
{
|
||||
{ E(0x0600), E(0x0900), E(0x0900), E(0x0900), E(0x09C0), E(0x0938), E(0x6926), E(0x9805),
|
||||
@@ -214,7 +321,7 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
|
||||
c = cursor_default;
|
||||
}
|
||||
CursHandle icrsr = fl_default_cursor;
|
||||
switch (c) {
|
||||
switch (c) {
|
||||
case FL_CURSOR_CROSS: icrsr = GetCursor( crossCursor ); break;
|
||||
case FL_CURSOR_WAIT: icrsr = GetCursor( watchCursor ); break;
|
||||
case FL_CURSOR_INSERT: icrsr = GetCursor( iBeamCursor ); break;
|
||||
@@ -246,6 +353,8 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__APPLE_COCOA__
|
||||
|
||||
#else
|
||||
|
||||
// I like the MSWindows resize cursors, so I duplicate them here:
|
||||
|
||||
@@ -46,6 +46,11 @@ extern int fl_selection_length;
|
||||
*/
|
||||
int Fl::dnd()
|
||||
{
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern int MACpreparedrag(void);
|
||||
return MACpreparedrag();
|
||||
#else
|
||||
|
||||
OSErr result;
|
||||
DragReference dragRef;
|
||||
result = NewDrag( &dragRef );
|
||||
@@ -82,6 +87,7 @@ int Fl::dnd()
|
||||
DisposeRgn( region );
|
||||
DisposeDrag( dragRef );
|
||||
return true;
|
||||
#endif //__APPLE_COCOA__
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ extern unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short*
|
||||
// if no font has been selected yet by the user, get one.
|
||||
#define check_default_font() {if (!fl_fontsize) fl_font(0, 12);}
|
||||
|
||||
static const CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
|
||||
|
||||
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
|
||||
next = 0;
|
||||
# if HAVE_GL
|
||||
@@ -43,13 +45,39 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
|
||||
// OpenGL needs those for its font handling
|
||||
q_name = strdup(name);
|
||||
size = Size;
|
||||
minsize = maxsize = Size;
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
if(CTFontCreateWithName != NULL) {
|
||||
CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
|
||||
fontref = CTFontCreateWithName(str, size, NULL);
|
||||
CGGlyph glyph[2];
|
||||
const UniChar A[2]={'W','.'};
|
||||
CTFontGetGlyphsForCharacters(fontref, A, glyph, 2);
|
||||
CGSize advances[2];
|
||||
double w;
|
||||
CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, advances, 2);
|
||||
w = advances[0].width;
|
||||
if( abs(advances[0].width - advances[1].width) < 1E-2 ) {//this is a fixed-width font
|
||||
//slightly rescale fixed-width fonts so the character width has an integral value
|
||||
CFRelease(fontref);
|
||||
CGFloat fsize = size / ( w/floor(w + 0.5) );
|
||||
fontref = CTFontCreateWithName(str, fsize, NULL);
|
||||
w = CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, NULL, 1);
|
||||
}
|
||||
CFRelease(str);
|
||||
ascent = (short)(CTFontGetAscent(fontref) + 0.5);
|
||||
descent = (short)(CTFontGetDescent(fontref) + 0.5);
|
||||
q_width = w + 0.5;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if ! __LP64__
|
||||
OSStatus err;
|
||||
// fill our structure with a few default values
|
||||
ascent = Size*3/4;
|
||||
descent = Size-ascent;
|
||||
q_width = Size*2/3;
|
||||
minsize = maxsize = Size;
|
||||
// now use ATS to get the actual Glyph size information
|
||||
// now use ATS to get the actual Glyph size information
|
||||
// say that our passed-in name is encoded as UTF-8, since this works for plain ASCII names too...
|
||||
CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingUTF8);
|
||||
ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault);
|
||||
@@ -112,6 +140,10 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
|
||||
// cause ATSU to find a suitable font to render any chars the current font can't do...
|
||||
ATSUSetTransientFontMatching (layout, true);
|
||||
# endif
|
||||
#endif//__LP64__
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Fl_Font_Descriptor* fl_fontsize = 0L;
|
||||
@@ -132,8 +164,12 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
|
||||
#endif
|
||||
*/
|
||||
if (this == fl_fontsize) fl_fontsize = 0;
|
||||
ATSUDisposeTextLayout(layout);
|
||||
ATSUDisposeStyle(style);
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
if(CTFontCreateWithName != NULL) CFRelease(fontref);
|
||||
#else
|
||||
/* ATSUDisposeTextLayout(layout);
|
||||
ATSUDisposeStyle(style); */
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -235,7 +271,25 @@ double fl_width(const UniChar* txt, int n) {
|
||||
if (!fl_fontsize)
|
||||
return 8*n; // user must select a font first!
|
||||
}
|
||||
OSStatus err;
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
if(CTFontCreateWithName != NULL) {
|
||||
CTFontRef fontref = fl_fontsize->fontref;
|
||||
CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n * sizeof(UniChar), kCFStringEncodingUTF16, false);
|
||||
CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str, NULL);
|
||||
CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr);
|
||||
CFRelease(astr);
|
||||
CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str)), kCTFontAttributeName, fontref);
|
||||
CFRelease(str);
|
||||
CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
|
||||
CFRelease(mastr);
|
||||
double retval = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL);
|
||||
CFRelease(ctline);
|
||||
return retval;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if ! __LP64__
|
||||
OSStatus err;
|
||||
Fixed bBefore, bAfter, bAscent, bDescent;
|
||||
ATSUTextLayout layout;
|
||||
ByteCount iSize;
|
||||
@@ -256,6 +310,10 @@ double fl_width(const UniChar* txt, int n) {
|
||||
// If err is OK then return length, else return 0. Or something...
|
||||
int len = FixedToInt(bAfter);
|
||||
return len;
|
||||
#endif
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
double fl_width(const char* txt, int n) {
|
||||
@@ -281,6 +339,30 @@ void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h
|
||||
h = 8.0;
|
||||
return;
|
||||
}
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
if(CTFontCreateWithName != NULL) {
|
||||
CTFontRef fontref = fl_fontsize->fontref;
|
||||
CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n *sizeof(UniChar), kCFStringEncodingUTF16, false);
|
||||
CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str16, NULL);
|
||||
CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr);
|
||||
CFRelease(astr);
|
||||
CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str16)), kCTFontAttributeName, fontref);
|
||||
CFRelease(str16);
|
||||
CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
|
||||
CFRelease(mastr);
|
||||
CGContextSetTextPosition(fl_gc, 0, 0);
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
CGRect rect = CTLineGetImageBounds(ctline, fl_gc);
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
CFRelease(ctline);
|
||||
dx = floor(rect.origin.x + 0.5);
|
||||
dy = floor(- rect.origin.y - rect.size.height + 0.5);
|
||||
w = rect.size.width + 0.5;
|
||||
h = rect.size.height + 0.5;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if ! __LP64__
|
||||
OSStatus err;
|
||||
ATSUTextLayout layout;
|
||||
ByteCount iSize;
|
||||
@@ -304,6 +386,10 @@ void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h
|
||||
dx = bbox.left;
|
||||
dy = -bbox.bottom;
|
||||
//printf("r: %d l: %d t: %d b: %d w: %d h: %d\n", bbox.right, bbox.left, bbox.top, bbox.bottom, w, h);
|
||||
#endif
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
} // fl_text_extents
|
||||
|
||||
@@ -320,13 +406,76 @@ void fl_draw(const char* str, int n, int x, int y) {
|
||||
fl_draw(str, n, (float)x-0.0f, (float)y-0.5f);
|
||||
}
|
||||
|
||||
|
||||
#if defined(__APPLE_COCOA__)
|
||||
static unsigned fl_cmap[256] = {
|
||||
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
|
||||
};
|
||||
CGColorRef flcolortocgcolor(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;
|
||||
}
|
||||
CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.};
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
return CGColorCreate(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), components);
|
||||
#else
|
||||
return CGColorCreate(CGColorSpaceCreateWithName(kCGColorSpaceUserRGB), components);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void fl_draw(const char *str, int n, float x, float y) {
|
||||
OSStatus err;
|
||||
// convert to UTF-16 first
|
||||
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
|
||||
|
||||
// avoid a crash if no font has been selected by user yet !
|
||||
check_default_font();
|
||||
// convert to UTF-16 first
|
||||
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
if(CTFontCreateWithName != NULL) {
|
||||
CFStringRef keys[2];
|
||||
CFTypeRef values[2];
|
||||
CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)uniStr, n * sizeof(UniChar), kCFStringEncodingUTF16, false);
|
||||
CGColorRef color = flcolortocgcolor(fl_color());
|
||||
keys[0] = kCTFontAttributeName;
|
||||
keys[1] = kCTForegroundColorAttributeName;
|
||||
values[0] = fl_fontsize->fontref;
|
||||
values[1] = color;
|
||||
CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void**)&keys,
|
||||
(const void**)&values,
|
||||
2,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes);
|
||||
CFRelease(str16);
|
||||
CFRelease(attributes);
|
||||
CFRelease(color);
|
||||
CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
|
||||
CFRelease(mastr);
|
||||
CGContextSetTextMatrix(fl_gc, font_mx);
|
||||
CGContextSetTextPosition(fl_gc, x, y);
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
CTLineDraw(ctline, fl_gc);
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
CFRelease(ctline);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if ! __LP64__
|
||||
OSStatus err;
|
||||
// now collect our ATSU resources
|
||||
ATSUTextLayout layout = fl_fontsize->layout;
|
||||
|
||||
@@ -336,12 +485,29 @@ void fl_draw(const char *str, int n, float x, float y) {
|
||||
ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
|
||||
|
||||
err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
|
||||
#if defined(__APPLE_COCOA__)
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y));
|
||||
#if defined(__APPLE_COCOA__)
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void fl_draw(int angle, const char *str, int n, int x, int y) {
|
||||
#if defined(__APPLE_COCOA__)
|
||||
CGContextSaveGState(fl_gc);
|
||||
CGContextTranslateCTM(fl_gc, x, y);
|
||||
CGContextRotateCTM(fl_gc, - angle*(M_PI/180) );
|
||||
fl_draw(str, n, (float)0., (float)0.);
|
||||
CGContextRestoreGState(fl_gc);
|
||||
#else
|
||||
OSStatus err;
|
||||
// convert to UTF-16 first
|
||||
// convert to UTF-16 first
|
||||
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
|
||||
|
||||
// avoid a crash if no font has been selected by user yet !
|
||||
@@ -360,10 +526,14 @@ void fl_draw(int angle, const char *str, int n, int x, int y) {
|
||||
//restore layout baseline
|
||||
ang = IntToFixed(0);
|
||||
ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void fl_rtl_draw(const char* c, int n, int x, int y) {
|
||||
// I guess with ATSU the thing to do is force the layout mode to RTL and let ATSU draw the text...
|
||||
#if defined(__APPLE_COCOA__)
|
||||
fl_draw(c, n, x - fl_width(c, n), y); //to check;
|
||||
#else
|
||||
// I guess with ATSU the thing to do is force the layout mode to RTL and let ATSU draw the text...
|
||||
double offs = fl_width(c, n);
|
||||
OSStatus err;
|
||||
// convert to UTF-16 first
|
||||
@@ -379,6 +549,7 @@ void fl_rtl_draw(const char* c, int n, int x, int y) {
|
||||
|
||||
err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
|
||||
err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x-offs), FloatToFixed(y));
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
float fl_quartz_line_width_ = 1.0f;
|
||||
static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt;
|
||||
static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter;
|
||||
static float *fl_quartz_line_pattern = 0;
|
||||
static CGFloat *fl_quartz_line_pattern = 0;
|
||||
static int fl_quartz_line_pattern_size = 0;
|
||||
void fl_quartz_restore_line_style_() {
|
||||
CGContextSetLineWidth(fl_gc, fl_quartz_line_width_);
|
||||
@@ -145,9 +145,9 @@ void fl_line_style(int style, int width, char* dashes) {
|
||||
fl_quartz_line_cap_ = Cap[(style>>8)&3];
|
||||
fl_quartz_line_join_ = Join[(style>>12)&3];
|
||||
char *d = dashes;
|
||||
static float pattern[16];
|
||||
static CGFloat pattern[16];
|
||||
if (d && *d) {
|
||||
float *p = pattern;
|
||||
CGFloat *p = pattern;
|
||||
while (*d) { *p++ = (float)*d++; }
|
||||
fl_quartz_line_pattern = pattern;
|
||||
fl_quartz_line_pattern_size = d-dashes;
|
||||
@@ -162,7 +162,7 @@ void fl_line_style(int style, int width, char* dashes) {
|
||||
dash = char(3*width);
|
||||
dot = gap = char(width);
|
||||
}
|
||||
float *p = pattern;
|
||||
CGFloat *p = pattern;
|
||||
switch (style & 0xff) {
|
||||
case FL_DASH: *p++ = dash; *p++ = gap; break;
|
||||
case FL_DOT: *p++ = dot; *p++ = gap; break;
|
||||
@@ -172,7 +172,8 @@ void fl_line_style(int style, int width, char* dashes) {
|
||||
fl_quartz_line_pattern_size = p-pattern;
|
||||
fl_quartz_line_pattern = pattern;
|
||||
} else {
|
||||
fl_quartz_line_pattern = 0; fl_quartz_line_pattern_size = 0;
|
||||
fl_quartz_line_pattern = 0;
|
||||
fl_quartz_line_pattern_size = 0;
|
||||
}
|
||||
fl_quartz_restore_line_style_();
|
||||
#else
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
//
|
||||
|
||||
#include <config.h>
|
||||
|
||||
// warning: this function is only implemented in Quickdraw. The function
|
||||
// below may not work If FLTK is compiled with Quartz enabled
|
||||
#ifdef __APPLE_COCOA__
|
||||
extern unsigned char *MACbitmapFromRectOfWindow(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
|
||||
#endif
|
||||
|
||||
//
|
||||
// 'fl_read_image()' - Read an image from the current window.
|
||||
@@ -41,6 +41,29 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
||||
int w, // I - Width of area to read
|
||||
int h, // I - Height of area to read
|
||||
int alpha) { // I - Alpha value for image (0 for none)
|
||||
#if defined(__APPLE_COCOA__)
|
||||
Fl_Window *window = Fl_Window::current();
|
||||
while(window->window()) window = window->window();
|
||||
int delta;
|
||||
uchar *base = MACbitmapFromRectOfWindow(window,x,y,w,h,&delta);
|
||||
int rowBytes = delta*w;
|
||||
// Allocate the image data array as needed...
|
||||
int d = alpha ? 4 : 3;
|
||||
if (!p) p = new uchar[w * h * d];
|
||||
// Initialize the default colors/alpha in the whole image...
|
||||
memset(p, alpha, w * h * d);
|
||||
// Copy the image from the off-screen buffer to the memory buffer.
|
||||
int idx, idy; // Current X & Y in image
|
||||
uchar *pdst, *psrc;
|
||||
for (idy = 0, pdst = p; idy < h; idy ++) {
|
||||
for (idx = 0, psrc = base + idy * rowBytes; idx < w; idx ++, psrc += delta, pdst += d) {
|
||||
/*R*/ pdst[0] = psrc[0];
|
||||
/*G*/ pdst[1] = psrc[1];
|
||||
/*B*/ pdst[2] = psrc[2];
|
||||
}
|
||||
}
|
||||
delete base;
|
||||
#else
|
||||
Rect src, // Source rectangle
|
||||
dst; // Destination rectangle
|
||||
GWorldPtr osbuffer; // Temporary off-screen buffer for copy
|
||||
@@ -128,7 +151,8 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
|
||||
DisposeGWorld(osbuffer);
|
||||
|
||||
SetPort(srcPort);
|
||||
return p;
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,10 +59,18 @@ void fl_rect(int x, int y, int w, int h) {
|
||||
LineTo(fl_gc, x, y+h-1);
|
||||
LineTo(fl_gc, x, y);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGRect rect = CGRectMake(x, y, w-1, h-1);
|
||||
CGContextStrokeRect(fl_gc, rect);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -81,10 +89,18 @@ void fl_rectf(int x, int y, int w, int h) {
|
||||
rect.right = x + w; rect.bottom = y + h;
|
||||
FillRect(fl_gc, &rect, fl_brush());
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGRect rect = CGRectMake(x, y, w-1, h-1);
|
||||
CGContextFillRect(fl_gc, rect);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -99,11 +115,19 @@ void fl_xyline(int x, int y, int x1) {
|
||||
#elif defined(WIN32)
|
||||
MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -125,12 +149,20 @@ void fl_xyline(int x, int y, int x1, int y2) {
|
||||
LineTo(fl_gc, x1, y);
|
||||
LineTo(fl_gc, x1, y2);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y2);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
@@ -155,13 +187,21 @@ void fl_xyline(int x, int y, int x1, int y2, int x3) {
|
||||
LineTo(fl_gc, x1, y2);
|
||||
LineTo(fl_gc, x3, y2);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y2);
|
||||
CGContextAddLineToPoint(fl_gc, x3, y2);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -178,11 +218,19 @@ void fl_yxline(int x, int y, int y1) {
|
||||
else y1++;
|
||||
MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x, y1);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -204,12 +252,20 @@ void fl_yxline(int x, int y, int y1, int x2) {
|
||||
LineTo(fl_gc, x, y1);
|
||||
LineTo(fl_gc, x2, y1);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y1);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -234,13 +290,21 @@ void fl_yxline(int x, int y, int y1, int x2, int y3) {
|
||||
LineTo(fl_gc, x2, y1);
|
||||
LineTo(fl_gc, x2, y3);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y3);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -259,11 +323,19 @@ void fl_line(int x, int y, int x1, int y1) {
|
||||
// functions will not draw the last point ("it's a feature!"...)
|
||||
SetPixel(fl_gc, x1, y1, fl_RGB());
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y1);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -287,12 +359,20 @@ void fl_line(int x, int y, int x1, int y1, int x2, int y2) {
|
||||
// functions will not draw the last point ("it's a feature!"...)
|
||||
SetPixel(fl_gc, x2, y2, fl_RGB());
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y2);
|
||||
CGContextStrokePath(fl_gc);
|
||||
if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -315,11 +395,17 @@ void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {
|
||||
LineTo(fl_gc, x2, y2);
|
||||
LineTo(fl_gc, x, y);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y2);
|
||||
CGContextClosePath(fl_gc);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -344,12 +430,18 @@ void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
LineTo(fl_gc, x3, y3);
|
||||
LineTo(fl_gc, x, y);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y2);
|
||||
CGContextAddLineToPoint(fl_gc, x3, y3);
|
||||
CGContextClosePath(fl_gc);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -371,11 +463,17 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {
|
||||
SelectObject(fl_gc, fl_brush());
|
||||
Polygon(fl_gc, p, 3);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y2);
|
||||
CGContextClosePath(fl_gc);
|
||||
CGContextFillPath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -398,12 +496,18 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
SelectObject(fl_gc, fl_brush());
|
||||
Polygon(fl_gc, p, 4);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x, y);
|
||||
CGContextAddLineToPoint(fl_gc, x1, y1);
|
||||
CGContextAddLineToPoint(fl_gc, x2, y2);
|
||||
CGContextAddLineToPoint(fl_gc, x3, y3);
|
||||
CGContextClosePath(fl_gc);
|
||||
CGContextFillPath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -418,11 +522,19 @@ void fl_point(int x, int y) {
|
||||
#elif defined(WIN32)
|
||||
SetPixel(fl_gc, x, y, fl_RGB());
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, x-.5, y); // Quartz needs a line that is one pixel long, or it will not draw anything
|
||||
CGContextAddLineToPoint(fl_gc, x+.5, y);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -467,7 +579,17 @@ void fl_restore_clip() {
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if ( fl_window ) // clipping for a true window
|
||||
{
|
||||
GrafPtr port = GetWindowPort( fl_window );
|
||||
#ifdef __APPLE_COCOA__
|
||||
Fl_X::q_clear_clipping();
|
||||
Fl_X::q_fill_context();//flip coords and translate if subwindow
|
||||
//apply window's clip
|
||||
CGContextClipToRects(fl_gc, fl_window_region->rects, fl_window_region->count );
|
||||
//apply additional program clip
|
||||
if(r) {
|
||||
CGContextClipToRects(fl_gc, r->rects, r->count);
|
||||
}
|
||||
#else
|
||||
GrafPtr port = GetWindowPort( fl_window );
|
||||
if ( port ) {
|
||||
RgnHandle portClip = NewRgn();
|
||||
CopyRgn( fl_window_region, portClip ); // changed
|
||||
@@ -479,16 +601,22 @@ void fl_restore_clip() {
|
||||
Fl_X::q_fill_context();
|
||||
DisposeRgn( portClip );
|
||||
}
|
||||
#endif
|
||||
} else if (fl_gc) { // clipping for an offscreen drawing world (CGBitmap)
|
||||
Rect portRect;
|
||||
portRect.top = 0;
|
||||
portRect.left = 0;
|
||||
portRect.bottom = CGBitmapContextGetHeight(fl_gc);
|
||||
portRect.right = CGBitmapContextGetWidth(fl_gc);
|
||||
Fl_X::q_clear_clipping();
|
||||
if (r)
|
||||
ClipCGContextToRegion(fl_gc, &portRect, r);
|
||||
Fl_X::q_fill_context();
|
||||
Rect portRect;
|
||||
portRect.top = 0;
|
||||
portRect.left = 0;
|
||||
portRect.bottom = CGBitmapContextGetHeight(fl_gc);
|
||||
portRect.right = CGBitmapContextGetWidth(fl_gc);
|
||||
Fl_X::q_clear_clipping();
|
||||
if (r) {
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextClipToRects(fl_gc, r->rects, r->count);
|
||||
#else
|
||||
ClipCGContextToRegion(fl_gc, &portRect, r);
|
||||
#endif
|
||||
}
|
||||
Fl_X::q_fill_context();
|
||||
}
|
||||
#else
|
||||
# error unsupported platform
|
||||
@@ -534,19 +662,33 @@ void fl_push_clip(int x, int y, int w, int h) {
|
||||
#elif defined(WIN32)
|
||||
CombineRgn(r,r,current,RGN_AND);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
SectRgn(r, current, r);
|
||||
#ifdef __APPLE_COCOA__
|
||||
XDestroyRegion(r);
|
||||
r = MacRectRegionIntersect(current, x,y,w,h);
|
||||
#else
|
||||
SectRgn(r, current, r);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
}
|
||||
#if defined(__APPLE_QUARTZ__)
|
||||
else {
|
||||
r = XRectangleRegion(x,y,w,h);
|
||||
}
|
||||
#endif
|
||||
} else { // make empty clip region:
|
||||
#if defined(USE_X11)
|
||||
r = XCreateRegion();
|
||||
#elif defined(WIN32)
|
||||
r = CreateRectRgn(0,0,0,0);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
r = NewRgn();
|
||||
SetEmptyRgn(r);
|
||||
#ifdef __APPLE_COCOA__
|
||||
r = NULL;
|
||||
#else
|
||||
r = NewRgn();
|
||||
SetEmptyRgn(r);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -604,9 +746,18 @@ int fl_not_clipped(int x, int y, int w, int h) {
|
||||
return RectInRegion(r,&rect);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (!r) return 1;
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGRect arg = CGRectMake(x,y,w - 1,h - 1);
|
||||
for(int i = 0; i < r->count; i++) {
|
||||
CGRect test = CGRectIntersection(r->rects[i], arg);
|
||||
if( ! CGRectIsEmpty(test)) return 1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
Rect rect;
|
||||
rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
|
||||
return RectInRgn(&rect, r);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -673,6 +824,24 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
|
||||
DeleteObject(rr);
|
||||
return ret;
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGRect arg = CGRectMake(x,y,w - 1,h - 1);
|
||||
CGRect u = CGRectMake(0,0,0,0);
|
||||
CGRect test;
|
||||
for(int i = 0; i < r->count; i++) {
|
||||
test = CGRectIntersection(r->rects[i], arg);
|
||||
if( ! CGRectIsEmpty(test) ) {
|
||||
if(CGRectIsEmpty(u)) u = test;
|
||||
else u = CGRectUnion(u, test);
|
||||
}
|
||||
}
|
||||
X = u.origin.x;
|
||||
Y = u.origin.y;
|
||||
W = u.size.width;
|
||||
H = u.size.height;
|
||||
if(CGRectIsEmpty(u)) W = H = 0;
|
||||
return ! CGRectEqualToRect(arg, u);
|
||||
#else
|
||||
RgnHandle rr = NewRgn();
|
||||
SetRectRgn( rr, x, y, x+w, y+h );
|
||||
SectRgn( r, rr, rr );
|
||||
@@ -685,6 +854,7 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
|
||||
if ( H==0 ) return 2;
|
||||
if ( h==H && w==W ) return 0;
|
||||
return 0;
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
@@ -151,6 +151,16 @@ 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);
|
||||
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
|
||||
#if defined(__APPLE_COCOA__)
|
||||
extern CGImageRef MAC_CGImageFromRectOfWindow(Fl_Window*, int x, int y, int w, int h);
|
||||
CGImageRef img = MAC_CGImageFromRectOfWindow(Fl_Window::current(), src_x, src_y, src_w, src_h);
|
||||
CGRect rect = { { dest_x, dest_y }, { src_w, src_h } };
|
||||
Fl_X::q_begin_image(rect, 0, 0, src_w, src_h);
|
||||
CGContextDrawImage(fl_gc, rect, img);
|
||||
Fl_X::q_end_image();
|
||||
CFRelease(img);
|
||||
#else
|
||||
// warning: there does not seem to be an equivalent to this function in Quartz
|
||||
// ScrollWindowRect is a QuickDraw function and won't work here.
|
||||
// Since on OS X all windows are fully double buffered, we need not
|
||||
@@ -161,6 +171,8 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
|
||||
static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg );
|
||||
CopyBits( GetPortBitMapForCopyBits( GetWindowPort(fl_window) ),
|
||||
GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), &src, &dst, srcCopy, 0L);
|
||||
#endif
|
||||
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
@@ -60,6 +60,33 @@ static int fl_free_font = FL_FREE_FONT;
|
||||
|
||||
Fl_Font Fl::set_fonts(const char* xstarname) {
|
||||
#pragma unused ( xstarname )
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
if(CTFontCreateWithFontDescriptor != NULL) {
|
||||
int value[1] = {1};
|
||||
CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)kCTFontCollectionRemoveDuplicatesOption,
|
||||
(const void **)&value, 1, NULL, NULL);
|
||||
CTFontCollectionRef fcref = CTFontCollectionCreateFromAvailableFonts(dict);
|
||||
CFRelease(dict);
|
||||
CFArrayRef arrayref = CTFontCollectionCreateMatchingFontDescriptors(fcref);
|
||||
CFRelease(fcref);
|
||||
CFIndex count = CFArrayGetCount(arrayref);
|
||||
CFIndex i;
|
||||
for (i = 0; i < count; i++) {
|
||||
CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i);
|
||||
CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL);
|
||||
CFStringRef cfname = CTFontCopyPostScriptName(font);
|
||||
CFRelease(font);
|
||||
static char fname[100];
|
||||
CFStringGetCString(cfname, fname, sizeof(fname), kCFStringEncodingUTF8);
|
||||
CFRelease(cfname);
|
||||
Fl::set_font((Fl_Font)(fl_free_font++), strdup(fname));
|
||||
}
|
||||
CFRelease(arrayref);
|
||||
return (Fl_Font)fl_free_font;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if ! __LP64__
|
||||
#if defined(OLD__APPLE_QUARTZ__)
|
||||
ATSFontIterator it;
|
||||
ATSFontIteratorCreate(kATSFontContextGlobal, 0L, 0L, kATSOptionFlagsUnRestrictedScope, &it);
|
||||
@@ -114,6 +141,10 @@ Fl_Font Fl::set_fonts(const char* xstarname) {
|
||||
}
|
||||
free(oFontIDs);
|
||||
return (Fl_Font)fl_free_font;
|
||||
#endif //OLD__APPLE_QUARTZ__
|
||||
#endif //__LP64__
|
||||
#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@
|
||||
be confused with
|
||||
Fl_Widget::test_shortcut().
|
||||
*/
|
||||
int Fl::test_shortcut(Fl_Shortcut shortcut) {
|
||||
int Fl::test_shortcut(unsigned int shortcut) {
|
||||
if (!shortcut) return 0;
|
||||
|
||||
Fl_Char v = shortcut & FL_KEY_MASK;
|
||||
unsigned int v = shortcut & FL_KEY_MASK;
|
||||
if (fl_tolower(v)!=v) {
|
||||
shortcut |= FL_SHIFT;
|
||||
}
|
||||
@@ -74,13 +74,13 @@ int Fl::test_shortcut(Fl_Shortcut shortcut) {
|
||||
// these three must always be correct:
|
||||
if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0;
|
||||
|
||||
Fl_Char key = shortcut & FL_KEY_MASK;
|
||||
unsigned int key = shortcut & FL_KEY_MASK;
|
||||
|
||||
// if shift is also correct, check for exactly equal keysyms:
|
||||
if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1;
|
||||
|
||||
// try matching utf8, ignore shift:
|
||||
Fl_Char firstChar = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0);
|
||||
unsigned int firstChar = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0);
|
||||
if (key==firstChar) return 1;
|
||||
|
||||
// kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'):
|
||||
@@ -174,7 +174,7 @@ static Keyname table[] = {
|
||||
\param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers
|
||||
\return a pointer to a static buffer containing human readable text for the shortcut
|
||||
*/
|
||||
const char* fl_shortcut_label(Fl_Shortcut shortcut) {
|
||||
const char* fl_shortcut_label(unsigned int shortcut) {
|
||||
return fl_shortcut_label(shortcut, 0L);
|
||||
}
|
||||
|
||||
@@ -184,15 +184,15 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut) {
|
||||
\param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers
|
||||
\param [in] eom if this pointer is set, it will receive a pointer to the end of the modifier text
|
||||
\return a pointer to a static buffer containing human readable text for the shortcut
|
||||
\see fl_shortcut_label(Fl_Shortcut shortcut)
|
||||
\see fl_shortcut_label(unsigned int shortcut)
|
||||
*/
|
||||
const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) {
|
||||
const char* fl_shortcut_label(unsigned int shortcut, const char **eom) {
|
||||
static char buf[20];
|
||||
char *p = buf;
|
||||
if (eom) *eom = p;
|
||||
if (!shortcut) {*p = 0; return buf;}
|
||||
// fix upper case shortcuts
|
||||
Fl_Char v = shortcut & FL_KEY_MASK;
|
||||
unsigned int v = shortcut & FL_KEY_MASK;
|
||||
if (fl_tolower(v)!=v) {
|
||||
shortcut |= FL_SHIFT;
|
||||
}
|
||||
@@ -200,7 +200,7 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) {
|
||||
// this column contains utf8 characters - v
|
||||
if (shortcut & FL_SHIFT) {strcpy(p,"\xe2\x87\xa7"); p += 3;} // ⇧ upwards white arrow
|
||||
if (shortcut & FL_CTRL) {strcpy(p,"\xe2\x8c\x83"); p += 3;} // ⌃ up arrowhead
|
||||
if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8e\x87"); p += 3;} // ⎇ alternative key symbol
|
||||
if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8c\xa5"); p += 3;} // ⌥ alternative key symbol
|
||||
if (shortcut & FL_META) {strcpy(p,"\xe2\x8c\x98"); p += 3;} // ⌘ place of interest sign
|
||||
#else
|
||||
if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;}
|
||||
@@ -209,7 +209,7 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) {
|
||||
if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;}
|
||||
#endif // __APPLE__
|
||||
if (eom) *eom = p;
|
||||
Fl_Char key = shortcut & FL_KEY_MASK;
|
||||
unsigned int key = shortcut & FL_KEY_MASK;
|
||||
#if defined(WIN32) || defined(__APPLE__) // if not X
|
||||
if (key >= FL_F && key <= FL_F_Last) {
|
||||
*p++ = 'F';
|
||||
@@ -270,9 +270,9 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) {
|
||||
/**
|
||||
Emulation of XForms named shortcuts.
|
||||
*/
|
||||
Fl_Shortcut fl_old_shortcut(const char* s) {
|
||||
unsigned int fl_old_shortcut(const char* s) {
|
||||
if (!s || !*s) return 0;
|
||||
Fl_Shortcut n = 0;
|
||||
unsigned int n = 0;
|
||||
if (*s == '#') {n |= FL_ALT; s++;}
|
||||
if (*s == '+') {n |= FL_SHIFT; s++;}
|
||||
if (*s == '^') {n |= FL_CTRL; s++;}
|
||||
@@ -282,14 +282,14 @@ Fl_Shortcut fl_old_shortcut(const char* s) {
|
||||
|
||||
// Tests for &x shortcuts in button labels:
|
||||
|
||||
Fl_Shortcut Fl_Widget::label_shortcut(const char *t) {
|
||||
unsigned int Fl_Widget::label_shortcut(const char *t) {
|
||||
if (!t) return 0;
|
||||
for (;;) {
|
||||
if (*t==0) return 0;
|
||||
if (*t=='&') {
|
||||
Fl_Shortcut s = fl_utf8decode(t+1, 0, 0);
|
||||
unsigned int s = fl_utf8decode(t+1, 0, 0);
|
||||
if (s==0) return 0;
|
||||
else if (s==(Fl_Char)'&') t++;
|
||||
else if (s==(unsigned int)'&') t++;
|
||||
else return s;
|
||||
}
|
||||
t++;
|
||||
@@ -302,7 +302,7 @@ int Fl_Widget::test_shortcut(const char *t) {
|
||||
if (Fl::event_state(FL_ALT)==0) return 0;
|
||||
#endif
|
||||
if (!t) return 0;
|
||||
Fl_Shortcut c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0);
|
||||
unsigned int c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0);
|
||||
if (!c) return 0;
|
||||
if (c == label_shortcut(t))
|
||||
return 1;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
\c NULL, only the length of the utf-8 sequence is calculated
|
||||
\return length of the sequence in bytes
|
||||
*/
|
||||
/* FL_EXPORT int fl_unichar_to_utf8(Fl_Char uc, char *text); */
|
||||
/* FL_EXPORT int fl_unichar_to_utf8(unsigned int uc, char *text); */
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
\param[in] uc Unicode character
|
||||
\return length of the sequence in bytes
|
||||
*/
|
||||
/* FL_EXPORT int fl_utf8_size(Fl_Char uc); */
|
||||
/* FL_EXPORT int fl_utf8_size(unsigned int uc); */
|
||||
|
||||
/** @} */
|
||||
#endif /* 0 */
|
||||
|
||||
@@ -229,13 +229,21 @@ void fl_end_points() {
|
||||
#elif defined(WIN32)
|
||||
for (int i=0; i<n; i++) SetPixel(fl_gc, p[i].x, p[i].y, fl_RGB());
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
for (int i=0; i<n; i++) {
|
||||
CGContextMoveToPoint(fl_gc, p[i].x, p[i].y);
|
||||
CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
|
||||
CGContextStrokePath(fl_gc);
|
||||
}
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#ifdef __APPLE_COCOA__
|
||||
if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
|
||||
#else
|
||||
if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -255,10 +263,16 @@ void fl_end_line() {
|
||||
if (n>1) Polyline(fl_gc, p, n);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (n<=1) return;
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, p[0].x, p[0].y);
|
||||
for (int i=1; i<n; i++)
|
||||
CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
|
||||
CGContextStrokePath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -295,11 +309,17 @@ void fl_end_polygon() {
|
||||
}
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (n<=1) return;
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, p[0].x, p[0].y);
|
||||
for (int i=1; i<n; i++)
|
||||
CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
|
||||
CGContextClosePath(fl_gc);
|
||||
CGContextFillPath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -370,11 +390,17 @@ void fl_end_complex_polygon() {
|
||||
}
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
if (n<=1) return;
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextMoveToPoint(fl_gc, p[0].x, p[0].y);
|
||||
for (int i=1; i<n; i++)
|
||||
CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y);
|
||||
CGContextClosePath(fl_gc);
|
||||
CGContextFillPath(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
@@ -412,8 +438,15 @@ void fl_circle(double x, double y,double r) {
|
||||
Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0);
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
// Quartz warning : circle won't scale to current matrix!
|
||||
CGContextAddArc(fl_gc, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 1);
|
||||
//last argument must be 0 (counterclockwise) or it draws nothing under __LP64__ !!!!
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, true);
|
||||
#endif
|
||||
CGContextAddArc(fl_gc, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 0);
|
||||
(what == POLYGON ? CGContextFillPath : CGContextStrokePath)(fl_gc);
|
||||
#ifdef __APPLE_COCOA__
|
||||
CGContextSetShouldAntialias(fl_gc, false);
|
||||
#endif
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
@@ -107,7 +107,11 @@ static void screen_init() {
|
||||
#elif defined(__APPLE__)
|
||||
XRectangle screens[16];
|
||||
|
||||
extern int MACscreen_init(XRectangle screens[]);
|
||||
static void screen_init() {
|
||||
#ifdef __APPLE_COCOA__
|
||||
num_screens = MACscreen_init(screens);
|
||||
#else
|
||||
GDHandle gd;
|
||||
|
||||
for (gd = GetDeviceList(), num_screens = 0; gd; gd = GetNextDevice(gd)) {
|
||||
@@ -120,6 +124,7 @@ static void screen_init() {
|
||||
num_screens ++;
|
||||
if (num_screens >= 16) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#elif HAVE_XINERAMA
|
||||
# include <X11/extensions/Xinerama.h>
|
||||
|
||||
Reference in New Issue
Block a user