Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/pbl/services/light.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ void light_touch_up(void);
//! @copydoc app_light_enable
void light_enable(bool enable);

//! @internal
//! Drop the backlight now, as if its timeout had expired. Unlike
//! light_enable(false), does not claim app control of the light.
void light_off_now(void);

//! @internal
//! light_enable that adheres to user's backlight setting.
void light_enable_respect_settings(bool enable);
Expand Down
1 change: 1 addition & 0 deletions include/pbl/services/touch/gesture_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
typedef enum GestureEventType {
GestureEvent_Tap,
GestureEvent_DoubleTap,
GestureEvent_Palm,
} GestureEventType;

//! Gesture event data, carried directly in PebbleGestureEvent
Expand Down
1 change: 1 addition & 0 deletions include/pbl/services/touch/touch.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef enum TouchState {
typedef enum TouchGesture {
TouchGesture_Tap,
TouchGesture_DoubleTap,
TouchGesture_Palm,
} TouchGesture;

void touch_init(void);
Expand Down
15 changes: 12 additions & 3 deletions src/fw/apps/system/settings/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ enum SettingsBacklightItem {
SettingsBacklightMotionWake,
#ifdef CONFIG_TOUCH
SettingsBacklightTouchWake,
SettingsBacklightPalmSleep,
#endif
SettingsBacklightTimeout,
NumSettingsBacklightItems
Expand All @@ -362,10 +363,11 @@ static bool prv_backlight_item_is_visible(uint16_t item) {
// Always shown, even when the backlight is off.
return true;
#ifdef CONFIG_TOUCH
// The wake-on-touch row is only relevant when global touch is enabled.
// It gets hidden dynamically (not just gated at compile time) so users
// don't see a dangling backlight option that can't do anything.
// The touch rows are only relevant when global touch is enabled. They get
// hidden dynamically (not just gated at compile time) so users don't see a
// dangling backlight option that can't do anything.
case SettingsBacklightTouchWake:
case SettingsBacklightPalmSleep:
return backlight_is_enabled() && touch_is_globally_enabled();
#endif
default:
Expand Down Expand Up @@ -400,6 +402,9 @@ static void prv_backlight_select_click_cb(SettingsCallbacks *context, uint16_t r
case SettingsBacklightTouchWake:
prv_touch_wake_menu_push(data);
break;
case SettingsBacklightPalmSleep:
backlight_set_palm_sleep_enabled(!backlight_is_palm_sleep_enabled());
break;
#endif
case SettingsBacklightAmbientSensor:
light_toggle_ambient_sensor_enabled();
Expand Down Expand Up @@ -456,6 +461,10 @@ static void prv_backlight_draw_row_cb(SettingsCallbacks *context, GContext *ctx,
title = i18n_noop("Wake on touch");
subtitle = s_touch_wake_labels[backlight_get_touch_wake()];
break;
case SettingsBacklightPalmSleep:
title = i18n_noop("Palm to sleep");
subtitle = backlight_is_palm_sleep_enabled() ? i18n_noop("On") : i18n_noop("Off");
break;
#endif
case SettingsBacklightAmbientSensor:
title = i18n_noop("Ambient Sensor");
Expand Down
16 changes: 15 additions & 1 deletion src/fw/drivers/touch/cst816/cst816.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ PBL_LOG_MODULE_DEFINE(driver_touch_cst816, CONFIG_DRIVER_TOUCH_LOG_LEVEL);
#define CST816_GESTURE_CLICK 0x05
#define CST816_GESTURE_DOUBLE_CLICK 0x0B
#define CST816_GESTURE_LONG_PRESS 0x0C
#define CST816_GESTURE_PALM 0xAA

#define CST816_BOOT_MODE_REG 0xA001
#define CST816_BOOT_MODE_CMD 0xAB
Expand All @@ -68,6 +69,7 @@ PBL_LOG_MODULE_DEFINE(driver_touch_cst816, CONFIG_DRIVER_TOUCH_LOG_LEVEL);
#define CST816_WAKE_SPACING_MS 2000

static bool s_callback_scheduled = false;
static bool s_palm_down = false;
static bool s_enabled = false;
static bool s_reset_scheduled = false;
static bool s_activity_since_check = false;
Expand Down Expand Up @@ -342,7 +344,18 @@ static void prv_process_pending_messages(void* context) {
break;
}

if (press == 0x01) {
// The gesture register holds its last value, so a palm reads back as one on
// every sample it produces, its liftoff included; latch it instead.
if (press != 0x01) {
s_palm_down = false;
} else if (id == CST816_GESTURE_PALM && !s_palm_down) {
s_palm_down = true;
touch_handle_gesture(TouchGesture_Palm, point.x, point.y);
}

// A palm also reports a contact at its centroid, which would take the
// backlight the gesture just dropped and land as a tap underneath it.
if (press == 0x01 && !s_palm_down) {
touch_handle_update(TouchState_FingerDown, point.x, point.y);
} else {
touch_handle_update(TouchState_FingerUp, point.x, point.y);
Expand Down Expand Up @@ -390,6 +403,7 @@ static void prv_watchdog_cb(void *data) {

void touch_sensor_set_enabled(bool enabled) {
cst816_hw_reset();
s_palm_down = false;

if (enabled) {
exti_enable(CST816->int_exti);
Expand Down
12 changes: 12 additions & 0 deletions src/fw/kernel/event_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,18 @@ static NOINLINE void prv_minimal_event_handler(PebbleEvent* e) {
#endif

case PEBBLE_GESTURE_EVENT: {
if (e->gesture.event.type == GestureEvent_Palm) {
if (backlight_is_palm_sleep_enabled()) {
light_off_now();
#ifdef CONFIG_TOUCH
// The screen was deliberately put to sleep, so close the interaction
// session too: a stray touch afterwards must not navigate.
touch_session_reset();
#endif
}
return;
}

bool wake_on_gesture = false;
switch (backlight_get_touch_wake()) {
case BacklightTouchWake_Tap:
Expand Down
11 changes: 11 additions & 0 deletions src/fw/services/light/service.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,17 @@ void light_enable(bool enable) {
mutex_unlock(s_mutex);
}

void light_off_now(void) {
mutex_lock(s_mutex);

if (s_num_buttons_down == 0) {
s_user_controlled_state = false;
prv_change_state(LIGHT_STATE_OFF);
}

mutex_unlock(s_mutex);
}

void light_enable_respect_settings(bool enable) {
mutex_lock(s_mutex);

Expand Down
3 changes: 3 additions & 0 deletions src/fw/services/touch/touch.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ void touch_handle_gesture(TouchGesture gesture, int16_t x, int16_t y) {
PBL_ANALYTICS_ADD(gesture_double_tap_count, 1);
prv_put_gesture_event(GestureEvent_DoubleTap, x, y);
break;
case TouchGesture_Palm:
prv_put_gesture_event(GestureEvent_Palm, x, y);
break;
default:
break;
}
Expand Down
16 changes: 16 additions & 0 deletions src/fw/shell/normal/prefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ static bool s_backlight_motion_enabled = true;
#define PREF_KEY_BACKLIGHT_TOUCH "lightTouch"
static uint8_t s_backlight_touch_wake = BacklightTouchWake_DoubleTap;

#define PREF_KEY_BACKLIGHT_PALM_SLEEP "lightPalmSleep"
static bool s_backlight_palm_sleep = true;

#define PREF_KEY_TOUCH_ENABLED "touchEnabled"
static bool s_touch_enabled = true;

Expand Down Expand Up @@ -440,6 +443,11 @@ static bool prv_set_s_backlight_touch_wake(uint8_t *wake) {
return true;
}

static bool prv_set_s_backlight_palm_sleep(bool *enable) {
s_backlight_palm_sleep = *enable;
return true;
}

#ifdef CONFIG_TOUCH
// System touch navigation is active only while BOTH prefs are on: the master
// "Touch" switch (the global touch kill, PREF_KEY_TOUCH_ENABLED) and the
Expand Down Expand Up @@ -1378,6 +1386,14 @@ void backlight_set_touch_wake(BacklightTouchWake wake) {
prv_pref_set(PREF_KEY_BACKLIGHT_TOUCH, &value, sizeof(value));
}

bool backlight_is_palm_sleep_enabled(void) {
return s_backlight_palm_sleep;
}

void backlight_set_palm_sleep_enabled(bool enable) {
prv_pref_set(PREF_KEY_BACKLIGHT_PALM_SLEEP, &enable, sizeof(enable));
}

bool touch_is_globally_enabled(void) {
return s_touch_enabled;
}
Expand Down
1 change: 1 addition & 0 deletions src/fw/shell/normal/prefs_values.h.inc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#endif
PREFS_MACRO(PREF_KEY_BACKLIGHT_MOTION, s_backlight_motion_enabled)
PREFS_MACRO(PREF_KEY_BACKLIGHT_TOUCH, s_backlight_touch_wake)
PREFS_MACRO(PREF_KEY_BACKLIGHT_PALM_SLEEP, s_backlight_palm_sleep)
PREFS_MACRO(PREF_KEY_TOUCH_ENABLED, s_touch_enabled)
PREFS_MACRO(PREF_KEY_TOUCH_NAVIGATION_MENU, s_touch_navigation_menu_enabled)
PREFS_MACRO(PREF_KEY_MOTION_SENSITIVITY, s_motion_sensitivity)
Expand Down
4 changes: 4 additions & 0 deletions src/fw/shell/prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ typedef enum BacklightTouchWake {
BacklightTouchWake backlight_get_touch_wake(void);
void backlight_set_touch_wake(BacklightTouchWake wake);

// Whether covering the screen with a palm turns the backlight off.
bool backlight_is_palm_sleep_enabled(void);
void backlight_set_palm_sleep_enabled(bool enable);

// Global touch input kill-switch. When false, the kernel touch service
// drops events at the source, powers the sensor down, and the applib
// touch_service_is_enabled() query returns false to apps.
Expand Down
7 changes: 7 additions & 0 deletions src/fw/shell/prf/stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ BacklightTouchWake backlight_get_touch_wake(void) {
void backlight_set_touch_wake(BacklightTouchWake wake) {
}

bool backlight_is_palm_sleep_enabled(void) {
return false;
}

void backlight_set_palm_sleep_enabled(bool enable) {
}

bool touch_is_globally_enabled(void) {
return true;
}
Expand Down
7 changes: 7 additions & 0 deletions src/fw/shell/sdk/stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ BacklightTouchWake backlight_get_touch_wake(void) {
void backlight_set_touch_wake(BacklightTouchWake wake) {
}

bool backlight_is_palm_sleep_enabled(void) {
return false;
}

void backlight_set_palm_sleep_enabled(bool enable) {
}

bool touch_is_globally_enabled(void) {
return true;
}
Expand Down
Loading