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

📄 fl_mac.cxx

📁 SRI international 发布的OAA框架软件
💻 CXX
📖 第 1 页 / 共 4 页
字号:
    if ( ret == noErr )
    {
      GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize );
      GetFlavorData( dragRef, itemRef, 'TEXT', dst, &itemSize, 0L );
      dst += itemSize;
      *dst++ = '\n'; // add our element seperator
    }
    ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags );
    if ( ret == noErr )
    {
      HFSFlavor hfs; itemSize = sizeof( hfs );
      GetFlavorData( dragRef, itemRef, 'hfs ', &hfs, &itemSize, 0L );
      itemSize = FSSpec2UnixPath( &hfs.fileSpec, dst );
      dst += itemSize;
      if ( itemSize>1 && ( hfs.fileType=='fold' || hfs.fileType=='disk' ) ) 
        *dst++ = '/';
      *dst++ = '\n'; // add our element seperator
    }
  }
  
  dst[-1] = 0;
//  if ( Fl::e_text[Fl::e_length-1]==0 ) Fl::e_length--; // modify, if trailing 0 is part of string
  Fl::e_length = dst - Fl::e_text - 1;
  target->handle(FL_PASTE);
  free( Fl::e_text );
  
  fl_dnd_target_window = 0L;
  breakMacEventLoop();
  return noErr;
}


/**
 * go ahead, create that (sub)window
 * \todo we should make menu windows slightly transparent for the new Mac look
 */
