bump product version to 4.2.0.1
[LibreOffice.git] / vcl / aqua / source / window / salframeview.mm
blob4bb1dfde3c4072efd124f70e3a3a37cc4dcb0e44
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
20 #include <sal/alloca.h>
21 #include <sal/macros.h>
23 #include "tools/helpers.hxx"
24 #include "vcl/window.hxx"
25 #include "vcl/svapp.hxx"
27 #include "aqua/salinst.h"
28 #include "aqua/salgdi.h"
29 #include "aqua/salframe.h"
30 #include "aqua/salframeview.h"
31 #include "aqua/aqua11yfactory.h"
32 #include "quartz/utils.h"
34 #define WHEEL_EVENT_FACTOR 1.5
36 // for allowing fullscreen support on deployment targets < OSX 10.7
37 #if !defined(MAC_OS_X_VERSION_10_7)
38     #define NSWindowCollectionBehaviorFullScreenPrimary   (1 << 7)
39     #define NSWindowCollectionBehaviorFullScreenAuxiliary (1 << 8)
40 //  #define NSFullScreenWindowMask (1 << 14)
41 #endif
44 static sal_uInt16 ImplGetModifierMask( unsigned int nMask )
46     sal_uInt16 nRet = 0;
47     if( (nMask & NSShiftKeyMask) != 0 )
48         nRet |= KEY_SHIFT;
49     if( (nMask & NSControlKeyMask) != 0 )
50         nRet |= KEY_MOD3;
51     if( (nMask & NSAlternateKeyMask) != 0 )
52         nRet |= KEY_MOD2;
53     if( (nMask & NSCommandKeyMask) != 0 )
54         nRet |= KEY_MOD1;
55     return nRet;
58 static sal_uInt16 ImplMapCharCode( sal_Unicode aCode )
60     static sal_uInt16 aKeyCodeMap[ 128 ] =
61     {
62         0, 0, 0, 0, 0, 0, 0, 0,
63         KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0,
64         0, 0, 0, 0, 0, 0, 0, 0,
65         0, KEY_TAB, 0, KEY_ESCAPE, 0, 0, 0, 0,
66         KEY_SPACE, 0, 0, 0, 0, 0, 0, 0,
67         0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE,
68         KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
69         KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0,
70         0, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
71         KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
72         KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
73         KEY_X, KEY_Y, KEY_Z, 0, 0, 0, 0, 0,
74         KEY_QUOTELEFT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
75         KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
76         KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
77         KEY_X, KEY_Y, KEY_Z, 0, 0, 0, KEY_TILDE, KEY_BACKSPACE
78     };
79     
80     // Note: the mapping 0x7f should by rights be KEY_DELETE
81     // however if you press "backspace" 0x7f is reported
82     // whereas for "delete" 0xf728 gets reported
83     
84     // Note: the mapping of 0x19 to KEY_TAB is because for unknown reasons
85     // tab alone is reported as 0x09 (as expected) but shift-tab is
86     // reported as 0x19 (end of medium)
87     
88     static sal_uInt16 aFunctionKeyCodeMap[ 128 ] =
89     {
90         KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4,
91         KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
92         KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20,
93         KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0,
94         0, 0, 0, 0, 0, 0, 0, KEY_INSERT,
95         KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0,
96         0, 0, 0, 0, 0, KEY_MENU, 0, 0,
97         0, 0, 0, 0, 0, 0, 0, 0,
98         0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 0,
99         0, 0, 0, 0, 0, 0, 0, 0,
100         0, 0, 0, 0, 0, 0, 0, 0,
101         0, 0, 0, 0, 0, 0, 0, 0,
102         0, 0, 0, 0, 0, 0, 0, 0,
103         0, 0, 0, 0, 0, 0, 0, 0,
104         0, 0, 0, 0, 0, 0, 0, 0,
105         0, 0, 0, 0, 0, 0, 0, 0
106     };
107     
108     sal_uInt16 nKeyCode = 0;
109     if( aCode < SAL_N_ELEMENTS( aKeyCodeMap)  )
110         nKeyCode = aKeyCodeMap[ aCode ];
111     else if( aCode >= 0xf700 && aCode < 0xf780 )
112         nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ]; 
113     return nKeyCode;
116 static sal_uInt16 ImplMapKeyCode(sal_uInt16 nKeyCode)
118     /*
119       http://stackoverflow.com/questions/2080312/where-can-i-find-a-list-of-key-codes-for-use-with-cocoas-nsevent-class/2080324#2080324
120       /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h
121      */
123     static sal_uInt16 aKeyCodeMap[ 0x80 ] =
124     {
125         KEY_A,               KEY_S,     KEY_D,        KEY_F,      KEY_H,      KEY_G,            KEY_Z,         KEY_X,
126         KEY_C,               KEY_V,     0,            KEY_B,      KEY_Q,      KEY_W,            KEY_E,         KEY_R,
127         KEY_Y,               KEY_T,     KEY_1,        KEY_2,      KEY_3,      KEY_4,            KEY_6,         KEY_5,
128         KEY_EQUAL,           KEY_9,     KEY_7, KEY_SUBTRACT,      KEY_8,      KEY_0, KEY_BRACKETRIGHT,         KEY_0,
129         KEY_U,     KEY_BRACKETLEFT,     KEY_I,        KEY_P, KEY_RETURN,      KEY_L,            KEY_J, KEY_QUOTELEFT,
130         KEY_K,       KEY_SEMICOLON,         0,    KEY_COMMA, KEY_DIVIDE,      KEY_N,            KEY_M,     KEY_POINT,
131         KEY_TAB,         KEY_SPACE, KEY_TILDE,   KEY_DELETE,          0, KEY_ESCAPE,                0,             0,
132               0,      KEY_CAPSLOCK,         0,            0,          0,          0,                0,             0,
133         KEY_F17,       KEY_DECIMAL,         0, KEY_MULTIPLY,          0,    KEY_ADD,                0,             0,
134               0,                 0,         0,   KEY_DIVIDE, KEY_RETURN,          0,     KEY_SUBTRACT,       KEY_F18,
135         KEY_F19,         KEY_EQUAL,         0,            0,          0,          0,                0,             0,
136               0,                 0,   KEY_F20,            0,          0,          0,                0,             0,
137          KEY_F5,            KEY_F6,    KEY_F7,       KEY_F3,     KEY_F8,     KEY_F9,                0,       KEY_F11,
138               0,           KEY_F13,   KEY_F16,      KEY_F14,          0,    KEY_F10,                0,       KEY_F12,
139               0,           KEY_F15,  KEY_HELP,     KEY_HOME, KEY_PAGEUP, KEY_DELETE,           KEY_F4,       KEY_END,
140          KEY_F2,      KEY_PAGEDOWN,    KEY_F1,     KEY_LEFT,  KEY_RIGHT,   KEY_DOWN,           KEY_UP,             0
141     };
143     if (nKeyCode < SAL_N_ELEMENTS(aKeyCodeMap))
144         return aKeyCodeMap[nKeyCode];
145     return 0;
148 // store the frame the mouse last entered
149 static AquaSalFrame* s_pMouseFrame = NULL;
150 // store the last pressed button for enter/exit events
151 // which lack that information
152 static sal_uInt16 s_nLastButton = 0;
154 // combinations of keys we need to handle ourselves
155 static const struct ExceptionalKey
157     const sal_uInt16        nKeyCode;
158     const unsigned int  nModifierMask;
159 } aExceptionalKeys[] =
161     { KEY_D, NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask },
162     { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask }
165 static AquaSalFrame* getMouseContainerFrame()
167     NSInteger nWindows = 0;
168     NSCountWindows( &nWindows );
169     NSInteger* pWindows = (NSInteger*)alloca( nWindows * sizeof(NSInteger) );
170     // note: NSWindowList is supposed to be in z-order front to back
171     NSWindowList( nWindows, pWindows );
172     AquaSalFrame* pDispatchFrame = NULL;
173     for(int i = 0; i < nWindows && ! pDispatchFrame; i++ )
174     {
175         NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]];
176         if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] )
177             pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame];
178     }
179     return pDispatchFrame;
182 @implementation SalFrameWindow
183 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
185         mDraggingDestinationHandler = nil;
186     mpFrame = pFrame;
187     NSRect aRect = { { static_cast<CGFloat>(pFrame->maGeometry.nX), static_cast<CGFloat>(pFrame->maGeometry.nY) },
188                      { static_cast<CGFloat>(pFrame->maGeometry.nWidth), static_cast<CGFloat>(pFrame->maGeometry.nHeight) } };
189     pFrame->VCLToCocoa( aRect );
190     NSWindow* pNSWindow = [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ];
191     [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver
193     // enable OSX>=10.7 fullscreen options if available and useful
194     bool bAllowFullScreen = (0 == (mpFrame->mnStyle & (SAL_FRAME_STYLE_DIALOG | SAL_FRAME_STYLE_TOOLTIP | SAL_FRAME_STYLE_SYSTEMCHILD | SAL_FRAME_STYLE_FLOAT | SAL_FRAME_STYLE_TOOLWINDOW | SAL_FRAME_STYLE_INTRO)));
195     bAllowFullScreen &= (0 == (~mpFrame->mnStyle & (SAL_FRAME_STYLE_SIZEABLE)));
196     bAllowFullScreen &= (mpFrame->mpParent == NULL);
197     const SEL setCollectionBehavior = @selector(setCollectionBehavior:);
198     if( bAllowFullScreen && [pNSWindow respondsToSelector: setCollectionBehavior])
199     {
200         const int bMode= (bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary);
201         [pNSWindow performSelector:setCollectionBehavior withObject:(id)(intptr_t)bMode];
202     }
204     // disable OSX>=10.7 window restoration until we support it directly
205     const SEL setRestorable = @selector(setRestorable:);
206     if( [pNSWindow respondsToSelector: setRestorable]) {
207         [pNSWindow performSelector:setRestorable withObject:(id)NO];
208     }
210     return (SalFrameWindow *) pNSWindow;
213 -(AquaSalFrame*)getSalFrame
215     return mpFrame;
218 -(void)displayIfNeeded
220     if( GetSalData() && GetSalData()->mpFirstInstance )
221     {
222         comphelper::SolarMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex();
223         if( pMutex )
224         {
225             pMutex->acquire();
226             [super displayIfNeeded];
227             pMutex->release();
228         }
229     }
232 -(BOOL)containsMouse
234     // is this event actually inside that NSWindow ?
235     NSPoint aPt = [NSEvent mouseLocation];
236     NSRect aFrameRect = [self frame];
237     BOOL bInRect = NSPointInRect( aPt, aFrameRect );
238     return bInRect;
241 -(BOOL)canBecomeKeyWindow
243     if( (mpFrame->mnStyle & 
244             ( SAL_FRAME_STYLE_FLOAT                 |
245               SAL_FRAME_STYLE_TOOLTIP               |
246               SAL_FRAME_STYLE_INTRO
247             )) == 0 )
248         return YES;
249     if( (mpFrame->mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) != 0 )
250         return YES;
251     if( mpFrame->mbFullScreen )
252         return YES;
253     if( (mpFrame->mnStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) )
254         return YES;
255     return [super canBecomeKeyWindow];
258 -(void)windowDidBecomeKey: (NSNotification*)pNotification
260     (void)pNotification;
261     YIELD_GUARD;
263     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
264     {
265         static const sal_uLong nGuessDocument = SAL_FRAME_STYLE_MOVEABLE|
266                                             SAL_FRAME_STYLE_SIZEABLE|
267                                             SAL_FRAME_STYLE_CLOSEABLE;
268         
269         if( mpFrame->mpMenu )
270             mpFrame->mpMenu->setMainMenu();
271         else if( ! mpFrame->mpParent &&
272                  ( (mpFrame->mnStyle & nGuessDocument) == nGuessDocument || // set default menu for e.g. help
273                     mpFrame->mbFullScreen ) )                               // ser default menu for e.g. presentation
274         {
275             AquaSalMenu::setDefaultMenu();
276         }
277         #if 0
278         // FIXME: we should disable menus while in modal mode
279         // however from down here there is currently no reliable way to
280         // find out when to do this
281         if( (mpFrame->mpParent && mpFrame->mpParent->GetWindow()->IsInModalMode()) )
282             AquaSalMenu::enableMainMenu( false );
283         #endif
284         mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 );
285         mpFrame->SendPaintEvent(); // repaint controls as active
286     }
289 -(void)windowDidResignKey: (NSNotification*)pNotification
291     (void)pNotification;
292     YIELD_GUARD;
294     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
295     {
296         mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0);
297         mpFrame->SendPaintEvent(); // repaint controls as inactive
298     }
301 -(void)windowDidChangeScreen: (NSNotification*)pNotification
303     (void)pNotification;
304     YIELD_GUARD;
306     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
307         mpFrame->screenParametersChanged();
310 -(void)windowDidMove: (NSNotification*)pNotification
312     (void)pNotification;
313     YIELD_GUARD;
315     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
316     {
317         mpFrame->UpdateFrameGeometry();
318         mpFrame->CallCallback( SALEVENT_MOVE, 0 );
319     }
322 -(void)windowDidResize: (NSNotification*)pNotification
324     (void)pNotification;
325     YIELD_GUARD;
327     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
328     {
329         mpFrame->UpdateFrameGeometry();
330         mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
331         mpFrame->SendPaintEvent();
332     }
335 -(void)windowDidMiniaturize: (NSNotification*)pNotification
337     (void)pNotification;
338     YIELD_GUARD;
340     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
341     {
342         mpFrame->mbShown = false;
343         mpFrame->UpdateFrameGeometry();
344         mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
345     }
348 -(void)windowDidDeminiaturize: (NSNotification*)pNotification
350     (void)pNotification;
351     YIELD_GUARD;
353     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
354     {
355         mpFrame->mbShown = true;
356         mpFrame->UpdateFrameGeometry();
357         mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
358     }
361 -(BOOL)windowShouldClose: (NSNotification*)pNotification
363     (void)pNotification;
364     YIELD_GUARD;
366     BOOL bRet = YES;
367     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
368     {
369         // #i84461# end possible input
370         mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
371         if( AquaSalFrame::isAlive( mpFrame ) )
372         {
373             mpFrame->CallCallback( SALEVENT_CLOSE, 0 );
374             bRet = NO; // application will close the window or not, AppKit shouldn't
375         }
376     }
378     return bRet;
381 -(void)windowDidEnterFullScreen: (NSNotification*)pNotification
383     YIELD_GUARD;
385     if( !mpFrame || !AquaSalFrame::isAlive( mpFrame))
386         return;
387     mpFrame->mbFullScreen = true;
388     (void)pNotification;
391 -(void)windowDidExitFullScreen: (NSNotification*)pNotification
393     YIELD_GUARD;
395     if( !mpFrame || !AquaSalFrame::isAlive( mpFrame))
396         return;
397     mpFrame->mbFullScreen = false;
398     (void)pNotification;
401 -(void)dockMenuItemTriggered: (id)sender
403     (void)sender;
404     YIELD_GUARD;
406     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
407         mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS );
410 -(::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >)accessibleContext
412     return mpFrame -> GetWindow() -> GetAccessible() -> getAccessibleContext();
415 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
417   return [mDraggingDestinationHandler draggingEntered: sender];
420 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
422   return [mDraggingDestinationHandler draggingUpdated: sender];
425 -(void)draggingExited:(id <NSDraggingInfo>)sender
427   [mDraggingDestinationHandler draggingExited: sender];
430 -(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
432   return [mDraggingDestinationHandler prepareForDragOperation: sender];
435 -(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
437   return [mDraggingDestinationHandler performDragOperation: sender];
440 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
442   [mDraggingDestinationHandler concludeDragOperation: sender];
445 -(void)registerDraggingDestinationHandler:(id)theHandler
447   mDraggingDestinationHandler = theHandler;
450 -(void)unregisterDraggingDestinationHandler:(id)theHandler
452     (void)theHandler;
453     mDraggingDestinationHandler = nil;
456 @end
458 @implementation SalFrameView
459 +(void)unsetMouseFrame: (AquaSalFrame*)pFrame
461     if( pFrame == s_pMouseFrame )
462         s_pMouseFrame = NULL;
465 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
467     if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [pFrame->getWindow() frame] styleMask: pFrame->mnStyleMask]]) != nil)
468     {
469         mDraggingDestinationHandler = nil;
470         mpFrame = pFrame;
471         mMarkedRange = NSMakeRange(NSNotFound, 0);
472         mSelectedRange = NSMakeRange(NSNotFound, 0);
473         mpReferenceWrapper = nil;
474                 mpMouseEventListener = nil;
475         mpLastSuperEvent = nil;
476     }
478     mfLastMagnifyTime = 0.0;
479     return self;
482 -(AquaSalFrame*)getSalFrame
484     return mpFrame;
487 -(void)resetCursorRects
489     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
490     {
491         // FIXME: does this leak the returned NSCursor of getCurrentCursor ?
492         NSRect aRect = { { 0, 0 }, { static_cast<CGFloat>(mpFrame->maGeometry.nWidth), static_cast<CGFloat>(mpFrame->maGeometry.nHeight) } };
493         [self addCursorRect: aRect cursor: mpFrame->getCurrentCursor()];
494     }
497 -(BOOL)acceptsFirstResponder
499     return YES;
502 -(BOOL)acceptsFirstMouse: (NSEvent*)pEvent
504     (void)pEvent;
505     return YES;
508 -(BOOL)isOpaque
510         if( !mpFrame)
511                 return YES;
512         if( !AquaSalFrame::isAlive( mpFrame))
513                 return YES;
514         if( !mpFrame->getClipPath())
515                 return YES;
516         return NO;
519 // helper class similar to a osl::Guard< comphelper::SolarMutex > for the
520 // SalYieldMutex; the difference is that it only does tryToAcquire instead of
521 // acquire so dreaded deadlocks like #i93512# are prevented
522 class TryGuard
524 public:
525                         TryGuard()  { mbGuarded = ImplSalYieldMutexTryToAcquire(); }
526                         ~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); }
527         bool    IsGuarded() { return mbGuarded; }
528 private:
529         bool    mbGuarded;
532 -(void)drawRect: (NSRect)aRect
534         // HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex
535         TryGuard aTryGuard;
536         if( !aTryGuard.IsGuarded() )
537         {
538                 // NOTE: the mpFrame access below is not guarded yet!
539                 // TODO: mpFrame et al need to be guarded by an independent mutex
540                 AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL;
541                 if( pGraphics )
542                 {
543                         // we did not get the mutex so we cannot draw now => request to redraw later
544                         // convert the NSRect to a CGRect for Refreshrect()
545                         const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}};
546                         pGraphics->RefreshRect( aCGRect );
547                 }
548                 return;
549         }
551     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
552     {
553         if( mpFrame->mpGraphics )
554         {
555             mpFrame->mpGraphics->UpdateWindow( aRect );
556             if( mpFrame->getClipPath() )
557                 [mpFrame->getWindow() invalidateShadow];
558         }
559     }
562 -(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(sal_uInt16)nButton eventtype:(sal_uInt16)nEvent
564     YIELD_GUARD;
566     AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame();
567     bool bIsCaptured = false;
568     if( pDispatchFrame )
569     {
570         bIsCaptured = true;
571         if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured
572             nEvent = SALEVENT_MOUSEMOVE;
573     }
574     else if( s_pMouseFrame )
575         pDispatchFrame = s_pMouseFrame;
576     else
577         pDispatchFrame = mpFrame;
578     
579     /* #i81645# Cocoa reports mouse events while a button is pressed
580        to the window in which it was first pressed. This is reasonable and fine and
581        gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer,
582        however vcl expects mouse events to occur in the window the mouse is over, unless the
583        mouse is explicitly captured. So we need to find the window the mouse is actually
584        over for conformance with other platforms.
585     */
586     if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
587     {
588         // is this event actually inside that NSWindow ?
589         NSPoint aPt = [NSEvent mouseLocation];
590         NSRect aFrameRect = [pDispatchFrame->getWindow() frame];
591         
592         if ( ! NSPointInRect( aPt, aFrameRect ) )
593         {
594             // no, it is not
595             // now we need to find the one it may be in
596             /* #i93756# we ant to get enumerate the application windows in z-order
597                to check if any contains the mouse. This could be elegantly done with this
598                code:
600                // use NSApp to check windows in ZOrder whether they contain the mouse pointer
601                NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES];
602                if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] )
603                    pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame];
604                
605                However if a non SalFrameWindow is on screen (like e.g. the file dialog)
606                it can be hit with the containsMouse selector, which it doesn't support.
607                Sadly NSApplication:makeWindowsPerform does not check (for performance reasons
608                I assume) whether a window supports a selector before sending it. 
609             */
610             AquaSalFrame* pMouseFrame = getMouseContainerFrame();
611             if( pMouseFrame )
612                 pDispatchFrame = pMouseFrame;
613         }
614     }
615     
616     if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
617     {
618         pDispatchFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
619         pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags];
621         NSPoint aPt = [NSEvent mouseLocation];
622         pDispatchFrame->CocoaToVCL( aPt );
623         
624         sal_uInt16 nModMask = ImplGetModifierMask( [pEvent modifierFlags] );
625         // #i82284# emulate ctrl left
626         if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT )
627         {
628             nModMask    = 0;
629             nButton     = MOUSE_RIGHT;
630         }
632         SalMouseEvent aEvent;
633         aEvent.mnTime   = pDispatchFrame->mnLastEventTime;
634         aEvent.mnX      = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX;
635         aEvent.mnY      = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY;
636         aEvent.mnButton = nButton;
637         aEvent.mnCode   =  aEvent.mnButton | nModMask;
639         // --- RTL --- (mirror mouse pos)
640         if( Application::GetSettings().GetLayoutRTL() )
641             aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX;
642         
643         pDispatchFrame->CallCallback( nEvent, &aEvent );
644     }
647 -(void)mouseDown: (NSEvent*)pEvent
649     if ( mpMouseEventListener != nil && 
650             [mpMouseEventListener respondsToSelector: @selector(mouseDown:)])
651         {
652             [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]];
653         }
655     s_nLastButton = MOUSE_LEFT;
656     [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN];
659 -(void)mouseDragged: (NSEvent*)pEvent
661     if ( mpMouseEventListener != nil && 
662              [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)])
663         {
664             [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]];
665         }
666     s_nLastButton = MOUSE_LEFT;
667     [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE];
670 -(void)mouseUp: (NSEvent*)pEvent
672     s_nLastButton = 0;
673     [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP];
676 -(void)mouseMoved: (NSEvent*)pEvent
678     s_nLastButton = 0;
679     [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE];
682 -(void)mouseEntered: (NSEvent*)pEvent
684     s_pMouseFrame = mpFrame;
686     // #i107215# the only mouse events we get when inactive are enter/exit
687     // actually we would like to have all of them, but better none than some
688     if( [NSApp isActive] )
689         [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE];
692 -(void)mouseExited: (NSEvent*)pEvent
694     if( s_pMouseFrame == mpFrame )
695         s_pMouseFrame = NULL;
697     // #i107215# the only mouse events we get when inactive are enter/exit
698     // actually we would like to have all of them, but better none than some
699     if( [NSApp isActive] )
700         [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE];
703 -(void)rightMouseDown: (NSEvent*)pEvent
705     s_nLastButton = MOUSE_RIGHT;
706     [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN];
709 -(void)rightMouseDragged: (NSEvent*)pEvent
711     s_nLastButton = MOUSE_RIGHT;
712     [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE];
715 -(void)rightMouseUp: (NSEvent*)pEvent
717     s_nLastButton = 0;
718     [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP];
721 -(void)otherMouseDown: (NSEvent*)pEvent
723     if( [pEvent buttonNumber] == 2 )
724     {
725         s_nLastButton = MOUSE_MIDDLE;
726         [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN];
727     }
728     else
729         s_nLastButton = 0;
732 -(void)otherMouseDragged: (NSEvent*)pEvent
734     if( [pEvent buttonNumber] == 2 )
735     {
736         s_nLastButton = MOUSE_MIDDLE;
737         [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE];
738     }
739     else
740         s_nLastButton = 0;
743 -(void)otherMouseUp: (NSEvent*)pEvent
745     s_nLastButton = 0;
746     if( [pEvent buttonNumber] == 2 )
747         [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP];
750 - (void)magnifyWithEvent: (NSEvent*)pEvent
752     YIELD_GUARD;
753     
754     // TODO: ??  -(float)magnification;
755     if( AquaSalFrame::isAlive( mpFrame ) )
756         {
757                 const NSTimeInterval fMagnifyTime = [pEvent timestamp];
758         mpFrame->mnLastEventTime = static_cast<sal_uLong>( fMagnifyTime * 1000.0 );
759         mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
761         // check if this is a new series of magnify events
762         static const NSTimeInterval fMaxDiffTime = 0.3;
763         const bool bNewSeries = (fMagnifyTime - mfLastMagnifyTime > fMaxDiffTime);
765         if( bNewSeries )
766             mfMagnifyDeltaSum = 0.0;
767         mfMagnifyDeltaSum += [pEvent deltaZ];
769                 mfLastMagnifyTime = [pEvent timestamp];
770                 // TODO: change to 0.1 when COMMAND_WHEEL_ZOOM handlers allow finer zooming control
771                 static const float fMagnifyFactor = 0.25;
772         static const float fMinMagnifyStep = 15.0 / fMagnifyFactor;
773         if( fabs(mfMagnifyDeltaSum) <= fMinMagnifyStep )
774             return;
776         // adapt NSEvent-sensitivity to application expectations
777         // TODO: rather make COMMAND_WHEEL_ZOOM handlers smarter
778         const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor;
779         int nDeltaZ = FRound( fDeltaZ );
780         if( !nDeltaZ )
781         {
782             // handle new series immediately
783             if( !bNewSeries )
784                 return;
785             nDeltaZ = (fDeltaZ >= 0.0) ? +1 : -1;
786         }
787         // eventually give credit for delta sum
788         mfMagnifyDeltaSum -= nDeltaZ / fMagnifyFactor;
790         NSPoint aPt = [NSEvent mouseLocation];
791         mpFrame->CocoaToVCL( aPt );
792         
793         SalWheelMouseEvent aEvent;
794         aEvent.mnTime           = mpFrame->mnLastEventTime;
795         aEvent.mnX              = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
796         aEvent.mnY              = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
797         aEvent.mnCode           = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
798         aEvent.mnCode           |= KEY_MOD1; // we want zooming, no scrolling
799         aEvent.mbDeltaIsPixel   = TRUE;
800         
801         // --- RTL --- (mirror mouse pos)
802         if( Application::GetSettings().GetLayoutRTL() )
803             aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
804         
805         aEvent.mnDelta = nDeltaZ;
806         aEvent.mnNotchDelta = (nDeltaZ >= 0) ? +1 : -1;
807         if( aEvent.mnDelta == 0 )
808             aEvent.mnDelta = aEvent.mnNotchDelta;
809         aEvent.mbHorz = FALSE;
810         aEvent.mnScrollLines = nDeltaZ;
811         if( aEvent.mnScrollLines == 0 )
812             aEvent.mnScrollLines = 1;
813         mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
814     }
817 - (void)rotateWithEvent: (NSEvent*)pEvent
819     //Rotation : -(float)rotation;
820     // TODO: create new CommandType so rotation is available to the applications
821     (void)pEvent;
824 - (void)swipeWithEvent: (NSEvent*)pEvent
826     YIELD_GUARD;
827     
828     if( AquaSalFrame::isAlive( mpFrame ) )
829     {
830         mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
831         mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
832         
833         // merge pending scroll wheel events
834         float dX = 0.0;
835         float dY = 0.0;
836         for(;;)
837         {
838             dX += [pEvent deltaX];
839             dY += [pEvent deltaY];
840             NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
841             untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
842             if( !pNextEvent )
843                 break;
844             pEvent = pNextEvent;
845         }
846         
847         NSPoint aPt = [NSEvent mouseLocation];
848         mpFrame->CocoaToVCL( aPt );
849         
850         SalWheelMouseEvent aEvent;
851         aEvent.mnTime           = mpFrame->mnLastEventTime;
852         aEvent.mnX              = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
853         aEvent.mnY              = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
854         aEvent.mnCode           = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
855         aEvent.mbDeltaIsPixel   = TRUE;
856         
857         // --- RTL --- (mirror mouse pos)
858         if( Application::GetSettings().GetLayoutRTL() )
859             aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
860         
861         if( dX != 0.0 )
862         {
863             aEvent.mnDelta = static_cast<long>(floor(dX));
864             aEvent.mnNotchDelta = dX < 0 ? -1 : 1;
865             if( aEvent.mnDelta == 0 )
866                 aEvent.mnDelta = aEvent.mnNotchDelta;
867             aEvent.mbHorz = TRUE;
868             aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
869             mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
870         }
871         if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ))
872         {
873             aEvent.mnDelta = static_cast<long>(floor(dY));
874             aEvent.mnNotchDelta = dY < 0 ? -1 : 1;
875             if( aEvent.mnDelta == 0 )
876                 aEvent.mnDelta = aEvent.mnNotchDelta;
877             aEvent.mbHorz = FALSE;
878             aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
879             mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
880         }
881     }
884 -(void)scrollWheel: (NSEvent*)pEvent
886     YIELD_GUARD;
887     
888     if( AquaSalFrame::isAlive( mpFrame ) )
889     {
890         mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
891         mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
893         // merge pending scroll wheel events
894         float dX = 0.0;
895         float dY = 0.0;
896         for(;;)
897         {
898             dX += [pEvent deltaX];
899             dY += [pEvent deltaY];
900             NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
901                 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
902             if( !pNextEvent )
903                 break;
904             pEvent = pNextEvent;
905         }
907         NSPoint aPt = [NSEvent mouseLocation];
908         mpFrame->CocoaToVCL( aPt );
910         SalWheelMouseEvent aEvent;
911         aEvent.mnTime         = mpFrame->mnLastEventTime;
912         aEvent.mnX            = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
913         aEvent.mnY            = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
914         aEvent.mnCode         = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
915         aEvent.mbDeltaIsPixel = FALSE;
917         // --- RTL --- (mirror mouse pos)
918         if( Application::GetSettings().GetLayoutRTL() )
919             aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
921         if( dX != 0.0 )
922         {
923             aEvent.mnDelta = static_cast<long>(floor(dX));
924             aEvent.mnNotchDelta = dX < 0 ? -1 : 1;
925             if( aEvent.mnDelta == 0 )
926                 aEvent.mnDelta = aEvent.mnNotchDelta;
927             aEvent.mbHorz = TRUE;
928             aEvent.mnScrollLines = dX > 0 ? dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR;
929             if( aEvent.mnScrollLines == 0 )
930                 aEvent.mnScrollLines = 1;
932             mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
933         }
934         if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) )
935         {
936             aEvent.mnDelta = static_cast<long>(floor(dY));
937             aEvent.mnNotchDelta = dY < 0 ? -1 : 1;
938             if( aEvent.mnDelta == 0 )
939                 aEvent.mnDelta = aEvent.mnNotchDelta;
940             aEvent.mbHorz = FALSE;
941             aEvent.mnScrollLines = dY > 0 ? dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR;
942             if( aEvent.mnScrollLines < 1 )
943                 aEvent.mnScrollLines = 1;
945             mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
946         }
947     }
951 -(void)keyDown: (NSEvent*)pEvent
953     YIELD_GUARD;
954     
955     if( AquaSalFrame::isAlive( mpFrame ) )
956     {
957         mpLastEvent = pEvent;
958         mbInKeyInput = true;
959         mbNeedSpecialKeyHandle = false;
960         mbKeyHandled = false;
962         mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
963         mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
964         
965         if( ! [self handleKeyDownException: pEvent] )
966         {
967             NSArray* pArray = [NSArray arrayWithObject: pEvent];
968             [self interpretKeyEvents: pArray];
969         }
971         mbInKeyInput = false;
972     }
975 -(BOOL)handleKeyDownException:(NSEvent*)pEvent
977     // check for a very special set of modified characters
978     NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 
980     if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
981     {
982         /* #i103102# key events with command and alternate don't make it through
983            interpretKeyEvents (why ?). Try to dispatch them here first,
984            if not successful continue normally
985         */
986         if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask))
987                     == (NSAlternateKeyMask | NSCommandKeyMask) )
988         {
989             if( [self sendSingleCharacter: mpLastEvent] )
990                 return YES;
991         }
992         unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
993         sal_uInt16 nKeyCode = ImplMapCharCode( keyChar );
994         
995         // Caution: should the table grow to more than 5 or 6 entries,
996         // we must consider moving it to a kind of hash map
997         const unsigned int nExceptions = SAL_N_ELEMENTS( aExceptionalKeys );
998         for( unsigned int i = 0; i < nExceptions; i++ )
999         {
1000             if( nKeyCode == aExceptionalKeys[i].nKeyCode &&
1001                 (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask)
1002                 == aExceptionalKeys[i].nModifierMask )
1003             {
1004                 [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0];
1006                 return YES;
1007             }
1008         }
1009     }
1010     return NO;
1013 -(void)flagsChanged: (NSEvent*)pEvent
1015     YIELD_GUARD;
1016     
1017     if( AquaSalFrame::isAlive( mpFrame ) )
1018     {
1019         mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
1020         mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
1021     }
1024 -(void)insertText:(id)aString
1026     YIELD_GUARD;
1027     
1028     if( AquaSalFrame::isAlive( mpFrame ) )
1029     {
1030         NSString* pInsert = nil;
1031         if( [aString isMemberOfClass: [NSAttributedString class]] )
1032             pInsert = [aString string];
1033         else
1034             pInsert = aString;
1035         
1036         int nLen = 0;
1037         if( pInsert && ( nLen = [pInsert length] ) > 0 )
1038         {
1039             OUString aInsertString( GetOUString( pInsert ) );
1040              // aCharCode initializer is safe since aInsertString will at least contain '\0'
1041             sal_Unicode aCharCode = *aInsertString.getStr();
1042             
1043             if( nLen == 1 &&
1044                 aCharCode < 0x80 &&
1045                 aCharCode > 0x1f &&
1046                                 ! [self hasMarkedText ]
1047                 )
1048             {
1049                 sal_uInt16 nKeyCode = ImplMapCharCode( aCharCode );
1050                 unsigned int nLastModifiers = mpFrame->mnLastModifierFlags;
1052                 // #i99567#
1053                 // find out the unmodified key code
1054     
1055                 // sanity check
1056                 if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) )
1057                 {
1058                     // get unmodified string
1059                     NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers]; 
1060                     if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
1061                     {
1062                         // map the unmodified key code
1063                         unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
1064                         nKeyCode = ImplMapCharCode( keyChar );
1065                     }
1066                     nLastModifiers = [mpLastEvent modifierFlags];
1068                 }
1069                 // #i99567#
1070                 // applications and vcl's edit fields ignore key events with ALT
1071                 // however we're at a place where we know text should be inserted
1072                 // so it seems we need to strip the Alt modifier here
1073                 if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask))
1074                     == NSAlternateKeyMask )
1075                 {
1076                     nLastModifiers = 0;
1077                 }
1078                 [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers];
1079             }
1080             else
1081             {
1082                 SalExtTextInputEvent aEvent;
1083                 aEvent.mnTime           = mpFrame->mnLastEventTime;
1084                 aEvent.maText           = aInsertString;
1085                 aEvent.mpTextAttr       = NULL;
1086                 aEvent.mnCursorPos      = aInsertString.getLength();
1087                 aEvent.mnDeltaStart     = 0;
1088                 aEvent.mnCursorFlags    = 0;
1089                 aEvent.mbOnlyCursor     = FALSE;
1090                 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
1091                 if( AquaSalFrame::isAlive( mpFrame ) )
1092                     mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1093             }
1094         }
1095         else
1096         {
1097             SalExtTextInputEvent aEvent;
1098             aEvent.mnTime           = mpFrame->mnLastEventTime;
1099             aEvent.maText           = OUString();
1100             aEvent.mpTextAttr       = NULL;
1101             aEvent.mnCursorPos      = 0;
1102             aEvent.mnDeltaStart     = 0;
1103             aEvent.mnCursorFlags    = 0;
1104             aEvent.mbOnlyCursor     = FALSE;
1105             mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
1106             if( AquaSalFrame::isAlive( mpFrame ) )
1107                 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1109         }
1110         mbKeyHandled = true;
1111         [self unmarkText];
1112     }
1115 -(void)insertTab: (id)aSender
1117     (void)aSender;
1118     [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0];
1121 -(void)insertBacktab: (id)aSender
1123     (void)aSender;
1124     [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0];
1127 -(void)moveLeft: (id)aSender
1129     (void)aSender;
1130     [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0];
1133 -(void)moveLeftAndModifySelection: (id)aSender
1135     (void)aSender;
1136     [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask];
1139 -(void)moveBackwardAndModifySelection: (id)aSender
1141     (void)aSender;
1142     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0  modifiers: 0];
1145 -(void)moveRight: (id)aSender
1147     (void)aSender;
1148     [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0];
1151 -(void)moveRightAndModifySelection: (id)aSender
1153     (void)aSender;
1154     [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask];
1157 -(void)moveForwardAndModifySelection: (id)aSender
1159     (void)aSender;
1160     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0  modifiers: 0];
1163 -(void)moveWordLeft: (id)aSender
1165     (void)aSender;
1166     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0  modifiers: 0];
1169 -(void)moveWordBackward: (id)aSender
1171     (void)aSender;
1172     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0  modifiers: 0];
1175 -(void)moveWordBackwardAndModifySelection: (id)aSender
1177     (void)aSender;
1178     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0  modifiers: 0];
1181 -(void)moveWordLeftAndModifySelection: (id)aSender
1183     (void)aSender;
1184     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0  modifiers: 0];
1187 -(void)moveWordRight: (id)aSender
1189     (void)aSender;
1190     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0  modifiers: 0];
1193 -(void)moveWordForward: (id)aSender
1195     (void)aSender;
1196     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0  modifiers: 0];
1199 -(void)moveWordForwardAndModifySelection: (id)aSender
1201     (void)aSender;
1202     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0  modifiers: 0];
1205 -(void)moveWordRightAndModifySelection: (id)aSender
1207     (void)aSender;
1208     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0  modifiers: 0];
1211 -(void)moveToEndOfLine: (id)aSender
1213     (void)aSender;
1214     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0  modifiers: 0];
1217 -(void)moveToRightEndOfLine: (id)aSender
1219     (void)aSender;
1220     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0  modifiers: 0];
1223 -(void)moveToEndOfLineAndModifySelection: (id)aSender
1225     (void)aSender;
1226     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0  modifiers: 0];
1229 -(void)moveToRightEndOfLineAndModifySelection: (id)aSender
1231     (void)aSender;
1232     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0  modifiers: 0];
1235 -(void)moveToBeginningOfLine: (id)aSender
1237     (void)aSender;
1238     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1241 -(void)moveToLeftEndOfLine: (id)aSender
1243     (void)aSender;
1244     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1247 -(void)moveToBeginningOfLineAndModifySelection: (id)aSender
1249     (void)aSender;
1250     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1253 -(void)moveToLeftEndOfLineAndModifySelection: (id)aSender
1255     (void)aSender;
1256     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1259 -(void)moveToEndOfParagraph: (id)aSender
1261     (void)aSender;
1262     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1265 -(void)moveToEndOfParagraphAndModifySelection: (id)aSender
1267     (void)aSender;
1268     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1271 -(void)moveParagraphForward: (id)aSender
1273     (void)aSender;
1274     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1277 -(void)moveParagraphForwardAndModifySelection: (id)aSender
1279     (void)aSender;
1280     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1283 -(void)moveToBeginningOfParagraph: (id)aSender
1285     (void)aSender;
1286     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1289 -(void)moveParagraphBackward: (id)aSender
1291     (void)aSender;
1292     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1295 -(void)moveToBeginningOfParagraphAndModifySelection: (id)aSender
1297     (void)aSender;
1298     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1301 -(void)moveParagraphBackwardAndModifySelection: (id)aSender
1303     (void)aSender;
1304     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1307 -(void)moveToEndOfDocument: (id)aSender
1309     (void)aSender;
1310     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0  modifiers: 0];
1313 -(void)scrollToEndOfDocument: (id)aSender
1315     (void)aSender;
1316     // this is not exactly what we should do, but it makes "End" and "Shift-End" behave consistent
1317     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0  modifiers: 0];
1320 -(void)moveToEndOfDocumentAndModifySelection: (id)aSender
1322     (void)aSender;
1323     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0  modifiers: 0];
1326 -(void)moveToBeginningOfDocument: (id)aSender
1328     (void)aSender;
1329     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0  modifiers: 0];
1332 -(void)scrollToBeginningOfDocument: (id)aSender
1334     (void)aSender;
1335     // this is not exactly what we should do, but it makes "Home" and "Shift-Home" behave consistent
1336     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0  modifiers: 0];
1339 -(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender
1341     (void)aSender;
1342     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0  modifiers: 0];
1345 -(void)moveUp: (id)aSender
1347     (void)aSender;
1348     [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0];
1351 -(void)moveDown: (id)aSender
1353     (void)aSender;
1354     [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0];
1357 -(void)insertNewline: (id)aSender
1359     (void)aSender;
1360     // #i91267# make enter and shift-enter work by evaluating the modifiers
1361     [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags];
1364 -(void)deleteBackward: (id)aSender
1366     (void)aSender;
1367     [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1370 -(void)deleteForward: (id)aSender
1372     (void)aSender;
1373     [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0];
1376 -(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender
1378     (void)aSender;
1379     [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1382 -(void)deleteWordBackward: (id)aSender
1384     (void)aSender;
1385     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0  modifiers: 0];
1388 -(void)deleteWordForward: (id)aSender
1390     (void)aSender;
1391     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0  modifiers: 0];
1394 -(void)deleteToBeginningOfLine: (id)aSender
1396     (void)aSender;
1397     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1400 -(void)deleteToEndOfLine: (id)aSender
1402     (void)aSender;
1403     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0  modifiers: 0];
1406 -(void)deleteToBeginningOfParagraph: (id)aSender
1408     (void)aSender;
1409     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1412 -(void)deleteToEndOfParagraph: (id)aSender
1414     (void)aSender;
1415     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1418 -(void)insertLineBreak: (id)aSender
1420     (void)aSender;
1421     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0  modifiers: 0];
1424 -(void)insertParagraphSeparator: (id)aSender
1426     (void)aSender;
1427     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0  modifiers: 0];
1430 -(void)selectWord: (id)aSender
1432     (void)aSender;
1433     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0  modifiers: 0];
1436 -(void)selectLine: (id)aSender
1438     (void)aSender;
1439     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0  modifiers: 0];
1442 -(void)selectParagraph: (id)aSender
1444     (void)aSender;
1445     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0  modifiers: 0];
1448 -(void)selectAll: (id)aSender
1450     (void)aSender;
1451     [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0  modifiers: 0];
1454 -(void)cancelOperation: (id)aSender
1456     (void)aSender;
1457     [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0];
1460 -(void)noop: (id)aSender
1462     (void)aSender;
1463     if( ! mbKeyHandled )
1464     {
1465         if( ! [self sendSingleCharacter:mpLastEvent] )
1466         {
1467             /* prevent recursion */
1468             if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] )
1469             {
1470                 id pLastSuperEvent = mpLastSuperEvent;
1471                 mpLastSuperEvent = mpLastEvent;
1472                 [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent];
1473                 mpLastSuperEvent = pLastSuperEvent;
1474                 
1475                 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1476                 if( it != GetSalData()->maKeyEventAnswer.end() )
1477                     it->second = true;
1478             }
1479         }
1480     }
1483 -(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar
1485     return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags];
1488 -(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1490     return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] ||
1491            [self sendSingleCharacter: mpLastEvent];
1494 -(BOOL)sendKeyToFrameDirect: (sal_uInt16)nKeyCode  character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1496     YIELD_GUARD;
1497     
1498     long nRet = 0;
1499     if( AquaSalFrame::isAlive( mpFrame ) )
1500     {
1501         SalKeyEvent aEvent;
1502         aEvent.mnTime           = mpFrame->mnLastEventTime;
1503         aEvent.mnCode           = nKeyCode | ImplGetModifierMask( nMod );
1504         aEvent.mnCharCode       = aChar;
1505         aEvent.mnRepeat         = FALSE;
1506         nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent );
1507         std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1508         if( it != GetSalData()->maKeyEventAnswer.end() )
1509             it->second = nRet ? true : false;
1510         if( AquaSalFrame::isAlive( mpFrame ) )
1511             mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent );
1512     }
1513     return nRet ? YES : NO;
1517 -(BOOL)sendSingleCharacter: (NSEvent *)pEvent
1519     NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 
1521     if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
1522     {
1523         unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
1524         sal_uInt16 nKeyCode = ImplMapCharCode( keyChar );
1525         if (nKeyCode == 0)
1526         {
1527             sal_uInt16 nOtherKeyCode = [pEvent keyCode];
1528             nKeyCode = ImplMapKeyCode(nOtherKeyCode);
1529         }
1530         if( nKeyCode != 0 )
1531         {
1532             // don't send unicodes in the private use area
1533             if( keyChar >= 0xf700 && keyChar < 0xf780 )
1534                 keyChar = 0;
1535             BOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags];
1536             mbInKeyInput = false;
1538             return bRet;
1539         }
1540     }
1541     return NO;
1545 // NSTextInput protocol
1546 - (NSArray *)validAttributesForMarkedText
1548     return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil];
1551 - (BOOL)hasMarkedText
1553     BOOL bHasMarkedText;
1555     bHasMarkedText = ( mMarkedRange.location != NSNotFound ) &&
1556                      ( mMarkedRange.length != 0 );
1557     // hack to check keys like "Control-j"
1558     if( mbInKeyInput )
1559     {
1560         mbNeedSpecialKeyHandle = true;
1561     }
1563     // FIXME:
1564     // #i106901#
1565     // if we come here outside of mbInKeyInput, this is likely to be because
1566     // of the keyboard viewer. For unknown reasons having no marked range
1567     // in this case causes a crash. So we say we have a marked range anyway
1568     // This is a hack, since it is not understood what a) causes that crash
1569     // and b) why we should have a marked range at this point.
1570     if( ! mbInKeyInput )
1571         bHasMarkedText = YES;
1573     return bHasMarkedText;
1576 - (NSRange)markedRange
1578     // FIXME:
1579     // #i106901#
1580     // if we come here outside of mbInKeyInput, this is likely to be because
1581     // of the keyboard viewer. For unknown reasons having no marked range
1582     // in this case causes a crash. So we say we have a marked range anyway
1583     // This is a hack, since it is not understood what a) causes that crash
1584     // and b) why we should have a marked range at this point.
1585     if( ! mbInKeyInput )
1586         return NSMakeRange( 0, 0 );
1587     
1588     return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 );
1591 - (NSRange)selectedRange
1593     return mSelectedRange;
1596 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange
1598     if( ![aString isKindOfClass:[NSAttributedString class]] )
1599         aString = [[[NSAttributedString alloc] initWithString:aString] autorelease];
1600     NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange];
1601     if( rangeToReplace.location == NSNotFound )
1602     {
1603         mMarkedRange = NSMakeRange( selRange.location, [aString length] );
1604         mSelectedRange = NSMakeRange( selRange.location, selRange.length );
1605     }
1606     else
1607     {
1608         mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] );
1609         mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length );
1610     }
1612     int len = [aString length];
1613     SalExtTextInputEvent aInputEvent;
1614     aInputEvent.mnTime = mpFrame->mnLastEventTime;
1615     aInputEvent.mnDeltaStart = 0;
1616     aInputEvent.mbOnlyCursor = FALSE;
1617     if( len > 0 ) {
1618         NSString *pString = [aString string];
1619         OUString aInsertString( GetOUString( pString ) );
1620         std::vector<sal_uInt16> aInputFlags = std::vector<sal_uInt16>( std::max( 1, len ), 0 );
1621         for ( int i = 0; i < len; i++ )
1622         {
1623             unsigned int nUnderlineValue;
1624             NSRange effectiveRange;
1625             
1626             effectiveRange = NSMakeRange(i, 1);
1627             nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue];
1629             switch (nUnderlineValue & 0xff) {
1630             case NSUnderlineStyleSingle:
1631                 aInputFlags[i] = EXTTEXTINPUT_ATTR_UNDERLINE;
1632                 break;
1633             case NSUnderlineStyleThick:
1634                 aInputFlags[i] = EXTTEXTINPUT_ATTR_UNDERLINE | EXTTEXTINPUT_ATTR_HIGHLIGHT;
1635                 break;
1636             case NSUnderlineStyleDouble:
1637                 aInputFlags[i] = EXTTEXTINPUT_ATTR_BOLDUNDERLINE;
1638                 break;
1639             default:
1640                 aInputFlags[i] = EXTTEXTINPUT_ATTR_HIGHLIGHT;
1641                 break;
1642             }
1643         }
1645         aInputEvent.maText = aInsertString;
1646         aInputEvent.mnCursorPos = selRange.location;
1647         aInputEvent.mpTextAttr = &aInputFlags[0];
1648         mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1649     } else {
1650         aInputEvent.maText = OUString();
1651         aInputEvent.mnCursorPos = 0;
1652         aInputEvent.mnCursorFlags = 0;
1653         aInputEvent.mpTextAttr = 0;
1654         mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1655         mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1656     }
1657     mbKeyHandled= true;
1660 - (void)unmarkText
1662     mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
1665 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange
1667     (void)theRange;
1668     // FIXME
1669     return nil;
1672 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
1674     (void)thePoint;
1675     // FIXME
1676     return 0;
1679 - (NSInteger)conversationIdentifier
1681     return (long)self;
1684 - (void)doCommandBySelector:(SEL)aSelector
1686     if( AquaSalFrame::isAlive( mpFrame ) )
1687     {
1688         #if OSL_DEBUG_LEVEL > 1
1689         // fprintf( stderr, "SalFrameView: doCommandBySelector %s\n", (char*)aSelector );
1690         #endif
1691         if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 &&
1692             aSelector != NULL && [self respondsToSelector: aSelector] )
1693         {
1694             [self performSelector: aSelector];
1695         }
1696         else
1697         {
1698             [self sendSingleCharacter:mpLastEvent];
1699         }
1700     }
1702     mbKeyHandled = true;
1705 -(void)clearLastEvent
1707     mpLastEvent = nil;
1710 - (NSRect)firstRectForCharacterRange:(NSRange)theRange
1712     (void)theRange;
1713     SalExtTextInputPosEvent aPosEvent;
1714     mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent );
1716     NSRect rect;
1718     rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX;
1719     rect.origin.y =   aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines
1720     rect.size.width = aPosEvent.mnWidth;
1721     rect.size.height = aPosEvent.mnHeight;
1723     mpFrame->VCLToCocoa( rect );
1724     return rect;
1727 -(id)parentAttribute {
1728     return (NSView *) mpFrame -> mpWindow;
1731 -(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext
1733     if ( mpReferenceWrapper == nil ) {
1734         // some frames never become visible ..
1735         Window *pWindow = mpFrame -> GetWindow();
1736         if ( ! pWindow ) 
1737             return nil;
1739         mpReferenceWrapper = new ReferenceWrapper;
1740         mpReferenceWrapper -> rAccessibleContext =  pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext();
1741         [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ];
1742     }
1743     return [ super accessibleContext ];
1746 -(NSView *)viewElementForParent
1748     return (NSView *) mpFrame -> mpWindow;
1751 -(void)registerMouseEventListener: (id)theListener
1753   mpMouseEventListener = theListener;
1756 -(void)unregisterMouseEventListener: (id)theListener
1758     (void)theListener;
1759     mpMouseEventListener = nil;
1762 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
1764   return [mDraggingDestinationHandler draggingEntered: sender];
1767 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
1769   return [mDraggingDestinationHandler draggingUpdated: sender];
1772 -(void)draggingExited:(id <NSDraggingInfo>)sender
1774   [mDraggingDestinationHandler draggingExited: sender];
1777 -(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
1779   return [mDraggingDestinationHandler prepareForDragOperation: sender];
1782 -(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
1784   return [mDraggingDestinationHandler performDragOperation: sender];
1787 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
1789   [mDraggingDestinationHandler concludeDragOperation: sender];
1792 -(void)registerDraggingDestinationHandler:(id)theHandler
1794   mDraggingDestinationHandler = theHandler;
1797 -(void)unregisterDraggingDestinationHandler:(id)theHandler
1799     (void)theHandler;
1800     mDraggingDestinationHandler = nil;
1803 @end
1805 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */