⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fl_mac.cxx

📁 SRI international 发布的OAA框架软件
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  else if ( mods & rightControlKey ) Fl::e_keysym = FL_Control_R;
  else if ( mods & shiftKey ) Fl::e_keysym = FL_Shift_L;
  else if ( mods & rightShiftKey ) Fl::e_keysym = FL_Shift_R;
  else if ( mods & alphaLock ) Fl::e_keysym = FL_Caps_Lock;
  else Fl::e_keysym = 0;
}

/**
 * convert the keyboard return code into the symbol on the keycaps
 */
static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned short deflt )
{
  static Ptr map = 0;
  UInt32 state = 0;
  if (!map) {
    map = (Ptr)GetScriptManagerVariable(smKCHRCache);
    if (!map) {
      long kbID = GetScriptManagerVariable(smKeyScript);
      map = *GetResource('KCHR', kbID);
    }
  }
  if (map)
    return KeyTranslate(map, keyCode|mods, &state );
  return deflt;
}

/**
 * handle carbon keyboard events
 */
pascal OSStatus carbonKeyboardHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
{
  static char buffer[5];
  int sendEvent = 0;
  Fl_Window *window = (Fl_Window*)userData;
  UInt32 mods;
  static UInt32 prevMods = 0xffffffff;

  fl_lock_function();
  
  GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &mods );
  if ( prevMods == 0xffffffff ) prevMods = mods;
  UInt32 keyCode;
  GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
  unsigned char key;
  GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key );
  unsigned short sym;

  switch ( GetEventKind( event ) )
  {
  case kEventRawKeyDown:
  case kEventRawKeyRepeat:
    sendEvent = FL_KEYBOARD;
    // fall through
  case kEventRawKeyUp:
    if ( !sendEvent ) sendEvent = FL_KEYUP;
    // if the user pressed alt/option, event_key should have the keycap, but event_text should generate the international symbol
    if ( isalpha(key) )
      sym = tolower(key);
    else if ( Fl::e_state&FL_CTRL && key<32 )
      sym = key+96;
    else if ( Fl::e_state&FL_ALT )
      sym = keycode_to_sym( keyCode & 0x7f, 0, macKeyLookUp[ keyCode & 0x7f ] ); // find the keycap of this key
    else
      sym = macKeyLookUp[ keyCode & 0x7f ];
    Fl::e_keysym = sym;
    if ( keyCode==0x4c ) key=0x0d;
    if ( ( (sym>=FL_KP) && (sym<=FL_KP_Last) ) || ((sym&0xff00)==0) || (sym==FL_Tab) ) {
      buffer[0] = key;
      Fl::e_length = 1;
    } else {
      buffer[0] = 0;
      Fl::e_length = 0;
    }
    Fl::e_text = buffer;
    // insert UnicodeHandling here!
    break;
  case kEventRawKeyModifiersChanged: {
    UInt32 tMods = prevMods ^ mods;
    if ( tMods )
    {
      mods_to_e_keysym( tMods );
      if ( Fl::e_keysym ) 
        sendEvent = ( prevMods<mods ) ? FL_KEYBOARD : FL_KEYUP;
      Fl::e_length = 0;
      buffer[0] = 0;
      prevMods = mods;
    }
    mods_to_e_state( mods );
    break; }
  }
  while (window->parent()) window = window->window();
  if (sendEvent && Fl::handle(sendEvent,window)) {
    fl_unlock_function();
  
    return noErr; // return noErr if FLTK handled the event
  } else {
    fl_unlock_function();
  
    return CallNextEventHandler( nextHandler, event );;
  }
}


/**
 * initialize the Mac toolboxes and set the default menubar
 */
void fl_open_display() {
  static char beenHereDoneThat = 0;
  if ( !beenHereDoneThat )  {
    beenHereDoneThat = 1;
    
    FlushEvents(everyEvent,0);

    MoreMasters(); // \todo Carbon suggests MoreMasterPointers()
    AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false );

    // create the Mac Handle for the default cursor (a pointer to a pointer)
    GetQDGlobalsArrow(&default_cursor);
    default_cursor_ptr = &default_cursor;
    fl_default_cursor  = &default_cursor_ptr;
    
    ClearMenuBar();
    AppendResMenu( GetMenuHandle( 1 ), 'DRVR' );
    DrawMenuBar();
  }
}


/**
 * get rid of allocated resources
 */
void fl_close_display()  {
}


/**
 * smallest x ccordinate in screen space
 */
int Fl::x() {
  BitMap r;
  GetQDGlobalsScreenBits(&r);
  return r.bounds.left;
}


