1 /*n***********************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salframeview.mm,v $
10 * $Revision: 1.12.22.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include "salframeview.h"
38 #include "aqua11yfactory.h"
39 #include <sal/alloca.h>
40 #include "vcl/window.hxx"
42 #include "vcl/svapp.hxx"
44 static USHORT ImplGetModifierMask( unsigned int nMask )
47 if( (nMask & NSShiftKeyMask) != 0 )
49 if( (nMask & NSControlKeyMask) != 0 )
51 if( (nMask & NSAlternateKeyMask) != 0 )
53 if( (nMask & NSCommandKeyMask) != 0 )
58 static USHORT ImplMapCharCode( sal_Unicode aCode )
60 static USHORT aKeyCodeMap[ 128 ] =
62 0, 0, 0, 0, 0, 0, 0, 0,
63 KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0,
65 0, KEY_TAB, 0, KEY_ESCAPE, 0, 0, 0, 0,
66 KEY_SPACE, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE,
68 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
69 KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0,
70 0, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
71 KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
72 KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
73 KEY_X, KEY_Y, KEY_Z, 0, 0, 0, 0, 0,
74 KEY_QUOTELEFT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
75 KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
76 KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
77 KEY_X, KEY_Y, KEY_Z, 0, 0, 0, KEY_TILDE, KEY_BACKSPACE
80 // Note: the mapping 0x7f should by rights be KEY_DELETE
81 // however if you press "backspace" 0x7f is reported
82 // whereas for "delete" 0xf728 gets reported
84 // Note: the mapping of 0x19 to KEY_TAB is because for unknown reasons
85 // tab alone is reported as 0x09 (as expected) but shift-tab is
86 // reported as 0x19 (end of medium)
88 static USHORT aFunctionKeyCodeMap[ 128 ] =
90 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4,
91 KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
92 KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20,
93 KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, KEY_INSERT,
95 KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0,
96 0, 0, 0, 0, 0, KEY_MENU, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 0,
99 0, 0, 0, 0, 0, 0, 0, 0,
100 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0
109 if( aCode < sizeof( aKeyCodeMap) / sizeof( aKeyCodeMap[0] ) )
110 nKeyCode = aKeyCodeMap[ aCode ];
111 else if( aCode >= 0xf700 && aCode < 0xf780 )
112 nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ];
116 // store the frame the mouse last entered
117 static AquaSalFrame* s_pMouseFrame = NULL;
118 // store the last pressed button for enter/exit events
119 // which lack that information
120 static USHORT s_nLastButton = 0;
122 // combinations of keys we need to handle ourselves
123 static const struct ExceptionalKey
125 const USHORT nKeyCode;
126 const unsigned int nModifierMask;
127 } aExceptionalKeys[] =
129 { KEY_D, NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask },
130 { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask }
133 static AquaSalFrame* getMouseContainerFrame()
136 NSCountWindows( &nWindows );
137 int* pWindows = (int*)alloca( nWindows * sizeof(int) );
138 // note: NSWindowList is supposed to be in z-order front to back
139 NSWindowList( nWindows, pWindows );
140 AquaSalFrame* pDispatchFrame = NULL;
141 for(int i = 0; i < nWindows && ! pDispatchFrame; i++ )
143 NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]];
144 if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] )
145 pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame];
147 return pDispatchFrame;
150 @implementation SalFrameWindow
151 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
153 mDraggingDestinationHandler = nil;
155 NSRect aRect = { { pFrame->maGeometry.nX, pFrame->maGeometry.nY },
156 { pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight } };
157 pFrame->VCLToCocoa( aRect );
158 return [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ];
161 -(AquaSalFrame*)getSalFrame
166 -(MacOSBOOL)containsMouse
168 // is this event actually inside that NSWindow ?
169 NSPoint aPt = [NSEvent mouseLocation];
170 NSRect aFrameRect = [self frame];
171 MacOSBOOL bInRect = NSPointInRect( aPt, aFrameRect );
175 -(MacOSBOOL)canBecomeKeyWindow
177 if( (mpFrame->mnStyle &
178 ( SAL_FRAME_STYLE_FLOAT |
179 SAL_FRAME_STYLE_TOOLTIP |
180 SAL_FRAME_STYLE_INTRO
183 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) != 0 )
185 if( mpFrame->mbFullScreen )
187 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) )
189 return [super canBecomeKeyWindow];
192 -(void)windowDidBecomeKey: (NSNotification*)pNotification
196 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
198 static const ULONG nGuessDocument = SAL_FRAME_STYLE_MOVEABLE|
199 SAL_FRAME_STYLE_SIZEABLE|
200 SAL_FRAME_STYLE_CLOSEABLE;
202 if( mpFrame->mpMenu )
203 mpFrame->mpMenu->setMainMenu();
204 else if( ! mpFrame->mpParent &&
205 ( (mpFrame->mnStyle & nGuessDocument) == nGuessDocument || // set default menu for e.g. help
206 mpFrame->mbFullScreen ) ) // ser default menu for e.g. presentation
208 AquaSalMenu::setDefaultMenu();
211 // FIXME: we should disable menus while in modal mode
212 // however from down here there is currently no reliable way to
213 // find out when to do this
214 if( (mpFrame->mpParent && mpFrame->mpParent->GetWindow()->IsInModalMode()) )
215 AquaSalMenu::enableMainMenu( false );
217 mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 );
221 -(void)windowDidResignKey: (NSNotification*)pNotification
225 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
226 mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0);
229 -(void)windowDidChangeScreen: (NSNotification*)pNotification
233 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
234 mpFrame->screenParametersChanged();
237 -(void)windowDidMove: (NSNotification*)pNotification
241 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
243 mpFrame->UpdateFrameGeometry();
244 mpFrame->CallCallback( SALEVENT_MOVE, 0 );
248 -(void)windowDidResize: (NSNotification*)pNotification
252 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
254 mpFrame->UpdateFrameGeometry();
255 mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
256 mpFrame->SendPaintEvent();
260 -(void)windowDidMiniaturize: (NSNotification*)pNotification
264 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
266 mpFrame->mbShown = false;
267 mpFrame->UpdateFrameGeometry();
268 mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
272 -(void)windowDidDeminiaturize: (NSNotification*)pNotification
276 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
278 mpFrame->mbShown = true;
279 mpFrame->UpdateFrameGeometry();
280 mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
284 -(MacOSBOOL)windowShouldClose: (NSNotification*)pNotification
288 MacOSBOOL bRet = YES;
289 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
291 // #i84461# end possible input
292 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
293 if( AquaSalFrame::isAlive( mpFrame ) )
295 mpFrame->CallCallback( SALEVENT_CLOSE, 0 );
296 bRet = NO; // application will close the window or not, AppKit shouldn't
303 -(void)dockMenuItemTriggered: (id)sender
307 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
308 mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS );
311 -(::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >)accessibleContext
313 return mpFrame -> GetWindow() -> GetAccessible() -> getAccessibleContext();
316 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
318 return [mDraggingDestinationHandler draggingEntered: sender];
321 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
323 return [mDraggingDestinationHandler draggingUpdated: sender];
326 -(void)draggingExited:(id <NSDraggingInfo>)sender
328 [mDraggingDestinationHandler draggingExited: sender];
331 -(MacOSBOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
333 return [mDraggingDestinationHandler prepareForDragOperation: sender];
336 -(MacOSBOOL)performDragOperation:(id <NSDraggingInfo>)sender
338 return [mDraggingDestinationHandler performDragOperation: sender];
341 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
343 [mDraggingDestinationHandler concludeDragOperation: sender];
346 -(void)registerDraggingDestinationHandler:(id)theHandler
348 mDraggingDestinationHandler = theHandler;
351 -(void)unregisterDraggingDestinationHandler:(id)theHandler
353 mDraggingDestinationHandler = nil;
358 @implementation SalFrameView
359 +(void)unsetMouseFrame: (AquaSalFrame*)pFrame
361 if( pFrame == s_pMouseFrame )
362 s_pMouseFrame = NULL;
365 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
367 if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [pFrame->getWindow() frame] styleMask: pFrame->mnStyleMask]]) != nil)
369 mDraggingDestinationHandler = nil;
371 mMarkedRange = NSMakeRange(NSNotFound, 0);
372 mSelectedRange = NSMakeRange(NSNotFound, 0);
373 mpReferenceWrapper = nil;
374 mpMouseEventListener = nil;
375 mpLastSuperEvent = nil;
381 -(void)resetCursorRects
383 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
385 // FIXME: does this leak the returned NSCursor of getCurrentCursor ?
386 NSRect aRect = { { 0, 0 }, { mpFrame->maGeometry.nWidth, mpFrame->maGeometry.nHeight } };
387 [self addCursorRect: aRect cursor: mpFrame->getCurrentCursor()];
391 -(MacOSBOOL)acceptsFirstResponder
396 -(MacOSBOOL)acceptsFirstMouse: (NSEvent*)pEvent
403 return mpFrame ? (mpFrame->getClipPath() != 0 ? NO : YES) : YES;
406 // helper class similar to a vos::OGuard for the SalYieldMutex
407 // the difference is that it only does tryToAcquire instead of aquire
408 // so dreaded deadlocks like #i93512# are prevented
412 TryGuard() { mbGuarded = ImplSalYieldMutexTryToAcquire(); }
413 ~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); }
414 bool IsGuarded() { return mbGuarded; }
419 -(void)drawRect: (NSRect)aRect
421 // HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex
423 if( !aTryGuard.IsGuarded() )
425 // NOTE: the mpFrame access below is not guarded yet!
426 // TODO: mpFrame et al need to be guarded by an independent mutex
427 AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL;
430 // we did not get the mutex so we cannot draw now => request to redraw later
431 // convert the NSRect to a CGRect for Refreshrect()
432 const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}};
433 pGraphics->RefreshRect( aCGRect );
438 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
440 if( mpFrame->mpGraphics )
442 mpFrame->mpGraphics->UpdateWindow( aRect );
443 if( mpFrame->getClipPath() )
444 [mpFrame->getWindow() invalidateShadow];
449 -(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(USHORT)nButton eventtype:(USHORT)nEvent
453 AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame();
454 bool bIsCaptured = false;
458 if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured
459 nEvent = SALEVENT_MOUSEMOVE;
461 else if( s_pMouseFrame )
462 pDispatchFrame = s_pMouseFrame;
464 pDispatchFrame = mpFrame;
466 /* #i81645# Cocoa reports mouse events while a button is pressed
467 to the window in which it was first pressed. This is reasonable and fine and
468 gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer,
469 however vcl expects mouse events to occur in the window the mouse is over, unless the
470 mouse is explicitly captured. So we need to find the window the mouse is actually
471 over for conformance with other platforms.
473 if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
475 // is this event actually inside that NSWindow ?
476 NSPoint aPt = [NSEvent mouseLocation];
477 NSRect aFrameRect = [pDispatchFrame->getWindow() frame];
479 if ( ! NSPointInRect( aPt, aFrameRect ) )
482 // now we need to find the one it may be in
483 /* #i93756# we ant to get enumerate the application windows in z-order
484 to check if any contains the mouse. This could be elegantly done with this
487 // use NSApp to check windows in ZOrder whether they contain the mouse pointer
488 NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES];
489 if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] )
490 pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame];
492 However if a non SalFrameWindow is on screen (like e.g. the file dialog)
493 it can be hit with the containsMouse selector, which it doesn't support.
494 Sadly NSApplication:makeWindowsPerform does not check (for performance reasons
495 I assume) whether a window supports a selector before sending it.
497 AquaSalFrame* pMouseFrame = getMouseContainerFrame();
499 pDispatchFrame = pMouseFrame;
503 if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
505 pDispatchFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
506 pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags];
508 NSPoint aPt = [NSEvent mouseLocation];
509 pDispatchFrame->CocoaToVCL( aPt );
511 USHORT nModMask = ImplGetModifierMask( [pEvent modifierFlags] );
512 // #i82284# emulate ctrl left
513 if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT )
516 nButton = MOUSE_RIGHT;
519 SalMouseEvent aEvent;
520 aEvent.mnTime = pDispatchFrame->mnLastEventTime;
521 aEvent.mnX = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX;
522 aEvent.mnY = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY;
523 aEvent.mnButton = nButton;
524 aEvent.mnCode = aEvent.mnButton | nModMask;
526 // --- RTL --- (mirror mouse pos)
527 if( Application::GetSettings().GetLayoutRTL() )
528 aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX;
530 pDispatchFrame->CallCallback( nEvent, &aEvent );
534 -(void)mouseDown: (NSEvent*)pEvent
536 if ( mpMouseEventListener != nil &&
537 [mpMouseEventListener respondsToSelector: @selector(mouseDown:)])
539 [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]];
542 s_nLastButton = MOUSE_LEFT;
543 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN];
546 -(void)mouseDragged: (NSEvent*)pEvent
548 if ( mpMouseEventListener != nil &&
549 [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)])
551 [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]];
553 s_nLastButton = MOUSE_LEFT;
554 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE];
557 -(void)mouseUp: (NSEvent*)pEvent
560 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP];
563 -(void)mouseMoved: (NSEvent*)pEvent
566 [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE];
569 -(void)mouseEntered: (NSEvent*)pEvent
571 s_pMouseFrame = mpFrame;
573 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE];
576 -(void)mouseExited: (NSEvent*)pEvent
578 if( s_pMouseFrame == mpFrame )
579 s_pMouseFrame = NULL;
581 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE];
584 -(void)rightMouseDown: (NSEvent*)pEvent
586 s_nLastButton = MOUSE_RIGHT;
587 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN];
590 -(void)rightMouseDragged: (NSEvent*)pEvent
592 s_nLastButton = MOUSE_RIGHT;
593 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE];
596 -(void)rightMouseUp: (NSEvent*)pEvent
599 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP];
602 -(void)otherMouseDown: (NSEvent*)pEvent
604 if( [pEvent buttonNumber] == 2 )
606 s_nLastButton = MOUSE_MIDDLE;
607 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN];
613 -(void)otherMouseDragged: (NSEvent*)pEvent
615 if( [pEvent buttonNumber] == 2 )
617 s_nLastButton = MOUSE_MIDDLE;
618 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE];
624 -(void)otherMouseUp: (NSEvent*)pEvent
627 if( [pEvent buttonNumber] == 2 )
628 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP];
631 - (void)magnifyWithEvent: (NSEvent*)pEvent
635 // TODO: ?? -(float)magnification;
636 if( AquaSalFrame::isAlive( mpFrame ) )
638 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
639 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
644 dZ += [pEvent deltaZ];
645 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
646 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
652 NSPoint aPt = [NSEvent mouseLocation];
653 mpFrame->CocoaToVCL( aPt );
655 SalWheelMouseEvent aEvent;
656 aEvent.mnTime = mpFrame->mnLastEventTime;
657 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
658 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
659 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
660 aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling
662 // --- RTL --- (mirror mouse pos)
663 if( Application::GetSettings().GetLayoutRTL() )
664 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
668 aEvent.mnDelta = static_cast<long>(floor(dZ));
669 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
670 if( aEvent.mnNotchDelta == 0 )
671 aEvent.mnNotchDelta = dZ < 0.0 ? -1 : 1;
672 aEvent.mbHorz = FALSE;
673 aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta;
674 if( aEvent.mnScrollLines == 0 )
675 aEvent.mnScrollLines = 1;
676 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
681 - (void)rotateWithEvent: (NSEvent*)pEvent
683 //Rotation : -(float)rotation;
684 // TODO: create new CommandType so rotation is available to the applications
687 - (void)swipeWithEvent: (NSEvent*)pEvent
691 if( AquaSalFrame::isAlive( mpFrame ) )
693 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
694 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
696 // merge pending scroll wheel events
701 dX += [pEvent deltaX];
702 dY += [pEvent deltaY];
703 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
704 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
710 NSPoint aPt = [NSEvent mouseLocation];
711 mpFrame->CocoaToVCL( aPt );
713 SalWheelMouseEvent aEvent;
714 aEvent.mnTime = mpFrame->mnLastEventTime;
715 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
716 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
717 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
719 // --- RTL --- (mirror mouse pos)
720 if( Application::GetSettings().GetLayoutRTL() )
721 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
725 aEvent.mnDelta = static_cast<long>(floor(dX));
726 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
727 if( aEvent.mnNotchDelta == 0 )
728 aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1;
729 aEvent.mbHorz = TRUE;
730 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
731 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
733 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ))
735 aEvent.mnDelta = static_cast<long>(floor(dY));
736 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
737 if( aEvent.mnNotchDelta == 0 )
738 aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1;
739 aEvent.mbHorz = FALSE;
740 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
741 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
746 -(void)scrollWheel: (NSEvent*)pEvent
750 if( AquaSalFrame::isAlive( mpFrame ) )
752 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
753 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
755 // merge pending scroll wheel events
760 dX += [pEvent deltaX];
761 dY += [pEvent deltaY];
762 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
763 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
769 NSPoint aPt = [NSEvent mouseLocation];
770 mpFrame->CocoaToVCL( aPt );
772 SalWheelMouseEvent aEvent;
773 aEvent.mnTime = mpFrame->mnLastEventTime;
774 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
775 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
776 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
778 // --- RTL --- (mirror mouse pos)
779 if( Application::GetSettings().GetLayoutRTL() )
780 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
784 aEvent.mnDelta = static_cast<long>(floor(dX));
785 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
786 if( aEvent.mnNotchDelta == 0 )
787 aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1;
788 aEvent.mbHorz = TRUE;
789 aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta;
790 if( aEvent.mnScrollLines == 0 )
791 aEvent.mnScrollLines = 1;
792 if( aEvent.mnScrollLines > 15 )
793 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
794 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
796 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) )
798 aEvent.mnDelta = static_cast<long>(floor(dY));
799 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
800 if( aEvent.mnNotchDelta == 0 )
801 aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1;
802 aEvent.mbHorz = FALSE;
803 aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta;
804 if( aEvent.mnScrollLines == 0 )
805 aEvent.mnScrollLines = 1;
806 if( aEvent.mnScrollLines > 15 )
807 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
809 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
815 -(void)keyDown: (NSEvent*)pEvent
819 if( AquaSalFrame::isAlive( mpFrame ) )
821 mpLastEvent = pEvent;
823 mbNeedSpecialKeyHandle = false;
824 mbKeyHandled = false;
826 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
827 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
829 if( ! [self handleKeyDownException: pEvent] )
831 NSArray* pArray = [NSArray arrayWithObject: pEvent];
832 [self interpretKeyEvents: pArray];
835 mbInKeyInput = false;
839 -(MacOSBOOL)handleKeyDownException:(NSEvent*)pEvent
841 // check for a very special set of modified characters
842 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers];
844 if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
846 /* #i103102# key events with command and alternate don't make it through
847 interpretKeyEvents (why ?). Try to dispatch them here first,
848 if not successful continue normally
850 if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask))
851 == (NSAlternateKeyMask | NSCommandKeyMask) )
853 if( [self sendSingleCharacter: mpLastEvent] )
856 unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
857 USHORT nKeyCode = ImplMapCharCode( keyChar );
859 // Caution: should the table grow to more than 5 or 6 entries,
860 // we must consider moving it to a kind of hash map
861 const unsigned int nExceptions = sizeof( aExceptionalKeys ) / sizeof( aExceptionalKeys[0] );
862 for( unsigned int i = 0; i < nExceptions; i++ )
864 if( nKeyCode == aExceptionalKeys[i].nKeyCode &&
865 (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask)
866 == aExceptionalKeys[i].nModifierMask )
868 [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0];
877 -(void)flagsChanged: (NSEvent*)pEvent
881 if( AquaSalFrame::isAlive( mpFrame ) )
883 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
884 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
888 -(void)insertText:(id)aString
892 if( AquaSalFrame::isAlive( mpFrame ) )
894 NSString* pInsert = nil;
895 if( [aString isMemberOfClass: [NSAttributedString class]] )
896 pInsert = [aString string];
901 if( pInsert && ( nLen = [pInsert length] ) > 0 )
903 OUString aInsertString( GetOUString( pInsert ) );
904 // aCharCode initializer is safe since aInsertString will at least contain '\0'
905 sal_Unicode aCharCode = *aInsertString.getStr();
910 ! [self hasMarkedText ]
913 USHORT nKeyCode = ImplMapCharCode( aCharCode );
914 unsigned int nLastModifiers = mpFrame->mnLastModifierFlags;
917 // find out the unmodified key code
920 if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) )
922 // get unmodified string
923 NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers];
924 if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
926 // map the unmodified key code
927 unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
928 nKeyCode = ImplMapCharCode( keyChar );
930 nLastModifiers = [mpLastEvent modifierFlags];
934 // applications and vcl's edit fields ignore key events with ALT
935 // however we're at a place where we know text should be inserted
936 // so it seems we need to strip the Alt modifier here
937 if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask))
938 == NSAlternateKeyMask )
942 [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers];
946 SalExtTextInputEvent aEvent;
947 aEvent.mnTime = mpFrame->mnLastEventTime;
948 aEvent.maText = aInsertString;
949 aEvent.mpTextAttr = NULL;
950 aEvent.mnCursorPos = aInsertString.getLength();
951 aEvent.mnDeltaStart = 0;
952 aEvent.mnCursorFlags = 0;
953 aEvent.mbOnlyCursor = FALSE;
954 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
955 if( AquaSalFrame::isAlive( mpFrame ) )
956 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
961 SalExtTextInputEvent aEvent;
962 aEvent.mnTime = mpFrame->mnLastEventTime;
963 aEvent.maText = String();
964 aEvent.mpTextAttr = NULL;
965 aEvent.mnCursorPos = 0;
966 aEvent.mnDeltaStart = 0;
967 aEvent.mnCursorFlags = 0;
968 aEvent.mbOnlyCursor = FALSE;
969 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
970 if( AquaSalFrame::isAlive( mpFrame ) )
971 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
979 -(void)insertTab: (id)aSender
981 [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0];
984 -(void)insertBacktab: (id)aSender
986 [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0];
989 -(void)moveLeft: (id)aSender
991 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0];
994 -(void)moveLeftAndModifySelection: (id)aSender
996 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask];
999 -(void)moveBackwardAndModifySelection: (id)aSender
1001 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0 modifiers: 0];
1004 -(void)moveRight: (id)aSender
1006 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0];
1009 -(void)moveRightAndModifySelection: (id)aSender
1011 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask];
1014 -(void)moveForwardAndModifySelection: (id)aSender
1016 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0 modifiers: 0];
1019 -(void)moveWordLeft: (id)aSender
1021 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0];
1024 -(void)moveWordBackward: (id)aSender
1026 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0];
1029 -(void)moveWordBackwardAndModifySelection: (id)aSender
1031 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0];
1034 -(void)moveWordLeftAndModifySelection: (id)aSender
1036 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0];
1039 -(void)moveWordRight: (id)aSender
1041 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0];
1044 -(void)moveWordForward: (id)aSender
1046 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0];
1049 -(void)moveWordForwardAndModifySelection: (id)aSender
1051 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0];
1054 -(void)moveWordRightAndModifySelection: (id)aSender
1056 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0];
1059 -(void)moveToEndOfLine: (id)aSender
1061 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0 modifiers: 0];
1064 -(void)moveToEndOfLineAndModifySelection: (id)aSender
1066 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0 modifiers: 0];
1069 -(void)moveToBeginningOfLine: (id)aSender
1071 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0 modifiers: 0];
1074 -(void)moveToBeginningOfLineAndModifySelection: (id)aSender
1076 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0 modifiers: 0];
1079 -(void)moveToEndOfParagraph: (id)aSender
1081 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1084 -(void)moveToEndOfParagraphAndModifySelection: (id)aSender
1086 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1089 -(void)moveParagraphForward: (id)aSender
1091 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1094 -(void)moveParagraphForwardAndModifySelection: (id)aSender
1096 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1099 -(void)moveToBeginningOfParagraph: (id)aSender
1101 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1104 -(void)moveParagraphBackward: (id)aSender
1106 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1109 -(void)moveToBeginningOfParagraphAndModifySelection: (id)aSender
1111 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1114 -(void)moveParagraphBackwardAndModifySelection: (id)aSender
1116 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1119 -(void)moveToEndOfDocument: (id)aSender
1121 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0];
1124 -(void)moveToEndOfDocumentAndModifySelection: (id)aSender
1126 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0 modifiers: 0];
1129 -(void)moveToBeginningOfDocument: (id)aSender
1131 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0];
1134 -(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender
1136 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0];
1139 -(void)moveUp: (id)aSender
1141 [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0];
1144 -(void)moveDown: (id)aSender
1146 [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0];
1149 -(void)insertNewline: (id)aSender
1151 // #i91267# make enter and shift-enter work by evaluating the modifiers
1152 [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags];
1155 -(void)deleteBackward: (id)aSender
1157 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1160 -(void)deleteForward: (id)aSender
1162 [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0];
1165 -(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender
1167 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1170 -(void)deleteWordBackward: (id)aSender
1172 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0 modifiers: 0];
1175 -(void)deleteWordForward: (id)aSender
1177 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0 modifiers: 0];
1180 -(void)deleteToBeginningOfLine: (id)aSender
1182 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0 modifiers: 0];
1185 -(void)deleteToEndOfLine: (id)aSender
1187 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0 modifiers: 0];
1190 -(void)deleteToBeginningOfParagraph: (id)aSender
1192 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1195 -(void)deleteToEndOfParagraph: (id)aSender
1197 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1200 -(void)insertLineBreak: (id)aSender
1202 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0 modifiers: 0];
1205 -(void)insertParagraphSeparator: (id)aSender
1207 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0 modifiers: 0];
1210 -(void)selectWord: (id)aSender
1212 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0 modifiers: 0];
1215 -(void)selectLine: (id)aSender
1217 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0 modifiers: 0];
1220 -(void)selectParagraph: (id)aSender
1222 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0 modifiers: 0];
1225 -(void)selectAll: (id)aSender
1227 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0 modifiers: 0];
1230 -(void)cancelOperation: (id)aSender
1232 [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0];
1235 -(void)noop: (id)aSender
1237 if( ! mbKeyHandled )
1239 if( ! [self sendSingleCharacter:mpLastEvent] )
1241 /* prevent recursion */
1242 if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] )
1244 id pLastSuperEvent = mpLastSuperEvent;
1245 mpLastSuperEvent = mpLastEvent;
1246 [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent];
1247 mpLastSuperEvent = pLastSuperEvent;
1249 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1250 if( it != GetSalData()->maKeyEventAnswer.end() )
1257 -(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar
1259 return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags];
1262 -(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1264 return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] ||
1265 [self sendSingleCharacter: mpLastEvent];
1268 -(MacOSBOOL)sendKeyToFrameDirect: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1273 if( AquaSalFrame::isAlive( mpFrame ) )
1276 aEvent.mnTime = mpFrame->mnLastEventTime;
1277 aEvent.mnCode = nKeyCode | ImplGetModifierMask( nMod );
1278 aEvent.mnCharCode = aChar;
1279 aEvent.mnRepeat = FALSE;
1280 nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent );
1281 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1282 if( it != GetSalData()->maKeyEventAnswer.end() )
1283 it->second = nRet ? true : false;
1284 if( AquaSalFrame::isAlive( mpFrame ) )
1285 mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent );
1287 return nRet ? YES : NO;
1291 -(MacOSBOOL)sendSingleCharacter: (NSEvent *)pEvent
1293 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers];
1295 if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
1297 unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
1298 USHORT nKeyCode = ImplMapCharCode( keyChar );
1301 // don't send unicodes in the private use area
1302 if( keyChar >= 0xf700 && keyChar < 0xf780 )
1304 MacOSBOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags];
1305 mbInKeyInput = false;
1314 // NSTextInput protocol
1315 - (NSArray *)validAttributesForMarkedText
1317 return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil];
1320 - (MacOSBOOL)hasMarkedText
1322 MacOSBOOL bHasMarkedText;
1324 bHasMarkedText = ( mMarkedRange.location != NSNotFound ) &&
1325 ( mMarkedRange.length != 0 );
1326 // hack to check keys like "Control-j"
1329 mbNeedSpecialKeyHandle = true;
1331 return bHasMarkedText;
1334 - (NSRange)markedRange
1336 return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 );
1339 - (NSRange)selectedRange
1341 return mSelectedRange;
1344 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange
1346 if( ![aString isKindOfClass:[NSAttributedString class]] )
1347 aString = [[[NSAttributedString alloc] initWithString:aString] autorelease];
1348 NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange];
1349 if( rangeToReplace.location == NSNotFound )
1351 mMarkedRange = NSMakeRange( selRange.location, [aString length] );
1352 mSelectedRange = NSMakeRange( selRange.location, selRange.length );
1356 mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] );
1357 mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length );
1360 int len = [aString length];
1361 SalExtTextInputEvent aInputEvent;
1362 aInputEvent.mnTime = mpFrame->mnLastEventTime;
1363 aInputEvent.mnDeltaStart = 0;
1364 aInputEvent.mbOnlyCursor = FALSE;
1366 NSString *pString = [aString string];
1367 OUString aInsertString( GetOUString( pString ) );
1368 std::vector<USHORT> aInputFlags = std::vector<USHORT>( std::max( 1, len ), 0 );
1369 for ( int i = 0; i < len; i++ )
1371 unsigned int nUnderlineValue;
1372 NSRange effectiveRange;
1374 effectiveRange = NSMakeRange(i, 1);
1375 nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue];
1377 switch (nUnderlineValue & 0xff) {
1378 case NSUnderlineStyleSingle:
1379 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
1381 case NSUnderlineStyleThick:
1382 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
1384 case NSUnderlineStyleDouble:
1385 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE;
1388 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
1393 aInputEvent.maText = aInsertString;
1394 aInputEvent.mnCursorPos = selRange.location;
1395 aInputEvent.mpTextAttr = &aInputFlags[0];
1396 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1398 aInputEvent.maText = String();
1399 aInputEvent.mnCursorPos = 0;
1400 aInputEvent.mnCursorFlags = 0;
1401 aInputEvent.mpTextAttr = 0;
1402 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1403 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1410 mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
1413 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange
1419 - (unsigned int)characterIndexForPoint:(NSPoint)thePoint
1425 #if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
1426 /* build target 10.5 or greater */
1427 - (NSInteger)conversationIdentifier
1429 /* build target 10.4 */
1430 - (long)conversationIdentifier
1436 - (void)doCommandBySelector:(SEL)aSelector
1438 if( AquaSalFrame::isAlive( mpFrame ) )
1440 if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 &&
1441 aSelector != NULL && [self respondsToSelector: aSelector] )
1443 [self performSelector: aSelector];
1447 [self sendSingleCharacter:mpLastEvent];
1451 mbKeyHandled = true;
1454 - (NSRect)firstRectForCharacterRange:(NSRange)theRange
1456 SalExtTextInputPosEvent aPosEvent;
1457 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent );
1461 rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX;
1462 rect.origin.y = aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines
1463 rect.size.width = aPosEvent.mnWidth;
1464 rect.size.height = aPosEvent.mnHeight;
1466 mpFrame->VCLToCocoa( rect );
1470 -(id)parentAttribute {
1471 return (NSView *) mpFrame -> mpWindow;
1474 -(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext
1476 if ( mpReferenceWrapper == nil ) {
1477 // some frames never become visible ..
1478 Window *pWindow = mpFrame -> GetWindow();
1482 mpReferenceWrapper = new ReferenceWrapper;
1483 mpReferenceWrapper -> rAccessibleContext = pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext();
1484 [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ];
1486 return [ super accessibleContext ];
1489 -(NSView *)viewElementForParent
1491 return (NSView *) mpFrame -> mpWindow;
1494 -(void)registerMouseEventListener: (id)theListener
1496 mpMouseEventListener = theListener;
1499 -(void)unregisterMouseEventListener: (id)theListener
1501 mpMouseEventListener = nil;
1504 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
1506 return [mDraggingDestinationHandler draggingEntered: sender];
1509 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
1511 return [mDraggingDestinationHandler draggingUpdated: sender];
1514 -(void)draggingExited:(id <NSDraggingInfo>)sender
1516 [mDraggingDestinationHandler draggingExited: sender];
1519 -(MacOSBOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
1521 return [mDraggingDestinationHandler prepareForDragOperation: sender];
1524 -(MacOSBOOL)performDragOperation:(id <NSDraggingInfo>)sender
1526 return [mDraggingDestinationHandler performDragOperation: sender];
1529 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
1531 [mDraggingDestinationHandler concludeDragOperation: sender];
1534 -(void)registerDraggingDestinationHandler:(id)theHandler
1536 mDraggingDestinationHandler = theHandler;
1539 -(void)unregisterDraggingDestinationHandler:(id)theHandler
1541 mDraggingDestinationHandler = nil;