OMXFocus.cpp revision 72bac2af47f73167bd288bc7278e5496ccabe6f4
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18/**
19* @file OMXFocus.cpp
20*
21* This file contains functionality for handling focus configurations.
22*
23*/
24
25#undef LOG_TAG
26
27#define LOG_TAG "CameraHAL"
28
29#include "CameraHal.h"
30#include "OMXCameraAdapter.h"
31#include "ErrorUtils.h"
32
33#define TOUCH_FOCUS_RANGE 0xFF
34#define AF_CALLBACK_TIMEOUT 10000000 //10 seconds timeout
35
36namespace android {
37
38status_t OMXCameraAdapter::setParametersFocus(const CameraParameters &params,
39                                              BaseCameraAdapter::AdapterState state)
40{
41    status_t ret = NO_ERROR;
42    const char *str = NULL;
43    Mutex::Autolock lock(mFocusAreasLock);
44
45    LOG_FUNCTION_NAME;
46
47    str = params.get(CameraParameters::KEY_FOCUS_AREAS);
48    mFocusAreas.clear();
49    if ( NULL != str ) {
50        ret = CameraArea::parseFocusArea(str, ( strlen(str) + 1 ), mFocusAreas);
51    }
52
53    if ( NO_ERROR == ret ) {
54        if ( MAX_FOCUS_AREAS < mFocusAreas.size() ) {
55            CAMHAL_LOGEB("Focus areas supported %d, focus areas set %d",
56                         MAX_FOCUS_AREAS,
57                         mFocusAreas.size());
58            ret = -EINVAL;
59        }
60    }
61
62    LOG_FUNCTION_NAME;
63
64    return ret;
65}
66
67status_t OMXCameraAdapter::doAutoFocus()
68{
69    status_t ret = NO_ERROR;
70    OMX_ERRORTYPE eError = OMX_ErrorNone;
71    OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
72    OMX_PARAM_FOCUSSTATUSTYPE focusStatus;
73
74    LOG_FUNCTION_NAME;
75
76    if ( OMX_StateExecuting != mComponentState )
77        {
78        CAMHAL_LOGEA("OMX component not in executing state");
79        returnFocusStatus(false);
80        return NO_INIT;
81        }
82
83    if ( 0 != mDoAFSem.Count() )
84        {
85        CAMHAL_LOGEB("Error mDoAFSem semaphore count %d", mDoAFSem.Count());
86        return NO_INIT;
87        }
88
89    // If the app calls autoFocus, the camera will stop sending face callbacks.
90    pauseFaceDetection(true);
91
92    OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
93    focusControl.eFocusControl = ( OMX_IMAGE_FOCUSCONTROLTYPE ) mParameters3A.Focus;
94
95    //In case we have CAF running we should first check the AF status.
96    //If it has managed to lock, then do as usual and return status
97    //immediately. If lock is not available, then switch temporarily
98    //to 'autolock' and do normal AF.
99    if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAuto ) {
100//FIXME: The CAF seems to return focus failure all the time.
101// Probably this is tuning related, disable this until the
102// MMS IQ team fixes it
103#if 0
104        ret = checkFocus(&focusStatus);
105#else
106        ret = NO_ERROR;
107        focusStatus.eFocusStatus = OMX_FocusStatusReached;
108#endif
109        if ( NO_ERROR != ret ) {
110            CAMHAL_LOGEB("Focus status check failed 0x%x!", ret);
111            return ret;
112        } else {
113            CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus);
114        }
115
116        if ( OMX_FocusStatusReached != focusStatus.eFocusStatus ) {
117            focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock;
118        }
119    }
120
121    if ( ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
122         ( focusControl.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
123                 OMX_IMAGE_FocusControlAutoInfinity ) ) {
124
125        ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
126                                    (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
127                                    OMX_ALL,
128                                    OMX_IndexConfigCommonFocusStatus,
129                                    mDoAFSem);
130
131        if ( NO_ERROR == ret ) {
132            ret = setFocusCallback(true);
133        }
134
135    }
136
137    eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
138                            OMX_IndexConfigFocusControl,
139                            &focusControl);
140
141    if ( OMX_ErrorNone != eError ) {
142        CAMHAL_LOGEB("Error while starting focus 0x%x", eError);
143        return INVALID_OPERATION;
144    } else {
145        CAMHAL_LOGDA("Autofocus started successfully");
146    }
147
148    if ( ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
149         ( focusControl.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
150                 OMX_IMAGE_FocusControlAutoInfinity ) ) {
151        ret = mDoAFSem.WaitTimeout(AF_CALLBACK_TIMEOUT);
152        //Disable auto focus callback from Ducati
153        setFocusCallback(false);
154        //Signal a dummy AF event so that in case the callback from ducati
155        //does come then it doesnt crash after
156        //exiting this function since eventSem will go out of scope.
157        if(ret != NO_ERROR) {
158            CAMHAL_LOGEA("Autofocus callback timeout expired");
159            SignalEvent(mCameraAdapterParameters.mHandleComp,
160                                        (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
161                                        OMX_ALL,
162                                        OMX_IndexConfigCommonFocusStatus,
163                                        NULL );
164            returnFocusStatus(true);
165        } else {
166            CAMHAL_LOGDA("Autofocus callback received");
167            ret = returnFocusStatus(false);
168        }
169
170    } else {
171        if ( NO_ERROR == ret ) {
172            ret = returnFocusStatus(false);
173        }
174    }
175
176    //Restore CAF if needed
177    if ( ( mParameters3A.Focus == OMX_IMAGE_FocusControlAuto ) &&
178         ( focusControl.eFocusControl == OMX_IMAGE_FocusControlAutoLock ) ) {
179        mPending3Asettings |= SetFocus;
180    }
181
182    LOG_FUNCTION_NAME_EXIT;
183
184    return ret;
185}
186
187status_t OMXCameraAdapter::stopAutoFocus()
188{
189    status_t ret = NO_ERROR;
190    OMX_ERRORTYPE eError = OMX_ErrorNone;
191    OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
192
193    LOG_FUNCTION_NAME;
194
195    if ( OMX_StateExecuting != mComponentState )
196        {
197        CAMHAL_LOGEA("OMX component not in executing state");
198        return NO_INIT;
199        }
200
201    if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) {
202        // No need to stop focus if we are in infinity mode. Nothing to stop.
203        return NO_ERROR;
204    }
205
206    if ( NO_ERROR == ret )
207       {
208       //Disable the callback first
209       ret = setFocusCallback(false);
210       }
211
212    if ( NO_ERROR == ret )
213        {
214        OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
215        focusControl.eFocusControl = OMX_IMAGE_FocusControlOff;
216
217        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
218                                OMX_IndexConfigFocusControl,
219                                &focusControl);
220        if ( OMX_ErrorNone != eError )
221            {
222            CAMHAL_LOGEB("Error while stopping focus 0x%x", eError);
223            return ErrorUtils::omxToAndroidError(eError);
224            }
225        }
226
227    //Query current focus distance after AF is complete
228    updateFocusDistances(mParameters);
229
230    LOG_FUNCTION_NAME_EXIT;
231
232    return ret;
233}
234
235status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode)
236{;
237    OMX_ERRORTYPE eError = OMX_ErrorNone;
238
239    LOG_FUNCTION_NAME;
240
241    if ( OMX_StateInvalid == mComponentState ) {
242        CAMHAL_LOGEA("OMX component is in invalid state");
243        return NO_INIT;
244    }
245
246    OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
247    focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
248
249    eError =  OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
250                            OMX_IndexConfigFocusControl,
251                            &focusMode);
252
253    if ( OMX_ErrorNone != eError ) {
254        CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError);
255    }
256
257    LOG_FUNCTION_NAME_EXIT;
258
259    return ErrorUtils::omxToAndroidError(eError);
260}
261
262status_t OMXCameraAdapter::cancelAutoFocus()
263{
264    status_t ret = NO_ERROR;
265    OMX_ERRORTYPE eError = OMX_ErrorNone;
266    OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode;
267
268    LOG_FUNCTION_NAME;
269    // Unlock 3A locks since they were locked by AF
270    if( set3ALock(OMX_FALSE) != NO_ERROR) {
271      CAMHAL_LOGEA("Error Unlocking 3A locks");
272    }
273    else{
274      CAMHAL_LOGDA("AE/AWB unlocked successfully");
275    }
276
277    ret = getFocusMode(focusMode);
278    if ( NO_ERROR != ret ) {
279        return ret;
280    }
281
282    //Stop the AF only for modes other than CAF  or Inifinity
283    if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
284         ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
285                 OMX_IMAGE_FocusControlAutoInfinity ) ) {
286        stopAutoFocus();
287        //Signal a dummy AF event so that in case the callback from ducati
288        //does come then it doesnt crash after
289        //exiting this function since eventSem will go out of scope.
290        ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
291                                    (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
292                                    OMX_ALL,
293                                    OMX_IndexConfigCommonFocusStatus,
294                                    NULL );
295    }
296
297    // If the apps call #cancelAutoFocus()}, the face callbacks will also resume.
298    pauseFaceDetection(false);
299
300    LOG_FUNCTION_NAME_EXIT;
301
302    return ret;
303
304}
305
306status_t OMXCameraAdapter::setFocusCallback(bool enabled)
307{
308    status_t ret = NO_ERROR;
309    OMX_ERRORTYPE eError = OMX_ErrorNone;
310    OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback;
311
312    LOG_FUNCTION_NAME;
313
314    if ( OMX_StateExecuting != mComponentState )
315        {
316        CAMHAL_LOGEA("OMX component not in executing state");
317        ret = -1;
318        }
319
320    if ( NO_ERROR == ret )
321        {
322
323        OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
324        focusRequstCallback.nPortIndex = OMX_ALL;
325        focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus;
326
327        if ( enabled )
328            {
329            focusRequstCallback.bEnable = OMX_TRUE;
330            }
331        else
332            {
333            focusRequstCallback.bEnable = OMX_FALSE;
334            }
335
336        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
337                                (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
338                                &focusRequstCallback);
339        if ( OMX_ErrorNone != eError )
340            {
341            CAMHAL_LOGEB("Error registering focus callback 0x%x", eError);
342            ret = -1;
343            }
344        else
345            {
346            CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully",
347                         OMX_IndexConfigCommonFocusStatus);
348            }
349        }
350
351    LOG_FUNCTION_NAME_EXIT;
352
353    return ret;
354}
355
356status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached)
357{
358    status_t ret = NO_ERROR;
359    OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus;
360    bool focusStatus = false;
361    BaseCameraAdapter::AdapterState state;
362    BaseCameraAdapter::getState(state);
363
364    LOG_FUNCTION_NAME;
365
366    OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
367
368    if( ( AF_ACTIVE & state ) != AF_ACTIVE )
369       {
370        /// We don't send focus callback if focus was not started
371       return NO_ERROR;
372       }
373
374    if ( NO_ERROR == ret )
375        {
376
377        if ( !timeoutReached )
378            {
379            ret = checkFocus(&eFocusStatus);
380
381            if ( NO_ERROR != ret )
382                {
383                CAMHAL_LOGEA("Focus status check failed!");
384                }
385            }
386        }
387
388    if ( NO_ERROR == ret )
389        {
390
391        if ( timeoutReached )
392            {
393            focusStatus = false;
394            }
395        ///FIXME: The ducati seems to return focus as false always if continuous focus is enabled
396        ///So, return focus as locked always until this is fixed.
397        else if(mParameters3A.Focus == OMX_IMAGE_FocusControlAuto )
398            {
399            focusStatus = true;
400            }
401        else
402            {
403            switch (eFocusStatus.eFocusStatus)
404                {
405                    case OMX_FocusStatusReached:
406                        {
407                        focusStatus = true;
408                        //Lock the AE and AWB here sinc the focus is locked
409                        // Apply 3A locks after AF
410                        if( set3ALock(OMX_TRUE) != NO_ERROR) {
411                            CAMHAL_LOGEA("Error Applying 3A locks");
412                        }
413                        else
414                            {
415                            CAMHAL_LOGDA("Focus locked. Applied focus locks successfully");
416                            }
417                        break;
418                        }
419                    case OMX_FocusStatusOff:
420                    case OMX_FocusStatusUnableToReach:
421                    case OMX_FocusStatusRequest:
422                    default:
423                        {
424                        focusStatus = false;
425                        break;
426                        }
427                }
428
429            stopAutoFocus();
430            }
431        }
432
433    ret =  BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS);
434    if ( NO_ERROR == ret )
435        {
436        ret = BaseCameraAdapter::commitState();
437        }
438    else
439        {
440        ret |= BaseCameraAdapter::rollbackState();
441        }
442
443    if ( NO_ERROR == ret )
444        {
445        notifyFocusSubscribers(focusStatus);
446        }
447
448    // After focus, face detection will resume sending face callbacks
449    pauseFaceDetection(false);
450
451    LOG_FUNCTION_NAME_EXIT;
452
453    return ret;
454}
455
456status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus)
457{
458    status_t ret = NO_ERROR;
459    OMX_ERRORTYPE eError = OMX_ErrorNone;
460
461    LOG_FUNCTION_NAME;
462
463    if ( NULL == eFocusStatus )
464        {
465        CAMHAL_LOGEA("Invalid focus status");
466        ret = -EINVAL;
467        }
468
469    if ( OMX_StateExecuting != mComponentState )
470        {
471        CAMHAL_LOGEA("OMX component not in executing state");
472        ret = -EINVAL;
473        }
474
475    if ( NO_ERROR == ret )
476        {
477        OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
478
479        eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
480                               OMX_IndexConfigCommonFocusStatus,
481                               eFocusStatus);
482        if ( OMX_ErrorNone != eError )
483            {
484            CAMHAL_LOGEB("Error while retrieving focus status: 0x%x", eError);
485            ret = -1;
486            }
487        }
488
489    if ( NO_ERROR == ret )
490        {
491        CAMHAL_LOGDB("Focus Status: %d", eFocusStatus->eFocusStatus);
492        }
493
494    LOG_FUNCTION_NAME_EXIT;
495
496    return ret;
497}
498
499status_t OMXCameraAdapter::updateFocusDistances(CameraParameters &params)
500{
501    OMX_U32 focusNear, focusOptimal, focusFar;
502    status_t ret = NO_ERROR;
503
504    LOG_FUNCTION_NAME;
505
506    ret = getFocusDistances(focusNear, focusOptimal, focusFar);
507    if ( NO_ERROR == ret)
508        {
509        ret = addFocusDistances(focusNear, focusOptimal, focusFar, params);
510            if ( NO_ERROR != ret )
511                {
512                CAMHAL_LOGEB("Error in call to addFocusDistances() 0x%x", ret);
513                }
514        }
515    else
516        {
517        CAMHAL_LOGEB("Error in call to getFocusDistances() 0x%x", ret);
518        }
519
520    LOG_FUNCTION_NAME_EXIT;
521
522    return ret;
523}
524
525status_t OMXCameraAdapter::getFocusDistances(OMX_U32 &near,OMX_U32 &optimal, OMX_U32 &far)
526{
527    status_t ret = NO_ERROR;
528    OMX_ERRORTYPE eError;
529
530    OMX_TI_CONFIG_FOCUSDISTANCETYPE focusDist;
531
532    LOG_FUNCTION_NAME;
533
534    if ( OMX_StateInvalid == mComponentState )
535        {
536        CAMHAL_LOGEA("OMX component is in invalid state");
537        ret = UNKNOWN_ERROR;
538        }
539
540    if ( NO_ERROR == ret )
541        {
542        OMX_INIT_STRUCT_PTR(&focusDist, OMX_TI_CONFIG_FOCUSDISTANCETYPE);
543        focusDist.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
544
545        eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
546                               ( OMX_INDEXTYPE ) OMX_TI_IndexConfigFocusDistance,
547                               &focusDist);
548        if ( OMX_ErrorNone != eError )
549            {
550            CAMHAL_LOGEB("Error while querying focus distances 0x%x", eError);
551            ret = UNKNOWN_ERROR;
552            }
553
554        }
555
556    if ( NO_ERROR == ret )
557        {
558        near = focusDist.nFocusDistanceNear;
559        optimal = focusDist.nFocusDistanceOptimal;
560        far = focusDist.nFocusDistanceFar;
561        }
562
563    LOG_FUNCTION_NAME_EXIT;
564
565    return ret;
566}
567
568status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_t length)
569{
570    status_t ret = NO_ERROR;
571    uint32_t focusScale = 1000;
572    float distFinal;
573
574    LOG_FUNCTION_NAME;
575
576    if(mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity)
577        {
578        dist=0;
579        }
580
581    if ( NO_ERROR == ret )
582        {
583        if ( 0 == dist )
584            {
585            strncpy(buffer, CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 ));
586            }
587        else
588            {
589            distFinal = dist;
590            distFinal /= focusScale;
591            snprintf(buffer, ( length - 1 ) , "%5.3f", distFinal);
592            }
593        }
594
595    LOG_FUNCTION_NAME_EXIT;
596
597    return ret;
598}
599
600status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near,
601                                             OMX_U32 &optimal,
602                                             OMX_U32 &far,
603                                             CameraParameters& params)
604{
605    status_t ret = NO_ERROR;
606
607    LOG_FUNCTION_NAME;
608
609    if ( NO_ERROR == ret )
610        {
611        ret = encodeFocusDistance(near, mFocusDistNear, FOCUS_DIST_SIZE);
612        if ( NO_ERROR != ret )
613            {
614            CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
615            }
616        }
617
618    if ( NO_ERROR == ret )
619        {
620        ret = encodeFocusDistance(optimal, mFocusDistOptimal, FOCUS_DIST_SIZE);
621        if ( NO_ERROR != ret )
622            {
623            CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
624            }
625        }
626
627    if ( NO_ERROR == ret )
628        {
629        ret = encodeFocusDistance(far, mFocusDistFar, FOCUS_DIST_SIZE);
630        if ( NO_ERROR != ret )
631            {
632            CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
633            }
634        }
635
636    if ( NO_ERROR == ret )
637        {
638        snprintf(mFocusDistBuffer, ( FOCUS_DIST_BUFFER_SIZE - 1) ,"%s,%s,%s", mFocusDistNear,
639                                                                              mFocusDistOptimal,
640                                                                              mFocusDistFar);
641
642        params.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer);
643        }
644
645    LOG_FUNCTION_NAME_EXIT;
646
647    return ret;
648}
649
650status_t OMXCameraAdapter::setTouchFocus(size_t posX,
651                                         size_t posY,
652                                         size_t posWidth,
653                                         size_t posHeight,
654                                         size_t previewWidth,
655                                         size_t previewHeight)
656{
657    status_t ret = NO_ERROR;
658    OMX_ERRORTYPE eError = OMX_ErrorNone;
659    OMX_CONFIG_EXTFOCUSREGIONTYPE touchControl;
660
661    LOG_FUNCTION_NAME;
662
663    if ( OMX_StateInvalid == mComponentState )
664        {
665        CAMHAL_LOGEA("OMX component is in invalid state");
666        ret = -1;
667        }
668
669    if ( NO_ERROR == ret )
670        {
671        OMX_INIT_STRUCT_PTR (&touchControl, OMX_CONFIG_EXTFOCUSREGIONTYPE);
672        touchControl.nLeft = ( posX * TOUCH_FOCUS_RANGE ) / previewWidth;
673        touchControl.nTop =  ( posY * TOUCH_FOCUS_RANGE ) / previewHeight;
674        touchControl.nWidth = ( posWidth * TOUCH_FOCUS_RANGE ) / previewWidth;
675        touchControl.nHeight = ( posHeight * TOUCH_FOCUS_RANGE ) / previewHeight;
676
677        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
678                                ( OMX_INDEXTYPE ) OMX_IndexConfigExtFocusRegion,
679                                &touchControl);
680        if ( OMX_ErrorNone != eError )
681            {
682            CAMHAL_LOGEB("Error while configuring touch focus 0x%x", eError);
683            ret = -1;
684            }
685        else
686            {
687            CAMHAL_LOGDB("Touch focus %d,%d %d,%d configured successfuly",
688                         ( int ) touchControl.nLeft,
689                         ( int ) touchControl.nTop,
690                         ( int ) touchControl.nWidth,
691                         ( int ) touchControl.nHeight);
692            }
693        }
694
695    LOG_FUNCTION_NAME_EXIT;
696
697    return ret;
698}
699
700};
701