Quantcast
Channel: xda-developers - Android Software and Hacking General [Developers Only]
Viewing all articles
Browse latest Browse all 3614

[PATCH]Various Swipe Gestures to Wake

$
0
0
Disclaimer
  • First off all, thanks to showp1984 for his original sweep2wake, based on which, this has been made.
  • I am a newbie in linux kernel programming, I did spend considerable amount of time, working with others to know about how touch input works. In many places, code will be useless, or there may be better way of implementation. Based on my understanding, I coded this.
  • This was originally made for a specific device, so I will try to explain wherever possible, so that it becomes easier for someone to implement in case they are interested.
  • This post does not show how to add hooks in touch panel driver and display driver.

Gestures Available
  • Swipe Left
  • Swipe Right
  • Swipe Up
  • Swipe Down
  • Swipe Forward Diagonally
  • Swipe Backward Diagonally
  • Draw 'L'
  • Draw 'V'

Commits
Walkthrough
First off all I modified detect_sweep2wake function.
Code:

static bool detect_sweep2wake(int x, int y, int id)
{
                key = KEY_POWER;
                if (id == 255 && s2w_touch_count > 10) {
                        int x = s2w_coord_nature();
                        if(x) {
                                if(x == 1) {
                                        if(s2w_right) {
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                                if(x == 2) {
                                        if(s2w_left){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                if(x == 3) {
                                        if(s2w_up){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                                if(x == 4) {
                                        if(s2w_down){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                                if(x == 5) {
                                        if(s2w_fwd_diag){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }   
                                if(x == 6) {
                                        if(s2w_bck_diag){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                                if(x == 7) {
                                        if(s2w_l){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                                if(x == 8) {
                                        if(s2w_v){
                                                s2w_coord_reset();
                                    doubletap2wake_reset();
                                                return true;
                                        }
                                }
                          //pr_info("%s returned true\n",__func__);
                         
                         
                }
                } else {
                        //doubletap2wake_reset();
                        s2w_coord_dump(x, y);
                        direction_vector_calc();
                        new_touch(x, y);
                }
                if (ktime_to_ms(ktime_get())-tap_time_pre > D2W_TIME){
                        s2w_coord_reset();
                        doubletap2wake_reset();
                }
                //pr_info("%s returned false\n",__func__);
                return false;
}


It now takes id as parameters as well.
id here is the touch id which is returned when we lift off contact from touch.
Do note that for this device, the id returned when we lift off contact from touch is 255, it will be different for different devices.

What this new detect_sweep2wake fn does is, it tests whether the id returned is that id (touch id which is returned when we lift off contact from touch) and the touch count is greater than a specific number or not.
The specific touch count is used to detect continuous touches (swipes).
If true, it calls for gesture detection function, if true, returns true, if false returns false.
If false, it dumps co-ordinates. Co-ordinates are dumped to 2 variables (x,y) and previous data is stored in (x_prev,y_prev). The first values of touch (the touch co-ordinates on first touch) is stored separately as well.

Then direction_vector_calc is called, which tests the nature of co-ordinates with respect to the previous one.
Code:

void direction_vector_calc(void) {
        int tot = 0;
        if(s2w_coord_count > 1) {
      if(x > x_pre) {
              dir[0]++;  //right
              tot++;
      } else if (x < x_pre) {
              dir[1]++;  //left
              tot++;
      }
      if(y < y_pre) {
              dir[2]++;  //up
              tot++;
      } else if (y > y_pre) {
              dir[3]++;  //down
              tot++;
      }
      //To determine whether both x and y co-ordinates have changed from previous input or not and act accordingly.
      if(tot > 1)
              multiple_dir++;
      //To determine max deviation in x coord.
      if(x > max_x)
              max_x = x;
      //To determine min deviation in x coord.
      if(x < min_x)
              min_x = x;
      //To determine max deviation in y coord.
      if(y > max_y)
              max_y = y;
      //To determine min deviation in y coord.
      if(y < min_y)
              min_y = y;
  } else {
          min_y = y;
          min_x = x;
          max_x = x;
          max_y = y;
  }
}


At times, there maybe cases that a co-ordinate differs from its previous co-ordinate by 2 directions. This functions take care of that too.
The readings are stored in an array an then tested by gesture detection logic.

The working of gesture_detection is explained in the extended description of this commit.
Code:

int s2w_coord_nature(void)
{
        int i = 0;
        pr_info("%s:Recieved count - %d\n",__func__,s2w_touch_count);
        pr_info("%s:max_x-%d\n",__func__,max_x);
        pr_info("%s:max_y-%d\n",__func__,max_y);
        pr_info("%s:min_x-%d\n",__func__,min_x);
        pr_info("%s:min_y-%d\n",__func__,min_y);
        /*This function detects the nature of sweep input, and on the basis of following, it returns -
        1 - sweep right
        2 - sweep left
        3 - sweep up
        4 - sweep down*/
        pr_info("%s:multiple_dir - %d\n",__func__,multiple_dir);
        for(i = 0; i < 4; i++ )
                pr_info("%s:dir[%d] - %d\n",__func__,i,dir[i]);
        if (abs(x - x_first) > 150 && abs(y - y_first) < 50 && abs(max_y - y) < 50) {
          if(dir[0] > s2w_touch_count/2) {
                    pr_info("%s:Sweep right\n",__func__);
                    return 1;
                  }
                  else if(dir[1] > s2w_touch_count/2) {
                    pr_info("%s:Sweep left\n",__func__);
                    return 2;
                  }
        }
        if (abs(y - y_first) > 150 && abs(x - x_first) < 50 && abs(max_x - x) < 50) {
          if(dir[2] > s2w_touch_count/2) {
                    pr_info("%s:Sweep up\n",__func__);
                    return 3;
                  }
                  else if(dir[3] > s2w_touch_count/2) {
                    pr_info("%s:Sweep down\n",__func__);
                    return 4;
                  }
        }
        if(abs(x - x_first) > 100 && abs(y - y_first) > 100 && (multiple_dir == s2w_touch_count - 1)) {
                if(x > x_first) {
                        pr_info("%s:Forward diagonal swipe!!\n",__func__);
                  return 5;
                }//forward diagonal swipe!!
                else if(x < x_first) {
                        pr_info("%s:Backward diagonal swipe!!\n",__func__);
                  return 6;
                }//backward diagonal swipe!!
        }
        if(abs(x - x_first) > 100 && abs(y - y_first) > 100 && (multiple_dir < s2w_touch_count - 1) && dir[0] > s2w_touch_count/3 && dir[3] > s2w_touch_count/3) {
                pr_info("%s:Draw 'L'\n",__func__);
                    return 7;
        }
        if(abs(x - x_first) > 80 && abs(y - y_first) < 50 && dir[2] > s2w_touch_count/3 && dir[3] > s2w_touch_count/3 && (multiple_dir < s2w_touch_count - 1)) {
                pr_info("%s:Draw 'V'\n",__func__);
                    return 8;
        }
       
        s2w_coord_reset();
        return 0;
       
}


If swipe matches any gesture, it returns corresponding value, else returns 0.

About toggling, I created separate files for each gesture. Also, to simplify things, I had added a master switch for these gestures.
I also made an app for this to control these toggles - Gesture Control 1.4

Credits
  • showp1984 - Without his works, this is just nothing.
  • thewisenerd - It is for this guy, I know what I know about touch panels.

Viewing all articles
Browse latest Browse all 3614

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>