دستگاه های لمسی

اندروید از انواع صفحه نمایش‌های لمسی و تاچ‌پد، از جمله تبلت‌های دیجیتایزر مبتنی بر قلم، پشتیبانی می‌کند.

صفحه نمایش‌های لمسی، دستگاه‌های لمسی هستند که به یک نمایشگر متصل می‌شوند، به طوری که کاربر این حس را دارد که مستقیماً موارد روی صفحه را دستکاری می‌کند.

تاچ‌پدها دستگاه‌های لمسی هستند که به صفحه نمایش متصل نیستند، مانند تبلت دیجیتایزر. تاچ‌پدها معمولاً برای اشاره یا برای موقعیت‌یابی غیرمستقیم مطلق یا کنترل مبتنی بر حرکت رابط کاربری استفاده می‌شوند.

دستگاه‌های لمسی می‌توانند دکمه‌هایی داشته باشند که عملکرد آنها مشابه دکمه‌های ماوس است.

دستگاه‌های لمسی گاهی اوقات می‌توانند با استفاده از ابزارهای مختلفی مانند انگشتان یا قلم، بسته به فناوری حسگر لمسی زیربنایی، دستکاری شوند.

دستگاه‌های لمسی گاهی اوقات برای پیاده‌سازی کلیدهای مجازی استفاده می‌شوند. برای مثال، در برخی از دستگاه‌های اندروید، ناحیه حسگر صفحه لمسی از لبه صفحه نمایش فراتر می‌رود و به عنوان بخشی از یک صفحه کلید حساس به لمس، دو منظوره عمل می‌کند.

با توجه به تنوع زیاد دستگاه‌های لمسی، اندروید برای توصیف ویژگی‌ها و رفتار مطلوب هر دستگاه، به تعداد زیادی از ویژگی‌های پیکربندی متکی است.

طبقه بندی دستگاه های لمسی

یک دستگاه ورودی در صورتی به عنوان یک دستگاه چند لمسی طبقه‌بندی می‌شود که هر دو شرط زیر برقرار باشد:

  • دستگاه ورودی وجود محورهای مطلق ABS_MT_POSITION_X و ABS_MT_POSITION_Y را گزارش می‌دهد.
  • دستگاه ورودی هیچ دکمه‌ای برای دسته بازی ندارد. این وضعیت، ابهام مربوط به دسته‌های بازی خاصی را که محورهایی را با کدهایی گزارش می‌دهند که با کدهای محورهای MT همپوشانی دارند، برطرف می‌کند.

یک دستگاه ورودی در صورتی به عنوان یک دستگاه تک لمسی طبقه‌بندی می‌شود که هر دو شرط زیر برقرار باشد:

  • دستگاه ورودی به عنوان یک دستگاه چند لمسی طبقه‌بندی نمی‌شود. یک دستگاه ورودی یا به عنوان یک دستگاه تک لمسی یا به عنوان یک دستگاه چند لمسی طبقه‌بندی می‌شود، هرگز هر دو را با هم ندارد.
  • دستگاه ورودی، وجود محورهای مطلق ABS_X و ABS_Y و وجود کد کلید BTN_TOUCH را گزارش می‌دهد.

