מכשירי מגע

‫Android תומך במגוון מסכי מגע ומשטחי מגע, כולל טאבלטים עם דיגיטייזר מבוסס-עט.

מסכי מגע הם מכשירי מגע שמשויכים לתצוגה, כך שהמשתמש מקבל את הרושם שהוא מפעיל פריטים במסך באופן ישיר.

משטחי מגע הם מכשירי מגע שלא משויכים לתצוגה, כמו טאבלט גרפי. בדרך כלל משתמשים בלוחות מגע כדי להצביע או כדי למקם באופן עקיף או לשלוט בממשק משתמש באמצעות תנועות.

למכשירי מגע יכולים להיות לחצנים שהפונקציות שלהם דומות ללחצני העכבר.

לפעמים אפשר לתפעל מכשירי מגע באמצעות מגוון כלים שונים, כמו אצבעות או עט, בהתאם לטכנולוגיית חיישן המגע הבסיסית.

לפעמים משתמשים במכשירי מגע כדי להטמיע מקשים וירטואליים. לדוגמה, בחלק ממכשירי Android, אזור החיישן של מסך המגע מתרחב מעבר לקצה התצוגה ומשמש למטרה כפולה כחלק ממקלדת רגישה למגע.

בגלל המגוון הגדול של מכשירי מגע, מערכת Android מסתמכת על מספר רב של מאפייני הגדרה כדי לתאר את המאפיינים ואת ההתנהגות הרצויה של כל מכשיר.

סיווג מכשירי מגע

מכשיר קלט מסווג כמכשיר מולטי-טאץ' אם מתקיימים שני התנאים הבאים:

  • מכשיר הקלט מדווח על נוכחות של הצירים המוחלטים ABS_MT_POSITION_X ו-ABS_MT_POSITION_Y.
  • למכשיר הקלט אין כפתורים של בקר משחקים. התנאי הזה פותר בעיה של דו-משמעותיות בבקרים מסוימים למשחקים שמדווחים על צירים עם קודים שחופפים לקודים של הצירים של MT.

מכשיר קלט מסווג כמכשיר מגע יחיד אם מתקיימים שני התנאים הבאים:

  • מכשיר הקלט לא מסווג כמכשיר מולטי-טאץ'. מכשיר קלט מסווג כמכשיר עם מגע יחיד או כמכשיר עם מגע מרובה, אף פעם לא שניהם.
  • מכשיר הקלט מדווח על הנוכחות של הצירים המוחלטים ABS_X ו-ABS_Y, ועל הנוכחות של קוד המקש BTN_TOUCH.

