mirror of
https://github.com/rfc2822/GfxTablet
synced 2025-10-03 01:29:17 +02:00
added multi-monitor support
This commit is contained in:
parent
ff865c297b
commit
c816f756b3
3 changed files with 117 additions and 6 deletions
|
@ -1,2 +1,2 @@
|
|||
|
||||
networktablet : networktablet.c protocol.h
|
||||
export CC=c99
|
||||
networktablet : networktablet.c protocol.h -lX11 -lXrandr
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uinput.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <dirent.h>
|
||||
#include "protocol.h"
|
||||
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <getopt.h>
|
||||
#define die(str, args...) { \
|
||||
perror(str); \
|
||||
exit(EXIT_FAILURE); \
|
||||
|
@ -19,7 +22,12 @@
|
|||
|
||||
|
||||
int udp_socket;
|
||||
|
||||
// parse args
|
||||
int screenId = -1;
|
||||
int width = -1;
|
||||
int height = -1;
|
||||
int xOffset = 0;
|
||||
int yOffset = 0;
|
||||
|
||||
void init_device(int fd)
|
||||
{
|
||||
|
@ -93,9 +101,83 @@ void quit(int signal) {
|
|||
close(udp_socket);
|
||||
}
|
||||
|
||||
gfx_host_monitor* getMonitors() {
|
||||
unsigned size = sizeof(gfx_host_monitor);
|
||||
Display *display = XOpenDisplay(0);
|
||||
Window root = RootWindow(display, 0);
|
||||
|
||||
int main(void)
|
||||
XRRScreenResources* screenResources = XRRGetScreenResources(display, root);
|
||||
RROutput primary = XRRGetOutputPrimary(display, root);
|
||||
|
||||
int screenCount = 0;
|
||||
gfx_host_monitor* monitors = malloc(size);
|
||||
for (int i = 0; i < screenResources->ncrtc; i++) {
|
||||
XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(display, screenResources, screenResources->crtcs[i]);
|
||||
|
||||
for (int j = 0; j < crtcInfo->noutput; j++) {
|
||||
XRROutputInfo* outputInfo = XRRGetOutputInfo(display, screenResources, crtcInfo->outputs[j]);
|
||||
|
||||
if (outputInfo->connection != RR_Connected) {
|
||||
XRRFreeOutputInfo(outputInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
size += sizeof(gfx_host_monitor);
|
||||
gfx_host_monitor* rallac = realloc(monitors, size);
|
||||
if (rallac) {
|
||||
monitors = rallac;
|
||||
if (screenCount > 0) {
|
||||
monitors[i].x = crtcInfo->x + monitors[i - 1].x;
|
||||
monitors[i].y = crtcInfo->y + monitors[i - 1].x;
|
||||
} else {
|
||||
monitors[i].x = crtcInfo->x;
|
||||
monitors[i].y = crtcInfo->y;
|
||||
}
|
||||
monitors[i].width = crtcInfo->width;
|
||||
monitors[i].height = crtcInfo->height;
|
||||
monitors[i].mm_width = outputInfo->mm_width;
|
||||
monitors[i].mm_height = outputInfo->mm_height;
|
||||
} else {
|
||||
//
|
||||
}
|
||||
|
||||
XRRFreeOutputInfo(outputInfo);
|
||||
screenCount++;
|
||||
}
|
||||
XRRFreeCrtcInfo(crtcInfo);
|
||||
}
|
||||
|
||||
XRRFreeScreenResources(screenResources);
|
||||
for (unsigned i = 0; i < screenCount; i++) {
|
||||
printf("Monitor %d: w:%d h:%d x:%d y:%d\n", i, monitors[i].width, monitors[i].height, monitors[i].x, monitors[i].y);
|
||||
}
|
||||
|
||||
return monitors;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Display *display = XOpenDisplay(NULL);
|
||||
Window root = RootWindow(display, 0);
|
||||
int totalWidth = width = XDisplayWidth(display, 0);
|
||||
int totalHeight = height = XDisplayHeight(display, 0);
|
||||
|
||||
printf("totalWidth %d\n", totalWidth);
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "s:w:h:x:y:")) != -1) {
|
||||
switch (opt) {
|
||||
case 's': screenId = atoi(optarg); break;
|
||||
case 'w': width = atoi(optarg); break;
|
||||
case 'h': height = atoi(optarg); break;
|
||||
case 'x': xOffset = atoi(optarg); break;
|
||||
case 'y': yOffset = atoi(optarg); break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [-s=SCREEN_NO -w=WIDTH -h=HEIGHT -x=X_OFFSET -y=Y-OFFSET]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int device;
|
||||
struct event_packet ev_pkt;
|
||||
|
||||
|
@ -111,6 +193,18 @@ int main(void)
|
|||
signal(SIGINT, quit);
|
||||
signal(SIGTERM, quit);
|
||||
|
||||
gfx_host_monitor* monitors = getMonitors();
|
||||
|
||||
if (screenId != -1) {
|
||||
if (width == -1)
|
||||
width = monitors[screenId].width;
|
||||
if (height == -1)
|
||||
height = monitors[screenId].height;
|
||||
xOffset = monitors[screenId].x + xOffset;
|
||||
yOffset = monitors[screenId].y + yOffset;
|
||||
}
|
||||
|
||||
//print_screen_information();
|
||||
while (recv(udp_socket, &ev_pkt, sizeof(ev_pkt), 0) >= 9) { // every packet has at least 9 bytes
|
||||
printf("."); fflush(0);
|
||||
|
||||
|
@ -130,9 +224,16 @@ int main(void)
|
|||
ev_pkt.pressure = ntohs(ev_pkt.pressure);
|
||||
printf("x: %hi, y: %hi, pressure: %hi\n", ev_pkt.x, ev_pkt.y, ev_pkt.pressure);
|
||||
|
||||
ev_pkt.x = ev_pkt.x * (float) totalWidth / SHRT_MAX;
|
||||
ev_pkt.x = ev_pkt.x * (float) width / totalWidth;
|
||||
ev_pkt.x = (short) ((float) SHRT_MAX / totalWidth * (xOffset + ev_pkt.x));
|
||||
ev_pkt.y = ev_pkt.y * (float) totalHeight / SHRT_MAX;
|
||||
ev_pkt.y = ev_pkt.y * (float) height / totalHeight;
|
||||
ev_pkt.y = (short) ((float) SHRT_MAX / totalHeight * (yOffset + ev_pkt.y));
|
||||
send_event(device, EV_ABS, ABS_X, ev_pkt.x);
|
||||
send_event(device, EV_ABS, ABS_Y, ev_pkt.y);
|
||||
send_event(device, EV_ABS, ABS_PRESSURE, ev_pkt.pressure);
|
||||
|
||||
//send_event(device, EV_ABS, ABS_PRESSURE, ev_pkt.pressure);
|
||||
|
||||
switch (ev_pkt.type) {
|
||||
case EVENT_TYPE_MOTION:
|
||||
|
|
|
@ -10,6 +10,16 @@
|
|||
#define EVENT_TYPE_MOTION 0
|
||||
#define EVENT_TYPE_BUTTON 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned long mm_height;
|
||||
unsigned long mm_width;
|
||||
} gfx_host_monitor;
|
||||
|
||||
struct event_packet
|
||||
{
|
||||
char signature[9];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue