1
0
forked from drath/libratbag

roccat: add support to write profile and macros

There is a slight difference with etekcity:
- there is no need to first set the config macro element we are about to
  send (the information are already in the macro report)
- we need to be sure the mouse processed the macro and is ready to handle
  a new command. Thus the introduction of roccat_is_ready()

We should see if the etekcity does not require such check too (IIRC it did,
but the timeout were sufficient).

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
This commit is contained in:
Benjamin Tissoires
2015-09-13 12:44:30 -04:00
committed by Benjamin Tissoires
parent 3ae353ffbf
commit 86a40ba519

View File

@@ -536,13 +536,14 @@ roccat_write_profile(struct ratbag_profile *profile)
struct roccat_data *drv_data;
int rc;
uint8_t *buf;
return 0;
uint16_t *crc;
assert(index <= ROCCAT_PROFILE_MAX);
drv_data = ratbag_get_drv_data(device);
buf = drv_data->profiles[index];
crc = (uint16_t *)&buf[ROCCAT_REPORT_SIZE_PROFILE - 2];
*crc = roccat_compute_crc(buf, ROCCAT_REPORT_SIZE_PROFILE);
roccat_set_config_profile(device, index, ROCCAT_CONFIG_KEY_MAPPING);
rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_KEY_MAPPING,
@@ -594,6 +595,7 @@ roccat_read_button(struct ratbag_button *button)
button->index);
macro = &drv_data->macros[button->profile->index][button->index];
buf = (uint8_t*)macro;
buf[0] = ROCCAT_REPORT_ID_MACRO;
rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_MACRO,
buf, ROCCAT_REPORT_SIZE_MACRO,
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
@@ -638,6 +640,26 @@ out_macro:
}
}
static int
roccat_is_ready(struct ratbag_device *device)
{
uint8_t buf[3] = { 0 };
int rc;
rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_CONFIGURE_PROFILE,
buf, sizeof(buf),
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (rc < 0)
return rc;
if (rc != sizeof(buf))
return -EIO;
if (buf[1] == 0x03)
msleep(100);
return buf[1] == 0x01;
}
static int
roccat_write_macro(struct ratbag_button *button,
const struct ratbag_button_action *action)
@@ -657,6 +679,8 @@ roccat_write_macro(struct ratbag_button *button,
macro = &drv_data->macros[button->profile->index][button->index];
buf = (uint8_t*)macro;
memset(buf, 0, ROCCAT_REPORT_SIZE_MACRO);
for (i = 0; i < MAX_MACRO_EVENTS && count < ROCCAT_MAX_MACRO_LENGTH; i++) {
if (action->macro->events[i].type == RATBAG_MACRO_EVENT_INVALID)
return -EINVAL; /* should not happen, ever */
@@ -664,38 +688,61 @@ roccat_write_macro(struct ratbag_button *button,
if (action->macro->events[i].type == RATBAG_MACRO_EVENT_NONE)
break;
/* ignore timeout events */
if (action->macro->events[i].type == RATBAG_MACRO_EVENT_WAIT)
/* ignore the first wait */
if (action->macro->events[i].type == RATBAG_MACRO_EVENT_WAIT &&
!count)
continue;
for (j = 0; j < ARRAY_LENGTH(macro_mapping); j++) {
if (macro_mapping[j] == action->macro->events[i].event.key)
macro->keys[count].keycode = j;
if (action->macro->events[i].type == RATBAG_MACRO_EVENT_KEY_PRESSED ||
action->macro->events[i].type == RATBAG_MACRO_EVENT_KEY_RELEASED) {
for (j = 0; j < ARRAY_LENGTH(macro_mapping); j++) {
if (macro_mapping[j] == action->macro->events[i].event.key)
macro->keys[count].keycode = j;
}
}
switch (action->macro->events[i].type) {
case RATBAG_MACRO_EVENT_KEY_PRESSED:
macro->keys[count].flag = 0x01;
break;
case RATBAG_MACRO_EVENT_KEY_RELEASED:
macro->keys[count].flag = 0x02;
break;
case RATBAG_MACRO_EVENT_WAIT:
macro->keys[--count].time = action->macro->events[i].event.timeout;
break;
case RATBAG_MACRO_EVENT_INVALID:
case RATBAG_MACRO_EVENT_NONE:
/* should not happen */
log_error(device->ratbag,
"something went wrong while writing a macro.\n");
}
if (action->macro->events[i].type == RATBAG_MACRO_EVENT_KEY_PRESSED)
macro->keys[count].flag = 0x00;
else
macro->keys[count].flag = 0x80;
count++;
}
macro->reportID = ROCCAT_REPORT_ID_MACRO;
macro->twentytwo = 0x22;
macro->height = 0x08;
macro->profile = button->profile->index;
macro->button_index = button->index;
macro->active = 0x01;
strcpy(macro->group, "g0");
strncpy(macro->name, action->macro->name, 23);
macro->length = count;
macro->checksum = roccat_compute_crc(buf, ROCCAT_REPORT_SIZE_MACRO);
while (!roccat_is_ready(device))
msleep(10);
roccat_set_config_profile(device,
button->profile->index,
button->index);
rc = ratbag_hidraw_raw_request(device, ROCCAT_REPORT_ID_MACRO,
buf, ROCCAT_REPORT_SIZE_MACRO,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (rc < 0)
return rc;
while (!roccat_is_ready(device))
msleep(10);
return rc == ROCCAT_REPORT_SIZE_MACRO ? 0 : -EIO;
}
@@ -852,6 +899,6 @@ struct ratbag_driver roccat_driver = {
.set_active_profile = roccat_set_current_profile,
.has_capability = roccat_has_capability,
.read_button = roccat_read_button,
// .write_button = roccat_write_button,
.write_button = roccat_write_button,
// .write_resolution_dpi = roccat_write_resolution_dpi,
};