diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index 313db38..eda0043 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -22,6 +22,7 @@ uint32_t id; uint32_t usageCount; Usage *usages; + void (*handle)(uint32_t, int32_t); } UsagePage; extern UsagePage *getUsagePage(uint32_t id); @@ -34,7 +35,7 @@ void (*handle)(int32_t); } Usage; -extern Usage *getUsage(UsagePage *usagePage, uint32_t id); +extern void handleUsage(UsagePage *usagePage, uint32_t usage, int32_t data); typedef struct { uint32_t padding; @@ -47,10 +48,11 @@ } ReportParserState; typedef struct { - Usage *usage; + uint32_t usage; uint8_t size; int32_t min, max; bool discard, relative, isSigned; + UsagePage *usagePage; } InputReader; #endif diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index 313db38..eda0043 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -22,6 +22,7 @@ uint32_t id; uint32_t usageCount; Usage *usages; + void (*handle)(uint32_t, int32_t); } UsagePage; extern UsagePage *getUsagePage(uint32_t id); @@ -34,7 +35,7 @@ void (*handle)(int32_t); } Usage; -extern Usage *getUsage(UsagePage *usagePage, uint32_t id); +extern void handleUsage(UsagePage *usagePage, uint32_t usage, int32_t data); typedef struct { uint32_t padding; @@ -47,10 +48,11 @@ } ReportParserState; typedef struct { - Usage *usage; + uint32_t usage; uint8_t size; int32_t min, max; bool discard, relative, isSigned; + UsagePage *usagePage; } InputReader; #endif diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 824183d..279931e 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,9 +26,10 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, Usage *usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; + reader->usagePage = state->usagePage; reader->usage = usage; reader->discard = (data >> 0) & 1; // signed integers are represented as 2s-complement @@ -72,31 +73,22 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, getUsage(state->usagePage, i), data, inputReaders); + insertInputReader(state, i, data, inputReaders); } } else if (usageCount == 1) { - Usage *usage = listGet(state->usages, 0); - printf("%p New input parser has usage %s for all entries\n", - state->padding, - usage ? usage->name : "Unknown" - ); + uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { insertInputReader(state, usage, data, inputReaders); } } else if (usageCount == state->reportCount) { printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; - foreach (state->usages, Usage *, usage, { - printf("%p Interpreting report %i as %s\n", - state->padding, - i++, - usage ? usage->name : "Unknown" - ); - insertInputReader(state, usage, data, inputReaders); + foreach (state->usages, void *, usage, { + insertInputReader(state, U32(usage), data, inputReaders); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, getUsage(state->usagePage, usage), data, inputReaders); + insertInputReader(state, usage, data, inputReaders); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -117,7 +109,7 @@ uint32_t data = *((uint32_t *)read); data &= 0xFFFFFFFF >> ((4 - dataSize) * 8); read += dataSize; - Usage *usage; + uint32_t usage; switch (item >> 2) { case 0: return state.totalBits; @@ -126,9 +118,8 @@ printf("%pUsagePage(%x: %s)\n", state.padding, data, state.usagePage->name); break; case 2: - usage = getUsage(state.usagePage, data); - printf("%pUsage(%x: %s)\n", state.padding, data, usage ? usage->name : "Unknown"); - listAdd(&state.usages, usage); + printf("%pUsage(%x)\n", state.padding, data); + listAdd(&state.usages, PTR(data)); break; case 0x05: printf("%pLogicalMinimum(%x)\n", state.padding, data); @@ -206,9 +197,7 @@ processedData = (int32_t)(int16_t) data; } } - if (reader->usage) { - reader->usage->handle(processedData); - } + handleUsage(reader->usagePage, reader->usage, processedData); }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index 313db38..eda0043 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -22,6 +22,7 @@ uint32_t id; uint32_t usageCount; Usage *usages; + void (*handle)(uint32_t, int32_t); } UsagePage; extern UsagePage *getUsagePage(uint32_t id); @@ -34,7 +35,7 @@ void (*handle)(int32_t); } Usage; -extern Usage *getUsage(UsagePage *usagePage, uint32_t id); +extern void handleUsage(UsagePage *usagePage, uint32_t usage, int32_t data); typedef struct { uint32_t padding; @@ -47,10 +48,11 @@ } ReportParserState; typedef struct { - Usage *usage; + uint32_t usage; uint8_t size; int32_t min, max; bool discard, relative, isSigned; + UsagePage *usagePage; } InputReader; #endif diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 824183d..279931e 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,9 +26,10 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, Usage *usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; + reader->usagePage = state->usagePage; reader->usage = usage; reader->discard = (data >> 0) & 1; // signed integers are represented as 2s-complement @@ -72,31 +73,22 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, getUsage(state->usagePage, i), data, inputReaders); + insertInputReader(state, i, data, inputReaders); } } else if (usageCount == 1) { - Usage *usage = listGet(state->usages, 0); - printf("%p New input parser has usage %s for all entries\n", - state->padding, - usage ? usage->name : "Unknown" - ); + uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { insertInputReader(state, usage, data, inputReaders); } } else if (usageCount == state->reportCount) { printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; - foreach (state->usages, Usage *, usage, { - printf("%p Interpreting report %i as %s\n", - state->padding, - i++, - usage ? usage->name : "Unknown" - ); - insertInputReader(state, usage, data, inputReaders); + foreach (state->usages, void *, usage, { + insertInputReader(state, U32(usage), data, inputReaders); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, getUsage(state->usagePage, usage), data, inputReaders); + insertInputReader(state, usage, data, inputReaders); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -117,7 +109,7 @@ uint32_t data = *((uint32_t *)read); data &= 0xFFFFFFFF >> ((4 - dataSize) * 8); read += dataSize; - Usage *usage; + uint32_t usage; switch (item >> 2) { case 0: return state.totalBits; @@ -126,9 +118,8 @@ printf("%pUsagePage(%x: %s)\n", state.padding, data, state.usagePage->name); break; case 2: - usage = getUsage(state.usagePage, data); - printf("%pUsage(%x: %s)\n", state.padding, data, usage ? usage->name : "Unknown"); - listAdd(&state.usages, usage); + printf("%pUsage(%x)\n", state.padding, data); + listAdd(&state.usages, PTR(data)); break; case 0x05: printf("%pLogicalMinimum(%x)\n", state.padding, data); @@ -206,9 +197,7 @@ processedData = (int32_t)(int16_t) data; } } - if (reader->usage) { - reader->usage->handle(processedData); - } + handleUsage(reader->usagePage, reader->usage, processedData); }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/usagePages/button.c b/src/userland/hid/usagePages/button.c index 488136a..5245bc4 100644 --- a/src/userland/hid/usagePages/button.c +++ b/src/userland/hid/usagePages/button.c @@ -5,34 +5,6 @@ REQUEST(updateButton, "mouse", "updateButton"); -void handleButton1(int32_t data) { updateButton(1, data); } -void handleButton2(int32_t data) { updateButton(2, data); } -void handleButton3(int32_t data) { updateButton(3, data); } -void handleButton4(int32_t data) { updateButton(4, data); } -void handleButton5(int32_t data) { updateButton(5, data); } - -Usage buttonUsages[] = { - { - .id = 1, - .handle = handleButton1, - .name = "Buton 1", - }, { - .id = 2, - .handle = handleButton2, - .name = "Buton 2", - }, { - .id = 3, - .handle = handleButton3, - .name = "Buton 3", - }, { - .id = 4, - .handle = handleButton4, - .name = "Buton 4", - }, { - .id = 5, - .handle = handleButton5, - .name = "Buton 5", - }, { - .id = -1, // end tag - } -}; +void handleButton(uint32_t usage, int32_t data) { + updateButton(usage, data); +} diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index 313db38..eda0043 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -22,6 +22,7 @@ uint32_t id; uint32_t usageCount; Usage *usages; + void (*handle)(uint32_t, int32_t); } UsagePage; extern UsagePage *getUsagePage(uint32_t id); @@ -34,7 +35,7 @@ void (*handle)(int32_t); } Usage; -extern Usage *getUsage(UsagePage *usagePage, uint32_t id); +extern void handleUsage(UsagePage *usagePage, uint32_t usage, int32_t data); typedef struct { uint32_t padding; @@ -47,10 +48,11 @@ } ReportParserState; typedef struct { - Usage *usage; + uint32_t usage; uint8_t size; int32_t min, max; bool discard, relative, isSigned; + UsagePage *usagePage; } InputReader; #endif diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 824183d..279931e 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,9 +26,10 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, Usage *usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; + reader->usagePage = state->usagePage; reader->usage = usage; reader->discard = (data >> 0) & 1; // signed integers are represented as 2s-complement @@ -72,31 +73,22 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, getUsage(state->usagePage, i), data, inputReaders); + insertInputReader(state, i, data, inputReaders); } } else if (usageCount == 1) { - Usage *usage = listGet(state->usages, 0); - printf("%p New input parser has usage %s for all entries\n", - state->padding, - usage ? usage->name : "Unknown" - ); + uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { insertInputReader(state, usage, data, inputReaders); } } else if (usageCount == state->reportCount) { printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; - foreach (state->usages, Usage *, usage, { - printf("%p Interpreting report %i as %s\n", - state->padding, - i++, - usage ? usage->name : "Unknown" - ); - insertInputReader(state, usage, data, inputReaders); + foreach (state->usages, void *, usage, { + insertInputReader(state, U32(usage), data, inputReaders); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, getUsage(state->usagePage, usage), data, inputReaders); + insertInputReader(state, usage, data, inputReaders); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -117,7 +109,7 @@ uint32_t data = *((uint32_t *)read); data &= 0xFFFFFFFF >> ((4 - dataSize) * 8); read += dataSize; - Usage *usage; + uint32_t usage; switch (item >> 2) { case 0: return state.totalBits; @@ -126,9 +118,8 @@ printf("%pUsagePage(%x: %s)\n", state.padding, data, state.usagePage->name); break; case 2: - usage = getUsage(state.usagePage, data); - printf("%pUsage(%x: %s)\n", state.padding, data, usage ? usage->name : "Unknown"); - listAdd(&state.usages, usage); + printf("%pUsage(%x)\n", state.padding, data); + listAdd(&state.usages, PTR(data)); break; case 0x05: printf("%pLogicalMinimum(%x)\n", state.padding, data); @@ -206,9 +197,7 @@ processedData = (int32_t)(int16_t) data; } } - if (reader->usage) { - reader->usage->handle(processedData); - } + handleUsage(reader->usagePage, reader->usage, processedData); }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/usagePages/button.c b/src/userland/hid/usagePages/button.c index 488136a..5245bc4 100644 --- a/src/userland/hid/usagePages/button.c +++ b/src/userland/hid/usagePages/button.c @@ -5,34 +5,6 @@ REQUEST(updateButton, "mouse", "updateButton"); -void handleButton1(int32_t data) { updateButton(1, data); } -void handleButton2(int32_t data) { updateButton(2, data); } -void handleButton3(int32_t data) { updateButton(3, data); } -void handleButton4(int32_t data) { updateButton(4, data); } -void handleButton5(int32_t data) { updateButton(5, data); } - -Usage buttonUsages[] = { - { - .id = 1, - .handle = handleButton1, - .name = "Buton 1", - }, { - .id = 2, - .handle = handleButton2, - .name = "Buton 2", - }, { - .id = 3, - .handle = handleButton3, - .name = "Buton 3", - }, { - .id = 4, - .handle = handleButton4, - .name = "Buton 4", - }, { - .id = 5, - .handle = handleButton5, - .name = "Buton 5", - }, { - .id = -1, // end tag - } -}; +void handleButton(uint32_t usage, int32_t data) { + updateButton(usage, data); +} diff --git a/src/userland/hid/usagePages/usagePages.c b/src/userland/hid/usagePages/usagePages.c index 8936c65..91e3ad0 100644 --- a/src/userland/hid/usagePages/usagePages.c +++ b/src/userland/hid/usagePages/usagePages.c @@ -1,7 +1,7 @@ #include extern Usage genericDesktopControlsUsages[]; -extern Usage buttonUsages[]; +extern void handleButton(uint32_t usage, int32_t data); // https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf // page 14, section 3, table 1: Usage Page Summary @@ -35,7 +35,7 @@ .usages = NULL, }, { .name = "Button", - .usages = buttonUsages, + .handle = handleButton, }, { .name = "Ordinal", .usages = NULL, @@ -79,14 +79,13 @@ return &usagePages[id]; } -Usage *getUsage(UsagePage *usagePage, uint32_t id) { - if (!usagePage || !usagePage->usages) { - return NULL; +void handleUsage(UsagePage *usagePage, uint32_t usage, int32_t data) { + if (usagePage->handle) { + return usagePage->handle(usage, data); } for (uint32_t i = 0; i < usagePage->usageCount; i++) { - if (usagePage->usages[i].id == id) { - return &usagePage->usages[i]; + if (usagePage->usages[i].id == usage) { + return usagePage->usages[i].handle(data); } } - return NULL; }