diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/desktop/source/splash/splash.cxx ooo_SRC680_m225_src.aquavcl03/desktop/source/splash/splash.cxx --- ooo_SRC680_m225_src.orig/desktop/source/splash/splash.cxx 2007-07-05 11:25:34.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/desktop/source/splash/splash.cxx 2007-08-20 12:44:53.000000000 +0200 @@ -57,6 +57,9 @@ #ifndef _SV_SVAPP_HXX #include #endif +#ifndef _SV_NATIVEWIDGETS_HXX +#include +#endif #include #include @@ -624,16 +627,47 @@ // draw progress... long length = (_iProgress * _barwidth / _iMax) - (2 * _barspace); if (length < 0) length = 0; - + + //native drawing + BOOL bNativeOK = FALSE; + + if( IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) ) + { + //TO DO: add support for mbProgressNeedsErase + //bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase; + + ImplControlValue aValue( _iProgress * _barwidth / _iMax); + Rectangle aDrawRect( Point(_tlx, _tly), Size( _barwidth, _barheight ) ); + Region aControlRegion( aDrawRect ); + Region aNativeControlRegion, aNativeContentRegion; + + if( GetNativeControlRegion( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aControlRegion, + CTRL_STATE_ENABLED, aValue, rtl::OUString(), + aNativeControlRegion, aNativeContentRegion ) ) + { + long nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight(); + aDrawRect.Top() -= (nProgressHeight - _barheight)/2; + aDrawRect.Bottom() += (nProgressHeight - _barheight)/2; + aControlRegion = Region( aDrawRect ); + } + + if( (bNativeOK = DrawNativeControl( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aControlRegion, + CTRL_STATE_ENABLED, aValue, rtl::OUString() )) != FALSE ) + { + return; + } + } + //non native drawing // border _vdev.SetFillColor(); - _vdev.SetLineColor( _cProgressFrameColor ); - _vdev.DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight)); - _vdev.SetFillColor( _cProgressBarColor ); + _vdev.SetLineColor( _cProgressFrameColor ); + _vdev.DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight)); + _vdev.SetFillColor( _cProgressBarColor ); _vdev.SetLineColor(); - Rectangle aRect(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace); + Rectangle aRect(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace); _vdev.DrawRect(Rectangle(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace)); + } Size aSize = GetOutputSizePixel(); Size bSize = _vdev.GetOutputSizePixel(); diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/Info.plist ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/Info.plist --- ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/Info.plist 2007-08-03 15:56:59.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/Info.plist 2007-08-07 14:38:21.000000000 +0200 @@ -521,6 +521,8 @@ OOo2 LSRequiresCarbon 1 + NSPrincipalClass + VCL_NSApplication diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/MainMenu.nib/classes.nib ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/MainMenu.nib/classes.nib --- ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/MainMenu.nib/classes.nib 1970-01-01 01:00:00.000000000 +0100 +++ ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/MainMenu.nib/classes.nib 2007-08-08 11:52:58.000000000 +0200 @@ -0,0 +1,4 @@ +{ + IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); + IBVersion = 1; +} \ No newline at end of file diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/MainMenu.nib/info.nib ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/MainMenu.nib/info.nib --- ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/MainMenu.nib/info.nib 1970-01-01 01:00:00.000000000 +0100 +++ ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/MainMenu.nib/info.nib 2007-08-08 18:08:18.000000000 +0200 @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 135 107 356 240 0 0 1680 1028 + IBEditorPositions + + 29 + 132 352 141 44 0 0 1680 1028 + + IBFramework Version + 446.1 + IBOpenObjects + + 29 + + IBSystem Version + 8R2218 + + Binary files ooo_SRC680_m225_src.orig/instsetoo_native/macosx/application/MainMenu.nib/keyedobjects.nib and ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/application/MainMenu.nib/keyedobjects.nib differ diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/instsetoo_native/macosx/makefile.mk ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/makefile.mk --- ooo_SRC680_m225_src.orig/instsetoo_native/macosx/makefile.mk 2007-06-05 13:51:39.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/instsetoo_native/macosx/makefile.mk 2007-08-08 11:52:58.000000000 +0200 @@ -57,7 +57,12 @@ $(CONTENTS)$/Resources$/Scripts$/main.scpt \ $(CONTENTS)$/Resources$/Scripts$/PostInstall.scpt -plistfiles = $(CONTENTS)$/Info.plist +plistfiles = $(CONTENTS)$/Info.plist + +nibfiles = \ + $(CONTENTS)$/Resources$/MainMenu.nib$/classes.nib \ + $(CONTENTS)$/Resources$/MainMenu.nib$/info.nib \ + $(CONTENTS)$/Resources$/MainMenu.nib$/keyedobjects.nib ZIPFLAGS = -r ZIP1TARGET = osxbundle @@ -76,7 +81,7 @@ .INCLUDE : target.mk -$(ZIP1TARGETN) : $(scriptfiles) $(plistfiles) +$(ZIP1TARGETN) : $(scriptfiles) $(plistfiles) $(nibfiles) $(plistfiles) : $(scriptfiles) @@ -99,6 +104,11 @@ make_versioned.sh "$<" "$(VERSIONED)/$<" sed "s|\%BUNDLEEXECUTABLE|${BUNDLEEXECUTABLE}|g" "$(VERSIONED)/$<" > "$@" +# nibs are just copied +$(CONTENTS)$/Resources$/MainMenu.nib$/%.nib: application/MainMenu.nib$/%.nib + $(MKDIRHIER) $(@:d) + $(COPY) "$<" "$@" + # The InfoPlist.strings file has to be in UTF-16, thus a back-and-forth conversion # is needed for versioning # diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/solenv/inc/unxmacx.mk ooo_SRC680_m225_src.aquavcl03/solenv/inc/unxmacx.mk --- ooo_SRC680_m225_src.orig/solenv/inc/unxmacx.mk 2007-08-03 15:55:43.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/solenv/inc/unxmacx.mk 2007-08-07 12:29:54.000000000 +0200 @@ -110,6 +110,7 @@ # Normal C++ compilation flags CFLAGSCXX=-pipe -malign-natural -fsigned-char -Wno-long-double $(ARCH_FLAGS) CFLAGSCXX+= -Wno-ctor-dtor-privacy + PICSWITCH:=-fPIC # Other flags CFLAGSOBJGUIMT=$(PICSWITCH) -fno-common @@ -231,9 +232,9 @@ .IF "$(GUIBASE)" == "aqua" STDLIBCUIMT=CPPRUNTIME -lm - STDLIBGUIMT=-framework Carbon -lpthread CPPRUNTIME -lm + STDLIBGUIMT=-framework Carbon -framework Cocoa -lpthread CPPRUNTIME -lm STDSHLCUIMT=-lpthread CPPRUNTIME -lm - STDSHLGUIMT=-framework Carbon -framework CoreFoundation -lpthread CPPRUNTIME -lm + STDSHLGUIMT=-framework Carbon -framework CoreFoundation -framework Cocoa -lpthread CPPRUNTIME -lm PSPLIB=-lpsp .ELSE STDLIBCUIMT= CPPRUNTIME -lm diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/svtools/source/contnr/svimpbox.cxx ooo_SRC680_m225_src.aquavcl03/svtools/source/contnr/svimpbox.cxx --- ooo_SRC680_m225_src.orig/svtools/source/contnr/svimpbox.cxx 2007-07-18 10:52:26.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/svtools/source/contnr/svimpbox.cxx 2007-08-23 14:29:58.000000000 +0200 @@ -40,6 +40,10 @@ #include #endif +#ifndef _SV_NATIVEWIDGETS_HXX +#include +#endif + #ifndef _HELP_HXX #include #endif @@ -1094,6 +1098,21 @@ if( pView->GetVisibleCount() < 2 && !pStartEntry->HasChildsOnDemand() && !pStartEntry->HasChilds() ) return; + + //for platforms who don't have nets, DrawNativeControl does nothing and return true + //so that SvImpLBox::DrawNet() doesn't draw anything too + if(pView->IsNativeControlSupported( CTRL_LISTNET, PART_ENTIRE_CONTROL)) { + ImplControlValue aControlValue; + Region aCtrlRegion( Rectangle(Point( 0, 0 ), Size( 0, 0 )) ); + ControlState nState = CTRL_STATE_ENABLED; + if( pView->DrawNativeControl( CTRL_LISTNET, PART_ENTIRE_CONTROL, + aCtrlRegion, nState, aControlValue, rtl::OUString() ) ) + { + return; + } + + } + long nEntryHeight = pView->GetEntryHeight(); long nEntryHeightDIV2 = nEntryHeight / 2; if( nEntryHeightDIV2 && !(nEntryHeight & 0x0001)) diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/svtools/source/contnr/svtreebx.cxx ooo_SRC680_m225_src.aquavcl03/svtools/source/contnr/svtreebx.cxx --- ooo_SRC680_m225_src.orig/svtools/source/contnr/svtreebx.cxx 2007-06-27 23:21:40.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/svtools/source/contnr/svtreebx.cxx 2007-08-23 14:29:58.000000000 +0200 @@ -1824,7 +1824,37 @@ USHORT nStyle = 0; if ( !IsEnabled() ) nStyle |= IMAGE_DRAW_DISABLE; - DrawImage( aPos, *pImg ,nStyle); + + //native + BOOL bNativeOK = FALSE; + if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) ) + { + ImplControlValue aControlValue; + Region aCtrlRegion( Rectangle(aPos, pImg->GetSizePixel() ) ); + ControlState nState = 0; + + if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; + + if ( IsExpanded(pEntry) ) + aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node + else + { + if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() && + (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) && + pImp->GetDontKnowNodeBmp().GetSizePixel().Width() ) + aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW );//dont know + else + aControlValue.setTristateVal( BUTTONVALUE_OFF );//collapsed node + } + + bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, + aCtrlRegion, nState, aControlValue, rtl::OUString() ); + } + + if( !bNativeOK) { + //non native + DrawImage( aPos, *pImg ,nStyle); + } } } } diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/aquavclevents.hxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/aquavclevents.hxx --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/aquavclevents.hxx 2007-07-05 10:09:39.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/aquavclevents.hxx 2007-08-08 11:27:49.000000000 +0200 @@ -1,3 +1,37 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * + * $Revision$ + * + * last change: $Author$ $Date$ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ #ifndef INCLUDED_AQUAVCLEVENTS_HXX #define INCLUDED_AQUAVCLEVENTS_HXX diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/aquavcltypes.h ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/aquavcltypes.h --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/aquavcltypes.h 2007-07-05 10:09:51.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/aquavcltypes.h 2007-08-08 11:27:49.000000000 +0200 @@ -1,8 +1,45 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * + * $Revision$ + * + * last change: $Author$ $Date$ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + #ifndef _AQUAVCLTYPES_H #define _AQUAVCLTYPES_H #include #include +#import +#import #include typedef WindowRef CarbonWindowRef; diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/saldata.hxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/saldata.hxx --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/saldata.hxx 2007-08-03 15:58:06.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/saldata.hxx 2007-08-07 16:44:33.000000000 +0200 @@ -38,7 +38,7 @@ #define _SV_SALDATA_HXX #include -#include +#include #include @@ -61,7 +61,7 @@ #include -class SalInstance; +class AquaSalInstance; class SalObject; class SalFrame; class SalVirtualDevice; @@ -89,7 +89,7 @@ { SALTIMERPROC mpTimerProc; // timer callback proc - SalInstance *mpFirstInstance; // pointer of first instance + AquaSalInstance *mpFirstInstance; // pointer of first instance std::list maFrames; // pointer of first frame std::hash_set maFrameCheck; // for fast check of frame existance SalObject *mpFirstObject; // pointer of first object window @@ -100,16 +100,6 @@ CGColorSpaceRef mxRGBSpace; CGColorSpaceRef mxGraySpace; - /* - * SalTimer related members - */ - BOOL mbInTimerProc; // timer event is currently being dispatched - BOOL mbTimerInstalled; // timer is in the event loop - ULONG mnTimerMS; // Current Time (in MS) of the Timer - ULONG mnTimerOrgMS; // Current Original Time (in MS) - - EventLoopTimerRef mrTimerRef; - EventLoopTimerUPP mrTimerUPP; static FILE *s_pLog; SalData() : @@ -120,13 +110,7 @@ mpFirstPrinter( NULL ), mpFontList( NULL ), mxRGBSpace( CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB) ), - mxGraySpace( CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) ), - mbInTimerProc( FALSE ), - mbTimerInstalled( FALSE ), - mnTimerMS( 0 ), - mnTimerOrgMS( 0 ), - mrTimerRef( 0 ), - mrTimerUPP( 0 ) + mxGraySpace( CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) ) {} ~SalData() diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/salframe.h ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salframe.h --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/salframe.h 2007-07-27 09:42:47.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salframe.h 2007-08-08 11:27:49.000000000 +0200 @@ -36,19 +36,15 @@ #ifndef _SV_SALFRAME_H #define _SV_SALFRAME_H -#include -#include +#include "vcl/sv.h" +#include "vcl/salframe.hxx" +#include "vcl/sysdata.hxx" + +#include "salmenu.h" +#include "saldata.hxx" +#include "aquavcltypes.h" -#ifndef _SV_SV_H -#include -#endif - -#ifndef _SV_SYSDATA_HXX -#include -#endif - -#include #include #include #include @@ -57,6 +53,7 @@ class AquaSalFrame; class AquaSalTimer; class AquaSalInstance; +class AquaSalMenu; typedef struct SalFrame::SalPointerState SalPointerState; @@ -67,31 +64,33 @@ class AquaSalFrame : public SalFrame { public: - CarbonWindowRef mrWindow; // Window handle + NSWindow* mpWindow; // Cocoa window + NSView* mpView; // Cocoa view (actually a custom view, see below + NSMenuItem* mpDockMenuEntry; // entry in the dynamic dock menu + NSRect maScreenRect; // for mirroring purposes AquaSalGraphics* mpGraphics; // current frame graphics AquaSalFrame* mpParent; // pointer to parent frame - void* mpInst; // instance handle for callback SystemEnvData maSysData; // system data - long mnWidth; // client width in pixels - long mnHeight; // client height in pixels int mnMinWidth; // min. client width in pixels int mnMinHeight; // min. client height in pixels int mnMaxWidth; // max. client width in pixels int mnMaxHeight; // max. client height in pixels - Rect maFullScreenRect; // old window size when in FullScreen - WindowAttributes maFullScreenAttr; // old window attributes when in FullScreen + NSRect maFullScreenRect; // old window size when in FullScreen BOOL mbGraphics; // is Graphics used? BOOL mbFullScreen; // is Window in FullScreen? - AquaSalInstance* mpSalInstance; bool mbShown; bool mbInitShow; bool mbPositioned; bool mbSized; ULONG mnStyle; - - TSMDocumentID maTsmDocumentId; - SalExtTextInputEvent maInputEvent; // preedit text + unsigned int mnStyleMask; // our style mask from NSWindow creation + + ULONG mnLastEventTime; + unsigned int mnLastModifierFlags; + AquaSalMenu* mpMenu; + + SalExtStyle mnExtStyle; // currently document frames are marked this way public: /** Constructor @@ -99,14 +98,13 @@ @throws std::runtime_error in case window creation fails */ - AquaSalFrame(SalFrame* pParent, ULONG salFrameStyle, AquaSalInstance* pSalInstance); + AquaSalFrame( SalFrame* pParent, ULONG salFrameStyle ); virtual ~AquaSalFrame(); virtual SalGraphics* GetGraphics(); virtual void ReleaseGraphics( SalGraphics* pGraphics ); virtual BOOL PostEvent( void* pData ); - BOOL PostTimerEvent( AquaSalTimer *pTimer ); virtual void SetTitle( const XubString& rTitle ); virtual void SetIcon( USHORT nIcon ); virtual void SetMenu( SalMenu* pSalMenu ); @@ -163,71 +161,103 @@ // trigger painting of the window void SendPaintEvent(); - void ActivateTSM(); - void DeactivateTSM(); - static bool isAlive( const AquaSalFrame* pFrame ) { return GetSalData()->maFrameCheck.find( pFrame ) != GetSalData()->maFrameCheck.end(); } static AquaSalFrame* GetCaptureFrame() { return s_pCaptureFrame; } + + NSWindow* getWindow() const { return mpWindow; } + NSView* getView() const { return mpView; } + unsigned int getStyleMask() const { return mnStyleMask; } + + // actually the follwing methods do the same thing: flipping y coordinates + // but having two of them makes clearer what the coordinate system + // is supposed to be before and after + void VCLToCocoa( NSRect& io_rRect, bool bRelativeToScreen = true ); + void CocoaToVCL( NSRect& io_rRect, bool bRelativeToScreen = true ); - private: // methods - - /** Create a new system window. - The newly create window will be associated whith this frame. - - @param pParent - the parent of the window may be NULL - - @param nSalFrameStyle - the style of the new window - - @throws std::runtime_error in case window creation fails - */ - void CreateNewSystemWindow(CarbonWindowRef pParent, ULONG nSalFrameStyle); - - BOOL ImplPostUserEvent( UInt32 eventKind, void *pData ); - - /** Install a window event handler - - The window event handler and the corresponding Universal Procedure Pointer (UPP) pointer - need to be save during destruction of the frame instance we have to unregister all installed - event handlers and dispose the UPP. - - @param upp - a universal procedure pointer - - @param nEvents - number of events to register - - @param eventSpec - the event specification + void VCLToCocoa( NSPoint& io_rPoint, bool bRelativeToScreen = true ); + void CocoaToVCL( NSPoint& io_Point, bool bRelativeToScreen = true ); - @return the status of the registration see Carbon Event Manager reference for details - */ - OSStatus InstallAndRegisterEventHandler(EventHandlerUPP upp, size_t nEvents, const EventTypeSpec* eventSpec); - void DeinstallAndUnregisterAllEventHandler(); - + private: // methods /** do things on initial show (like centering on parent or on screen) */ void initShow(); - - private: // data - - typedef std::pair SysWindowEventHandlerData_t; - typedef std::vector SysWindowEventHandlerDataContainer_t; - SysWindowEventHandlerDataContainer_t mSysWindowEventHandlerDataContainer; - - // Menu associated with this SalFrame - SalMenu *mpMenu; - static SysWindowEventHandlerData_t s_aOverlayEvtHandler; + void initWindowAndView(); + + private: // data static AquaSalFrame* s_pCaptureFrame; - static CarbonWindowRef s_rOverlay; // window handle for overlay (needed in CaptureMouse) // make AquaSalFrame non copyable AquaSalFrame( const AquaSalFrame& ); AquaSalFrame& operator=(const AquaSalFrame&); }; +@interface SalFrameWindow : NSWindow +{ + AquaSalFrame* mpFrame; +} +-(id)initWithSalFrame: (AquaSalFrame*)pFrame; +-(void)windowDidBecomeKey: (NSNotification*)pNotification; +-(void)windowDidResignKey: (NSNotification*)pNotification; +-(void)windowDidChangeScreen: (NSNotification*)pNotification; +-(void)windowDidMove: (NSNotification*)pNotification; +-(void)windowDidResize: (NSNotification*)pNotification; +-(void)windowDidMiniaturize: (NSNotification*)pNotification; +-(void)windowDidDeminiaturize: (NSNotification*)pNotification; +-(MacOSBOOL)windowShouldClose: (NSNotification*)pNotification; +-(void)dockMenuItemTriggered: (id)sender; +@end + +@interface SalFrameView : NSView +{ + AquaSalFrame* mpFrame; + + // for NSTextInput + id mpLastEvent; + BOOL mbNeedSpecialKeyHandle; + BOOL mbInKeyInput; + BOOL mbKeyHandled; + NSRange mMarkedRange; + NSRange mSelectedRange; +} +-(id)initWithSalFrame: (AquaSalFrame*)pFrame; +-(MacOSBOOL)acceptsFirstResponder; +-(MacOSBOOL)acceptsFirstMouse: (NSEvent *)pEvent; +-(MacOSBOOL)isOpaque; +-(void)drawRect: (NSRect)aRect; +-(void)mouseDown: (NSEvent*)pEvent; +-(void)mouseDragged: (NSEvent*)pEvent; +-(void)mouseUp: (NSEvent*)pEvent; +-(void)mouseMoved: (NSEvent*)pEvent; +-(void)mouseEntered: (NSEvent*)pEvent; +-(void)mouseExited: (NSEvent*)pEvent; +-(void)rightMouseDown: (NSEvent*)pEvent; +-(void)rightMouseDragged: (NSEvent*)pEvent; +-(void)rightMouseUp: (NSEvent*)pEvent; +-(void)otherMouseDown: (NSEvent*)pEvent; +-(void)otherMouseDragged: (NSEvent*)pEvent; +-(void)otherMouseUp: (NSEvent*)pEvent; +-(void)scrollWheel: (NSEvent*)pEvent; +-(void)keyDown: (NSEvent*)pEvent; +-(void)flagsChanged: (NSEvent*)pEvent; +-(void)sendMouseEventToFrame:(NSEvent*)pEvent button:(USHORT)nButton eventtype:(USHORT)nEvent; +-(void)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar; +-(MacOSBOOL)checkSpecialCharacters:(NSEvent*)pEvent; +/* + text action methods +*/ +-(void)insertText:(id)aString; +-(void)insertTab: (id)aSender; +-(void)moveLeft: (id)aSender; +-(void)moveRight: (id)aSender; +-(void)moveUp: (id)aSender; +-(void)moveDown: (id)aSender; +-(void)insertNewline: (id)aSender; +-(void)deleteBackward: (id)aSender; +-(void)deleteForward: (id)aSender; +-(void)cancelOperation: (id)aSender; +@end + #endif // _SV_SALFRAME_H diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/salgdi.h ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salgdi.h --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/salgdi.h 2007-08-03 15:58:36.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salgdi.h 2007-08-13 13:42:03.000000000 +0200 @@ -61,6 +61,8 @@ #include #include + +class AquaSalFrame; class AquaSalBitmap; class ImplDevFontAttributes; @@ -96,26 +98,27 @@ // ------------------- // - AquaSalGraphics - // ------------------- - class AquaSalGraphics : public SalGraphics { friend class ATSLayout; protected: - /// VCLVIEW - CarbonViewRef mrView; + AquaSalFrame* mpFrame; /// graphics context for Quartz 2D CGContextRef mrContext; - /// Window if this is a Window graphics - CarbonWindowRef mrWindow; - /// resolution of this graphics (72 on window and virdev, device dependent on printer) - long mnDPIX; - long mnDPIY; + /// device resolution of this graphics + long mnRealDPIX; + long mnRealDPIY; + /// some graphics implementations (e.g. AquaSalInfoPrinter) scale + /// everything down by a factor (see SetupPrinterGraphics for details) + /// so we have to compensate for it with the inverse factor + double mfFakeDPIScale; + /// memory for graphics bitmap context (window or virdev) boost::shared_array< sal_uInt8 > maContextMemory; /// basebmp::BitmapDevice used for XOR rendering basebmp::BitmapDeviceSharedPtr maXORDevice; basebmp::BitmapDeviceSharedPtr maXORClipMask; - + /// path representing current clip region CGMutablePathRef mrClippingPath; std::vector< CGRect > maClippingRects; @@ -127,14 +130,14 @@ float mpFillColor[4]; /// is XOR mode enabled ? bool mbXORMode; - + // Device Font settings - const ImplMacFontData* mpMacFontData; - /// style object which carries all font attributes + const ImplMacFontData* mpMacFontData; + /// ATSU style object which carries all font attributes ATSUStyle maATSUStyle; /// text rotation as ATSU angle Fixed mnATSUIRotation; - /// allows text measurements for huge font sizes + /// workaround to prevent ATSU overflows for huge font sizes float mfFontScale; /// allows text to be rendered without antialiasing bool mbNonAntialiasedText; @@ -147,8 +150,7 @@ bool mbVirDev; /// is this a window graphics bool mbWindow; - /// is this graphics screen compatible - bool mbScreen; + private: /** returns the display id this window is mostly visible on */ CGDirectDisplayID GetWindowDisplayID() const; @@ -159,20 +161,18 @@ bool IsPenTransparent() const { return (mpLineColor[3] == 0.0); } bool IsBrushTransparent() const { return (mpFillColor[3] == 0.0); } - void SetWindowGraphics( CarbonViewRef rView, CarbonWindowRef rWindow, bool bScreenCompatible ); - void SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY ); + void SetWindowGraphics( AquaSalFrame* pFrame ); + void SetPrinterGraphics( CGContextRef, long nRealDPIX, long nRealDPIY, double fFakeScale ); void SetVirDevGraphics( CGContextRef xContext, bool bSCreenCompatible ); bool IsWindowGraphics() const { return mbWindow; } bool IsPrinterGraphics() const { return mbPrinter; } bool IsVirDevGraphics() const { return mbVirDev; } - bool IsScreenCompatible() const { return mbScreen; } void ImplDrawPixel( long nX, long nY, float pColor[] ); // helper to draw single pixels - void Flush(); bool CheckContext(); - void UpdateWindow(); + void UpdateWindow( NSGraphicsContext* pContext ); void RefreshRect(float lX, float lY, float lWidth, float lHeight); void SetState(); diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/salinst.h ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salinst.h --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/salinst.h 2007-07-05 10:13:10.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salinst.h 2007-08-08 11:27:49.000000000 +0200 @@ -36,32 +36,16 @@ #ifndef _SV_SALINST_H #define _SV_SALINST_H -#ifndef _SV_SV_H -#include -#endif -#ifndef _VOS_MUTEX_HXX -#include -#endif -#ifndef _VOS_THREAD_HXX -#include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus +#include "vcl/sv.h" +#include "vos/mutex.hxx" +#include "vos/thread.hxx" +#include "vcl/salinst.hxx" -class SalYieldMutex; +#include "aquavcltypes.h" -#else // __cplusplus +#include -#define SalYieldMutex void - -#endif // __cplusplus +class AquaSalFrame; // ----------------- // - SalYieldMutex - @@ -70,7 +54,7 @@ class SalYieldMutex : public vos::OMutex { ULONG mnCount; - NAMESPACE_VOS(OThread)::TThreadIdentifier mnThreadId; + vos::OThread::TThreadIdentifier mnThreadId; public: SalYieldMutex(); @@ -78,7 +62,7 @@ virtual void release(); virtual sal_Bool tryToAcquire(); ULONG GetAcquireCount() const { return mnCount; } - NAMESPACE_VOS(OThread)::TThreadIdentifier GetThreadId() const { return mnThreadId; } + vos::OThread::TThreadIdentifier GetThreadId() const { return mnThreadId; } }; #define YIELD_GUARD vos::OGuard aGuard( GetSalData()->mpFirstInstance->GetYieldMutex() ) @@ -98,11 +82,25 @@ class AquaSalInstance : public SalInstance { + struct SalUserEvent + { + AquaSalFrame* mpFrame; + void* mpData; + USHORT mnType; + + SalUserEvent( AquaSalFrame* pFrame, void* pData, USHORT nType ) : + mpFrame( pFrame ), mpData( pData ), mnType( nType ) + {} + }; + public: - void* mpFilterInst; - void* mpFilterCallback; - SalYieldMutex* mpSalYieldMutex; // Sal-Yield-Mutex - rtl::OUString maDefaultPrinter; + SalYieldMutex* mpSalYieldMutex; // Sal-Yield-Mutex + rtl::OUString maDefaultPrinter; + vos::OThread::TThreadIdentifier maMainThread; + int mnMainThreadLevel; + NSAutoreleasePool* mpAutoreleasePool; + std::list< SalUserEvent > maUserEvents; + oslMutex maUserEventListMutex; public: AquaSalInstance(); virtual ~AquaSalInstance(); @@ -148,7 +146,7 @@ virtual void SetEventCallback( void* pInstance, bool(*pCallback)(void*,void*,int) ); virtual void SetErrorEventCallback( void* pInstance, bool(*pCallback)(void*,void*,int) ); - static void TimerEventHandler(EventLoopTimerRef inTimer, void* pData); + static void handleAppDefinedEvent( NSEvent* pEvent ); public: /* During window resizing the standard event handler does @@ -164,15 +162,27 @@ */ void StartForceDispatchingPaintEvents(); void StopForceDispatchingPaintEvents(); - EventLoopTimerRef mEventLoopTimerRef; bool mbForceDispatchPaintEvents; friend class AquaSalFrame; + + void PostUserEvent( AquaSalFrame* pFrame, USHORT nType, void* pData ); + + bool isNSAppThread() const; + + // event subtypes for NSApplicationDefined events + static const short AppExecuteSVMain = 0x7fff; + static const short AppEndLoopEvent = 1; + static const short AppStartTimerEvent = 10; + + static NSMenu* GetDynamicDockMenu(); }; // helper class rtl::OUString GetOUString( CFStringRef ); +rtl::OUString GetOUString( NSString* ); CFStringRef CreateCFString( const rtl::OUString& ); +NSString* CreateNSString( const rtl::OUString& ); #endif // _SV_SALINST_H diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/salmenu.h ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salmenu.h --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/salmenu.h 2007-07-27 09:43:42.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/salmenu.h 2007-08-07 12:31:16.000000000 +0200 @@ -37,25 +37,21 @@ #define _SV_SALMENU_H #include -#include +#include #include -#ifndef _SV_SV_H #include -#endif -#ifndef _SV_BITMAP_HXX -#include -#endif - -#ifndef _SV_SALMENU_HXX #include -#endif +#include + +class AquaSalFrame; +class AquaSalMenuItem; class AquaSalMenu : public SalMenu { public: - AquaSalMenu() {} + AquaSalMenu( bool bMenuBar ); virtual ~AquaSalMenu(); virtual BOOL VisibleMenuBar(); // must return TRUE to actually DISPLAY native menu bars @@ -71,31 +67,50 @@ virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage); virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const XubString& rKeyName ); virtual void GetSystemMenuData( SystemMenuData* pData ); - - XubString mText; // Title of this menu - MenuRef mrMenuRef; // The Carbon reference to this menu - BOOL mbMenuBar; // TRUE - Menubar, FALSE - Menu + + int getItemIndexByPos( USHORT nPos ) const; + const AquaSalFrame* getFrame() const; + + void setMainMenu(); + + bool mbMenuBar; // true - Menubar, false - Menu + NSMenu* mpMenu; // The Carbon reference to this menu + Menu* mpVCLMenu; // the corresponding vcl Menu object + const AquaSalFrame* mpFrame; // the frame to dispatch the menu events to + AquaSalMenu* mpParentSalMenu; // the parent menu that contains us (and perhaps has a frame) + + static const AquaSalMenu* pCurrentMenuBar; + + std::vector< AquaSalMenuItem* > maItems; }; class AquaSalMenuItem : public SalMenuItem { public: - AquaSalMenuItem() {} + AquaSalMenuItem( const SalItemParams* ); virtual ~AquaSalMenuItem(); - USHORT mnId; // Item ID - Menu *mpMenu; // Menu into which this MenuItem is inserted - SalMenu *mpSubMenu; // Sub menu of this item (if defined) - XubString mText; // Title of this menu item - MenuRef mrParentMenuRef; // The menu in which this menu item is inserted - - MenuItemIndex mnMenuItemIndex; // The menu index of this menu item in mpMenu - // It is 1 based, so the first menu - // item's MenuItemIndex in the menu has value 1 + USHORT mnId; // Item ID + Menu* mpVCLMenu; // VCL Menu into which this MenuItem is inserted + AquaSalMenu* mpParentMenu; // The menu in which this menu item is inserted + AquaSalMenu* mpSubMenu; // Sub menu of this item (if defined) + NSMenuItem* mpMenuItem; // The NSMenuItem +}; - MenuItemAttributes maMenuAttributes; +@interface SalNSMenu : NSMenu +{ + AquaSalMenu* mpMenu; +} +-(id)initWithMenu: (AquaSalMenu*)pMenu; +-(void)menuNeedsUpdate: (NSMenu*)pMenu; +@end - Bitmap maBitmap; // item image -}; +@interface SalNSMenuItem : NSMenuItem +{ + AquaSalMenuItem* mpMenuItem; +} +-(id)initWithMenuItem: (AquaSalMenuItem*)pMenuItem; +-(void)menuItemTriggered: (id)aSender; +@end #endif // _SV_SALMENU_H diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/inc/saltimer.h ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/saltimer.h --- ooo_SRC680_m225_src.orig/vcl/aqua/inc/saltimer.h 2007-07-05 17:56:34.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/inc/saltimer.h 2007-07-26 13:02:25.000000000 +0200 @@ -37,8 +37,7 @@ #define _SV_SALTIMER_H #include -#include -#include +#include #include #ifndef _SV_SALTIMER_HXX @@ -54,6 +53,8 @@ void Start( ULONG nMS ); void Stop(); + + static void handleStartTimerEvent( NSEvent* pEvent ); }; diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/app/salinst.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/app/salinst.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/app/salinst.cxx 2007-08-03 16:00:41.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/app/salinst.cxx 2007-08-08 11:27:49.000000000 +0200 @@ -38,63 +38,129 @@ #include -#ifndef _SV_SALDATA_HXX -#include -#endif -#ifndef _SV_SALINST_HXX -#include -#endif -#ifndef _SV_SALINST_H -#include -#endif -#ifndef _SV_SALFRAME_H -#include -#endif -#ifndef _SV_SALOBJ_HXX -#include -#endif -#ifndef _SV_SALOBJ_H -#include -#endif -#ifndef _SV_SALSYS_HXX -#include -#endif -#ifndef _SV_SALSYS_H -#include -#endif -#ifndef _SV_SALVD_HXX -#include -#endif -#ifndef _SV_SALVD_H -#include -#endif -#ifndef _SV_DIALOG_HXX -#include -#endif -#ifndef _FSYS_HXX -#include -#endif -#ifndef _SV_SALIMESTATUS_HXX -#include -#endif - -#include - -#include -#include +#include "tools/fsys.hxx" +#include "osl/process.h" +#include "rtl/ustrbuf.hxx" +#include "vcl/svapp.hxx" +#include "vcl/print.h" +#include "vcl/salimestatus.hxx" + +#include "saldata.hxx" +#include "salinst.h" +#include "salframe.h" +#include "salobj.h" +#include "salsys.h" +#include "salvd.h" +#include "salsound.h" +#include "salbmp.h" +#include "salprn.h" +#include "salogl.h" +#include "saltimer.h" -#include -#include +#include "premac.h" +#include +#include "postmac.h" -#include +using namespace std; -#include +extern BOOL ImplSVMain(); -#include -#include -#include +static BOOL* gpbInit = 0; +static NSMenu* pDockMenu = nil; +bool bLeftMain = false; -using namespace std; +NSMenu* AquaSalInstance::GetDynamicDockMenu() +{ + if( ! pDockMenu && ! bLeftMain ) + pDockMenu = [[NSMenu alloc] initWithTitle: @""]; + return pDockMenu; +} + +@interface CocoaThreadEnabler : NSObject +{ +} +-(void)enableCocoaThreads:(id)param; +@end + +@implementation CocoaThreadEnabler +-(void)enableCocoaThreads:(id)param +{ + // do nothing, this is just to start an NSThread and therefore put + // Cococa into multithread mode +} +@end + +// our very own application +@interface VCL_NSApplication : NSApplication +{ +} +-(void)sendEvent:(NSEvent*)pEvent; +-(NSMenu*)applicationDockMenu:(NSApplication *)sender; +@end + +@implementation VCL_NSApplication +-(void)sendEvent:(NSEvent*)pEvent +{ + if( [pEvent type] == NSApplicationDefined ) + GetSalData()->mpFirstInstance->handleAppDefinedEvent( pEvent ); + [super sendEvent: pEvent]; +} + +-(NSMenu*)applicationDockMenu:(NSApplication *)sender +{ + return AquaSalInstance::GetDynamicDockMenu(); +} +@end + +BOOL ImplSVMainHook( BOOL * pbInit ) +{ + gpbInit = pbInit; + + // create our cocoa NSApplication + [VCL_NSApplication sharedApplication]; + + // put cocoa into multithreaded mode + [NSThread detachNewThreadSelector:@selector(enableCocoaThreads:) toTarget:[[CocoaThreadEnabler alloc] init] withObject:nil]; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + // activate our delegate methods + [NSApp setDelegate: NSApp]; + + NSPoint aPt = { 0, 0 }; + NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined + location: aPt + modifierFlags: 0 + timestamp: 0 + windowNumber: 0 + context: nil + subtype: AquaSalInstance::AppExecuteSVMain + data1: 0 + data2: 0 ]; + if( pEvent ) + { + [NSApp postEvent: pEvent atStart: NO]; + [pool release]; + + // install handlers of AppleEvents BEFORE handling event loops + // else we miss the for initial OpenDocument apple events + extern void InstallAEHandlers(); + InstallAEHandlers(); + + + rtl::OUString aExeURL, aExe; + osl_getExecutableFile( &aExeURL.pData ); + osl_getSystemPathFromFileURL( aExeURL.pData, &aExe.pData ); + rtl::OString aByteExe( rtl::OUStringToOString( aExe, osl_getThreadTextEncoding() ) ); + + const char* pArgv[] = { aByteExe.getStr(), NULL }; + NSApplicationMain( 1, pArgv ); + } + else + DBG_ERROR( "NSApplication initialization could not be done" ); + + return TRUE; // indicate that ImplSVMainHook is implemented +} // ----------------------------------------------------------------------- @@ -223,18 +289,6 @@ void DeInitSalMain() { - // Release autorelease pool - //VCLAutoreleasePool_Release( hMainAutoreleasePool ); - -} - -// ----------------------------------------------------------------------- - -void SetFilterCallback( void* pCallback, void* pInst ) -{ - // SalData *pSalData = GetSalData(); - //[fheckl]pSalData->mpFirstInstance->mpFilterCallback = pCallback; - //[fheckl]pSalData->mpFirstInstance->mpFilterInst = pInst; } // ======================================================================= @@ -299,10 +353,7 @@ { AquaSalInstance* pInst = (AquaSalInstance*) GetSalData()->mpFirstInstance; if ( pInst ) - { - //GdiFlush(); pInst->mpSalYieldMutex->release(); - } } // ======================================================================= @@ -318,20 +369,21 @@ else SalData::s_pLog = fopen( pLogEnv, "w" ); - AquaSalInstance* pInst = new AquaSalInstance; - - EventLoopTimerUPP eventLoopTimer = NewEventLoopTimerUPP(AquaSalInstance::TimerEventHandler); - InstallEventLoopTimer(GetMainEventLoop(), 1, 0, eventLoopTimer, pInst, &pInst->mEventLoopTimerRef); - - // init instance (only one instance in this version !!!) - SalData* pSalData = GetSalData(); - pSalData->mpFirstInstance = pInst; - ImplGetSVData()->maNWFData.mbNoFocusRects = true; + SalData* pSalData = GetSalData(); + DBG_ASSERT( pSalData->mpFirstInstance == NULL, "more than one instance created" ); + AquaSalInstance* pInst = new AquaSalInstance; + + // init instance (only one instance in this version !!!) + pSalData->mpFirstInstance = pInst; + // this one is for outside AquaSalInstance::Yield + pInst->mpAutoreleasePool = [[NSAutoreleasePool alloc] init]; + // no focus rects on NWF aqua + ImplGetSVData()->maNWFData.mbNoFocusRects = true; ImplGetSVData()->maNWFData.mbNoBoldTabFocus = true; ImplGetSVData()->maNWFData.mbCenteredTabs = true; ImplGetSVData()->maNWFData.mbProgressNeedsErase = true; - - return pInst; + + return pInst; } // ----------------------------------------------------------------------- @@ -348,18 +400,13 @@ AquaSalInstance::AquaSalInstance() { - mpFilterCallback = NULL; - mpFilterInst = NULL; mpSalYieldMutex = new SalYieldMutex; - mEventLoopTimerRef = NULL; mbForceDispatchPaintEvents = false; mpSalYieldMutex->acquire(); - - // In order to receive events, we put the application in foreground - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - SetFrontProcess(&psn); + maMainThread = vos::OThread::getCurrentIdentifier(); + mnMainThreadLevel = 0; + mpAutoreleasePool = nil; + maUserEventListMutex = osl_createMutex(); } // ----------------------------------------------------------------------- @@ -368,36 +415,16 @@ { mpSalYieldMutex->release(); delete mpSalYieldMutex; + osl_destroyMutex( maUserEventListMutex ); } // ----------------------------------------------------------------------- -void AquaSalInstance::TimerEventHandler(EventLoopTimerRef inTimer, void* pData) +void AquaSalInstance::PostUserEvent( AquaSalFrame* pFrame, USHORT nType, void* pData ) { - AquaSalInstance* pInst = reinterpret_cast(pData); - - if (pInst->mbForceDispatchPaintEvents) - { - ULONG nCount = 0; - - // Release all locks so that we don't deadlock when we pull pending - // events from the event queue - nCount = pInst->ReleaseYieldMutex(); - - EventRef theEvent; - EventTargetRef theTarget = GetEventDispatcherTarget(); - - if (ReceiveNextEvent(1, &cOOoSalTimerEvent, 0, true, &theEvent) == noErr) - { - SendEventToEventTarget(theEvent, theTarget); - ReleaseEvent(theEvent); - } - - // Reset all locks - pInst->AcquireYieldMutex(nCount); - - SetEventLoopTimerNextFireTime(inTimer, 1); // restart timer - } + osl_acquireMutex( maUserEventListMutex ); + maUserEvents.push_back( SalUserEvent( pFrame, pData, nType ) ); + osl_releaseMutex( maUserEventListMutex ); } // ----------------------------------------------------------------------- @@ -443,65 +470,126 @@ // ----------------------------------------------------------------------- -void AquaSalInstance::StartForceDispatchingPaintEvents() +bool AquaSalInstance::isNSAppThread() const { - SetEventLoopTimerNextFireTime(mEventLoopTimerRef, 1); - mbForceDispatchPaintEvents = true; + return vos::OThread::getCurrentIdentifier() == maMainThread; } -void AquaSalInstance::StopForceDispatchingPaintEvents() +// ----------------------------------------------------------------------- + +void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent ) { - mbForceDispatchPaintEvents = false; + switch( [pEvent subtype] ) + { + case AppStartTimerEvent: + AquaSalTimer::handleStartTimerEvent( pEvent ); + break; + case AppEndLoopEvent: + [NSApp stop: NSApp]; + break; + case AppExecuteSVMain: + { + BOOL bResult = ImplSVMain(); + if( gpbInit ) + *gpbInit = bResult; + [NSApp stop: NSApp]; + bLeftMain = true; + if( pDockMenu ) + { + [pDockMenu release]; + pDockMenu = nil; + } + } + break; + default: + DBG_ERROR( "unhandled NSApplicationDefined event" ); + break; + }; } +// ----------------------------------------------------------------------- + void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) { - ULONG nCount = 0; // Release all locks so that we don't deadlock when we pull pending // events from the event queue - nCount = ReleaseYieldMutex(); - - EventTargetRef theTarget = GetEventDispatcherTarget(); - EventTimeout timeout = bWait ? kEventDurationForever : 0; - - EventRef aLastTimerEvent = NULL; - for(;;) + bool bDispatchUser = true; + while( bDispatchUser ) { - EventRef theEvent; - OSStatus eStatus = ReceiveNextEvent( 0, NULL, timeout, kEventRemoveFromQueue, &theEvent ); - if( eStatus != noErr) - break; - if( bHandleAllCurrentEvents - && GetEventClass(theEvent) == cOOoSalUserEventClass - && GetEventKind(theEvent) == cOOoSalEventTimer ) - { - // ignore any timer event except the last one - if( aLastTimerEvent ) - ReleaseEvent( aLastTimerEvent ); - aLastTimerEvent = theEvent; - } - else - { - //ImplSalYieldMutexAcquire(); - eStatus = SendEventToEventTarget(theEvent, theTarget); - //ImplSalYieldMutexRelease(); - - ReleaseEvent(theEvent); - } - - if( !bHandleAllCurrentEvents ) - break; - } - - // send only the latest timer event if any - if( aLastTimerEvent ) - { - SendEventToEventTarget( aLastTimerEvent, theTarget ); - ReleaseEvent( aLastTimerEvent ); - } - - // Reset all locks - AcquireYieldMutex( nCount ); + ULONG nCount = ReleaseYieldMutex(); + + // get one user event + osl_acquireMutex( maUserEventListMutex ); + SalUserEvent aEvent( NULL, 0, NULL ); + if( ! maUserEvents.empty() ) + { + aEvent = maUserEvents.front(); + maUserEvents.pop_front(); + } + else + bDispatchUser = false; + osl_releaseMutex( maUserEventListMutex ); + + AcquireYieldMutex( nCount ); + + // dispatch it + if( aEvent.mpFrame && AquaSalFrame::isAlive( aEvent.mpFrame ) ) + { + aEvent.mpFrame->CallCallback( aEvent.mnType, aEvent.mpData ); + // return if only one event is asked for + if( ! bHandleAllCurrentEvents ) + return; + } + } + + // handle cocoa event queue + // cocoa events mye be only handled in the thread the NSApp was created + if( isNSAppThread() ) + { + mnMainThreadLevel++; + + // handle available events + NSEvent* pEvent = nil; + bool bHadEvent = false; + do + { + ULONG nCount = ReleaseYieldMutex(); + + pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: nil + inMode: NSDefaultRunLoopMode dequeue: YES]; + if( pEvent ) + { + [NSApp sendEvent: pEvent]; + bHadEvent = true; + } + [NSApp updateWindows]; + + AcquireYieldMutex( nCount ); + } while( bHandleAllCurrentEvents && pEvent ); + + // if we had no event yet, wait for one if requested + if( bWait && ! bHadEvent ) + { + ULONG nCount = ReleaseYieldMutex(); + + pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: [NSDate distantFuture] + inMode: NSDefaultRunLoopMode dequeue: YES]; + if( pEvent ) + [NSApp sendEvent: pEvent]; + [NSApp updateWindows]; + + AcquireYieldMutex( nCount ); + } + + mnMainThreadLevel--; + + if( mnMainThreadLevel == 0 ) + { + // flush the autorelease pool + [mpAutoreleasePool release]; + mpAutoreleasePool = [[NSAutoreleasePool alloc] init]; + } + } // we get some apple events way too early // before the application is ready to handle them, @@ -548,14 +636,7 @@ { SalFrame* pFrame = NULL; - try - { - pFrame = new AquaSalFrame(pParent, nSalFrameStyle, this); - } - catch(runtime_error&) - { - // frame creation failed - } + pFrame = new AquaSalFrame( pParent, nSalFrameStyle ); return pFrame; } @@ -886,6 +967,8 @@ extern void InstallAEHandlers() { + // FIXME: port to cocoa + #if 0 // check if it is possible to install AppleEvent handlers long nGestaltAttrs; OSStatus eStatus = Gestalt( gestaltAppleEventsAttr, &nGestaltAttrs ); @@ -911,6 +994,7 @@ AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, aAEHandler, 0L, false ); // TODO: handle other events from the AppleEventManager too + #endif } ////////////////////////////////////////////////////////////// @@ -933,8 +1017,26 @@ return aRet; } +rtl::OUString GetOUString( NSString* pStr ) +{ + if( ! pStr ) + return rtl::OUString(); + int nLen = [pStr length]; + if( nLen == 0 ) + return rtl::OUString(); + + rtl::OUStringBuffer aBuf( nLen+1 ); + aBuf.setLength( nLen ); + [pStr getCharacters: const_cast(aBuf.getStr())]; + return aBuf.makeStringAndClear(); +} + CFStringRef CreateCFString( const rtl::OUString& rStr ) { return CFStringCreateWithCharacters(kCFAllocatorDefault, rStr.getStr(), rStr.getLength() ); } +NSString* CreateNSString( const rtl::OUString& rStr ) +{ + return [[NSString alloc] initWithCharacters: rStr.getStr() length: rStr.getLength()]; +} diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/app/saltimer.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/app/saltimer.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/app/saltimer.cxx 2007-07-05 18:00:00.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/app/saltimer.cxx 2007-07-26 18:13:31.000000000 +0200 @@ -36,133 +36,123 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#ifndef _SV_SALTIMER_H #include -#endif -#ifndef _SV_SALDATA_HXX #include -#endif -#ifndef _SV_SALFRAME_H #include -#endif +#include // ======================================================================= +static NSTimer* pRunningTimer = nil; +static bool bDispatchTimer = false; +static bool bTimerInDispatch = false; -#define USEMAINTHREAD 1 +@interface TimerCallbackCaller : NSObject +{ +} +-(void)timerElapsed:(NSTimer*)pTimer; +@end -void ImplSalStartTimer ( ULONG nMS, BOOL bMutex) +@implementation TimerCallbackCaller +-(void)timerElapsed:(NSTimer*)pTimer +{ + if( bDispatchTimer && ! bTimerInDispatch ) + { + ImplSVData* pSVData = ImplGetSVData(); + if( pSVData->mpSalTimer ) + { + YIELD_GUARD; + bTimerInDispatch = true; + pSVData->mpSalTimer->CallCallback(); + bTimerInDispatch = false; + } + } +} +@end + +void ImplSalStartTimer( ULONG nMS ) { - AquaLog( "ImplSalStartTimer\n"); - SalData* pSalData = GetSalData(); - - // Store the new timeout - pSalData->mnTimerMS = nMS; - - if ( !bMutex ) - pSalData->mnTimerOrgMS = nMS; - - // Cancel current timer - if( pSalData->mbTimerInstalled ) - RemoveEventLoopTimer( pSalData->mrTimerRef ); - - // Install the timer task - if( InstallEventLoopTimer( GetMainEventLoop(), - kEventDurationMillisecond * nMS, - kEventDurationForever, - pSalData->mrTimerUPP, - NULL, - &pSalData->mrTimerRef) == noErr ) + if( pSalData->mpFirstInstance->isNSAppThread() ) { - pSalData->mbTimerInstalled = TRUE; + bDispatchTimer = true; + NSTimeInterval aTI = double(nMS)/1000.0; + if( pRunningTimer != nil ) + { + if( [pRunningTimer timeInterval] == aTI ) + // set new fire date + [pRunningTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: aTI]]; + else + { + [pRunningTimer invalidate]; + pRunningTimer = nil; + } + } + if( pRunningTimer == nil ) + { + pRunningTimer = [NSTimer scheduledTimerWithTimeInterval: aTI + target: [[TimerCallbackCaller alloc] init] + selector: @selector(timerElapsed:) + userInfo: nil + repeats: YES]; + } } - else + else { - AquaLog( "Could not install timer task!\n"); - pSalData->mbTimerInstalled = FALSE; + // post an event so we can get into the main thread + NSPoint aPt = { 0, 0 }; + NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined + location: aPt + modifierFlags: 0 + timestamp: [NSDate timeIntervalSinceReferenceDate] + windowNumber: 0 + context: nil + subtype: AquaSalInstance::AppStartTimerEvent + data1: (int)nMS + data2: 0 ]; + if( pEvent ) + [NSApp postEvent: pEvent atStart: YES]; } } -void AquaSalTimerProc ( EventLoopTimerRef theTimer, void * /* userData */) +void ImplSalStopTimer() { - AquaLog( "...AquaSalTimerProc...\n"); - - SalData* pSalData = GetSalData(); - ImplSVData* pSVData = ImplGetSVData(); - AquaSalTimer *pSalTimer = (AquaSalTimer*) pSVData->mpSalTimer; - - if( pSalTimer && !pSalData->mbInTimerProc ) - { - #ifdef USEMAINTHREAD - // Send event to the main thread - if( ! pSalData->maFrames.empty() ) - pSalData->maFrames.front()->PostTimerEvent( pSalTimer ); - - // FIXME? - // fire again using current timeout as this is a single shot timer - ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE ); - #else - // call back directly from timer thread - if( ImplSalYieldMutexTryToAcquire() ) - { - pSalData->mbInTimerProc = TRUE; - pSalTimer->CallCallback(); - pSalData->mbInTimerProc = FALSE; - ImplSalYieldMutexRelease(); - - // fire again using current timeout as this is a single shot timer - ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE ); - } - else - { - // could not acquire solar mutex, so - // fire again with a short delay (10ms) - AquaLog( "SHOULD NOT HAPPEN! TIMER: solar mutex not free\n"); - ImplSalStartTimer( 10, TRUE ); - } - #endif - } -} + bDispatchTimer = false; +} +void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( pSVData->mpSalTimer ) + { + NSTimeInterval posted = [pEvent timestamp] + NSTimeInterval([pEvent data1])/1000.0; + NSTimeInterval current = [NSDate timeIntervalSinceReferenceDate]; + if( current - posted <= 0.0 ) + // timer already elapsed since event posted + pSVData->mpSalTimer->CallCallback(); + else + ImplSalStartTimer( ULONG( (posted - current) * 1000.0 ) ); + } + +} AquaSalTimer::AquaSalTimer( ) { - AquaLog( "AquaSalTimer::AquaSalTimer\n"); - SalData* pSalData = GetSalData(); - - pSalData->mbTimerInstalled = FALSE; - pSalData->mnTimerMS = 0; - pSalData->mnTimerOrgMS = 0; - pSalData->mrTimerUPP = NewEventLoopTimerUPP( AquaSalTimerProc ); } AquaSalTimer::~AquaSalTimer() { - AquaLog( "AquaSalTimer::~AquaSalTimer\n"); - - SalData* pSalData = GetSalData(); - if( pSalData->mbTimerInstalled ) - RemoveEventLoopTimer( pSalData->mrTimerRef ); - - DisposeEventLoopTimerUPP( pSalData->mrTimerUPP ); + ImplSalStopTimer(); } void AquaSalTimer::Start( ULONG nMS ) { - ImplSalStartTimer(nMS, FALSE); + ImplSalStartTimer( nMS ); } void AquaSalTimer::Stop() { - AquaLog( "AquaSalTimer::Stop\n"); - - SalData* pSalData = GetSalData(); - if( pSalData->mbTimerInstalled ) - { - RemoveEventLoopTimer( pSalData->mrTimerRef ); - pSalData->mbTimerInstalled = FALSE; - } + ImplSalStopTimer(); } diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salatslayout.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salatslayout.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salatslayout.cxx 2007-08-03 16:01:34.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salatslayout.cxx 2007-08-13 13:58:30.000000000 +0200 @@ -59,7 +59,7 @@ class ATSLayout : public SalLayout { public: - ATSLayout( AquaSalGraphics*, double fFontScale ); + ATSLayout( ATSUStyle&, double fFontScale ); virtual ~ATSLayout(); virtual bool LayoutText( ImplLayoutArgs& ); @@ -83,10 +83,13 @@ virtual void Simplify( bool bIsBase ); private: - AquaSalGraphics* mpGraphics; - double mfFontScale; // allows metrics emulation of huge font sizes + ATSUStyle& mrATSUStyle; ATSUTextLayout maATSULayout; int mnCharCount; // ==mnEndCharPos-mnMinCharPos + // to prevent ATS overflowing the Fixed16.16 values + // ATS font requests get size limited by downscaling huge fonts + // in these cases the font scale becomes something bigger than 1.0 + double mfFontScale; private: mutable Fixed mnCachedWidth; // cached value of resulting typographical width @@ -115,11 +118,11 @@ // ======================================================================= -ATSLayout::ATSLayout( AquaSalGraphics* pGraphics, double fFontScale ) -: mpGraphics( pGraphics ), - mfFontScale( fFontScale ), +ATSLayout::ATSLayout( ATSUStyle& rATSUStyle, double fFontScale ) +: mrATSUStyle( rATSUStyle ), maATSULayout( NULL ), mnCharCount( 0 ), + mfFontScale( fFontScale ), mnCachedWidth( 0 ), mnGlyphCount( -1 ), mnNotdefWidth( 0 ), @@ -164,7 +167,7 @@ * * @param rArgs: contains array of char to be layouted, starting and ending position of the text to layout * - * Manage text layouting : choose glyph to represent characters using the style maATSUStyle + * Typographic layout of text by using the style maATSUStyle * * @return : true if everything is ok **/ @@ -178,7 +181,7 @@ // Layout text // set up our locals, verify parameters... DBG_ASSERT( (rArgs.mpStr!=NULL), "ATSLayout::LayoutText() with rArgs.mpStr==NULL !!!"); - DBG_ASSERT( (mpGraphics->maATSUStyle!=NULL), "ATSLayout::LayoutText() with maATSUStyle==NULL !!!"); + DBG_ASSERT( (mrATSUStyle!=NULL), "ATSLayout::LayoutText() with ATSUStyle==NULL !!!"); SalLayout::AdjustLayout( rArgs ); mnCharCount = mnEndCharPos - mnMinCharPos; @@ -190,7 +193,7 @@ #if (OSL_DEBUG_LEVEL > 3) Fixed fFontSize = 0; ByteCount nDummy; - ATSUGetAttribute( mpGraphics->maATSUStyle, kATSUSizeTag, sizeof(fFontSize), &fFontSize, &nDummy); + ATSUGetAttribute( mrATSUStyle, kATSUSizeTag, sizeof(fFontSize), &fFontSize, &nDummy); String aUniName( &rArgs.mpStr[rArgs.mnMinCharPos], mnCharCount ); ByteString aCName( aUniName, RTL_TEXTENCODING_UTF8 ); AquaLog( "ATSLayout( \"%s\" %d..%d of %d) with h=%4.1f\n", @@ -202,7 +205,7 @@ const int nRunCount = sizeof(nRunLengths)/sizeof(*nRunLengths); OSStatus eStatus = ATSUCreateTextLayoutWithTextPtr( rArgs.mpStr, rArgs.mnMinCharPos, mnCharCount, rArgs.mnLength, - nRunCount, &nRunLengths[0], &mpGraphics->maATSUStyle, + nRunCount, &nRunLengths[0], &mrATSUStyle, &maATSULayout); DBG_ASSERT( (eStatus==noErr), "ATSUCreateTextLayoutWithTextPtr failed\n"); @@ -218,7 +221,7 @@ * * @param rArgs: contains attributes relevant to do a text specific layout * - * Adjust text layouting : move glyphs to match the requested logical widths + * Adjust text layout by moving glyphs to match the requested logical widths * * @return : none **/ @@ -271,23 +274,25 @@ * * @param rGraphics: device to draw to * - * Draw the layouted text to screen and offscreen copy + * Draw the layouted text to the CGContext * * @return : none **/ void ATSLayout::DrawText( SalGraphics& rGraphics ) const { + AquaSalGraphics& rAquaGraphics = static_cast(rGraphics); + // short circuit if there is nothing to do if( (mnCharCount <= 0) - || !mpGraphics->CheckContext() ) + || !rAquaGraphics.CheckContext() ) return; // the view is vertically flipped => flipped glyphs // so apply a temporary transformation that it flips back // also compensate if the font was size limited - CGContextSaveGState( mpGraphics->mrContext ); - CGContextScaleCTM( mpGraphics->mrContext, +mfFontScale, -mfFontScale ); - CGContextSetShouldAntialias( mpGraphics->mrContext, !mpGraphics->mbNonAntialiasedText ); + CGContextSaveGState( rAquaGraphics.mrContext ); + CGContextScaleCTM( rAquaGraphics.mrContext, +mfFontScale, -mfFontScale ); + CGContextSetShouldAntialias( rAquaGraphics.mrContext, !rAquaGraphics.mbNonAntialiasedText ); // prepare ATSUI drawing attributes static const ItemCount nMaxControls = 8; @@ -299,12 +304,12 @@ // Tell ATSUI to use CoreGraphics theTags[numcontrols] = kATSUCGContextTag; theSizes[numcontrols] = sizeof( CGContextRef ); - theValues[numcontrols++] = &(mpGraphics->mrContext); + theValues[numcontrols++] = &rAquaGraphics.mrContext; // Rotate if necessary - if( mpGraphics->mnATSUIRotation != 0 ) + if( rAquaGraphics.mnATSUIRotation != 0 ) { - Fixed theAngle = mpGraphics->mnATSUIRotation; + Fixed theAngle = rAquaGraphics.mnATSUIRotation; theTags[numcontrols] = kATSULineRotationTag; theSizes[numcontrols] = sizeof( Fixed ); theValues[numcontrols++] = &theAngle; @@ -315,14 +320,15 @@ DBG_ASSERT( (theErr==noErr), "ATSLayout::DrawText ATSUSetLayoutControls failed!\n" ); // Draw the text - const Point aPos = GetDrawPosition( Point(mnBaseAdv, 0) ); + DBG_ASSERT( mnBaseAdv==0, "ATSLayout::DrawText() not yet implemented for glyph fallback layouts" ); + const Point aPos = GetDrawPosition( Point(mnBaseAdv,0) ); const Fixed nFixedX = FloatToFixed( +aPos.X() / mfFontScale ); - const Fixed nFixedY = FloatToFixed( -aPos.Y() / mfFontScale ); // adjusted for y-mirroring + const Fixed nFixedY = FloatToFixed( -aPos.Y() / mfFontScale ); // adjusted for y-mirroring theErr = ATSUDrawText( maATSULayout, mnMinCharPos, mnCharCount, nFixedX, nFixedY ); DBG_ASSERT( (theErr==noErr), "ATSLayout::DrawText ATSUDrawText failed!\n" ); // request an update of the changed window area - if( mpGraphics->IsWindowGraphics() ) + if( rAquaGraphics.IsWindowGraphics() ) { Rect drawRect; // rectangle of the changed area theErr = ATSUMeasureTextImage( maATSULayout, @@ -330,25 +336,25 @@ if( theErr == noErr ) { // FIXME: transformation from baseline to top left - // with the simple apporach below we invalidate too much + // with the simple approach below we invalidate too much short d = drawRect.bottom - drawRect.top; drawRect.top -= d; drawRect.bottom += d; CGRect aRect = CGRectMake( drawRect.left, drawRect.top, drawRect.right - drawRect.left, drawRect.bottom - drawRect.top ); - aRect = CGContextConvertRectToDeviceSpace( mpGraphics->mrContext, aRect ); - mpGraphics->RefreshRect( aRect.origin.x, aRect.origin.y, aRect.size.width+1, aRect.size.height+1 ); + aRect = CGContextConvertRectToDeviceSpace( rAquaGraphics.mrContext, aRect ); + rAquaGraphics.RefreshRect( aRect.origin.x, aRect.origin.y, aRect.size.width+1, aRect.size.height+1 ); } } // restore the original graphic context transformations - CGContextRestoreGState( mpGraphics->mrContext ); + CGContextRestoreGState( rAquaGraphics.mrContext ); } // ----------------------------------------------------------------------- /** - * ATSLayout::GetNextGlyphs : Get next glyphs informations + * ATSLayout::GetNextGlyphs : Get info about next glyphs in the layout * * @param nLen: max number of char * @param pGlyphs: returned array of glyph ids @@ -357,9 +363,9 @@ * @param pGlyphAdvances: returned array of glyphs advances * @param pCharIndexes: returned array of char indexes * - * Returns infos about the next requested glyphs + * Returns infos about the next glyphs in the text layout * - * @return : index of next glyph + * @return : number of glyph details that were provided **/ int ATSLayout::GetNextGlyphs( int nLen, long* pGlyphIDs, Point& rPos, int& nStart, long* pGlyphAdvances, int* pCharIndexes ) const @@ -488,7 +494,7 @@ mnCachedWidth = nRightBound - nLeftBound; } - const long nScaledWidth = static_cast( mfFontScale * FixedToFloat(mnCachedWidth) ); + const long nScaledWidth = static_cast(mfFontScale * FixedToFloat(mnCachedWidth)); return nScaledWidth; } @@ -555,11 +561,11 @@ if( (nStatus != noErr) && (nStatus != kATSULineBreakInWord) ) { - AquaLog("ATSUBreakLine => %d\n", nStatus); - return( STRING_LEN ); + AquaLog( "ATSUBreakLine => %d\n", nStatus); + return STRING_LEN; } - return( nBreakPos ); + return nBreakPos; } // ----------------------------------------------------------------------- @@ -812,12 +818,12 @@ return true; DBG_ASSERT( (mpGlyphIds!=NULL), "GetIdealX() called with mpGlyphIds==NULL !" ); - DBG_ASSERT( (mpGraphics->maATSUStyle!=NULL), "GetIdealX called with maATSUStyle==NULL !" ); + DBG_ASSERT( (mrATSUStyle!=NULL), "GetIdealX called with mrATSUStyle==NULL !" ); // TODO: cache ideal metrics per glyph? std::vector aIdealMetrics; aIdealMetrics.resize( mnGlyphCount ); - OSStatus theErr = ATSUGlyphGetIdealMetrics( mpGraphics->maATSUStyle, + OSStatus theErr = ATSUGlyphGetIdealMetrics( mrATSUStyle, mnGlyphCount, &mpGlyphIds[0], sizeof(*mpGlyphIds), &aIdealMetrics[0] ); DBG_ASSERT( (theErr==noErr), "ATSUGlyphGetIdealMetrics failed!"); if( theErr != noErr ) @@ -1031,7 +1037,7 @@ aPolyArgs.Init( &rPPV[i], pG->screenX, nDeltaY ); OSStatus nStatus, nCBStatus; nStatus = ATSUGlyphGetCubicPaths( - mpGraphics->maATSUStyle, nGlyphId, + mrATSUStyle, nGlyphId, MyATSCubicMoveToCallback, MyATSCubicLineToCallback, MyATSCubicCurveToCallback, MyATSCubicClosePathCallback, &aPolyArgs, &nCBStatus ); @@ -1182,7 +1188,7 @@ SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) { - ATSLayout* pATSLayout = new ATSLayout( this, mfFontScale ); + ATSLayout* pATSLayout = new ATSLayout( maATSUStyle, mfFontScale ); return pATSLayout; } diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salgdi.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salgdi.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salgdi.cxx 2007-08-03 16:02:18.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salgdi.cxx 2007-08-13 13:42:03.000000000 +0200 @@ -291,11 +291,11 @@ // ======================================================================= AquaSalGraphics::AquaSalGraphics() - : mrView( 0 ) + : mpFrame( NULL ) , mrContext( 0 ) - , mrWindow( 0 ) - , mnDPIX( 72 ) // since Quartz only knows point units instead of pixel units - , mnDPIY( 72 ) // faking the resolution to point==pixel is beneficial + , mnRealDPIX( 0 ) + , mnRealDPIY( 0 ) + , mfFakeDPIScale( 1.0 ) , mrClippingPath( 0 ) , mbXORMode( false ) , mpMacFontData( NULL ) @@ -305,8 +305,10 @@ , mbPrinter( false ) , mbVirDev( false ) , mbWindow( false ) - , mbScreen( false ) { + long nDummyX, nDummyY; + GetResolution( nDummyX, nDummyY ); + // init colors for(int i=0; i<3; i++) { @@ -332,7 +334,7 @@ CGPathRelease( mrClippingPath ); ATSUDisposeStyle( maATSUStyle ); - if( mrContext && mrWindow != 0 ) + if( mrContext && mbWindow ) { // destroy backbuffer bitmap context that we created ourself CFRelease( mrContext ); @@ -350,12 +352,36 @@ return CGMainDisplayID(); } -// ----------------------------------------------------------------------- +// ---------------------------------------------- + +static void GetDisplayResolution( long& rDPIX, long& rDPIY ) +{ + // calculate resolution from physical size and pixel count + const CGDirectDisplayID nDisplayID = CGMainDisplayID(); + const CGSize aSize = CGDisplayScreenSize( nDisplayID ); // => result is in millimeters + rDPIX = static_cast((CGDisplayPixelsWide( nDisplayID ) * 25.4) / aSize.width); + rDPIY = static_cast((CGDisplayPixelsHigh( nDisplayID ) * 25.4) / aSize.height); + + // equalize x- and y-resolution if they are close enough to prevent unneeded font stretching + if( (rDPIX != rDPIY) + && (10*rDPIX < 13*rDPIY) && (13*rDPIX > 10*rDPIY) ) + { + // also adjust to the next common resolution 72,96,120,144,... + const long nCommonDPI = (rDPIX >= rDPIY) ? rDPIX : rDPIY; + rDPIX = rDPIY = ((nCommonDPI + 12) / 24) * 24; + } +} void AquaSalGraphics::GetResolution( long& rDPIX, long& rDPIY ) { - rDPIX = mnDPIX; - rDPIY = mnDPIY; + if( !mnRealDPIY ) + { + GetDisplayResolution( mnRealDPIX, mnRealDPIY ); + mfFakeDPIScale = 1.0; + } + + rDPIX = static_cast(mfFakeDPIScale * mnRealDPIX); + rDPIY = static_cast(mfFakeDPIScale * mnRealDPIY); } // ----------------------------------------------------------------------- @@ -1052,7 +1078,7 @@ if( mrContext ) { pBitmap = new AquaSalBitmap; - if( !pBitmap->Create( mrContext, nX, nY, nDX, nDY, mrWindow == 0 ) ) + if( !pBitmap->Create( mrContext, nX, nY, nDX, nDY, ! mbWindow ) ) { delete pBitmap; pBitmap = 0; @@ -1242,7 +1268,6 @@ mpLineColor[3] = fOldLineAlpha; } - CGContextBeginPath( mrContext ); CGRect aRect; aRect.origin.x = nX; @@ -1315,7 +1340,7 @@ // convert quartz units to pixel units // please see the comment in AquaSalGraphics::SetFont() for details - const double fPixelSize = (mfFontScale * fPointSize); // * (mnDpiY / 72.0); + const double fPixelSize = (mfFontScale * mfFakeDPIScale * fPointSize); pMetric->mnAscent = +(aMetrics.ascent * fPixelSize + 0.5); pMetric->mnDescent = -(aMetrics.descent * fPixelSize + 0.5); pMetric->mnExtLeading = +(aMetrics.leading * fPixelSize + 0.5); @@ -1468,13 +1493,7 @@ long AquaSalGraphics::GetGraphicsWidth() const { - if( mrWindow ) - { - Rect windowBounds; - GetWindowPortBounds ( mrWindow, &windowBounds); - return windowBounds.right - windowBounds.left; - } - else if( mrContext ) + if( mrContext && (mbWindow || mbVirDev) ) { return CGBitmapContextGetWidth( mrContext ); } @@ -1519,24 +1538,18 @@ ImplMacFontData* pMacFont = static_cast( pReqFont->mpFontData ); mpMacFontData = pMacFont; - // Set Style Attributes (i.e. font parameters) - - // convert pixel units to typographic point - // for the display's forced-72dpi display this is 1:1 - // the printer reports >>72dpi to OOo's independent layer though - // and sets to transformation matrix scale to (72/dpi) - // but Quartz wants the size in points, so 1:1 is also appropriate here - double fPointHeight = pReqFont->mnHeight; // * (72 / mnDPIY); - // watch out for Fixed16.16 overflows - static const double fMaxHeight = 144.0; - if( fPointHeight <= fMaxHeight ) + // convert pixel units (as seen by upper layers) to typographic point units + double fScaledAtsHeight = pReqFont->mnHeight; + // avoid Fixed16.16 overflows by limiting the ATS font size + static const double fMaxAtsHeight = 144.0; + if( fScaledAtsHeight <= fMaxAtsHeight ) mfFontScale = 1.0; else { - mfFontScale = fPointHeight / fMaxHeight; - fPointHeight = fMaxHeight; + mfFontScale = fScaledAtsHeight / fMaxAtsHeight; + fScaledAtsHeight = fMaxAtsHeight; } - Fixed fSize = FloatToFixed( fPointHeight ); + Fixed fFixedSize = FloatToFixed( fScaledAtsHeight ); // enable bold-emulation if needed Boolean bFakeBold = FALSE; if( (pReqFont->GetWeight() >= WEIGHT_BOLD) @@ -1554,8 +1567,11 @@ if( pReqFont->mbNonAntialiased ) nStyleRenderingOptions |= kATSStyleNoAntiAliasing; + // prepare ATS-fontid as type matching to the kATSUFontTag request ATSUFontID nFontID = static_cast(pMacFont->GetFontId()); + // update ATSU style attributes with requested font parameters + const ATSUAttributeTag aTag[] = { kATSUFontTag, @@ -1568,7 +1584,7 @@ const ByteCount aValueSize[] = { sizeof(ATSUFontID), - sizeof(fSize), + sizeof(fFixedSize), sizeof(bFakeBold), sizeof(bFakeItalic), sizeof(nStyleRenderingOptions) @@ -1576,17 +1592,17 @@ const ATSUAttributeValuePtr aValue[] = { - &nFontID, // the original font id - &fSize, // the requested attributes + &nFontID, + &fFixedSize, &bFakeBold, &bFakeItalic, &nStyleRenderingOptions }; - OSStatus err = ATSUSetAttributes( maATSUStyle, + OSStatus eStatus = ATSUSetAttributes( maATSUStyle, sizeof(aTag) / sizeof(ATSUAttributeTag), aTag, aValueSize, aValue ); - DBG_ASSERT( (err==noErr), "AquaSalGraphics::SetFont() : Could not set font attributes!\n"); + DBG_ASSERT( (eStatus==noErr), "AquaSalGraphics::SetFont() : Could not set font attributes!\n"); // prepare font stretching const ATSUAttributeTag aMatrixTag = kATSUFontMatrixTag; @@ -1599,8 +1615,8 @@ CGAffineTransform aMatrix = CGAffineTransformMakeScale( fStretch, 1.0F ); const ATSUAttributeValuePtr aAttr = &aMatrix; const ByteCount aMatrixBytes = sizeof(aMatrix); - err = ATSUSetAttributes( maATSUStyle, 1, &aMatrixTag, &aMatrixBytes, &aAttr ); - DBG_ASSERT( (err==noErr), "AquaSalGraphics::SetFont() : Could not set font matrix\n"); + eStatus = ATSUSetAttributes( maATSUStyle, 1, &aMatrixTag, &aMatrixBytes, &aAttr ); + DBG_ASSERT( (eStatus==noErr), "AquaSalGraphics::SetFont() : Could not set font matrix\n"); } // prepare font rotation diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salgdiutils.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salgdiutils.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salgdiutils.cxx 2007-08-03 16:02:31.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salgdiutils.cxx 2007-08-13 13:42:03.000000000 +0200 @@ -36,9 +36,8 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#ifndef _SV_SALGDI_H #include -#endif +#include #include #include @@ -55,29 +54,25 @@ // ---------------------------------------------------------------------- -void AquaSalGraphics::SetWindowGraphics( CarbonViewRef rView, CarbonWindowRef rWindow, bool bScreenCompatible ) +void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame ) { - mrView = rView; - mrWindow = rWindow; - mbScreen = bScreenCompatible; + mpFrame = pFrame; mbWindow = true; mbPrinter = false; mbVirDev = false; } -void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY ) +void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY, double fScale ) { - mrView = 0; - mbScreen = false; - mbWindow = false; mbPrinter = true; mbVirDev = false; mrContext = xContext; - mnDPIX = nDPIX; - mnDPIY = nDPIY; + mfFakeDPIScale = fScale; + mnRealDPIX = nDPIX; + mnRealDPIY = nDPIY; if( mrContext ) { @@ -94,9 +89,6 @@ void AquaSalGraphics::SetVirDevGraphics( CGContextRef xContext, bool bScreenCompatible ) { - mrView = 0; - mbScreen = bScreenCompatible; - mbWindow = false; mbPrinter = false; mbVirDev = true; @@ -183,19 +175,16 @@ } CGContextSetShouldAntialias( mrContext, false ); - } // ---------------------------------------------------------------------- bool AquaSalGraphics::CheckContext() { - if( mrWindow != NULL ) + if( mpFrame != NULL ) { - Rect windowBounds; - GetWindowPortBounds( mrWindow, &windowBounds ); - const unsigned int nWidth = windowBounds.right - windowBounds.left; - const unsigned int nHeight = windowBounds.bottom - windowBounds.top; + const unsigned int nWidth = mpFrame->maGeometry.nWidth; + const unsigned int nHeight = mpFrame->maGeometry.nHeight; CGContextRef rReleaseContext = 0; unsigned int nReleaseContextWidth = 0; @@ -278,31 +267,13 @@ if( ! mbWindow ) // view only on Window graphics return; - AquaLog("-->%s refresh %d - %d - %d - %d\n", __func__, static_cast(lX), static_cast(lY), static_cast(lWidth), static_cast(lHeight)); - - // Refresh windows rect content - HIRect aHIRect; - aHIRect.origin.x = static_cast(lX); - aHIRect.origin.y = static_cast(lY); - aHIRect.size.width = static_cast(lWidth); - aHIRect.size.height = static_cast(lHeight); - OSStatus retVal = HIViewSetNeedsDisplayInRect(mrView,&aHIRect,true); - if (retVal) - AquaLog( "FIXME: HIViewSetNeedsDisplayInRect returned %d (mrView is %p)\n", (int) retVal, mrView); - - Rect aRect; - aRect.left = (short)lX; - aRect.top = (short)lY; - aRect.right = (short)(lX + lWidth ); - aRect.bottom = (short)(lY + lHeight ); - InvalWindowRect(mrWindow, &aRect); -} - -void AquaSalGraphics::Flush() -{ - if( mbWindow ) + if( mpFrame ) { - UpdateWindow(); + // update a little more around the designated rectangle + // this helps with antialiased rendering + NSRect aRect = { { lX-1, lY-1 }, { lWidth+2, lHeight+2 } }; + mpFrame->VCLToCocoa( aRect, false ); + [mpFrame->getView() setNeedsDisplayInRect: aRect]; } } @@ -324,22 +295,20 @@ // ----------------------------------------------------------------------- -void AquaSalGraphics::UpdateWindow() +void AquaSalGraphics::UpdateWindow( NSGraphicsContext* pContext ) { - if( mrContext != NULL && mrWindow != NULL ) + if( mrContext != NULL && mpFrame != NULL && pContext != nil ) { - SetPortWindowPort(mrWindow); - CGContextRef xWindowContext = 0; - if( noErr == QDBeginCGContext (GetWindowPort (mrWindow), &xWindowContext)) - { - Rect windowBounds; - GetWindowPortBounds( mrWindow, &windowBounds); - CGImageRef xImage = CGBitmapContextCreateImage( mrContext ); - CGContextDrawImage(xWindowContext, CGRectMake(windowBounds.left, windowBounds.top, windowBounds.right - windowBounds.left, windowBounds.bottom - windowBounds.top ), xImage); - CGImageRelease(xImage); - CGContextFlush( xWindowContext ); - QDEndCGContext (GetWindowPort(mrWindow), &xWindowContext); - } + CGContextRef rCGContext = reinterpret_cast([pContext graphicsPort]); + CGRect aBitmapRect = { + { 0, 0 }, + { CGBitmapContextGetWidth(mrContext), CGBitmapContextGetHeight(mrContext) } + }; + + CGImageRef xImage = CGBitmapContextCreateImage( mrContext ); + CGContextDrawImage( rCGContext, aBitmapRect, xImage ); + CGImageRelease( xImage ); + CGContextFlush( rCGContext ); } } diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salnativewidgets.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salnativewidgets.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salnativewidgets.cxx 2007-08-03 16:02:52.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salnativewidgets.cxx 2007-08-23 14:20:08.000000000 +0200 @@ -63,6 +63,28 @@ * AquaGet* are helpers for native controls */ +ControlPart ImplgetCounterPart( ControlPart nPart ) +{ + ControlPart nCounterPart = 0; + switch (nPart) + { + case PART_BUTTON_UP: + nCounterPart = PART_BUTTON_DOWN; + break; + case PART_BUTTON_DOWN: + nCounterPart = PART_BUTTON_UP; + break; + case PART_BUTTON_LEFT: + nCounterPart = PART_BUTTON_RIGHT; + break; + case PART_BUTTON_RIGHT: + nCounterPart = PART_BUTTON_LEFT; + break; + } + return nCounterPart; +} + + // Helper returns an HIRect HIRect ImplGetHIRectFromRectangle(Rectangle aRect) @@ -80,10 +102,10 @@ Rectangle ImplGetRectangleFromHIRect( HIRect aHIRect ) { Rectangle aRect; - aRect.Top() = static_cast(aHIRect.origin.y); - aRect.Left() = static_cast(aHIRect.origin.x); - aRect.Bottom() = static_cast(aHIRect.size.height) + static_cast(aHIRect.origin.y); - aRect.Right() = static_cast(aHIRect.origin.x) + static_cast(aHIRect.size.width); + aRect.Top() = static_cast(aHIRect.origin.y); + aRect.Left() = static_cast(aHIRect.origin.x); + aRect.Bottom() = static_cast(aHIRect.size.height) + static_cast(aHIRect.origin.y); + aRect.Right() = static_cast(aHIRect.origin.x) + static_cast(aHIRect.size.width); return aRect; } @@ -103,18 +125,25 @@ static bool isAppleScrollBarVariantDoubleMax(void) { bool isDoubleMax = true; // default is DoubleMax - CFStringRef ScrollBarVariant; - - ScrollBarVariant = ( (CFStringRef)CFPreferencesCopyAppValue(CFSTR("AppleScrollBarVariant"), kCFPreferencesCurrentApplication) ); - if ( ScrollBarVariant ) + CFStringRef AppleScrollBarType = CFSTR("AppleScrollBarVariant"); + if (AppleScrollBarType) { - if ( !CFStringCompare(ScrollBarVariant, CFSTR("DoubleMax"), kCFCompareCaseInsensitive) ) - isDoubleMax = true; - else - isDoubleMax = false; - CFRelease( ScrollBarVariant ); + CFStringRef ScrollBarVariant = ((CFStringRef)CFPreferencesCopyAppValue( AppleScrollBarType, kCFPreferencesCurrentApplication )); + if (ScrollBarVariant) + { + CFStringRef DoubleMax = CFSTR("DoubleMax"); + if (DoubleMax) + { + if ( !CFStringCompare(ScrollBarVariant, CFSTR("DoubleMax"), kCFCompareCaseInsensitive) ) + isDoubleMax = true; + else + isDoubleMax = false; + CFRelease(DoubleMax); + } + CFRelease( ScrollBarVariant ); + } + CFRelease(AppleScrollBarType); } - return isDoubleMax; } @@ -263,6 +292,7 @@ case CTRL_PUSHBUTTON: case CTRL_RADIOBUTTON: case CTRL_CHECKBOX: + case CTRL_LISTNODE: if( nPart == PART_ENTIRE_CONTROL ) return true; break; @@ -294,19 +324,19 @@ return true; break; - case CTRL_SPINBUTTONS: // ** TO DO ** + case CTRL_SPINBUTTONS: if( nPart == PART_ENTIRE_CONTROL || nPart == PART_ALL_BUTTONS ) return false; break; - case CTRL_COMBOBOX: // ** TO DO ** + case CTRL_COMBOBOX: if( nPart == PART_ENTIRE_CONTROL || nPart == HAS_BACKGROUND_TEXTURE ) return true; break; - case CTRL_LISTBOX: // ** TO DO ** + case CTRL_LISTBOX: if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW || nPart == HAS_BACKGROUND_TEXTURE || @@ -340,12 +370,12 @@ return true; break; - case CTRL_MENUBAR: // ** TO DO + CHECK IF NEEDED ** + case CTRL_MENUBAR: if( nPart == PART_ENTIRE_CONTROL ) return true; break; - case CTRL_TOOLTIP: // ** TO DO + CHECK IF NEEDED ** + case CTRL_TOOLTIP: // ** TO DO #if 0 if( nPart == PART_ENTIRE_CONTROL ) // we don't currently support the tooltip return true; @@ -360,6 +390,7 @@ return true; break; case CTRL_PROGRESS: + case CTRL_INTROPROGRESS: if( nPart == PART_ENTIRE_CONTROL ) return true; break; @@ -367,6 +398,10 @@ if( nPart == PART_BORDER ) return true; break; + case CTRL_LISTNET: + if( nPart == PART_ENTIRE_CONTROL ) + return true; + break; } return bOk; @@ -389,22 +424,8 @@ // outside by default rIsInside = FALSE; - ControlPart nCounterPart = 0; - switch (nPart) - { - case PART_BUTTON_UP: - nCounterPart = PART_BUTTON_DOWN; - break; - case PART_BUTTON_DOWN: - nCounterPart = PART_BUTTON_UP; - break; - case PART_BUTTON_LEFT: - nCounterPart = PART_BUTTON_RIGHT; - break; - case PART_BUTTON_RIGHT: - nCounterPart = PART_BUTTON_LEFT; - break; - } + ControlPart nCounterPart = ImplgetCounterPart( nPart ); + // make position relative to rControlRegion // [ericb] rControlRegion.GetBoundRect() returns the rectangle where vcl control is located @@ -772,7 +793,35 @@ bOK = true; } break; + + case CTRL_LISTNODE: + { + HIThemeButtonDrawInfo aInfo; + aInfo.version = 0; + aInfo.kind = kThemeDisclosureButton; + aInfo.state = getState( nState ); + + aInfo.adornment = kThemeAdornmentNone; + + ButtonValue aButtonValue = aValue.getTristateVal(); + + switch( aButtonValue ) { + case BUTTONVALUE_ON: aInfo.value = kThemeDisclosureDown;//expanded + break; + case BUTTONVALUE_OFF: aInfo.value = kThemeDisclosureRight;//collapsed + break; + case BUTTONVALUE_DONTKNOW: //what to do? + default: + break; + } + + HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL ); + bOK = true; + } + break; + case CTRL_PROGRESS: + case CTRL_INTROPROGRESS: { long nProgressWidth = aValue.getNumericVal(); HIThemeTrackDrawInfo aTrackInfo; @@ -807,6 +856,13 @@ HIThemeTrackDrawInfo aTrackDraw; aTrackDraw.version = 0; aTrackDraw.kind = kThemeMediumScrollBar; + + // FIXME: the scrollbar length must be adjusted + if (nPart == PART_DRAW_BACKGROUND_VERT) + rc.size.height += 2; + else + rc.size.width += 2; + aTrackDraw.bounds = rc; aTrackDraw.min = pScrollbarVal->mnMin; aTrackDraw.max = pScrollbarVal->mnMax - pScrollbarVal->mnVisibleSize; @@ -1131,6 +1187,13 @@ } } break; + + case CTRL_LISTNET: + { + //do nothing as there isn't net for listviews on macos + bOK=true; + } + break; } @@ -1189,6 +1252,64 @@ switch (nType) { + case CTRL_SCROLLBAR: + { + Rectangle button_Part = AquaGetScrollButtonRect( /* m_nScreen, implement me */ nPart, rControlRegion.GetBoundRect() ); + + if ( (nPart==PART_BUTTON_DOWN) || (nPart==PART_BUTTON_RIGHT) ) // nothing to do + { + rNativeBoundingRegion = button_Part; + rNativeContentRegion = rNativeBoundingRegion; + toReturn = TRUE; + + } + + else if ((nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_LEFT) ) + { + if ( isAppleScrollBarVariantDoubleMax() == true ) + { + ControlPart nCounterPart = ImplgetCounterPart( nPart ); + Rectangle button_CounterPart = AquaGetScrollButtonRect( /* m_nScreen, implement me */ nCounterPart, rControlRegion.GetBoundRect() ); + Rectangle button_Part2; + + switch (nPart) + { + case PART_BUTTON_UP: + { + button_Part2.Top() = button_Part.Top(); + button_Part2.Left() = button_CounterPart.Left(); + button_Part2.Right() = button_CounterPart.Right(); + button_Part2.Bottom() = button_Part.Top() + 4; // FIXME: magic to simulate the border of the scrollbar + } + break; + + case PART_BUTTON_LEFT: + { + button_Part2.Top() = button_CounterPart.Top(); + button_Part2.Left() = button_Part.Left(); + button_Part2.Right() = button_Part.Left() + 4; // FIXME: magic to simulate the border of the scrollbar + button_Part2.Bottom() = button_CounterPart.Bottom(); + } + break; + } + + rNativeBoundingRegion = button_Part2; + rNativeContentRegion = rNativeBoundingRegion; + toReturn = TRUE; + } + else + { + rNativeBoundingRegion = button_Part; + rNativeContentRegion = rNativeBoundingRegion; + toReturn = TRUE; + + } + } + else + toReturn = FALSE; + } + break; + case CTRL_PUSHBUTTON: case CTRL_RADIOBUTTON: case CTRL_CHECKBOX: @@ -1228,6 +1349,16 @@ } break; + case CTRL_INTROPROGRESS: + { + Rectangle aRect( rControlRegion.GetBoundRect() ); + aRect.Bottom() = aRect.Top() + 9; // values taken from HIG for medium progress + rNativeBoundingRegion = aRect; + rNativeContentRegion = aRect; + toReturn = TRUE; + } + break; + case CTRL_TAB_ITEM: w = rControlRegion.GetBoundRect().GetWidth() + 2*TAB_TEXT_OFFSET - 2*VCL_TAB_TEXT_OFFSET; diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salprn.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salprn.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salprn.cxx 2007-07-05 12:20:17.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salprn.cxx 2007-08-13 13:42:03.000000000 +0200 @@ -121,17 +121,21 @@ { if( mrPageFormat ) { - PMResolution aRes; - if( PMGetResolution( mrPageFormat, &aRes ) != noErr ) - aRes.hRes = aRes.vRes = 72.0; + PMResolution aRealRes; + if( PMGetResolution( mrPageFormat, &aRealRes ) != noErr ) + aRealRes.hRes = aRealRes.vRes = 72.0; // a reported resolution of 72 dpi ist most likely not good for // formatting and downscaling images // so assume a reasonable default resolution for a printer - if( aRes.hRes == 72.0 ) - aRes.hRes = 720.0; - if( aRes.vRes == 72.0 ) - aRes.vRes = 720.0; + PMResolution aFakeRes = aRealRes; + if( aFakeRes.hRes < 300.0 ) + aFakeRes.hRes = 720.0; + if( aFakeRes.vRes < 300.0 ) + aFakeRes.vRes = 720.0; + + const double fXScaling = aRealRes.hRes / aFakeRes.hRes; + const double fYScaling = aRealRes.vRes / aFakeRes.vRes; // mirror context so it fits OOo's coordinate space // get page height @@ -146,18 +150,18 @@ { case kPMLandscape: CGContextTranslateCTM( i_rContext, aRect.bottom, -aRect.left ); - CGContextScaleCTM( i_rContext, -72.0/aRes.vRes, 72.0/aRes.hRes ); + CGContextScaleCTM( i_rContext, -fYScaling, +fXScaling ); break; default: DBG_ERROR( "unhandled orientation, defaulting to portrait" ); case kPMPortrait: CGContextTranslateCTM( i_rContext, -aRect.left, aRect.bottom ); - CGContextScaleCTM( i_rContext, 72.0/aRes.hRes, -72.0/aRes.vRes ); + CGContextScaleCTM( i_rContext, +fXScaling, -fYScaling ); break; } } - mpGraphics->SetPrinterGraphics( i_rContext, static_cast(aRes.hRes), static_cast(aRes.vRes) ); + mpGraphics->SetPrinterGraphics( i_rContext, static_cast(aRealRes.hRes), static_cast(aRealRes.vRes), aFakeRes.vRes/aRealRes.vRes ); } else DBG_ERROR( "no page format in SetupPrinterGraphics" ); @@ -238,7 +242,6 @@ break; } } - } return aPaper; diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salvd.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salvd.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/gdi/salvd.cxx 2007-08-03 16:03:27.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/gdi/salvd.cxx 2007-08-08 11:27:50.000000000 +0200 @@ -36,15 +36,12 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#ifndef _SV_SALVD_HXX -#include -#endif -#ifndef _SV_SALVD_H -#include -#endif -#ifndef _SV_SALINST_H -#include -#endif +#include "salvd.h" +#include "salinst.h" +#include "salgdi.h" +#include "saldata.hxx" + +#include "vcl/sysdata.hxx" // ----------------------------------------------------------------------- diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/window/salframe.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/window/salframe.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/window/salframe.cxx 2007-08-03 16:03:49.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/window/salframe.cxx 2007-08-13 17:00:27.000000000 +0200 @@ -1,4 +1,4 @@ -/************************************************************************* +/*n*********************************************************************** * * OpenOffice.org - a multi-platform office productivity suite * @@ -36,108 +36,56 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include - -#ifndef _SV_SALDATA_HXX -#include -#endif -#ifndef _SV_SALGDI_HXX -#include -#endif -#ifndef _SV_SALGDI_H -#include -#endif -#ifndef _SV_SALFRAME_H -#include -#endif -#ifndef _SV_SALMENU_H -#include -#endif -#ifndef _SV_SALTIMER_H -#include -#endif -#ifndef _SV_SALINST_H -#include -#endif -#ifndef _SV_SALWTYPE_HXX -#include -#endif - -#include -#include - #include -#include -#include -#include +#include "saldata.hxx" +#include "salgdi.h" +#include "salframe.h" +#include "salmenu.h" +#include "saltimer.h" +#include "salinst.h" +#include "vcl/salwtype.hxx" + +#include "boost/assert.hpp" +#include "vcl/svapp.hxx" +#include "rtl/ustrbuf.hxx" using namespace std; // ======================================================================= -AquaSalFrame::SysWindowEventHandlerData_t AquaSalFrame::s_aOverlayEvtHandler; -AquaSalFrame* AquaSalFrame::s_pCaptureFrame = NULL; -CarbonWindowRef AquaSalFrame::s_rOverlay = 0; - +AquaSalFrame* AquaSalFrame::s_pCaptureFrame = NULL; -static void ImplSalCalcFullScreenSize( const AquaSalFrame* pFrame, Rect* pSize ) -{ - /** FIXME ** - * Implement multiple displays here. That's why a pointer - * to frame is passed. But pointer not currently used. - **/ - CGDirectDisplayID mainDisplayID = CGMainDisplayID(); - AquaLog("Display ID %p\n", mainDisplayID); - - CGRect rect; - rect = CGDisplayBounds( mainDisplayID ); - AquaLog( "Screen resolution: %.0fx%.0f\n", rect.size.width, rect.size.height ); - - // Stores current resolution in pSize. - // Rect made out of ints -> cast required -> CGRect made out of floats. - pSize->top = 0; - pSize->left = 0; - pSize->bottom = static_cast(rect.size.height); - pSize->right = static_cast(rect.size.width); -} // ======================================================================= -// Returns the free area excluding the Dock (when displayed) and main menubar - -static void ImplSalCalcMaxClientSize( const AquaSalFrame* pFrame, Rect* pSize ) -{ - GetAvailableWindowPositioningBounds(NULL, pSize); -} - -// ======================================================================= - -AquaSalFrame::AquaSalFrame(SalFrame* pParent, ULONG salFrameStyle, AquaSalInstance* pSalInstance) : - mrWindow(0), +AquaSalFrame::AquaSalFrame( SalFrame* pParent, ULONG salFrameStyle ) : + mpWindow(nil), + mpView(nil), + mpDockMenuEntry(nil), mpGraphics(NULL), mpParent(NULL), - mpInst(NULL), - mnWidth(0), - mnHeight(0), mnMinWidth(0), mnMinHeight(0), mnMaxWidth(0), mnMaxHeight(0), mbGraphics(FALSE), - mpSalInstance(pSalInstance), mbShown(false), mbInitShow(true), mbPositioned(false), mbSized(false), mnStyle( salFrameStyle ), - maTsmDocumentId(0), - mpMenu(NULL) + mnStyleMask( 0 ), + mnLastEventTime( 0 ), + mnLastModifierFlags( 0 ), + mpMenu( NULL ), + mnExtStyle( 0 ) { maSysData.nSize = sizeof( SystemEnvData ); mpParent = dynamic_cast(pParent); - CreateNewSystemWindow(mpParent ? mpParent->mrWindow : NULL, salFrameStyle); + + initWindowAndView(); SalData* pSalData = GetSalData(); pSalData->maFrames.push_front( this ); @@ -148,8 +96,6 @@ AquaSalFrame::~AquaSalFrame() { - AquaLog( ">*>_> %s %p\n",__func__, this); - SalData* pSalData = GetSalData(); pSalData->maFrames.remove( this ); pSalData->maFrameCheck.erase( this ); @@ -157,17 +103,125 @@ if ( mpGraphics ) delete mpGraphics; - if (mrWindow) + if( mpDockMenuEntry ) + // life cycle comment: the menu has ownership of the item, so no release + [AquaSalInstance::GetDynamicDockMenu() removeItem: mpDockMenuEntry]; + if( mpView ) + [mpView release]; + if (mpWindow) + [mpWindow release]; +} + +// ----------------------------------------------------------------------- + +void AquaSalFrame::initWindowAndView() +{ + // initialize mirroring parameters + // FIXME: multiple screens, screens changing + maScreenRect = [[NSScreen mainScreen] frame]; + + // calculate some default geometry + NSRect aVisibleRect = [[NSScreen mainScreen] visibleFrame]; + CocoaToVCL( aVisibleRect ); + + maGeometry.nX = aVisibleRect.origin.x + aVisibleRect.size.width / 10; + maGeometry.nY = aVisibleRect.origin.y + aVisibleRect.size.height / 10; + maGeometry.nWidth = static_cast(aVisibleRect.size.width * 0.8); + maGeometry.nHeight = static_cast(aVisibleRect.size.height * 0.8); + + // calculate style mask + if( (mnStyle & SAL_FRAME_STYLE_FLOAT) || + (mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) + mnStyleMask = NSBorderlessWindowMask; + else if( mnStyle & SAL_FRAME_STYLE_DEFAULT ) + { + mnStyleMask = NSTitledWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask | + NSClosableWindowMask; + // make default window "maximized" + maGeometry.nX = aVisibleRect.origin.x; + maGeometry.nY = aVisibleRect.origin.y; + maGeometry.nWidth = aVisibleRect.size.width; + maGeometry.nHeight = aVisibleRect.size.height; + mbPositioned = mbSized = true; + } + else { - HideWindow(mrWindow); - DeinstallAndUnregisterAllEventHandler(); - ReleaseWindow(mrWindow); + if( (mnStyle & SAL_FRAME_STYLE_MOVEABLE) ) + { + mnStyleMask |= NSTitledWindowMask; + if( mpParent == NULL ) + mnStyleMask |= NSMiniaturizableWindowMask; + } + if( (mnStyle & SAL_FRAME_STYLE_SIZEABLE) ) + mnStyleMask |= NSResizableWindowMask; + if( (mnStyle & SAL_FRAME_STYLE_CLOSEABLE) ) + mnStyleMask |= NSClosableWindowMask; + // documentation says anything other than NSBorderlessWindowMask (=0) + // should also include NSTitledWindowMask; + if( mnStyleMask != 0 ) + mnStyleMask |= NSTitledWindowMask; + } + + mpWindow = [[SalFrameWindow alloc] initWithSalFrame: this]; + mpView = [[SalFrameView alloc] initWithSalFrame: this]; + [mpWindow setContentView: mpView]; + [mpWindow setAcceptsMouseMovedEvents: YES]; + [mpWindow setHasShadow: YES]; + [mpWindow setDelegate: mpWindow]; + + // create an entry in the dock menu + const ULONG nAppWindowStyle = (SAL_FRAME_STYLE_CLOSEABLE | SAL_FRAME_STYLE_MOVEABLE); + if( mpParent == NULL && + (mnStyle & nAppWindowStyle) == nAppWindowStyle ) + { + NSMenu* pDock = AquaSalInstance::GetDynamicDockMenu(); + mpDockMenuEntry = [pDock insertItemWithTitle: @"" + action: @selector(dockMenuItemTriggered:) + keyEquivalent: @"" + atIndex: [pDock numberOfItems]]; + [mpDockMenuEntry setTarget: mpWindow]; + + // TODO: image (either the generic window image or an icon + // check mark (for "main" window ?) } + + UpdateFrameGeometry(); +} + +// ----------------------------------------------------------------------- + +void AquaSalFrame::CocoaToVCL( NSRect& io_rRect, bool bRelativeToScreen ) +{ + if( bRelativeToScreen ) + io_rRect.origin.y = maScreenRect.size.height - (io_rRect.origin.y+io_rRect.size.height); + else + io_rRect.origin.y = maGeometry.nHeight - (io_rRect.origin.y+io_rRect.size.height); +} - if (maTsmDocumentId) - DeleteTSMDocument(maTsmDocumentId); +void AquaSalFrame::VCLToCocoa( NSRect& io_rRect, bool bRelativeToScreen ) +{ + if( bRelativeToScreen ) + io_rRect.origin.y = maScreenRect.size.height - (io_rRect.origin.y+io_rRect.size.height); + else + io_rRect.origin.y = maGeometry.nHeight - (io_rRect.origin.y+io_rRect.size.height); +} - AquaLog( ">*>_> %s %p end of destructor\n",__func__, this); +void AquaSalFrame::CocoaToVCL( NSPoint& io_rPoint, bool bRelativeToScreen ) +{ + if( bRelativeToScreen ) + io_rPoint.y = maScreenRect.size.height - io_rPoint.y; + else + io_rPoint.y = maGeometry.nHeight - io_rPoint.y; +} + +void AquaSalFrame::VCLToCocoa( NSPoint& io_rPoint, bool bRelativeToScreen ) +{ + if( bRelativeToScreen ) + io_rPoint.y = maScreenRect.size.height - io_rPoint.y; + else + io_rPoint.y = maGeometry.nHeight - io_rPoint.y; } // ----------------------------------------------------------------------- @@ -179,23 +233,8 @@ if ( !mpGraphics ) { - CarbonViewRef hView = NULL; - - OSL_ENSURE(mrWindow, "windowless frame !!!"); - - // create root control if it does not exist - // however, this is currently not used - OSErr errval = GetRootControl( mrWindow, &hView ); - if( errval == errNoRootControl ) - errval = CreateRootControl( mrWindow, &hView ); - - if( errval == noErr ) - { - mpGraphics = new AquaSalGraphics; - mpGraphics->SetWindowGraphics( hView, mrWindow, true ); - } - else - AquaLog( "could not get graphics (get/create root control returned %d)\n", errval); + mpGraphics = new AquaSalGraphics; + mpGraphics->SetWindowGraphics( this ); } mbGraphics = TRUE; @@ -206,65 +245,26 @@ void AquaSalFrame::ReleaseGraphics( SalGraphics *pGraphics ) { - AquaLog( ">*>_> %s\n",__func__); + DBG_ASSERT( pGraphics == mpGraphics, "graphics released on wrong frame" ); mbGraphics = FALSE; } // ----------------------------------------------------------------------- -BOOL AquaSalFrame::ImplPostUserEvent( UInt32 eventKind, void *pData ) -{ - //AquaLog( "implpost user event\n"); - - // Search for the parent SalFrame that has a native window and - // use that window to post the event to - AquaSalFrame *pFrame = this; - while (!pFrame->mrWindow) - { - pFrame = pFrame->mpParent; - if (!pFrame) - break; - } - - bool bret = false; - - if (pFrame) - { - EventRef eventRef; - if (CreateEvent(NULL, cOOoSalUserEventClass, eventKind, 0, kEventAttributeNone, &eventRef) == noErr) - { - EventTargetRef eventTargetRef = GetWindowEventTarget(pFrame->mrWindow); - if (SetEventParameter(eventRef, kEventParamPostTarget, typeEventTargetRef, sizeof(EventTargetRef), &eventTargetRef) == noErr && - SetEventParameter(eventRef, cOOoSalEventData, cOOoSalEventParamTypePtr, sizeof(pData), &pData) == noErr && - PostEventToQueue(GetMainEventQueue(), eventRef, kEventPriorityStandard) == noErr) - { - bret = true; - } - ReleaseEvent(eventRef); - } - } - return bret; -} - BOOL AquaSalFrame::PostEvent( void *pData ) { - AquaLog( ">*>_> %s\n",__func__); - return ImplPostUserEvent( cOOoSalEventUser, pData ); -} - -BOOL AquaSalFrame::PostTimerEvent( AquaSalTimer *pTimer ) -{ - //AquaLog( ">*>_> %s\n",__func__); - return ImplPostUserEvent( cOOoSalEventTimer, (void*) pTimer ); + GetSalData()->mpFirstInstance->PostUserEvent( this, SALEVENT_USEREVENT, pData ); + return TRUE; } // ----------------------------------------------------------------------- void AquaSalFrame::SetTitle(const XubString& rTitle) { - CFStringRef rStr = CreateCFString( rTitle ); - SetWindowTitleWithCFString(mrWindow, rStr); - if (rStr) - CFRelease(rStr); + NSString* pTitle = CreateNSString( rTitle ); + [mpWindow setTitle: pTitle]; + if( mpDockMenuEntry ) + [mpDockMenuEntry setTitle: pTitle]; + [pTitle release]; } // ----------------------------------------------------------------------- @@ -320,40 +320,25 @@ void AquaSalFrame::Show(BOOL bVisible, BOOL bNoActivate) { - BOOST_ASSERT(mrWindow && "Precondition violation - no window associated with frame yet"); - - AquaLog( ">*>_> %s(%s) %p (%ldx%ld)\n",__func__, bVisible ? "true" : "false", this, mnWidth, mnHeight ); + AquaLog( ">*>_> %s(%s) %p (%ldx%ld)\n",__func__, bVisible ? "true" : "false", this, maGeometry.nWidth, maGeometry.nHeight ); mbShown = bVisible; if(bVisible) { if( mbInitShow ) initShow(); - + + CallCallback(SALEVENT_RESIZE, 0); // trigger filling our backbuffer SendPaintEvent(); - ShowWindow(mrWindow); - if(!bNoActivate) - SelectWindow(mrWindow); //ActivateWindow(mrWindow, true); - - // FIXME: create empty menu bar for SalFrame without menu yet! - if (!mpMenu) - { - if (mpParent) //tooltips need the parent menu, else no menu shows - mpMenu = mpParent->mpMenu; - else - mpMenu = mpSalInstance->CreateMenu(TRUE); - } - - if (mpMenu) - { - AquaSalMenu *pAquaSalMenu = (AquaSalMenu *) mpMenu; - SetRootMenu(pAquaSalMenu->mrMenuRef); - } + if( bNoActivate ) + [mpWindow orderFront: NSApp]; + else + [mpWindow makeKeyAndOrderFront: NSApp]; } else - HideWindow(mrWindow); + [mpWindow orderOut: NSApp]; } // ----------------------------------------------------------------------- @@ -371,18 +356,18 @@ mnMinWidth = nWidth; mnMinHeight = nHeight; - if (mrWindow) + if( mpWindow ) { // Always add the decoration as the dimension concerns only // the content rectangle nWidth += maGeometry.nLeftDecoration + maGeometry.nRightDecoration; nHeight += maGeometry.nTopDecoration + maGeometry.nBottomDecoration; - CGSize nMinSize = CGSizeMake(nWidth, nHeight); + NSSize aSize = { nWidth, nHeight }; // Size of full window (content+structure) although we only // have the client size in arguments - SetWindowResizeLimits(mrWindow, &nMinSize, NULL); + [mpWindow setMinSize: aSize]; } } @@ -394,7 +379,7 @@ mnMaxWidth = nWidth; mnMaxHeight = nHeight; - if (mrWindow) + if( mpWindow ) { // Always add the decoration as the dimension concerns only // the content rectangle @@ -405,11 +390,11 @@ if (nWidth>32767) nWidth=32767; if (nHeight>32767) nHeight=32767; - CGSize nMaxSize = CGSizeMake(nWidth, nHeight); + NSSize aSize = { nWidth, nHeight }; // Size of full window (content+structure) although we only // have the client size in arguments - SetWindowResizeLimits(mrWindow, NULL, &nMaxSize); + [mpWindow setMaxSize: aSize]; } } @@ -418,24 +403,15 @@ void AquaSalFrame::SetClientSize( long nWidth, long nHeight ) { AquaLog( ">*>_> %s\n",__func__); - mnWidth = nWidth; - mnHeight = nHeight; - - // If this is a native window, resize it - if ( mrWindow ) + if( mpWindow ) { - Rect bounds; - GetWindowBounds( mrWindow, kWindowContentRgn, &bounds ); - if( bounds.right - bounds.left != nWidth || - bounds.bottom - bounds.top != nHeight ) - { - bounds.right = bounds.left + nWidth; - bounds.bottom = bounds.top + nHeight; - SetWindowBounds( mrWindow, kWindowContentRgn, &bounds ); - if( mbShown ) - // trigger filling our backbuffer - SendPaintEvent(); - } + NSSize aSize = { nWidth, nHeight }; + + [mpWindow setContentSize: aSize]; + UpdateFrameGeometry(); + if( mbShown ) + // trigger filling our backbuffer + SendPaintEvent(); } } @@ -444,8 +420,8 @@ void AquaSalFrame::GetClientSize( long& rWidth, long& rHeight ) { AquaLog( ">*>_> %s\n",__func__); - rWidth = mbShown ? mnWidth : 0; - rHeight = mbShown ? mnHeight : 0; + rWidth = mbShown ? maGeometry.nWidth : 0; + rHeight = mbShown ? maGeometry.nHeight : 0; } // ----------------------------------------------------------------------- @@ -454,33 +430,21 @@ { AquaLog( ">*>_> %s\n",__func__); - Rect aStateRect; // set normal state - GetWindowBounds( mrWindow, kWindowContentRgn, &aStateRect ); + NSRect aStateRect = [mpWindow frame]; + CocoaToVCL( aStateRect ); if( pState->mnMask & SAL_FRAMESTATE_MASK_X ) - aStateRect.left = short(pState->mnX); + aStateRect.origin.x = float(pState->mnX); if( pState->mnMask & SAL_FRAMESTATE_MASK_Y ) - aStateRect.top = short(pState->mnY); + aStateRect.origin.y = float(pState->mnY); if( pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH ) - aStateRect.right = aStateRect.left + short(pState->mnWidth); - else - aStateRect.right = aStateRect.left + maGeometry.nWidth; + aStateRect.size.width = float(pState->mnWidth); if( pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT ) - aStateRect.bottom = aStateRect.top + short(pState->mnHeight); - else - aStateRect.bottom = aStateRect.top + maGeometry.nHeight; - SetWindowBounds( mrWindow, kWindowContentRgn, &aStateRect ); + aStateRect.size.height = float(pState->mnHeight); + VCLToCocoa( aStateRect ); + [mpWindow setFrame: aStateRect display: FALSE]; // FIXME: HTH maximized state ? - - if( pState->mnMask & SAL_FRAMESTATE_MASK_STATE ) - { - if( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) - ZoomWindow( mrWindow, inZoomIn, false ); - if( (pState->mnState & SAL_FRAMESTATE_MINIMIZED) ) - CollapseWindow( mrWindow, true ); - } - if( mbShown ) // trigger filling our backbuffer SendPaintEvent(); @@ -519,18 +483,18 @@ #endif SAL_FRAMESTATE_MASK_STATE; - Rect aStateRect; - GetWindowBounds( mrWindow, kWindowContentRgn, &aStateRect ); - pState->mnX = long(aStateRect.left); - pState->mnY = long(aStateRect.top); - pState->mnWidth = long(aStateRect.right - aStateRect.left); - pState->mnHeight = long(aStateRect.bottom - aStateRect.top); + NSRect aStateRect = [mpWindow frame]; + CocoaToVCL( aStateRect ); + pState->mnX = long(aStateRect.origin.x); + pState->mnY = long(aStateRect.origin.y); + pState->mnWidth = long(aStateRect.size.width); + pState->mnHeight = long(aStateRect.size.height); // FIXME: HTH maximized state ? - if( IsWindowCollapsed( mrWindow ) || ! IsWindowVisible( mrWindow ) ) + if( [mpWindow isMiniaturized] ) pState->mnState = SAL_FRAMESTATE_MINIMIZED; - else if( IsWindowInStandardState( mrWindow, NULL, NULL ) ) + else if( ! [mpWindow isZoomed] ) pState->mnState = SAL_FRAMESTATE_NORMAL; else pState->mnState = SAL_FRAMESTATE_MAXIMIZED; @@ -548,22 +512,29 @@ return; mbFullScreen = bFullScreen; - AquaSalFrame* pFrame = this; if( bFullScreen ) { - Rect newBounds; - ImplSalCalcFullScreenSize( pFrame, &newBounds ); // Get new bounds - GetWindowAttributes( mrWindow, &maFullScreenAttr ); // Save attributes - ChangeWindowAttributes( mrWindow, kWindowNoAttributes, maFullScreenAttr ); - GetWindowBounds( mrWindow, kWindowContentRgn, &maFullScreenRect ); - SetWindowBounds( mrWindow, kWindowContentRgn, &newBounds ); + NSRect aNewContentRect = maScreenRect; + maFullScreenRect = [mpWindow frame]; + [mpWindow setFrame: [NSWindow frameRectForContentRect: aNewContentRect styleMask: mnStyleMask] display: YES]; + + UpdateFrameGeometry(); + if( mbShown ) + CallCallback( SALEVENT_MOVERESIZE, NULL ); + + // FIXME: replace by Cocoa calls SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar ); // -> Shows menubar when we move the mouse over it. } else { - SetWindowBounds( mrWindow, kWindowContentRgn, &maFullScreenRect ); - ChangeWindowAttributes( mrWindow, maFullScreenAttr, kWindowNoAttributes ); + [mpWindow setFrame: maFullScreenRect display: YES]; + + UpdateFrameGeometry(); + if( mbShown ) + CallCallback( SALEVENT_MOVERESIZE, NULL ); + + // FIXME: replace by Cocoa calls SetSystemUIMode( kUIModeNormal, nil ); } if( mbShown ) @@ -592,15 +563,13 @@ AquaLog( ">*>_> %s %p %d\n",__func__, this, (int)nFlags); if( ! (nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN) ) { - if( ! IsWindowVisible( mrWindow ) || IsWindowCollapsed( mrWindow ) ) + if( ! [mpWindow isVisible] || [mpWindow isMiniaturized] ) return; } - if( ! IsWindowVisible( mrWindow ) ) - ShowWindow( mrWindow ); if( nFlags & SAL_FRAME_TOTOP_GRABFOCUS ) - SelectWindow( mrWindow ); + [mpWindow makeKeyAndOrderFront: NSApp]; else - BringToFront( mrWindow ); + [mpWindow orderFront: NSApp]; } // ----------------------------------------------------------------------- @@ -715,6 +684,7 @@ #error New Pointer must be defined! #endif +// FIXME: use Cocoa pointers SetThemeCursor(aPointer[ePointerStyle]); } @@ -723,6 +693,8 @@ void AquaSalFrame::SetPointerPos( long nX, long nY ) { + // FIXME: use Cocoa functions + AquaLog( ">*>_> %s\n",__func__); // FIXME: multiscreen support @@ -735,9 +707,7 @@ void AquaSalFrame::Flush() { - AquaLog( ">*>_> %s\n",__func__); - if( mbGraphics && mpGraphics ) - mpGraphics->Flush(); + Sync(); } // ----------------------------------------------------------------------- @@ -745,8 +715,11 @@ void AquaSalFrame::Sync() { AquaLog( ">*>_> %s\n",__func__); - if( mbGraphics && mpGraphics ) - mpGraphics->Flush(); + if( mbGraphics && mpGraphics && mpView ) + { + [mpView setNeedsDisplay: YES]; + [mpView display]; + } } // ----------------------------------------------------------------------- @@ -759,18 +732,9 @@ return; if(!(pContext->mnOptions & SAL_INPUTCONTEXT_TEXT)) - return; - - // create a new im context - if (!maTsmDocumentId) - { - InterfaceTypeList typeList; - typeList[0] = kUnicodeDocumentInterfaceType; + return; - NewTSMDocument(1, typeList, &maTsmDocumentId, (long)pContext); - AquaLog( "create NewTSMDocument\n"); - ActivateTSM(); - } + // FIXME: implementation } // ----------------------------------------------------------------------- @@ -986,17 +950,17 @@ return eScriptCode; } -static bool GetSystemFontSetting( ThemeFontID eThemeFontID, Font* pFont ) +static bool GetSystemFontSetting( ThemeFontID eThemeFontID, int nDPIY, Font* pFont ) { // TODO: also allow non-roman font names Str255 aFontFamilyName = ""; Str255 aFontStyleName = ""; - SInt16 nFontSize; + SInt16 nFontPixelSize; const rtl_TextEncoding eNameEncoding = RTL_TEXTENCODING_APPLE_ROMAN; ScriptCode eScriptCode = GetScriptCodeForUiLocale(); - OSStatus eStatus = AquaGetThemeFont( eThemeFontID, eScriptCode, aFontFamilyName, &nFontSize, aFontStyleName ); - AquaLog("GetSystemFontSetting(%d) => err=%d => (\"%s\", \"%s\", h=%d)\n",eThemeFontID,eStatus,aFontFamilyName+1,aFontStyleName+1,nFontSize); + OSStatus eStatus = AquaGetThemeFont( eThemeFontID, eScriptCode, aFontFamilyName, &nFontPixelSize, aFontStyleName ); + AquaLog("GetSystemFontSetting(id=%d) => err=%d => (\"%s\", \"%s\", h=%d)\n",eThemeFontID,eStatus,aFontFamilyName+1,aFontStyleName+1,nFontPixelSize); if( eStatus != noErr ) return false; @@ -1025,7 +989,9 @@ pFont->SetName( String( oNameString, eNameEncoding ) ); pFont->SetStyleName( String( (const sal_Char*)aFontStyleName+1, aFontStyleName[0], eNameEncoding ) ); - pFont->SetHeight( nFontSize ); + + const long nFontPointSize = static_cast(nFontPixelSize * 72.0 / nDPIY); + pFont->SetHeight( nFontPointSize ); return true; } @@ -1064,7 +1030,10 @@ // get the system font settings Font aFont = aStyleSettings.GetAppFont(); - if( GetSystemFontSetting( kThemeApplicationFont, &aFont ) ) + GetGraphics(); + long nDPIX = 72, nDPIY = 72; + mpGraphics->GetResolution( nDPIX, nDPIY ); + if( GetSystemFontSetting( kThemeApplicationFont, nDPIY, &aFont ) ) { // TODO: better mapping of aqua<->ooo font settings aStyleSettings.SetAppFont( aFont ); @@ -1072,13 +1041,13 @@ aStyleSettings.SetTitleFont( aFont ); aStyleSettings.SetFloatTitleFont( aFont ); - GetSystemFontSetting( kThemeMenuItemFont, &aFont ); + GetSystemFontSetting( kThemeMenuItemFont, nDPIY, &aFont ); aStyleSettings.SetMenuFont( aFont ); - GetSystemFontSetting( kThemeToolbarFont, &aFont ); + GetSystemFontSetting( kThemeToolbarFont, nDPIY, &aFont ); aStyleSettings.SetToolFont( aFont ); - GetSystemFontSetting( kThemeLabelFont, &aFont ); + GetSystemFontSetting( kThemeLabelFont, nDPIY, &aFont ); aStyleSettings.SetLabelFont( aFont ); aStyleSettings.SetInfoFont( aFont ); aStyleSettings.SetRadioCheckFont( aFont ); @@ -1086,7 +1055,7 @@ aStyleSettings.SetGroupFont( aFont ); aStyleSettings.SetIconFont( aFont ); - GetSystemFontSetting( kThemePushButtonFont, &aFont ); + GetSystemFontSetting( kThemePushButtonFont, nDPIY, &aFont ); aStyleSettings.SetPushButtonFont( aFont ); } @@ -1146,8 +1115,8 @@ */ USHORT nEvent = 0; - if (IsWindowCollapsed(mrWindow)) - CollapseWindow(mrWindow, false); // expand the window + if( [mpWindow isMiniaturized] ) + [mpWindow deminiaturize: NSApp]; // expand the window if (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) { @@ -1161,110 +1130,69 @@ nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE; } - Rect currentWindowRect; - GetWindowBounds(mrWindow, kWindowStructureRgn, ¤tWindowRect); - - Rect currentContentRect; - GetWindowBounds(mrWindow, kWindowContentRgn, ¤tContentRect); + NSRect aFrameRect = [mpWindow frame]; + NSRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; // position is always relative to parent frame - Rect parentContentRect; + NSRect aParentContentRect; if( mpParent ) - GetWindowBounds(mpParent->mrWindow, kWindowContentRgn, &parentContentRect); + { + NSRect aParentFrameRect = [mpParent->mpWindow frame]; + aParentContentRect = [NSWindow contentRectForFrameRect: aParentFrameRect styleMask: mpParent->mnStyleMask]; + } else - ImplSalCalcFullScreenSize( this, &parentContentRect); // use screen if no parent + aParentContentRect = maScreenRect; // use screen if no parent + + CocoaToVCL( aContentRect ); + CocoaToVCL( aParentContentRect ); bool bPaint = false; if( (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) != 0 ) { - if( nWidth != currentContentRect.right - currentContentRect.left || - nHeight != currentContentRect.bottom - currentContentRect.top ) + if( nWidth != aContentRect.size.width || nHeight != aContentRect.size.height ) bPaint = true; } // use old window pos if no new pos requested - if (!(nFlags & SAL_FRAME_POSSIZE_X)) - nX = currentWindowRect.left; - else - nX += parentContentRect.left; - - if (!(nFlags & SAL_FRAME_POSSIZE_Y)) - nY = currentWindowRect.top; - else - nY += parentContentRect.top; - - // use old window width if no new width requested - if (!(nFlags & SAL_FRAME_POSSIZE_WIDTH)) - nWidth = currentContentRect.right - currentContentRect.left; - - // use old window height if no new height requested - if (!(nFlags & SAL_FRAME_POSSIZE_HEIGHT)) - nHeight = currentContentRect.bottom - currentContentRect.top; - - // --- RTL --- (mirror window pos) - if( mpParent && Application::GetSettings().GetLayoutRTL() ) - { - // undo the change above - if( nFlags & SAL_FRAME_POSSIZE_X ) - nX -= parentContentRect.left; - // mirror - nX = parentContentRect.right - nWidth - nX; - } - - Rect newWindowRect; + if( (nFlags & SAL_FRAME_POSSIZE_X) != 0 ) + aContentRect.origin.x = nX + aParentContentRect.origin.x; + if( (nFlags & SAL_FRAME_POSSIZE_Y) != 0) + aContentRect.origin.y = nY + aParentContentRect.origin.y; + + // use old size if no new size requested + if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 ) + aContentRect.size.width = nWidth; + if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0) + aContentRect.size.height = nHeight; - newWindowRect.left = nX; - newWindowRect.top = nY; - - newWindowRect.right = nX + nWidth; - // always add the decoration as nWidth concerns only the content rect - newWindowRect.right += maGeometry.nLeftDecoration + maGeometry.nRightDecoration; - - newWindowRect.bottom = nY + nHeight; - // always add the decoration as nHeight concerns only the content rect - newWindowRect.bottom += maGeometry.nTopDecoration + maGeometry.nBottomDecoration; - + VCLToCocoa( aContentRect ); - - /* - AquaLog( "SetPosSize: Old rect (x: %d, y: %d, w: %d, h: %d)\n", - currentWindowRect.left, currentWindowRect.top, currentWindowRect.right - currentWindowRect.left, currentWindowRect.bottom - currentWindowRect.top); - AquaLog( "SetPosSize: New rect (x: %d, y: %d, w: %d, h: %d)\n", nX, nY, nWidth, nHeight); - */ - SetWindowBounds(mrWindow, kWindowStructureRgn, &newWindowRect); + // do not display yet, we need to update our backbuffer + [mpWindow setFrame: [NSWindow frameRectForContentRect: aContentRect styleMask: mnStyleMask] display: NO]; UpdateFrameGeometry(); - if( mbShown && bPaint ) - // trigger filling our backbuffer - SendPaintEvent(); - if (nEvent) CallCallback(nEvent, NULL); -} - -void AquaSalFrame::DrawMenuBar() -{ - AquaLog( ">*>_> %s\n",__func__); + if( mbShown && bPaint ) + // trigger filling our backbuffer + SendPaintEvent(); - if (mpMenu) - { - AquaSalMenu *pAquaSalMenu = (AquaSalMenu *) mpMenu; - SetRootMenu(pAquaSalMenu->mrMenuRef); - } + // now inform the system that the views need to be drawn + [mpWindow display]; } void AquaSalFrame::GetWorkArea( Rectangle& rRect ) { - Rect aRect; - AquaSalFrame* pFrame = this; - ImplSalCalcMaxClientSize( pFrame, &aRect ); - rRect.nLeft = aRect.left; - rRect.nRight = aRect.right; - rRect.nTop = aRect.top; - rRect.nBottom = aRect.bottom; + // FIXME: multiple screens + NSRect aRect = [[NSScreen mainScreen] visibleFrame]; + CocoaToVCL( aRect ); + rRect.nLeft = aRect.origin.x; + rRect.nTop = aRect.origin.y; + rRect.nRight = aRect.origin.x + aRect.size.width - 1; + rRect.nBottom = aRect.origin.y + aRect.size.height - 1; } SalPointerState AquaSalFrame::GetPointerState() @@ -1272,6 +1200,8 @@ AquaLog( ">*>_> %s\n",__func__); SalPointerState state; + + // FIXME: replace Carbon by Cocoa // get position MacOSPoint aMousePos; @@ -1324,19 +1254,22 @@ return LANGUAGE_DONTKNOW; } -void AquaSalFrame::SetMenu( SalMenu* pSalMenu ) +void AquaSalFrame::DrawMenuBar() { - AquaLog( ">*>_> %s\n",__func__); +} - mpMenu = pSalMenu; - DrawMenuBar(); - +void AquaSalFrame::SetMenu( SalMenu* pSalMenu ) +{ + AquaSalMenu* pMenu = static_cast(pSalMenu); + DBG_ASSERT( ! pMenu || pMenu->mbMenuBar, "setting non menubar on frame" ); + mpMenu = pMenu; + if( mpMenu ) + mpMenu->setMainMenu(); } void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) { - AquaLog( ">*>_> %s\n",__func__); - //TODO: implement + mnExtStyle = nStyle; } void AquaSalFrame::SetBackgroundBitmap( SalBitmap* ) @@ -1348,7 +1281,7 @@ SalBitmap* AquaSalFrame::SnapShot() { AquaLog( ">*>_> %s\n",__func__); - return mpGraphics ? mpGraphics->getBitmap( 0, 0, mnWidth, mnHeight ) : NULL; + return mpGraphics ? mpGraphics->getBitmap( 0, 0, maGeometry.nWidth, maGeometry.nHeight ) : NULL; } SalFrame* AquaSalFrame::GetParent() const @@ -1375,38 +1308,35 @@ void AquaSalFrame::UpdateFrameGeometry() { - memset(&maGeometry, 0, sizeof(SalFrameGeometry)); - - if (IsWindowCollapsed(mrWindow)) - return; - - Rect fullWindowRect; - GetWindowBounds(mrWindow, kWindowStructureRgn, &fullWindowRect); - - Rect contentRect; - GetWindowBounds(mrWindow, kWindowContentRgn, &contentRect); + // keep in mind that view and window coordinates are lower left + // whereas vcl's are upper left - maGeometry.nX = contentRect.left; - maGeometry.nY = contentRect.top; - - maGeometry.nLeftDecoration = contentRect.left - fullWindowRect.left; - maGeometry.nRightDecoration = fullWindowRect.right - contentRect.right; + NSRect aFrameRect = [mpWindow frame]; + NSRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; - maGeometry.nTopDecoration = contentRect.top - fullWindowRect.top; - maGeometry.nBottomDecoration = fullWindowRect.bottom - contentRect.bottom; + // convert to vcl convention + CocoaToVCL( aFrameRect ); + CocoaToVCL( aContentRect ); - Rect titleBarRect; - GetWindowBounds(mrWindow, kWindowTitleBarRgn, &titleBarRect); + maGeometry.nX = aContentRect.origin.x; + maGeometry.nY = aContentRect.origin.y; - int width = fullWindowRect.right - fullWindowRect.left - maGeometry.nRightDecoration - maGeometry.nLeftDecoration; - int height = fullWindowRect.bottom - fullWindowRect.top - maGeometry.nBottomDecoration - maGeometry.nTopDecoration; + maGeometry.nLeftDecoration = aContentRect.origin.x - aFrameRect.origin.x; + maGeometry.nRightDecoration = (aFrameRect.origin.x + aFrameRect.size.width) - + (aContentRect.origin.x + aContentRect.size.width); + + maGeometry.nTopDecoration = aContentRect.origin.y - aFrameRect.origin.y; + maGeometry.nBottomDecoration = (aFrameRect.origin.y + aFrameRect.size.height) - + (aContentRect.origin.y + aContentRect.size.height); - maGeometry.nWidth = width < 0 ? 0 : width; - maGeometry.nHeight = height < 0 ? 0 : height; + maGeometry.nWidth = aContentRect.size.width; + maGeometry.nHeight = aContentRect.size.height; //DbgPrintFrameGeometry(fullWindowRect, contentRect, titleBarRect, maGeometry); } +#if 0 // keep Carbon handlers for reference until cocoa handlers are all in place + OSStatus HandleCommandProcessEvent(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData) { @@ -2614,277 +2544,749 @@ return result; } -OSStatus GetOptimalWindowSize(Rect* rect); - -void DbgWhichSalFrameStyle(ULONG style) -{ - AquaLog( "==============================\n"); +#endif - if (style & SAL_FRAME_STYLE_DEFAULT) - AquaLog( "SAL_FRAME_STYLE_DEFAULT\n"); - if (style & SAL_FRAME_STYLE_MOVEABLE) - AquaLog( "SAL_FRAME_STYLE_MOVEABLE\n"); - if (style & SAL_FRAME_STYLE_SIZEABLE) - AquaLog( "SAL_FRAME_STYLE_SIZEABLE\n"); - if (style & SAL_FRAME_STYLE_CLOSEABLE) - AquaLog( "SAL_FRAME_STYLE_CLOSEABLE\n"); - if (style & SAL_FRAME_STYLE_NOSHADOW) - AquaLog( "SAL_FRAME_STYLE_NOSHADOW\n"); - if (style & SAL_FRAME_STYLE_TOOLTIP) - AquaLog( "SAL_FRAME_STYLE_TOOLTIP\n"); - if (style & SAL_FRAME_STYLE_OWNERDRAWDECORATION) - AquaLog( "SAL_FRAME_STYLE_OWNERDRAWDECORATION\n"); - if (style & SAL_FRAME_STYLE_DIALOG) - AquaLog( "SAL_FRAME_STYLE_DIALOG\n"); - if (style & SAL_FRAME_STYLE_CHILD) - AquaLog( "SAL_FRAME_STYLE_CHILD\n"); - if (style & SAL_FRAME_STYLE_FLOAT) - AquaLog( "SAL_FRAME_STYLE_FLOAT\n"); - if (style & SAL_FRAME_STYLE_TOOLWINDOW) - AquaLog( "SAL_FRAME_STYLE_TOOLWINDOW\n"); - if (style & SAL_FRAME_STYLE_INTRO) - AquaLog( "SAL_FRAME_STYLE_INTRO\n"); - - AquaLog( "==============================\n"); -} - -void AquaSalFrame::CreateNewSystemWindow(CarbonWindowRef pParent, ULONG nSalFrameStyle) -{ - DbgWhichSalFrameStyle(nSalFrameStyle); - - // in order to receive windowupdate events we must not use compositing (kWindowCompositingAttribute)! - - // initialize with useful defaults - unsigned int nWindowAttributes = kWindowStandardHandlerAttribute; - WindowClass windowClass = kDocumentWindowClass; +// ----------------------------------------------------------------------- - if (nSalFrameStyle & SAL_FRAME_STYLE_CHILD) - { - BOOST_ASSERT(false && "Not yet implemented! How to handle child windows on Mac OS X?"); - } - else // none-child windows +void AquaSalFrame::CaptureMouse( BOOL bCapture ) +{ + AquaLog( ">*>_> %s\n",__func__); + // FIXME: implement + #if 0 + if( bCapture ) { - if (nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT) - nWindowAttributes |= kWindowStandardDocumentAttributes; - - if( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT || nSalFrameStyle & SAL_FRAME_STYLE_TOOLWINDOW) - windowClass = kFloatingWindowClass; - if (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) - windowClass = kToolbarWindowClass; - if (nSalFrameStyle & SAL_FRAME_STYLE_TOOLTIP) - windowClass = kHelpWindowClass; - if( nSalFrameStyle & SAL_FRAME_STYLE_INTRO ) - windowClass = kUtilityWindowClass; - - // check moveable, sizeable, closeable - if( !(nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) ) // window without decoration - { - if( windowClass != kHelpWindowClass && // creation fails with kHelpWindowClass and kWindowNoTitleBarAttribute - windowClass != kToolbarWindowClass ) // creation fails with kToolbarWindowClass and kWindowNoTitleBarAttribute - nWindowAttributes |= kWindowNoTitleBarAttribute; - } - else + if( s_rOverlay == 0 ) { - // close box requires a titlebar - if( nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE ) - nWindowAttributes |= kWindowCloseBoxAttribute; - else - nWindowAttributes &= ~kWindowCloseBoxAttribute; + Rect aFullRect; + ImplSalCalcFullScreenSize( this, &aFullRect ); + + OSStatus rc = CreateNewWindow( kOverlayWindowClass, + kWindowOpaqueForEventsAttribute, + &aFullRect, + &s_rOverlay); + if( rc != noErr ) + return; + EventHandlerRef evtHandler; + EventHandlerUPP upp( NewEventHandlerUPP(HandleOverlayMouseEvent) ); + rc = InstallWindowEventHandler( s_rOverlay, upp, GetEventTypeCount(cMouseEvent), cMouseEvent, this, &evtHandler); + if( rc != noErr ) + { + ReleaseWindow( s_rOverlay ); + s_rOverlay = 0; + return; + } + s_aOverlayEvtHandler.first = upp; + s_aOverlayEvtHandler.second = evtHandler; + ShowWindow( s_rOverlay ); } - - if( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE ) + s_pCaptureFrame = this; + } + else if( ! bCapture && s_pCaptureFrame == this ) + { + s_pCaptureFrame = NULL; + if( s_rOverlay != 0 ) { - nWindowAttributes |= (kWindowResizableAttribute | kWindowLiveResizeAttribute); - if( (nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE) && (windowClass == kDocumentWindowClass)) - nWindowAttributes |= (kWindowCollapseBoxAttribute | kWindowFullZoomAttribute); // requires titlebar (moveable) and not allowed for floating windows + DisposeEventHandlerUPP( s_aOverlayEvtHandler.first ); + RemoveEventHandler( s_aOverlayEvtHandler.second ); + ReleaseWindow( s_rOverlay ); + s_rOverlay = 0; } - else - nWindowAttributes &= ~(kWindowResizableAttribute | kWindowLiveResizeAttribute | kWindowCollapseBoxAttribute | kWindowFullZoomAttribute); } - - Rect aContentRect; - GetOptimalWindowSize(&aContentRect); + #endif +} - // Directly connect the frame with the window in contrast to Win32 where frame and - // window will be connected in the WM_CREATE message handler - OSStatus rc = CreateNewWindow(windowClass, nWindowAttributes, &aContentRect, &mrWindow); - - if (rc != noErr) - throw runtime_error("System window creation failed"); - - HIViewRef content = NULL; - rc = HIViewFindByID( HIViewGetRoot( mrWindow ), kHIViewWindowContentID, &content ); - - HIViewTrackingAreaRef track_area = NULL; - rc = HIViewNewTrackingArea( content, NULL, 0, &track_area ); - rc = InstallControlEventHandler( content, HandleMouseEvent, GetEventTypeCount( cMouseEnterExitEvent ), cMouseEnterExitEvent, this, NULL ); +void AquaSalFrame::ResetClipRegion() +{ + /* FIXME: implement */ +} - UpdateFrameGeometry(); +void AquaSalFrame::BeginSetClipRegion( ULONG nRects ) +{ + /* FIXME: implement */ +} - // Store window handle - maSysData.rWindow = mrWindow; +void AquaSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) +{ + /* FIXME: implement */ +} - // Cache the size of the content area of the window - mnHeight = aContentRect.bottom - aContentRect.top; - mnWidth = aContentRect.right - aContentRect.left; +void AquaSalFrame::EndSetClipRegion() +{ + /* FIXME: implement */ +} - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowCloseEvent), 1, &cWindowCloseEvent); +static USHORT ImplGetModifierMask( unsigned int nMask, bool bKeyEvent ) +{ + USHORT nRet = 0; + if( (nMask & NSShiftKeyMask) != 0 ) + nRet |= KEY_SHIFT; + if( (nMask & NSControlKeyMask) != 0 ) + nRet |= KEY_MOD1; + if( (nMask & NSAlternateKeyMask) != 0 ) + nRet |= bKeyEvent ? KEY_MOD5 : KEY_MOD2; + return nRet; +} + +static USHORT ImplMapCharCode( sal_Unicode aCode ) +{ + static USHORT aKeyCodeMap[ 128 ] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KEY_ESCAPE, 0, 0, 0, 0, + KEY_SPACE, 0, 0, 0, 0, 0, 0, 0, + 0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE, + KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, + KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0, + 0, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, + KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, + KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, + KEY_X, KEY_Y, KEY_Z, 0, 0, 0, 0, 0, + KEY_QUOTELEFT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, + KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, + KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, + KEY_X, KEY_Y, KEY_Z, 0, 0, 0, KEY_TILDE, KEY_DELETE + }; + + static USHORT aFunctionKeyCodeMap[ 128 ] = + { + KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4, + KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, + KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, + KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0, + 0, 0, 0, 0, 0, 0, 0, KEY_INSERT, + KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0, + 0, 0, 0, 0, 0, KEY_MENU, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }; - if(windowClass != kHelpWindowClass) //workaround for tooltip crash #74392 - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowBoundsChangedEvent), 1, &cWindowBoundsChangedEvent); + USHORT nKeyCode = 0; + if( aCode < sizeof( aKeyCodeMap) / sizeof( aKeyCodeMap[0] ) ) + nKeyCode = aKeyCodeMap[ aCode ]; + else if( aCode >= 0xf700 && aCode < 0xf780 ) + nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ]; + return nKeyCode; +} + +@implementation SalFrameWindow +-(id)initWithSalFrame: (AquaSalFrame*)pFrame +{ + mpFrame = pFrame; + NSRect aRect = { { pFrame->maGeometry.nX, pFrame->maGeometry.nY }, + { pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight } }; + pFrame->VCLToCocoa( aRect ); + return [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ]; +} +-(void)windowDidBecomeKey: (NSNotification*)pNotification +{ + YIELD_GUARD; - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowFocusEvent), GetEventTypeCount(cWindowFocusEvent), cWindowFocusEvent); + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + if( mpFrame->mpMenu ) + mpFrame->mpMenu->setMainMenu(); + mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 ); + } +} - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleOOoSalUserEvent), 1, &cOOoSalUserEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleOOoSalTimerEvent), 1, &cOOoSalTimerEvent); +-(void)windowDidResignKey: (NSNotification*)pNotification +{ + YIELD_GUARD; - // do not register for paint events as this would result in no draw content events during resize anymore - // draw content events, however, are more effective as they do not require a full window repaint - //InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowPaintEvent), 1, &cWindowPaintEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowDrawContentEvent), 1, &cWindowDrawContentEvent); + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0); +} - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowActivatedEvent), GetEventTypeCount(cWindowActivatedEvent), cWindowActivatedEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleMouseEvent), GetEventTypeCount(cMouseEvent), cMouseEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleMouseWheelMovedEvent), 1, &cMouseWheelMovedEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowResizeStarted), 1, &cWindowResizeStarted); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleWindowResizeCompleted), 1, &cWindowResizeCompleted); +-(void)windowDidChangeScreen: (NSNotification*)pNotification +{ + // FIXME: multiscreen +} - /* Menu event handlers */ +-(void)windowDidMove: (NSNotification*)pNotification +{ + YIELD_GUARD; - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleCommandProcessEvent), 1, &cCommandProcessEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleMenuPopulateEvent), 1, &cMenuPopulateEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleMenuClosedEvent), 1, &cMenuClosedEvent); - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleMenuTargetItemEvent), 1, &cMenuTargetItemEvent); + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->UpdateFrameGeometry(); + mpFrame->CallCallback( SALEVENT_MOVE, 0 ); + } +} - /* Keyboard event handlers*/ +-(void)windowDidResize: (NSNotification*)pNotification +{ + YIELD_GUARD; -#if 0 - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleKeyboardEvent), GetEventTypeCount(cKeyboardRawKeyEvents), cKeyboardRawKeyEvents); -#else - // TSM! - InstallAndRegisterEventHandler(NewEventHandlerUPP(HandleTSMEvent), GetEventTypeCount(cTextInputEvents), cTextInputEvents); -#endif + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->UpdateFrameGeometry(); + mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); + } +} + +-(void)windowDidMiniaturize: (NSNotification*)pNotification +{ + YIELD_GUARD; + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->mbShown = false; + mpFrame->UpdateFrameGeometry(); + mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); + } } -OSStatus AquaSalFrame::InstallAndRegisterEventHandler(EventHandlerUPP upp, size_t nEvents, const EventTypeSpec* eventSpec) +-(void)windowDidDeminiaturize: (NSNotification*)pNotification { - EventHandlerRef evtHandler; - OSStatus rc = InstallWindowEventHandler(mrWindow, upp, nEvents, eventSpec, this, &evtHandler); + YIELD_GUARD; + + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->mbShown = true; + mpFrame->UpdateFrameGeometry(); + mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); + } +} - if (rc == noErr) - mSysWindowEventHandlerDataContainer.push_back(make_pair(upp, evtHandler)); +-(MacOSBOOL)windowShouldClose: (NSNotification*)pNotification +{ + YIELD_GUARD; - return rc; + MacOSBOOL bRet = YES; + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->CallCallback( SALEVENT_CLOSE, 0 ); + bRet = NO; // application will close the window or not, AppKit shouldn't + } + return bRet; } -void AquaSalFrame::DeinstallAndUnregisterAllEventHandler() +-(void)dockMenuItemTriggered: (id)sender { - SysWindowEventHandlerDataContainer_t::iterator iter = mSysWindowEventHandlerDataContainer.begin(); - SysWindowEventHandlerDataContainer_t::iterator iter_end = mSysWindowEventHandlerDataContainer.end(); - for (/*NOP*/; iter != iter_end; ++iter) + YIELD_GUARD; + + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS ); +} + +@end + +@implementation SalFrameView +-(id)initWithSalFrame: (AquaSalFrame*)pFrame +{ + mpFrame = pFrame; + if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [mpFrame->getWindow() frame] styleMask: mpFrame->mnStyleMask]]) != nil) { - DisposeEventHandlerUPP((*iter).first); - RemoveEventHandler((*iter).second); + mMarkedRange = NSMakeRange(NSNotFound, 0); + mSelectedRange = NSMakeRange(NSNotFound, 0); } - mSysWindowEventHandlerDataContainer.clear(); + + return self; } -// ----------------------------------------------------------------------- +-(MacOSBOOL)acceptsFirstResponder +{ + return YES; +} -void AquaSalFrame::CaptureMouse( BOOL bCapture ) +-(MacOSBOOL)acceptsFirstMouse: (NSEvent*)pEvent { - AquaLog( ">*>_> %s\n",__func__); - if( bCapture ) + return YES; +} + +-(MacOSBOOL)isOpaque +{ + return YES; +} + +-(void)drawRect: (NSRect)aRect +{ + AquaLog( "drawRect\n" ); + + YIELD_GUARD; + + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) { - if( s_rOverlay == 0 ) + // FIXME: optimize UpdateWindow wrt to aRect + if( mpFrame->mpGraphics ) + mpFrame->mpGraphics->UpdateWindow( [NSGraphicsContext currentContext] ); + } +} + +-(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(USHORT)nButton eventtype:(USHORT)nEvent +{ + YIELD_GUARD; + + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->mnLastEventTime = static_cast( [pEvent timestamp] * 1000.0 ); + mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; + + NSPoint aPt = [NSEvent mouseLocation]; + mpFrame->CocoaToVCL( aPt ); + + SalMouseEvent aEvent; + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnButton = nButton; + aEvent.mnCode = aEvent.mnButton | ImplGetModifierMask( [pEvent modifierFlags], false ); + + mpFrame->CallCallback( nEvent, &aEvent ); + } +} + +-(void)mouseDown: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN]; +} + +-(void)mouseDragged: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE]; +} + +-(void)mouseUp: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP]; +} + +-(void)mouseMoved: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE]; +} + +-(void)mouseEntered: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE]; +} + +-(void)mouseExited: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSELEAVE]; +} + +-(void)rightMouseDown: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN]; +} + +-(void)rightMouseDragged: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE]; +} + +-(void)rightMouseUp: (NSEvent*)pEvent +{ + [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP]; +} + +-(void)otherMouseDown: (NSEvent*)pEvent +{ + if( [pEvent buttonNumber] == 2 ) + [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN]; +} + +-(void)otherMouseDragged: (NSEvent*)pEvent +{ + if( [pEvent buttonNumber] == 2 ) + [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE]; +} + +-(void)otherMouseUp: (NSEvent*)pEvent +{ + if( [pEvent buttonNumber] == 2 ) + [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP]; +} + +-(void)scrollWheel: (NSEvent*)pEvent +{ + YIELD_GUARD; + + if( AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->mnLastEventTime = static_cast( [pEvent timestamp] * 1000.0 ); + mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; + + NSPoint aPt = [NSEvent mouseLocation]; + mpFrame->CocoaToVCL( aPt ); + + SalWheelMouseEvent aEvent; + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags, false ); // FIXME: button code + + float dX = [pEvent deltaX]; + float dY = [pEvent deltaY]; + if( dX != 0.0 ) { - Rect aFullRect; - ImplSalCalcFullScreenSize( this, &aFullRect ); - - OSStatus rc = CreateNewWindow( kOverlayWindowClass, - kWindowOpaqueForEventsAttribute, - &aFullRect, - &s_rOverlay); - if( rc != noErr ) + aEvent.mnDelta = dX; + aEvent.mnNotchDelta = dX; + aEvent.mnScrollLines = dX < 0.0 ? -1 : 1; + aEvent.mbHorz = TRUE; + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); + } + if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) ) + { + aEvent.mnDelta = dY; + aEvent.mnNotchDelta = dY; + aEvent.mnScrollLines = dY < 0.0 ? -1 : 1; + aEvent.mbHorz = FALSE; + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); + } + } +} + +-(void)keyDown: (NSEvent*)pEvent +{ + YIELD_GUARD; + + if( AquaSalFrame::isAlive( mpFrame ) ) + { + mpLastEvent = pEvent; + mbInKeyInput = true; + mbNeedSpecialKeyHandle = false; + mbKeyHandled = false; + + mpFrame->mnLastEventTime = static_cast( [pEvent timestamp] * 1000.0 ); + mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; + + if( (mpFrame->mnLastModifierFlags & NSControlKeyMask) /*&& mbNeedSpecialKeyHandle && !mbKeyHandled */ ) + { + // note: checkSpecialCharacters sets mbInKeyInput to false as a side effect + // if the event is consumed + if ( [self checkSpecialCharacters:pEvent] ) return; - EventHandlerRef evtHandler; - EventHandlerUPP upp( NewEventHandlerUPP(HandleOverlayMouseEvent) ); - rc = InstallWindowEventHandler( s_rOverlay, upp, GetEventTypeCount(cMouseEvent), cMouseEvent, this, &evtHandler); - if( rc != noErr ) + } + + NSArray* pArray = [NSArray arrayWithObject: pEvent]; + [self interpretKeyEvents: pArray]; + + mbInKeyInput = false; + } +} + +-(void)flagsChanged: (NSEvent*)pEvent +{ + YIELD_GUARD; + + if( AquaSalFrame::isAlive( mpFrame ) ) + { + mpFrame->mnLastEventTime = static_cast( [pEvent timestamp] * 1000.0 ); + mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; + } +} + +-(void)insertText:(id)aString +{ + YIELD_GUARD; + + if( AquaSalFrame::isAlive( mpFrame ) ) + { + NSString* pInsert = nil; + if( [aString isMemberOfClass: [NSAttributedString class]] ) + pInsert = [aString string]; + else + pInsert = aString; + + int nLen = 0; + if( pInsert && ( nLen = [pInsert length] ) > 0 ) + { + OUString aInsertString( GetOUString( pInsert ) ); + USHORT nKeyCode = 0; + // aCharCode initializer is safe since aInsertString will at least contain '\0' + sal_Unicode aCharCode = *aInsertString.getStr(); + // FIXME: will probably break somehow in less than trivial text input mode + if( nLen == 1 && + aCharCode < 0x80 && + aCharCode > 0x31 && + ( nKeyCode = ImplMapCharCode( aCharCode ) ) != 0 + ) { - ReleaseWindow( s_rOverlay ); - s_rOverlay = 0; - return; + [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode]; + } + else + { + SalExtTextInputEvent aEvent; + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.maText = aInsertString; + aEvent.mpTextAttr = NULL; + aEvent.mnCursorPos = aInsertString.getLength(); + aEvent.mnDeltaStart = 0; + aEvent.mnCursorFlags = 0; + aEvent.mbOnlyCursor = FALSE; + mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); + if( AquaSalFrame::isAlive( mpFrame ) ) + mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); } - s_aOverlayEvtHandler.first = upp; - s_aOverlayEvtHandler.second = evtHandler; - ShowWindow( s_rOverlay ); } - s_pCaptureFrame = this; + else + { + SalExtTextInputEvent aEvent; + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.maText = String(); + aEvent.mpTextAttr = NULL; + aEvent.mnCursorPos = 0; + aEvent.mnDeltaStart = 0; + aEvent.mnCursorFlags = 0; + aEvent.mbOnlyCursor = FALSE; + mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); + if( AquaSalFrame::isAlive( mpFrame ) ) + mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); + + } + mbKeyHandled = true; } - else if( ! bCapture && s_pCaptureFrame == this ) +} + +-(void)insertTab: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t']; +} + +-(void)moveLeft: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0]; +} + +-(void)moveRight: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0]; +} + +-(void)moveUp: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0]; +} + +-(void)moveDown: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0]; +} + +-(void)insertNewline: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n']; +} + +-(void)deleteBackward: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b']; +} + +-(void)deleteForward: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f]; +} + +-(void)cancelOperation: (id)aSender +{ + [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b]; +} + +-(void)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar +{ + YIELD_GUARD; + + if( AquaSalFrame::isAlive( mpFrame ) ) { - s_pCaptureFrame = NULL; - if( s_rOverlay != 0 ) + SalKeyEvent aEvent; + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnCode = nKeyCode | ImplGetModifierMask( mpFrame->mnLastModifierFlags, true ); + aEvent.mnCharCode = aChar; + aEvent.mnRepeat = FALSE; + mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent ); + if( AquaSalFrame::isAlive( mpFrame ) ) + mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent ); + } +} + + +-(MacOSBOOL)checkSpecialCharacters: (NSEvent *)pEvent +{ + // check for special characters + NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; + + if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) + { + unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; + USHORT nKeyCode = ImplMapCharCode( keyChar ); + bool bUseKeyInput = false; + if( nKeyCode != 0 ) { - DisposeEventHandlerUPP( s_aOverlayEvtHandler.first ); - RemoveEventHandler( s_aOverlayEvtHandler.second ); - ReleaseWindow( s_rOverlay ); - s_rOverlay = 0; + // handle function keys, let unmodified cursor keys through to input manager + if( keyChar >= 0xf704 && keyChar < 0xf900 ) + bUseKeyInput = true; + else if( keyChar >= 0xf700 && keyChar < 0xf704 && + mpFrame->mnLastModifierFlags != 0 ) + bUseKeyInput = true; + else if( ((mpFrame->mnLastModifierFlags & ~(NSControlKeyMask | NSAlternateKeyMask | NSShiftKeyMask)) & NSDeviceIndependentModifierFlagsMask) == 0 && + (mpFrame->mnLastModifierFlags & (NSControlKeyMask | NSAlternateKeyMask)) != 0 ) + bUseKeyInput = true; + } + if( bUseKeyInput ) + { + [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0]; + mbInKeyInput = false; + + return TRUE; } } + return FALSE; } -OSStatus GetOptimalWindowSize(Rect* rect) + +// NSTextInput protocol +- (NSArray *)validAttributesForMarkedText { - OSStatus err = noErr; + // FIXME + return [NSArray array]; +} - BOOST_ASSERT(rect != NULL && "Precondition violated"); +- (MacOSBOOL)hasMarkedText +{ + MacOSBOOL bHasMarkedText; - // [FIXME] : define better the main window size and implement screen detection - // In multiscreen mode, the fullscreen always fill the active windows - Rect aRect; - ImplSalCalcFullScreenSize( NULL, &aRect ); + bHasMarkedText = ( mMarkedRange.location != NSNotFound ) && + ( mMarkedRange.length != 0 ); + // hack to check keys like "Control-j" + if( mbInKeyInput ) + { + mbNeedSpecialKeyHandle = true; + } + return bHasMarkedText; +} - rect->left = aRect.left + floor( 0.10 * (aRect.right - aRect.left) ); - rect->right = aRect.right - floor( 0.10 * (aRect.right - aRect.left) ); - rect->top = aRect.top + floor( 0.10 * (aRect.bottom - aRect.top) ); - rect->bottom = aRect.bottom - floor( 0.10 * (aRect.bottom - aRect.top) ); +- (NSRange)markedRange +{ + return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 ); +} - return err; +- (NSRange)selectedRange +{ + return mSelectedRange; } -void AquaSalFrame::ActivateTSM() +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange { - AquaLog( ">*>_> %s\n",__func__); - if (maTsmDocumentId) - ActivateTSMDocument(maTsmDocumentId); + AquaLog( ">*>_> %s\n",__func__ ); + AquaLog( "location: %d, length: %d\n", selRange.location, selRange.length ); + AquaLog( "aString = '%@'\n", aString ); + AquaLog( "length %d\n", [aString length] ); + + if( ![aString isKindOfClass:[NSAttributedString class]] ) + aString = [[[NSAttributedString alloc] initWithString:aString] autorelease]; + NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange]; + mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] ); + mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length ); + + int len = [aString length]; + SalExtTextInputEvent aInputEvent; + aInputEvent.mnTime = mpFrame->mnLastEventTime; + aInputEvent.mnDeltaStart = 0; + aInputEvent.mbOnlyCursor = FALSE; + if( len > 0 ) { + NSString *pString = [aString string]; + OUString aInsertString( GetOUString( pString ) ); + std::vector aInputFlags = std::vector( std::max( 1, len ), 0 ); + for ( int i = 0; i < len; i++ ) + { + // FIXME + aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE; + } + + aInputEvent.maText = aInsertString; + aInputEvent.mnCursorPos = selRange.location; + aInputEvent.mpTextAttr = &aInputFlags[0]; + mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); + } else { + aInputEvent.maText = String(); + aInputEvent.mnCursorPos = 0; + aInputEvent.mnCursorFlags = 0; + aInputEvent.mpTextAttr = 0; + mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); + mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); + } + mbKeyHandled= true; } -void AquaSalFrame::DeactivateTSM() +- (void)unmarkText { - AquaLog( ">*>_> %s\n",__func__); - if (maTsmDocumentId) - DeactivateTSMDocument(maTsmDocumentId); + AquaLog( ">*>_> %s\n", __func__ ); + + mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0); } -void AquaSalFrame::ResetClipRegion() +- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange { - /* FIXME: implement */ + AquaLog( ">*>_> %s\n", __func__ ); + AquaLog( "theRange = %d, %d\n", theRange.location, theRange.length); + + // FIXME + return nil; } -void AquaSalFrame::BeginSetClipRegion( ULONG nRects ) +- (unsigned int)characterIndexForPoint:(NSPoint)thePoint { - /* FIXME: implement */ + AquaLog( ">*>_> %s\n",__func__ ); + + // FIXME + return 0; } -void AquaSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) +- (long)conversationIdentifier { - /* FIXME: implement */ + return (long)self; } -void AquaSalFrame::EndSetClipRegion() +- (void)doCommandBySelector:(SEL)aSelector { - /* FIXME: implement */ + AquaLog( ">*>_> %s\n",__func__ ); + AquaLog( "aSelector %s", aSelector ); + + // check for special characters with OOo way + if ( [self checkSpecialCharacters:mpLastEvent] ) + { + mbKeyHandled = true; + return; + } + + // Cocoa way + (void)[self performSelector: aSelector]; + mbKeyHandled = true; } + +- (NSRect)firstRectForCharacterRange:(NSRange)theRange +{ + AquaLog( ">*>_> %s\n",__func__ ); + AquaLog( "mSelectedRange = %d, %d", mSelectedRange.location, mSelectedRange.length ); + AquaLog( " theRange = %d, %d\n", theRange.location, theRange.length ); + + SalExtTextInputPosEvent aPosEvent; + mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent ); + + NSRect rect; + + rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX; + rect.origin.y = aPosEvent.mnY + mpFrame->maGeometry.nY; + rect.size.width = aPosEvent.mnWidth; + rect.size.height = aPosEvent.mnHeight; + + // FIXME how to convert the geometry?? + //rect = [self convertRect:rect toView:nil]; + //rect.origin = [[self window] convertBaseToScreen:rect.origin]; + return rect; +} + +@end + diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/aqua/source/window/salmenu.cxx ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/window/salmenu.cxx --- ooo_SRC680_m225_src.orig/vcl/aqua/source/window/salmenu.cxx 2007-07-27 09:43:00.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/aqua/source/window/salmenu.cxx 2007-08-08 18:07:13.000000000 +0200 @@ -33,48 +33,105 @@ * ************************************************************************/ -#include -#include -#include -#include -#include +#include "saldata.hxx" +#include "salinst.h" +#include "salmenu.h" +#include "salframe.h" +#include "vcl/impbmp.hxx" +#include "vcl/svids.hrc" +#include "vcl/cmdevt.hxx" +const AquaSalMenu* AquaSalMenu::pCurrentMenuBar = NULL; -// nPos is 0 based, MenuItemIndex is 1 based -#define GETITEMINDEXBYPOS(nPos) (nPos+1) +@interface MainMenuSelector : NSObject +{ +} +-(void)showDialog: (int)nDialog; +-(void)showPreferences: (id)sender; +-(void)showAbout: (id)sender; +@end -// ======================================================================= +@implementation MainMenuSelector +-(void)showDialog: (int)nDialog +{ + if( AquaSalMenu::pCurrentMenuBar ) + { + const AquaSalFrame* pFrame = AquaSalMenu::pCurrentMenuBar->mpFrame; + if( pFrame && AquaSalFrame::isAlive( pFrame ) ) + { + pFrame->CallCallback( SALEVENT_SHOWDIALOG, reinterpret_cast(nDialog) ); + } + } +} -SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar ) +-(void)showPreferences: (id) sender +{ + [self showDialog: SHOWDIALOG_ID_PREFERENCES]; +} +-(void)showAbout: (id) sender { - AquaSalMenu *pAquaSalMenu = new AquaSalMenu(); - static MenuID inMenuID=0; + [self showDialog: SHOWDIALOG_ID_ABOUT]; +} +@end - pAquaSalMenu->mbMenuBar = bMenuBar; +// FIXME: currently this is leaked +static MainMenuSelector* pMainMenuSelector = nil; - CreateNewMenu (inMenuID++, 0, &pAquaSalMenu->mrMenuRef); +// ======================================================================= - /* Associate the pointer to this SalMenu with the menu */ - SetMenuItemProperty (pAquaSalMenu->mrMenuRef, 0, - APP_PROPERTY_CREATOR, APP_PROPERTY_TAG_MENU_POINTER, - sizeof(pAquaSalMenu), &pAquaSalMenu); +SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar ) +{ + AquaSalMenu *pAquaSalMenu = new AquaSalMenu( bMenuBar ); static bool bOnce = true; if( bOnce ) { bOnce = false; - EnableMenuCommand(NULL, kHICommandPreferences); // enable pref menu - + ResMgr* pMgr = ImplGetResMgr(); if( pMgr ) { - String aAbout( ResId( SV_STDTEXT_ABOUT, *pMgr ) ); - MenuRef rApplicationMenu; - MenuItemIndex outIndex[1]; - GetIndMenuItemWithCommandID(NULL, kHICommandPreferences, 1, &rApplicationMenu, outIndex); - CFStringRef rStr = CreateCFString( aAbout ); - InsertMenuItemTextWithCFString(rApplicationMenu, rStr, (short) 0, 0, kHICommandAbout); - CFRelease( rStr ); + // get the main menu + NSMenu* pMainMenu = [NSApp mainMenu]; + if( pMainMenu != nil ) + { + // cretate the action selector + pMainMenuSelector = [[MainMenuSelector alloc] init]; + + // get the proper submenu + NSMenu* pAppMenu = [[pMainMenu itemAtIndex: 0] submenu]; + if( pAppMenu ) + { + // insert about entry + String aAbout( ResId( SV_STDTEXT_ABOUT, *pMgr ) ); + NSString* pString = CreateNSString( aAbout ); + NSMenuItem* pNewItem = [pAppMenu insertItemWithTitle: pString + action: @selector(showAbout:) + keyEquivalent: @"" + atIndex: 0]; + [pString release]; + if( pNewItem ) + { + [pNewItem setTarget: pMainMenuSelector]; + [pAppMenu insertItem: [NSMenuItem separatorItem] atIndex: 1]; + } + + // insert preferences entry + String aPref( ResId( SV_STDTEXT_PREFERENCES, *pMgr ) ); + pString = CreateNSString( aPref ); + pNewItem = [pAppMenu insertItemWithTitle: pString + action: @selector(showPreferences:) + keyEquivalent: @"," + atIndex: 2]; + [pString release]; + if( pNewItem ) + { + [pNewItem setKeyEquivalentModifierMask: NSCommandKeyMask]; + [pNewItem setTarget: pMainMenuSelector]; + [pAppMenu insertItem: [NSMenuItem separatorItem] atIndex: 3]; + } + } + } } } return pAquaSalMenu; @@ -82,11 +139,6 @@ void AquaSalInstance::DestroyMenu( SalMenu* pSalMenu ) { - - AquaSalMenu *pAquaSalMenu = (AquaSalMenu *) pSalMenu; - - RemoveMenuItemProperty (pAquaSalMenu->mrMenuRef, 0, - APP_PROPERTY_CREATOR, APP_PROPERTY_TAG_MENU_POINTER); delete pSalMenu; } @@ -95,20 +147,7 @@ if( !pItemData ) return NULL; - AquaSalMenuItem *pSalMenuItem = new AquaSalMenuItem(); - - pSalMenuItem->maMenuAttributes = 0; - pSalMenuItem->mpSubMenu = NULL; - pSalMenuItem->mnId = pItemData->nId; - pSalMenuItem->mText = pItemData->aText; - - // Delete mnemonics - pSalMenuItem->mText.EraseAllChars( '~' ); - - pSalMenuItem->mpMenu = pItemData->pMenu; - - if (pItemData->eType == MENUITEM_SEPARATOR) - pSalMenuItem->maMenuAttributes |= kMenuItemAttrSeparator; + AquaSalMenuItem *pSalMenuItem = new AquaSalMenuItem( pItemData ); return pSalMenuItem; } @@ -126,11 +165,68 @@ * AquaSalMenu */ +AquaSalMenu::AquaSalMenu( bool bMenuBar ) : + mbMenuBar( bMenuBar ), + mpMenu( nil ), + mpVCLMenu( NULL ), + mpFrame( NULL ), + mpParentSalMenu( NULL ) +{ + if( ! mbMenuBar ) + { + mpMenu = [[SalNSMenu alloc] initWithMenu: this]; + [mpMenu setDelegate: mpMenu]; + // these can go occasionally go in and out of a menu, ensure their lifecycle + [mpMenu retain]; + } + else + { + mpMenu = [NSApp mainMenu]; + } + [mpMenu setAutoenablesItems: NO]; +} + AquaSalMenu::~AquaSalMenu() { - if (this->mrMenuRef) + // is this leaking in some cases ? the release often leads to a duplicate release + // it seems the parent item gets ownership of the menu + if( mpMenu && ! mbMenuBar ) + [mpMenu release]; +} + +int AquaSalMenu::getItemIndexByPos( USHORT nPos ) const +{ + int nIndex = 0; + if( nPos == MENU_APPEND ) + nIndex = [mpMenu numberOfItems]; + else + nIndex = sal::static_int_cast( mbMenuBar ? nPos+1 : nPos ); + return nIndex; +} + +const AquaSalFrame* AquaSalMenu::getFrame() const +{ + const AquaSalMenu* pMenu = this; + while( pMenu && ! pMenu->mpFrame ) + pMenu = pMenu->mpParentSalMenu; + return pMenu ? pMenu->mpFrame : NULL; +} + +void AquaSalMenu::setMainMenu() +{ + DBG_ASSERT( mbMenuBar, "setMainMenu on non menubar" ); + if( mbMenuBar && pCurrentMenuBar != this ) { - DisposeMenu(this->mrMenuRef); + // remove items from main menu + for( int nItems = [mpMenu numberOfItems]; nItems > 1; nItems-- ) + [mpMenu removeItemAtIndex: 1]; + // insert our items + for( unsigned int i = 0; i < maItems.size(); i++ ) + { + NSMenuItem* pItem = maItems[i]->mpMenuItem; + [mpMenu insertItem: pItem atIndex: i+1]; + } + pCurrentMenuBar = this; } } @@ -152,108 +248,94 @@ void AquaSalMenu::SetFrame( const SalFrame *pFrame ) { - AquaLog( ">*>_> %s\n",__func__); + mpFrame = static_cast(pFrame); } void AquaSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) { - AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem; - - // save MenuRef of the menu for future reference - pAquaSalMenuItem->mrParentMenuRef = mrMenuRef; - - if (mbMenuBar) - AppendMenuItemTextWithCFString( mrMenuRef, NULL, pAquaSalMenuItem->maMenuAttributes, 0, &pAquaSalMenuItem->mnMenuItemIndex); + AquaSalMenuItem *pAquaSalMenuItem = static_cast(pSalMenuItem); + pAquaSalMenuItem->mpParentMenu = this; + DBG_ASSERT( pAquaSalMenuItem->mpVCLMenu == NULL || + pAquaSalMenuItem->mpVCLMenu == mpVCLMenu || + mpVCLMenu == NULL, + "resetting menu ?" ); + if( pAquaSalMenuItem->mpVCLMenu ) + mpVCLMenu = pAquaSalMenuItem->mpVCLMenu; + + if( nPos == MENU_APPEND || nPos == maItems.size() ) + maItems.push_back( pAquaSalMenuItem ); + else if( nPos < maItems.size() ) + maItems.insert( maItems.begin() + nPos, pAquaSalMenuItem ); else - { - CFStringRef menuText = CreateCFString(pAquaSalMenuItem->mText); - - AppendMenuItemTextWithCFString( mrMenuRef, menuText, pAquaSalMenuItem->maMenuAttributes, 0, &pAquaSalMenuItem->mnMenuItemIndex); - CFRelease(menuText); - } + DBG_ERROR( "invalid item index in insert" ); - /* Associate the pointer to this SalMenuItem with the menu item */ - SetMenuItemProperty (mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, - APP_PROPERTY_CREATOR, APP_PROPERTY_TAG_MENU_ITEM_POINTER, - sizeof(pSalMenuItem), &pSalMenuItem); + if( ! mbMenuBar || pCurrentMenuBar == this ) + [mpMenu insertItem: pAquaSalMenuItem->mpMenuItem atIndex: getItemIndexByPos(nPos)]; } void AquaSalMenu::RemoveItem( unsigned nPos ) { - if (mrMenuRef) - DeleteMenuItem (mrMenuRef, GETITEMINDEXBYPOS(nPos)); + if( nPos == MENU_APPEND ) + maItems.pop_back(); + else if( nPos < maItems.size() ) + maItems.erase( maItems.begin()+nPos ); + else + DBG_ERROR( "invalid item index in remove" ); + if( ! mbMenuBar || pCurrentMenuBar == this ) + [mpMenu removeItemAtIndex: getItemIndexByPos(nPos)]; } void AquaSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) { - AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem; - - AquaSalMenu *subAquaSalMenu = (AquaSalMenu *) pSubMenu; + AquaSalMenuItem *pAquaSalMenuItem = static_cast(pSalMenuItem); + AquaSalMenu *subAquaSalMenu = static_cast(pSubMenu); // FIXME: in svtools - workben - svdem, pSubMenu is NULL! if (subAquaSalMenu) { - CFStringRef menuText = CreateCFString(pAquaSalMenuItem->mText); - - pAquaSalMenuItem->mpSubMenu = pSubMenu; - SetMenuTitleWithCFString(subAquaSalMenu->mrMenuRef, menuText); - CFRelease(menuText); - SetMenuItemHierarchicalMenu (mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, subAquaSalMenu->mrMenuRef); + pAquaSalMenuItem->mpSubMenu = subAquaSalMenu; + if( subAquaSalMenu->mpParentSalMenu == NULL ) + { + subAquaSalMenu->mpParentSalMenu = this; + [pAquaSalMenuItem->mpMenuItem setSubmenu: subAquaSalMenu->mpMenu]; + + // set title of submenu + [subAquaSalMenu->mpMenu setTitle: [pAquaSalMenuItem->mpMenuItem title]]; + } + else if( subAquaSalMenu->mpParentSalMenu != this ) + { + // cocoa doesn't allow menus to be submenus of multiple + // menu items, so place a copy in the menu item instead ? + // let's hope that NSMenu copy does the right thing + NSMenu* pCopy = [subAquaSalMenu->mpMenu copy]; + [pAquaSalMenuItem->mpMenuItem setSubmenu: pCopy]; + + // set title of submenu + [pCopy setTitle: [pAquaSalMenuItem->mpMenuItem title]]; + } } } void AquaSalMenu::CheckItem( unsigned nPos, BOOL bCheck ) { - CheckMenuItem(this->mrMenuRef, GETITEMINDEXBYPOS(nPos), bCheck); + if( nPos < maItems.size() ) + { + NSMenuItem* pItem = maItems[nPos]->mpMenuItem; + [pItem setState: bCheck ? NSOnState : NSOffState]; + } } void AquaSalMenu::EnableItem( unsigned nPos, BOOL bEnable ) { - if (bEnable) - EnableMenuItem(this->mrMenuRef, GETITEMINDEXBYPOS(nPos)); - else - DisableMenuItem(this->mrMenuRef, GETITEMINDEXBYPOS(nPos)); + if( nPos < maItems.size() ) + { + NSMenuItem* pItem = maItems[nPos]->mpMenuItem; + [pItem setEnabled: bEnable ? YES : NO]; + } } void AquaSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage ) { - AquaLog( ">*>_> %s\n",__func__); - - if (!pSalMenuItem) - return; - - AquaSalMenuItem *pAquaSalMenuItem = static_cast(pSalMenuItem); - - BitmapEx aBitmapEx = rImage.GetBitmapEx(); - aBitmapEx.Mirror(BMP_MIRROR_VERT); - - pAquaSalMenuItem->maBitmap = aBitmapEx.GetBitmap(); - - Bitmap aBitmap (pAquaSalMenuItem->maBitmap); - - ImpBitmap *aImpBitmap = aBitmap.ImplGetImpBitmap(); - - if (aImpBitmap) - { - AquaSalBitmap *pSalBmp = static_cast(aImpBitmap->ImplGetSalBitmap()); - CGImageRef xImage = NULL; - - // check alpha - if (aBitmapEx.IsAlpha()) - { - AquaSalBitmap *pSalMask = static_cast(aBitmapEx.GetAlpha().GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap()); - - if (pSalMask) - xImage = pSalBmp->CreateWithMask ( *pSalMask, 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight); - } - - if (!xImage) - xImage = pSalBmp->CreateCroppedImage( 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight ); - - SetMenuItemIconHandle(mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, kMenuCGImageRefType, (Handle)xImage); - - CGImageRelease(xImage); - } } void AquaSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const XubString& rText ) @@ -263,48 +345,40 @@ AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem; - pAquaSalMenuItem->mText = rText; + String aText( rText ); // Delete mnemonics - pAquaSalMenuItem->mText.EraseAllChars( '~' ); - - CFStringRef menuText = CreateCFString(pAquaSalMenuItem->mText); - - SetMenuItemTextWithCFString( mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, menuText); - + aText.EraseAllChars( '~' ); + + NSString* pString = CreateNSString( aText ); + [pAquaSalMenuItem->mpMenuItem setTitle: pString]; // if the menu item has a submenu, change its title as well if (pAquaSalMenuItem->mpSubMenu) - { - AquaSalMenu *subMenu = (AquaSalMenu *) pAquaSalMenuItem->mpSubMenu; - SetMenuTitleWithCFString(subMenu->mrMenuRef, menuText); - } - CFRelease(menuText); + [pAquaSalMenuItem->mpSubMenu->mpMenu setTitle: pString]; + + [pString release]; } void AquaSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const XubString& rKeyName ) { - AquaLog( ">*>_> %s\n",__func__); - USHORT nModifier; - int nCommandKey = -1, nKeyGlyph = -1; + sal_Unicode nCommandKey = 0; - if (rKeyCode.GetCode()) + USHORT nKeyCode=rKeyCode.GetCode(); + if( nKeyCode ) { - USHORT nKeyCode=rKeyCode.GetCode(); - if ((nKeyCode>=KEY_A) && (nKeyCode<=KEY_Z)) // letter A..Z - nCommandKey=nKeyCode-KEY_A+'A'; + nCommandKey = nKeyCode-KEY_A + 'a'; else if ((nKeyCode>=KEY_0) && (nKeyCode<=KEY_9)) // numbers 0..9 - nCommandKey=nKeyCode-KEY_0+'0'; - else if ((nKeyCode>=KEY_F1) && (nKeyCode<=KEY_F12)) // function keys F1..F12 - nKeyGlyph=kMenuF1Glyph+nKeyCode-KEY_F1; // only for n<13! - else if ((nKeyCode>=KEY_F13) && (nKeyCode<=KEY_F15)) - nKeyGlyph=kMenuF13Glyph+nKeyCode-KEY_F13; // function keys F13, F14, F15 -#if 0 - else if (nKeyCode==KEY_SPACE) - nKeyGlyph=kMenuSpaceGlyph; -#endif + nCommandKey = nKeyCode-KEY_0 + '0'; + else if ((nKeyCode>=KEY_F1) && (nKeyCode<=KEY_F26)) // function keys F1..F26 + nCommandKey = nKeyCode-KEY_F1 + NSF1FunctionKey; + else if( nKeyCode == KEY_REPEAT ) + nCommandKey = NSRedoFunctionKey; + else if( nKeyCode == KEY_SPACE ) + nCommandKey = ' '; else + { switch (nKeyCode) { case KEY_ADD: @@ -332,41 +406,43 @@ nCommandKey='='; break; } - - if (nCommandKey > -1) - SetMenuItemCommandKey (mrMenuRef, GETITEMINDEXBYPOS(nPos), 0, nCommandKey); - - if (nKeyGlyph > -1) - SetMenuItemKeyGlyph (mrMenuRef, GETITEMINDEXBYPOS(nPos), nKeyGlyph); - - if((nKeyGlyph <= -1) && (nCommandKey <= -1)) - AquaLog( "%s: Couldn't process rKeyCode.GetCode()=%d\n",__func__, rKeyCode.GetCode()); + } } + else // not even a code ? nonsense -> ignore + return; + + DBG_ASSERT( nCommandKey, "unmapped accelerator key" ); nModifier=rKeyCode.GetAllModifier(); - int nItemModifier = kMenuNoCommandModifier; + // should always use the command key + int nItemModifier = NSCommandKeyMask; + // ignore KEY_MOD1, Ctrl replaced by Command + #if 0 if (nModifier & KEY_MOD1) - nItemModifier = kMenuNoModifiers; // for the cmd key - // = and not += because should replace kMenuNoCommandModifier + nItemModifier |= NSControlKeyMask; // for the Ctrl key + #endif if (nModifier & KEY_SHIFT) - nItemModifier += kMenuShiftModifier; - - if (nModifier & KEY_MOD5) - //should use mod3 or 2 - nItemModifier += kMenuOptionModifier; // for the ALT key + { + nItemModifier |= NSShiftKeyMask; // actually useful only for function keys + if( nKeyCode >= KEY_A && nKeyCode <= KEY_Z ) + nCommandKey = nKeyCode - KEY_A + 'A'; + } if(nModifier & KEY_MOD2) - nItemModifier += kMenuControlModifier; // maybe for the ctrl key + nItemModifier |= NSAlternateKeyMask; - SetMenuItemModifiers (mrMenuRef, GETITEMINDEXBYPOS(nPos), nItemModifier); + AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem; + NSString* pString = CreateNSString( rtl::OUString( &nCommandKey, 1 ) ); + [pAquaSalMenuItem->mpMenuItem setKeyEquivalent: pString]; + [pAquaSalMenuItem->mpMenuItem setKeyEquivalentModifierMask: nItemModifier]; + [pString release]; } void AquaSalMenu::GetSystemMenuData( SystemMenuData* pData ) { - AquaLog( ">*>_> %s\n",__func__); } // ======================================================================= @@ -375,8 +451,93 @@ * SalMenuItem */ +AquaSalMenuItem::AquaSalMenuItem( const SalItemParams* pItemData ) : + mnId( pItemData->nId ), + mpVCLMenu( pItemData->pMenu ), + mpParentMenu( NULL ), + mpSubMenu( NULL ), + mpMenuItem( nil ) +{ + String aText( pItemData->aText ); + + // Delete mnemonics + aText.EraseAllChars( '~' ); + + if (pItemData->eType == MENUITEM_SEPARATOR) + mpMenuItem = [NSMenuItem separatorItem]; + else + { + mpMenuItem = [[SalNSMenuItem alloc] initWithMenuItem: this]; + + [mpMenuItem setEnabled: YES]; + NSString* pString = CreateNSString( aText ); + [mpMenuItem setTitle: pString]; + [pString release]; + + // anything but a separator should set a menu to dispatch to + DBG_ASSERT( mpVCLMenu, "no menu" ); + } + // these can go occasionally go in and out of a menu, ensure their lifecycle + [mpMenuItem retain]; +} + AquaSalMenuItem::~AquaSalMenuItem() { + if( mpMenuItem ) + [mpMenuItem release]; } // ------------------------------------------------------------------- + +@implementation SalNSMenu +-(id)initWithMenu: (AquaSalMenu*)pMenu +{ + mpMenu = pMenu; + return [super initWithTitle: [NSString string]]; +} + +-(void)menuNeedsUpdate: (NSMenu*)pMenu +{ + YIELD_GUARD; + + const AquaSalFrame* pFrame = mpMenu->getFrame(); + if( pFrame && AquaSalFrame::isAlive( pFrame ) ) + { + SalMenuEvent aMenuEvt; + aMenuEvt.mnId = 0; + aMenuEvt.mpMenu = mpMenu->mpVCLMenu; + if( aMenuEvt.mpMenu ) + { + pFrame->CallCallback(SALEVENT_MENUACTIVATE, &aMenuEvt); + pFrame->CallCallback(SALEVENT_MENUDEACTIVATE, &aMenuEvt); + } + else + DBG_ERROR( "unconnected menu" ); + } +} +@end + +@implementation SalNSMenuItem +-(id)initWithMenuItem: (AquaSalMenuItem*)pMenuItem +{ + mpMenuItem = pMenuItem; + id ret = [super initWithTitle: [NSString string] action: nil keyEquivalent: [NSString string]]; + [ret setAction:@selector(menuItemTriggered:)]; + [ret setTarget: self]; + return ret; +} +-(void)menuItemTriggered: (id)aSender +{ + YIELD_GUARD; + + const AquaSalFrame* pFrame = mpMenuItem->mpParentMenu ? mpMenuItem->mpParentMenu->getFrame() : NULL; + if( pFrame && AquaSalFrame::isAlive( pFrame ) ) + { + SalMenuEvent aMenuEvt; + aMenuEvt.mnId = mpMenuItem->mnId; + aMenuEvt.mpMenu = mpMenuItem->mpVCLMenu; + pFrame->CallCallback(SALEVENT_MENUCOMMAND, &aMenuEvt); + } +} +@end + diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/inc/vcl/salnativewidgets.hxx ooo_SRC680_m225_src.aquavcl03/vcl/inc/vcl/salnativewidgets.hxx --- ooo_SRC680_m225_src.orig/vcl/inc/vcl/salnativewidgets.hxx 2007-08-03 16:04:48.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/inc/vcl/salnativewidgets.hxx 2007-08-23 14:20:08.000000000 +0200 @@ -135,6 +135,12 @@ // The statusbar #define CTRL_STATUSBAR 130 #define CTRL_PROGRESS 131 +// Progress bar for the intro window +// (aka splash screen), in case some +// wants native progress bar in the +// application but not for the splash +// screen (used in desktop/) +#define CTRL_INTROPROGRESS 132 // tool tips #define CTRL_TOOLTIP 140 @@ -145,6 +151,14 @@ //to draw border of frames natively #define CTRL_FRAME 160 +// for nodes in listviews +// used in svtools/source/contnr/svtreebx.cxx +#define CTRL_LISTNODE 170 +// nets between elements of listviews +// with nodes +#define CTRL_LISTNET 171 + + /* Control Parts: * * Uniquely identify a part of a control, diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/inc/vcl/svids.hrc ooo_SRC680_m225_src.aquavcl03/vcl/inc/vcl/svids.hrc --- ooo_SRC680_m225_src.orig/vcl/inc/vcl/svids.hrc 2007-07-27 09:43:56.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/inc/vcl/svids.hrc 2007-08-08 18:07:13.000000000 +0200 @@ -104,7 +104,8 @@ #define SV_STDTEXT_DONTASKAGAIN 10202 #define SV_STDTEXT_DONTWARNAGAIN 10203 #define SV_STDTEXT_ABOUT 10204 -#define SV_STDTEXT_LAST SV_STDTEXT_ABOUT +#define SV_STDTEXT_PREFERENCES 10205 +#define SV_STDTEXT_LAST SV_STDTEXT_PREFERENCES #define SV_ACCESSERROR_FIRST SV_ACCESSERROR_WRONG_VERSION #define SV_ACCESSERROR_WRONG_VERSION 10500 diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/source/app/svmainhook.cxx ooo_SRC680_m225_src.aquavcl03/vcl/source/app/svmainhook.cxx --- ooo_SRC680_m225_src.orig/vcl/source/app/svmainhook.cxx 2007-08-03 16:06:28.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/source/app/svmainhook.cxx 2007-08-07 12:49:20.000000000 +0200 @@ -48,46 +48,8 @@ } #else -#ifdef QUARTZ // only Mac OS X / X11 needs this trick, the Aqua version has its own native event loop -#include -//#include -#include -#include -#include - -extern BOOL ImplSVMain(); - -static BOOL* gpbInit = 0; - -static pascal void MainRunLoopForThreadedApps( EventLoopTimerRef inTimer, void *inUserData ) -{ - BOOL bRet = ImplSVMain(); - if( gpbInit ) - *gpbInit = bRet; - - QuitApplicationEventLoop(); -} - -BOOL ImplSVMainHook( BOOL * pbInit ) -{ - gpbInit = pbInit; - - // install handlers of AppleEvents BEFORE handling event loops - // else we miss the for initial OpenDocument apple events - extern void InstallAEHandlers(); - InstallAEHandlers(); - - EventLoopTimerRef aMainRunLoopTimerRef; - (void) InstallEventLoopTimer( GetCurrentEventLoop(), 0, 0, NewEventLoopTimerUPP( MainRunLoopForThreadedApps ), NULL, &aMainRunLoopTimerRef ); - - // We really only call RunApplicationEventLoop() to install the default CarbonEvent handlers. Once the timer installed above - // fires, we remain in the MainRunLoopForThreadedApps() routine which is designed to yield to other cooperative threads. - RunApplicationEventLoop(); - - return TRUE; // indicate that ImplSVMainHook is implemented -} - -#else // MACOSX (X11) needs the CFRunLoop() +// MACOSX cocoa implementation of ImplSVMainHook is in aqua/source/app/salinst.cxx +#ifndef QUARTZ // MACOSX (X11) needs the CFRunLoop() #include #include #include diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/source/gdi/outdev3.cxx ooo_SRC680_m225_src.aquavcl03/vcl/source/gdi/outdev3.cxx --- ooo_SRC680_m225_src.orig/vcl/source/gdi/outdev3.cxx 2007-07-24 12:12:25.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/source/gdi/outdev3.cxx 2007-08-17 17:18:27.000000000 +0200 @@ -5719,6 +5719,9 @@ if( mbNewFont ) if( !ImplNewFont() ) return 0; + if( mbInitFont ) + if( !ImplNewFont() ) + return 0; long nHeight = mpFontEntry->mnLineHeight + mnEmphasisAscent + mnEmphasisDescent; diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/source/src/stdtext.src ooo_SRC680_m225_src.aquavcl03/vcl/source/src/stdtext.src --- ooo_SRC680_m225_src.orig/vcl/source/src/stdtext.src 2007-07-24 12:17:30.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/source/src/stdtext.src 2007-08-08 18:07:13.000000000 +0200 @@ -113,3 +113,9 @@ { Text [ en-US ] = "About %PRODUCTNAME"; }; + +String SV_STDTEXT_PREFERENCES +{ + Text [ en-US ] = "Preferences..."; +}; + diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/util/makefile2.pmk ooo_SRC680_m225_src.aquavcl03/vcl/util/makefile2.pmk --- ooo_SRC680_m225_src.orig/vcl/util/makefile2.pmk 2005-09-09 15:53:58.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/util/makefile2.pmk 2007-07-27 00:17:46.000000000 +0200 @@ -40,3 +40,8 @@ .ELIF "$(COMNAME)" == "sunpro5" && "$(CCNUMVER)" >= "00050005" CFLAGS += -xldscope=hidden .ENDIF + +.IF "$(GUIBASE)"=="aqua" +OBJCXXFLAGS=-x objective-c++ -fobjc-exceptions +CFLAGSCXX+=$(OBJCXXFLAGS) +.ENDIF # "$(GUIBASE)"=="aqua" diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/workben/makefile.mk ooo_SRC680_m225_src.aquavcl03/vcl/workben/makefile.mk --- ooo_SRC680_m225_src.orig/vcl/workben/makefile.mk 2007-07-24 12:43:56.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/workben/makefile.mk 2007-08-07 13:17:04.000000000 +0200 @@ -98,7 +98,7 @@ APP3NOSAL=TRUE APP3TARGET=vcldemo APP3OBJS= \ - $(OBJ)$/svdem.obj + $(OBJ)$/vcldemo.obj APP3STDLIBS= $(CPPULIB) \ $(UNOTOOLSLIB) \ diff -x CVS -x wntmsci3 -x wntmsci7 -x wntmsci8 -urN ooo_SRC680_m225_src.orig/vcl/workben/vcldemo.cxx ooo_SRC680_m225_src.aquavcl03/vcl/workben/vcldemo.cxx --- ooo_SRC680_m225_src.orig/vcl/workben/vcldemo.cxx 2007-07-05 17:56:47.000000000 +0200 +++ ooo_SRC680_m225_src.aquavcl03/vcl/workben/vcldemo.cxx 2007-07-26 13:02:27.000000000 +0200 @@ -177,6 +177,11 @@ DrawLine( Point(r.nLeft, r.nTop+i), Point(r.nRight, r.nBottom-i) ); for(int i=0; i