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