Open joncampbell123 opened 11 months ago
Is that possible to write named pipe and inject an SDL_event for GFX_Events function start at line 5363 of sdlmain.cpp? I tried hard-coding for the case SDL_MOUSEMOTION and the mouse does stay at the hard-coded position (x 235 y 347). My thought is to override polled event and inject a customed event. Is that achievable? Thanks!
void GFX_Events() {
....
SDL_Event event;
....
while (SDL_PollEvent(&event)) {
......
switch (event.type) {
......
case SDL_MOUSEMOTION:
int32_t test_x = 235;
int32_t test_y = 347;
event.motion.state = 0;
event.motion.which = 0;
event.motion.x = test_x;
event.motion.y = test_y;
event.motion.xrel = 0l;
event.motion.yrel = 0l;
//event.motion.xrel = (Sint16)((rx >= 0) ? min(rx, 32767l) : max(rx, -32768l));
//event.motion.yrel = (Sint16)((ry >= 0) ? min(ry, 32767l) : max(ry, -32768l));
HandleMouseMotion(&event.motion);
break;
......
What I had in mind was more controlling the guest DOS application or OS by injecting keystrokes into it's mouse and keyboard I/O, not DOSBox-X itself.
If you're looking at injecting input into DOSBox-X interfaces, perhaps there should be specialized messages for that use case? Ones that specifically trigger shortcuts by name? And then push specific buttons by name?
The reason I suggest this is that if you hardcode around locations in the window to interact with DOSBox-X UI elements your remote control code will break if anything moves around on screen.
Yeah, I have commented out SDL_MOUSEMOTION, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP in GFX_Events() so that hovering over window will not interrupt API. Ideally it would be good to switch remote control on and off by API. My current plan is to encode signals (maybe 64bits) for x and y position, mouse buttons, button pressed or released, API take over/release control, etc. I've tested mouse buttons and they worked very well. The reason I'm injecting through interface is I have very limited knowledge about operating system while I am hungering for a quick walkaround solution.
Thanks for plans of more sophisticate ways of implementing these APIs because based on my limit understanding of OS, I/O would be more stable and more "nature" pathway. I'm looking forward for your progresses on that.
Here is my test code:
c++:
...... void GFX_Events() {
......
HANDLE hPipe;
char buffer[4];
hPipe = CreateNamedPipe(
"\\\\.\\pipe\\MyNamedPipeNew", // Pipe name
PIPE_ACCESS_INBOUND, // Pipe open mode
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // Pipe mode and blocking mode
1, // Maximum instances
sizeof(buffer), // Output buffer size
sizeof(buffer), // Input buffer size
NMPWAIT_USE_DEFAULT_WAIT, // Default timeout (0 means default)
NULL // Security attributes
);
if(hPipe == INVALID_HANDLE_VALUE) {
//LOG_MSG("Error creating named pipe.");
}
else {
//LOG_MSG("Pipe created successfully.");
}
if(ConnectNamedPipe(hPipe, NULL) != 0) {
DWORD bytesRead;
ReadFile(hPipe, buffer, sizeof(buffer), &bytesRead, NULL);
memcpy(&test_input, buffer, sizeof(test_input));
// Pass the string to LOG_MSG
char log_msg[100];
if(test_input== 3) {
LOG_MSG("is 3");
SDL_memset(&event, 0, sizeof(event));
event.type = SDL_MOUSEMOTION;
event.motion.type = SDL_MOUSEMOTION;
event.motion.state = 0;
event.motion.which = 0;
event.motion.x = 345l; // to be implemented
event.motion.y = 240l; // to be implemented
event.motion.xrel = 0l;
event.motion.yrel = 0l;
HandleMouseMotion(&event.motion);
}
else if(test_input== 4) {
LOG_MSG("is 4");
SDL_memset(&event, 0, sizeof(event));
event.type = SDL_MOUSEBUTTONDOWN;
event.motion.type = SDL_MOUSEBUTTONDOWN;
event.motion.state = 0;
event.motion.which = 0;
event.motion.x = 345l; // to be implemented
event.motion.y = 240l; // to be implemented
event.motion.xrel = 0l;
event.motion.yrel = 0l;
event.button.button = SDL_BUTTON_LEFT;
event.button.state = SDL_PRESSED;
HandleMouseButton(&event.button, &event.motion);
}
else if(test_input == 5) {
LOG_MSG("is 5");
SDL_memset(&event, 0, sizeof(event));
event.type = SDL_MOUSEBUTTONUP;
event.motion.type = SDL_MOUSEBUTTONUP;
event.motion.state = 0;
event.motion.which = 0;
event.motion.x = 345l;
event.motion.y = 240l;
event.motion.xrel = 0l;
event.motion.yrel = 0l;
event.button.button = SDL_BUTTON_LEFT;
event.button.state = SDL_RELEASED;
//push_event_status = SDL_PushEvent(&event);
HandleMouseButton(&event.button, &event.motion);
}
DisconnectNamedPipe(hPipe);
}
CloseHandle(hPipe);
while (SDL_PollEvent(&event)) {
......
}
.......
python:
import ctypes import os import struct import time
transmitted_data = 3 # 4 or 5
with open(r'\.\pipe\MyNamedPipeNew', 'wb') as pipe: pipe.write(struct.pack('<i', transmitted_data))
Is your feature request related to a problem? Please describe.
I've been getting requests lately from people who obviously want to control DOSBox-X from another program, such as a recent one where a programmer wishes to direct DOSBox-X from their Python script.
What you want
I don't think my suggestion of sending to a named pipe serial port in DOSBox-X and writing a TSR is coming off well with these users, so I think it's time to consider a more direct interface via a named pipe (that you specify in dosbox.conf or the command line) since that is something Python could easily support.
The external commands would allow most of the same injection/monitoring that the DOSBox Integration Device already allows.
The programmer in question wishes to inject mouse movement into the guest DOS environment.
Describe alternatives you've considered
No response
Additional information
No response
Have you checked that no similar feature request(s) exist?
Code of Conduct & Contributing Guidelines