Skip to content

Commit 242ba96

Browse files
committed
Shim: On fork, decouple child memory from parent
1 parent 5683496 commit 242ba96

8 files changed

Lines changed: 134 additions & 111 deletions

File tree

shim/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.14)
22
project(qtfb-shim VERSION 0.1.0 LANGUAGES CXX)
33

44
set(QTFB_SHIM_BASE_SOURCES
5+
src/worldvars.cpp
56
src/shim.cpp
67
src/connection.cpp
78
src/input-shim.cpp

shim/src/connection.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
#include "qtfb-client/qtfb-client.h"
22
#include "shim.h"
3-
4-
qtfb::FBKey shimFramebufferKey;
5-
uint8_t shimType = FBFMT_RM2FB;
6-
7-
qtfb::ClientConnection *clientConnection = NULL;
8-
void *shmMemory = NULL;
9-
int shmFD = -1;
10-
3+
#include "worldvars.h"
114

125
void connectShim(){
136
char *fbKey = getenv("QTFB_KEY");
147
if(fbKey != NULL) {
15-
shimFramebufferKey = (unsigned int) strtoul(fbKey, NULL, 10);
8+
WORLD.shimFramebufferKey = (unsigned int) strtoul(fbKey, NULL, 10);
169
}
1710

1811
CERR << "Connecting to the shim!" << std::endl;
19-
if(shmFD == -1) {
12+
if(WORLD.shmFD == -1) {
2013
CERR << "Connecting to the shim step2!" << std::endl;
21-
clientConnection = new qtfb::ClientConnection(shimFramebufferKey, shimType, {}, false);
22-
shmFD = clientConnection->shmFD;
23-
shmMemory = clientConnection->shm;
24-
25-
atexit([](){ delete clientConnection; });
14+
WORLD.clientConnection = new qtfb::ClientConnection(WORLD.shimFramebufferKey, WORLD.shimType, {}, false);
15+
WORLD.shmFD = WORLD.clientConnection->shmFD;
16+
WORLD.shmMemory = WORLD.clientConnection->shm;
2617
}
2718
}

shim/src/connection.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
11
#pragma once
22
#include "qtfb-client/qtfb-client.h"
33

4-
5-
extern qtfb::FBKey shimFramebufferKey;
6-
extern uint8_t shimType;
7-
8-
extern qtfb::ClientConnection *clientConnection;
9-
extern void *shmMemory;
10-
extern int shmFD;
114
void connectShim();

shim/src/fb-shim.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "fb-shim.h"
33
#include "connection.h"
44
#include "shim.h"
5+
#include "worldvars.h"
56
#include "qtfb-client/qtfb-client.h"
67

78
// Ehhh..
@@ -40,18 +41,18 @@ struct _32_bit_fb_fix_screeninfo {
4041

4142

4243
int fbShimOpen(const char *file) {
43-
return strcmp(file, FILE_FB) == 0 ? shmFD : INTERNAL_SHIM_NOT_APPLICABLE;
44+
return strcmp(file, FILE_FB) == 0 ? WORLD.shmFD : INTERNAL_SHIM_NOT_APPLICABLE;
4445
}
4546

4647
int fbShimClose(int fd) {
47-
return fd == shmFD ? 0 : INTERNAL_SHIM_NOT_APPLICABLE;
48+
return fd == WORLD.shmFD ? 0 : INTERNAL_SHIM_NOT_APPLICABLE;
4849
}
4950

5051
int fbShimIoctl(int fd, unsigned long request, char *ptr) {
51-
if (fd == shmFD) {
52+
if (fd == WORLD.shmFD) {
5253
if (request == MXCFB_SEND_UPDATE) {
5354
mxcfb_update_data *update = (mxcfb_update_data *) ptr;
54-
clientConnection->sendPartialUpdate(
55+
WORLD.clientConnection->sendPartialUpdate(
5556
update->update_region.left,
5657
update->update_region.top,
5758
update->update_region.width,
@@ -66,12 +67,12 @@ int fbShimIoctl(int fd, unsigned long request, char *ptr) {
6667
}
6768
else if (request == FBIOGET_VSCREENINFO) {
6869
fb_var_screeninfo *screeninfo = (fb_var_screeninfo *)ptr;
69-
screeninfo->xres = clientConnection->width();
70-
screeninfo->yres = clientConnection->height();
70+
screeninfo->xres = WORLD.clientConnection->width();
71+
screeninfo->yres = WORLD.clientConnection->height();
7172
screeninfo->grayscale = 0;
7273
screeninfo->bits_per_pixel = 8 * BYTES_PER_PIXEL;
73-
screeninfo->xres_virtual = clientConnection->width();
74-
screeninfo->yres_virtual = clientConnection->height();
74+
screeninfo->xres_virtual = WORLD.clientConnection->width();
75+
screeninfo->yres_virtual = WORLD.clientConnection->height();
7576

7677
screeninfo->red.offset = 11;
7778
screeninfo->red.length = 5;
@@ -85,9 +86,9 @@ int fbShimIoctl(int fd, unsigned long request, char *ptr) {
8586
return 0;
8687
} else if (request == FBIOGET_FSCREENINFO) {
8788
remapped_fb_var_screeninfo *screeninfo = (remapped_fb_var_screeninfo *)ptr;
88-
screeninfo->smem_len = clientConnection->shmSize;
89-
screeninfo->smem_start = (unsigned long) shmMemory;
90-
screeninfo->line_length = clientConnection->width() * BYTES_PER_PIXEL;
89+
screeninfo->smem_len = WORLD.clientConnection->shmSize;
90+
screeninfo->smem_start = (unsigned long) WORLD.shmMemory;
91+
screeninfo->line_length = WORLD.clientConnection->width() * BYTES_PER_PIXEL;
9192
constexpr char fb_id[] = "mxcfb";
9293
memcpy(screeninfo->id, fb_id, sizeof(fb_id));
9394
return 0;

shim/src/input-shim.cpp

Lines changed: 28 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <dlfcn.h>
1717
#include <poll.h>
1818

19+
#include "worldvars.h"
1920
#include "qtfb-client/qtfb-client.h"
2021

2122
#define DEV_NULL "/dev/null"
@@ -45,31 +46,10 @@
4546
#define RMPP_MAX_TOUCH_Y 2832
4647
#define RMPP_MAX_PRESSURE 255
4748

48-
extern qtfb::ClientConnection *clientConnection;
49-
extern int shimInputType;
50-
51-
struct TouchSlotState {
52-
int x, y;
53-
};
54-
55-
std::map<int, TouchSlotState> touchStates;
56-
5749
#define QUEUE_TOUCH 1
5850
#define QUEUE_PEN 2
5951
#define QUEUE_BUTTONS 3
6052

61-
struct PerFDEventQueue {
62-
int queueType;
63-
int queueRead;
64-
int queueWrite;
65-
66-
PerFDEventQueue(int e, int r, int w): queueType(e), queueRead(r), queueWrite(w) {}
67-
};
68-
static std::map<int, PerFDEventQueue> eventQueue;
69-
static struct {
70-
int pipeRead, pipeWrite;
71-
} nullPipe;
72-
7353
static struct input_event evt(unsigned short type, unsigned short code, int value) {
7454
#if (__BITS_PER_LONG != 32)
7555
timeval time;
@@ -100,7 +80,7 @@ static int mapKey(int x) {
10080
}
10181

10282
static void pushToAll(int queueType, struct input_event evt) {
103-
for(auto &ref : eventQueue) {
83+
for(auto &ref : WORLD.eventQueue) {
10484
if(ref.second.queueType == queueType) {
10585
write(ref.second.queueWrite, &evt, sizeof(evt));
10686
}
@@ -109,35 +89,35 @@ static void pushToAll(int queueType, struct input_event evt) {
10989

11090
static void pollInputUpdates() {
11191
qtfb::ServerMessage message;
112-
if(clientConnection) {
113-
if(clientConnection->pollServerPacket(message) && message.type == MESSAGE_USERINPUT) {
92+
if(WORLD.clientConnection) {
93+
if(WORLD.clientConnection->pollServerPacket(message) && message.type == MESSAGE_USERINPUT) {
11494
// Did we get a packet?
11595
char state_a;
11696

11797
int xTranslate, yTranslate, dTranslate;
118-
switch(shimInputType) {
98+
switch(WORLD.shimInputType) {
11999
case SHIM_INPUT_RM1:
120100
switch(message.userInput.inputType & 0xF0) {
121101
case INPUT_TOUCH_PRESS:
122-
xTranslate = RM1_MAX_TOUCH_X - ((message.userInput.x * RM1_MAX_TOUCH_X) / (int) clientConnection->width());
123-
yTranslate = RM1_MAX_TOUCH_Y - ((message.userInput.y * RM1_MAX_TOUCH_Y) / (int) clientConnection->height());
102+
xTranslate = RM1_MAX_TOUCH_X - ((message.userInput.x * RM1_MAX_TOUCH_X) / (int) WORLD.clientConnection->width());
103+
yTranslate = RM1_MAX_TOUCH_Y - ((message.userInput.y * RM1_MAX_TOUCH_Y) / (int) WORLD.clientConnection->height());
124104
break;
125105
case INPUT_PEN_PRESS:
126-
xTranslate = RM1_MAX_DIGI_X - ((message.userInput.y * RM1_MAX_DIGI_X) / clientConnection->height());
127-
yTranslate = (message.userInput.x * RM1_MAX_DIGI_Y) / clientConnection->width();
106+
xTranslate = RM1_MAX_DIGI_X - ((message.userInput.y * RM1_MAX_DIGI_X) / WORLD.clientConnection->height());
107+
yTranslate = (message.userInput.x * RM1_MAX_DIGI_Y) / WORLD.clientConnection->width();
128108
dTranslate = (message.userInput.d * 4096) / 100;
129109
break;
130110
}
131111
break;
132112
case SHIM_INPUT_RMPP:
133113
switch(message.userInput.inputType & 0xF0) {
134114
case INPUT_TOUCH_PRESS:
135-
xTranslate = ((message.userInput.x * RMPP_MAX_TOUCH_X) / (int) clientConnection->width());
136-
yTranslate = ((message.userInput.y * RMPP_MAX_TOUCH_Y) / (int) clientConnection->height());
115+
xTranslate = ((message.userInput.x * RMPP_MAX_TOUCH_X) / (int) WORLD.clientConnection->width());
116+
yTranslate = ((message.userInput.y * RMPP_MAX_TOUCH_Y) / (int) WORLD.clientConnection->height());
137117
break;
138118
case INPUT_PEN_PRESS:
139-
xTranslate = (message.userInput.x * RMPP_MAX_DIGI_X) / clientConnection->width();
140-
yTranslate = (message.userInput.y * RMPP_MAX_DIGI_Y) / clientConnection->height();
119+
xTranslate = (message.userInput.x * RMPP_MAX_DIGI_X) / WORLD.clientConnection->width();
120+
yTranslate = (message.userInput.y * RMPP_MAX_DIGI_Y) / WORLD.clientConnection->height();
141121
dTranslate = (message.userInput.d * 255) / 100;
142122
break;
143123
}
@@ -198,19 +178,16 @@ static void pollInputUpdates() {
198178
}
199179
}
200180

201-
static std::thread pollingThread;
202-
static bool pollingThreadRunning;
203-
204181
static void killPollingThread() {
205-
pollingThreadRunning = false;
206-
// pollingThreadRunning.join();
182+
WORLD.pollingThreadRunning = false;
183+
// WORLD.pollingThreadRunning.join();
207184
}
208185

209186
void startPollingThread() {
210-
pipe((int*) &nullPipe);
211-
pollingThreadRunning = true;
212-
pollingThread = std::thread([&]() {
213-
while(pollingThreadRunning) {
187+
pipe((int*) &WORLD.nullPipe);
188+
WORLD.pollingThreadRunning = true;
189+
WORLD.pollingThread = std::thread([&]() {
190+
while(WORLD.pollingThreadRunning) {
214191
pollInputUpdates();
215192
}
216193
});
@@ -225,12 +202,12 @@ static int createInEventMap(int type, int flags) {
225202
abort();
226203
}
227204
CERR << "Create evqueue pipe r:" << _pipe[0] << ", w:" << _pipe[1] << std::endl;
228-
eventQueue.try_emplace(_pipe[0], type, _pipe[0], _pipe[1]);
205+
WORLD.eventQueue.try_emplace(_pipe[0], type, _pipe[0], _pipe[1]);
229206
return _pipe[0];
230207
}
231208

232209
int inputShimOpen(const char *file, int (*realOpen)(const char *name, int flags, mode_t mode), int flags, mode_t mode) {
233-
if(shimInputType == SHIM_INPUT_RM1) {
210+
if(WORLD.shimInputType == SHIM_INPUT_RM1) {
234211
if(strcmp(file, RM1_DIGITIZER) == 0) {
235212
int fd = createInEventMap(QUEUE_PEN, flags);
236213
CERR << "Open digitizer " << fd << std::endl;
@@ -248,7 +225,7 @@ int inputShimOpen(const char *file, int (*realOpen)(const char *name, int flags,
248225
CERR << "Open buttons " << fd << std::endl;
249226
return fd;
250227
}
251-
} else if(shimInputType == SHIM_INPUT_RMPP) {
228+
} else if(WORLD.shimInputType == SHIM_INPUT_RMPP) {
252229
if(strcmp(file, RMPP_DIGITIZER) == 0) {
253230
int fd = createInEventMap(QUEUE_PEN, flags);
254231
CERR << "Open digitizer " << fd << std::endl;
@@ -268,11 +245,11 @@ int inputShimOpen(const char *file, int (*realOpen)(const char *name, int flags,
268245

269246
int inputShimClose(int fd, int (*realClose)(int)) {
270247
CERR << "Shim close " << fd << std::endl;
271-
auto position = eventQueue.find(fd);
272-
if(position != eventQueue.end()) {
248+
auto position = WORLD.eventQueue.find(fd);
249+
if(position != WORLD.eventQueue.end()) {
273250
realClose(position->second.queueRead);
274251
realClose(position->second.queueWrite);
275-
eventQueue.erase(position);
252+
WORLD.eventQueue.erase(position);
276253
return 0;
277254
}
278255

@@ -313,9 +290,9 @@ static int fakeOrOverrideAbsInfo(
313290
#define IS_MATCHING_IOCTL(dir, type, nr) ((request & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == (_IOC(dir, type, nr, 0)))
314291
#define IS_MATCHING_IOCTL_S(dir, type, nr, size) (request == (_IOC(dir, type, nr, size)))
315292
int inputShimIoctl(int fd, unsigned long request, char *ptr, int (*realIoctl)(int fd, unsigned long request, char *ptr)) {
316-
auto position = eventQueue.find(fd);
317-
if(position == eventQueue.end()) return INTERNAL_SHIM_NOT_APPLICABLE;
318-
const auto &ref = eventQueue.at(fd);
293+
auto position = WORLD.eventQueue.find(fd);
294+
if(position == WORLD.eventQueue.end()) return INTERNAL_SHIM_NOT_APPLICABLE;
295+
const auto &ref = WORLD.eventQueue.at(fd);
319296
int ioctlInternalSize = _IOC_SIZE(request);
320297

321298
unsigned cmdDir = _IOC_DIR(request);

0 commit comments

Comments
 (0)