כשמסווגים מכשיר קלט כמכשיר מגע, כדי לקבוע אם יש מקשים וירטואליים, המערכת מנסה לטעון את קובץ מיפוי המקשים הווירטואליים של המכשיר. אם יש מיפוי מקשים וירטואלי, נטען גם קובץ פריסת המקשים של המכשיר. מידע על המיקום והפורמט של הקבצים האלה זמין בקטע [Virtual key map files](#virtual-key-map-files).

לאחר מכן, המערכת טוענת את קובץ התצורה של מכשיר הקלט עבור מכשיר המגע.

לכל מכשירי המגע המובנים צריכים להיות קובצי הגדרה של מכשיר קלט. אם אין קובץ הגדרה של מכשיר קלט, המערכת בוחרת הגדרת ברירת מחדל שמתאימה לציוד היקפי כללי למגע, כמו מסכי מגע חיצוניים של USB או Bluetooth HID או משטחי מגע. הגדרות ברירת המחדל האלה לא מיועדות למסכי מגע מובנים, והן עלולות לגרום להתנהגות שגויה.

אחרי שההגדרה של מכשיר הקלט נטענת, המערכת מסווגת את מכשיר הקלט כמסך מגע, משטח מגע או מצביע.

  • במכשיר עם מסך מגע משתמשים כדי לתפעל ישירות אובייקטים במסך. המשתמש נוגע ישירות במסך, ולכן המערכת לא צריכה לספק אמצעים נוספים כדי לציין את האובייקטים שמבצעים בהם מניפולציה.
  • מכשיר עם משטח מגע משמש כדי לספק לאפליקציה מידע על מיקום מוחלט של מגעים באזור חיישן נתון. הוא יכול להיות שימושי לטאבלטים עם דיגיטייזר.
  • מכשיר סמן משמש לתפעול עקיף של אובייקטים במסך באמצעות סמן. האצבעות מפורשות כתנועות של מצביע מולטי-טאץ'. כלים אחרים, כמו עטים אלקטרוניים, מפורשים באמצעות מיקומים מוחלטים. מידע נוסף זמין במאמר בנושא מחוות של מצביע מגע עקיף מרובה נקודות.

הכללים הבאים משמשים לסיווג של מכשיר הקלט כמסך מגע, כלוח מגע או כמכשיר הצבעה.

  • אם המאפיין touch.deviceType מוגדר, סוג המכשיר מוגדר בהתאם.
  • אם מכשיר הקלט מדווח על נוכחות של מאפיין הקלט INPUT_PROP_DIRECT (דרך EVIOCGPROP ioctl), סוג המכשיר מוגדר כמסך מגע. התנאי הזה מניח שמכשירי מגע עם קלט ישיר מחוברים למסך שגם הוא מחובר.
  • אם מכשיר הקלט מדווח על נוכחות של מאפיין הקלט INPUT_PROP_POINTER (דרך ioctl‏ EVIOCGPROP), סוג המכשיר מוגדר כ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.

כלים וסוגי כלים

כלי הוא אצבע, עט או מכשיר אחר שמשמש לאינטראקציה עם מכשיר מגע. חלק מהמכשירים עם מסך מגע יכולים להבחין בין סוגים שונים של כלים.

במקומות אחרים ב-Android, כמו ב-MotionEvent API, כלי נקרא לעיתים קרובות מצביע.

יש תמיכה בסוגים הבאים של כלים:

  • 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 כדי לציין שהכלי נמצא רק בטווח ומרחף.
  • במכשירים עם מגע יחיד נעשה שימוש באירועי הקלט הבאים של Linux:
    • 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: (אופציונלי) מדווח על סוג הכלי.
  • במכשירים עם מגע מרובה משתמשים באירועי הקלט הבאים של Linux:
    • 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: (אופציונלי) מדווח על מזהה המשבצת של הכלי, כשמשתמשים בפרוטוקול ה-Linux למולטי-טאץ' 'B'. פרטים נוספים זמינים במסמכי התיעוד של פרוטוקול המולטי-טאץ' ב-Linux.
    • 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_* הם 1.

      התנאי הזה מרמז ש-InputReader צריך לכלול לפחות מידע מסוים על אופי הכלי, למשל אם הוא נוגע במכשיר או לפחות את סוג הכלי. אם אין מידע זמין, הכלי נחשב ללא פעיל (מחוץ לטווח).

    • כשמשתמשים בפרוטוקול מגע מרובה 'A', הכלי פעיל בכל פעם שהוא מופיע בדוח הסנכרון האחרון. כשהכלי מפסיק להופיע בדוחות הסנכרון, הוא כבר לא קיים.
    • כשמשתמשים בפרוטוקול המולטי-טאץ' 'B', הכלי פעיל כל עוד יש לו משבצת פעילה. כשמשחררים את המשבצת, הכלי מפסיק להתקיים.
  • כלי מוגדר ככלי שמוצג מעל תוכן אחר בהתאם לתנאים הבאים:
    • אם הכלי הוא BTN_TOOL_MOUSE או BTN_TOOL_LENS, הכלי לא מרחף, גם אם מתקיים אחד מהתנאים הבאים.
    • אם הכלי פעיל והדרייבר מדווח על מידע לגבי לחץ, והלחץ המדווח הוא אפס, הכלי מרחף.
    • אם הכלי פעיל והדרייבר תומך בקוד המקש BTN_TOUCH וערכו הוא אפס, הכלי מרחף.BTN_TOUCH
  • InputReader תומך בפרוטוקול ריבוי מגע 'A' וגם בפרוטוקול 'B'. נהגים חדשים צריכים להשתמש בפרוטוקול B, אבל אפשר להשתמש גם בפרוטוקול A.
  • ב-Android מגרסה 4.0 ואילך, יכול להיות שיהיה צורך לשנות את מנהלי ההתקנים של מסך המגע כדי לעמוד בדרישות של מפרט פרוטוקול הקלט של Linux.

    יכול להיות שיהיה צורך לבצע את השינויים הבאים:

    • כשכלי הופך ללא פעיל (האצבע מורמת), הוא אמור להפסיק להופיע בדוחות סנכרון מרובי מגע הבאים. כשכל הכלים לא פעילים (כל האצבעות מורמות), מנהל ההתקן צריך לשלוח חבילת דוחות סנכרון ריקה, כמו SYN_MT_REPORT ואחריה SYN_REPORT.

      בגרסאות קודמות של Android, אירועים מסוג 'למעלה' דווחו באמצעות שליחת ערך לחץ של 0. ההתנהגות הקודמת לא הייתה תואמת למפרט של פרוטוקול הקלט של Linux, והיא לא נתמכת יותר.

    • צריך לדווח על לחץ פיזי או על מידע על עוצמת האות באמצעות ABS_MT_PRESSURE.

      בגרסאות קודמות של Android, נתוני הלחץ אוחזרו מ-ABS_MT_TOUCH_MAJOR. ההתנהגות הקודמת לא הייתה תואמת למפרט של פרוטוקול הקלט של Linux, והיא לא נתמכת יותר.

    • צריך לדווח על מידע לגבי גודל המגע באמצעות ABS_MT_TOUCH_MAJOR.

      בגרסאות קודמות של Android, נתוני הגודל אוחזרו מ-ABS_MT_TOOL_MAJOR. ההתנהגות הקודמת לא הייתה תואמת למפרט של פרוטוקול הקלט של Linux, והיא לא נתמכת יותר.

    מנהלי התקנים של מכשירי מגע כבר לא צריכים התאמות אישיות ספציפיות ל-Android. הסתמכות על פרוטוקול הקלט הסטנדרטי של לינוקס מאפשרת ל-Android לתמוך במגוון רחב יותר של ציוד היקפי למגע, כמו מסכי מגע חיצוניים מסוג HID multi-touch, באמצעות מנהלי התקנים שלא עברו שינוי.

הפעלה של מכשיר מגע

בהמשך מופיע סיכום קצר של הפעולה של מכשיר מגע ב-Android.

  1. EventHub קורא אירועים גולמיים מדרייבר evdev.
  2. InputReader צורך את האירועים הגולמיים ומעדכן את המצב הפנימי לגבי המיקום ומאפיינים אחרים של כל כלי. הוא גם עוקב אחרי מצבי הלחצנים.
  3. אם נלחץ על BACK או על FORWARD או שהלחצן שוחרר, ‫InputReader מודיע ל-InputDispatcher על האירוע המרכזי.
  4. InputReader קובע אם התרחשה הקשה על מקש וירטואלי. אם כן, הוא שולח ל-InputDispatcher הודעה על האירוע המרכזי.
  5. InputReader קובעת אם ההקשה התחילה בגבולות של המסך. אם כן, הוא שולח הודעה ל-InputDispatcher על אירוע המגע.
  6. אם אין כלים שנוגעים במסך אבל יש לפחות כלי אחד שמרחף מעל המסך, InputReader מודיע ל-InputDispatcher על אירוע הריחוף.
  7. אם סוג מכשיר המגע הוא pointer,‏ InputReader מבצע זיהוי של תנועת המצביע, מזיז את המצביע ומזהה את המיקום שלו בהתאם, ומודיע ל-InputDispatcher על אירוע המצביע.
  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, או 0 אם הוא לא זמין.
raw.touchMajor
הערך של ציר ABS_MT_TOUCH_MAJOR, או 0 אם הוא לא זמין.
raw.touchMinor
הערך של ציר ABS_MT_TOUCH_MINOR, או raw.touchMajor אם הערך לא זמין.
raw.toolMajor
הערך של ציר ABS_TOOL_WIDTH או ABS_MT_WIDTH_MAJOR, או 0 אם הוא לא זמין.
raw.toolMinor
הערך של ציר ABS_MT_WIDTH_MINOR, או raw.toolMajor אם הוא לא זמין.
raw.orientation
הערך של ציר ABS_MT_ORIENTATION, או 0 אם הוא לא זמין.
raw.distance
הערך של ציר ABS_DISTANCE או ABS_MT_DISTANCE, או 0 אם הוא לא זמין.
raw.tiltX
הערך של ציר ABS_TILT_X, או 0 אם הוא לא זמין.
raw.tiltY
הערך של ציר ABS_TILT_Y, או 0 אם הוא לא זמין.

טווחי צירים גולמיים

הביטויים הבאים מציינים את הגבולות של ערכים גולמיים. הם מתקבלים על ידי קריאה ל-EVIOCGABS ioctl לכל ציר.

raw.*.min
הערך המינימלי כולל של הציר הגולמי.
raw.*.max
הערך המקסימלי של הציר הגולמי, כולל.
raw.*.range
שווה ערך ל-raw.*.max - raw.*.min.
raw.*.fuzz
הדיוק של הציר הגולמי. למשל, fuzz = 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

הגדרה: touch.deviceType = touchScreen | touchPad | pointer | default

מציין את סוג מכשיר המגע.

  • אם הערך הוא touchScreen, מכשיר המגע הוא מסך מגע שמשויך לתצוגה.

  • אם הערך הוא touchPad, מכשיר המגע הוא לוח מגע שלא משויך לצג.

  • אם הערך הוא pointer, מכשיר המגע הוא משטח מגע שלא משויך לתצוגה, והתנועות שלו משמשות לתנועות עקיפות של מצביע מולטי-טאץ'.

  • אם הערך הוא default, המערכת מזהה באופן אוטומטי את סוג המכשיר בהתאם לאלגוריתם הסיווג.

לפרטים נוספים על האופן שבו סוג המכשיר משפיע על ההתנהגות של מכשיר המגע, אפשר לעיין בקטע סיווג.

ב-Android 3 ובגרסאות קודמות, כל מכשירי המגע נחשבו למסכי מגע.

touch.orientationAware

הגדרה: touch.orientationAware = 0 | 1

ההגדרה מציינת אם מכשיר המגע צריך להגיב לשינויים בכיוון התצוגה.

  • אם הערך הוא 1, המיקומים של המגע שמדווחים על ידי מכשיר המגע מסובבים בכל פעם שכיוון התצוגה משתנה.

  • אם הערך הוא 0, מיקומי המגע שמדווחים על ידי מכשיר המגע חסינים לשינויים בכיוון התצוגה.

ערך ברירת המחדל הוא 1 אם המכשיר הוא מסך מגע, ו-0 אחרת.

המערכת מבחינה בין מסכי מגע ותצוגות פנימיים לבין מסכי מגע ותצוגות חיצוניים. מסך מגע פנימי שמודע לכיוון שלו מסתובב בהתאם לכיוון של המסך הפנימי. מסך מגע חיצוני שמודע לכיוון שלו מסתובב בהתאם לכיוון של המסך החיצוני.

המודעות לכיוון משמשת לתמיכה בסיבוב של מסכי מגע במכשירים כמו Nexus One. לדוגמה, כשמסובבים את המכשיר ב-90 מעלות בכיוון השעון מהכיוון הטבעי שלו, המיקומים המוחלטים של המגעים ממופים מחדש כך שמגע בפינה הימנית העליונה של מערכת הקואורדינטות המוחלטת של מסך המגע מדווח כמגע בפינה הימנית העליונה של מערכת הקואורדינטות המסובבת של התצוגה. הפעולה הזו מתבצעת כדי שהדיווח על מגעים יתבצע באמצעות אותה מערכת קואורדינטות שבה האפליקציות משתמשות כדי לצייר את הרכיבים החזותיים שלהן.

לפני Honeycomb, כל מכשירי המגע נחשבו למכשירים שמודעים לכיוון.

touch.gestureMode

הגדרה: touch.gestureMode = pointer | spots | default

מציינת את מצב המצגת עבור תנועות המצביע. מאפיין ההגדרה הזה רלוונטי רק כשמכשיר המגע הוא מסוג pointer.

  • אם הערך הוא pointer, מחוות לוח המגע מוצגות באמצעות סמן בדומה למצביע עכבר.

  • אם הערך הוא spots, מחוות לוח המגע מוצגות באמצעות עוגן שמייצג את מרכז המסה של המחוות וקבוצה של נקודות עגולות שמייצגות את המיקום של כל אחת מהאצבעות.

ערך ברירת המחדל הוא pointer כשהמאפיין INPUT_PROP_SEMI_MT של קלט מוגדר, או 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 ו-size

השדות 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, המערכת משתמשת בכיול geometric אם הציר raw.touchMajor או raw.toolMajor זמין, אחרת היא משתמשת בכיול none.

touch.size.scale

הגדרה: touch.size.scale = <מספר נקודה צפה לא שלילי>

מציין גורם קבוע לקביעת קנה מידה שמשמש לכיול.

ערך ברירת המחדל הוא 1.0.

touch.size.bias

הגדרה: touch.size.bias = <מספר נקודה צפה לא שלילי>

מציין ערך קבוע של הטיה שמשמש לכיול.

ערך ברירת המחדל הוא 0.0.

touch.size.isSummed

הגדרה: touch.size.isSummed = 0 | 1

ההגדרה הזו מציינת אם הגודל מדווח כסכום הגדלים של כל אנשי הקשר הפעילים, או מדווח בנפרד לכל איש קשר.

  • אם הערך הוא 1, הגודל המדווח מחולק במספר אנשי הקשר לפני השימוש.

  • אם הערך הוא 0, הגודל המדווח ישמש כמו שהוא.

ערך ברירת המחדל הוא 0.

חלק ממכשירי מגע, במיוחד מכשירי Semi-MT, לא יכולים להבחין בין המימדים הנפרדים של כמה מגעים, ולכן הם מדווחים על מדידת גודל שמייצגת את השטח הכולל או את הרוחב שלהם. המאפיין הזה צריך להיות מוגדר לערך 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

הגדרה: touch.pressure.calibration = none | physical | amplitude | default

מציין את סוג המדידה שמשמש את מנהל ההתקן של המגע כדי לדווח על הלחץ.

  • אם הערך הוא none, הלחץ לא ידוע ולכן הוא מוגדר כ-1.0 כשנוגעים במסך וכ-0.0 כשמרחפים מעליו.

  • אם הערך הוא physical, ההנחה היא שציר הלחץ מודד את עוצמת הלחץ הפיזי בפועל שמופעל על משטח המגע.

  • אם הערך הוא amplitude, ההנחה היא שציר הלחץ מודד את אמפליטודת האות, שקשורה לגודל המגע וללחץ המופעל.

  • אם הערך הוא default, המערכת משתמשת בכיול physical אם ציר הלחץ זמין, אחרת היא משתמשת ב-none.

touch.pressure.scale

הגדרה: touch.pressure.scale = <מספר נקודה צפה לא שלילי>

מציין גורם קבוע לקביעת קנה מידה שמשמש לכיול.

ערך ברירת המחדל הוא 1.0 / raw.pressure.max.

חישוב

החישוב של השדה pressure תלוי בפרמטרים של הכיול שצוינו.

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 מתאר את הכיוון של המגע והכלי כמדידה זוויתית. הכיוון 0 מציין שהציר הראשי הוא אנכי, הכיוון -PI/2 מציין שהציר הראשי הוא אופקי שמאלה והכיוון PI/2 מציין שהציר הראשי הוא אופקי ימינה. אם יש כלי של עט סטיילוס, טווח הכיוון יכול להיות טווח של עיגול מלא מ--PI או מ-PI.

בשדה tilt מתואר השיפוע של הכלי כמדידה זוויתית. הטיה של 0 מציינת שהכלי ניצב בניצב למשטח. הטיה של PI/2 מציינת שהכלי מונח שטוח על המשטח.

touch.orientation.calibration

הגדרה: touch.orientation.calibration = none | interpolated | vector | default

מציין את סוג המדידה שמשמש את מנהל ההתקן של המסך למגע כדי לדווח על הכיוון.

  • אם הערך הוא none, הכיוון לא ידוע ולכן הוא מוגדר כ-0.
  • אם הערך הוא interpolated, המערכת מבצעת אינטרפולציה לינארית של הכיוון כך שערך גולמי של raw.orientation.min ממופה ל--PI/2 וערך גולמי של raw.orientation.max ממופה ל-PI/2. הערך המרכזי של (raw.orientation.min + raw.orientation.max) / 2 ממופה ל-0.
  • אם הערך הוא vector, הכיוון מפורש כווקטור דחוס שמורכב משני שדות של 4 ביט עם סימן. הייצוג הזה משמש בחלקים של Atmel Object Based Protocol. אחרי הפענוח, הווקטור מניב זווית כיוון וגודל ודאות. הגודל של רמת הביטחון משמש לשינוי קנה המידה של פרטי הגודל, אלא אם מדובר בגיאומטריה.
  • אם הערך הוא default, המערכת משתמשת בכיול interpolated אם ציר הכיוון זמין, אחרת היא משתמשת ב-none.

חישוב

החישוב של השדות orientation ו-tilt תלוי בפרמטרים של הכיול שצוינו ובקלט שזמין.

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 מתואר המרחק בין הכלי לבין משטח מכשיר המגע. הערך 0.0 מציין מגע ישיר, וערכים גדולים יותר מציינים מרחק הולך וגדל מהמשטח.

touch.distance.calibration

הגדרה: touch.distance.calibration = none | scaled | default

מציין את סוג המדידה שמשמש את מנהל ההתקן של המגע כדי לדווח על המרחק.

  • אם הערך הוא none, המרחק לא ידוע ולכן הוא מוגדר כ-0.

  • אם הערך הוא scaled, המרחק המדווח מוכפל בפקטור קבוע של קנה מידה.

  • אם הערך הוא default, המערכת משתמשת בכיול scaled אם ציר המרחק זמין, אחרת היא משתמשת ב-none.

touch.distance.scale

הגדרה: touch.distance.scale = <מספר נקודה צפה לא שלילי>

מציין גורם קבוע לקביעת קנה מידה שמשמש לכיול.

ערך ברירת המחדל הוא 1.0.

חישוב

החישוב של השדה distance תלוי בפרמטרים של הכיול שצוינו.

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

הערות לגבי תאימות

מאפייני ההגדרה למכשירי מגע השתנו באופן משמעותי ב-Android Ice Cream Sandwich 4.0. צריך לעדכן את כל קובצי ההגדרות של מכשירי קלט למכשירי מגע כדי להשתמש במאפייני ההגדרה החדשים.

יכול להיות שיהיה צורך לעדכן גם מנהלי התקנים של מכשירים ישנים יותר עם מסך מגע.

קבצים של מיפוי מקשים וירטואליים

אפשר להשתמש במכשירי מגע כדי להטמיע מקשים וירטואליים.

יש כמה דרכים לעשות את זה, בהתאם ליכולות של בקר המגע. אפשר להגדיר ישירות חלק מבקרי המגע כך שיטמיעו מקשים רכים על ידי הגדרת רשומות קושחה. במקרים אחרים, רצוי לבצע את המיפוי מקואורדינטות של מגע לקודי מקשים בתוכנה.

כשמטמיעים מקשים וירטואליים בתוכנה, ליבת המערכת צריכה לייצא קובץ מיפוי של מקשים וירטואליים בשם virtualkeys.<devicename> כמאפיין של הלוח. לדוגמה, אם מנהלי ההתקנים של מכשיר מסך המגע מדווחים על השם שלו כ-touchyfeely, קובץ מיפוי המקשים הווירטואליים צריך לכלול את הנתיב /sys/board_properties/virtualkeys.touchyfeely.

קובץ מיפוי של מקשים וירטואליים מתאר את הקואורדינטות ואת קודי המקשים של Linux של מקשים וירטואליים במסך המגע.

בנוסף לקובץ מיפוי המקשים הווירטואלי, צריך להיות קובץ פריסת מקשים תואם וקובץ מיפוי תווים של מקשים כדי למפות את קודי המקשים של Linux לקודי המקשים של Android, וכדי לציין את סוג מכשיר המקלדת (בדרך כלל SPECIAL_FUNCTION).

תחביר

קובץ של מיפוי מקשים וירטואליים הוא קובץ טקסט פשוט שמורכב מרצף של תיאורי פריסת מקשים וירטואליים, שמופרדים בשורות חדשות או בנקודתיים.

שורות של הערות מתחילות ב-'#' וממשיכות עד סוף השורה.

כל מקש וירטואלי מתואר על ידי 6 רכיבים שמופרדים באמצעות נקודתיים:

  • 0x01: קוד גרסה. תמיד צריך להיות 0x01.
  • ‫<Linux key code>: קוד המקש של Linux של המקש הווירטואלי.
  • ‫<centerX>: קואורדינטת הפיקסל X של מרכז המקש הווירטואלי.
  • ‫<centerY>: קואורדינטת הפיקסל Y של מרכז המקש הווירטואלי.
  • ‫<width>: הרוחב של המקש הווירטואלי בפיקסלים.
  • ‫<height>: הגובה של המקש הווירטואלי בפיקסלים.

כל הקואורדינטות והגדלים מצוינים במונחים של מערכת הקואורדינטות של התצוגה.

זהו קובץ של מיפוי מקשים וירטואליים שכולו כתוב בשורה אחת.

# 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

אפשר גם לכתוב את אותו קובץ מיפוי של מקשים וירטואליים בכמה שורות.

# 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

בדוגמה שלמעלה, רזולוציית מסך המגע היא 480x800. לכן, לכל המקשים הווירטואליים יש קואורדינטה <centerY> של 835, שהיא קצת מתחת לאזור הגלוי של מסך המגע.

למפתח הראשון יש קוד סריקה של Linux‏ 158 (KEY_BACK), centerX של 55,‏ centerY של 835,‏ width של 90 ו-height של 55.

דוגמה

קובץ מיפוי מקשים וירטואלי: /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

קובץ פריסת המקשים: /system/usr/keylayout/touchyfeely.kl.

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

קובץ מיפוי תווים של המקשים: /system/usr/keychars/touchyfeely.kcm.

type SPECIAL_FUNCTION

תנועות עקיפות של מצביע מולטי-טאץ'

במצב מצביע, המערכת מפרשת את התנועות הבאות:

  • הקשה עם אצבע אחת: קליק.
  • תנועה עם אצבע אחת: הזזת הסמן.
  • תנועה של אצבע אחת בתוספת לחיצות על לחצנים: גוררים את מצביע העכבר.
  • תנועה של שתי אצבעות, שתי האצבעות נעות באותו כיוון: גוררים את האזור שמתחת לנקודת המיקום באותו כיוון. המצביע עצמו לא זז.
  • תנועה של שתי אצבעות – שתי האצבעות נעות זו לעבר זו או זו מזו בכיוונים שונים: הזזה/שינוי קנה מידה/סיבוב של האזור שמסביב למיקום הסמן. המצביע עצמו לא זז.
  • תנועה בכמה אצבעות: תנועה חופשית.

מניעת הפעלה בטעות

מגרסה Android 13 ואילך, המערכת יכולה לדחות באופן אוטומטי קלט ממגע של כפות ידיים כשהמסגרת המובנית מופעלת. עדיין יש תמיכה בפתרונות פנימיים בהתאמה אישית, אבל יכול להיות שיהיה צורך לשנות אותם כדי להחזיר את הדגל TOOL_TYPE_PALM כשמזוהה כף יד. המסגרת המובנית פועלת גם בשילוב עם פתרונות בהתאמה אישית.

המודל בפועל בודק את 90 האלפיות השנייה הראשונות של נתוני התנועות, את מיקום הסמן הנוכחי ואת הסמנים שמסביב, ואז בודק את המרחק של נקודות המגע מקצה המסך. לאחר מכן, המערכת קובעת, על בסיס כל מצביע בנפרד, אילו מהמצביעים הם כפות ידיים. הפונקציה גם לוקחת בחשבון את הגודל של כל איש קשר, כפי שמדווח על ידי touchMajor ו-touchMinor. לאחר מכן, מסגרת Android מסירה מזרם המגע את המצביעים שמסומנים ככפות ידיים.

אם כבר נשלח מצביע לאפליקציות, המערכת תבצע אחת מהפעולות הבאות:

  • (אם יש עוד מצביעים פעילים) מבטל את המצביע עם ההגדרה ACTION_POINTER_UP וFLAG_CANCELED.
  • (אם זה הסמן היחיד) מבטלים את הסמן באמצעות ACTION_CANCEL.

ממשק API ציבורי, MotionEvent.FLAG_CANCELED, מציין שהאירוע הנוכחי לא אמור להפעיל פעולת משתמש. הסימון הבוליאני הזה מוגדר גם ל-ACTION_CANCEL וגם ל-ACTION_POINTER_UP.

אם מצביע כף היד לא נשלח לאפליקציות, המערכת פשוט משמיטה את המצביע.

הפעלת מניעת הפעלה בטעות

  1. בדרייבר של מסך המגע, משתמשים בפקודת המאקרו input_abs_set_res כדי להגדיר את הרזולוציות בשדות הבאים (היחידות הן פיקסלים למילימטר):
    • ABS_MT_POSITION_X
    • ABS_MT_POSITION_Y
    • ABS_MT_TOUCH_MAJOR
    • ABS_MT_TOUCH_MINOR

    התמיכה ב-ABS_MT_TOUCH_MINOR היא אופציונלית. עם זאת, אם המכשיר שלכם תומך בכך, צריך לוודא שהרזולוציה מוגדרת בצורה נכונה.

  2. כדי לוודא שהשדות מוגדרים בצורה נכונה, מריצים את הפקודה:
        $ adb shell getevent -li
    
  3. כדי להפעיל את התכונה במהלך זמן הריצה, מריצים את:
        $ adb shell device_config put input_native_boot palm_rejection_enabled 1
    
  4. מפעילים מחדש את התהליך system_server.
         $ adb shell stop && adb shell start
        
  5. מוודאים שב-adb shell dumpsys input מופיע שיש אמצעי מניעה להפעלת מגע בטעות בתוך UnwantedInteractionBlocker. אם לא, בודקים את היומנים שקשורים לקלט כדי למצוא רמזים לגבי מה יכול להיות מוגדר בצורה שגויה.

    לדוגמה:

    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. כדי להפעיל את התכונה באופן קבוע, מוסיפים את פקודת sysprop המתאימה לקובץ init**rc:

    setprop persist.device_config.input_native_boot.palm_rejection_enabled 1
    

קריאה נוספת