void Fl_X::make(Fl_Window* w)
{
  static int xyPos = 50;
  if ( w->parent() ) // create a subwindow
  {
    Fl_Group::current(0);
    Rect wRect;
    wRect.top    = w->y();
    wRect.left   = w->x();
    wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1;
    wRect.right  = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1;
    // our subwindow needs this structure to know about its clipping. 
    Fl_X* x = new Fl_X;
    x->other_xid = 0;
    x->region = 0;
    x->subRegion = 0;
    x->cursor = fl_default_cursor;
    Fl_Window *win = w->window();
    Fl_X *xo = Fl_X::i(win);
    x->xidNext = xo->xidChildren;
    x->xidChildren = 0L;
    xo->xidChildren = x;
    x->xid = fl_xid(win);
    x->w = w; w->i = x;
    x->wait_for_expose = 0;
    x->next = Fl_X::first; // must be in the list for ::flush()
    Fl_X::first = x;
    w->set_visible();
    w->handle(FL_SHOW);
    w->redraw(); // force draw to happen
    fl_show_iconic = 0;
  }
  else // create a desktop window
  {
    Fl_Group::current(0);
    fl_open_display();
    int winclass = kDocumentWindowClass;
    int winattr = kWindowStandardHandlerAttribute | kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute;
    int xp = w->x();
    int yp = w->y();
    int wp = w->w();
    int hp = w->h();
    if (w->size_range_set) {
      if ( w->minh != w->maxh || w->minw != w->maxw)
        winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute;
    } else {
      if (w->resizable()) {
        Fl_Widget *o = w->resizable();
        int minw = o->w(); if (minw > 100) minw = 100;
        int minh = o->h(); if (minh > 100) minh = 100;
        w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
        winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute;
      } else {
        w->size_range(w->w(), w->h(), w->w(), w->h());
      }
    }
    int xwm = xp, ywm = yp, bt, bx, by;
    if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) 
      { winclass = kHelpWindowClass; winattr = 0; } // menu windows and tooltips
    else if (w->modal())
      winclass = kMovableModalWindowClass;
    if (by+bt) {
      wp += 2*bx;
      hp += 2*by+bt;
    }
    if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) {
      w->x(xyPos+Fl::x()); w->y(xyPos+Fl::y()); // use the Carbon functions below for default window positioning
      xyPos += 25;
      if (xyPos>200) xyPos = 25;
    } else {
      if (!Fl::grab()) {
        xp = xwm; yp = ywm;
        w->x(xp);w->y(yp);
      }
      xp -= bx;
      yp -= by+bt;
    }

    if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) {
      // find some other window to be "transient for":
      Fl_Window* w = Fl_X::first->w;
      while (w->parent()) w = w->window(); // todo: this code does not make any sense! (w!=w??)
    }

    Rect wRect;
    wRect.top    = w->y();
    wRect.left   = w->x();
    wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1;
    wRect.right  = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1;

    const char *name = w->label();
    Str255 pTitle; 
    if (name) { pTitle[0] = strlen(name); memcpy(pTitle+1, name, pTitle[0]); }
    else pTitle[0]=0;

    Fl_X* x = new Fl_X;
    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->xidChildren = 0;
    x->xidNext = 0;

    winattr &= GetAvailableWindowAttributes( winclass );	// make sure that the window will open
    CreateNewWindow( winclass, winattr, &wRect, &(x->xid) );
    SetWTitle(x->xid, pTitle);
    MoveWindow(x->xid, wRect.left, wRect.top, 1);	// avoid Carbon Bug on old OS
    if (w->non_modal() && !w->modal())
      SetWindowClass(x->xid, kFloatingWindowClass );	// Major kludge: this is to have the regular look, but stay above the document windows
    if (!(w->flags() & Fl_Window::FL_FORCE_POSITION))
    {
      WindowRef pw = Fl_X::first ? Fl_X::first->xid : 0 ;
      if ( w->modal() )
        RepositionWindow( x->xid, pw, kWindowAlertPositionOnParentWindowScreen );
      else if ( w->non_modal() )
        RepositionWindow( x->xid, pw, kWindowCenterOnParentWindowScreen );
      else
        RepositionWindow( x->xid, pw, kWindowCascadeOnParentWindowScreen );
    }
    x->w = w; w->i = x;
    x->wait_for_expose = 1;
    x->next = Fl_X::first;
    Fl_X::first = x;
    if (w->resizable()) DrawGrowIcon(x->xid);
    w->set_visible();
    { // Install Carbon Event handlers 
      OSStatus ret;
      EventHandlerUPP mousewheelHandler = NewEventHandlerUPP( carbonMousewheelHandler ); // will not be disposed by Carbon...
      static EventTypeSpec mousewheelEvents[] = {
        { kEventClassMouse, kEventMouseWheelMoved } };
      ret = InstallWindowEventHandler( x->xid, mousewheelHandler, 1, mousewheelEvents, w, 0L );
      EventHandlerUPP mouseHandler = NewEventHandlerUPP( carbonMouseHandler ); // will not be disposed by Carbon...
      static EventTypeSpec mouseEvents[] = {
        { kEventClassMouse, kEventMouseDown },
        { kEventClassMouse, kEventMouseUp },
        { kEventClassMouse, kEventMouseMoved },
        { kEventClassMouse, kEventMouseDragged } };
      ret = InstallWindowEventHandler( x->xid, mouseHandler, 4, mouseEvents, w, 0L );
      EventHandlerUPP keyboardHandler = NewEventHandlerUPP( carbonKeyboardHandler ); // will not be disposed by Carbon...
      static EventTypeSpec keyboardEvents[] = {
        { kEventClassKeyboard, kEventRawKeyDown },
        { kEventClassKeyboard, kEventRawKeyRepeat },
        { kEventClassKeyboard, kEventRawKeyUp },
        { kEventClassKeyboard, kEventRawKeyModifiersChanged } };
      ret = InstallWindowEventHandler( x->xid, keyboardHandler, 4, keyboardEvents, w, 0L );
      EventHandlerUPP windowHandler = NewEventHandlerUPP( carbonWindowHandler ); // will not be disposed by Carbon...
      static EventTypeSpec windowEvents[] = {
        { kEventClassWindow, kEventWindowDrawContent },
        { kEventClassWindow, kEventWindowShown },
        { kEventClassWindow, kEventWindowHidden },
        { kEventClassWindow, kEventWindowActivated },
        { kEventClassWindow, kEventWindowDeactivated },
        { kEventClassWindow, kEventWindowClose },
        { kEventClassWindow, kEventWindowBoundsChanged } };
      ret = InstallWindowEventHandler( x->xid, windowHandler, 7, windowEvents, w, 0L );
      ret = InstallTrackingHandler( dndTrackingHandler, x->xid, w );
      ret = InstallReceiveHandler( dndReceiveHandler, x->xid, w );
    }

    if ( ! Fl_X::first->next ) // if this is the first window, we need to bring the application to the front
    { 
      ProcessSerialNumber psn;
      OSErr err = GetCurrentProcess( &psn );
      if ( err==noErr ) SetFrontProcess( &psn );
    }
    
    if (fl_show_iconic) { 
      fl_show_iconic = 0;
      CollapseWindow( x->xid, true ); // \todo Mac ; untested
    } else if (winclass != kHelpWindowClass) {
      Fl_Tooltip::enter(0);
    }

    ShowWindow(x->xid);

    w->handle(FL_SHOW);
    w->redraw(); // force draw to happen
    w->set_visible();
    
    if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); }
  }
}