/**
 * smallest y ccordinate in screen space
 */
int Fl::y() {
  BitMap r;
  GetQDGlobalsScreenBits(&r);
  return r.bounds.top + 20; // \todo 20 pixel menu bar?
}


/**
 * screen width (single monitor!?)
 */
int Fl::w() {
  BitMap r;
  GetQDGlobalsScreenBits(&r);
  return r.bounds.right - r.bounds.left;
}


/**
 * screen height (single monitor!?)
 */
int Fl::h() {
  BitMap r;
  GetQDGlobalsScreenBits(&r);
  return r.bounds.bottom - r.bounds.top - 20;
}


/**
 * get the current mouse pointer world coordinates
 */
void Fl::get_mouse(int &x, int &y) 
{
  fl_open_display();
  Point loc; 
  GetMouse( &loc );
  LocalToGlobal( &loc );
  x = loc.h;
  y = loc.v;
}


/**
 * convert Mac keystrokes to FLTK
 */
unsigned short mac2fltk(ulong macKey) 
{
  unsigned short cc = macKeyLookUp[(macKey>>8)&0x7f];
  if (cc) return cc;
  return macKey&0xff;
}


/**
 * Initialize the given port for redraw and call the windw's flush() to actually draw the content
 */ 
void Fl_X::flush()
{
  w->flush();
  SetOrigin( 0, 0 );
  //QDFlushPortBuffer( GetWindowPort(xid), 0 ); // \todo do we need this?
}


/**
 * Handle all clipping and redraw for the given port
 * There are two different callers for this event:
 * 1: the OS can request a redraw and provides all clipping itself
 * 2: Fl::flush() wants all redraws now
 */    
void handleUpdateEvent( WindowPtr xid ) 
{
  Fl_Window *window = fl_find( xid );
  if ( !window ) return;
  GrafPtr oldPort;
  GetPort( &oldPort );
  SetPort( GetWindowPort(xid) );
  Fl_X *i = Fl_X::i( window );
  i->wait_for_expose = 0;
  if ( window->damage() ) {
    if ( i->region ) {
      InvalWindowRgn( xid, i->region );
    }
  }
  if ( i->region ) { // no region, so the sytem will take the update region from the OS
    DisposeRgn( i->region );
    i->region = 0;
  }
  for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext )
  {
    cx->w->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
    cx->flush();
    cx->w->clear_damage();
  }
  window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
  i->flush();
  window->clear_damage();
  SetPort( oldPort );
}     


/**
 * \todo this is a leftover from OS9 times. Please check how much applies to Carbon!
 */
int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
  int W, H, xoff, yoff, dx, dy;
  int ret = bx = by = bt = 0;
  if (w->border() && !w->parent()) {
    if (w->maxw != w->minw || w->maxh != w->minh) {
      ret = 2;
      bx = 6; // \todo Mac : GetSystemMetrics(SM_CXSIZEFRAME);
      by = 6; // \todo Mac : get Mac window frame size GetSystemMetrics(SM_CYSIZEFRAME);
    } else {
      ret = 1;
      bx = 6; // \todo Mac : GetSystemMetrics(SM_CXFIXEDFRAME);
      by = 6; // \todo Mac : GetSystemMetrics(SM_CYFIXEDFRAME);
    }
    bt = 22; // \todo Mac : GetSystemMetrics(SM_CYCAPTION);
  }
  //The coordinates of the whole window, including non-client area
  xoff = bx;
  yoff = by + bt;
  dx = 2*bx;
  dy = 2*by + bt;
  X = w->x()-xoff;
  Y = w->y()-yoff;
  W = w->w()+dx;
  H = w->h()+dy;

  //Proceed to positioning the window fully inside the screen, if possible
  //Make border's lower right corner visible
  if (Fl::w() < X+W) X = Fl::w() - W;
  if (Fl::h() < Y+H) Y = Fl::h() - H;
  //Make border's upper left corner visible
  if (X<0) X = 0;
  if (Y<0) Y = 0;
  //Make client area's lower right corner visible
  if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx;
  if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy;
  //Make client area's upper left corner visible
  if (X+xoff < 0) X = -xoff;
  if (Y+yoff < 0) Y = -yoff;
  //Return the client area's top left corner in (X,Y)
  X+=xoff;
  Y+=yoff;

  return ret;
}

/**
 * convert a Mac FSSpec structure into a Unix filename 
 */