وقتی یک دستگاه ورودی به عنوان یک دستگاه لمسی طبقه‌بندی می‌شود، وجود کلیدهای مجازی با تلاش برای بارگذاری فایل نقشه کلید مجازی برای دستگاه تعیین می‌شود. اگر یک نقشه کلید مجازی موجود باشد، فایل طرح‌بندی کلید برای دستگاه نیز بارگذاری می‌شود. برای اطلاعات مربوط به مکان و قالب این فایل‌ها به [فایل‌های نقشه کلید مجازی](#virtual-key-map-files) مراجعه کنید.

در مرحله بعد، سیستم فایل پیکربندی دستگاه ورودی را برای دستگاه لمسی بارگذاری می‌کند.

تمام دستگاه‌های لمسی داخلی باید فایل‌های پیکربندی دستگاه ورودی داشته باشند. اگر هیچ فایل پیکربندی دستگاه ورودی وجود نداشته باشد، سیستم یک پیکربندی پیش‌فرض را انتخاب می‌کند که برای لوازم جانبی لمسی عمومی مانند صفحه نمایش‌های لمسی یا پدهای لمسی USB یا Bluetooth HID خارجی مناسب است. این پیش‌فرض‌ها برای صفحه نمایش‌های لمسی داخلی طراحی نشده‌اند و می‌توانند منجر به رفتار نادرست شوند.

پس از بارگذاری پیکربندی دستگاه ورودی، سیستم دستگاه ورودی را به عنوان صفحه لمسی ، پد لمسی یا دستگاه اشاره‌گر طبقه‌بندی می‌کند.

  • یک دستگاه صفحه لمسی برای دستکاری مستقیم اشیاء روی صفحه استفاده می‌شود. کاربر مستقیماً صفحه را لمس می‌کند، بنابراین سیستم به هیچ ابزار اضافی برای نشان دادن اشیاء در حال دستکاری نیاز ندارد.
  • یک دستگاه تاچ‌پد برای ارائه اطلاعات موقعیت‌یابی مطلق به یک برنامه در مورد لمس‌های روی یک ناحیه حسگر مشخص استفاده می‌شود. این دستگاه می‌تواند برای تبلت‌های دیجیتایزر مفید باشد.
  • یک دستگاه اشاره‌گر برای دستکاری غیرمستقیم اشیاء روی صفحه با استفاده از مکان‌نما استفاده می‌شود. انگشتان به عنوان حرکات اشاره‌گر چند لمسی تفسیر می‌شوند. ابزارهای دیگر، مانند قلم‌ها، با استفاده از موقعیت‌های مطلق تفسیر می‌شوند. برای اطلاعات بیشتر به حرکات اشاره‌گر چند لمسی غیرمستقیم مراجعه کنید.

قوانین زیر برای طبقه‌بندی دستگاه ورودی به عنوان صفحه لمسی، پد لمسی یا دستگاه اشاره‌گر استفاده می‌شود.

  • اگر ویژگی touch.deviceType تنظیم شده باشد، نوع دستگاه همانطور که نشان داده شده است تنظیم می‌شود.
  • اگر دستگاه ورودی وجود ویژگی ورودی INPUT_PROP_DIRECT را گزارش دهد (از طریق EVIOCGPROP ioctl)، نوع دستگاه روی صفحه لمسی تنظیم می‌شود. این شرط فرض می‌کند که دستگاه‌های لمسی با ورودی مستقیم به صفحه نمایشی متصل هستند که آن صفحه نیز متصل است.
  • اگر دستگاه ورودی وجود ویژگی ورودی INPUT_PROP_POINTER را گزارش دهد (از طریق EVIOCGPROP ioctl)، نوع دستگاه روی pointer تنظیم می‌شود.
  • اگر دستگاه ورودی وجود محورهای نسبی REL_X یا REL_Y را گزارش دهد، نوع دستگاه روی پد لمسی تنظیم می‌شود. این شرط، ابهام مربوط به دستگاه‌های ورودی که شامل ماوس و پد لمسی هستند را برطرف می‌کند. در این حالت، از پد لمسی برای کنترل اشاره‌گر استفاده نمی‌شود زیرا ماوس از قبل آن را کنترل می‌کند.
  • در غیر این صورت، نوع دستگاه روی اشاره‌گر تنظیم می‌شود. این پیش‌فرض تضمین می‌کند که پدهای لمسی که برای هیچ هدف خاص دیگری تعیین نشده‌اند، اشاره‌گر را کنترل می‌کنند.

دکمه‌ها

دکمه‌ها کنترل‌های اختیاری هستند که برنامه‌ها می‌توانند از آنها برای انجام عملکردهای اضافی استفاده کنند. دکمه‌ها در دستگاه‌های لمسی مشابه دکمه‌های ماوس رفتار می‌کنند و عمدتاً با دستگاه‌های لمسی از نوع اشاره‌گر یا با قلم مورد استفاده قرار می‌گیرند.

دکمه‌های زیر پشتیبانی می‌شوند:

  • BTN_LEFT : به MotionEvent.BUTTON_PRIMARY نگاشت شده است.
  • BTN_RIGHT : به MotionEvent.BUTTON_SECONDARY نگاشت شده است.
  • BTN_MIDDLE : به MotionEvent.BUTTON_MIDDLE نگاشت شده است.
  • BTN_BACK و BTN_SIDE : به MotionEvent.BUTTON_BACK نگاشت شده‌اند. فشردن این دکمه، فشردن کلید را با کد کلید KeyEvent.KEYCODE_BACK ترکیب می‌کند.
  • BTN_FORWARD و BTN_EXTRA : به MotionEvent.BUTTON_FORWARD نگاشت شده‌اند. فشردن این دکمه، فشردن کلید را با کد کلید KeyEvent.KEYCODE_FORWARD ترکیب می‌کند.
  • BTN_STYLUS : به MotionEvent.BUTTON_SECONDARY نگاشت شده است.
  • BTN_STYLUS2 : به MotionEvent.BUTTON_TERTIARY نگاشت شده است.

ابزارها و انواع ابزار

ابزار ، انگشت، قلم یا وسیله‌ی دیگری است که برای تعامل با دستگاه لمسی استفاده می‌شود. برخی از دستگاه‌های لمسی می‌توانند انواع مختلف ابزارها را از هم تشخیص دهند.

در جاهای دیگر اندروید، مانند MotionEvent API، اغلب به یک ابزار، اشاره‌گر ( pointer) گفته می‌شود.

انواع ابزارهای زیر پشتیبانی می‌شوند:

  • BTN_TOOL_FINGER و MT_TOOL_FINGER : به MotionEvent.TOOL_TYPE_FINGER نگاشت شده‌اند.
  • BTN_TOOL_PEN و MT_TOOL_PEN : به MotionEvent.TOOL_TYPE_STYLUS نگاشت شده‌اند.
  • BTN_TOOL_RUBBER : به MotionEvent.TOOL_TYPE_ERASER نگاشت شده است.
  • BTN_TOOL_BRUSH : به MotionEvent.TOOL_TYPE_STYLUS نگاشت شده است.
  • BTN_TOOL_PENCIL : به MotionEvent.TOOL_TYPE_STYLUS نگاشت شده است.
  • BTN_TOOL_AIRBRUSH : به MotionEvent.TOOL_TYPE_STYLUS نگاشت شده است.
  • BTN_TOOL_MOUSE : به MotionEvent.TOOL_TYPE_MOUSE نگاشت شده است.
  • BTN_TOOL_LENS : به MotionEvent.TOOL_TYPE_MOUSE نگاشت شده است.
  • BTN_TOOL_DOUBLETAP ، BTN_TOOL_TRIPLETAP و BTN_TOOL_QUADTAP : به MotionEvent.TOOL_TYPE_FINGER نگاشت شده‌اند.

ابزارهای شناور در مقابل ابزارهای لمسی

ابزارها می‌توانند یا در تماس با دستگاه لمسی باشند یا در محدوده و بالای آن معلق باشند. همه دستگاه‌های لمسی نمی‌توانند وجود ابزاری را که بالای دستگاه لمسی معلق است حس کنند. آن‌هایی که این کار را انجام می‌دهند، مانند دیجیتایزرهای قلمی مبتنی بر RF، اغلب می‌توانند تشخیص دهند که ابزار در محدوده محدودی از دیجیتایزر قرار دارد.

کامپوننت InputReader ابزارهای لمسی را از ابزارهای شناور متمایز می‌کند. به همین ترتیب، ابزارهای لمسی و ابزارهای شناور به روش‌های مختلفی به برنامه‌ها گزارش می‌شوند.

ابزارهای لمسی با استفاده از MotionEvent.ACTION_DOWN ، MotionEvent.ACTION_MOVE ، MotionEvent.ACTION_DOWN ، MotionEvent.ACTION_POINTER_DOWN و MotionEvent.ACTION_POINTER_UP به عنوان رویدادهای لمسی به برنامه‌ها گزارش می‌شوند.

ابزارهای شناور با استفاده از MotionEvent.ACTION_HOVER_ENTER ، MotionEvent.ACTION_HOVER_MOVE و MotionEvent.ACTION_HOVER_EXIT به عنوان رویدادهای حرکتی عمومی به برنامه‌ها گزارش می‌شوند.

الزامات درایور دستگاه لمسی

  • درایورهای دستگاه‌های لمسی باید فقط محورها و کدهای کلید را برای محورها و دکمه‌هایی که پشتیبانی می‌کنند، ثبت کنند. ثبت محورها یا کدهای کلید پشتیبانی نشده می‌تواند الگوریتم طبقه‌بندی دستگاه را گیج کند یا باعث شود سیستم به اشتباه قابلیت‌های دستگاه را تشخیص دهد. به عنوان مثال، اگر دستگاه کد کلید BTN_TOUCH را گزارش دهد، سیستم فرض می‌کند که BTN_TOUCH همیشه برای نشان دادن اینکه آیا ابزار صفحه را لمس می‌کند یا خیر، استفاده می‌شود. بنابراین، BTN_TOUCH نباید برای نشان دادن اینکه ابزار صرفاً در محدوده و در حال حرکت است، استفاده شود.
  • دستگاه‌های تک لمسی از رویدادهای ورودی لینوکس زیر استفاده می‌کنند:
    • ABS_X : (الزامی) مختصات X ابزار را گزارش می‌دهد.
    • ABS_Y : (الزامی) مختصات Y ابزار را گزارش می‌دهد.
    • ABS_PRESSURE : (اختیاری) فشار فیزیکی اعمال شده به نوک ابزار یا قدرت سیگنال تماس لمسی را گزارش می‌دهد.
    • ABS_TOOL_WIDTH : (اختیاری) مساحت سطح مقطع یا عرض تماس لمسی یا خود ابزار را گزارش می‌دهد.
    • ABS_DISTANCE : (اختیاری) فاصله ابزار از سطح دستگاه لمسی را گزارش می‌دهد.
    • ABS_TILT_X : (اختیاری) میزان شیب ابزار را از سطح دستگاه لمسی در امتداد محور X گزارش می‌دهد.
    • ABS_TILT_Y : (اختیاری) میزان شیب ابزار را از سطح دستگاه لمسی در امتداد محور Y گزارش می‌دهد.
    • BTN_TOUCH : (الزامی) نشان می‌دهد که آیا ابزار با دستگاه در تماس است یا خیر.
    • BTN_LEFT ، BTN_RIGHT ، BTN_MIDDLE ، BTN_BACK ، BTN_SIDE ، BTN_FORWARD ، BTN_EXTRA ، BTN_STYLUS ، BTN_STYLUS2 : (اختیاری) وضعیت دکمه‌ها را گزارش می‌دهد.
    • BTN_TOOL_FINGER ، BTN_TOOL_PEN ، BTN_TOOL_RUBBER ، BTN_TOOL_BRUSH ، BTN_TOOL_PENCIL ، BTN_TOOL_AIRBRUSH ، BTN_TOOL_MOUSE ، BTN_TOOL_LENS ، BTN_TOOL_DOUBLETAP ، BTN_TOOL_TRIPLETAP ، BTN_TOOL_QUADTAP : (اختیاری) نوع ابزار را گزارش می‌دهد.
  • دستگاه‌های چند لمسی از رویدادهای ورودی لینوکس زیر استفاده می‌کنند:
    • ABS_MT_POSITION_X : (الزامی) مختصات X ابزار را گزارش می‌دهد.
    • ABS_MT_POSITION_Y : (الزامی) مختصات Y ابزار را گزارش می‌دهد.
    • ABS_MT_PRESSURE : (اختیاری) فشار فیزیکی اعمال شده به نوک ابزار یا قدرت سیگنال تماس لمسی را گزارش می‌دهد.
    • ABS_MT_TOUCH_MAJOR : (اختیاری) سطح مقطع تماس لمسی یا طول بُعد بلندتر تماس لمسی را گزارش می‌دهد.
    • ABS_MT_TOUCH_MINOR : (اختیاری) طول بُعد کوتاه‌ترِ تماس لمسی را گزارش می‌دهد. اگر ABS_MT_TOUCH_MAJOR اندازه‌گیری مساحت را گزارش می‌دهد، این محور نباید استفاده شود.
    • ABS_MT_WIDTH_MAJOR : (اختیاری) مساحت سطح مقطع خود ابزار یا طول بُعد بلندتر خود ابزار را گزارش می‌دهد. از این محور استفاده نکنید مگر اینکه ابعاد خود ابزار را بدانید.
    • ABS_MT_WIDTH_MINOR : (اختیاری) طول بُعد کوتاه‌تر خود ابزار را گزارش می‌دهد. اگر ABS_MT_WIDTH_MAJOR اندازه‌گیری مساحت را گزارش می‌دهد یا اگر ابعاد خود ابزار ناشناخته است، نباید از این محور استفاده شود.
    • ABS_MT_ORIENTATION : (اختیاری) جهت ابزار را گزارش می‌دهد.
    • ABS_MT_DISTANCE : (اختیاری) فاصله ابزار از سطح دستگاه لمسی را گزارش می‌دهد.
    • ABS_MT_TOOL_TYPE : (اختیاری) نوع ابزار را به صورت MT_TOOL_FINGER یا MT_TOOL_PEN گزارش می‌دهد.
    • ABS_MT_TRACKING_ID : (اختیاری) شناسه ردیابی ابزار را گزارش می‌دهد. شناسه ردیابی یک عدد صحیح غیرمنفی دلخواه است که برای شناسایی و ردیابی هر ابزار به طور مستقل هنگام فعال بودن چندین ابزار استفاده می‌شود. به عنوان مثال، هنگامی که چندین انگشت دستگاه را لمس می‌کنند، به هر انگشت باید یک شناسه ردیابی مجزا اختصاص داده شود که تا زمانی که انگشت در تماس باشد، استفاده می‌شود. شناسه‌های ردیابی را می‌توان هنگامی که ابزارهای مرتبط با آنها از محدوده خارج می‌شوند، دوباره استفاده کرد.
    • ABS_MT_SLOT : (اختیاری) هنگام استفاده از پروتکل چند لمسی لینوکس 'B'، شناسه اسلات ابزار را گزارش می‌دهد. برای جزئیات بیشتر به مستندات پروتکل چند لمسی لینوکس مراجعه کنید.
    • BTN_TOUCH : (الزامی) نشان می‌دهد که آیا ابزار با دستگاه در تماس است یا خیر.
    • BTN_LEFT ، BTN_RIGHT ، BTN_MIDDLE ، BTN_BACK ، BTN_SIDE ، BTN_FORWARD ، BTN_EXTRA ، BTN_STYLUS ، BTN_STYLUS2 : (اختیاری) وضعیت دکمه‌ها را گزارش می‌دهد.
    • BTN_TOOL_FINGER ، BTN_TOOL_PEN ، BTN_TOOL_RUBBER ، BTN_TOOL_BRUSH ، BTN_TOOL_PENCIL ، BTN_TOOL_AIRBRUSH ، BTN_TOOL_MOUSE ، BTN_TOOL_LENS ، BTN_TOOL_DOUBLETAP ، BTN_TOOL_TRIPLETAP ، BTN_TOOL_QUADTAP : (اختیاری) نوع ابزار را گزارش می‌دهد.
  • اگر محورهایی برای هر دو پروتکل تک لمسی و چند لمسی تعریف شده باشند، فقط محورهای چند لمسی استفاده می‌شوند و محورهای تک لمسی نادیده گرفته می‌شوند.
  • مقادیر حداقل و حداکثر محورهای ABS_X ، ABS_Y ، ABS_MT_POSITION_X و ABS_MT_POSITION_Y ، محدوده‌های ناحیه فعال دستگاه را در واحدهای سطح مخصوص دستگاه تعریف می‌کنند. در مورد صفحه نمایش لمسی، ناحیه فعال بخشی از دستگاه لمسی را توصیف می‌کند که در واقع صفحه نمایش را می‌پوشاند.

    برای یک صفحه نمایش لمسی، سیستم به طور خودکار موقعیت‌های لمسی گزارش شده را در واحدهای سطح درون‌یابی می‌کند تا موقعیت‌های لمسی را در پیکسل‌های صفحه نمایش طبق محاسبه زیر بدست آورد:

        displayX = (x - minX) * displayWidth / (maxX - minX + 1)
        displayY = (y - minY) * displayHeight / (maxY - minY + 1)
        

    یک صفحه لمسی ممکن است لمس‌هایی خارج از ناحیه فعال گزارش‌شده را گزارش دهد.

    لمس‌هایی که خارج از ناحیه فعال آغاز می‌شوند، به برنامه‌ها ارسال نمی‌شوند، اما می‌توانند برای کلیدهای مجازی استفاده شوند.

    لمس‌هایی که درون ناحیه فعال آغاز می‌شوند، یا به ناحیه نمایش وارد و از آن خارج می‌شوند، به برنامه‌ها تحویل داده می‌شوند. در نتیجه، اگر لمسی درون محدوده یک برنامه شروع شود و سپس به خارج از ناحیه فعال حرکت کند، برنامه ممکن است رویدادهای لمسی با مختصات نمایش منفی یا فراتر از محدوده صفحه نمایش دریافت کند. این رفتار مورد انتظار است.

    یک دستگاه لمسی هرگز نباید مختصات لمسی را به مرزهای ناحیه فعال محدود کند. اگر لمسی از ناحیه فعال خارج شود، باید به عنوان خارج از ناحیه فعال گزارش شود، یا اصلاً نباید گزارش شود.

    برای مثال، اگر انگشت کاربر نزدیک گوشه بالا سمت چپ صفحه لمسی را لمس کند، ممکن است مختصات (minX, minY) را گزارش دهد. اگر انگشت به حرکت خود در خارج از ناحیه فعال ادامه دهد، صفحه لمسی یا باید شروع به گزارش مختصات با مؤلفه‌های کمتر از minX و minY کند، مانند (minX - 2, minY - 3)، یا باید گزارش لمس را به طور کلی متوقف کند. به عبارت دیگر، وقتی انگشت کاربر واقعاً خارج از ناحیه فعال را لمس می‌کند، صفحه لمسی نباید (minX, minY) را گزارش دهد.

    قرار دادن مختصات لمسی در لبه صفحه نمایش، یک مرز سخت مصنوعی در اطراف لبه صفحه نمایش ایجاد می‌کند که مانع از ردیابی روان حرکاتی می‌شود که وارد یا از مرزهای ناحیه نمایش خارج می‌شوند.

  • مقادیر گزارش‌شده توسط ABS_PRESSURE یا ABS_MT_PRESSURE ، در صورت گزارش شدن، باید هنگام لمس ابزار توسط دستگاه غیرصفر و در غیر این صورت صفر باشند تا نشان دهند که ابزار در حال معلق بودن است.

    گزارش اطلاعات فشار اختیاری است اما اکیداً توصیه می‌شود. برنامه‌ها می‌توانند از اطلاعات فشار برای پیاده‌سازی طراحی حساس به فشار و سایر جلوه‌ها استفاده کنند.

  • مقادیر گزارش‌شده توسط ABS_TOOL_WIDTH ، ABS_MT_TOUCH_MAJOR ، ABS_MT_TOUCH_MINOR ، ABS_MT_WIDTH_MAJOR یا ABS_MT_WIDTH_MINOR باید در هنگام لمس دستگاه توسط ابزار غیر صفر و در غیر این صورت صفر باشند، اما این الزامی نیست. برای مثال، دستگاه لمسی ممکن است بتواند اندازه تماس‌های لمسی انگشت را اندازه‌گیری کند اما نمی‌تواند تماس‌های لمسی قلم را اندازه‌گیری کند.

    گزارش اطلاعات اندازه اختیاری است اما اکیداً توصیه می‌شود. برنامه‌ها می‌توانند از اطلاعات فشار برای پیاده‌سازی طراحی حساس به اندازه و سایر جلوه‌ها استفاده کنند.

  • مقادیر گزارش شده توسط ABS_DISTANCE یا ABS_MT_DISTANCE باید هنگام تماس ابزار با دستگاه به صفر نزدیک شوند. حتی زمانی که ابزار در تماس مستقیم است، فاصله می‌تواند غیر صفر باقی بماند. مقادیر دقیق گزارش شده به نحوه اندازه‌گیری فاصله توسط سخت‌افزار بستگی دارد.

    گزارش اطلاعات فاصله اختیاری است اما برای دستگاه‌های قلمی توصیه می‌شود.

  • مقادیر گزارش شده توسط ABS_TILT_X و ABS_TILT_Y باید زمانی که ابزار عمود بر دستگاه است، صفر باشند. شیب غیر صفر نشان می‌دهد که ابزار به صورت شیب‌دار نگه داشته شده است.

    فرض می‌شود زاویه‌های شیب در امتداد محورهای X و Y بر حسب درجه از عمود بر صفحه مشخص شده‌اند. نقطه مرکزی (کاملاً عمود) برای هر محور با (max + min) / 2 داده می‌شود. مقادیر کوچکتر از نقطه مرکزی نشان دهنده شیب به سمت بالا یا چپ و مقادیر بزرگتر از نقطه مرکزی نشان دهنده شیب به سمت پایین یا راست هستند.

    InputReader مؤلفه‌های شیب X و Y را به یک زاویه شیب عمود در محدوده 0 تا PI / 2 رادیان و یک زاویه جهت‌گیری مسطح در محدوده -PI تا رادیان PI تبدیل می‌کند. این نمایش منجر به توصیفی از جهت‌گیری می‌شود که با آنچه برای توصیف لمس‌های انگشت استفاده می‌شود، سازگار است.

    گزارش اطلاعات شیب اختیاری است اما برای دستگاه‌های قلمی توصیه می‌شود.

  • اگر نوع ابزار توسط ABS_MT_TOOL_TYPE گزارش شده باشد، جایگزین هرگونه اطلاعات نوع ابزار گزارش شده توسط BTN_TOOL_* می‌شود. اگر هیچ اطلاعاتی از نوع ابزار در دسترس نباشد، نوع ابزار به طور پیش‌فرض MotionEvent.TOOL_TYPE_FINGER در نظر گرفته می‌شود.

  • یک ابزار بر اساس شرایط زیر فعال تعیین می‌شود:

    • هنگام استفاده از پروتکل تک لمسی، اگر BTN_TOUCH یا BTN_TOOL_* برابر با ۱ باشد، ابزار فعال است.

      این شرط حاکی از آن است که InputReader باید حداقل اطلاعاتی در مورد ماهیت ابزار، چه لمسی بودن آن و چه حداقل نوع ابزار آن، داشته باشد. اگر هیچ اطلاعاتی در دسترس نباشد، فرض می‌شود که ابزار غیرفعال (خارج از محدوده) است.

    • هنگام استفاده از پروتکل چند لمسی «A»، این ابزار هر زمان که در جدیدترین گزارش همگام‌سازی ظاهر شود، فعال است. هنگامی که نمایش این ابزار در گزارش‌های همگام‌سازی متوقف شود، دیگر وجود نخواهد داشت.
    • هنگام استفاده از پروتکل چند لمسی «B»، ابزار تا زمانی که یک اسلات فعال داشته باشد فعال است. وقتی اسلات خالی شد، ابزار از بین می‌رود.
  • یک ابزار بر اساس شرایط زیر در حالت معلق (Hover) قرار می‌گیرد:
    • اگر ابزار BTN_TOOL_MOUSE یا BTN_TOOL_LENS باشد، حتی اگر هر یک از شرایط زیر درست باشد، ابزار در حالت شناور قرار نمی‌گیرد.
    • اگر ابزار فعال باشد و درایور اطلاعات فشار را گزارش دهد و فشار گزارش شده صفر باشد، ابزار در حال حرکت است.
    • اگر ابزار فعال باشد و درایور از کد کلید BTN_TOUCH پشتیبانی کند و BTN_TOUCH مقدار صفر داشته باشد، آنگاه ابزار در حال حرکت است.
  • InputReader از هر دو پروتکل چند لمسی «A» و «B» پشتیبانی می‌کند. درایورهای جدید باید از پروتکل «B» استفاده کنند، اما هر دو کار می‌کنند.
  • از اندروید ۴.۰ به بعد، ممکن است لازم باشد درایورهای صفحه لمسی برای مطابقت با مشخصات پروتکل ورودی لینوکس تغییر کنند.

    ممکن است تغییرات زیر مورد نیاز باشد:

    • وقتی ابزاری غیرفعال می‌شود (انگشت به سمت بالا می‌رود)، دیگر نباید در گزارش‌های همگام‌سازی چند لمسی بعدی ظاهر شود. وقتی همه ابزارها غیرفعال می‌شوند (همه انگشتان به سمت بالا می‌روند)، درایور باید یک بسته گزارش همگام‌سازی خالی، مانند SYN_MT_REPORT و به دنبال آن SYN_REPORT ارسال کند.

      نسخه‌های قبلی اندروید انتظار داشتند رویدادهای «بالا آمدن» با ارسال مقدار فشار ۰ گزارش شوند. رفتار قدیمی با مشخصات پروتکل ورودی لینوکس سازگار نبود و دیگر پشتیبانی نمی‌شود.

    • اطلاعات فشار فیزیکی یا قدرت سیگنال باید با استفاده از ABS_MT_PRESSURE گزارش شود.

      نسخه‌های قبلی اندروید اطلاعات فشار را از ABS_MT_TOUCH_MAJOR بازیابی می‌کردند. این رفتار قدیمی با مشخصات پروتکل ورودی لینوکس سازگار نبود و دیگر پشتیبانی نمی‌شود.

    • اطلاعات اندازه لمس باید با استفاده از ABS_MT_TOUCH_MAJOR گزارش شود.

      نسخه‌های قبلی اندروید اطلاعات اندازه را از ABS_MT_TOOL_MAJOR بازیابی می‌کردند. این رفتار قدیمی با مشخصات پروتکل ورودی لینوکس سازگار نبود و دیگر پشتیبانی نمی‌شود.

    درایورهای دستگاه‌های لمسی دیگر نیازی به سفارشی‌سازی‌های خاص اندروید ندارند. اندروید با تکیه بر پروتکل ورودی استاندارد لینوکس، می‌تواند از طیف وسیع‌تری از لوازم جانبی لمسی، مانند صفحه نمایش‌های لمسی چند لمسی HID خارجی، با استفاده از درایورهای اصلاح نشده پشتیبانی کند.

عملکرد دستگاه لمسی

در ادامه خلاصه‌ای از عملکرد دستگاه‌های لمسی در اندروید ارائه شده است.

  1. EventHub رویدادهای خام را از درایور evdev می‌خواند.
  2. InputReader رویدادهای خام را مصرف می‌کند و وضعیت داخلی را در مورد موقعیت و سایر ویژگی‌های هر ابزار به‌روزرسانی می‌کند. همچنین وضعیت دکمه‌ها را ردیابی می‌کند.
  3. اگر کلید BACK یا FORWARD فشرده یا رها شده باشد، InputReader رویداد کلید را به InputDispatcher اطلاع می‌دهد.
  4. InputReader تعیین می‌کند که آیا فشرده شدن کلید مجازی رخ داده است یا خیر. در این صورت، InputDispatcher از رویداد کلید مطلع می‌کند.
  5. InputReader تعیین می‌کند که آیا لمس در محدوده‌ی نمایشگر آغاز شده است یا خیر. در این صورت، InputDispatcher از رویداد لمس مطلع می‌کند.
  6. اگر هیچ ابزار لمسی وجود نداشته باشد اما حداقل یک ابزار معلق در هوا وجود داشته باشد، InputReader رویداد شناور شدن را به InputDispatcher اطلاع می‌دهد.
  7. اگر نوع دستگاه لمسی pointer باشد، InputReader تشخیص حرکت اشاره‌گر را انجام می‌دهد، اشاره‌گر را حرکت می‌دهد و بر اساس آن نقطه‌گذاری می‌کند و InputDispatcher در مورد رویداد pointer مطلع می‌سازد.
  8. InputDispatcher از WindowManagerPolicy برای تعیین اینکه آیا رویدادها باید ارسال شوند و آیا باید دستگاه را بیدار کنند، استفاده می‌کند. سپس، InputDispatcher رویدادها را به برنامه‌های مناسب تحویل می‌دهد.

پیکربندی دستگاه لمسی

رفتار دستگاه لمسی توسط محورهای دستگاه، دکمه‌ها، ویژگی‌های ورودی، پیکربندی دستگاه ورودی، نقشه کلید مجازی و طرح‌بندی کلید تعیین می‌شود.

برای جزئیات بیشتر در مورد فایل‌هایی که در پیکربندی صفحه‌کلید نقش دارند، به بخش‌های زیر مراجعه کنید:

خواص

این سیستم برای پیکربندی و کالیبراسیون رفتار دستگاه لمسی به بسیاری از ویژگی‌های پیکربندی دستگاه ورودی متکی است.

یکی از دلایل این امر این است که درایورهای دستگاه برای دستگاه‌های لمسی اغلب ویژگی‌های لمس را با استفاده از واحدهای خاص دستگاه گزارش می‌دهند.

برای مثال، بسیاری از دستگاه‌های لمسی، ناحیه تماس لمسی را با استفاده از یک مقیاس داخلی مخصوص دستگاه، مانند تعداد کل گره‌های حسگر که توسط لمس فعال شده‌اند، اندازه‌گیری می‌کنند. این مقدار خام اندازه برای برنامه‌ها معنی‌دار نخواهد بود زیرا آنها باید در مورد اندازه فیزیکی و سایر ویژگی‌های گره‌های حسگر دستگاه لمسی اطلاعات داشته باشند.

این سیستم از پارامترهای کالیبراسیون کدگذاری شده در فایل‌های پیکربندی دستگاه ورودی برای رمزگشایی، تبدیل و نرمال‌سازی مقادیر گزارش شده توسط دستگاه لمسی به یک نمایش استاندارد ساده‌تر که برنامه‌ها می‌توانند آن را درک کنند، استفاده می‌کند.

قراردادهای مستندسازی

برای اهداف مستندسازی، ما از قراردادهای زیر برای توصیف مقادیر مورد استفاده سیستم در طول فرآیند کالیبراسیون استفاده می‌کنیم.

مقادیر خام محور

عبارات زیر مقادیر خام گزارش شده توسط درایور دستگاه لمسی را به عنوان رویدادهای EV_ABS نشان می‌دهند.

raw.x
مقدار محور ABS_X یا ABS_MT_POSITION_X .
raw.y
مقدار محور ABS_Y یا ABS_MT_POSITION_Y .
raw.pressure
مقدار محور ABS_PRESSURE یا ABS_MT_PRESSURE ، یا در صورت عدم وجود، ۰.
raw.touchMajor
مقدار محور ABS_MT_TOUCH_MAJOR ، یا در صورت موجود نبودن، ۰.
raw.touchMinor
مقدار محور ABS_MT_TOUCH_MINOR ، یا در صورت عدم وجود raw.touchMajor .
raw.toolMajor
مقدار محور ABS_TOOL_WIDTH یا ABS_MT_WIDTH_MAJOR ، یا در صورت عدم وجود، ۰.
raw.toolMinor
مقدار محور ABS_MT_WIDTH_MINOR ، یا در صورت عدم وجود raw.toolMajor .
raw.orientation
مقدار محور ABS_MT_ORIENTATION ، یا در صورت موجود نبودن، ۰.
raw.distance
مقدار محور ABS_DISTANCE یا ABS_MT_DISTANCE ، یا در صورت موجود نبودن، ۰.
raw.tiltX
مقدار محور ABS_TILT_X ، یا در صورت موجود نبودن، ۰.
raw.tiltY
مقدار محور ABS_TILT_Y ، یا در صورت موجود نبودن، ۰.

محدوده‌های خام محور

عبارات زیر محدوده مقادیر خام را نشان می‌دهند. این مقادیر با فراخوانی تابع ioctl EVIOCGABS برای هر محور به دست می‌آیند.

raw.*.min
حداقل مقدار کلی محور خام.
raw.*.max
حداکثر مقدار کلی محور خام.
raw.*.range
معادل raw.*.max - raw.*.min .
raw.*.fuzz
دقت محور خام، مثلاً fuzz = 1، به این معنی است که مقادیر با دقت +/- 1 واحد هستند.
raw.width
عرض فراگیر ناحیه لمسی، معادل raw.x.range + 1 .
raw.height
ارتفاع فراگیر ناحیه لمسی، معادل raw.y.range + 1 .

محدوده‌های خروجی

عبارات زیر ویژگی‌های سیستم مختصات خروجی را نشان می‌دهند. این سیستم از درون‌یابی خطی برای ترجمه اطلاعات موقعیت لمس از واحدهای سطحی مورد استفاده توسط دستگاه لمسی به واحدهای خروجی که به برنامه‌هایی مانند پیکسل‌های صفحه نمایش گزارش می‌شوند، استفاده می‌کند.

output.width
عرض خروجی. برای صفحات لمسی (مرتبط با نمایشگر)، این عرض نمایشگر بر حسب پیکسل است. برای تاچ‌پدها (غیرمرتبط با نمایشگر)، عرض خروجی برابر raw.width است که نشان می‌دهد هیچ درون‌یابی انجام نشده است.
output.height
ارتفاع خروجی. برای صفحات لمسی (مرتبط با نمایشگر)، این ارتفاع نمایش بر حسب پیکسل است. برای تاچ‌پدها (غیرمرتبط با نمایشگر)، ارتفاع خروجی برابر با raw.height است که نشان می‌دهد هیچ درون‌یابی انجام نشده است.
output.diag
طول مورب سیستم مختصات خروجی، معادل با sqrt(output.width ^2 + output.height ^2) .

پیکربندی اولیه

نگاشت‌کننده ورودی لمسی از بسیاری از ویژگی‌های پیکربندی در فایل پیکربندی دستگاه ورودی برای تعیین مقادیر کالیبراسیون استفاده می‌کند. جدول زیر برخی از ویژگی‌های پیکربندی عمومی را شرح می‌دهد. سایر ویژگی‌ها در بخش‌های بعدی به همراه فیلدهایی که برای کالیبراسیون استفاده می‌شوند، شرح داده شده‌اند.

نوع دستگاه لمسی

تعریف: touch.deviceType = touchScreen | touchPad | pointer | default

نوع دستگاه لمسی را مشخص می‌کند.

  • اگر مقدار touchScreen باشد، دستگاه لمسی یک صفحه لمسی مرتبط با نمایشگر است.

  • اگر مقدار touchPad باشد، دستگاه لمسی یک پد لمسی است که به نمایشگر متصل نیست.

  • اگر مقدار pointer باشد، دستگاه لمسی یک تاچ‌پد است که به نمایشگر متصل نیست و حرکات آن برای ژست‌های اشاره‌گر چند لمسی غیرمستقیم استفاده می‌شود.

  • اگر مقدار default باشد، سیستم به طور خودکار نوع دستگاه را طبق الگوریتم طبقه‌بندی تشخیص می‌دهد.

برای جزئیات بیشتر در مورد چگونگی تأثیر نوع دستگاه بر رفتار دستگاه لمسی، به بخش طبقه‌بندی مراجعه کنید.

در اندروید ۳ و پایین‌تر، تمام دستگاه‌های لمسی، صفحه نمایش لمسی فرض می‌شدند.

جهت‌یابی لمسی

تعریف: touch.orientationAware = 0 | 1

مشخص می‌کند که آیا دستگاه لمسی باید به تغییرات جهت صفحه نمایش واکنش نشان دهد یا خیر.

  • اگر مقدار 1 باشد، موقعیت‌های لمسی گزارش‌شده توسط دستگاه لمسی، هر زمان که جهت‌گیری صفحه نمایش تغییر کند، چرخانده می‌شوند.

  • اگر مقدار 0 باشد، موقعیت‌های لمسی گزارش‌شده توسط دستگاه لمسی، در برابر تغییرات جهت‌گیری نمایشگر مصون هستند.

اگر دستگاه لمسی باشد، مقدار پیش‌فرض 1 و در غیر این صورت 0 است.

این سیستم بین صفحات لمسی و نمایشگرهای داخلی و خارجی تمایز قائل می‌شود. یک صفحه لمسی داخلیِ آگاه از جهت‌گیری، بر اساس جهت نمایشگر داخلی می‌چرخد. یک صفحه لمسی خارجیِ آگاه از جهت‌گیری، بر اساس جهت نمایشگر خارجی می‌چرخد.

آگاهی از جهت‌گیری برای پشتیبانی از چرخش صفحات لمسی در دستگاه‌هایی مانند Nexus One استفاده می‌شود. به عنوان مثال، هنگامی که دستگاه ۹۰ درجه نسبت به جهت طبیعی خود در جهت عقربه‌های ساعت چرخانده می‌شود، موقعیت‌های مطلق لمس‌ها به گونه‌ای تغییر داده می‌شوند که یک لمس در گوشه بالا سمت چپ سیستم مختصات مطلق صفحه لمسی به عنوان یک لمس در گوشه بالا سمت چپ سیستم مختصات چرخانده شده صفحه نمایش گزارش شود. این کار به گونه‌ای انجام می‌شود که لمس‌ها با همان سیستم مختصاتی گزارش شوند که برنامه‌ها برای ترسیم عناصر بصری خود استفاده می‌کنند.

قبل از Honeycomb، فرض بر این بود که تمام دستگاه‌های لمسی از جهت‌گیری آگاه هستند.

حالت لمس.حرکت

تعریف: touch.gestureMode = pointer | spots | default

حالت نمایش حرکات اشاره‌گر را مشخص می‌کند. این ویژگی پیکربندی فقط زمانی مرتبط است که دستگاه لمسی از نوع اشاره‌گر باشد.

  • اگر مقدار pointer باشد، حرکات تاچ‌پد به صورت یک مکان‌نما شبیه به اشاره‌گر ماوس نمایش داده می‌شوند.

  • اگر مقدار spots باشد، حرکات تاچ‌پد توسط یک لنگر که نشان دهنده مرکز ثقل حرکت است و مجموعه‌ای از نقاط دایره‌ای که نشان دهنده موقعیت انگشتان هستند، نمایش داده می‌شوند.

مقدار پیش‌فرض زمانی که ویژگی ورودی INPUT_PROP_SEMI_MT تنظیم شده باشد، pointer است، در غیر این صورت spots .

فیلدهای X و Y

میدان‌های X و Y اطلاعات موقعیتی را برای مرکز ناحیه تماس ارائه می‌دهند.

محاسبه

محاسبه ساده است: اطلاعات موقعیتی از درایور لمسی به صورت خطی در سیستم مختصات خروجی درون‌یابی می‌شود.

xScale = output.width / raw.width
yScale = output.height / raw.height

If not orientation aware or screen rotation is 0 degrees:
output.x = (raw.x - raw.x.min) * xScale
output.y = (raw.y - raw.y.min) * yScale
Else If rotation is 90 degrees:
    output.x = (raw.y - raw.y.min) * yScale
    output.y = (raw.x.max - raw.x) * xScale
Else If rotation is 180 degrees:
    output.x = (raw.x.max - raw.x) * xScale
    output.y = (raw.y.max - raw.y) * yScale
Else If rotation is 270 degrees:
    output.x = (raw.y.max - raw.y) * yScale
    output.y = (raw.x - raw.x.min) * xScale
End If

فیلدهای touchMajor، touchMinor، toolMajor، toolMinor، اندازه

فیلدهای touchMajor و touchMinor ابعاد تقریبی ناحیه تماس را بر حسب واحدهای خروجی (پیکسل) توصیف می‌کنند.

فیلدهای toolMajor و toolMinor ابعاد تقریبی خود ابزار را بر حسب واحدهای خروجی (پیکسل) توصیف می‌کنند.

فیلد size ، اندازه نرمال‌شده لمس را نسبت به بزرگترین لمس ممکنی که دستگاه لمسی می‌تواند حس کند، توصیف می‌کند. کوچکترین اندازه نرمال‌شده ممکن 0.0 (بدون تماس یا غیرقابل اندازه‌گیری) و بزرگترین اندازه نرمال‌شده ممکن 1.0 (ناحیه حسگر اشباع شده) است.

وقتی هر دو مقدار تقریبی طول و عرض قابل اندازه‌گیری باشند، فیلد touchMajor بُعد بلندتر و فیلد touchMinor بُعد کوتاه‌تر ناحیه تماس را مشخص می‌کند. وقتی فقط قطر تقریبی ناحیه تماس قابل اندازه‌گیری باشد، فیلدهای touchMajor و touchMinor با هم برابرند.

به همین ترتیب، فیلد toolMajor بُعد بلندتر و فیلد toolMinor بُعد کوتاه‌تر سطح مقطع ابزار را مشخص می‌کند.

اگر اندازه لمس در دسترس نباشد اما اندازه ابزار در دسترس باشد، اندازه ابزار برابر با اندازه لمس تنظیم می‌شود. برعکس، اگر اندازه ابزار در دسترس نباشد اما اندازه لمس در دسترس باشد، اندازه لمس برابر با اندازه ابزار تنظیم می‌شود.

دستگاه‌های لمسی، اندازه تماس و اندازه ابزار را به روش‌های مختلف اندازه‌گیری یا گزارش می‌کنند. پیاده‌سازی فعلی از سه نوع اندازه‌گیری مختلف پشتیبانی می‌کند: قطر، مساحت و کادر مرزی هندسی در واحدهای سطح.

تعریف: touch.size.calibration = none | geometric | diameter | area | default

نوع اندازه‌گیری مورد استفاده توسط درایور لمسی برای گزارش اندازه لمس و اندازه ابزار را مشخص می‌کند.

  • اگر مقدار none باشد، اندازه روی صفر تنظیم می‌شود.

  • اگر مقدار geometric باشد، فرض می‌شود که اندازه با همان واحدهای سطحی که موقعیت مشخص شده است، مشخص می‌شود، بنابراین به همان شیوه مقیاس‌بندی می‌شود.

  • اگر مقدار، diameter باشد، فرض می‌شود که اندازه متناسب با قطر (عرض) لمس یا ابزار است.

  • اگر مقدار، area باشد، فرض می‌شود که اندازه متناسب با مساحت لمس یا ابزار است.

  • اگر مقدار default باشد، سیستم در صورت موجود بودن محور raw.touchMajor یا raw.toolMajor از کالیبراسیون geometric استفاده می‌کند، در غیر این صورت از کالیبراسیون none استفاده می‌کند.

لمس.اندازه.مقیاس

تعریف: touch.size.scale = <یک عدد اعشاری غیر منفی>

ضریب مقیاس ثابت مورد استفاده در کالیبراسیون را مشخص می‌کند.

مقدار پیش‌فرض 1.0 است.

اندازه.بایاس.لمس

تعریف: touch.size.bias = <یک عدد اعشاری غیر منفی>

مقدار بایاس ثابت مورد استفاده در کالیبراسیون را مشخص می‌کند.

مقدار پیش‌فرض 0.0 است.

اندازه لمس جمع شده

تعریف: touch.size.isSummed = 0 | 1

مشخص می‌کند که آیا اندازه به صورت مجموع اندازه‌های تمام مخاطبین فعال گزارش شود یا برای هر مخاطب به صورت جداگانه گزارش شود.

  • اگر مقدار 1 باشد، اندازه گزارش شده قبل از استفاده بر تعداد مخاطبین تقسیم می‌شود.

  • اگر مقدار 0 باشد، اندازه گزارش شده به همان صورت استفاده می‌شود.

مقدار پیش‌فرض 0 است.

برخی از دستگاه‌های لمسی، به ویژه دستگاه‌های "نیمه لمسی" نمی‌توانند ابعاد جداگانه چندین تماس را تشخیص دهند، بنابراین اندازه‌گیری اندازه‌ای را گزارش می‌دهند که نشان دهنده مساحت یا عرض کل آنها است. این ویژگی فقط باید برای چنین دستگاه‌هایی روی 1 تنظیم شود. در صورت شک، این مقدار را روی 0 تنظیم کنید.

محاسبه

محاسبه‌ی فیلدهای touchMajor ، touchMinor ، toolMajor ، toolMinor و size به پارامترهای کالیبراسیون مشخص شده بستگی دارد.

If raw.touchMajor and raw.toolMajor are available:
    touchMajor = raw.touchMajor
    touchMinor = raw.touchMinor
    toolMajor = raw.toolMajor
    toolMinor = raw.toolMinor
Else If raw.touchMajor is available:
    toolMajor = touchMajor = raw.touchMajor
    toolMinor = touchMinor = raw.touchMinor
Else If raw.toolMajor is available:
    touchMajor = toolMajor = raw.toolMajor
    touchMinor = toolMinor = raw.toolMinor
Else
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
End If

size = avg(touchMajor, touchMinor)

If touch.size.isSummed == 1:
    touchMajor = touchMajor / numberOfActiveContacts
    touchMinor = touchMinor / numberOfActiveContacts
    toolMajor = toolMajor / numberOfActiveContacts
    toolMinor = toolMinor / numberOfActiveContacts
    size = size / numberOfActiveContacts
End If

If touch.size.calibration == "none":
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
Else If touch.size.calibration == "geometric":
    outputScale = average(output.width / raw.width, output.height / raw.height)
    touchMajor = touchMajor * outputScale
    touchMinor = touchMinor * outputScale
    toolMajor = toolMajor * outputScale
    toolMinor = toolMinor * outputScale
Else If touch.size.calibration == "area":
    touchMajor = sqrt(touchMajor)
    touchMinor = touchMajor
    toolMajor = sqrt(toolMajor)
    toolMinor = toolMajor
Else If touch.size.calibration == "diameter":
    touchMinor = touchMajor
    toolMinor = toolMajor
End If

If touchMajor != 0:
    output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
Else
    output.touchMajor = 0
End If

If touchMinor != 0:
    output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
Else
    output.touchMinor = 0
End If

If toolMajor != 0:
    output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
Else
    output.toolMajor = 0
End If

If toolMinor != 0:
    output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
Else
    output.toolMinor = 0
End If

output.size = size

میدان فشار

میدان pressure فشار فیزیکی تقریبی اعمال شده بر دستگاه لمسی را به عنوان یک مقدار نرمال شده بین 0.0 (بدون لمس) و 1.0 (فشار عادی) توصیف می‌کند.

فشار صفر نشان می‌دهد که ابزار در حال معلق بودن است.

کالیبراسیون.فشار.لمسی

تعریف: touch.pressure.calibration = none | physical | amplitude | default

نوع اندازه‌گیری مورد استفاده توسط درایور لمسی برای گزارش فشار را مشخص می‌کند.

  • اگر مقدار none باشد، فشار ناشناخته است، بنابراین هنگام لمس روی ۱.۰ و هنگام معلق ماندن روی ۰.۰ تنظیم می‌شود.

  • اگر مقدار physical باشد، فرض می‌شود محور فشار، شدت فیزیکی واقعی فشار اعمال شده بر صفحه لمسی را اندازه‌گیری می‌کند.

  • اگر مقدار amplitude باشد، فرض می‌شود محور فشار، دامنه سیگنال را اندازه‌گیری می‌کند که به اندازه تماس و فشار اعمال شده مربوط است.

  • If the value is default , the system uses the physical calibration if the pressure axis available, otherwise uses none .

touch.pressure.scale

Definition: touch.pressure.scale = <a non-negative floating point number>

Specifies a constant scale factor used in the calibration.

The default value is 1.0 / raw.pressure.max .

محاسبه

The calculation of the pressure field depends on the specified calibration parameters.

If touch.pressure.calibration == "physical" or "amplitude":
    output.pressure = raw.pressure * touch.pressure.scale
Else
    If hovering:
        output.pressure = 0
    Else
        output.pressure = 1
    End If
End If

orientation and tilt fields

The orientation field describes the orientation of the touch and tool as an angular measurement. An orientation of 0 indicates that the major axis is oriented vertically, -PI/2 indicates that the major axis is oriented to the left, PI/2 indicates that the major axis is oriented to the right. When a stylus tool is present, the orientation range can be described in a full circle range from -PI or PI .

The tilt field describes the inclination of the tool as an angular measurement. A tilt of 0 indicates that the tool is perpendicular to the surface. A tilt of PI/2 indicates that the tool is flat on the surface.

touch.orientation.calibration

Definition: touch.orientation.calibration = none | interpolated | vector | default

Specifies the kind of measurement used by the touch driver to report the orientation.

  • If the value is none , the orientation is unknown so it is set to 0.
  • If the value is interpolated , the orientation is linearly interpolated such that a raw value of raw.orientation.min maps to -PI/2 and a raw value of raw.orientation.max maps to PI/2 . The center value of (raw.orientation.min + raw.orientation.max) / 2 maps to 0 .
  • If the value is vector , the orientation is interpreted as a packed vector consisiting of two signed 4-bit fields. This representation is used on Atmel Object Based Protocol parts. When decoded, the vector yields an orientation angle and confidence magnitude. The confidence magnitude is used to scale the size information, unless it is geometric.
  • If the value is default , the system uses the interpolated calibration if the orientation axis available, otherwise uses none .

محاسبه

The calculation of the orientation and tilt fields depends on the specified calibration parameters and available input.

If touch.tiltX and touch.tiltY are available:
    tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
    tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
    tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
    tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
    output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
    output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
Else If touch.orientation.calibration == "interpolated":
    center = average(raw.orientation.min, raw.orientation.max)
    output.orientation = PI / (raw.orientation.max - raw.orientation.min)
    output.tilt = 0
Else If touch.orientation.calibration == "vector":
    c1 = (raw.orientation & 0xF0) >> 4
    c2 = raw.orientation & 0x0F

    If c1 != 0 or c2 != 0:
        If c1 >= 8 Then c1 = c1 - 16
        If c2 >= 8 Then c2 = c2 - 16
        angle = atan2(c1, c2) / 2
        confidence = sqrt(c1*c1 + c2*c2)

        output.orientation = angle

        If touch.size.calibration == "diameter" or "area":
            scale = 1.0 + confidence / 16
            output.touchMajor *= scale
            output.touchMinor /= scale
            output.toolMajor *= scale
            output.toolMinor /= scale
        End If
    Else
        output.orientation = 0
    End If
    output.tilt = 0
Else
    output.orientation = 0
    output.tilt = 0
End If

If orientation aware:
    If screen rotation is 90 degrees:
        output.orientation = output.orientation - PI / 2
    Else If screen rotation is 270 degrees:
        output.orientation = output.orientation + PI / 2
    End If
End If

distance field

The distance field describes the distance between the tool and the touch device surface. A value of 0.0 indicates direct contact and larger values indicate increasing distance from the surface.

touch.distance.calibration

Definition: touch.distance.calibration = none | scaled | default

Specifies the kind of measurement used by the touch driver to report the distance.

  • If the value is none , the distance is unknown so it is set to 0.

  • If the value is scaled , the reported distance is multiplied by a constant scale factor.

  • If the value is default , the system uses the scaled calibration if the distance axis available, otherwise uses none .

touch.distance.scale

Definition: touch.distance.scale = <a non-negative floating point number>

Specifies a constant scale factor used in the calibration.

The default value is 1.0 .

محاسبه

The calculation of the distance field depends on the specified calibration parameters.

If touch.distance.calibration == "scaled":
    output.distance = raw.distance * touch.distance.scale
Else
    output.distance = 0
End If

مثال

# Input device configuration file for a touch screen that supports pressure,
# size and orientation. The pressure and size scale factors were obtained
# by measuring the characteristics of the device itself and deriving
# useful approximations based on the resolution of the touch sensor and the
# display.
#
# Note that these parameters are specific to a particular device model.
# Different parameters need to be used for other devices.

# Basic Parameters
touch.deviceType = touchScreen
touch.orientationAware = 1

# Size
# Based on empirical measurements, we estimate the size of the contact
# using size = sqrt(area) * 28 + 0.
touch.size.calibration = area
touch.size.scale = 28
touch.size.bias = 0
touch.size.isSummed = 0

# Pressure
# Driver reports signal strength as pressure.
#
# A normal index finger touch typically registers about 80 signal strength
# units although we don't expect these values to be accurate.
touch.pressure.calibration = amplitude
touch.pressure.scale = 0.0125

# Orientation
touch.orientation.calibration = vector

یادداشت‌های سازگاری

The configuration properties for touch devices changed significantly in Android Ice Cream Sandwich 4.0. All input device configuration files for touch devices must be updated to use the new configuration properties.

Older touch device drivers might also need to be updated.

Virtual key map files

Touch devices can be used to implement virtual keys.

There are several ways of doing this, depending on the capabilities of the touch controller. Some touch controllers can be directly configured to implement soft keys by setting firmware registers. Other times it is desirable to perform the mapping from touch coordinates to key codes in software.

When virtual keys are implemented in software, the kernel must export a virtual key map file called virtualkeys.<devicename> as a board property. For example, if the touch screen device drivers reports its name as "touchyfeely" then the virtual key map file must have the path /sys/board_properties/virtualkeys.touchyfeely .

A virtual key map file describes the coordinates and Linux key codes of virtual keys on the touch screen.

In addition to the virtual key map file, there must be a corresponding key layout file and key character map file to map the Linux key codes to Android key codes and to specify the type of the keyboard device (usually SPECIAL_FUNCTION ).

نحو

A virtual key map file is a plain text file consisting of a sequence of virtual key layout descriptions either separated by newlines or by colons.

Comment lines begin with '#' and continue to the end of the line.

Each virtual key is described by 6 colon-delimited components:

  • 0x01 : A version code. Must always be 0x01 .
  • <Linux key code>: The Linux key code of the virtual key.
  • <centerX>: The X pixel coordinate of the center of the virtual key.
  • <centerY>: The Y pixel coordinate of the center of the virtual key.
  • <width>: The width of the virtual key in pixels.
  • <height>: The height of the virtual key in pixels.

All coordinates and sizes are specified in terms of the display coordinate system.

Here is a virtual key map file all written on one line.

# All on one line
0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55

The same virtual key map file can also be written on multiple lines.

# One key per line
0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

In the above example, the touch screen has a resolution of 480x800. Accordingly, all of the virtual keys have a <centerY> coordinate of 835, which is a little bit below the visible area of the touch screen.

The first key has a Linux scan code of 158 ( KEY_BACK ), centerX of 55 , centerY of 835 , width of 90 , and height of 55 .

مثال

Virtual key map file: /sys/board_properties/virtualkeys.touchyfeely .

0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

Key layout file: /system/usr/keylayout/touchyfeely.kl .

key 158 BACK
key 139 MENU
key 172 HOME
key 217 SEARCH

Key character map file: /system/usr/keychars/touchyfeely.kcm .

type SPECIAL_FUNCTION

Indirect multi-touch pointer gestures

In pointer mode, the system interprets the following gestures:

  • Single finger tap: click.
  • Single finger motion: move the pointer.
  • Single finger motion plus button presses: drag the pointer.
  • Two finger motion both fingers moving in the same direction: drag the area under the pointer in that direction. The pointer itself does not move.
  • Two finger motion both fingers moving towards each other or apart in different directions: pan/scale/rotate the area surrounding the pointer. The pointer itself does not move.
  • Multiple finger motion: freeform gesture.

Palm rejection

As of Android 13, the system can automatically reject inputs from palms when the built-in framework is enabled. In-house, custom-built solutions are still supported, though they might need to be modified to return the TOOL_TYPE_PALM flag when a palm is detected. The built-in framework also works in conjunction with custom solutions.

The actual model looks at the first 90 ms of gesture data, at the current pointer, and at the surrounding pointers, then considers how far away from the display edge the touches are. It then determines, on a per-pointer basis, which of the pointers are palms. It also takes into account the size of each contact, as reported by touchMajor and touchMinor . The Android framework then removes the pointers that are marked as palms from the touch stream.

If a pointer was already sent to the apps, then the system either:

  • (If there are other active pointers) Cancels the pointer with ACTION_POINTER_UP and FLAG_CANCELED set.
  • (If this is the only pointer) Cancels the pointer with ACTION_CANCEL .

A public API, MotionEvent.FLAG_CANCELED , indicates that the current event shouldn't trigger user action. This flag is set for both ACTION_CANCEL and ACTION_POINTER_UP .

If the palm pointer wasn't sent to apps, then the system simply drops the pointer.

Enable palm rejection

  1. In your touch driver, use the input_abs_set_res macro to set the resolutions for the following fields (units are pixels per mm ):
    • ABS_MT_POSITION_X
    • ABS_MT_POSITION_Y
    • ABS_MT_TOUCH_MAJOR
    • ABS_MT_TOUCH_MINOR

    Support for ABS_MT_TOUCH_MINOR is optional. However, if your device does support it, make sure the resolution is set correctly.

  2. To confirm the fields are set correctly, run:
        $ adb shell getevent -li
    
  3. To enable the feature during runtime, run:
        $ adb shell device_config put input_native_boot palm_rejection_enabled 1
    
  4. Restart the system_server process.
         $ adb shell stop && adb shell start
        
  5. Confirm that adb shell dumpsys input shows that there are palm rejectors inside UnwantedInteractionBlocker . If it doesn't, check the input-related logs to find clues on what might be misconfigured.

    See the following example for reference:

    UnwantedInteractionBlocker:
      mEnablePalmRejection: true
      isPalmRejectionEnabled (flag value): true
      mPalmRejectors:
        deviceId = 3:
          mDeviceInfo:
            max_x = 
            max_y = 
            x_res = 11.00
            y_res = 11.00
            major_radius_res = 1.00
            minor_radius_res = 1.00
            minor_radius_supported = true
            touch_major_res = 1
            touch_minor_res = 1
          mSlotState:
            mSlotsByPointerId:
    
            mPointerIdsBySlot:
    
          mSuppressedPointerIds: {}
    
  6. To permanently enable the feature, add the corresponding sysprop command in your init**rc file:

    setprop persist.device_config.input_native_boot.palm_rejection_enabled 1
    

مطالعه بیشتر