diff options
| -rw-r--r-- | FL/Fl_Sys_Menu_Bar.H | 5 | ||||
| -rw-r--r-- | FL/mac.H | 4 | ||||
| -rw-r--r-- | src/Fl_Sys_Menu_Bar.cxx | 52 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 222 | ||||
| -rw-r--r-- | src/Fl_x.cxx | 41 | ||||
| -rw-r--r-- | src/Makefile | 5 | ||||
| -rw-r--r-- | src/fl_font_mac.cxx | 98 |
7 files changed, 231 insertions, 196 deletions
diff --git a/FL/Fl_Sys_Menu_Bar.H b/FL/Fl_Sys_Menu_Bar.H index 40e587a8b..8c8cbfd40 100644 --- a/FL/Fl_Sys_Menu_Bar.H +++ b/FL/Fl_Sys_Menu_Bar.H @@ -43,8 +43,9 @@ public: 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); + 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 @@ -54,6 +54,7 @@ #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__ @@ -61,9 +62,8 @@ typedef double CGFloat; #else typedef float CGFloat; #endif -#endif +#endif //CGFLOAT_DEFINED -#endif // Now make some fixes to the headers... #undef check // Dunno where this comes from... diff --git a/src/Fl_Sys_Menu_Bar.cxx b/src/Fl_Sys_Menu_Bar.cxx index 8893c0b26..e35cff790 100644 --- a/src/Fl_Sys_Menu_Bar.cxx +++ b/src/Fl_Sys_Menu_Bar.cxx @@ -65,7 +65,6 @@ #ifdef __APPLE_COCOA__ extern void *MACMenuOrItemOperation(const char *operation, ...); -extern void *MACmainMenu(void); #define MenuHandle void * #endif @@ -149,7 +148,7 @@ static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) #ifdef __APPLE_COCOA__ void *menuItem = MACMenuOrItemOperation("itemAtIndex", mh, miCnt); - MACMenuOrItemOperation("setKeyEquivalent", menuItem, key ); + MACMenuOrItemOperation("setKeyEquivalent", menuItem, m->shortcut_ & 0xff ); MACMenuOrItemOperation("setKeyEquivalentModifierMask", menuItem, m->shortcut_ ); #else long macMod = kMenuNoCommandModifier; @@ -223,20 +222,21 @@ static void createSubMenu( void * mh, pFl_Menu_Item &mm ) menuItem = MACMenuOrItemOperation("itemAtIndex", mh, cnt); MACMenuOrItemOperation("setSubmenu", menuItem, submenu); if ( mm->flags & FL_MENU_INACTIVE ) { - MACMenuOrItemOperation("setEnabled", menuItem, 0); + MACMenuOrItemOperation("setEnabled", menuItem, 0); } mm++; while ( mm->text ) { - MACMenuOrItemOperation("addNewItem", submenu, mm, &miCnt); + 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_MENU_INACTIVE ) { + void *item = MACMenuOrItemOperation("itemAtIndex", submenu, miCnt); + MACMenuOrItemOperation("setEnabled", item, 0); + } + flags = mm->flags; if ( mm->flags & FL_SUBMENU ) { createSubMenu( submenu, mm ); @@ -247,8 +247,8 @@ static void createSubMenu( void * mh, pFl_Menu_Item &mm ) createSubMenu( submenu, smm ); } if ( flags & FL_MENU_DIVIDER ) { - MACMenuOrItemOperation("addSeparatorItem", submenu); - } + MACMenuOrItemOperation("addSeparatorItem", submenu); + } mm++; } } @@ -259,9 +259,9 @@ static void convertToMenuBar(const Fl_Menu_Item *mm) //ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW DATA { int count;//first, delete all existing system menus - MACMenuOrItemOperation("numberOfItems", MACmainMenu(), &count); + MACMenuOrItemOperation("numberOfItems", fl_system_menu, &count); for(int i = count - 1; i > 0; i--) { - MACMenuOrItemOperation("removeItem", MACmainMenu(), i); + MACMenuOrItemOperation("removeItem", fl_system_menu, i); } //now convert FLTK stuff into MacOS menus for (;;) @@ -269,13 +269,14 @@ static void convertToMenuBar(const Fl_Menu_Item *mm) if ( !mm || !mm->text ) break; char visible = mm->visible() ? 1 : 0; - MACMenuOrItemOperation("addNewItem", MACmainMenu(), mm, NULL); + int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); + MACMenuOrItemOperation("addNewItem", fl_system_menu, flRank, NULL); if ( mm->flags & FL_SUBMENU ) - createSubMenu( MACmainMenu(), mm ); + createSubMenu( fl_system_menu, mm ); else if ( mm->flags & FL_SUBMENU_POINTER ) { const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( MACmainMenu(), smm ); + createSubMenu( fl_system_menu, smm ); } if ( visible ) { // InsertMenu( mh, 0 ); @@ -315,14 +316,27 @@ int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void /** * remove an item from the system menu bar * - * @param n the rank of the item to remove + * @param rank the rank of the item to remove */ -void Fl_Sys_Menu_Bar::remove(int n) +void Fl_Sys_Menu_Bar::remove(int rank) { - Fl_Menu_::remove(n); + 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 ) diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 809f230c8..ce7665c41 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -54,6 +54,7 @@ extern "C" { #include <FL/Fl_Window.H> #include <FL/Fl_Tooltip.H> #include <FL/Fl_Sys_Menu_Bar.H> +#include <FL/Fl_Input_.H> #include <stdio.h> #include <stdlib.h> #include "flstring.h" @@ -1268,14 +1269,9 @@ extern "C" { - (void)windowDidMiniaturize:(NSNotification *)notif; - (void)windowWillClose:(NSNotification *)notif; - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender; -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification; @end @implementation FLDelegate -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - fl_system_menu = [NSApp mainMenu]; -} - (void)windowDidMove:(NSNotification *)notif { FLWindow *nsw = (FLWindow*)[notif object]; @@ -1882,14 +1878,14 @@ void Fl_X::make(Fl_Window* w) } else // create a desktop window { - NSAutoreleasePool *localPool; - localPool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; Fl_Group::current(0); fl_open_display(); - NSInteger winlevel = NSNormalWindowLevel; - NSUInteger winstyle; - if(w->border()) winstyle = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; - else winstyle = NSBorderlessWindowMask; + NSInteger winlevel = NSNormalWindowLevel; + NSUInteger winstyle; + if(w->border()) winstyle = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; + else winstyle = NSBorderlessWindowMask; int xp = w->x(); int yp = w->y(); int wp = w->w(); @@ -2809,11 +2805,11 @@ static void createAppleMenu(void) [menuItem setSubmenu:appleMenu]; mainmenu = [[NSMenu alloc] initWithTitle:@""]; [mainmenu addItem:menuItem]; - if(MACsystemVersion < 0x1060) { + if(MACsystemVersion < 0x1060) { // [NSApp setAppleMenu:appleMenu]; // to avoid compiler warning raised by use of undocumented setAppleMenu : - [NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu]; - } + [NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu]; + } [NSApp setServicesMenu:services]; [NSApp setMainMenu:mainmenu]; CFRelease(nsappname); @@ -2821,23 +2817,19 @@ static void createAppleMenu(void) [mainmenu release]; [appleMenu release]; [menuItem release]; + fl_system_menu = [NSApp mainMenu]; } @interface FLMenuItem : NSMenuItem { - const Fl_Menu_Item *item; } -- (void) setFlMenuItem:(const Fl_Menu_Item*)flItem; - (void) doCallback:(id)unused; - (void) directCallback:(id)unused; -- (Fl_Menu_Item*)getFlMenuItem; @end @implementation FLMenuItem -- (void) setFlMenuItem:(const Fl_Menu_Item*)flItem -{ - item = flItem; -} - (void) doCallback:(id)unused { + int flRank = [self tag]; + const Fl_Menu_Item *item = fl_sys_menu_bar->Fl_Menu_::menu() + flRank; if(item) { fl_sys_menu_bar->picked(item); if ( item->flags & FL_MENU_TOGGLE ) {// update the menu toggle symbol @@ -2847,62 +2839,45 @@ static void createAppleMenu(void) } - (void) directCallback:(id)unused { + Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes]; if( item && item->callback() ) item->do_callback(NULL); } -- (const Fl_Menu_Item*)getFlMenuItem -{ - return item; -} @end -void *MACmainMenu(void) -{ - return (void *)[NSApp mainMenu]; -} -void *MACcreateMenu(const char *name) -// to create a new top-level menu in the apple menu bar -// returns the created menu (NSMenu*) -{ - fl_open_display(); - NSMenu *mymenu; - NSMenuItem *menuItem; - CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); - mymenu = [[NSMenu alloc] initWithTitle:(NSString*)cfname]; - CFRelease(cfname); - // Put menu into the menubar - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:mymenu]; - [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; - [mymenu setAutoenablesItems:NO]; - [mymenu release]; - return (void *)mymenu; -} - -void fl_mac_set_about( const Fl_Menu_Item *flItem ) +void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut = 0) /** - * Mac OS: attaches an Fl_Menu_Item to the "About myprog" item of the system application menu. - * \note Only the shortcut_, callback_ and user_data_ fields of the Fl_Menu_Item* \p flItem are used. + * Mac OS: attaches a callback to the "About myprog" item of the system application menu. * * \author Manolo Gouy * - * \param[in] flItem is a const Fl_Menu_Item* + * \param[in] cb a callback that will be called by "About myprog" menu item + * \param[in] user_data a pointer transmitted as 2nd argument to the callback + * \param[in] shortcut optional shortcut to attach to the "About myprog" menu item (e.g., FL_META+'a') */ { + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; fl_open_display(); + Fl_Menu_Item aboutItem; + memset(&aboutItem, 0, sizeof(Fl_Menu_Item)); + aboutItem.callback(cb); + aboutItem.user_data(user_data); + aboutItem.shortcut(shortcut); CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu itemAtIndex:0] title]); [appleMenu removeItemAtIndex:0]; FLMenuItem *item = [[FLMenuItem alloc] autorelease]; [item initWithTitle:(NSString*)cfname action:@selector(directCallback:) keyEquivalent:@""]; - if(flItem->shortcut()) { - MACMenuOrItemOperation("setKeyEquivalent", item, flItem->shortcut() & 0xff); - MACMenuOrItemOperation("setKeyEquivalentModifierMask", item, flItem->shortcut() ); + if(aboutItem.shortcut()) { + MACMenuOrItemOperation("setKeyEquivalent", item, aboutItem.shortcut() & 0xff); + MACMenuOrItemOperation("setKeyEquivalentModifierMask", item, aboutItem.shortcut() ); } - [item setFlMenuItem:flItem]; + NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)]; + [item setRepresentedObject:pointer]; [appleMenu insertItem:item atIndex:0]; CFRelease(cfname); [item setTarget:item]; + [localPool release]; } static char *remove_ampersand(const char *s) @@ -2929,6 +2904,8 @@ void *MACMenuOrItemOperation(const char *operation, ...) /* these operations apply to menus, submenus, or menu items */ { + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; NSMenu *menu; NSMenuItem *item; int value; @@ -2945,7 +2922,8 @@ void *MACMenuOrItemOperation(const char *operation, ...) else if(strcmp(operation, "setKeyEquivalent") == 0) {//arguments: NSMenuItem*, int item = va_arg(ap, NSMenuItem*); value = va_arg(ap, int); - NSString *equiv = [[NSString alloc] initWithBytes:&value length:1 encoding:NSASCIIStringEncoding]; + char key = value; + NSString *equiv = [[NSString alloc] initWithBytes:&key length:1 encoding:NSASCIIStringEncoding]; [item setKeyEquivalent:equiv]; [equiv release]; } @@ -2973,7 +2951,6 @@ void *MACMenuOrItemOperation(const char *operation, ...) CFRelease(title); [menu setAutoenablesItems:NO]; retval = (void *)menu; - [menu autorelease]; } else if(strcmp(operation, "numberOfItems") == 0) {//arguments: NSMenu *menu, int *pcount //upon return, *pcount is set to menu's item count @@ -2986,6 +2963,7 @@ void *MACMenuOrItemOperation(const char *operation, ...) item = va_arg(ap, NSMenuItem*); menu = va_arg(ap, NSMenu*); [item setSubmenu:menu]; + [menu release]; } else if(strcmp(operation, "setEnabled") == 0) {//arguments: NSMenuItem*, int item = va_arg(ap, NSMenuItem*); @@ -3009,32 +2987,49 @@ void *MACMenuOrItemOperation(const char *operation, ...) value = va_arg(ap, int); [menu removeItem:[menu itemAtIndex:value]]; } - else if(strcmp(operation, "getFlMenuItem") == 0) {//arguments: NSMenu*, int. Returns the item's Fl_Menu_Item* - menu = va_arg(ap, NSMenu*); - value = va_arg(ap, int); - retval = [(FLMenuItem *)[menu itemAtIndex:value] getFlMenuItem]; - } - else if(strcmp(operation, "addNewItem") == 0) { - //arguments: NSMenu *menu, const Fl_Menu_Item* flItem, int *prank + else if(strcmp(operation, "addNewItem") == 0) {//arguments: NSMenu *menu, int flrank, int *prank //creates a new menu item at the end of 'menu' - //attaches the Fl_Menu_Item *flItem to it - //upon return, puts the rank of the new item in *prank unless prank is NULL + //attaches the item of rank flrank (counted in Fl_Menu_) of fl_sys_menu_bar to it + //upon return, puts the rank (counted in NSMenu) of the new item in *prank unless prank is NULL menu = va_arg(ap, NSMenu*); - const Fl_Menu_Item *flItem = va_arg(ap, const Fl_Menu_Item*); - char *name = remove_ampersand(flItem->label()); + int flRank = va_arg(ap, int); + char *name = remove_ampersand( (fl_sys_menu_bar->Fl_Menu_::menu() + flRank)->label()); int *prank = va_arg(ap, int*); CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); free(name); FLMenuItem *item = [FLMenuItem alloc]; [item initWithTitle:(NSString*)cfname action:@selector(doCallback:) keyEquivalent:@""]; - [item setFlMenuItem:flItem]; + [item setTag:flRank]; [menu addItem:item]; CFRelease(cfname); [item setTarget:item]; if(prank != NULL) *prank = [menu indexOfItem:item]; [item release]; + } + else if(strcmp(operation, "renameItem") == 0) {//arguments: int rank, const char *newname + //renames the system menu item numbered rank in fl_sys_menu_bar->menu() + int rank = va_arg(ap, int); + char *newname = remove_ampersand( va_arg(ap, const char *) ); + int countmenus = [(NSMenu*)fl_system_menu numberOfItems]; + bool found = NO; + NSMenuItem *macitem; + for(int i = 1; (!found) && i < countmenus; i++) { + NSMenuItem *item = [(NSMenu*)fl_system_menu itemAtIndex:i]; + NSMenu *submenu = [item submenu]; + if(submenu == nil) continue; + int countitems = [submenu numberOfItems]; + for(int j = 0; j < countitems; j++) { + macitem = [submenu itemAtIndex:j]; + if([macitem tag] == rank) { found = YES; break; } + } + } + if(found) { + [macitem setTitle:[[[NSString alloc] initWithUTF8String:newname] autorelease]]; + } + free(newname); } va_end(ap); + [localPool release]; return retval; } @@ -3043,39 +3038,24 @@ void MACsetkeywindow(void *nsw) [(NSWindow*)nsw makeKeyAndOrderFront:nil]; } -int MACpreparedrag(void) +static NSImage *imageFromText(const char *text, int *pwidth, int *pheight) { - CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[0], fl_selection_length[0]); - if (text==NULL) return false; - NSAutoreleasePool *localPool; - localPool = [[NSAutoreleasePool alloc] init]; - NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - [mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil]; - [mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"]; - CFRelease(text); - Fl_Widget *w = Fl::pushed(); - Fl_Window *win = w->window(); - while(win->window()) win = win->window(); - NSView *myview = [(NSWindow*)Fl_X::i(win)->xid contentView]; - NSEvent *theEvent = [NSApp currentEvent]; - - char *p, *q; - int width = 0, height, w2; + const char *p, *q; + int width = 0, height, w2, ltext = strlen(text); fl_font(FL_HELVETICA, 10); - fl_selection_buffer[0][ fl_selection_length[0] ] = 0; - p = fl_selection_buffer[0]; + p = text; int nl = 0; while((q=strchr(p, '\n')) != NULL) { nl++; w2 = fl_width(p, q - p); if(w2 > width) width = w2; p = q + 1; - } - if(fl_selection_buffer[0][ fl_selection_length[0] - 1] != '\n') { + } + if(text[ ltext - 1] != '\n') { nl++; w2 = fl_width(p); if(w2 > width) width = w2; - } + } height = nl * fl_height() + 3; width += 6; Fl_Offscreen off = fl_create_offscreen_with_alpha(width, height); @@ -3083,7 +3063,7 @@ int MACpreparedrag(void) CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); fl_rectf(0,0,width,height); fl_color(FL_BLACK); - p = fl_selection_buffer[0]; + p = text; int y = fl_height(); while(TRUE) { q = strchr(p, '\n'); @@ -3091,13 +3071,63 @@ int MACpreparedrag(void) else { fl_draw(p, 3, y); break; - } + } y += fl_height(); p = q + 1; - } + } + fl_end_offscreen(); + NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off ); + fl_delete_offscreen( off ); + *pwidth = width; + *pheight = height; + return image; +} + +static NSImage *defaultDragImage(int *pwidth, int *pheight) +{ + const int width = 16, height = 16; + Fl_Offscreen off = fl_create_offscreen_with_alpha(width, height); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,width,height); + CGContextSetRGBStrokeColor( (CGContextRef)off, 0,0,0,0.6); + fl_rect(0,0,width,height); + fl_rect(2,2,width-4,height-4); fl_end_offscreen(); NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off ); fl_delete_offscreen( off ); + *pwidth = width; + *pheight = height; + return image; +} + +int MACpreparedrag(void) +{ + CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[0], fl_selection_length[0]); + if (text==NULL) return false; + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + [mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil]; + [mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"]; + CFRelease(text); + Fl_Widget *w = Fl::pushed(); + Fl_Window *win = w->window(); + if(win == NULL) { win = (Fl_Window*)w; } + else { while(win->window()) win = win->window(); } + NSView *myview = [(NSWindow*)Fl_X::i(win)->xid contentView]; + NSEvent *theEvent = [NSApp currentEvent]; + + int width, height; + NSImage *image; + if( dynamic_cast<Fl_Input_*>(w) != NULL) { + fl_selection_buffer[0][ fl_selection_length[0] ] = 0; + image = imageFromText(fl_selection_buffer[0], &width, &height); + } + else { + image = defaultDragImage(&width, &height); + } + static NSSize offset={0,0}; NSPoint pt = [theEvent locationInWindow]; pt.x -= width/2; diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index d57385aed..ce1fc036f 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -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: diff --git a/src/Makefile b/src/Makefile index 01a498f3a..0aa6ed1ba 100644 --- a/src/Makefile +++ b/src/Makefile @@ -476,7 +476,7 @@ include makedepend # These dependencies aren't part of the makedepend file since # they are part of the WIN32 and MacOS code base... Fl_get_key.o: Fl_get_key_mac.cxx Fl_get_key_win32.cxx -Fl.o: Fl_mac.cxx Fl_win32.cxx +Fl.o: Fl_mac.cxx Fl_win32.cxx Fl_cocoa.mm fl_color.o: fl_color_mac.cxx fl_color_win32.cxx fl_dnd.o: fl_dnd_mac.cxx fl_dnd_win32.cxx fl_dnd_x.cxx fl_draw_image.o: fl_draw_image_mac.cxx fl_draw_image_win32.cxx @@ -492,7 +492,7 @@ Fl_Bitmap.o: ../FL/mac.H ../FL/win32.H fl_color.o: ../FL/mac.H ../FL/win32.H fl_cursor.o: ../FL/mac.H ../FL/win32.H fl_dnd.o: ../FL/mac.H ../FL/win32.H -Fl.o: ../FL/mac.H ../FL/win32.H Fl_win32.cxx Fl_mac.cxx +Fl.o: ../FL/mac.H ../FL/win32.H Fl_win32.cxx Fl_mac.cxx Fl_cocoa.mm Fl_Double_Window.o: ../FL/mac.H ../FL/win32.H fl_draw_image.o: ../FL/mac.H ../FL/win32.H fl_draw_image_mac.o: ../FL/mac.H ../FL/win32.H @@ -511,6 +511,7 @@ Fl_grab.o: ../FL/mac.H ../FL/win32.H Fl_Image.o: ../FL/mac.H ../FL/win32.H fl_line_style.o: ../FL/mac.H ../FL/win32.H Fl_mac.o: ../FL/mac.H ../FL/win32.H +Fl_cocoa.o: ../FL/mac.H ../FL/win32.H Fl_Menu_Window.o: ../FL/mac.H ../FL/win32.H fl_overlay.o: ../FL/mac.H ../FL/win32.H fl_overlay_visual.o: ../FL/mac.H ../FL/win32.H diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx index 8fdbe6b3d..a85fbc2cd 100644 --- a/src/fl_font_mac.cxx +++ b/src/fl_font_mac.cxx @@ -428,7 +428,7 @@ CGColorRef flcolortocgcolor(Fl_Color i) g = c>>16; b = c>> 8; } - CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.}; + 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 @@ -444,35 +444,35 @@ void fl_draw(const char *str, int n, float x, float y) { // 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); + 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 { + else { #endif #if ! __LP64__ OSStatus err; @@ -499,19 +499,15 @@ else { } void fl_draw(int angle, const char *str, int n, int x, int y) { -#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 -if(CTFontCreateWithName != NULL) { +#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 { -#endif -#if ! __LP64__ - OSStatus err; - // convert to UTF-16 first +#else + 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 ! @@ -526,31 +522,18 @@ else { ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr); 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 //restore layout baseline ang = IntToFixed(0); ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr); #endif -#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - } -#endif } void fl_rtl_draw(const char* c, int n, int x, int y) { -#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 -if(CTFontCreateWithName != NULL) { +#if defined(__APPLE_COCOA__) fl_draw(c, n, x - fl_width(c, n), y); //to check; - } -else { -#endif -#if ! __LP64__ - // I guess with ATSU the thing to do is force the layout mode to RTL and let ATSU draw the text... +#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 @@ -565,16 +548,7 @@ else { ATSUSetLayoutControls (layout, 2, iTag, iSize, aAttr ); err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); -#if defined(__APPLE_COCOA__) - CGContextSetShouldAntialias(fl_gc, true); -#endif err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x-offs), 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 } |