/**
 * this is a leftover from X Windows
 */
void Fl_Window::size_range_() {
  size_range_set = 1;
}


/**
 * returns pointer to the filename, or null if name ends with ':'
 */
const char *fl_filename_name( const char *name ) 
{
  const char *p, *q;
  if (!name) return (0);
  for ( p = q = name ; *p ; ) 
  {
    if ( ( p[0] == ':' ) && ( p[1] == ':' ) ) 
    {
      q = p+2;
      p++;
    }
    else if (p[0] == '/')
      q = p + 1;
    p++;
  }
  return q;
}


/**
 * set the window title bar
 * \todo make the titlebar icon work!
 */
void Fl_Window::label(const char *name,const char */*iname*/) {
  Fl_Widget::label(name);
  Str255 pTitle;

  if (name) { pTitle[0] = strlen(name); memcpy(pTitle+1, name, pTitle[0]); }
  else pTitle[0] = 0;

  if (shown() || i) SetWTitle(fl_xid(this), pTitle);
}


/**
 * make a window visible
 */
void Fl_Window::show() {
  image(Fl::scheme_bg_);
  if (Fl::scheme_bg_) {
    labeltype(FL_NORMAL_LABEL);
    align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
  } else {
    labeltype(FL_NO_LABEL);
  }
  if (!shown() || !i) {
    Fl_X::make(this);
  } else {
      if ( !parent() )
      {
        if ( IsWindowCollapsed( i->xid ) ) CollapseWindow( i->xid, false );
        if (!fl_capture) {
          BringToFront(i->xid);
          SelectWindow(i->xid);
        }
      }
  }
}


/**
 * resize a window
 */
void Fl_Window::resize(int X,int Y,int W,int H) {
  int is_a_resize = (W != w() || H != h());
  if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION);
  else if (!is_a_resize) return;
  if ( (resize_from_system!=this) && (!parent()) && shown()) {
    MoveWindow(i->xid, X, Y, 0);
    if (is_a_resize) {
      SizeWindow(i->xid, W>0 ? W : 1, H>0 ? H : 1, 1);
      Rect all; all.top=-32000; all.bottom=32000; all.left=-32000; all.right=32000;
      InvalWindowRect( i->xid, &all );    
    }
  } else if (resize_from_system == this && size_range_set && !parent() && shown()) {
    if (size_range_set) {
      if (W < minw) W = minw;
      else if (W > maxw && maxw) W = maxw;
      if (H < minh) H = minh;
      else if (H > maxh && maxh) H = maxh;
    }
    SizeWindow(i->xid, W>0 ? W : 1, H>0 ? H : 1, 1);
  }
  resize_from_system = 0;
  if (is_a_resize) {
    Fl_Group::resize(X,Y,W,H);
    if (shown()) { redraw(); if (!parent()) i->wait_for_expose = 1; }
  } else {
    x(X); y(Y); 
  }
}


