Skip to content

Commit

Permalink
Support for hall effect mouse keys: wheel support
Browse files Browse the repository at this point in the history
Also refactors the code a little
  • Loading branch information
bjonnh committed Dec 8, 2024
1 parent 1dc5cae commit e0f1d21
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 55 deletions.
25 changes: 19 additions & 6 deletions keyboards/keychron/common/analog_matrix/analog_matrix_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,34 @@ void matrix_read_rows_on_col(uint8_t current_col, matrix_row_t row_shifter) {
if ((analog_raw_matrix[row_index] & row_mask) == 0)
changed = true;

if (is_mouse_key(current_col, row_index)) {
uint16_t mouse_keycode = is_mouse_key(current_col, row_index);
if (mouse_keycode>0) {
uint8_t travel = analog_matrix_get_travel(row_index, current_col)/TRAVEL_SCALE;
uint8_t mouse_speed = ((travel * travel + travel) * 4) / 100;
if (mouse_speed == 0)
mouse_speed = 1;
if (mouse_speed > 200)
mouse_speed = 200;
if (is_vertical_mouse_key(current_col, row_index)) {
mousekey_set_speed_y(mouse_speed);
} else {
mousekey_set_speed_x(mouse_speed);
switch (mouse_keycode) {
case KC_MS_UP:
case KC_MS_DOWN:
mousekey_set_speed_y(mouse_speed);
break;
case KC_MS_LEFT:
case KC_MS_RIGHT:
mousekey_set_speed_x(mouse_speed);
break;
case KC_MS_WH_UP:
case KC_MS_WH_DOWN:
mousekey_set_speed_v(mouse_speed);
break;
case KC_MS_WH_LEFT:
case KC_MS_WH_RIGHT:
mousekey_set_speed_h(mouse_speed);
break;
}
}


if (debouce_times == ANALOG_DEBOUCE_TIME) {
row_value |= (0x01 << row_index);
} else {
Expand Down
42 changes: 27 additions & 15 deletions keyboards/keychron/common/keychron_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,33 +52,33 @@ static key_combination_t key_comb_list[4] = {
typedef struct {
uint8_t col;
uint8_t row;
uint16_t keycode;
} key_pos_t;

// An array for the 4 keys, all set to 255, 255 by default using key_post_t
key_pos_t mouse_keys_pos[4] = {
{255, 255},
{255, 255},
{255, 255},
{255, 255},
key_pos_t mouse_keys_pos[8] = {
{255, 255, KC_MS_UP},
{255, 255, KC_MS_DOWN},
{255, 255, KC_MS_LEFT},
{255, 255, KC_MS_RIGHT},
{255, 255, KC_MS_WH_UP},
{255, 255, KC_MS_WH_DOWN},
{255, 255, KC_MS_WH_LEFT},
{255, 255, KC_MS_WH_RIGHT},
};

void set_mouse_key_last_key_pos(uint8_t pos, uint8_t col, uint8_t row) {
if (pos>3) return;
if (pos>7) return;
mouse_keys_pos[pos].col = col;
mouse_keys_pos[pos].row = row;
}

inline bool is_mouse_key(uint8_t col, uint8_t row) {
for (uint8_t i = 0; i < 4; i++) {
uint16_t is_mouse_key(uint8_t col, uint8_t row) {
for (uint8_t i = 0; i < 8; i++) {
if (mouse_keys_pos[i].col == col && mouse_keys_pos[i].row == row) {
return true;
return mouse_keys_pos[i].keycode;
}
}
return false;
}

inline bool is_vertical_mouse_key(uint8_t col, uint8_t row) {
return (mouse_keys_pos[0].col == col && mouse_keys_pos[0].row == row) || (mouse_keys_pos[1].col == col && mouse_keys_pos[1].row == row);
return 0;
}

bool process_record_keychron_common(uint16_t keycode, keyrecord_t *record) {
Expand Down Expand Up @@ -145,6 +145,18 @@ bool process_record_keychron_common(uint16_t keycode, keyrecord_t *record) {
case KC_MS_RIGHT:
set_mouse_key_last_key_pos(3, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_UP:
set_mouse_key_last_key_pos(4, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_DOWN:
set_mouse_key_last_key_pos(5, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_LEFT:
set_mouse_key_last_key_pos(6, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_RIGHT:
set_mouse_key_last_key_pos(7, record->event.key.col, record->event.key.row);
break;
default:
#ifdef ANANLOG_MATRIX
return process_record_profile( keycode, record);
Expand Down
3 changes: 1 addition & 2 deletions keyboards/keychron/common/keychron_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ void keychron_common_task(void);
void set_mouse_vertical_last_key_pos(uint8_t col, uint8_t row);
void set_mouse_horizontal_last_key_pos(uint8_t col, uint8_t row);
void set_mouse_key_last_key_pos(uint8_t pos, uint8_t col, uint8_t row);
bool is_mouse_key(uint8_t col, uint8_t row);
bool is_vertical_mouse_key(uint8_t col, uint8_t row);
uint16_t is_mouse_key(uint8_t col, uint8_t row);

#ifdef ENCODER_ENABLE
void encoder_cb_init(void);
Expand Down
69 changes: 37 additions & 32 deletions quantum/mousekey.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ static uint8_t mousekey_wheel_repeat = 0;
static uint8_t mousekey_variable = MOUSEKEY_VARIABLE;
static uint8_t mousekey_speed_x = 1;
static uint8_t mousekey_speed_y = 1;
static uint8_t mousekey_speed_h = 1;
static uint8_t mousekey_speed_v = 1;
#
#ifdef MOUSEKEY_INERTIA
static uint8_t mousekey_frame = 0; // track whether gesture is inactive, first frame, or repeating
static int8_t mousekey_x_dir = 0; // -1 / 0 / 1 = left / neutral / right
Expand Down Expand Up @@ -95,9 +98,15 @@ uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;

/* Default accelerated mode */

static uint8_t move_unit(void) {
static uint8_t move_unit(uint8_t axis) {
uint16_t unit;
if (mousekey_accel & (1 << 0)) {
if (mousekey_variable) {
if (axis) {
unit = mousekey_speed_x;
} else {
unit = mousekey_speed_y;
}
} else if (mousekey_accel & (1 << 0)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4;
} else if (mousekey_accel & (1 << 1)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
Expand All @@ -113,6 +122,8 @@ static uint8_t move_unit(void) {
return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
}

/* Used to set acceleration from other means such as hall effect */

void mousekey_set_speed_x(uint8_t speed) {
mousekey_speed_x = speed;
}
Expand All @@ -121,24 +132,12 @@ void mousekey_set_speed_y(uint8_t speed) {
mousekey_speed_y = speed;
}

static uint8_t move_unit_x(void) {
uint16_t unit;
if (mousekey_variable) {
unit = mousekey_speed_x;
} else {
unit = move_unit();
}
return unit;
void mousekey_set_speed_h(uint8_t speed) {
mousekey_speed_h = speed;
}

static uint8_t move_unit_y(void) {
uint16_t unit;
if (mousekey_variable) {
unit = mousekey_speed_y;
} else {
unit = move_unit();
}
return unit;
void mousekey_set_speed_v(uint8_t speed) {
mousekey_speed_v = speed;
}

# else // MOUSEKEY_INERTIA mode
Expand Down Expand Up @@ -188,9 +187,15 @@ static int8_t move_unit(uint8_t axis) {

# endif // end MOUSEKEY_INERTIA mode

static uint8_t wheel_unit(void) {
static uint8_t wheel_unit(uint8_t axis) {
uint16_t unit;
if (mousekey_accel & (1 << 0)) {
if (mousekey_variable) {
if (axis) {
unit = mousekey_speed_h;
} else {
unit = mousekey_speed_v;
}
} else if (mousekey_accel & (1 << 0)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4;
} else if (mousekey_accel & (1 << 1)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
Expand Down Expand Up @@ -372,8 +377,8 @@ void mousekey_task(void) {

if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {
if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
if (tmpmr.x != 0) mouse_report.x = move_unit_x() * ((tmpmr.x > 0) ? 1 : -1);
if (tmpmr.y != 0) mouse_report.y = move_unit_y() * ((tmpmr.y > 0) ? 1 : -1);
if (tmpmr.x != 0) mouse_report.x = move_unit(1) * ((tmpmr.x > 0) ? 1 : -1);
if (tmpmr.y != 0) mouse_report.y = move_unit(0) * ((tmpmr.y > 0) ? 1 : -1);

/* diagonal move [1/sqrt(2)] */
if (mouse_report.x && mouse_report.y) {
Expand All @@ -392,8 +397,8 @@ void mousekey_task(void) {

if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++;
if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1);
if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1);
if (tmpmr.v != 0) mouse_report.v = wheel_unit(0) * ((tmpmr.v > 0) ? 1 : -1);
if (tmpmr.h != 0) mouse_report.h = wheel_unit(1) * ((tmpmr.h > 0) ? 1 : -1);

/* diagonal move [1/sqrt(2)] */
if (mouse_report.v && mouse_report.h) {
Expand Down Expand Up @@ -449,24 +454,24 @@ void mousekey_on(uint8_t code) {
# else // no inertia

if (code == KC_MS_UP)
mouse_report.y = move_unit_y() * -1;
mouse_report.y = move_unit(0) * -1;
else if (code == KC_MS_DOWN)
mouse_report.y = move_unit_y();
mouse_report.y = move_unit(0);
else if (code == KC_MS_LEFT)
mouse_report.x = move_unit_x() * -1;
mouse_report.x = move_unit(1) * -1;
else if (code == KC_MS_RIGHT)
mouse_report.x = move_unit_x();
mouse_report.x = move_unit(1);

# endif // inertia or not

else if (code == KC_MS_WH_UP)
mouse_report.v = wheel_unit();
mouse_report.v = wheel_unit(0);
else if (code == KC_MS_WH_DOWN)
mouse_report.v = wheel_unit() * -1;
mouse_report.v = wheel_unit(0) * -1;
else if (code == KC_MS_WH_LEFT)
mouse_report.h = wheel_unit() * -1;
mouse_report.h = wheel_unit(1) * -1;
else if (code == KC_MS_WH_RIGHT)
mouse_report.h = wheel_unit();
mouse_report.h = wheel_unit(1);
else if (IS_MOUSEKEY_BUTTON(code))
mouse_report.buttons |= 1 << (code - KC_MS_BTN1);
else if (code == KC_MS_ACCEL0)
Expand Down
2 changes: 2 additions & 0 deletions quantum/mousekey.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ void mousekey_clear(void);
void mousekey_send(void);
void mousekey_set_speed_x(uint8_t);
void mousekey_set_speed_y(uint8_t);
void mousekey_set_speed_h(uint8_t);
void mousekey_set_speed_v(uint8_t);
report_mouse_t mousekey_get_report(void);
bool should_mousekey_report_send(report_mouse_t *mouse_report);

Expand Down

0 comments on commit e0f1d21

Please sign in to comment.