xref: /AOO41X/main/winaccessibility/source/UAccCOM/AccActionBase.cpp (revision 5fdc4257b5e43545f8f7841d9e8303d3a99b1714)
1*5fdc4257SSteve Yin /*************************************************************************
2*5fdc4257SSteve Yin  *
3*5fdc4257SSteve Yin  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*5fdc4257SSteve Yin  *
5*5fdc4257SSteve Yin  * Copyright IBM Corporation 2010.
6*5fdc4257SSteve Yin  * Copyright 2000, 2010 Oracle and/or its affiliates.
7*5fdc4257SSteve Yin  *
8*5fdc4257SSteve Yin  * OpenOffice.org - a multi-platform office productivity suite
9*5fdc4257SSteve Yin  *
10*5fdc4257SSteve Yin  * This file is part of OpenOffice.org.
11*5fdc4257SSteve Yin  *
12*5fdc4257SSteve Yin  * OpenOffice.org is free software: you can redistribute it and/or modify
13*5fdc4257SSteve Yin  * it under the terms of the GNU Lesser General Public License version 3
14*5fdc4257SSteve Yin  * only, as published by the Free Software Foundation.
15*5fdc4257SSteve Yin  *
16*5fdc4257SSteve Yin  * OpenOffice.org is distributed in the hope that it will be useful,
17*5fdc4257SSteve Yin  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18*5fdc4257SSteve Yin  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19*5fdc4257SSteve Yin  * GNU Lesser General Public License version 3 for more details
20*5fdc4257SSteve Yin  * (a copy is included in the LICENSE file that accompanied this code).
21*5fdc4257SSteve Yin  *
22*5fdc4257SSteve Yin  * You should have received a copy of the GNU Lesser General Public License
23*5fdc4257SSteve Yin  * version 3 along with OpenOffice.org.  If not, see
24*5fdc4257SSteve Yin  * <http://www.openoffice.org/license.html>
25*5fdc4257SSteve Yin  * for a copy of the LGPLv3 License.
26*5fdc4257SSteve Yin  *
27*5fdc4257SSteve Yin  ************************************************************************/
28*5fdc4257SSteve Yin 
29*5fdc4257SSteve Yin //////////////////////////////////////////////////////////////////////
30*5fdc4257SSteve Yin // AccActionBase.cpp: implementation of the CAccActionBase class.
31*5fdc4257SSteve Yin //////////////////////////////////////////////////////////////////////
32*5fdc4257SSteve Yin #include "stdafx.h"
33*5fdc4257SSteve Yin 
34*5fdc4257SSteve Yin #include "AccActionBase.h"
35*5fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessible.hpp>
36*5fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleStateType.hpp>
37*5fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleRole.hpp>
38*5fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessibleContext.hpp>
39*5fdc4257SSteve Yin 
40*5fdc4257SSteve Yin #include "AccessibleKeyStroke.h"
41*5fdc4257SSteve Yin 
42*5fdc4257SSteve Yin #ifndef __ACCCOMMON_H_
43*5fdc4257SSteve Yin #include "acccommon.h"
44*5fdc4257SSteve Yin #endif
45*5fdc4257SSteve Yin 
46*5fdc4257SSteve Yin using namespace com::sun::star::accessibility::AccessibleRole;
47*5fdc4257SSteve Yin using namespace com::sun::star::accessibility;
48*5fdc4257SSteve Yin using namespace com::sun::star::uno;
49*5fdc4257SSteve Yin using namespace com::sun::star::awt;
50*5fdc4257SSteve Yin 
51*5fdc4257SSteve Yin //////////////////////////////////////////////////////////////////////
52*5fdc4257SSteve Yin // Construction/Destruction
53*5fdc4257SSteve Yin //////////////////////////////////////////////////////////////////////
54*5fdc4257SSteve Yin 
55*5fdc4257SSteve Yin CAccActionBase::CAccActionBase()
56*5fdc4257SSteve Yin {}
57*5fdc4257SSteve Yin 
58*5fdc4257SSteve Yin CAccActionBase::~CAccActionBase()
59*5fdc4257SSteve Yin {}
60*5fdc4257SSteve Yin 
61*5fdc4257SSteve Yin /**
62*5fdc4257SSteve Yin  * Helper function used for getting default action by UNO role.
63*5fdc4257SSteve Yin  *
64*5fdc4257SSteve Yin  * @param    pRContext    UNO context interface pointer.
65*5fdc4257SSteve Yin  * @param    pRet         the corresponding string to be returned.
66*5fdc4257SSteve Yin  */
67*5fdc4257SSteve Yin void GetDfActionByUNORole(XAccessibleContext* pRContext, BSTR* pRet)
68*5fdc4257SSteve Yin {
69*5fdc4257SSteve Yin     // #CHECK#
70*5fdc4257SSteve Yin     if(pRContext == NULL || pRet == NULL)
71*5fdc4257SSteve Yin     {
72*5fdc4257SSteve Yin         return;
73*5fdc4257SSteve Yin     }
74*5fdc4257SSteve Yin 
75*5fdc4257SSteve Yin     long Role = pRContext->getAccessibleRole();
76*5fdc4257SSteve Yin 
77*5fdc4257SSteve Yin     switch(Role)
78*5fdc4257SSteve Yin     {
79*5fdc4257SSteve Yin     case PUSH_BUTTON:
80*5fdc4257SSteve Yin         *pRet = ::SysAllocString(PRESS);
81*5fdc4257SSteve Yin         break;
82*5fdc4257SSteve Yin     case RADIO_BUTTON:
83*5fdc4257SSteve Yin     case MENU_ITEM:
84*5fdc4257SSteve Yin     case LIST_ITEM:
85*5fdc4257SSteve Yin         *pRet = ::SysAllocString(SELECT);
86*5fdc4257SSteve Yin         break;
87*5fdc4257SSteve Yin     case CHECK_BOX:
88*5fdc4257SSteve Yin         {
89*5fdc4257SSteve Yin             Reference< XAccessibleStateSet > pRState = pRContext->getAccessibleStateSet();
90*5fdc4257SSteve Yin             if( !pRState.is() )
91*5fdc4257SSteve Yin             {
92*5fdc4257SSteve Yin                 return;
93*5fdc4257SSteve Yin             }
94*5fdc4257SSteve Yin 
95*5fdc4257SSteve Yin             Sequence<short> pStates = pRState->getStates();
96*5fdc4257SSteve Yin             int count = pStates.getLength();
97*5fdc4257SSteve Yin             *pRet = ::SysAllocString(CHECK);
98*5fdc4257SSteve Yin             for( int iIndex = 0;iIndex < count;iIndex++ )
99*5fdc4257SSteve Yin             {
100*5fdc4257SSteve Yin                 if( pStates[iIndex] == AccessibleStateType::CHECKED )
101*5fdc4257SSteve Yin                 {
102*5fdc4257SSteve Yin                     SAFE_SYSFREESTRING(*pRet);
103*5fdc4257SSteve Yin                     *pRet = ::SysAllocString(UNCHECK);
104*5fdc4257SSteve Yin                     break;
105*5fdc4257SSteve Yin                 }
106*5fdc4257SSteve Yin             }
107*5fdc4257SSteve Yin             break;
108*5fdc4257SSteve Yin         }
109*5fdc4257SSteve Yin     }
110*5fdc4257SSteve Yin }
111*5fdc4257SSteve Yin 
112*5fdc4257SSteve Yin /**
113*5fdc4257SSteve Yin  * Returns the number of action.
114*5fdc4257SSteve Yin  *
115*5fdc4257SSteve Yin  * @param    nActions    the number of action.
116*5fdc4257SSteve Yin  */
117*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::nActions(/*[out,retval]*/long* nActions)
118*5fdc4257SSteve Yin {
119*5fdc4257SSteve Yin 
120*5fdc4257SSteve Yin 	CHECK_ENABLE_INF
121*5fdc4257SSteve Yin 
122*5fdc4257SSteve Yin     ENTER_PROTECTED_BLOCK
123*5fdc4257SSteve Yin 
124*5fdc4257SSteve Yin     // #CHECK#
125*5fdc4257SSteve Yin     if( pRXAct.is() && nActions != NULL )
126*5fdc4257SSteve Yin     {
127*5fdc4257SSteve Yin         *nActions = GetXInterface()->getAccessibleActionCount();
128*5fdc4257SSteve Yin         return S_OK;
129*5fdc4257SSteve Yin     }
130*5fdc4257SSteve Yin     *nActions = 0;
131*5fdc4257SSteve Yin 
132*5fdc4257SSteve Yin     return S_OK;
133*5fdc4257SSteve Yin 
134*5fdc4257SSteve Yin     LEAVE_PROTECTED_BLOCK
135*5fdc4257SSteve Yin }
136*5fdc4257SSteve Yin 
137*5fdc4257SSteve Yin /**
138*5fdc4257SSteve Yin  * Performs specified action on the object.
139*5fdc4257SSteve Yin  *
140*5fdc4257SSteve Yin  * @param    actionIndex    the index of action.
141*5fdc4257SSteve Yin  */
142*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::doAction(/* [in] */ long actionIndex)
143*5fdc4257SSteve Yin {
144*5fdc4257SSteve Yin 
145*5fdc4257SSteve Yin 	CHECK_ENABLE_INF
146*5fdc4257SSteve Yin 
147*5fdc4257SSteve Yin     ENTER_PROTECTED_BLOCK
148*5fdc4257SSteve Yin 
149*5fdc4257SSteve Yin     if( pRXAct.is() )
150*5fdc4257SSteve Yin     {
151*5fdc4257SSteve Yin         return GetXInterface()->doAccessibleAction( actionIndex )?S_OK:E_FAIL;
152*5fdc4257SSteve Yin     }
153*5fdc4257SSteve Yin     return E_FAIL;
154*5fdc4257SSteve Yin 
155*5fdc4257SSteve Yin     LEAVE_PROTECTED_BLOCK
156*5fdc4257SSteve Yin }
157*5fdc4257SSteve Yin 
158*5fdc4257SSteve Yin /**
159*5fdc4257SSteve Yin  * Gets description of specified action.
160*5fdc4257SSteve Yin  *
161*5fdc4257SSteve Yin  * @param    actionIndex    the index of action.
162*5fdc4257SSteve Yin  * @param    description    the description string of the specified action.
163*5fdc4257SSteve Yin  */
164*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_description(long actionIndex,BSTR __RPC_FAR *description)
165*5fdc4257SSteve Yin {
166*5fdc4257SSteve Yin 
167*5fdc4257SSteve Yin 	CHECK_ENABLE_INF
168*5fdc4257SSteve Yin 
169*5fdc4257SSteve Yin     ENTER_PROTECTED_BLOCK
170*5fdc4257SSteve Yin 
171*5fdc4257SSteve Yin     // #CHECK#
172*5fdc4257SSteve Yin     if(description == NULL)
173*5fdc4257SSteve Yin         return E_INVALIDARG;
174*5fdc4257SSteve Yin 
175*5fdc4257SSteve Yin     // #CHECK XInterface#
176*5fdc4257SSteve Yin     if(!pRXAct.is())
177*5fdc4257SSteve Yin         return E_FAIL;
178*5fdc4257SSteve Yin 
179*5fdc4257SSteve Yin     ::rtl::OUString ouStr = GetXInterface()->getAccessibleActionDescription(actionIndex);
180*5fdc4257SSteve Yin     // #CHECK#
181*5fdc4257SSteve Yin 
182*5fdc4257SSteve Yin     SAFE_SYSFREESTRING(*description);
183*5fdc4257SSteve Yin     *description = SysAllocString((OLECHAR*)ouStr.getStr());
184*5fdc4257SSteve Yin 
185*5fdc4257SSteve Yin     return S_OK;
186*5fdc4257SSteve Yin 
187*5fdc4257SSteve Yin     LEAVE_PROTECTED_BLOCK
188*5fdc4257SSteve Yin }
189*5fdc4257SSteve Yin 
190*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_name( long, BSTR __RPC_FAR *)
191*5fdc4257SSteve Yin {
192*5fdc4257SSteve Yin     return E_NOTIMPL;
193*5fdc4257SSteve Yin }
194*5fdc4257SSteve Yin 
195*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_localizedName( long, BSTR __RPC_FAR *)
196*5fdc4257SSteve Yin {
197*5fdc4257SSteve Yin     return E_NOTIMPL;
198*5fdc4257SSteve Yin }
199*5fdc4257SSteve Yin 
200*5fdc4257SSteve Yin /**
201*5fdc4257SSteve Yin  * Returns key binding object (if any) associated with specified action
202*5fdc4257SSteve Yin  * key binding is string.
203*5fdc4257SSteve Yin  * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut).
204*5fdc4257SSteve Yin  *
205*5fdc4257SSteve Yin  * @param    actionIndex    the index of action.
206*5fdc4257SSteve Yin  * @param    nMaxBinding    the max number of key binding.
207*5fdc4257SSteve Yin  * @param    keyBinding     the key binding array.
208*5fdc4257SSteve Yin  * @param    nBinding       the actual number of key binding returned.
209*5fdc4257SSteve Yin  */
210*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_keyBinding(
211*5fdc4257SSteve Yin     /* [in] */ long actionIndex,
212*5fdc4257SSteve Yin     /* [in] */ long,
213*5fdc4257SSteve Yin     /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding,
214*5fdc4257SSteve Yin     /* [retval][out] */ long __RPC_FAR *nBinding)
215*5fdc4257SSteve Yin {
216*5fdc4257SSteve Yin 
217*5fdc4257SSteve Yin 	CHECK_ENABLE_INF
218*5fdc4257SSteve Yin 
219*5fdc4257SSteve Yin     ENTER_PROTECTED_BLOCK
220*5fdc4257SSteve Yin 
221*5fdc4257SSteve Yin     if( !keyBinding || !nBinding)
222*5fdc4257SSteve Yin         return E_INVALIDARG;
223*5fdc4257SSteve Yin 
224*5fdc4257SSteve Yin     if( !pRXAct.is() )
225*5fdc4257SSteve Yin         return E_FAIL;
226*5fdc4257SSteve Yin 
227*5fdc4257SSteve Yin     Reference< XAccessibleKeyBinding > binding = GetXInterface()->getAccessibleActionKeyBinding(actionIndex);
228*5fdc4257SSteve Yin     if( !binding.is() )
229*5fdc4257SSteve Yin         return E_FAIL;
230*5fdc4257SSteve Yin 
231*5fdc4257SSteve Yin     long nCount = (binding.get())->getAccessibleKeyBindingCount();
232*5fdc4257SSteve Yin 
233*5fdc4257SSteve Yin     OLECHAR wString[64];
234*5fdc4257SSteve Yin 
235*5fdc4257SSteve Yin     *keyBinding = (BSTR*)::CoTaskMemAlloc(nCount*sizeof(BSTR));
236*5fdc4257SSteve Yin 
237*5fdc4257SSteve Yin     // #CHECK Memory Allocation#
238*5fdc4257SSteve Yin     if(*keyBinding == NULL)
239*5fdc4257SSteve Yin         return E_FAIL;
240*5fdc4257SSteve Yin 
241*5fdc4257SSteve Yin     for( int index = 0;index < nCount;index++ )
242*5fdc4257SSteve Yin     {
243*5fdc4257SSteve Yin         memset(wString,0,sizeof(wString));
244*5fdc4257SSteve Yin         GetkeyBindingStrByXkeyBinding( (binding.get())->getAccessibleKeyBinding(index), wString );
245*5fdc4257SSteve Yin 
246*5fdc4257SSteve Yin         (*keyBinding)[index] = SysAllocString(wString);
247*5fdc4257SSteve Yin     }
248*5fdc4257SSteve Yin 
249*5fdc4257SSteve Yin     *nBinding = nCount;
250*5fdc4257SSteve Yin     return S_OK;
251*5fdc4257SSteve Yin 
252*5fdc4257SSteve Yin     LEAVE_PROTECTED_BLOCK
253*5fdc4257SSteve Yin }
254*5fdc4257SSteve Yin 
255*5fdc4257SSteve Yin /**
256*5fdc4257SSteve Yin  * Overide of IUNOXWrapper.
257*5fdc4257SSteve Yin  *
258*5fdc4257SSteve Yin  * @param    pXInterface    the pointer of UNO interface.
259*5fdc4257SSteve Yin  */
260*5fdc4257SSteve Yin STDMETHODIMP CAccActionBase::put_XInterface(long pXInterface)
261*5fdc4257SSteve Yin {
262*5fdc4257SSteve Yin 
263*5fdc4257SSteve Yin 
264*5fdc4257SSteve Yin     ENTER_PROTECTED_BLOCK
265*5fdc4257SSteve Yin 
266*5fdc4257SSteve Yin     CUNOXWrapper::put_XInterface(pXInterface);
267*5fdc4257SSteve Yin 
268*5fdc4257SSteve Yin     //special query.
269*5fdc4257SSteve Yin     if(pUNOInterface == NULL)
270*5fdc4257SSteve Yin         return E_FAIL;
271*5fdc4257SSteve Yin     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
272*5fdc4257SSteve Yin     if( !pRContext.is() )
273*5fdc4257SSteve Yin         return E_FAIL;
274*5fdc4257SSteve Yin 
275*5fdc4257SSteve Yin     Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY);
276*5fdc4257SSteve Yin     if( !pRXI.is() )
277*5fdc4257SSteve Yin         pRXAct = NULL;
278*5fdc4257SSteve Yin     else
279*5fdc4257SSteve Yin         pRXAct = pRXI.get();
280*5fdc4257SSteve Yin     return S_OK;
281*5fdc4257SSteve Yin 
282*5fdc4257SSteve Yin     LEAVE_PROTECTED_BLOCK
283*5fdc4257SSteve Yin }
284*5fdc4257SSteve Yin 
285*5fdc4257SSteve Yin /**
286*5fdc4257SSteve Yin  * Helper function used for converting keybinding to string.
287*5fdc4257SSteve Yin  *
288*5fdc4257SSteve Yin  * @param    keySet    the key stroke sequence.
289*5fdc4257SSteve Yin  * @param    pString   the output keybinding string.
290*5fdc4257SSteve Yin  */
291*5fdc4257SSteve Yin void CAccActionBase::GetkeyBindingStrByXkeyBinding( const Sequence< KeyStroke > &keySet, OLECHAR* pString )
292*5fdc4257SSteve Yin {
293*5fdc4257SSteve Yin     // #CHECK#
294*5fdc4257SSteve Yin     if(pString == NULL)
295*5fdc4257SSteve Yin         return;
296*5fdc4257SSteve Yin 
297*5fdc4257SSteve Yin     for( int iIndex = 0;iIndex < keySet.getLength();iIndex++ )
298*5fdc4257SSteve Yin     {
299*5fdc4257SSteve Yin         KeyStroke stroke = keySet[iIndex];
300*5fdc4257SSteve Yin         OLECHAR wString[64] = {NULL};
301*5fdc4257SSteve Yin         if(iIndex>0)
302*5fdc4257SSteve Yin             wcscat( wString, OLESTR("  ") );
303*5fdc4257SSteve Yin         if((stroke.Modifiers & MODIFIER_SHIFT) == MODIFIER_SHIFT)
304*5fdc4257SSteve Yin             wcscat( wString, OLESTR("Shift+") );
305*5fdc4257SSteve Yin         if((stroke.Modifiers & MODIFIER_CTRL) == MODIFIER_CTRL)
306*5fdc4257SSteve Yin             wcscat( wString, OLESTR("Ctrl+") );
307*5fdc4257SSteve Yin         if((stroke.Modifiers & MODIFIER_ALT) == MODIFIER_ALT)
308*5fdc4257SSteve Yin             wcscat( wString, OLESTR("Alt+") );
309*5fdc4257SSteve Yin         if(stroke.KeyCode)
310*5fdc4257SSteve Yin         {
311*5fdc4257SSteve Yin             OLECHAR* pChar = getOLECHARFromKeyCode(stroke.KeyCode);
312*5fdc4257SSteve Yin             if(pChar != NULL)
313*5fdc4257SSteve Yin                 wcscat( wString, pChar );
314*5fdc4257SSteve Yin             else if (stroke.KeyCode <= 255)
315*5fdc4257SSteve Yin             {
316*5fdc4257SSteve Yin                 OLECHAR pChar[4] = {NULL};
317*5fdc4257SSteve Yin                 swprintf( pChar, L"%c", stroke.KeyCode);
318*5fdc4257SSteve Yin                 wcscat( wString, pChar);
319*5fdc4257SSteve Yin             }
320*5fdc4257SSteve Yin             else
321*5fdc4257SSteve Yin             {
322*5fdc4257SSteve Yin                 OLECHAR pChar[4] = {NULL};
323*5fdc4257SSteve Yin                 swprintf( pChar, L"%d", stroke.KeyCode);
324*5fdc4257SSteve Yin                 wcscat( wString, pChar);
325*5fdc4257SSteve Yin             }
326*5fdc4257SSteve Yin         }
327*5fdc4257SSteve Yin 
328*5fdc4257SSteve Yin         wcscat( pString, wString);
329*5fdc4257SSteve Yin     }
330*5fdc4257SSteve Yin }
331*5fdc4257SSteve Yin 
332*5fdc4257SSteve Yin /**
333*5fdc4257SSteve Yin  * Helper function used for converting key code to ole string.
334*5fdc4257SSteve Yin  *
335*5fdc4257SSteve Yin  * @param    key    the key code.
336*5fdc4257SSteve Yin  */
337*5fdc4257SSteve Yin OLECHAR* CAccActionBase::getOLECHARFromKeyCode(long key)
338*5fdc4257SSteve Yin {
339*5fdc4257SSteve Yin     static struct keyMap
340*5fdc4257SSteve Yin     {
341*5fdc4257SSteve Yin         int keyCode;
342*5fdc4257SSteve Yin         OLECHAR* key;
343*5fdc4257SSteve Yin     }
344*5fdc4257SSteve Yin     map[] =
345*5fdc4257SSteve Yin         {
346*5fdc4257SSteve Yin             {MODIFIER_SHIFT, L"SHIFT" },
347*5fdc4257SSteve Yin             {MODIFIER_CTRL, L"CTRL" },
348*5fdc4257SSteve Yin             {MODIFIER_ALT, L"ALT" },
349*5fdc4257SSteve Yin             CODEENTRY(NUM0),CODEENTRY(NUM1),CODEENTRY(NUM2),CODEENTRY(NUM3),CODEENTRY(NUM4),CODEENTRY(NUM5),
350*5fdc4257SSteve Yin             CODEENTRY(NUM6),CODEENTRY(NUM7),CODEENTRY(NUM8),CODEENTRY(NUM9),
351*5fdc4257SSteve Yin             CODEENTRY(A),CODEENTRY(B),CODEENTRY(C),CODEENTRY(D),CODEENTRY(E),CODEENTRY(F),
352*5fdc4257SSteve Yin             CODEENTRY(G),CODEENTRY(H),CODEENTRY(I),CODEENTRY(J),CODEENTRY(K),CODEENTRY(L),
353*5fdc4257SSteve Yin             CODEENTRY(M),CODEENTRY(N),CODEENTRY(O),CODEENTRY(P),CODEENTRY(Q),CODEENTRY(R),
354*5fdc4257SSteve Yin             CODEENTRY(S),CODEENTRY(T),CODEENTRY(U),CODEENTRY(V),CODEENTRY(W),CODEENTRY(X),
355*5fdc4257SSteve Yin             CODEENTRY(Y),CODEENTRY(Z),
356*5fdc4257SSteve Yin             CODEENTRY(F1),CODEENTRY(F2),CODEENTRY(F3),CODEENTRY(F4),CODEENTRY(F5),CODEENTRY(F6),
357*5fdc4257SSteve Yin             CODEENTRY(F7),CODEENTRY(F8),CODEENTRY(F9),CODEENTRY(F10),CODEENTRY(F11),CODEENTRY(F12),
358*5fdc4257SSteve Yin             CODEENTRY(F13),CODEENTRY(F14),CODEENTRY(F15),CODEENTRY(F16),CODEENTRY(F17),CODEENTRY(F18),
359*5fdc4257SSteve Yin             CODEENTRY(F19),CODEENTRY(F20),CODEENTRY(F21),CODEENTRY(F22),CODEENTRY(F23),CODEENTRY(F24),
360*5fdc4257SSteve Yin             CODEENTRY(F25),CODEENTRY(F26),
361*5fdc4257SSteve Yin 
362*5fdc4257SSteve Yin             { KEYCODE_DOWN, L"DOWN" },
363*5fdc4257SSteve Yin             { KEYCODE_UP, L"UP" },
364*5fdc4257SSteve Yin             { KEYCODE_LEFT, L"LEFT" },
365*5fdc4257SSteve Yin             { KEYCODE_RIGHT, L"RIGHT" },
366*5fdc4257SSteve Yin             { KEYCODE_HOME, L"HOME" },
367*5fdc4257SSteve Yin             { KEYCODE_END, L"END" },
368*5fdc4257SSteve Yin             { KEYCODE_PAGEUP, L"PAGEUP" },
369*5fdc4257SSteve Yin             { KEYCODE_PAGEDOWN, L"PAGEDOWN" },
370*5fdc4257SSteve Yin             { KEYCODE_RETURN, L"RETURN" },
371*5fdc4257SSteve Yin             { KEYCODE_ESCAPE, L"ESCAPE" },
372*5fdc4257SSteve Yin             { KEYCODE_TAB, L"TAB" },
373*5fdc4257SSteve Yin             { KEYCODE_BACKSPACE, L"BACKSPACE" },
374*5fdc4257SSteve Yin             { KEYCODE_SPACE, L"SPACE" },
375*5fdc4257SSteve Yin             { KEYCODE_INSERT, L"INSERT" },
376*5fdc4257SSteve Yin             { KEYCODE_DELETE, L"DELETE" },
377*5fdc4257SSteve Yin             { KEYCODE_ADD, L"ADD" },
378*5fdc4257SSteve Yin             { KEYCODE_SUBTRACT, L"SUBTRACT" },
379*5fdc4257SSteve Yin             { KEYCODE_MULTIPLY, L"MULTIPLY" },
380*5fdc4257SSteve Yin             { KEYCODE_DIVIDE, L"DIVIDE" },
381*5fdc4257SSteve Yin             { KEYCODE_POINT, L"POINT" },
382*5fdc4257SSteve Yin             { KEYCODE_COMMA, L"COMMA" },
383*5fdc4257SSteve Yin             { KEYCODE_LESS, L"LESS" },
384*5fdc4257SSteve Yin             { KEYCODE_GREATER, L"GREATER" },
385*5fdc4257SSteve Yin             { KEYCODE_EQUAL, L"EQUAL" },
386*5fdc4257SSteve Yin             { KEYCODE_OPEN, L"OPEN" },
387*5fdc4257SSteve Yin             { KEYCODE_CUT, L"CUT" },
388*5fdc4257SSteve Yin             { KEYCODE_COPY, L"COPY" },
389*5fdc4257SSteve Yin             { KEYCODE_PASTE, L"PASTE" },
390*5fdc4257SSteve Yin             { KEYCODE_UNDO, L"UNDO" },
391*5fdc4257SSteve Yin             { KEYCODE_REPEAT, L"REPEAT" },
392*5fdc4257SSteve Yin             { KEYCODE_FIND, L"FIND" },
393*5fdc4257SSteve Yin             { KEYCODE_PROPERTIES, L"PROPERTIES" },
394*5fdc4257SSteve Yin             { KEYCODE_FRONT, L"FRONT" },
395*5fdc4257SSteve Yin             { KEYCODE_CONTEXTMENU, L"CONTEXTMENU" },
396*5fdc4257SSteve Yin             { KEYCODE_HELP, L"HELP" },
397*5fdc4257SSteve Yin         };
398*5fdc4257SSteve Yin     static long nCount = countof(map);
399*5fdc4257SSteve Yin 
400*5fdc4257SSteve Yin     long min = 0;
401*5fdc4257SSteve Yin     long max = nCount-1;
402*5fdc4257SSteve Yin     long mid = nCount/2;
403*5fdc4257SSteve Yin     while(min<max)
404*5fdc4257SSteve Yin     {
405*5fdc4257SSteve Yin         if(key<map[mid].keyCode)
406*5fdc4257SSteve Yin             max = mid-1;
407*5fdc4257SSteve Yin         else if(key>map[mid].keyCode)
408*5fdc4257SSteve Yin             min = mid+1;
409*5fdc4257SSteve Yin         else
410*5fdc4257SSteve Yin             break;
411*5fdc4257SSteve Yin         mid = (min+max)/2;
412*5fdc4257SSteve Yin     }
413*5fdc4257SSteve Yin 
414*5fdc4257SSteve Yin     if(key == map[mid].keyCode)
415*5fdc4257SSteve Yin     {
416*5fdc4257SSteve Yin         return map[mid].key;
417*5fdc4257SSteve Yin     }
418*5fdc4257SSteve Yin     else
419*5fdc4257SSteve Yin     {
420*5fdc4257SSteve Yin         return NULL;
421*5fdc4257SSteve Yin     }
422*5fdc4257SSteve Yin }
423*5fdc4257SSteve Yin 
424