diff --git a/xdg/get-x-slave-devnodes/Makefile b/xdg/get-x-slave-devnodes/Makefile deleted file mode 100644 index eb9dfb8..0000000 --- a/xdg/get-x-slave-devnodes/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -get-x-slave-devnodes: get-x-slave-devnodes.c - $(CC) -O2 --std=gnu99 -pedantic -Wall get-x-slave-devnodes.c -o get-x-slave-devnodes -lX11 -lXi -clean: - rm -f get-x-slave-devnodes - diff --git a/xdg/xinput_devnodes/Makefile b/xdg/xinput_devnodes/Makefile new file mode 100644 index 0000000..a806a65 --- /dev/null +++ b/xdg/xinput_devnodes/Makefile @@ -0,0 +1,5 @@ +main: main.c + $(CC) -O2 --std=gnu99 -pedantic -Wall main.c xslaves.c devnodes.c -o devnodes -lX11 -lXi +clean: + rm -f devnodes + diff --git a/xdg/get-x-slave-devnodes/get-x-slave-devnodes.c b/xdg/xinput_devnodes/devnodes.c similarity index 70% rename from xdg/get-x-slave-devnodes/get-x-slave-devnodes.c rename to xdg/xinput_devnodes/devnodes.c index a0ea294..9a1948b 100644 --- a/xdg/get-x-slave-devnodes/get-x-slave-devnodes.c +++ b/xdg/xinput_devnodes/devnodes.c @@ -8,11 +8,13 @@ #define _GNU_SOURCE -#include -#include +#include "devnodes.h" + #include +#include #include #include +#include #include #include @@ -73,6 +75,42 @@ char* get_property_xi2(Display* dpy, int deviceid, Atom property, const char* pr return ret; } +XSlaves* build_slave_info(Display* disp) +{ + int num_slaves; + XIDeviceInfo* all_slaves = XIQueryDevice(disp, XIAllDevices, &num_slaves); + XSlaves* slaves = new_xslaves(num_slaves); + bool fail = false; + + for (int i = 0; i < num_slaves; i++) + { + XIDeviceInfo* current_slave = &all_slaves[i]; + int nprops; + Atom* props = XIListProperties(disp, current_slave->deviceid, &nprops); + + while(nprops-- && !fail) + { + char* devnode = get_property_xi2(disp, current_slave->deviceid, props[nprops], "Device Node"); + if (current_slave->name != NULL && devnode != NULL) + { + int success = add_slaveinfo(slaves, current_slave->name, devnode); + if (success != 0) + fail = true; + } + free(devnode); + } + XFree(props); + if (fail) + { + free_xslaves(slaves); + break; + } + + } + XIFreeDeviceInfo(all_slaves); + return slaves; +} + int is_xinput2_available(Display* disp) { int xiOpcode; @@ -99,103 +137,6 @@ int is_xinput2_available(Display* disp) return 0; } -typedef struct SlaveInfo -{ - char* slave_names; - char* dev_nodes; -} SlaveInfo; - -SlaveInfo new_slave_info() -{ - SlaveInfo si; - si.slave_names = NULL; - si.dev_nodes = NULL; - return si; -} - -void free_slave_info(SlaveInfo si) -{ - free(si.slave_names); - free(si.dev_nodes); - si.slave_names = NULL; - si.dev_nodes = NULL; -} - -bool is_empty_slave_info(SlaveInfo si) -{ - return (si.slave_names == NULL || si.dev_nodes == NULL); -} - -void replace(char* str, char old, char new) -{ - int i = 0; - while (str[i] != '\0') - { - if (str[i] == old) - str[i] = new; - i++; - } -} - -int append_as_line(char** dst, char* line) -{ - uint len_newstr = strlen(line) + 2; - if (*dst != NULL) - len_newstr += strlen(*dst); - - char* newstr = (char*)malloc(len_newstr); - if (newstr == NULL) - return -1; - - newstr[0] = '\0'; - replace(line, '\n', ' '); - if (*dst != NULL) - strcat(newstr, *dst); - strcat(newstr, line); - strcat(newstr, "\n"); - - free(*dst); - *dst = newstr; - return 0; -} - -SlaveInfo get_slave_info(Display* disp) -{ - int num_slaves; - XIDeviceInfo* all_slaves = XIQueryDevice(disp, XIAllDevices, &num_slaves); - SlaveInfo slaveinfo = new_slave_info(); - bool fail = false; - - for (int i = 0; i < num_slaves; i++) - { - XIDeviceInfo* current_slave = &all_slaves[i]; - int nprops; - Atom* props = XIListProperties(disp, current_slave->deviceid, &nprops); - - while(nprops-- && !fail) - { - char* devnode = get_property_xi2(disp, current_slave->deviceid, props[nprops], "Device Node"); - if (current_slave->name != NULL && devnode != NULL) - { - int append_slave_success = append_as_line(&slaveinfo.slave_names, current_slave->name); - int append_devnode_success = append_as_line(&slaveinfo.dev_nodes, devnode); - if (append_slave_success != 0 || append_devnode_success != 0) - fail = true; - } - free(devnode); - } - XFree(props); - if (fail) - { - free_slave_info(slaveinfo); - break; - } - - } - XIFreeDeviceInfo(all_slaves); - return slaveinfo; -} - Display* connect_to_x(const char* xDisplayName) { Display* disp = XOpenDisplay(xDisplayName); @@ -214,8 +155,7 @@ Display* connect_to_x(const char* xDisplayName) return disp; } - -int main(int argc, char * argv[]) +XSlaves* get_slave_info() { char* xDisplayName = getenv("DISPLAY"); if (xDisplayName == NULL) @@ -228,14 +168,21 @@ int main(int argc, char * argv[]) if (disp == NULL) exit(1); - SlaveInfo si = get_slave_info(disp); - if (!is_empty_slave_info(si)) - { - printf("%s", si.slave_names); - printf("%s", si.dev_nodes); - } - - free_slave_info(si); + XSlaves* s = build_slave_info(disp); XCloseDisplay(disp); - exit(0); + return s; } + + +// int main(int argc, char * argv[]) +// { +// XSlaves* s = get_slave_info(); +// for (int i = 0; i < s->length; i++) +// { +// XSlaveInfo si = s->slaves[i]; +// printf("Name: %s\n", si.name); +// printf("Node: %s\n", si.dev_node); +// printf("\n"); +// } +// free_xslaves(s); +// } diff --git a/xdg/xinput_devnodes/devnodes.h b/xdg/xinput_devnodes/devnodes.h new file mode 100644 index 0000000..8cde8aa --- /dev/null +++ b/xdg/xinput_devnodes/devnodes.h @@ -0,0 +1,6 @@ +#pragma once + +#include "xslaves.h" + + +XSlaves* get_slave_info(); diff --git a/xdg/xinput_devnodes/main.c b/xdg/xinput_devnodes/main.c new file mode 100644 index 0000000..d70ebb8 --- /dev/null +++ b/xdg/xinput_devnodes/main.c @@ -0,0 +1,16 @@ +#include "devnodes.h" +#include "xslaves.h" + +#include + + +int main(int argc, char** argv) { + XSlaves* xs = get_slave_info(); + for (int i=0; i < xs->length; i++) + { + XSlaveInfo si = xs->slaves[i]; + printf("%s = %s\n", si.name, si.dev_node); + } + + free_xslaves(xs); +} diff --git a/xdg/xinput_devnodes/xinput_devnodes.go b/xdg/xinput_devnodes/xinput_devnodes.go new file mode 100644 index 0000000..3bad466 --- /dev/null +++ b/xdg/xinput_devnodes/xinput_devnodes.go @@ -0,0 +1,51 @@ +package xinput_devnodes + +// #cgo CFLAGS: -g --std=gnu99 -pedantic -Wall +// #cgo LDFLAGS: -lX11 -lXi +// #include "devnodes.h" +// #include +// #include +import "C" +import ( + "fmt" + "unsafe" + "regexp" +) + + +func FindKeyboardDevNode() string { + xslaveinfos, freeMethod := GetXSlaveInfo() + defer freeMethod() + + re := regexp.MustCompile(`(?i).*keyboard.*`) + for _, xslaveinfo := range xslaveinfos { + name, devNode := C.GoString(xslaveinfo.name), C.GoString(xslaveinfo.dev_node) + if re.MatchString(name) { + return devNode + } + } + return "" +} + + +func Print() { + xslaveinfos, freeMethod := GetXSlaveInfo() + defer freeMethod() + + for _, xslaveinfo := range xslaveinfos { + fmt.Printf("%s = %s\n", C.GoString(xslaveinfo.name), C.GoString(xslaveinfo.dev_node)) + } +} + + +func GetXSlaveInfo() ([]C.XSlaveInfo, func()) { + xslaves := C.get_slave_info() + arr := (*[1 << 30]C.XSlaveInfo)(unsafe.Pointer(xslaves.slaves)) + slice := arr[:xslaves.length:xslaves.length] + freeMethod := func() { + C.free_xslaves(xslaves) + } + + return slice, freeMethod +} + diff --git a/xdg/xinput_devnodes/xslaves.c b/xdg/xinput_devnodes/xslaves.c new file mode 100644 index 0000000..a833332 --- /dev/null +++ b/xdg/xinput_devnodes/xslaves.c @@ -0,0 +1,55 @@ +#include "xslaves.h" + +#include +#include + + +XSlaveInfo new_slave_info() +{ + XSlaveInfo si; + si.name = NULL; + si.dev_node = NULL; + return si; +} + +void free_slave_info(XSlaveInfo si) +{ + free(si.name); + free(si.dev_node); + si.name = NULL; + si.dev_node = NULL; +} + +XSlaves* new_xslaves(size_t capacity) +{ + XSlaves* s = (XSlaves*)malloc(sizeof(XSlaves)); + s->capacity = capacity; + s->length = 0; + s->slaves = (XSlaveInfo*)malloc(capacity*sizeof(XSlaveInfo)); + return s; +} + +void free_xslaves(XSlaves* slaves) +{ + for (int i = 0; i < slaves->length; i++) + free_slave_info(slaves->slaves[i]); + free(slaves->slaves); + slaves->slaves = NULL; + slaves->length = 0; + slaves->capacity = 0; + free(slaves); +} + +int add_slaveinfo(XSlaves* slaves, char* name, char* dev_node) +{ + XSlaveInfo si = new_slave_info(); + si.name = strdup(name); + si.dev_node = strdup(dev_node); + if (slaves->length < slaves->capacity) + { + slaves->slaves[slaves->length] = si; + slaves->length++; + return 0; + } + return -1; +} diff --git a/xdg/xinput_devnodes/xslaves.h b/xdg/xinput_devnodes/xslaves.h new file mode 100644 index 0000000..7075bd6 --- /dev/null +++ b/xdg/xinput_devnodes/xslaves.h @@ -0,0 +1,25 @@ +#pragma once + +#include + + +typedef struct XSlaveInfo +{ + char* name; + char* dev_node; +} XSlaveInfo; + +typedef struct XSalves +{ + XSlaveInfo* slaves; + size_t capacity; + size_t length; +} XSlaves; + + +XSlaveInfo new_slave_info(); +void free_slave_info(XSlaveInfo si); + +XSlaves* new_xslaves(size_t capacity); +void free_xslaves(XSlaves* slaves); +int add_slaveinfo(XSlaves* slaves, char* name, char* dev_node);