Compare commits
6 Commits
55984bc7ef
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
c6f47a0981
|
|||
|
c8f3b9ba38
|
|||
|
d8b01cdaee
|
|||
|
135f336a7c
|
|||
|
b4c1817c10
|
|||
|
32ea934947
|
@@ -41,13 +41,16 @@ pkg_check_modules (libusb libusb-1.0)
|
|||||||
|
|
||||||
# On MSYS2, the CMake package cannot link statically, but pkg-config can.
|
# On MSYS2, the CMake package cannot link statically, but pkg-config can.
|
||||||
# On macOS, we explicitly want to use the CMake package.
|
# On macOS, we explicitly want to use the CMake package.
|
||||||
if (WIN32)
|
if (NOT WIN32)
|
||||||
pkg_search_module (hidapi hidapi hidapi-hidraw hidapi-libusb)
|
find_package (hidapi QUIET)
|
||||||
else ()
|
if (hidapi_FOUND)
|
||||||
find_package (hidapi)
|
|
||||||
set (hidapi_INCLUDE_DIRS)
|
set (hidapi_INCLUDE_DIRS)
|
||||||
set (hidapi_LIBRARY_DIRS)
|
set (hidapi_LIBRARY_DIRS)
|
||||||
set (hidapi_LIBRARIES hidapi::hidapi)
|
set (hidapi_LIBRARIES hidapi::hidapi)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
if (NOT hidapi_FOUND)
|
||||||
|
pkg_search_module (hidapi hidapi hidapi-hidraw hidapi-libusb)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
option (WITH_LIBUSB "Compile with libusb-based utilities" ${libusb_FOUND})
|
option (WITH_LIBUSB "Compile with libusb-based utilities" ${libusb_FOUND})
|
||||||
|
|||||||
57
README.adoc
57
README.adoc
@@ -1,6 +1,7 @@
|
|||||||
USB drivers
|
USB drivers
|
||||||
===========
|
===========
|
||||||
:compact-option:
|
:compact-option:
|
||||||
|
:source-highlighter: chroma
|
||||||
|
|
||||||
_usb-drivers_ is a collection of utilities to control various hardware over USB.
|
_usb-drivers_ is a collection of utilities to control various hardware over USB.
|
||||||
|
|
||||||
@@ -26,6 +27,60 @@ it will also suspend or power off the system, respectively.
|
|||||||
image:eizoctltray-win.png["eizoctltray on Windows with expanded menu", 343, 278]
|
image:eizoctltray-win.png["eizoctltray on Windows with expanded menu", 343, 278]
|
||||||
image:eizoctltray-mac.png["eizoctltray on macOS with expanded menu", 343, 278]
|
image:eizoctltray-mac.png["eizoctltray on macOS with expanded menu", 343, 278]
|
||||||
|
|
||||||
|
Installation
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
On Windows, copy it to
|
||||||
|
__Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup__.
|
||||||
|
|
||||||
|
On macOS, copy it to the _Applications_ folder,
|
||||||
|
then add it in _System Settings → General → Login Items → Open at Login_.
|
||||||
|
|
||||||
|
Automation
|
||||||
|
^^^^^^^^^^
|
||||||
|
_eizoctltray_ can also be used the same way as _eizoctl_, just with any output
|
||||||
|
redirected to message windows, rather than a console window or a terminal.
|
||||||
|
This is useful for automation, such as with AutoHotkey.
|
||||||
|
|
||||||
|
Beware that Windows is not a fan of how rapidly EIZO monitors switch upstream
|
||||||
|
USB ports. Thus, if you invoke port switching with keyboard shortcuts,
|
||||||
|
remember to add a small delay, so that pressed modifier keys are not remembered.
|
||||||
|
You will also want to silence any error messages.
|
||||||
|
|
||||||
|
.AutoHotkey example
|
||||||
|
```autohotkey
|
||||||
|
#Requires AutoHotkey v2.0
|
||||||
|
exe := A_Startup . "\eizoctltray.exe"
|
||||||
|
^#F1:: { ; Windows + Control + F1
|
||||||
|
Sleep 500
|
||||||
|
Run exe " -qq --input HDMI"
|
||||||
|
}
|
||||||
|
^#F2:: { ; Windows + Control + F2
|
||||||
|
Sleep 500
|
||||||
|
Run exe " -qq --input DP"
|
||||||
|
}
|
||||||
|
^#F3:: { ; Windows + Control + F3
|
||||||
|
Sleep 500
|
||||||
|
Run exe " -qq --input USB-C"
|
||||||
|
}
|
||||||
|
#Home:: { ; Windows + Home
|
||||||
|
Run exe " -q --brightness +0.1"
|
||||||
|
}
|
||||||
|
#End:: { ; Windows + End
|
||||||
|
Run exe " -q --brightness -0.1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
On macOS, the simplest way to bind keyboard shortcuts is the Shortcuts app,
|
||||||
|
with _Run Shell Scripts_ actions:
|
||||||
|
|
||||||
|
```
|
||||||
|
/Applications/eizoctltray.app/Contents/MacOS/eizoctltray -q --input HDMI
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have issues with entering a specific key combination, like I did
|
||||||
|
with ^⌘F1 etc., try changing it later within _System Settings_ → _Keyboard_ →
|
||||||
|
_Keyboard Shortcuts..._ → _Services_ → _Shortcuts_.
|
||||||
|
|
||||||
elksmart-comm
|
elksmart-comm
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
_elksmart-comm_ interfaces with ELK Smart infrared dongles EKX4S and EKX5S-T,
|
_elksmart-comm_ interfaces with ELK Smart infrared dongles EKX4S and EKX5S-T,
|
||||||
@@ -53,7 +108,7 @@ Regular releases are sporadic. git master should be stable enough.
|
|||||||
You can get a package with the latest development version
|
You can get a package with the latest development version
|
||||||
as a https://git.janouch.name/p/nixexprs[Nix derivation].
|
as a https://git.janouch.name/p/nixexprs[Nix derivation].
|
||||||
|
|
||||||
Windows binaries can be downloaded from
|
Windows/macOS binaries can be downloaded from
|
||||||
https://git.janouch.name/p/usb-drivers/releases[the Releases page on Gitea].
|
https://git.janouch.name/p/usb-drivers/releases[the Releases page on Gitea].
|
||||||
|
|
||||||
Building
|
Building
|
||||||
|
|||||||
37
eizoctl.c
37
eizoctl.c
@@ -1037,6 +1037,10 @@ eizo_watch(struct eizo_monitor *m, print_fn output, print_fn error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *usage = "Usage: %s OPTION...\n\n"
|
static const char *usage = "Usage: %s OPTION...\n\n"
|
||||||
|
" -l, --list\n"
|
||||||
|
" List all connected EIZO monitors, with their serial number.\n"
|
||||||
|
" -s, --serial SERIAL\n"
|
||||||
|
" Only act on the monitor matching the specified serial number.\n"
|
||||||
" -b, --brightness [+-]BRIGHTNESS\n"
|
" -b, --brightness [+-]BRIGHTNESS\n"
|
||||||
" Change monitor brightness; values go from 0 to 1 and may be relative.\n"
|
" Change monitor brightness; values go from 0 to 1 and may be relative.\n"
|
||||||
" -i, --input NAME\n"
|
" -i, --input NAME\n"
|
||||||
@@ -1057,6 +1061,8 @@ run(int argc, char *argv[], print_fn output, print_fn error)
|
|||||||
{
|
{
|
||||||
const char *name = argv[0];
|
const char *name = argv[0];
|
||||||
static struct option opts[] = {
|
static struct option opts[] = {
|
||||||
|
{"list", no_argument, NULL, 'l'},
|
||||||
|
{"serial", required_argument, NULL, 's'},
|
||||||
{"brightness", required_argument, NULL, 'b'},
|
{"brightness", required_argument, NULL, 'b'},
|
||||||
{"input", required_argument, NULL, 'i'},
|
{"input", required_argument, NULL, 'i'},
|
||||||
{"restart", no_argument, NULL, 'r'},
|
{"restart", no_argument, NULL, 'r'},
|
||||||
@@ -1069,11 +1075,17 @@ run(int argc, char *argv[], print_fn output, print_fn error)
|
|||||||
|
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
double brightness = NAN;
|
double brightness = NAN;
|
||||||
bool relative = false, restart = false, events = false;
|
bool list = false, relative = false, restart = false, events = false;
|
||||||
const char *port = NULL;
|
const char *serial = NULL, *port = NULL;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
while ((c = getopt_long(argc, argv, "b:i:reqhV", opts, NULL)) != -1)
|
while ((c = getopt_long(argc, argv, "ls:b:i:reqhV", opts, NULL)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'l':
|
||||||
|
list = true;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
serial = optarg;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
relative = *optarg == '+' || *optarg == '-';
|
relative = *optarg == '+' || *optarg == '-';
|
||||||
if (sscanf(optarg, "%lf", &brightness) && isfinite(brightness))
|
if (sscanf(optarg, "%lf", &brightness) && isfinite(brightness))
|
||||||
@@ -1123,8 +1135,6 @@ run(int argc, char *argv[], print_fn output, print_fn error)
|
|||||||
if (quiet > 1)
|
if (quiet > 1)
|
||||||
error = print_dummy;
|
error = print_dummy;
|
||||||
|
|
||||||
// It should be possible to choose a particular monitor,
|
|
||||||
// but it is generally more useful to operate on all of them.
|
|
||||||
struct hid_device_info *devs = hid_enumerate(USB_VID_EIZO, 0), *p = devs;
|
struct hid_device_info *devs = hid_enumerate(USB_VID_EIZO, 0), *p = devs;
|
||||||
for (; p; p = p->next) {
|
for (; p; p = p->next) {
|
||||||
struct eizo_monitor m = {};
|
struct eizo_monitor m = {};
|
||||||
@@ -1133,6 +1143,15 @@ run(int argc, char *argv[], print_fn output, print_fn error)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
output("%s %s\n", m.product, m.serial);
|
||||||
|
|
||||||
|
// Generously assuming that different products/models
|
||||||
|
// don't share serial numbers,
|
||||||
|
// which would otherwise deserve another filtering option.
|
||||||
|
if (serial && strcmp(serial, m.serial))
|
||||||
|
goto next;
|
||||||
|
|
||||||
if (isfinite(brightness)) {
|
if (isfinite(brightness)) {
|
||||||
double prev = 0.;
|
double prev = 0.;
|
||||||
if (!eizo_get_brightness(&m, &prev)) {
|
if (!eizo_get_brightness(&m, &prev)) {
|
||||||
@@ -1177,6 +1196,7 @@ run(int argc, char *argv[], print_fn output, print_fn error)
|
|||||||
error("%s\n", m.error);
|
error("%s\n", m.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
eizo_monitor_close(&m);
|
eizo_monitor_close(&m);
|
||||||
}
|
}
|
||||||
hid_free_enumeration(devs);
|
hid_free_enumeration(devs);
|
||||||
@@ -1231,10 +1251,13 @@ message_printf(const char *format, va_list ap)
|
|||||||
return NULL;
|
return NULL;
|
||||||
mbstowcs(format_wide, format, format_wide_len);
|
mbstowcs(format_wide, format, format_wide_len);
|
||||||
|
|
||||||
int message_len = vswprintf(NULL, 0, format_wide, ap) + 1;
|
// Note that just vswprintf() cannot be used like this
|
||||||
|
// (at least since mingw-w64 commit c85d64),
|
||||||
|
// and vsnwprintf() is a MinGW extension, acting like C11 vsnwprintf_s.
|
||||||
|
int message_len = vsnwprintf(NULL, 0, format_wide, ap) + 1;
|
||||||
wchar_t *message = calloc(message_len, sizeof *message);
|
wchar_t *message = calloc(message_len, sizeof *message);
|
||||||
if (message_len > 0 && message)
|
if (message_len > 0 && message)
|
||||||
vswprintf(message, message_len, format_wide, ap);
|
vsnwprintf(message, message_len, format_wide, ap);
|
||||||
|
|
||||||
free(format_wide);
|
free(format_wide);
|
||||||
return message;
|
return message;
|
||||||
|
|||||||
Reference in New Issue
Block a user