|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: fl_cursor.cxx 8055 2010-12-18 22:31:01Z manolo $" 00003 // 00004 // Mouse cursor support for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 // Change the current cursor. 00029 // Under X the cursor is attached to the X window. I tried to hide 00030 // this and pretend that changing the cursor is a drawing function. 00031 // This avoids a field in the Fl_Window, and I suspect is more 00032 // portable to other systems. 00033 00034 #include <FL/Fl.H> 00035 #include <FL/Fl_Window.H> 00036 #include <FL/x.H> 00037 #if !defined(WIN32) && !defined(__APPLE__) 00038 # include <X11/cursorfont.h> 00039 #endif 00040 #include <FL/fl_draw.H> 00041 00046 void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { 00047 if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg); 00048 } 00054 void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { 00055 // if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW; 00056 00057 cursor_default = c; 00058 cursor_fg = fg; 00059 cursor_bg = bg; 00060 00061 cursor(c, fg, bg); 00062 } 00063 00064 #ifdef WIN32 00065 00066 # ifndef IDC_HAND 00067 # define IDC_HAND MAKEINTRESOURCE(32649) 00068 # endif // !IDC_HAND 00069 00070 void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) { 00071 if (!shown()) return; 00072 // the cursor must be set for the top level window, not for subwindows 00073 Fl_Window *w = window(), *toplevel = this; 00074 while (w) { toplevel = w; w = w->window(); } 00075 if (toplevel != this) { toplevel->cursor(c, c1, c2); return; } 00076 // now set the actual cursor 00077 if (c == FL_CURSOR_DEFAULT) { 00078 c = cursor_default; 00079 } 00080 if (c > FL_CURSOR_NESW) { 00081 i->cursor = 0; 00082 } else if (c == FL_CURSOR_DEFAULT) { 00083 i->cursor = fl_default_cursor; 00084 } else { 00085 LPSTR n; 00086 switch (c) { 00087 case FL_CURSOR_ARROW: n = IDC_ARROW; break; 00088 case FL_CURSOR_CROSS: n = IDC_CROSS; break; 00089 case FL_CURSOR_WAIT: n = IDC_WAIT; break; 00090 case FL_CURSOR_INSERT: n = IDC_IBEAM; break; 00091 case FL_CURSOR_HELP: n = IDC_HELP; break; 00092 case FL_CURSOR_HAND: { 00093 OSVERSIONINFO osvi; 00094 00095 // Get the OS version: Windows 98 and 2000 have a standard 00096 // hand cursor. 00097 memset(&osvi, 0, sizeof(OSVERSIONINFO)); 00098 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00099 GetVersionEx(&osvi); 00100 00101 if (osvi.dwMajorVersion > 4 || 00102 (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 && 00103 osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND; 00104 else n = IDC_UPARROW; 00105 } break; 00106 case FL_CURSOR_MOVE: n = IDC_SIZEALL; break; 00107 case FL_CURSOR_N: 00108 case FL_CURSOR_S: 00109 case FL_CURSOR_NS: n = IDC_SIZENS; break; 00110 case FL_CURSOR_NE: 00111 case FL_CURSOR_SW: 00112 case FL_CURSOR_NESW: n = IDC_SIZENESW; break; 00113 case FL_CURSOR_E: 00114 case FL_CURSOR_W: 00115 case FL_CURSOR_WE: n = IDC_SIZEWE; break; 00116 case FL_CURSOR_SE: 00117 case FL_CURSOR_NW: 00118 case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break; 00119 default: n = IDC_NO; break; 00120 } 00121 i->cursor = LoadCursor(NULL, n); 00122 } 00123 SetCursor(i->cursor); 00124 } 00125 00126 #elif defined(__APPLE__) 00127 00128 #ifdef __BIG_ENDIAN__ 00129 # define E(x) x 00130 #elif defined __LITTLE_ENDIAN__ 00131 // Don't worry. This will be resolved at compile time 00132 # define E(x) (x>>8)|((x<<8)&0xff00) 00133 #else 00134 # error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined" 00135 #endif 00136 00137 extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h); 00138 00139 00140 CGContextRef Fl_X::help_cursor_image(void) 00141 { 00142 int w = 20, h = 20; 00143 Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); 00144 fl_begin_offscreen(off); 00145 CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); 00146 fl_rectf(0,0,w,h); 00147 fl_color(FL_BLACK); 00148 fl_font(FL_COURIER_BOLD, 20); 00149 fl_draw("?", 1, h-1); 00150 fl_end_offscreen(); 00151 return (CGContextRef)off; 00152 } 00153 00154 CGContextRef Fl_X::none_cursor_image(void) 00155 { 00156 int w = 20, h = 20; 00157 Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); 00158 fl_begin_offscreen(off); 00159 CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); 00160 fl_rectf(0,0,w,h); 00161 fl_end_offscreen(); 00162 return (CGContextRef)off; 00163 } 00164 00165 CGContextRef Fl_X::watch_cursor_image(void) 00166 { 00167 int w, h, r = 5; 00168 w = 2*r+6; 00169 h = 4*r; 00170 Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); 00171 fl_begin_offscreen(off); 00172 CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); 00173 fl_rectf(0,0,w,h); 00174 CGContextTranslateCTM( (CGContextRef)off, w/2, h/2); 00175 fl_color(FL_WHITE); 00176 fl_circle(0, 0, r+1); 00177 fl_color(FL_BLACK); 00178 fl_rectf(int(-r*0.7), int(-r*1.7), int(1.4*r), int(3.4*r)); 00179 fl_rectf(r-1, -1, 3, 3); 00180 fl_color(FL_WHITE); 00181 fl_pie(-r, -r, 2*r, 2*r, 0, 360); 00182 fl_color(FL_BLACK); 00183 fl_circle(0,0,r); 00184 fl_xyline(0, 0, int(-r*.7)); 00185 fl_xyline(0, 0, 0, int(-r*.7)); 00186 fl_end_offscreen(); 00187 return (CGContextRef)off; 00188 } 00189 00190 CGContextRef Fl_X::nesw_cursor_image(void) 00191 { 00192 int c = 7, r = 2*c; 00193 int w = r, h = r; 00194 Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); 00195 fl_begin_offscreen(off); 00196 CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); 00197 fl_rectf(0,0,w,h); 00198 CGContextTranslateCTM( (CGContextRef)off, 0, h); 00199 CGContextScaleCTM( (CGContextRef)off, 1, -1); 00200 fl_color(FL_BLACK); 00201 fl_polygon(0, 0, c, 0, 0, c); 00202 fl_polygon(r, r, r, r-c, r-c, r); 00203 fl_line_style(FL_SOLID, 2, 0); 00204 fl_line(0,1, r,r+1); 00205 fl_line_style(FL_SOLID, 0, 0); 00206 fl_end_offscreen(); 00207 return (CGContextRef)off; 00208 } 00209 00210 CGContextRef Fl_X::nwse_cursor_image(void) 00211 { 00212 int c = 7, r = 2*c; 00213 int w = r, h = r; 00214 Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); 00215 fl_begin_offscreen(off); 00216 CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); 00217 fl_rectf(0,0,w,h); 00218 CGContextTranslateCTM( (CGContextRef)off, 0, h); 00219 CGContextScaleCTM( (CGContextRef)off, 1, -1); 00220 fl_color(FL_BLACK); 00221 fl_polygon(r-1, 0, r-1, c, r-1-c, 0); 00222 fl_polygon(-1, r, c-1, r, -1, r-c); 00223 fl_line_style(FL_SOLID, 2, 0); 00224 fl_line(r-1,1, -1,r+1); 00225 fl_line_style(FL_SOLID, 0, 0); 00226 fl_end_offscreen(); 00227 return (CGContextRef)off; 00228 } 00229 00230 void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) { 00231 if (c == FL_CURSOR_DEFAULT) { 00232 c = cursor_default; 00233 } 00234 if (i) i->set_cursor(c); 00235 } 00236 00237 #else 00238 00239 // I like the MSWindows resize cursors, so I duplicate them here: 00240 00241 #define CURSORSIZE 16 00242 #define HOTXY 7 00243 static struct TableEntry { 00244 uchar bits[CURSORSIZE*CURSORSIZE/8]; 00245 uchar mask[CURSORSIZE*CURSORSIZE/8]; 00246 Cursor cursor; 00247 } table[] = { 00248 {{ // FL_CURSOR_NS 00249 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, 00250 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 00251 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00}, 00252 { 00253 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03, 00254 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f, 00255 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}}, 00256 {{ // FL_CURSOR_EW 00257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 00258 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00, 00259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 00260 { 00261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38, 00262 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18, 00263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 00264 {{ // FL_CURSOR_NWSE 00265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00, 00266 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c, 00267 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 00268 { 00269 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00, 00270 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 00271 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}}, 00272 {{ // FL_CURSOR_NESW 00273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e, 00274 0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00, 00275 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 00276 { 00277 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f, 00278 0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00, 00279 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}}, 00280 {{0}, {0}} // FL_CURSOR_NONE & unknown 00281 }; 00282 00283 void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { 00284 if (!shown()) return; 00285 Cursor xc; 00286 int deleteit = 0; 00287 if (c == FL_CURSOR_DEFAULT) { 00288 c = cursor_default; 00289 fg = cursor_fg; 00290 bg = cursor_bg; 00291 } 00292 00293 if (!c) { 00294 xc = None; 00295 } else { 00296 if (c >= FL_CURSOR_NS) { 00297 TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS); 00298 if (!(q->cursor)) { 00299 XColor dummy = { 0 }; 00300 Pixmap p = XCreateBitmapFromData(fl_display, 00301 RootWindow(fl_display, fl_screen), (const char*)(q->bits), 00302 CURSORSIZE, CURSORSIZE); 00303 Pixmap m = XCreateBitmapFromData(fl_display, 00304 RootWindow(fl_display, fl_screen), (const char*)(q->mask), 00305 CURSORSIZE, CURSORSIZE); 00306 q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy, 00307 HOTXY, HOTXY); 00308 XFreePixmap(fl_display, m); 00309 XFreePixmap(fl_display, p); 00310 } 00311 xc = q->cursor; 00312 } else { 00313 xc = XCreateFontCursor(fl_display, (c-1)*2); 00314 deleteit = 1; 00315 } 00316 XColor fgc; 00317 uchar r,g,b; 00318 Fl::get_color(fg,r,g,b); 00319 fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8; 00320 XColor bgc; 00321 Fl::get_color(bg,r,g,b); 00322 bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8; 00323 XRecolorCursor(fl_display, xc, &fgc, &bgc); 00324 } 00325 XDefineCursor(fl_display, fl_xid(this), xc); 00326 if (deleteit) XFreeCursor(fl_display, xc); 00327 } 00328 00329 #endif 00330 00331 // 00332 // End of "$Id: fl_cursor.cxx 8055 2010-12-18 22:31:01Z manolo $". 00333 //