Add method to set any custom cursor, based on a Fl_RGB_Image object.

Also change our fallback cursors to use this method, so that fallback
cursors are handled in a platform independent manner. STR #2660.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10196 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Pierre Ossman 2014-06-16 11:17:57 +00:00
parent b4013ef602
commit 332dc1b7ac
22 changed files with 778 additions and 402 deletions

View File

@ -345,6 +345,20 @@ else()
set(FLTK_XFIXES_FOUND FALSE)
endif(OPTION_USE_XFIXES)
#######################################################################
if(X11_Xcursor_FOUND)
option(OPTION_USE_XCURSOR "use lib XCURSOR" ON)
endif(X11_Xcursor_FOUND)
if(OPTION_USE_XCURSOR)
set(HAVE_XCURSOR ${X11_Xcursor_FOUND})
include_directories(${X11_Xcursor_INCLUDE_PATH})
list(APPEND FLTK_LDLIBS -lXcursor)
set(FLTK_XCURSOR_FOUND TRUE)
else()
set(FLTK_XCURSOR_FOUND FALSE)
endif(OPTION_USE_XCURSOR)
#######################################################################
if(X11_Xft_FOUND)
option(OPTION_USE_XFT "use lib Xft" ON)

View File

@ -901,35 +901,37 @@ inline Fl_Color fl_color_cube(int r, int g, int b) {
/** The following constants define the mouse cursors that are available in FLTK.
The double-headed arrows are bitmaps provided by FLTK on X, the others
are provided by system-defined cursors.
Cursors are provided by the system when available, or bitmaps built into
FLTK as a fallback.
\todo enum Fl_Cursor needs maybe an image.
*/
/* FIXME: We should renumber these, but that will break the ABI */
enum Fl_Cursor {
FL_CURSOR_DEFAULT = 0, /**< the default cursor, usually an arrow. */
FL_CURSOR_ARROW = 35, /**< an arrow pointer. */
FL_CURSOR_CROSS = 66, /**< crosshair. */
FL_CURSOR_WAIT = 76, /**< watch or hourglass. */
FL_CURSOR_INSERT = 77, /**< I-beam. */
FL_CURSOR_HAND = 31, /**< hand (uparrow on MSWindows). */
FL_CURSOR_HELP = 47, /**< question mark. */
FL_CURSOR_MOVE = 27, /**< 4-pointed arrow. */
// fltk provides bitmaps for these:
FL_CURSOR_NS = 78, /**< up/down arrow. */
FL_CURSOR_WE = 79, /**< left/right arrow. */
FL_CURSOR_NWSE = 80, /**< diagonal arrow. */
FL_CURSOR_NESW = 81, /**< diagonal arrow. */
FL_CURSOR_NONE =255, /**< invisible. */
// for back compatibility (non MSWindows ones):
FL_CURSOR_N = 70, /**< for back compatibility. */
FL_CURSOR_NE = 69, /**< for back compatibility. */
FL_CURSOR_E = 49, /**< for back compatibility. */
FL_CURSOR_SE = 8, /**< for back compatibility. */
FL_CURSOR_S = 9, /**< for back compatibility. */
FL_CURSOR_SW = 7, /**< for back compatibility. */
FL_CURSOR_W = 36, /**< for back compatibility. */
FL_CURSOR_NW = 68 /**< for back compatibility. */
FL_CURSOR_DEFAULT = 0, /**< the default cursor, usually an arrow. */
FL_CURSOR_ARROW = 35, /**< an arrow pointer. */
FL_CURSOR_CROSS = 66, /**< crosshair. */
FL_CURSOR_WAIT = 76, /**< busy indicator (e.g. hourglass). */
FL_CURSOR_INSERT = 77, /**< I-beam. */
FL_CURSOR_HAND = 31, /**< pointing hand. */
FL_CURSOR_HELP = 47, /**< question mark pointer. */
FL_CURSOR_MOVE = 27, /**< 4-pointed arrow or hand. */
/* Resize indicators */
FL_CURSOR_NS = 78, /**< up/down resize. */
FL_CURSOR_WE = 79, /**< left/right resize. */
FL_CURSOR_NWSE = 80, /**< diagonal resize. */
FL_CURSOR_NESW = 81, /**< diagonal resize. */
FL_CURSOR_N = 70, /**< upwards resize. */
FL_CURSOR_NE = 69, /**< upwards, right resize. */
FL_CURSOR_E = 49, /**< rightwards resize. */
FL_CURSOR_SE = 8, /**< downwards, right resize. */
FL_CURSOR_S = 9, /**< downwards resize. */
FL_CURSOR_SW = 7, /**< downwards, left resize. */
FL_CURSOR_W = 36, /**< leftwards resize. */
FL_CURSOR_NW = 68, /**< upwards, left resize. */
FL_CURSOR_NONE =255, /**< invisible. */
};
/*@}*/ // group: Cursors

View File

@ -28,6 +28,7 @@
#define FL_DOUBLE_WINDOW 0xF1 ///< double window type id
class Fl_X;
class Fl_RGB_Image;
/**
This widget produces an actual window. This can either be a main
@ -97,7 +98,10 @@ class FL_EXPORT Fl_Window : public Fl_Group {
uchar size_range_set;
// cursor stuff
Fl_Cursor cursor_default;
#if FLTK_ABI_VERSION < 10303
// legacy, not used
Fl_Color cursor_fg, cursor_bg;
#endif
void size_range_();
void _Fl_Window(); // constructor innards
void fullscreen_x(); // platform-specific part of sending a window to full screen
@ -495,14 +499,17 @@ public:
is different.
The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
(Under X you can get any XC_cursor value by passing
Fl_Cursor((XC_foo/2)+1)). The colors only work on X, they are
not implemented on WIN32.
For back compatibility only.
\see cursor(const Fl_RGB_Image*, int, int), default_cursor()
*/
void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); // platform dependent
void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
void cursor(Fl_Cursor);
void cursor(const Fl_RGB_Image*, int, int);
void default_cursor(Fl_Cursor);
/* for legacy compatibility */
void cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE);
void default_cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE);
static void default_callback(Fl_Window*, void* v);
/** Returns the window width including any frame added by the window manager.

View File

@ -769,7 +769,8 @@ FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut, const char **eom)
FL_EXPORT unsigned int fl_old_shortcut(const char* s);
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);
FL_EXPORT void fl_cursor(Fl_Cursor);
FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg, Fl_Color bg=FL_WHITE);
FL_EXPORT const char* fl_expand_text(const char* from, char* buf, int maxbuf,
double maxw, int& n, double &width,
int wrap, int draw_symbols = 0);

View File

@ -142,7 +142,8 @@ public:
void collapse(void);
WindowRef window_ref(void);
void set_key_window(void);
void set_cursor(Fl_Cursor);
int set_cursor(Fl_Cursor);
int set_cursor(const Fl_RGB_Image*, int, int);
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
static unsigned char *bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
static CFDataRef CGBitmapContextToTIFF(CGContextRef c);

View File

@ -73,6 +73,7 @@ public:
int wait_for_expose;
HDC private_dc; // used for OpenGL
HCURSOR cursor;
int custom_cursor;
HDC saved_hdc; // saves the handle of the DC currently loaded
// static variables, static functions and member functions
static Fl_X* first;
@ -84,6 +85,8 @@ public:
void flush() {w->flush();}
void set_minmax(LPMINMAXINFO minmax);
void mapraise();
int set_cursor(Fl_Cursor);
int set_cursor(const Fl_RGB_Image*, int, int);
static Fl_X* make(Fl_Window*);
};
extern FL_EXPORT HCURSOR fl_default_cursor;

2
FL/x.H
View File

@ -150,6 +150,8 @@ public:
static Fl_X* i(const Fl_Window* wi) {return wi->i;}
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
void sendxjunk();
int set_cursor(Fl_Cursor);
int set_cursor(const Fl_RGB_Image*, int, int);
static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
static Fl_X* set_xid(Fl_Window*, Window);
// kludges to get around protection:

View File

@ -115,6 +115,14 @@
#cmakedefine01 HAVE_XFIXES
/*
* HAVE_XCURSOR:
*
* Do we have the X cursor library?
*/
#cmakedefine01 HAVE_XCURSOR
/*
* __APPLE_QUARTZ__:
*

View File

@ -115,6 +115,14 @@
#define HAVE_XFIXES 0
/*
* HAVE_XCURSOR:
*
* Do we have the X cursor library?
*/
#define HAVE_XCURSOR 0
/*
* __APPLE_QUARTZ__:
*

View File

@ -975,6 +975,16 @@ case $host_os_gui in
LIBS="-lXfixes $LIBS")
fi
dnl Check for the Xcursor library unless disabled...
AC_ARG_ENABLE(xcursor, [ --enable-xcursor turn on Xcursor support [default=yes]])
if test x$enable_xcursor != xno; then
AC_CHECK_HEADER(X11/Xcursor/Xcursor.h, AC_DEFINE(HAVE_XCURSOR),,
[#include <X11/Xlib.h>])
AC_CHECK_LIB(Xcursor, XcursorImageCreate,
LIBS="-lXcursor $LIBS")
fi
dnl Check for overlay visuals...
AC_PATH_PROG(XPROP, xprop)
AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay,

View File

@ -247,6 +247,10 @@ if(HAVE_XFIXES)
target_link_libraries(fltk ${X11_Xfixes_LIB})
endif(HAVE_XFIXES)
if(HAVE_XCURSOR)
target_link_libraries(fltk ${X11_Xcursor_LIB})
endif(HAVE_XCURSOR)
if(USE_XFT)
target_link_libraries(fltk ${X11_Xft_LIB})
endif(USE_XFT)

View File

@ -62,8 +62,6 @@ void Fl_Window::_Fl_Window() {
Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l)
: Fl_Group(X, Y, W, H, l) {
cursor_default = FL_CURSOR_DEFAULT;
cursor_fg = FL_BLACK;
cursor_bg = FL_WHITE;
_Fl_Window();
set_flag(FORCE_POSITION);
@ -73,8 +71,6 @@ Fl_Window::Fl_Window(int W, int H, const char *l)
// fix common user error of a missing end() with current(0):
: Fl_Group((Fl_Group::current(0),0), 0, W, H, l) {
cursor_default = FL_CURSOR_DEFAULT;
cursor_fg = FL_BLACK;
cursor_bg = FL_WHITE;
_Fl_Window();
clear_visible();

View File

@ -97,7 +97,6 @@ Fl_Display_Device *Fl_Display_Device::_display = new Fl_Display_Device(new Fl_Qu
// public variables
CGContextRef fl_gc = 0;
NSCursor *fl_default_cursor;
void *fl_capture = 0; // (NSWindow*) we need this to compensate for a missing(?) mouse capture
bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state
//int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
@ -1413,8 +1412,6 @@ void fl_open_display() {
dequeue:YES];
while (ign_event);
fl_default_cursor = [NSCursor arrowCursor];
// bring the application into foreground without a 'CARB' resource
Boolean same_psn;
ProcessSerialNumber cur_psn, front_psn;
@ -1832,6 +1829,7 @@ static void cocoaKeyboardHandler(NSEvent *theEvent)
- (void)drawRect:(NSRect)rect;
- (BOOL)acceptsFirstResponder;
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
- (void)resetCursorRects;
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent;
@ -1921,6 +1919,16 @@ static void cocoaKeyboardHandler(NSEvent *theEvent)
Fl_Window *first = Fl::first_window();
return (first == w || !first->modal());
}
- (void)resetCursorRects {
Fl_Window *w = [(FLWindow*)[self window] getFl_Window];
Fl_X *i = Fl_X::i(w);
// We have to have at least one cursor rect for invalidateCursorRectsForView
// to work, hence the "else" clause.
if (i->cursor)
[self addCursorRect:[self visibleRect] cursor:(NSCursor*)i->cursor];
else
[self addCursorRect:[self visibleRect] cursor:[NSCursor arrowCursor]];
}
- (void)mouseUp:(NSEvent *)theEvent {
cocoaMouseHandler(theEvent);
}
@ -2367,7 +2375,7 @@ void Fl_X::make(Fl_Window* w)
x->other_xid = 0;
x->region = 0;
x->subRegion = 0;
x->cursor = fl_default_cursor;
x->cursor = NULL;
x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz
w->set_visible();
Fl_Window *win = w->window();
@ -2464,7 +2472,7 @@ void Fl_X::make(Fl_Window* w)
x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows
x->region = 0;
x->subRegion = 0;
x->cursor = fl_default_cursor;
x->cursor = NULL;
x->xidChildren = 0;
x->xidNext = 0;
x->gc = 0;
@ -3148,6 +3156,10 @@ void Fl_X::map() {
Fl_X::relink(w, w->window() );
w->redraw();
}
if (cursor) {
[(NSCursor*)cursor release];
cursor = NULL;
}
}
void Fl_X::unmap() {
@ -3282,68 +3294,106 @@ CFDataRef Fl_X::CGBitmapContextToTIFF(CGContextRef c)
return (CFDataRef)tiff;
}
static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
int Fl_X::set_cursor(Fl_Cursor c)
{
if (cursor == nil) {
CGContextRef c = f();
NSImage *image = CGBitmapContextToNSImage(c);
fl_delete_offscreen( (Fl_Offscreen)c );
NSPoint pt = {[image size].width/2, [image size].height/2};
cursor = [[NSCursor alloc] initWithImage:image hotSpot:pt];
if (cursor) {
[(NSCursor*)cursor release];
cursor = NULL;
}
return cursor;
switch (c) {
case FL_CURSOR_ARROW: cursor = [NSCursor arrowCursor]; break;
case FL_CURSOR_CROSS: cursor = [NSCursor crosshairCursor]; break;
case FL_CURSOR_INSERT: cursor = [NSCursor IBeamCursor]; break;
case FL_CURSOR_HAND: cursor = [NSCursor pointingHandCursor]; break;
case FL_CURSOR_MOVE: cursor = [NSCursor openHandCursor]; break;
case FL_CURSOR_NS: cursor = [NSCursor resizeUpDownCursor]; break;
case FL_CURSOR_WE: cursor = [NSCursor resizeLeftRightCursor]; break;
case FL_CURSOR_N: cursor = [NSCursor resizeUpCursor]; break;
case FL_CURSOR_E: cursor = [NSCursor resizeRightCursor]; break;
case FL_CURSOR_W: cursor = [NSCursor resizeLeftCursor]; break;
case FL_CURSOR_S: cursor = [NSCursor resizeDownCursor]; break;
default:
return 0;
}
[(NSCursor*)cursor retain];
[(NSWindow*)xid invalidateCursorRectsForView:[(NSWindow*)xid contentView]];
return 1;
}
void Fl_X::set_cursor(Fl_Cursor c)
{
NSCursor *icrsr;
switch (c) {
case FL_CURSOR_CROSS: icrsr = [NSCursor crosshairCursor]; break;
case FL_CURSOR_WAIT:
static NSCursor *watch = nil;
watch = PrepareCursor(watch, &Fl_X::watch_cursor_image);
icrsr = watch;
break;
case FL_CURSOR_INSERT: icrsr = [NSCursor IBeamCursor]; break;
case FL_CURSOR_N: icrsr = [NSCursor resizeUpCursor]; break;
case FL_CURSOR_S: icrsr = [NSCursor resizeDownCursor]; break;
case FL_CURSOR_NS: icrsr = [NSCursor resizeUpDownCursor]; break;
case FL_CURSOR_HELP:
static NSCursor *help = nil;
help = PrepareCursor(help, &Fl_X::help_cursor_image);
icrsr = help;
break;
case FL_CURSOR_HAND: icrsr = [NSCursor pointingHandCursor]; break;
case FL_CURSOR_MOVE: icrsr = [NSCursor openHandCursor]; break;
case FL_CURSOR_NE:
case FL_CURSOR_SW:
case FL_CURSOR_NESW:
static NSCursor *nesw = nil;
nesw = PrepareCursor(nesw, &Fl_X::nesw_cursor_image);
icrsr = nesw;
break;
case FL_CURSOR_E: icrsr = [NSCursor resizeRightCursor]; break;
case FL_CURSOR_W: icrsr = [NSCursor resizeLeftCursor]; break;
case FL_CURSOR_WE: icrsr = [NSCursor resizeLeftRightCursor]; break;
case FL_CURSOR_SE:
case FL_CURSOR_NW:
case FL_CURSOR_NWSE:
static NSCursor *nwse = nil;
nwse = PrepareCursor(nwse, &Fl_X::nwse_cursor_image);
icrsr = nwse;
break;
case FL_CURSOR_NONE:
static NSCursor *none = nil;
none = PrepareCursor(none, &Fl_X::none_cursor_image);
icrsr = none;
break;
case FL_CURSOR_ARROW:
case FL_CURSOR_DEFAULT:
default: icrsr = [NSCursor arrowCursor];
break;
int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
if (cursor) {
[(NSCursor*)cursor release];
cursor = NULL;
}
[icrsr set];
cursor = icrsr;
if ((hotx < 0) || (hotx >= image->w()))
return 0;
if ((hoty < 0) || (hoty >= image->h()))
return 0;
// OS X >= 10.6 can create a NSImage from a CGImage, but we need to
// support older versions, hence this pesky handling.
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:image->w()
pixelsHigh:image->h()
bitsPerSample:8
samplesPerPixel:image->d()
hasAlpha:!(image->d() & 1)
isPlanar:NO
colorSpaceName:(image->d()<=2) ? NSDeviceWhiteColorSpace : NSDeviceRGBColorSpace
bytesPerRow:(image->w() * image->d())
bitsPerPixel:(image->d()*8)];
// Alpha needs to be premultiplied for this format
const uchar *i = (const uchar*)*image->data();
unsigned char *o = [bitmap bitmapData];
for (int y = 0;y < image->h();y++) {
if (image->d() & 1) {
for (int x = 0;x < image->w();x++) {
unsigned int alpha;
if (image->d() == 4) {
alpha = i[3];
*o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
*o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
}
alpha = i[1];
*o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
*o++ = alpha;
i++;
}
} else {
// No alpha, so we can just copy everything directly.
int len = image->w() * image->d();
memcpy(o, i, len);
o += len;
i += len;
}
i += image->ld();
}
NSImage *nsimage = [[NSImage alloc]
initWithSize:NSMakeSize(image->w(), image->h())];
[nsimage addRepresentation:bitmap];
cursor = [[NSCursor alloc]
initWithImage:nsimage
hotSpot:NSMakePoint(hotx, hoty)];
[(NSWindow*)xid invalidateCursorRectsForView:[(NSWindow*)xid contentView]];
[bitmap release];
[nsimage release];
return 1;
}
@interface FLaboutItemTarget : NSObject

View File

@ -1653,7 +1653,6 @@ void fl_fix_focus(); // in Fl.cxx
char fl_show_iconic; // hack for Fl_Window::iconic()
// int fl_background_pixel = -1; // color to use for background
HCURSOR fl_default_cursor;
UINT fl_wake_msg = 0;
int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
@ -1702,7 +1701,7 @@ Fl_X* Fl_X::make(Fl_Window* w) {
if (!w->icon())
w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
wcw.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
wcw.hCursor = LoadCursor(NULL, IDC_ARROW);
//uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
//wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
wcw.hbrBackground = NULL;
@ -1794,7 +1793,8 @@ Fl_X* Fl_X::make(Fl_Window* w) {
x->setwindow(w);
x->region = 0;
x->private_dc = 0;
x->cursor = fl_default_cursor;
x->cursor = LoadCursor(NULL, IDC_ARROW);
x->custom_cursor = 0;
if (!fl_codepage) fl_get_codepage();
WCHAR *lab = NULL;
@ -2051,6 +2051,153 @@ void Fl_Window::label(const char *name,const char *iname) {
}
}
////////////////////////////////////////////////////////////////
#ifndef IDC_HAND
# define IDC_HAND MAKEINTRESOURCE(32649)
#endif // !IDC_HAND
int Fl_X::set_cursor(Fl_Cursor c) {
LPSTR n;
HCURSOR new_cursor;
if (c == FL_CURSOR_NONE)
new_cursor = NULL;
else {
switch (c) {
case FL_CURSOR_ARROW: n = IDC_ARROW; break;
case FL_CURSOR_CROSS: n = IDC_CROSS; break;
case FL_CURSOR_WAIT: n = IDC_WAIT; break;
case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
case FL_CURSOR_HAND: n = IDC_HAND; break;
case FL_CURSOR_HELP: n = IDC_HELP; break;
case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
case FL_CURSOR_N:
case FL_CURSOR_S:
// FIXME: Should probably have fallbacks for these instead
case FL_CURSOR_NS: n = IDC_SIZENS; break;
case FL_CURSOR_NE:
case FL_CURSOR_SW:
// FIXME: Dito.
case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
case FL_CURSOR_E:
case FL_CURSOR_W:
// FIXME: Dito.
case FL_CURSOR_WE: n = IDC_SIZEWE; break;
case FL_CURSOR_SE:
case FL_CURSOR_NW:
// FIXME: Dito.
case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
default:
return 0;
}
new_cursor = LoadCursor(NULL, n);
if (new_cursor == NULL)
return 0;
}
if ((cursor != NULL) && custom_cursor)
DestroyIcon(cursor);
cursor = new_cursor;
custom_cursor = 0;
SetCursor(cursor);
return 1;
}
int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
BITMAPV5HEADER bi;
HBITMAP bitmap, mask;
DWORD *bits;
HCURSOR new_cursor;
if ((hotx < 0) || (hotx >= image->w()))
return 0;
if ((hoty < 0) || (hoty >= image->h()))
return 0;
memset(&bi, 0, sizeof(BITMAPV5HEADER));
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = image->w();
bi.bV5Height = -image->h(); // Negative for top-down
bi.bV5Planes = 1;
bi.bV5BitCount = 32;
bi.bV5Compression = BI_BITFIELDS;
bi.bV5RedMask = 0x00FF0000;
bi.bV5GreenMask = 0x0000FF00;
bi.bV5BlueMask = 0x000000FF;
bi.bV5AlphaMask = 0xFF000000;
HDC hdc;
hdc = GetDC(NULL);
bitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ReleaseDC(NULL, hdc);
if (bits == NULL)
return 0;
const uchar *i = (const uchar*)*image->data();
for (int y = 0;y < image->h();y++) {
for (int x = 0;x < image->w();x++) {
switch (image->d()) {
case 1:
*bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
break;
case 2:
*bits = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
break;
case 3:
*bits = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
break;
case 4:
*bits = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
break;
}
i += image->d();
bits++;
}
i += image->ld();
}
// A mask bitmap is still needed even though it isn't used
mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
if (mask == NULL) {
DeleteObject(bitmap);
return 0;
}
ICONINFO ii;
ii.fIcon = FALSE;
ii.xHotspot = hotx;
ii.yHotspot = hoty;
ii.hbmMask = mask;
ii.hbmColor = bitmap;
new_cursor = CreateIconIndirect(&ii);
DeleteObject(bitmap);
DeleteObject(mask);
if (new_cursor == NULL)
return 0;
if ((cursor != NULL) && custom_cursor)
DestroyIcon(cursor);
cursor = new_cursor;
custom_cursor = 1;
SetCursor(cursor);
return 1;
}
////////////////////////////////////////////////////////////////
// Implement the virtual functions for the base Fl_Window class:

View File

@ -62,6 +62,11 @@ static int xfixes_event_base = 0;
static bool have_xfixes = false;
# endif
# include <X11/cursorfont.h>
# if HAVE_XCURSOR
# include <X11/Xcursor/Xcursor.h>
# endif
static Fl_Xlib_Graphics_Driver fl_xlib_driver;
static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
@ -2600,6 +2605,94 @@ void Fl_Window::size_range_() {
////////////////////////////////////////////////////////////////
int Fl_X::set_cursor(Fl_Cursor c) {
unsigned int shape;
Cursor xc;
switch (c) {
case FL_CURSOR_ARROW: shape = XC_left_ptr; break;
case FL_CURSOR_CROSS: shape = XC_tcross; break;
case FL_CURSOR_WAIT: shape = XC_watch; break;
case FL_CURSOR_INSERT: shape = XC_xterm; break;
case FL_CURSOR_HAND: shape = XC_hand2; break;
case FL_CURSOR_HELP: shape = XC_question_arrow; break;
case FL_CURSOR_MOVE: shape = XC_fleur; break;
case FL_CURSOR_NS: shape = XC_sb_v_double_arrow; break;
case FL_CURSOR_WE: shape = XC_sb_h_double_arrow; break;
case FL_CURSOR_NE: shape = XC_top_right_corner; break;
case FL_CURSOR_N: shape = XC_top_side; break;
case FL_CURSOR_NW: shape = XC_top_left_corner; break;
case FL_CURSOR_E: shape = XC_right_side; break;
case FL_CURSOR_W: shape = XC_left_side; break;
case FL_CURSOR_SE: shape = XC_bottom_right_corner; break;
case FL_CURSOR_S: shape = XC_bottom_side; break;
case FL_CURSOR_SW: shape = XC_bottom_left_corner; break;
default:
return 0;
}
xc = XCreateFontCursor(fl_display, shape);
XDefineCursor(fl_display, xid, xc);
XFreeCursor(fl_display, xc);
return 1;
}
int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
#if ! HAVE_XCURSOR
return 0;
#else
XcursorImage *cursor;
Cursor xc;
if ((hotx < 0) || (hotx >= image->w()))
return 0;
if ((hoty < 0) || (hoty >= image->h()))
return 0;
cursor = XcursorImageCreate(image->w(), image->h());
if (!cursor)
return 0;
const uchar *i = (const uchar*)*image->data();
XcursorPixel *o = cursor->pixels;
for (int y = 0;y < image->h();y++) {
for (int x = 0;x < image->w();x++) {
switch (image->d()) {
case 1:
*o = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
break;
case 2:
*o = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
break;
case 3:
*o = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
break;
case 4:
*o = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
break;
}
i += image->d();
o++;
}
i += image->ld();
}
cursor->xhot = hotx;
cursor->yhot = hoty;
xc = XcursorImageLoadCursor(fl_display, cursor);
XDefineCursor(fl_display, xid, xc);
XFreeCursor(fl_display, xc);
XcursorImageDestroy(cursor);
return 1;
#endif
}
////////////////////////////////////////////////////////////////
// returns pointer to the filename, or null if name ends with '/'
const char *fl_filename_name(const char *name) {
const char *p,*q;

View File

@ -24,297 +24,165 @@
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_RGB_Image.H>
#include <FL/x.H>
#if !defined(WIN32) && !defined(__APPLE__)
# include <X11/cursorfont.h>
#endif
#include <FL/fl_draw.H>
#include "fl_cursor_wait.xpm"
#include "fl_cursor_help.xpm"
#include "fl_cursor_nwse.xpm"
#include "fl_cursor_nesw.xpm"
#include "fl_cursor_none.xpm"
/**
Sets the cursor for the current window to the specified shape and colors.
The cursors are defined in the <FL/Enumerations.H> header file.
*/
void fl_cursor(Fl_Cursor c) {
if (Fl::first_window()) Fl::first_window()->cursor(c);
}
/* For back compatibility only. */
void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
fl_cursor(c);
}
/**
Sets the default window cursor as well as its color.
Sets the default window cursor. This is the cursor that will be used
after the mouse pointer leaves a widget with a custom cursor set.
For back compatibility only.
\see cursor(const Fl_RGB_Image*, int, int), default_cursor()
*/
void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
// if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW;
void Fl_Window::default_cursor(Fl_Cursor c) {
cursor_default = c;
cursor_fg = fg;
cursor_bg = bg;
cursor(c, fg, bg);
cursor(c);
}
#ifdef WIN32
# ifndef IDC_HAND
# define IDC_HAND MAKEINTRESOURCE(32649)
# endif // !IDC_HAND
static void fallback_cursor(Fl_Window *w, Fl_Cursor c) {
const char **xpm;
int hotx, hoty;
// The standard arrow is our final fallback, so something is broken
// if we get called back here with that as an argument.
if (c == FL_CURSOR_ARROW)
return;
switch (c) {
case FL_CURSOR_WAIT:
xpm = (const char**)fl_cursor_wait_xpm;
hotx = 8;
hoty = 15;
break;
case FL_CURSOR_HELP:
xpm = (const char**)fl_cursor_help_xpm;
hotx = 1;
hoty = 3;
break;
case FL_CURSOR_NWSE:
xpm = (const char**)fl_cursor_nwse_xpm;
hotx = 7;
hoty = 7;
break;
case FL_CURSOR_NESW:
xpm = (const char**)fl_cursor_nesw_xpm;
hotx = 7;
hoty = 7;
break;
case FL_CURSOR_NONE:
xpm = (const char**)fl_cursor_none_xpm;
hotx = 0;
hoty = 0;
break;
default:
w->cursor(FL_CURSOR_ARROW);
return;
}
Fl_Pixmap pxm(xpm);
Fl_RGB_Image image(&pxm);
w->cursor(&image, hotx, hoty);
}
void Fl_Window::cursor(Fl_Cursor c) {
int ret;
void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) {
if (!shown()) return;
// the cursor must be set for the top level window, not for subwindows
Fl_Window *w = window(), *toplevel = this;
while (w) { toplevel = w; w = w->window(); }
if (toplevel != this) { toplevel->cursor(c, c1, c2); return; }
// now set the actual cursor
if (c == FL_CURSOR_DEFAULT) {
while (w) {
toplevel = w;
w = w->window();
}
if (toplevel != this) {
toplevel->cursor(c);
return;
}
if (c == FL_CURSOR_DEFAULT)
c = cursor_default;
if (!i)
return;
ret = i->set_cursor(c);
if (ret)
return;
fallback_cursor(this, c);
}
/**
Changes the cursor for this window. This always calls the system, if
you are changing the cursor a lot you may want to keep track of how
you set it in a static variable and call this only if the new cursor
is different.
The default cursor will be used if the provided image cannot be used
as a cursor.
\see cursor(Fl_Cursor), default_cursor()
*/
void Fl_Window::cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
int ret;
// the cursor must be set for the top level window, not for subwindows
Fl_Window *w = window(), *toplevel = this;
while (w) {
toplevel = w;
w = w->window();
}
if (c > FL_CURSOR_NESW) {
i->cursor = 0;
} else if (c == FL_CURSOR_DEFAULT) {
i->cursor = fl_default_cursor;
} else {
LPSTR n;
switch (c) {
case FL_CURSOR_ARROW: n = IDC_ARROW; break;
case FL_CURSOR_CROSS: n = IDC_CROSS; break;
case FL_CURSOR_WAIT: n = IDC_WAIT; break;
case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
case FL_CURSOR_HELP: n = IDC_HELP; break;
case FL_CURSOR_HAND: {
OSVERSIONINFO osvi;
// Get the OS version: Windows 98 and 2000 have a standard
// hand cursor.
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
if (osvi.dwMajorVersion > 4 ||
(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 &&
osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND;
else n = IDC_UPARROW;
} break;
case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
case FL_CURSOR_N:
case FL_CURSOR_S:
case FL_CURSOR_NS: n = IDC_SIZENS; break;
case FL_CURSOR_NE:
case FL_CURSOR_SW:
case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
case FL_CURSOR_E:
case FL_CURSOR_W:
case FL_CURSOR_WE: n = IDC_SIZEWE; break;
case FL_CURSOR_SE:
case FL_CURSOR_NW:
case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
default: n = IDC_NO; break;
}
i->cursor = LoadCursor(NULL, n);
if (toplevel != this) {
toplevel->cursor(image, hotx, hoty);
return;
}
SetCursor(i->cursor);
}
#elif defined(__APPLE__)
#ifdef __BIG_ENDIAN__
# define E(x) x
#elif defined __LITTLE_ENDIAN__
// Don't worry. This will be resolved at compile time
# define E(x) (x>>8)|((x<<8)&0xff00)
#else
# error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined"
#endif
CGContextRef Fl_X::help_cursor_image(void)
{
int w = 20, h = 20;
Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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 Fl_X::none_cursor_image(void)
{
int w = 20, h = 20;
Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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 Fl_X::watch_cursor_image(void)
{
int w, h, r = 5;
w = 2*r+6;
h = 4*r;
Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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(int(-r*0.7), int(-r*1.7), int(1.4*r), int(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, int(-r*.7));
fl_xyline(0, 0, 0, int(-r*.7));
fl_end_offscreen();
return (CGContextRef)off;
}
CGContextRef Fl_X::nesw_cursor_image(void)
{
int c = 7, r = 2*c;
int w = r, h = r;
Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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 Fl_X::nwse_cursor_image(void)
{
int c = 7, r = 2*c;
int w = r, h = r;
Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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;
if (!i)
return;
ret = i->set_cursor(image, hotx, hoty);
if (ret)
return;
cursor(FL_CURSOR_DEFAULT);
}
/* For back compatibility only. */
void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
if (c == FL_CURSOR_DEFAULT) {
c = cursor_default;
}
if (i) i->set_cursor(c);
}
#else
// I like the MSWindows resize cursors, so I duplicate them here:
#define CURSORSIZE 16
#define HOTXY 7
static struct TableEntry {
uchar bits[CURSORSIZE*CURSORSIZE/8];
uchar mask[CURSORSIZE*CURSORSIZE/8];
Cursor cursor;
} table[] = {
{{ // FL_CURSOR_NS
0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
{
0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
{{ // FL_CURSOR_EW
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{ // FL_CURSOR_NWSE
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
{{ // FL_CURSOR_NESW
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
{{0}, {0}} // FL_CURSOR_NONE & unknown
cursor(c);
};
void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
if (!shown()) return;
Cursor xc;
int deleteit = 0;
if (c == FL_CURSOR_DEFAULT) {
c = cursor_default;
fg = cursor_fg;
bg = cursor_bg;
}
void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
default_cursor(c);
};
if (!c) {
xc = None;
} else {
if (c >= FL_CURSOR_NS) {
TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
if (!(q->cursor)) {
XColor dummy = { 0 };
Pixmap p = XCreateBitmapFromData(fl_display,
RootWindow(fl_display, fl_screen), (const char*)(q->bits),
CURSORSIZE, CURSORSIZE);
Pixmap m = XCreateBitmapFromData(fl_display,
RootWindow(fl_display, fl_screen), (const char*)(q->mask),
CURSORSIZE, CURSORSIZE);
q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy,
HOTXY, HOTXY);
XFreePixmap(fl_display, m);
XFreePixmap(fl_display, p);
}
xc = q->cursor;
} else {
xc = XCreateFontCursor(fl_display, (c-1)*2);
deleteit = 1;
}
XColor fgc;
uchar r,g,b;
Fl::get_color(fg,r,g,b);
fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8;
XColor bgc;
Fl::get_color(bg,r,g,b);
bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8;
XRecolorCursor(fl_display, xc, &fgc, &bgc);
}
XDefineCursor(fl_display, fl_xid(this), xc);
if (deleteit) XFreeCursor(fl_display, xc);
}
#endif
//
// End of "$Id$".

39
src/fl_cursor_help.xpm Normal file
View File

@ -0,0 +1,39 @@
/* XPM */
static char * fl_cursor_help_xpm[] = {
"16 27 9 1",
" c None",
". c #FFFFFF",
"+ c #DBDBDB",
"@ c #242424",
"# c #000000",
"$ c #494949",
"% c #6D6D6D",
"& c #929292",
"* c #B6B6B6",
" ",
". ",
".+ ",
".@+ ",
".#@+ ",
".##@. ",
".###@. ",
".####@. ",
".#####$. ",
".######$. ",
".#######$. ",
".#####@@@%. ",
".#####+..... ",
".##$%#%. ",
".#$..@#. ",
".$. .&#%. ",
".. .##. .... ",
". .&#.+%$%&. ",
" ...*#@##%.",
" ++.*#@.",
" .%#$.",
" .%#@. ",
" .##+ ",
" .++. ",
" +##. ",
" +##. ",
" .... "};

46
src/fl_cursor_nesw.xpm Normal file
View File

@ -0,0 +1,46 @@
/* XPM */
static const char * fl_cursor_nesw_xpm[] = {
"15 15 28 1",
" c None",
". c #FFFFFF",
"+ c #767676",
"@ c #000000",
"# c #4E4E4E",
"$ c #0C0C0C",
"% c #494949",
"& c #4D4D4D",
"* c #1B1B1B",
"= c #515151",
"- c #646464",
"; c #363636",
"> c #6A6A6A",
", c #545454",
"' c #585858",
") c #242424",
"! c #797979",
"~ c #2E2E2E",
"{ c #444444",
"] c #3B3B3B",
"^ c #0A0A0A",
"/ c #595959",
"( c #F7F7F7",
"_ c #080808",
": c #6B6B6B",
"< c #FDFDFD",
"[ c #FCFCFC",
"} c #FEFEFE",
" ..........",
" .+@@@@@@.",
" .#@@@@@.",
" .$@@@@.",
" .%@@@@@.",
". .&@@@*@@.",
".. .=@@@-.;@.",
".>. .,@@@'. .).",
".@!.'@@@#. ..",
".@@~@@@{. .",
".@@@@@]. ",
".@@@@^. ",
".@@@@@/( ",
".______:( ",
"<[[[[[[[[} "};

19
src/fl_cursor_none.xpm Normal file
View File

@ -0,0 +1,19 @@
/* XPM */
static const char * fl_cursor_none_xpm[] = {
"15 15 1 1",
" c None",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};

46
src/fl_cursor_nwse.xpm Normal file
View File

@ -0,0 +1,46 @@
/* XPM */
static const char * fl_cursor_nwse_xpm[] = {
"15 15 28 1",
" c None",
". c #FFFFFF",
"+ c #000000",
"@ c #767676",
"# c #4E4E4E",
"$ c #0C0C0C",
"% c #494949",
"& c #1B1B1B",
"* c #4D4D4D",
"= c #363636",
"- c #646464",
"; c #515151",
"> c #242424",
", c #585858",
"' c #545454",
") c #6A6A6A",
"! c #797979",
"~ c #444444",
"{ c #2E2E2E",
"] c #3B3B3B",
"^ c #0A0A0A",
"/ c #F7F7F7",
"( c #595959",
"_ c #6B6B6B",
": c #080808",
"< c #FEFEFE",
"[ c #FCFCFC",
"} c #FDFDFD",
".......... ",
".++++++@. ",
".+++++#. ",
".++++$. ",
".+++++%. ",
".++&+++*. .",
".+=.-+++;. ..",
".>. .,+++'. .).",
".. .#+++,.!+.",
". .~+++{++.",
" .]+++++.",
" .^++++.",
" /(+++++.",
" /_::::::.",
" <[[[[[[[[}"};

46
src/fl_cursor_wait.xpm Normal file
View File

@ -0,0 +1,46 @@
/* XPM */
static char * fl_cursor_wait_xpm[] = {
"17 32 11 1",
" c None",
". c #FFFFFF",
"+ c #2E2E2E",
"@ c #202020",
"# c #242424",
"$ c #000000",
"% c #494949",
"& c #929292",
"* c #B6B6B6",
"= c #DBDBDB",
"- c #6D6D6D",
".................",
".+@@@@@@@@@@@@@+.",
".................",
" .#$$$$$$$$$$$#. ",
" .%$$$$$$$$$$$%. ",
" .&$$$$$$$$$$$&. ",
" *$$$$$$$$$$$* ",
" =$$$$$$$$$$$= ",
" .#$$$$$$$$$#. ",
" .-$$$$$$$$$-. ",
" *$$$$$$$$$* ",
" .$=.....=$. ",
" .%-.....-%. ",
" =#=...=#= ",
" .-%...%-. ",
" .##.##. ",
" .#$.$#. ",
" .-$$.$$-. ",
" =$$$.$$$= ",
" .%$$$.$$$%. ",
" .$$$$.$$$$. ",
" *$$$$.$$$$* ",
" .-$$$$.$$$$-. ",
" .#$$$$.$$$$#. ",
" =$$#&*.*&#$$= ",
" *$%.......%$* ",
" .&#.........#&. ",
" .%-.........-%. ",
" .#$$$$$$$$$$$#. ",
".................",
".+@@@@@@@@@@@@@+.",
"................."};

View File

@ -23,8 +23,6 @@
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
Fl_Color fg = FL_BLACK;
Fl_Color bg = FL_WHITE;
Fl_Cursor cursor = FL_CURSOR_DEFAULT;
Fl_Hor_Value_Slider *cursor_slider;
@ -32,7 +30,7 @@ Fl_Hor_Value_Slider *cursor_slider;
void choice_cb(Fl_Widget *, void *v) {
cursor = (Fl_Cursor)(fl_intptr_t)v;
cursor_slider->value(cursor);
fl_cursor(cursor,fg,bg);
fl_cursor(cursor);
}
Fl_Menu_Item choices[] = {
@ -48,8 +46,6 @@ Fl_Menu_Item choices[] = {
{"FL_CURSOR_WE",0,choice_cb,(void*)FL_CURSOR_WE},
{"FL_CURSOR_NWSE",0,choice_cb,(void*)FL_CURSOR_NWSE},
{"FL_CURSOR_NESW",0,choice_cb,(void*)FL_CURSOR_NESW},
{"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
#if 0
{"FL_CURSOR_N",0,choice_cb,(void*)FL_CURSOR_N},
{"FL_CURSOR_NE",0,choice_cb,(void*)FL_CURSOR_NE},
{"FL_CURSOR_E",0,choice_cb,(void*)FL_CURSOR_E},
@ -58,26 +54,14 @@ Fl_Menu_Item choices[] = {
{"FL_CURSOR_SW",0,choice_cb,(void*)FL_CURSOR_SW},
{"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
{"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
#endif
{"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
{0}
};
void setcursor(Fl_Widget *o, void *) {
Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
cursor = Fl_Cursor((int)slider->value());
fl_cursor(cursor,fg,bg);
}
void setfg(Fl_Widget *o, void *) {
Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
fg = Fl_Color((int)slider->value());
fl_cursor(cursor,fg,bg);
}
void setbg(Fl_Widget *o, void *) {
Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
bg = Fl_Color((int)slider->value());
fl_cursor(cursor,fg,bg);
fl_cursor(cursor);
}
// draw the label without any ^C or \nnn conversions:
@ -103,29 +87,11 @@ int main(int argc, char **argv) {
slider1.align(FL_ALIGN_LEFT);
slider1.step(1);
slider1.precision(0);
slider1.bounds(0,100);
slider1.bounds(0,255);
slider1.value(0);
slider1.callback(setcursor);
slider1.value(cursor);
Fl_Hor_Value_Slider slider2(80,220,310,30,"fgcolor:");
slider2.align(FL_ALIGN_LEFT);
slider2.step(1);
slider2.precision(0);
slider2.bounds(0,255);
slider2.value(0);
slider2.callback(setfg);
slider2.value(fg);
Fl_Hor_Value_Slider slider3(80,260,310,30,"bgcolor:");
slider3.align(FL_ALIGN_LEFT);
slider3.step(1);
slider3.precision(0);
slider3.bounds(0,255);
slider3.value(0);
slider3.callback(setbg);
slider3.value(bg);
#if 0
// draw the manual's diagram of cursors...
window.size(400,800);