static int FSSpec2UnixPath( FSSpec *fs, char *dst )
{
  FSRef fsRef;
  FSpMakeFSRef( fs, &fsRef );
  FSRefMakePath( &fsRef, (UInt8*)dst, 1024 );
  return strlen(dst);
/* keep the code below. The above function is only implemented in OS X, so we might need the other code for OS 9 and friends
  short offset = 0;
  if ( fs->parID != fsRtParID )
  {
    FSSpec parent;
    OSErr ret = FSMakeFSSpec( fs->vRefNum, fs->parID, 0, &parent );
    if ( ret != noErr ) return 0;
    offset = FSSpec2UnixPath( &parent, dst );
  }

  if ( fs->parID == fsRtParID && fs->vRefNum == -100 ) //+ bad hack: we assume that volume -100 is mounted as root
  {
    memcpy( dst, "/", 2 );
    return 1; // don't add anything to the filename - we are fine already
  }

  short len = fs->name[0];
  if ( fs->parID == fsRtParID ) { // assume tat all other volumes are in this directory (international name WILL vary!)
    memcpy( dst, "/Volumes", 8 );
    offset = 8;
  }
  
  if ( offset!=1 ) dst[ offset++ ] = '/'; // avoid double '/'
  memcpy( dst+offset, fs->name+1, len );
  dst[ len+offset ] = 0;
  return len+offset;
*/
}
 
Fl_Window *fl_dnd_target_window = 0;
#include <FL/fl_draw.H>
/**
 * Drag'n'drop tracking handler
 */
static pascal OSErr dndTrackingHandler( DragTrackingMessage msg, WindowPtr w, void *userData, DragReference dragRef )
{
  Fl_Window *target = (Fl_Window*)userData;
  Point mp;
  static int px, py;
  
  switch ( msg )
  {
  case kDragTrackingEnterWindow:
    // check if 'TEXT' is available
    GetDragMouse( dragRef, &mp, 0 );
    Fl::e_x_root = px = mp.h;
    Fl::e_y_root = py = mp.v;
    Fl::e_x = px - target->x();
    Fl::e_y = py - target->y();
    fl_dnd_target_window = target;
    if ( Fl::handle( FL_DND_ENTER, target ) )
      fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
    else
      fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
    breakMacEventLoop();
    return noErr;
  case kDragTrackingInWindow:
    GetDragMouse( dragRef, &mp, 0 );
    if ( mp.h==px && mp.v==py )
      break;	//+ return previous condition for dnd hiliting
    Fl::e_x_root = px = mp.h;
    Fl::e_y_root = py = mp.v;
    Fl::e_x = px - target->x();
    Fl::e_y = py - target->y();
    fl_dnd_target_window = target;
    if ( Fl::handle( FL_DND_DRAG, target ) )
      fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
    else
      fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
    breakMacEventLoop();
    return noErr;
    break;
  case kDragTrackingLeaveWindow:
    // HideDragHilite()
    fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
    if ( fl_dnd_target_window )
    {
      Fl::handle( FL_DND_LEAVE, fl_dnd_target_window );
      fl_dnd_target_window = 0;
    }
    breakMacEventLoop();
    return noErr;
  }
  return noErr;
}


/**
 * Drag'n'drop receive handler
 */
static pascal OSErr dndReceiveHandler( WindowPtr w, void *userData, DragReference dragRef )
{
  Point mp;
  OSErr ret;
  
  Fl_Window *target = fl_dnd_target_window = (Fl_Window*)userData;
  GetDragMouse( dragRef, &mp, 0 );
  Fl::e_x_root = mp.h;
  Fl::e_y_root = mp.v;
  Fl::e_x = Fl::e_x_root - target->x();
  Fl::e_y = Fl::e_y_root - target->y();
  if ( !Fl::handle( FL_DND_RELEASE, target ) )
    return userCanceledErr;
    
  // get the ASCII text
  UInt16 i, nItem;
  ItemReference itemRef;
  FlavorFlags flags;
  Size itemSize, size = 0;
  CountDragItems( dragRef, &nItem );
  for ( i = 1; i <= nItem; i++ )
  {
    GetDragItemReferenceNumber( dragRef, i, &itemRef );
    ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags );
    if ( ret == noErr )
    {
      GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize );
      size += itemSize;
    }
    ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags );
    if ( ret == noErr )
    {
      size += 1024; //++ ouch! We should create the full pathname and figure out its length
    }
  }
  
  if ( !size )
    return userCanceledErr;
  
  Fl::e_length = size + nItem - 1;
  char *dst = Fl::e_text = (char*)malloc( size+nItem );;
  
  for ( i = 1; i <= nItem; i++ )
  {
    GetDragItemReferenceNumber( dragRef, i, &itemRef );
    ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -