1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *   http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24// MARKER(update_precomp.py): autogen include statement, do not remove
25#include "precompiled_vcl.hxx"
26
27#include <sal/alloca.h>
28
29#include "vcl/window.hxx"
30#include "vcl/svapp.hxx"
31
32#include "aqua/salinst.h"
33#include "aqua/salgdi.h"
34#include "aqua/salframe.h"
35#include "aqua/salframeview.h"
36#include "aqua/aqua11yfactory.h"
37
38#define WHEEL_EVENT_FACTOR 1.5
39
40// for allowing fullscreen support on deployment targets < OSX 10.7
41#if !defined(MAC_OS_X_VERSION_10_7)
42    #define NSWindowCollectionBehaviorFullScreenPrimary   (1 << 7)
43    #define NSWindowCollectionBehaviorFullScreenAuxiliary (1 << 8)
44//  #define NSFullScreenWindowMask (1 << 14)
45#endif
46
47
48static sal_uInt16 ImplGetModifierMask( unsigned int nMask )
49{
50    sal_uInt16 nRet = 0;
51    if( (nMask & NSShiftKeyMask) != 0 )
52        nRet |= KEY_SHIFT;
53    if( (nMask & NSControlKeyMask) != 0 )
54        nRet |= KEY_MOD3;
55    if( (nMask & NSAlternateKeyMask) != 0 )
56        nRet |= KEY_MOD2;
57    if( (nMask & NSCommandKeyMask) != 0 )
58        nRet |= KEY_MOD1;
59    return nRet;
60}
61
62static sal_uInt16 ImplMapCharCode( sal_Unicode aCode )
63{
64    static sal_uInt16 aKeyCodeMap[ 128 ] =
65    {
66        0, 0, 0, 0, 0, 0, 0, 0,
67        KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0,
68        0, 0, 0, 0, 0, 0, 0, 0,
69        0, KEY_TAB, 0, KEY_ESCAPE, 0, 0, 0, 0,
70        KEY_SPACE, 0, 0, 0, 0, 0, 0, 0,
71        0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE,
72        KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
73        KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0,
74        0, 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, 0, 0,
78        KEY_QUOTELEFT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
79        KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
80        KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
81        KEY_X, KEY_Y, KEY_Z, 0, 0, 0, KEY_TILDE, KEY_BACKSPACE
82    };
83
84    // Note: the mapping 0x7f should by rights be KEY_DELETE
85    // however if you press "backspace" 0x7f is reported
86    // whereas for "delete" 0xf728 gets reported
87
88    // Note: the mapping of 0x19 to KEY_TAB is because for unknown reasons
89    // tab alone is reported as 0x09 (as expected) but shift-tab is
90    // reported as 0x19 (end of medium)
91
92    static sal_uInt16 aFunctionKeyCodeMap[ 128 ] =
93    {
94        KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4,
95        KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
96        KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20,
97        KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0,
98        0, 0, 0, 0, 0, 0, 0, KEY_INSERT,
99        KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0,
100        0, 0, 0, 0, 0, KEY_MENU, 0, 0,
101        0, 0, 0, 0, 0, 0, 0, 0,
102        0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 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        0, 0, 0, 0, 0, 0, 0, 0,
107        0, 0, 0, 0, 0, 0, 0, 0,
108        0, 0, 0, 0, 0, 0, 0, 0,
109        0, 0, 0, 0, 0, 0, 0, 0
110    };
111
112    sal_uInt16 nKeyCode = 0;
113    if( aCode < sizeof( aKeyCodeMap) / sizeof( aKeyCodeMap[0] ) )
114        nKeyCode = aKeyCodeMap[ aCode ];
115    else if( aCode >= 0xf700 && aCode < 0xf780 )
116        nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ];
117    return nKeyCode;
118}
119
120// store the frame the mouse last entered
121static AquaSalFrame* s_pMouseFrame = NULL;
122// store the last pressed button for enter/exit events
123// which lack that information
124static sal_uInt16 s_nLastButton = 0;
125
126// combinations of keys we need to handle ourselves
127static const struct ExceptionalKey
128{
129    const sal_uInt16        nKeyCode;
130    const unsigned int  nModifierMask;
131} aExceptionalKeys[] =
132{
133    { KEY_D, NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask },
134    { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask }
135};
136
137static AquaSalFrame* getMouseContainerFrame()
138{
139    NSInteger nWindows = 0;
140    NSCountWindows( &nWindows );
141    NSInteger* pWindows = (NSInteger*)alloca( nWindows * sizeof(NSInteger) );
142    // note: NSWindowList is supposed to be in z-order front to back
143    NSWindowList( nWindows, pWindows );
144    AquaSalFrame* pDispatchFrame = NULL;
145    for(int i = 0; i < nWindows && ! pDispatchFrame; i++ )
146    {
147        NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]];
148        if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] )
149            pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame];
150    }
151    return pDispatchFrame;
152}
153
154@implementation SalFrameWindow
155-(id)initWithSalFrame: (AquaSalFrame*)pFrame
156{
157	mDraggingDestinationHandler = nil;
158    mpFrame = pFrame;
159    NSRect aRect = NSMakeRect( pFrame->maGeometry.nX, pFrame->maGeometry.nY,
160                     pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight);
161    pFrame->VCLToCocoa( aRect );
162    NSWindow* pNSWindow = [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ];
163    [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver
164
165    // enable OSX>=10.7 fullscreen options if available and useful
166    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)));
167    bAllowFullScreen &= (0 == (~mpFrame->mnStyle & (SAL_FRAME_STYLE_SIZEABLE)));
168    bAllowFullScreen &= (mpFrame->mpParent == NULL);
169    const SEL setCollectionBehavior = @selector(setCollectionBehavior:);
170    if( bAllowFullScreen && [pNSWindow respondsToSelector: setCollectionBehavior])
171    {
172        const int bMode= (bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary);
173        [pNSWindow performSelector:setCollectionBehavior withObject:(id)bMode];
174    }
175
176    // disable OSX>=10.7 window restoration until we support it directly
177    const SEL setRestorable = @selector(setRestorable:);
178    if( [pNSWindow respondsToSelector: setRestorable]) {
179        [pNSWindow performSelector:setRestorable withObject:(id)NO];
180    }
181
182    return pNSWindow;
183}
184
185-(AquaSalFrame*)getSalFrame
186{
187    return mpFrame;
188}
189
190-(void)displayIfNeeded
191{
192    if( GetSalData() && GetSalData()->mpFirstInstance )
193    {
194        vos::IMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex();
195        if( pMutex )
196        {
197            pMutex->acquire();
198            [super displayIfNeeded];
199            pMutex->release();
200        }
201    }
202}
203
204-(BOOL)containsMouse
205{
206    // is this event actually inside that NSWindow ?
207    NSPoint aPt = [NSEvent mouseLocation];
208    NSRect aFrameRect = [self frame];
209    BOOL bInRect = NSPointInRect( aPt, aFrameRect );
210    return bInRect;
211}
212
213-(BOOL)canBecomeKeyWindow
214{
215    if( (mpFrame->mnStyle &
216            ( SAL_FRAME_STYLE_FLOAT                 |
217              SAL_FRAME_STYLE_TOOLTIP               |
218              SAL_FRAME_STYLE_INTRO
219            )) == 0 )
220        return YES;
221    if( (mpFrame->mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) != 0 )
222        return YES;
223    if( mpFrame->mbFullScreen )
224        return YES;
225    if( (mpFrame->mnStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) )
226        return YES;
227    return [super canBecomeKeyWindow];
228}
229
230-(void)windowDidBecomeKey: (NSNotification*)pNotification
231{
232    (void)pNotification;
233    YIELD_GUARD;
234
235    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
236    {
237        static const sal_uLong nGuessDocument = SAL_FRAME_STYLE_MOVEABLE|
238                                            SAL_FRAME_STYLE_SIZEABLE|
239                                            SAL_FRAME_STYLE_CLOSEABLE;
240
241        if( mpFrame->mpMenu )
242            mpFrame->mpMenu->setMainMenu();
243        else if( ! mpFrame->mpParent &&
244                 ( (mpFrame->mnStyle & nGuessDocument) == nGuessDocument || // set default menu for e.g. help
245                    mpFrame->mbFullScreen ) )                               // ser default menu for e.g. presentation
246        {
247            AquaSalMenu::setDefaultMenu();
248        }
249        #if 0
250        // FIXME: we should disable menus while in modal mode
251        // however from down here there is currently no reliable way to
252        // find out when to do this
253        if( (mpFrame->mpParent && mpFrame->mpParent->GetWindow()->IsInModalMode()) )
254            AquaSalMenu::enableMainMenu( false );
255        #endif
256        mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 );
257        mpFrame->SendPaintEvent(); // repaint controls as active
258    }
259}
260
261-(void)windowDidResignKey: (NSNotification*)pNotification
262{
263    (void)pNotification;
264    YIELD_GUARD;
265
266    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
267    {
268        mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0);
269        mpFrame->SendPaintEvent(); // repaint controls as inactive
270    }
271}
272
273-(void)windowDidChangeScreen: (NSNotification*)pNotification
274{
275    (void)pNotification;
276    YIELD_GUARD;
277
278    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
279        mpFrame->screenParametersChanged();
280}
281
282-(void)windowDidMove: (NSNotification*)pNotification
283{
284    (void)pNotification;
285    YIELD_GUARD;
286
287    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
288    {
289        mpFrame->UpdateFrameGeometry();
290        mpFrame->CallCallback( SALEVENT_MOVE, 0 );
291    }
292}
293
294-(void)windowDidResize: (NSNotification*)pNotification
295{
296    (void)pNotification;
297    YIELD_GUARD;
298
299    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
300    {
301        mpFrame->UpdateFrameGeometry();
302        mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
303        mpFrame->SendPaintEvent();
304    }
305}
306
307-(void)windowDidMiniaturize: (NSNotification*)pNotification
308{
309    (void)pNotification;
310    YIELD_GUARD;
311
312    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
313    {
314        mpFrame->mbShown = false;
315        mpFrame->UpdateFrameGeometry();
316        mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
317    }
318}
319
320-(void)windowDidDeminiaturize: (NSNotification*)pNotification
321{
322    (void)pNotification;
323    YIELD_GUARD;
324
325    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
326    {
327        mpFrame->mbShown = true;
328        mpFrame->UpdateFrameGeometry();
329        mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
330    }
331}
332
333-(BOOL)windowShouldClose: (NSNotification*)pNotification
334{
335    (void)pNotification;
336    YIELD_GUARD;
337
338    BOOL bRet = YES;
339    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
340    {
341        // #i84461# end possible input
342        mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
343        if( AquaSalFrame::isAlive( mpFrame ) )
344        {
345            mpFrame->CallCallback( SALEVENT_CLOSE, 0 );
346            bRet = NO; // application will close the window or not, AppKit shouldn't
347        }
348    }
349
350    return bRet;
351}
352
353-(void)windowDidEnterFullScreen: (NSNotification*)pNotification
354{
355    YIELD_GUARD;
356
357    if( !mpFrame || !AquaSalFrame::isAlive( mpFrame))
358        return;
359    mpFrame->mbFullScreen = true;
360    (void)pNotification;
361}
362
363-(void)windowDidExitFullScreen: (NSNotification*)pNotification
364{
365    YIELD_GUARD;
366
367    if( !mpFrame || !AquaSalFrame::isAlive( mpFrame))
368        return;
369    mpFrame->mbFullScreen = false;
370    (void)pNotification;
371}
372
373-(void)dockMenuItemTriggered: (id)sender
374{
375    (void)sender;
376    YIELD_GUARD;
377
378    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
379        mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS );
380}
381
382-(::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >)accessibleContext
383{
384    return mpFrame -> GetWindow() -> GetAccessible() -> getAccessibleContext();
385}
386
387-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
388{
389  return [mDraggingDestinationHandler draggingEntered: sender];
390}
391
392-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
393{
394  return [mDraggingDestinationHandler draggingUpdated: sender];
395}
396
397-(void)draggingExited:(id <NSDraggingInfo>)sender
398{
399  [mDraggingDestinationHandler draggingExited: sender];
400}
401
402-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
403{
404  return [mDraggingDestinationHandler prepareForDragOperation: sender];
405}
406
407-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
408{
409  return [mDraggingDestinationHandler performDragOperation: sender];
410}
411
412-(void)concludeDragOperation:(id <NSDraggingInfo>)sender
413{
414  [mDraggingDestinationHandler concludeDragOperation: sender];
415}
416
417-(void)registerDraggingDestinationHandler:(id)theHandler
418{
419  mDraggingDestinationHandler = theHandler;
420}
421
422-(void)unregisterDraggingDestinationHandler:(id)theHandler
423{
424    (void)theHandler;
425    mDraggingDestinationHandler = nil;
426}
427
428@end
429
430@implementation SalFrameView
431+(void)unsetMouseFrame: (AquaSalFrame*)pFrame
432{
433    if( pFrame == s_pMouseFrame )
434        s_pMouseFrame = NULL;
435}
436
437-(id)initWithSalFrame: (AquaSalFrame*)pFrame
438{
439    if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [pFrame->getNSWindow() frame] styleMask: pFrame->mnStyleMask]]) != nil)
440    {
441        mDraggingDestinationHandler = nil;
442        mpFrame = pFrame;
443        mMarkedRange = NSMakeRange(NSNotFound, 0);
444        mSelectedRange = NSMakeRange(NSNotFound, 0);
445        mpReferenceWrapper = nil;
446		mpMouseEventListener = nil;
447        mpLastSuperEvent = nil;
448    }
449
450    mfLastMagnifyTime = 0.0;
451    return self;
452}
453
454-(AquaSalFrame*)getSalFrame
455{
456    return mpFrame;
457}
458
459-(void)resetCursorRects
460{
461    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
462    {
463        // FIXME: does this leak the returned NSCursor of getCurrentCursor ?
464        const NSRect aRect = { NSZeroPoint, NSMakeSize( mpFrame->maGeometry.nWidth, mpFrame->maGeometry.nHeight) };
465        [self addCursorRect: aRect cursor: mpFrame->getCurrentCursor()];
466    }
467}
468
469-(BOOL)acceptsFirstResponder
470{
471    return YES;
472}
473
474-(BOOL)acceptsFirstMouse: (NSEvent*)pEvent
475{
476    (void)pEvent;
477    return YES;
478}
479
480-(BOOL)isOpaque
481{
482	if( !mpFrame)
483		return YES;
484	if( !AquaSalFrame::isAlive( mpFrame))
485		return YES;
486	if( !mpFrame->getClipPath())
487		return YES;
488	return NO;
489}
490
491// helper class similar to a vos::OGuard for the SalYieldMutex
492// the difference is that it only does tryToAcquire instead of acquire
493// so dreaded deadlocks like #i93512# are prevented
494class TryGuard
495{
496public:
497			TryGuard()  { mbGuarded = ImplSalYieldMutexTryToAcquire(); }
498			~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); }
499	bool	IsGuarded() { return mbGuarded; }
500private:
501	bool	mbGuarded;
502};
503
504-(void)drawRect: (NSRect)aRect
505{
506	// HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex
507	TryGuard aTryGuard;
508	if( !aTryGuard.IsGuarded() )
509	{
510		// NOTE: the mpFrame access below is not guarded yet!
511		// TODO: mpFrame et al need to be guarded by an independent mutex
512		AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL;
513		if( pGraphics )
514		{
515			// we did not get the mutex so we cannot draw now => request to redraw later
516			// convert the NSRect to a CGRect for Refreshrect()
517			const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}};
518			pGraphics->RefreshRect( aCGRect );
519		}
520		return;
521	}
522
523    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
524    {
525        if( mpFrame->mpGraphics )
526        {
527            mpFrame->mpGraphics->UpdateWindow( aRect );
528            if( mpFrame->getClipPath() )
529                [mpFrame->getNSWindow() invalidateShadow];
530        }
531    }
532}
533
534-(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(sal_uInt16)nButton eventtype:(sal_uInt16)nEvent
535{
536    YIELD_GUARD;
537
538    AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame();
539    bool bIsCaptured = false;
540    if( pDispatchFrame )
541    {
542        bIsCaptured = true;
543        if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured
544            nEvent = SALEVENT_MOUSEMOVE;
545    }
546    else if( s_pMouseFrame )
547        pDispatchFrame = s_pMouseFrame;
548    else
549        pDispatchFrame = mpFrame;
550
551    /* #i81645# Cocoa reports mouse events while a button is pressed
552       to the window in which it was first pressed. This is reasonable and fine and
553       gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer,
554       however vcl expects mouse events to occur in the window the mouse is over, unless the
555       mouse is explicitly captured. So we need to find the window the mouse is actually
556       over for conformance with other platforms.
557    */
558    if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
559    {
560        // is this event actually inside that NSWindow ?
561        NSPoint aPt = [NSEvent mouseLocation];
562        NSRect aFrameRect = [pDispatchFrame->getNSWindow() frame];
563
564	if ( ! NSPointInRect( aPt, aFrameRect ) )
565        {
566            // no, it is not
567            // now we need to find the one it may be in
568            /* #i93756# we ant to get enumerate the application windows in z-order
569               to check if any contains the mouse. This could be elegantly done with this
570               code:
571
572               // use NSApp to check windows in ZOrder whether they contain the mouse pointer
573               NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES];
574               if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] )
575                   pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame];
576
577               However if a non SalFrameWindow is on screen (like e.g. the file dialog)
578               it can be hit with the containsMouse selector, which it doesn't support.
579               Sadly NSApplication:makeWindowsPerform does not check (for performance reasons
580               I assume) whether a window supports a selector before sending it.
581            */
582            AquaSalFrame* pMouseFrame = getMouseContainerFrame();
583            if( pMouseFrame )
584                pDispatchFrame = pMouseFrame;
585        }
586    }
587
588    if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
589    {
590        pDispatchFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
591        pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags];
592
593        NSPoint aPt = [NSEvent mouseLocation];
594        pDispatchFrame->CocoaToVCL( aPt );
595
596        sal_uInt16 nModMask = ImplGetModifierMask( [pEvent modifierFlags] );
597        // #i82284# emulate ctrl left
598        if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT )
599        {
600            nModMask    = 0;
601            nButton     = MOUSE_RIGHT;
602        }
603
604        SalMouseEvent aEvent;
605        aEvent.mnTime   = pDispatchFrame->mnLastEventTime;
606        aEvent.mnX      = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX;
607        aEvent.mnY      = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY;
608        aEvent.mnButton = nButton;
609        aEvent.mnCode   =  aEvent.mnButton | nModMask;
610
611        // --- RTL --- (mirror mouse pos)
612        if( Application::GetSettings().GetLayoutRTL() )
613            aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX;
614
615        pDispatchFrame->CallCallback( nEvent, &aEvent );
616    }
617}
618
619-(void)mouseDown: (NSEvent*)pEvent
620{
621    if ( mpMouseEventListener != nil &&
622	    [mpMouseEventListener respondsToSelector: @selector(mouseDown:)])
623	{
624	    [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]];
625	}
626
627    s_nLastButton = MOUSE_LEFT;
628    [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN];
629}
630
631-(void)mouseDragged: (NSEvent*)pEvent
632{
633    if ( mpMouseEventListener != nil &&
634	     [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)])
635	{
636	    [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]];
637	}
638    s_nLastButton = MOUSE_LEFT;
639    [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE];
640}
641
642-(void)mouseUp: (NSEvent*)pEvent
643{
644    s_nLastButton = 0;
645    [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP];
646}
647
648-(void)mouseMoved: (NSEvent*)pEvent
649{
650    s_nLastButton = 0;
651    [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE];
652}
653
654-(void)mouseEntered: (NSEvent*)pEvent
655{
656    s_pMouseFrame = mpFrame;
657
658    // #i107215# the only mouse events we get when inactive are enter/exit
659    // actually we would like to have all of them, but better none than some
660    if( [NSApp isActive] )
661        [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE];
662}
663
664-(void)mouseExited: (NSEvent*)pEvent
665{
666    if( s_pMouseFrame == mpFrame )
667        s_pMouseFrame = NULL;
668
669    // #i107215# the only mouse events we get when inactive are enter/exit
670    // actually we would like to have all of them, but better none than some
671    if( [NSApp isActive] )
672        [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE];
673}
674
675-(void)rightMouseDown: (NSEvent*)pEvent
676{
677    s_nLastButton = MOUSE_RIGHT;
678    [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN];
679}
680
681-(void)rightMouseDragged: (NSEvent*)pEvent
682{
683    s_nLastButton = MOUSE_RIGHT;
684    [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE];
685}
686
687-(void)rightMouseUp: (NSEvent*)pEvent
688{
689    s_nLastButton = 0;
690    [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP];
691}
692
693-(void)otherMouseDown: (NSEvent*)pEvent
694{
695    if( [pEvent buttonNumber] == 2 )
696    {
697        s_nLastButton = MOUSE_MIDDLE;
698        [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN];
699    }
700    else
701        s_nLastButton = 0;
702}
703
704-(void)otherMouseDragged: (NSEvent*)pEvent
705{
706    if( [pEvent buttonNumber] == 2 )
707    {
708        s_nLastButton = MOUSE_MIDDLE;
709        [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE];
710    }
711    else
712        s_nLastButton = 0;
713}
714
715-(void)otherMouseUp: (NSEvent*)pEvent
716{
717    s_nLastButton = 0;
718    if( [pEvent buttonNumber] == 2 )
719        [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP];
720}
721
722- (void)magnifyWithEvent: (NSEvent*)pEvent
723{
724    YIELD_GUARD;
725
726    // TODO: ??  -(float)magnification;
727    if( AquaSalFrame::isAlive( mpFrame ) )
728	{
729		const NSTimeInterval fMagnifyTime = [pEvent timestamp];
730        mpFrame->mnLastEventTime = static_cast<sal_uLong>( fMagnifyTime * 1000.0 );
731        mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
732
733        // check if this is a new series of magnify events
734        static const NSTimeInterval fMaxDiffTime = 0.3;
735        const bool bNewSeries = (fMagnifyTime - mfLastMagnifyTime > fMaxDiffTime);
736
737        if( bNewSeries )
738            mfMagnifyDeltaSum = 0.0;
739        mfMagnifyDeltaSum += [pEvent deltaZ];
740
741		mfLastMagnifyTime = [pEvent timestamp];
742		// TODO: change to 0.1 when COMMAND_WHEEL_ZOOM handlers allow finer zooming control
743		static const float fMagnifyFactor = 0.25;
744        static const float fMinMagnifyStep = 15.0 / fMagnifyFactor;
745        if( fabs(mfMagnifyDeltaSum) <= fMinMagnifyStep )
746            return;
747
748        // adapt NSEvent-sensitivity to application expectations
749        // TODO: rather make COMMAND_WHEEL_ZOOM handlers smarter
750        const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor;
751        int nDeltaZ = FRound( fDeltaZ );
752        if( !nDeltaZ )
753        {
754            // handle new series immediately
755            if( !bNewSeries )
756                return;
757            nDeltaZ = (fDeltaZ >= 0.0) ? +1 : -1;
758        }
759        // eventually give credit for delta sum
760        mfMagnifyDeltaSum -= nDeltaZ / fMagnifyFactor;
761
762        NSPoint aPt = [NSEvent mouseLocation];
763        mpFrame->CocoaToVCL( aPt );
764
765        SalWheelMouseEvent aEvent;
766        aEvent.mnTime           = mpFrame->mnLastEventTime;
767        aEvent.mnX              = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
768        aEvent.mnY              = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
769        aEvent.mnCode           = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
770        aEvent.mnCode           |= KEY_MOD1; // we want zooming, no scrolling
771        aEvent.mbDeltaIsPixel   = TRUE;
772
773        // --- RTL --- (mirror mouse pos)
774        if( Application::GetSettings().GetLayoutRTL() )
775            aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
776
777        aEvent.mnDelta = nDeltaZ;
778        aEvent.mnNotchDelta = (nDeltaZ >= 0) ? +1 : -1;
779        if( aEvent.mnDelta == 0 )
780            aEvent.mnDelta = aEvent.mnNotchDelta;
781        aEvent.mbHorz = FALSE;
782        aEvent.mnScrollLines = nDeltaZ;
783        if( aEvent.mnScrollLines == 0 )
784            aEvent.mnScrollLines = 1;
785        mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
786    }
787}
788
789- (void)rotateWithEvent: (NSEvent*)pEvent
790{
791    //Rotation : -(float)rotation;
792    // TODO: create new CommandType so rotation is available to the applications
793    (void)pEvent;
794}
795
796- (void)swipeWithEvent: (NSEvent*)pEvent
797{
798    YIELD_GUARD;
799
800    if( AquaSalFrame::isAlive( mpFrame ) )
801    {
802        mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
803        mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
804
805        // merge pending scroll wheel events
806        CGFloat dX = 0.0;
807        CGFloat dY = 0.0;
808        for(;;)
809        {
810            dX += [pEvent deltaX];
811            dY += [pEvent deltaY];
812            NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
813            untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
814            if( !pNextEvent )
815                break;
816            pEvent = pNextEvent;
817        }
818
819        NSPoint aPt = [NSEvent mouseLocation];
820        mpFrame->CocoaToVCL( aPt );
821
822        SalWheelMouseEvent aEvent;
823        aEvent.mnTime           = mpFrame->mnLastEventTime;
824        aEvent.mnX              = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
825        aEvent.mnY              = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
826        aEvent.mnCode           = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
827        aEvent.mbDeltaIsPixel   = TRUE;
828
829        // --- RTL --- (mirror mouse pos)
830        if( Application::GetSettings().GetLayoutRTL() )
831            aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
832
833        if( dX != 0.0 )
834        {
835            aEvent.mnDelta = static_cast<long>(floor(dX));
836            aEvent.mnNotchDelta = (dX < 0) ? -1 : +1;
837            if( aEvent.mnDelta == 0 )
838                aEvent.mnDelta = aEvent.mnNotchDelta;
839            aEvent.mbHorz = TRUE;
840            aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
841            mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
842        }
843        if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ))
844        {
845            aEvent.mnDelta = static_cast<long>(floor(dY));
846            aEvent.mnNotchDelta = (dY < 0) ? -1 : +1;
847            if( aEvent.mnDelta == 0 )
848                aEvent.mnDelta = aEvent.mnNotchDelta;
849            aEvent.mbHorz = FALSE;
850            aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
851            mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
852        }
853    }
854}
855
856-(void)scrollWheel: (NSEvent*)pEvent
857{
858    YIELD_GUARD;
859
860    if( AquaSalFrame::isAlive( mpFrame ) )
861    {
862        mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
863        mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
864
865        // merge pending scroll wheel events
866        CGFloat dX = 0.0;
867        CGFloat dY = 0.0;
868        for(;;)
869        {
870            dX += [pEvent deltaX];
871    	    dY += [pEvent deltaY];
872            NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
873                untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
874            if( !pNextEvent )
875                break;
876            pEvent = pNextEvent;
877        }
878
879        NSPoint aPt = [NSEvent mouseLocation];
880        mpFrame->CocoaToVCL( aPt );
881
882        SalWheelMouseEvent aEvent;
883        aEvent.mnTime         = mpFrame->mnLastEventTime;
884        aEvent.mnX            = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
885        aEvent.mnY            = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
886        aEvent.mnCode         = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
887        aEvent.mbDeltaIsPixel = TRUE;
888
889        // --- RTL --- (mirror mouse pos)
890        if( Application::GetSettings().GetLayoutRTL() )
891            aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
892
893        if( dX != 0.0 )
894        {
895            aEvent.mnDelta = static_cast<long>(floor(dX));
896            aEvent.mnNotchDelta = (dX < 0) ? -1 : +1;
897            if( aEvent.mnDelta == 0 )
898                aEvent.mnDelta = aEvent.mnNotchDelta;
899            aEvent.mbHorz = TRUE;
900            aEvent.mnScrollLines = (dX > 0) ? +dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR;
901            if( aEvent.mnScrollLines == 0 )
902                aEvent.mnScrollLines = 1;
903
904            mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
905        }
906        if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) )
907        {
908            aEvent.mnDelta = static_cast<long>(floor(dY));
909            aEvent.mnNotchDelta = (dY < 0) ? -1 : +1;
910            if( aEvent.mnDelta == 0 )
911                aEvent.mnDelta = aEvent.mnNotchDelta;
912            aEvent.mbHorz = FALSE;
913            aEvent.mnScrollLines = (dY > 0) ? +dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR;
914            if( aEvent.mnScrollLines < 1 )
915                aEvent.mnScrollLines = 1;
916
917            mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
918        }
919    }
920}
921
922
923-(void)keyDown: (NSEvent*)pEvent
924{
925    YIELD_GUARD;
926
927    if( AquaSalFrame::isAlive( mpFrame ) )
928    {
929        mpLastEvent = pEvent;
930        mbInKeyInput = true;
931        mbNeedSpecialKeyHandle = false;
932        mbKeyHandled = false;
933
934        mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
935        mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
936
937        if( ! [self handleKeyDownException: pEvent] )
938        {
939            NSArray* pArray = [NSArray arrayWithObject: pEvent];
940            [self interpretKeyEvents: pArray];
941        }
942
943        mbInKeyInput = false;
944    }
945}
946
947-(BOOL)handleKeyDownException:(NSEvent*)pEvent
948{
949    // check for a very special set of modified characters
950    NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers];
951
952    if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
953    {
954        /* #i103102# key events with command and alternate don't make it through
955           interpretKeyEvents (why ?). Try to dispatch them here first,
956           if not successful continue normally
957        */
958        if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask))
959                    == (NSAlternateKeyMask | NSCommandKeyMask) )
960        {
961            if( [self sendSingleCharacter: mpLastEvent] )
962                return YES;
963        }
964        unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
965        sal_uInt16 nKeyCode = ImplMapCharCode( keyChar );
966
967        // Caution: should the table grow to more than 5 or 6 entries,
968        // we must consider moving it to a kind of hash map
969        const unsigned int nExceptions = sizeof( aExceptionalKeys ) / sizeof( aExceptionalKeys[0] );
970        for( unsigned int i = 0; i < nExceptions; i++ )
971        {
972            if( nKeyCode == aExceptionalKeys[i].nKeyCode &&
973                (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask)
974                == aExceptionalKeys[i].nModifierMask )
975            {
976                [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0];
977
978                return YES;
979            }
980        }
981    }
982    return NO;
983}
984
985-(void)flagsChanged: (NSEvent*)pEvent
986{
987    YIELD_GUARD;
988
989    if( AquaSalFrame::isAlive( mpFrame ) )
990    {
991        mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 );
992        mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
993    }
994}
995
996-(void)insertText:(id)aString
997{
998    YIELD_GUARD;
999
1000    if( AquaSalFrame::isAlive( mpFrame ) )
1001    {
1002        NSString* pInsert = nil;
1003        if( [aString isMemberOfClass: [NSAttributedString class]] )
1004            pInsert = [aString string];
1005        else
1006            pInsert = aString;
1007
1008        int nLen = 0;
1009        if( pInsert && ( nLen = [pInsert length] ) > 0 )
1010        {
1011            OUString aInsertString( GetOUString( pInsert ) );
1012             // aCharCode initializer is safe since aInsertString will at least contain '\0'
1013            sal_Unicode aCharCode = *aInsertString.getStr();
1014
1015            if( nLen == 1 &&
1016                aCharCode < 0x80 &&
1017                aCharCode > 0x1f &&
1018				! [self hasMarkedText ]
1019                )
1020            {
1021                sal_uInt16 nKeyCode = ImplMapCharCode( aCharCode );
1022                unsigned int nLastModifiers = mpFrame->mnLastModifierFlags;
1023
1024                // #i99567#
1025                // find out the unmodified key code
1026
1027                // sanity check
1028                if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) )
1029                {
1030                    // get unmodified string
1031                    NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers];
1032                    if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
1033                    {
1034                        // map the unmodified key code
1035                        unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
1036                        nKeyCode = ImplMapCharCode( keyChar );
1037                    }
1038                    nLastModifiers = [mpLastEvent modifierFlags];
1039
1040                }
1041                // #i99567#
1042                // applications and vcl's edit fields ignore key events with ALT
1043                // however we're at a place where we know text should be inserted
1044                // so it seems we need to strip the Alt modifier here
1045                if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask))
1046                    == NSAlternateKeyMask )
1047                {
1048                    nLastModifiers = 0;
1049                }
1050                [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers];
1051            }
1052            else
1053            {
1054                SalExtTextInputEvent aEvent;
1055                aEvent.mnTime           = mpFrame->mnLastEventTime;
1056                aEvent.maText           = aInsertString;
1057                aEvent.mpTextAttr       = NULL;
1058                aEvent.mnCursorPos      = aInsertString.getLength();
1059                aEvent.mnDeltaStart     = 0;
1060                aEvent.mnCursorFlags    = 0;
1061                aEvent.mbOnlyCursor     = FALSE;
1062                mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
1063                if( AquaSalFrame::isAlive( mpFrame ) )
1064                    mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1065            }
1066        }
1067        else
1068        {
1069            SalExtTextInputEvent aEvent;
1070            aEvent.mnTime           = mpFrame->mnLastEventTime;
1071            aEvent.maText           = String();
1072            aEvent.mpTextAttr       = NULL;
1073            aEvent.mnCursorPos      = 0;
1074            aEvent.mnDeltaStart     = 0;
1075            aEvent.mnCursorFlags    = 0;
1076            aEvent.mbOnlyCursor     = FALSE;
1077            mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
1078            if( AquaSalFrame::isAlive( mpFrame ) )
1079                mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1080
1081        }
1082        mbKeyHandled = true;
1083        [self unmarkText];
1084    }
1085}
1086
1087-(void)insertTab: (id)aSender
1088{
1089    (void)aSender;
1090    [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0];
1091}
1092
1093-(void)insertBacktab: (id)aSender
1094{
1095    (void)aSender;
1096    [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0];
1097}
1098
1099-(void)moveLeft: (id)aSender
1100{
1101    (void)aSender;
1102    [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0];
1103}
1104
1105-(void)moveLeftAndModifySelection: (id)aSender
1106{
1107    (void)aSender;
1108    [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask];
1109}
1110
1111-(void)moveBackwardAndModifySelection: (id)aSender
1112{
1113    (void)aSender;
1114    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0  modifiers: 0];
1115}
1116
1117-(void)moveRight: (id)aSender
1118{
1119    (void)aSender;
1120    [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0];
1121}
1122
1123-(void)moveRightAndModifySelection: (id)aSender
1124{
1125    (void)aSender;
1126    [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask];
1127}
1128
1129-(void)moveForwardAndModifySelection: (id)aSender
1130{
1131    (void)aSender;
1132    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0  modifiers: 0];
1133}
1134
1135-(void)moveWordLeft: (id)aSender
1136{
1137    (void)aSender;
1138    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0  modifiers: 0];
1139}
1140
1141-(void)moveWordBackward: (id)aSender
1142{
1143    (void)aSender;
1144    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0  modifiers: 0];
1145}
1146
1147-(void)moveWordBackwardAndModifySelection: (id)aSender
1148{
1149    (void)aSender;
1150    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0  modifiers: 0];
1151}
1152
1153-(void)moveWordLeftAndModifySelection: (id)aSender
1154{
1155    (void)aSender;
1156    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0  modifiers: 0];
1157}
1158
1159-(void)moveWordRight: (id)aSender
1160{
1161    (void)aSender;
1162    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0  modifiers: 0];
1163}
1164
1165-(void)moveWordForward: (id)aSender
1166{
1167    (void)aSender;
1168    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0  modifiers: 0];
1169}
1170
1171-(void)moveWordForwardAndModifySelection: (id)aSender
1172{
1173    (void)aSender;
1174    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0  modifiers: 0];
1175}
1176
1177-(void)moveWordRightAndModifySelection: (id)aSender
1178{
1179    (void)aSender;
1180    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0  modifiers: 0];
1181}
1182
1183-(void)moveToEndOfLine: (id)aSender
1184{
1185    (void)aSender;
1186    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0  modifiers: 0];
1187}
1188
1189-(void)moveToRightEndOfLine: (id)aSender
1190{
1191    (void)aSender;
1192    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0  modifiers: 0];
1193}
1194
1195-(void)moveToEndOfLineAndModifySelection: (id)aSender
1196{
1197    (void)aSender;
1198    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0  modifiers: 0];
1199}
1200
1201-(void)moveToRightEndOfLineAndModifySelection: (id)aSender
1202{
1203    (void)aSender;
1204    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0  modifiers: 0];
1205}
1206
1207-(void)moveToBeginningOfLine: (id)aSender
1208{
1209    (void)aSender;
1210    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1211}
1212
1213-(void)moveToLeftEndOfLine: (id)aSender
1214{
1215    (void)aSender;
1216    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1217}
1218
1219-(void)moveToBeginningOfLineAndModifySelection: (id)aSender
1220{
1221    (void)aSender;
1222    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1223}
1224
1225-(void)moveToLeftEndOfLineAndModifySelection: (id)aSender
1226{
1227    (void)aSender;
1228    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1229}
1230
1231-(void)moveToEndOfParagraph: (id)aSender
1232{
1233    (void)aSender;
1234    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1235}
1236
1237-(void)moveToEndOfParagraphAndModifySelection: (id)aSender
1238{
1239    (void)aSender;
1240    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1241}
1242
1243-(void)moveParagraphForward: (id)aSender
1244{
1245    (void)aSender;
1246    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1247}
1248
1249-(void)moveParagraphForwardAndModifySelection: (id)aSender
1250{
1251    (void)aSender;
1252    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1253}
1254
1255-(void)moveToBeginningOfParagraph: (id)aSender
1256{
1257    (void)aSender;
1258    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1259}
1260
1261-(void)moveParagraphBackward: (id)aSender
1262{
1263    (void)aSender;
1264    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1265}
1266
1267-(void)moveToBeginningOfParagraphAndModifySelection: (id)aSender
1268{
1269    (void)aSender;
1270    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1271}
1272
1273-(void)moveParagraphBackwardAndModifySelection: (id)aSender
1274{
1275    (void)aSender;
1276    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1277}
1278
1279-(void)moveToEndOfDocument: (id)aSender
1280{
1281    (void)aSender;
1282    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0  modifiers: 0];
1283}
1284
1285-(void)scrollToEndOfDocument: (id)aSender
1286{
1287    (void)aSender;
1288    // this is not exactly what we should do, but it makes "End" and "Shift-End" behave consistent
1289    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0  modifiers: 0];
1290}
1291
1292-(void)moveToEndOfDocumentAndModifySelection: (id)aSender
1293{
1294    (void)aSender;
1295    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0  modifiers: 0];
1296}
1297
1298-(void)moveToBeginningOfDocument: (id)aSender
1299{
1300    (void)aSender;
1301    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0  modifiers: 0];
1302}
1303
1304-(void)scrollToBeginningOfDocument: (id)aSender
1305{
1306    (void)aSender;
1307    // this is not exactly what we should do, but it makes "Home" and "Shift-Home" behave consistent
1308    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0  modifiers: 0];
1309}
1310
1311-(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender
1312{
1313    (void)aSender;
1314    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0  modifiers: 0];
1315}
1316
1317-(void)moveUp: (id)aSender
1318{
1319    (void)aSender;
1320    [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0];
1321}
1322
1323-(void)moveDown: (id)aSender
1324{
1325    (void)aSender;
1326    [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0];
1327}
1328
1329-(void)insertNewline: (id)aSender
1330{
1331    (void)aSender;
1332    // #i91267# make enter and shift-enter work by evaluating the modifiers
1333    [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags];
1334}
1335
1336-(void)deleteBackward: (id)aSender
1337{
1338    (void)aSender;
1339    [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1340}
1341
1342-(void)deleteForward: (id)aSender
1343{
1344    (void)aSender;
1345    [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0];
1346}
1347
1348-(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender
1349{
1350    (void)aSender;
1351    [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1352}
1353
1354-(void)deleteWordBackward: (id)aSender
1355{
1356    (void)aSender;
1357    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0  modifiers: 0];
1358}
1359
1360-(void)deleteWordForward: (id)aSender
1361{
1362    (void)aSender;
1363    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0  modifiers: 0];
1364}
1365
1366-(void)deleteToBeginningOfLine: (id)aSender
1367{
1368    (void)aSender;
1369    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0  modifiers: 0];
1370}
1371
1372-(void)deleteToEndOfLine: (id)aSender
1373{
1374    (void)aSender;
1375    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0  modifiers: 0];
1376}
1377
1378-(void)deleteToBeginningOfParagraph: (id)aSender
1379{
1380    (void)aSender;
1381    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0  modifiers: 0];
1382}
1383
1384-(void)deleteToEndOfParagraph: (id)aSender
1385{
1386    (void)aSender;
1387    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0  modifiers: 0];
1388}
1389
1390-(void)insertLineBreak: (id)aSender
1391{
1392    (void)aSender;
1393    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0  modifiers: 0];
1394}
1395
1396-(void)insertParagraphSeparator: (id)aSender
1397{
1398    (void)aSender;
1399    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0  modifiers: 0];
1400}
1401
1402-(void)selectWord: (id)aSender
1403{
1404    (void)aSender;
1405    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0  modifiers: 0];
1406}
1407
1408-(void)selectLine: (id)aSender
1409{
1410    (void)aSender;
1411    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0  modifiers: 0];
1412}
1413
1414-(void)selectParagraph: (id)aSender
1415{
1416    (void)aSender;
1417    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0  modifiers: 0];
1418}
1419
1420-(void)selectAll: (id)aSender
1421{
1422    (void)aSender;
1423    [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0  modifiers: 0];
1424}
1425
1426-(void)cancelOperation: (id)aSender
1427{
1428    (void)aSender;
1429    [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0];
1430}
1431
1432-(void)noop: (id)aSender
1433{
1434    (void)aSender;
1435    if( ! mbKeyHandled )
1436    {
1437        if( ! [self sendSingleCharacter:mpLastEvent] )
1438        {
1439            /* prevent recursion */
1440            if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] )
1441            {
1442                id pLastSuperEvent = mpLastSuperEvent;
1443                mpLastSuperEvent = mpLastEvent;
1444                [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent];
1445                mpLastSuperEvent = pLastSuperEvent;
1446
1447                std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1448                if( it != GetSalData()->maKeyEventAnswer.end() )
1449                    it->second = true;
1450            }
1451        }
1452    }
1453}
1454
1455-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar
1456{
1457    return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags];
1458}
1459
1460-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1461{
1462    return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] ||
1463           [self sendSingleCharacter: mpLastEvent];
1464}
1465
1466-(BOOL)sendKeyToFrameDirect: (sal_uInt16)nKeyCode  character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1467{
1468    YIELD_GUARD;
1469
1470    long nRet = 0;
1471    if( AquaSalFrame::isAlive( mpFrame ) )
1472    {
1473        SalKeyEvent aEvent;
1474        aEvent.mnTime           = mpFrame->mnLastEventTime;
1475        aEvent.mnCode           = nKeyCode | ImplGetModifierMask( nMod );
1476        aEvent.mnCharCode       = aChar;
1477        aEvent.mnRepeat         = FALSE;
1478        nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent );
1479        std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1480        if( it != GetSalData()->maKeyEventAnswer.end() )
1481            it->second = nRet ? true : false;
1482        if( AquaSalFrame::isAlive( mpFrame ) )
1483            mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent );
1484    }
1485    return nRet ? YES : NO;
1486}
1487
1488
1489-(BOOL)sendSingleCharacter: (NSEvent *)pEvent
1490{
1491    NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers];
1492
1493    if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
1494    {
1495        unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
1496        sal_uInt16 nKeyCode = ImplMapCharCode( keyChar );
1497        if( nKeyCode != 0 )
1498        {
1499            // don't send unicodes in the private use area
1500            if( keyChar >= 0xf700 && keyChar < 0xf780 )
1501                keyChar = 0;
1502            BOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags];
1503            mbInKeyInput = false;
1504
1505            return bRet;
1506        }
1507    }
1508    return NO;
1509}
1510
1511
1512// NSTextInput protocol
1513- (NSArray *)validAttributesForMarkedText
1514{
1515    return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil];
1516}
1517
1518- (BOOL)hasMarkedText
1519{
1520    BOOL bHasMarkedText;
1521
1522    bHasMarkedText = ( mMarkedRange.location != NSNotFound ) &&
1523                     ( mMarkedRange.length != 0 );
1524    // hack to check keys like "Control-j"
1525    if( mbInKeyInput )
1526    {
1527        mbNeedSpecialKeyHandle = true;
1528    }
1529
1530    // FIXME:
1531    // #i106901#
1532    // if we come here outside of mbInKeyInput, this is likely to be because
1533    // of the keyboard viewer. For unknown reasons having no marked range
1534    // in this case causes a crash. So we say we have a marked range anyway
1535    // This is a hack, since it is not understood what a) causes that crash
1536    // and b) why we should have a marked range at this point.
1537    if( ! mbInKeyInput )
1538        bHasMarkedText = YES;
1539
1540    return bHasMarkedText;
1541}
1542
1543- (NSRange)markedRange
1544{
1545    // FIXME:
1546    // #i106901#
1547    // if we come here outside of mbInKeyInput, this is likely to be because
1548    // of the keyboard viewer. For unknown reasons having no marked range
1549    // in this case causes a crash. So we say we have a marked range anyway
1550    // This is a hack, since it is not understood what a) causes that crash
1551    // and b) why we should have a marked range at this point.
1552    if( ! mbInKeyInput )
1553        return NSMakeRange( 0, 0 );
1554
1555    return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 );
1556}
1557
1558- (NSRange)selectedRange
1559{
1560    return mSelectedRange;
1561}
1562
1563- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange
1564{
1565    if( ![aString isKindOfClass:[NSAttributedString class]] )
1566        aString = [[[NSAttributedString alloc] initWithString:aString] autorelease];
1567    NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange];
1568    if( rangeToReplace.location == NSNotFound )
1569    {
1570        mMarkedRange = NSMakeRange( selRange.location, [aString length] );
1571        mSelectedRange = NSMakeRange( selRange.location, selRange.length );
1572    }
1573    else
1574    {
1575        mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] );
1576        mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length );
1577    }
1578
1579    int len = [aString length];
1580    SalExtTextInputEvent aInputEvent;
1581    aInputEvent.mnTime = mpFrame->mnLastEventTime;
1582    aInputEvent.mnDeltaStart = 0;
1583    aInputEvent.mbOnlyCursor = FALSE;
1584    if( len > 0 ) {
1585        NSString *pString = [aString string];
1586        OUString aInsertString( GetOUString( pString ) );
1587        std::vector<sal_uInt16> aInputFlags = std::vector<sal_uInt16>( std::max( 1, len ), 0 );
1588        for ( int i = 0; i < len; i++ )
1589        {
1590            unsigned int nUnderlineValue;
1591            NSRange effectiveRange;
1592
1593            effectiveRange = NSMakeRange(i, 1);
1594            nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue];
1595
1596            switch (nUnderlineValue & 0xff) {
1597            case NSUnderlineStyleSingle:
1598                aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
1599                break;
1600            case NSUnderlineStyleThick:
1601                aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
1602                break;
1603            case NSUnderlineStyleDouble:
1604                aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE;
1605                break;
1606            default:
1607                aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
1608                break;
1609            }
1610        }
1611
1612        aInputEvent.maText = aInsertString;
1613        aInputEvent.mnCursorPos = selRange.location;
1614        aInputEvent.mpTextAttr = &aInputFlags[0];
1615        mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1616    } else {
1617        aInputEvent.maText = String();
1618        aInputEvent.mnCursorPos = 0;
1619        aInputEvent.mnCursorFlags = 0;
1620        aInputEvent.mpTextAttr = 0;
1621        mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1622        mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1623    }
1624    mbKeyHandled= true;
1625}
1626
1627- (void)unmarkText
1628{
1629    mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
1630}
1631
1632- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange
1633{
1634    (void)theRange;
1635    // FIXME
1636    return nil;
1637}
1638
1639- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
1640{
1641    (void)thePoint;
1642    // FIXME
1643    return 0;
1644}
1645
1646#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
1647/* build target 10.5 or greater */
1648- (NSInteger)conversationIdentifier
1649#else
1650/* build target 10.4 */
1651- (long)conversationIdentifier
1652#endif
1653{
1654    return (long)self;
1655}
1656
1657- (void)doCommandBySelector:(SEL)aSelector
1658{
1659    if( AquaSalFrame::isAlive( mpFrame ) )
1660    {
1661        #if OSL_DEBUG_LEVEL > 1
1662        // fprintf( stderr, "SalFrameView: doCommandBySelector %s\n", (char*)aSelector );
1663        #endif
1664        if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 &&
1665            aSelector != NULL && [self respondsToSelector: aSelector] )
1666        {
1667            [self performSelector: aSelector];
1668        }
1669        else
1670        {
1671            [self sendSingleCharacter:mpLastEvent];
1672        }
1673    }
1674
1675    mbKeyHandled = true;
1676}
1677
1678-(void)clearLastEvent
1679{
1680    mpLastEvent = nil;
1681}
1682
1683- (NSRect)firstRectForCharacterRange:(NSRange)theRange
1684{
1685    (void)theRange;
1686    SalExtTextInputPosEvent aPosEvent;
1687    mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent );
1688
1689    NSRect rect;
1690
1691    rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX;
1692    rect.origin.y =   aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines
1693    rect.size.width = aPosEvent.mnWidth;
1694    rect.size.height = aPosEvent.mnHeight;
1695
1696    mpFrame->VCLToCocoa( rect );
1697    return rect;
1698}
1699
1700-(id)parentAttribute {
1701    return mpFrame->getNSWindow();
1702}
1703
1704-(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext
1705{
1706    if ( mpReferenceWrapper == nil ) {
1707        // some frames never become visible ..
1708        Window *pWindow = mpFrame -> GetWindow();
1709        if ( ! pWindow )
1710            return nil;
1711
1712        mpReferenceWrapper = new ReferenceWrapper;
1713        mpReferenceWrapper -> rAccessibleContext =  pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext();
1714        [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ];
1715    }
1716    return [ super accessibleContext ];
1717}
1718
1719-(NSWindow*)windowForParent
1720{
1721    return mpFrame->getNSWindow();
1722}
1723
1724-(void)registerMouseEventListener: (id)theListener
1725{
1726  mpMouseEventListener = theListener;
1727}
1728
1729-(void)unregisterMouseEventListener: (id)theListener
1730{
1731    (void)theListener;
1732    mpMouseEventListener = nil;
1733}
1734
1735-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
1736{
1737  return [mDraggingDestinationHandler draggingEntered: sender];
1738}
1739
1740-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
1741{
1742  return [mDraggingDestinationHandler draggingUpdated: sender];
1743}
1744
1745-(void)draggingExited:(id <NSDraggingInfo>)sender
1746{
1747  [mDraggingDestinationHandler draggingExited: sender];
1748}
1749
1750-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
1751{
1752  return [mDraggingDestinationHandler prepareForDragOperation: sender];
1753}
1754
1755-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
1756{
1757  return [mDraggingDestinationHandler performDragOperation: sender];
1758}
1759
1760-(void)concludeDragOperation:(id <NSDraggingInfo>)sender
1761{
1762  [mDraggingDestinationHandler concludeDragOperation: sender];
1763}
1764
1765-(void)registerDraggingDestinationHandler:(id)theHandler
1766{
1767  mDraggingDestinationHandler = theHandler;
1768}
1769
1770-(void)unregisterDraggingDestinationHandler:(id)theHandler
1771{
1772    (void)theHandler;
1773    mDraggingDestinationHandler = nil;
1774}
1775
1776@end
1777
1778