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:
Tobias Doerffel
2009-12-13 22:29:54 +01:00
parent de09a96b4b
commit d46762a7be
35 changed files with 1233 additions and 324 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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*);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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];

View File

@@ -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) {
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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--);
}
}

View File

@@ -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

View File

@@ -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++;

View File

@@ -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 =

View File

@@ -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);

View File

@@ -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:

View File

@@ -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

View File

@@ -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;

View File

@@ -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:

View File

@@ -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__
}

View File

@@ -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
}
//

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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

View File

@@ -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>