123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- /*
- * Razer device access library
- * Profile emulation
- *
- * Copyright (C) 2011 Michael Buesch <m@bues.ch>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include "profile_emulation.h"
- static int mouse_profemu_commit(struct razer_mouse_profile_emu *emu)
- {
- struct razer_mouse_profile *hw_profile = emu->hw_profile;
- unsigned int active_prof_nr = emu->active_profile->nr;
- struct razer_mouse_profile_emu_data *data;
- struct razer_mouse *mouse = emu->mouse;
- unsigned int i;
- int err;
- if (WARN_ON(active_prof_nr >= ARRAY_SIZE(emu->data)))
- return -EINVAL;
- data = &emu->data[active_prof_nr];
- err = mouse->claim(mouse);
- if (err) {
- razer_error("profile emulation: Failed to claim mouse\n");
- return err;
- }
- if (hw_profile->set_dpimapping) {
- struct razer_axis *axes = NULL;
- if (mouse->supported_axes) {
- err = mouse->supported_axes(mouse, &axes);
- if (err < 0)
- goto error;
- WARN_ON((unsigned int)err != data->nr_dpimappings);
- }
- for (i = 0; i < data->nr_dpimappings; i++) {
- if (!data->dpimappings[i])
- continue;
- err = hw_profile->set_dpimapping(
- hw_profile,
- axes ? &axes[i] : NULL,
- data->dpimappings[i]);
- if (err)
- goto error;
- }
- }
- if (hw_profile->set_button_function) {
- struct razer_button *buttons = NULL;
- if (mouse->supported_buttons) {
- err = mouse->supported_buttons(mouse, &buttons);
- if (err < 0)
- goto error;
- WARN_ON((unsigned int)err != data->nr_butfuncs);
- }
- for (i = 0; i < data->nr_butfuncs; i++) {
- if (!data->butfuncs[i])
- continue;
- err = hw_profile->set_button_function(
- hw_profile,
- buttons ? &buttons[i] : NULL,
- data->butfuncs[i]);
- if (err)
- goto error;
- }
- }
- if (hw_profile->set_freq) {
- err = hw_profile->set_freq(hw_profile, data->freq);
- if (err)
- goto error;
- }
- mouse->release(mouse);
- razer_debug("profile emulation: Committed active profile\n");
- return 0;
- error:
- razer_error("profile emulation: Failed to commit settings\n");
- mouse->release(mouse);
- return err;
- }
- static const razer_utf16_t * mouse_profemu_get_name(struct razer_mouse_profile *p)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return NULL;
- return emu->data[p->nr].name;
- }
- static int mouse_profemu_set_name(struct razer_mouse_profile *p,
- const razer_utf16_t *new_name)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return -EINVAL;
- razer_utf16_cpy(emu->data[p->nr].name, new_name, PROFEMU_NAME_MAX);
- return 0;
- }
- static enum razer_mouse_freq mouse_profemu_get_freq(struct razer_mouse_profile *p)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return RAZER_MOUSE_FREQ_UNKNOWN;
- return emu->data[p->nr].freq;
- }
- static int mouse_profemu_set_freq(struct razer_mouse_profile *p,
- enum razer_mouse_freq freq)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return -EINVAL;
- emu->data[p->nr].freq = freq;
- if (p == emu->active_profile)
- return mouse_profemu_commit(emu);
- return 0;
- }
- static struct razer_mouse_dpimapping * mouse_profemu_get_dpimapping(
- struct razer_mouse_profile *p,
- struct razer_axis *axis)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- struct razer_mouse_profile_emu_data *data;
- unsigned int axis_index;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return NULL;
- data = &emu->data[p->nr];
- axis_index = axis ? axis->id : 0;
- if (WARN_ON(axis_index >= ARRAY_SIZE(data->dpimappings)))
- return NULL;
- return data->dpimappings[axis_index];
- }
- static int mouse_profemu_set_dpimapping(struct razer_mouse_profile *p,
- struct razer_axis *axis,
- struct razer_mouse_dpimapping *d)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- struct razer_mouse_profile_emu_data *data;
- unsigned int i;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return -EINVAL;
- data = &emu->data[p->nr];
- if (axis) {
- if (WARN_ON(axis->id >= ARRAY_SIZE(data->dpimappings)))
- return -EINVAL;
- data->dpimappings[axis->id] = d;
- } else {
- for (i = 0; i < data->nr_dpimappings; i++) {
- if (data->dpimappings[i])
- data->dpimappings[i] = d;
- }
- }
- if (p == emu->active_profile)
- return mouse_profemu_commit(emu);
- return 0;
- }
- static struct razer_button_function * mouse_profemu_get_button_function(
- struct razer_mouse_profile *p,
- struct razer_button *b)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- struct razer_mouse_profile_emu_data *data;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return NULL;
- data = &emu->data[p->nr];
- if (WARN_ON(b->id >= ARRAY_SIZE(data->butfuncs)))
- return NULL;
- return data->butfuncs[b->id];
- }
- static int mouse_profemu_set_button_function(struct razer_mouse_profile *p,
- struct razer_button *b,
- struct razer_button_function *f)
- {
- struct razer_mouse *mouse = p->mouse;
- struct razer_mouse_profile_emu *emu = mouse->profemu;
- struct razer_mouse_profile_emu_data *data;
- if (WARN_ON(p->nr >= ARRAY_SIZE(emu->profiles)))
- return -EINVAL;
- data = &emu->data[p->nr];
- if (WARN_ON(b->id >= ARRAY_SIZE(data->butfuncs)))
- return -EINVAL;
- data->butfuncs[b->id] = f;
- if (p == emu->active_profile)
- return mouse_profemu_commit(emu);
- return 0;
- }
- static struct razer_mouse_profile * mouse_profemu_get(struct razer_mouse *m)
- {
- return &m->profemu->profiles[0];
- }
- static struct razer_mouse_profile * mouse_profemu_get_active(struct razer_mouse *m)
- {
- return m->profemu->active_profile;
- }
- static int mouse_profemu_set_active(struct razer_mouse *m,
- struct razer_mouse_profile *p)
- {
- struct razer_mouse_profile_emu *emu = m->profemu;
- if (p == emu->active_profile)
- return 0;
- emu->active_profile = p;
- return mouse_profemu_commit(emu);
- }
- static void mouse_profemu_initial_name(razer_utf16_t *namebuf, unsigned int profnr)
- {
- char name[PROFEMU_NAME_MAX + 1];
- switch (profnr) {
- case 0:
- snprintf(name, sizeof(name), "Desktop");
- break;
- case 1:
- snprintf(name, sizeof(name), "FPS gaming");
- break;
- case 2:
- snprintf(name, sizeof(name), "RPG gaming");
- break;
- case 3:
- snprintf(name, sizeof(name), "Generic gaming");
- break;
- case 4:
- snprintf(name, sizeof(name), "CAD");
- break;
- default:
- snprintf(name, sizeof(name), "Profile %u", profnr + 1);
- }
- razer_ascii_to_utf16(namebuf, PROFEMU_NAME_MAX, name);
- }
- int razer_mouse_init_profile_emulation(struct razer_mouse *m)
- {
- struct razer_mouse_profile_emu *emu;
- struct razer_mouse_profile_emu_data *data;
- struct razer_mouse_profile *prof, *hw_profile;
- unsigned int i, j;
- int err;
- struct razer_axis *axes = NULL;
- int nr_axes = 1;
- struct razer_button *buttons = NULL;
- int nr_buttons = 0;
- emu = zalloc(sizeof(*emu));
- if (!emu)
- return -ENOMEM;
- emu->mouse = m;
- hw_profile = m->get_profiles(m);
- emu->hw_profile = hw_profile;
- if (WARN_ON(!emu->hw_profile))
- goto err_free;
- if (m->supported_axes) {
- nr_axes = m->supported_axes(m, &axes);
- if (WARN_ON(nr_axes < 0))
- goto err_free;
- }
- if (m->supported_buttons) {
- nr_buttons = m->supported_buttons(m, &buttons);
- if (WARN_ON(nr_buttons < 0))
- goto err_free;
- }
- for (i = 0; i < ARRAY_SIZE(emu->profiles); i++) {
- prof = &emu->profiles[i];
- data = &emu->data[i];
- prof->mouse = m;
- prof->nr = i;
- prof->get_name = mouse_profemu_get_name;
- prof->set_name = mouse_profemu_set_name;
- /* Assign callbacks, if the driver supports the feature. */
- //TODO LEDs
- if (hw_profile->get_freq)
- prof->get_freq = mouse_profemu_get_freq;
- if (hw_profile->set_freq)
- prof->set_freq = mouse_profemu_set_freq;
- if (hw_profile->get_dpimapping)
- prof->get_dpimapping = mouse_profemu_get_dpimapping;
- if (hw_profile->set_dpimapping)
- prof->set_dpimapping = mouse_profemu_set_dpimapping;
- if (hw_profile->get_button_function)
- prof->get_button_function = mouse_profemu_get_button_function;
- if (hw_profile->set_button_function)
- prof->set_button_function = mouse_profemu_set_button_function;
- /* Load initial settings */
- mouse_profemu_initial_name(data->name, i);
- if (hw_profile->get_freq)
- data->freq = hw_profile->get_freq(hw_profile);
- if (hw_profile->get_dpimapping) {
- for (j = 0; j < (unsigned int)nr_axes; j++) {
- if (WARN_ON(j >= ARRAY_SIZE(data->dpimappings)))
- break;
- if (!axes || (axes[j].flags & RAZER_AXIS_INDEPENDENT_DPIMAPPING)) {
- data->dpimappings[j] = hw_profile->get_dpimapping(
- hw_profile,
- axes ? &axes[j] : NULL);
- }
- }
- data->nr_dpimappings = j;
- }
- if (hw_profile->get_button_function) {
- for (j = 0; j < (unsigned int)nr_buttons; j++) {
- if (WARN_ON(j >= ARRAY_SIZE(data->butfuncs)))
- break;
- data->butfuncs[j] = hw_profile->get_button_function(
- hw_profile,
- buttons ? &buttons[j] : NULL);
- }
- data->nr_butfuncs = j;
- }
- }
- emu->active_profile = &emu->profiles[0];
- err = mouse_profemu_commit(emu);
- if (err)
- goto err_free;
- m->nr_profiles = ARRAY_SIZE(emu->profiles);
- m->get_profiles = mouse_profemu_get;
- m->get_active_profile = mouse_profemu_get_active;
- m->set_active_profile = mouse_profemu_set_active;
- m->profemu = emu;
- m->flags |= RAZER_MOUSEFLG_PROFEMU;
- razer_debug("Mouse profile emulation initialized for %s\n", m->idstr);
- return 0;
- err_free:
- razer_free(emu, sizeof(*emu));
- return -EINVAL;
- }
- void razer_mouse_exit_profile_emulation(struct razer_mouse *m)
- {
- struct razer_mouse_profile_emu *emu;
- if (!(m->flags & RAZER_MOUSEFLG_PROFEMU))
- return;
- emu = m->profemu;
- m->nr_profiles = 0;
- m->get_profiles = NULL;
- m->get_active_profile = NULL;
- m->set_active_profile = NULL;
- m->profemu = NULL;
- m->flags &= ~RAZER_MOUSEFLG_PROFEMU;
- razer_free(emu, sizeof(*emu));
- }
|