/**
 * make all drawing go into this window (called by subclass flush() impl.)
 */
void Fl_Window::make_current() 
{
  if ( !fl_window_region )
    fl_window_region = NewRgn();
  fl_window = i->xid;
  current_ = this;

  SetPort( GetWindowPort(i->xid) ); // \todo check for the handling of doublebuffered windows

  int xp = 0, yp = 0;
  Fl_Window *win = this;
  while ( win ) 
  {
    if ( !win->window() )
      break;
    xp += win->x();
    yp += win->y();
    win = (Fl_Window*)win->window();
  }
  SetOrigin( -xp, -yp );
  
  SetRectRgn( fl_window_region, 0, 0, w(), h() );
  
  // \todo for performance reasons: we don't have to create this unless the child windows moved
  for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext )
  {
    Fl_Region r = NewRgn();
    Fl_Window *cw = cx->w;
    SetRectRgn( r, cw->x() - xp, cw->y() - yp, 
                   cw->x() + cw->w() - xp, cw->y() + cw->h() - yp );
    DiffRgn( fl_window_region, r, fl_window_region );
    DisposeRgn( r );
  }
  
  fl_clip_region( 0 );
  SetPortClipRegion( GetWindowPort(i->xid), fl_window_region );
  return;
}

////////////////////////////////////////////////////////////////
// Cut & paste.

Fl_Widget *fl_selection_requestor = 0;
char *fl_selection_buffer[2];
int fl_selection_length[2];
int fl_selection_buffer_length[2];
static ScrapRef myScrap = 0;

/**
 * create a selection
 * owner: widget that created the selection
 * stuff: pointer to selected data
 * size of selected data
 */
void Fl::copy(const char *stuff, int len, int clipboard) {
  if (!stuff || len<0) return;
  if (len+1 > fl_selection_buffer_length[clipboard]) {
    delete[] fl_selection_buffer[clipboard];
    fl_selection_buffer[clipboard] = new char[len+100];
    fl_selection_buffer_length[clipboard] = len+100;
  }
  memcpy(fl_selection_buffer[clipboard], stuff, len);
  fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
  fl_selection_length[clipboard] = len;
  if (clipboard) {
    ClearCurrentScrap();
    OSStatus ret = GetCurrentScrap( &myScrap );
    if ( ret != noErr ) {
      myScrap = 0;
      return;
    }
    // Previous version changed \n to \r before sending the text, but I would
    // prefer to leave the local buffer alone, so a copied buffer may be
    // needed. Check to see if this is necessary on OS/X.
    PutScrapFlavor( myScrap, kScrapFlavorTypeText, 0,
		    len, fl_selection_buffer[1] );
  }
}

// Call this when a "paste" operation happens:
void Fl::paste(Fl_Widget &receiver, int clipboard) {
  if (clipboard) {
    // see if we own the selection, if not go get it:
    ScrapRef scrap = 0;
    Size len = 0;
    if (GetCurrentScrap(&scrap) == noErr && scrap != myScrap &&
	GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &len) == noErr) {
      if ( len > fl_selection_buffer_length[1] ) {
	fl_selection_buffer_length[1] = len + 32;
	delete[] fl_selection_buffer[1];
	fl_selection_buffer[1] = new char[len];
      }
      GetScrapFlavorData( scrap, kScrapFlavorTypeText, &len,
			  fl_selection_buffer[1] );
      fl_selection_length[1] = len;
      // turn all \r characters into \n:
      for (int x = 0; x < len; x++) {
	if (fl_selection_buffer[1][x] == '\r')
	  fl_selection_buffer[1][x] = '\n';
      }
    }
  }
  Fl::e_text = fl_selection_buffer[clipboard];
  Fl::e_length = fl_selection_length[clipboard];
  receiver.handle(FL_PASTE);
  return;
}


//
// End of "$Id: Fl_mac.cxx,v 1.1.1.1 2003/06/03 22:25:45 agno Exp $".
//

⌨️ 快捷键说明

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