mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-15 07:43:50 +00:00
KVM Fixes
1. Added changes to support MacOS 2. Updated Linux KVM, so X11 is dynamically loaded at runtime
This commit is contained in:
@@ -85,10 +85,22 @@ __declspec(dllexport) int mainEx(int argc, char **argv, ExternalDispatch ptr)
|
|||||||
while (MeshAgent_Start(agentHost, argc, argv) != 0);
|
while (MeshAgent_Start(agentHost, argc, argv) != 0);
|
||||||
retCode = agentHost->exitCode;
|
retCode = agentHost->exitCode;
|
||||||
MeshAgent_Destroy(agentHost);
|
MeshAgent_Destroy(agentHost);
|
||||||
|
agentHost = NULL;
|
||||||
return(retCode);
|
return(retCode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LINKVM) && defined(__APPLE__)
|
||||||
|
extern void* kvm_server_mainloop(void *parm);
|
||||||
|
extern void senddebug(int val);
|
||||||
|
ILibTransport_DoneState kvm_serviceWriteSink(char *buffer, int bufferLen, void *reserved)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
ignore_result(write(STDOUT_FILENO, (void*)buffer, bufferLen));
|
||||||
|
return ILibTransport_DoneState_COMPLETE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Check if .JS file is integrated with executable
|
// Check if .JS file is integrated with executable
|
||||||
@@ -106,6 +118,27 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
|
|||||||
|
|
||||||
ILibDuktape_ScriptContainer_CheckEmbedded(&integratedJavaScript, &integratedJavaScriptLen);
|
ILibDuktape_ScriptContainer_CheckEmbedded(&integratedJavaScript, &integratedJavaScriptLen);
|
||||||
|
|
||||||
|
if (argc > 1 && strcasecmp(argv[1], "-info") == 0)
|
||||||
|
{
|
||||||
|
printf("Compiled on: %s, %s\n", __TIME__, __DATE__);
|
||||||
|
printf("Using %s\n", SSLeay_version(SSLEAY_VERSION));
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_LINKVM) && defined(__APPLE__)
|
||||||
|
if (argc > 1 && strcasecmp(argv[1], "-kvm0") == 0)
|
||||||
|
{
|
||||||
|
kvm_server_mainloop(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (argc > 1 && strcasecmp(argv[1], "-kvm1") == 0)
|
||||||
|
{
|
||||||
|
kvm_server_mainloop((void*)(uint64_t)getpid());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (argc > 2 && strcasecmp(argv[1], "-faddr") == 0)
|
if (argc > 2 && strcasecmp(argv[1], "-faddr") == 0)
|
||||||
{
|
{
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
@@ -180,6 +213,7 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
|
|||||||
while (MeshAgent_Start(agentHost, argc, argv) != 0);
|
while (MeshAgent_Start(agentHost, argc, argv) != 0);
|
||||||
retCode = agentHost->exitCode;
|
retCode = agentHost->exitCode;
|
||||||
MeshAgent_Destroy(agentHost);
|
MeshAgent_Destroy(agentHost);
|
||||||
|
agentHost = NULL;
|
||||||
}
|
}
|
||||||
__except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winExceptionContext))
|
__except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winExceptionContext))
|
||||||
{
|
{
|
||||||
@@ -193,6 +227,7 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
|
|||||||
while (MeshAgent_Start(agentHost, argc, argv) != 0);
|
while (MeshAgent_Start(agentHost, argc, argv) != 0);
|
||||||
retCode = agentHost->exitCode;
|
retCode = agentHost->exitCode;
|
||||||
MeshAgent_Destroy(agentHost);
|
MeshAgent_Destroy(agentHost);
|
||||||
|
agentHost = NULL;
|
||||||
#ifndef _NOILIBSTACKDEBUG
|
#ifndef _NOILIBSTACKDEBUG
|
||||||
if (crashMemory != NULL) { free(crashMemory); }
|
if (crashMemory != NULL) { free(crashMemory); }
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ limitations under the License.
|
|||||||
|
|
||||||
unsigned char *jpeg_buffer = NULL;
|
unsigned char *jpeg_buffer = NULL;
|
||||||
int jpeg_buffer_length = 0;
|
int jpeg_buffer_length = 0;
|
||||||
|
char jpegLastError[JMSG_LENGTH_MAX];
|
||||||
|
JPEG_error_handler default_JPEG_error_handler = NULL;
|
||||||
|
|
||||||
|
void jpeg_error_handler(j_common_ptr ptr)
|
||||||
|
{
|
||||||
|
// Build the error string
|
||||||
|
(*(ptr->err->format_message)) (ptr, jpegLastError);
|
||||||
|
|
||||||
|
if (default_JPEG_error_handler != NULL) { default_JPEG_error_handler(jpegLastError); }
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
void init_destination(j_compress_ptr cinfo)
|
void init_destination(j_compress_ptr cinfo)
|
||||||
{
|
{
|
||||||
@@ -67,6 +78,8 @@ int write_JPEG_buffer (JSAMPLE * image_buffer, int image_width, int image_height
|
|||||||
int row_stride;
|
int row_stride;
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
if (default_JPEG_error_handler != NULL) { jerr.error_exit = jpeg_error_handler; }
|
||||||
|
|
||||||
jpeg_create_compress(&cinfo);
|
jpeg_create_compress(&cinfo);
|
||||||
cinfo.dest = (struct jpeg_destination_mgr *) malloc (sizeof(struct jpeg_destination_mgr));
|
cinfo.dest = (struct jpeg_destination_mgr *) malloc (sizeof(struct jpeg_destination_mgr));
|
||||||
cinfo.dest->init_destination = &init_destination;
|
cinfo.dest->init_destination = &init_destination;
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ limitations under the License.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include "../../libjpeg-turbo/jpeglib.h"
|
#include "lib-jpeg-turbo/includes/jpeglib.h"
|
||||||
#include "../../libjpeg-turbo/jerror.h"
|
#include "lib-jpeg-turbo/includes/jerror.h"
|
||||||
#else
|
#else
|
||||||
#include <jpeglib.h>
|
#include <jpeglib.h>
|
||||||
#include <jerror.h>
|
#include <jerror.h>
|
||||||
@@ -29,6 +29,9 @@ limitations under the License.
|
|||||||
|
|
||||||
#define MAX_BUFFER 22528 // 22 KiB should be fine.
|
#define MAX_BUFFER 22528 // 22 KiB should be fine.
|
||||||
|
|
||||||
extern int write_JPEG_buffer (JSAMPLE * image_buffer, int image_width, int image_height, int quality);
|
typedef void(*JPEG_error_handler)(char *msg);
|
||||||
|
|
||||||
#endif /* LINUX_COMPRESSION_H_ */
|
extern int write_JPEG_buffer (JSAMPLE * image_buffer, int image_width, int image_height, int quality);
|
||||||
|
extern JPEG_error_handler default_JPEG_error_handler;
|
||||||
|
|
||||||
|
#endif // LINUX_COMPRESSION_H_
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ limitations under the License.
|
|||||||
|
|
||||||
static const int g_keymapLen = 96; // Modify this when you change anything in g_keymap.
|
static const int g_keymapLen = 96; // Modify this when you change anything in g_keymap.
|
||||||
extern int change_display;
|
extern int change_display;
|
||||||
|
x11tst_struct *x11tst_exports = NULL;
|
||||||
|
|
||||||
static struct keymap_t g_keymap[] = {
|
static struct keymap_t g_keymap[] = {
|
||||||
{ XK_BackSpace, VK_BACK },
|
{ XK_BackSpace, VK_BACK },
|
||||||
@@ -123,8 +124,8 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
|
|||||||
if (change_display) {
|
if (change_display) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!XTestFakeMotionEvent(display, -1, absX, absY, CurrentTime )) { return; }
|
if (!x11tst_exports->XTestFakeMotionEvent(display, -1, absX, absY, CurrentTime )) { return; }
|
||||||
|
|
||||||
if (button != 0) {
|
if (button != 0) {
|
||||||
int mouseDown = 1;
|
int mouseDown = 1;
|
||||||
@@ -155,7 +156,7 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!XTestFakeButtonEvent(display, button, mouseDown, CurrentTime)) { return; }
|
if (!x11tst_exports->XTestFakeButtonEvent(display, button, mouseDown, CurrentTime)) { return; }
|
||||||
}
|
}
|
||||||
else if (wheel != 0) {
|
else if (wheel != 0) {
|
||||||
if (wheel > 0) {
|
if (wheel > 0) {
|
||||||
@@ -165,13 +166,13 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
|
|||||||
button = Button5;
|
button = Button5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!XTestFakeButtonEvent(display, button, True, CurrentTime)) { return; }
|
if (!x11tst_exports->XTestFakeButtonEvent(display, button, True, CurrentTime)) { return; }
|
||||||
XFlush(display);
|
x11tst_exports->XFlush(display);
|
||||||
|
|
||||||
if (!XTestFakeButtonEvent(display, button, False, CurrentTime)) { return; }
|
if (!x11tst_exports->XTestFakeButtonEvent(display, button, False, CurrentTime)) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
XFlush(display);
|
x11tst_exports->XFlush(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyAction(unsigned char vk, int up, Display *display) {
|
void KeyAction(unsigned char vk, int up, Display *display) {
|
||||||
@@ -190,15 +191,15 @@ void KeyAction(unsigned char vk, int up, Display *display) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keysym == 0) {
|
if (keysym == 0) {
|
||||||
keycode = XKeysymToKeycode(display, vk);
|
keycode = x11tst_exports->XKeysymToKeycode(display, vk);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
keycode = XKeysymToKeycode(display, keysym);
|
keycode = x11tst_exports->XKeysymToKeycode(display, keysym);
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%x %x %d %d\n", keysym, vk, keycode, up);
|
//printf("%x %x %d %d\n", keysym, vk, keycode, up);
|
||||||
if (keycode != 0) {
|
if (keycode != 0) {
|
||||||
if (!XTestFakeKeyEvent(display, keycode, !up, 0)) { return; }
|
if (!x11tst_exports->XTestFakeKeyEvent(display, keycode, !up, 0)) { return; }
|
||||||
XFlush(display);
|
x11tst_exports->XFlush(display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,18 @@ limitations under the License.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef struct x11tst_struct
|
||||||
|
{
|
||||||
|
void *x11tst_lib;
|
||||||
|
int(*XTestFakeMotionEvent)(Display *d, int screen_number, int x, int y, unsigned long delay);
|
||||||
|
int(*XTestFakeButtonEvent)(Display *d, unsigned int button, Bool is_press, unsigned long delay);
|
||||||
|
int(*XTestFakeKeyEvent)(Display *d, unsigned int key_code, Bool is_press, unsigned long delay);
|
||||||
|
|
||||||
|
int(*XFlush)(Display *d);
|
||||||
|
KeyCode(*XKeysymToKeycode)(Display *d, KeySym keysym);
|
||||||
|
}x11tst_struct;
|
||||||
|
x11tst_struct *x11tst_exports;
|
||||||
|
|
||||||
enum MOUSE_EVENTS {
|
enum MOUSE_EVENTS {
|
||||||
MOUSEEVENTF_LEFTDOWN = 0x0002,
|
MOUSEEVENTF_LEFTDOWN = 0x0002,
|
||||||
MOUSEEVENTF_RIGHTDOWN = 0x0008,
|
MOUSEEVENTF_RIGHTDOWN = 0x0008,
|
||||||
|
|||||||
@@ -25,14 +25,15 @@ limitations under the License.
|
|||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#include <X11/extensions/XShm.h>
|
#include <X11/extensions/XShm.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "linux_events.h"
|
||||||
|
#include "linux_compression.h"
|
||||||
|
|
||||||
#define EXIT_SUCCESS 0
|
#define EXIT_SUCCESS 0
|
||||||
#define EXIT_FAILURE 1
|
#define EXIT_FAILURE 1
|
||||||
|
|
||||||
#ifdef _DAEMON
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int SCREEN_NUM = 0;
|
int SCREEN_NUM = 0;
|
||||||
int SCREEN_WIDTH = 0;
|
int SCREEN_WIDTH = 0;
|
||||||
int SCREEN_HEIGHT = 0;
|
int SCREEN_HEIGHT = 0;
|
||||||
@@ -63,6 +64,28 @@ int g_enableEvents = 0;
|
|||||||
|
|
||||||
extern void* tilebuffer;
|
extern void* tilebuffer;
|
||||||
|
|
||||||
|
typedef struct x11ext_struct
|
||||||
|
{
|
||||||
|
void *xext_lib;
|
||||||
|
Bool(*XShmDetach)(Display *d, XShmSegmentInfo *si);
|
||||||
|
Bool(*XShmGetImage)(Display *dis, Drawable d, XImage *image, int x, int y, unsigned long plane_mask);
|
||||||
|
Bool(*XShmAttach)(Display *d, XShmSegmentInfo *si);
|
||||||
|
XImage*(*XShmCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, char *data, XShmSegmentInfo *shminfo, unsigned int width, unsigned int height);
|
||||||
|
}x11ext_struct;
|
||||||
|
x11ext_struct *x11ext_exports = NULL;
|
||||||
|
extern x11tst_struct *x11tst_exports;
|
||||||
|
|
||||||
|
typedef struct x11_struct
|
||||||
|
{
|
||||||
|
void *x11_lib;
|
||||||
|
Display*(*XOpenDisplay)(char *display_name);
|
||||||
|
int(*XCloseDisplay)(Display *d);
|
||||||
|
int(*XFlush)(Display *d);
|
||||||
|
KeyCode(*XKeysymToKeycode)(Display *d, KeySym keysym);
|
||||||
|
Bool(*XQueryExtension)(Display *d, char *name, int* maj, int *firstev, int *firsterr);
|
||||||
|
}x11_struct;
|
||||||
|
x11_struct *x11_exports = NULL;
|
||||||
|
|
||||||
void kvm_send_resolution()
|
void kvm_send_resolution()
|
||||||
{
|
{
|
||||||
char buffer[8];
|
char buffer[8];
|
||||||
@@ -95,87 +118,6 @@ void kvm_send_display()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define BUFSIZE 65535
|
#define BUFSIZE 65535
|
||||||
#ifdef _DAEMON
|
|
||||||
int kvm_relay_restart(int paused);
|
|
||||||
|
|
||||||
void* kvm_mainrelay(void* param)
|
|
||||||
{
|
|
||||||
int ptr = 0;
|
|
||||||
int endPointer = 0;
|
|
||||||
unsigned short size;
|
|
||||||
char* pchRequest;
|
|
||||||
ssize_t cbBytesRead = 0;
|
|
||||||
enum ILibAsyncSocket_SendStatus r;
|
|
||||||
|
|
||||||
if ((pchRequest = (char*)malloc(BUFSIZE)) == NULL) ILIBCRITICALEXIT(254);
|
|
||||||
|
|
||||||
g_restartcount = 0;
|
|
||||||
while (!g_shutdown)
|
|
||||||
{
|
|
||||||
//fprintf(logFile, "Reading from slave in kvm_mainrelay\n");
|
|
||||||
cbBytesRead = read(slave2master[0], pchRequest + endPointer, BUFSIZE - endPointer);
|
|
||||||
//fprintf(logFile, "Read %d bytes from slave in kvm_mainrelay\n", cbBytesRead);
|
|
||||||
if (g_shutdown == 0 && (cbBytesRead == -1 || cbBytesRead == 0)) { g_shutdown = 3; }
|
|
||||||
if (g_shutdown) { /*ILIBMESSAGE("KVMBREAK-R1\r\n");*/ break; }
|
|
||||||
endPointer += cbBytesRead;
|
|
||||||
|
|
||||||
// See how much we can safely send
|
|
||||||
while (endPointer - ptr > 4)
|
|
||||||
{
|
|
||||||
//type = ntohs(((unsigned short*)(pchRequest + ptr))[0]);
|
|
||||||
size = ntohs(((unsigned short*)(pchRequest + ptr))[1]);
|
|
||||||
if (ptr + size > endPointer) break;
|
|
||||||
ptr += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ptr > 0)
|
|
||||||
{
|
|
||||||
// Send any complete data
|
|
||||||
r = GuardPost_ILibKVMSendTo(pchRequest, ptr, ILibAsyncSocket_MemoryOwnership_USER);
|
|
||||||
if (r == ILibAsyncSocket_SEND_ON_CLOSED_SOCKET_ERROR) { /*ILIBMESSAGE("KVMBREAK-R2\r\n");*/ break; }
|
|
||||||
else if (r == ILibAsyncSocket_NOT_ALL_DATA_SENT_YET)
|
|
||||||
{
|
|
||||||
g_pause = 1;
|
|
||||||
while (g_pause && !g_shutdown) { if (GuardPost_ILibKVMGetPendingBytesToSend() == 0) { g_pause = 0; } usleep(5000); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move remaining data to the front of the buffer
|
|
||||||
if (endPointer - ptr > 0) memcpy(pchRequest, pchRequest + ptr, endPointer - ptr);
|
|
||||||
endPointer -= ptr;
|
|
||||||
ptr = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_shutdown || ((BUFSIZE - endPointer) == 0)) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_slavekvm != 0)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
kill(g_slavekvm, SIGKILL);
|
|
||||||
waitpid(g_slavekvm, &r, 0);
|
|
||||||
g_slavekvm = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(slave2master[0]);
|
|
||||||
close(master2slave[1]);
|
|
||||||
kvmthread = (pthread_t)NULL;
|
|
||||||
free(pchRequest);
|
|
||||||
if (g_shutdown == 3 && g_restartcount < 4 && g_totalRestartCount < 256)
|
|
||||||
{
|
|
||||||
g_restartcount++;
|
|
||||||
g_totalRestartCount++;
|
|
||||||
usleep(500000);
|
|
||||||
// fprintf(logFile, "Restarting again!\n");
|
|
||||||
if (kvm_relay_restart(0) == 0) GuardPost_ILibKVMDisconnect();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (g_shutdown == 2) GuardPost_ILibKVMDisconnect();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int kvm_server_inputdata(char* block, int blocklen);
|
int kvm_server_inputdata(char* block, int blocklen);
|
||||||
void* kvm_mainloopinput(void* parm)
|
void* kvm_mainloopinput(void* parm)
|
||||||
@@ -326,6 +268,16 @@ void kvm_send_display_list()
|
|||||||
if (displays != NULL) free(displays);
|
if (displays != NULL) free(displays);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char Location_X11LIB[NAME_MAX];
|
||||||
|
char Location_X11TST[NAME_MAX];
|
||||||
|
char Location_X11EXT[NAME_MAX];
|
||||||
|
void kvm_set_x11_locations(char *libx11, char *libx11tst, char *libx11ext)
|
||||||
|
{
|
||||||
|
if (libx11 != NULL) { strcpy_s(Location_X11LIB, sizeof(Location_X11LIB), libx11); } else { strcpy_s(Location_X11LIB, sizeof(Location_X11LIB), "libX11.so"); }
|
||||||
|
if (libx11tst != NULL) { strcpy_s(Location_X11TST, sizeof(Location_X11TST), libx11tst); } else { strcpy_s(Location_X11TST, sizeof(Location_X11TST), "libXtst.so"); }
|
||||||
|
if (libx11ext != NULL) { strcpy_s(Location_X11EXT, sizeof(Location_X11EXT), libx11ext); } else { strcpy_s(Location_X11EXT, sizeof(Location_X11EXT), "libXext.so"); }
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_init(int displayNo)
|
int kvm_init(int displayNo)
|
||||||
{
|
{
|
||||||
//fprintf(logFile, "kvm_init called\n"); fflush(logFile);
|
//fprintf(logFile, "kvm_init called\n"); fflush(logFile);
|
||||||
@@ -334,15 +286,59 @@ int kvm_init(int displayNo)
|
|||||||
int dummy1, dummy2, dummy3;
|
int dummy1, dummy2, dummy3;
|
||||||
char displayString[256] = "";
|
char displayString[256] = "";
|
||||||
|
|
||||||
|
if (x11ext_exports == NULL)
|
||||||
|
{
|
||||||
|
x11ext_exports = ILibMemory_SmartAllocate(sizeof(x11ext_struct));
|
||||||
|
x11ext_exports->xext_lib = dlopen(Location_X11EXT, RTLD_NOW);
|
||||||
|
if (x11ext_exports->xext_lib)
|
||||||
|
{
|
||||||
|
((void**)x11ext_exports)[1] = (void*)dlsym(x11ext_exports->xext_lib, "XShmDetach");
|
||||||
|
((void**)x11ext_exports)[2] = (void*)dlsym(x11ext_exports->xext_lib, "XShmGetImage");
|
||||||
|
((void**)x11ext_exports)[3] = (void*)dlsym(x11ext_exports->xext_lib, "XShmAttach");
|
||||||
|
((void**)x11ext_exports)[4] = (void*)dlsym(x11ext_exports->xext_lib, "XShmCreateImage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x11tst_exports == NULL)
|
||||||
|
{
|
||||||
|
x11tst_exports = ILibMemory_SmartAllocate(sizeof(x11tst_struct));
|
||||||
|
x11tst_exports->x11tst_lib = dlopen(Location_X11TST, RTLD_NOW);
|
||||||
|
if (x11tst_exports->x11tst_lib)
|
||||||
|
{
|
||||||
|
((void**)x11tst_exports)[1] = (void*)dlsym(x11tst_exports->x11tst_lib, "XTestFakeMotionEvent");
|
||||||
|
((void**)x11tst_exports)[2] = (void*)dlsym(x11tst_exports->x11tst_lib, "XTestFakeButtonEvent");
|
||||||
|
((void**)x11tst_exports)[3] = (void*)dlsym(x11tst_exports->x11tst_lib, "XTestFakeKeyEvent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x11_exports == NULL)
|
||||||
|
{
|
||||||
|
x11_exports = ILibMemory_SmartAllocate(sizeof(x11_struct));
|
||||||
|
x11_exports->x11_lib = dlopen(Location_X11LIB, RTLD_NOW);
|
||||||
|
if (x11_exports->x11_lib)
|
||||||
|
{
|
||||||
|
((void**)x11_exports)[1] = (void*)dlsym(x11_exports->x11_lib, "XOpenDisplay");
|
||||||
|
((void**)x11_exports)[2] = (void*)dlsym(x11_exports->x11_lib, "XCloseDisplay");
|
||||||
|
((void**)x11_exports)[3] = (void*)dlsym(x11_exports->x11_lib, "XFlush");
|
||||||
|
((void**)x11_exports)[4] = (void*)dlsym(x11_exports->x11_lib, "XKeysymToKeycode");
|
||||||
|
((void**)x11_exports)[5] = (void*)dlsym(x11_exports->x11_lib, "XQueryExtension");
|
||||||
|
|
||||||
|
((void**)x11tst_exports)[4] = (void*)x11_exports->XFlush;
|
||||||
|
((void**)x11tst_exports)[5] = (void*)x11_exports->XKeysymToKeycode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(displayString, ":%d", (int)displayNo);
|
sprintf(displayString, ":%d", (int)displayNo);
|
||||||
|
|
||||||
while (setDisplay(displayNo) != 0 && count++ < 10);
|
while (setDisplay(displayNo) != 0 && count++ < 10);
|
||||||
|
|
||||||
if (count == 10) { return -1; }
|
if (count == 10) { return -1; }
|
||||||
count = 0;
|
count = 0;
|
||||||
|
eventdisplay = x11_exports->XOpenDisplay(displayString);
|
||||||
eventdisplay = XOpenDisplay(displayString);
|
|
||||||
//fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile);
|
//fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile);
|
||||||
|
if (eventdisplay == NULL)
|
||||||
|
{
|
||||||
|
fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile);
|
||||||
|
fprintf(logFile, "Error calling XOpenDisplay()\n"); fflush(logFile);
|
||||||
|
}
|
||||||
|
|
||||||
if (eventdisplay != NULL) { current_display = (unsigned short)displayNo; }
|
if (eventdisplay != NULL) { current_display = (unsigned short)displayNo; }
|
||||||
|
|
||||||
@@ -350,12 +346,12 @@ int kvm_init(int displayNo)
|
|||||||
if (getNextDisplay() == -1) { return -1; }
|
if (getNextDisplay() == -1) { return -1; }
|
||||||
sprintf(displayString, ":%d", (int)current_display);
|
sprintf(displayString, ":%d", (int)current_display);
|
||||||
if (setDisplay(current_display) != 0) { continue; }
|
if (setDisplay(current_display) != 0) { continue; }
|
||||||
eventdisplay = XOpenDisplay(displayString);
|
eventdisplay = x11_exports->XOpenDisplay(displayString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 100 && eventdisplay == NULL) { return -1; }
|
if (count == 100 && eventdisplay == NULL) { return -1; }
|
||||||
|
|
||||||
g_enableEvents = XQueryExtension(eventdisplay, "XTEST", &dummy1, &dummy2, &dummy3)? 1 : 0;
|
g_enableEvents = x11_exports->XQueryExtension(eventdisplay, "XTEST", &dummy1, &dummy2, &dummy3)? 1 : 0;
|
||||||
if (!g_enableEvents) { printf("FATAL::::Fake motion is not supported.\n\n\n"); }
|
if (!g_enableEvents) { printf("FATAL::::Fake motion is not supported.\n\n\n"); }
|
||||||
|
|
||||||
SCREEN_NUM = DefaultScreen(eventdisplay);
|
SCREEN_NUM = DefaultScreen(eventdisplay);
|
||||||
@@ -508,6 +504,19 @@ void kvm_pause(int pause)
|
|||||||
g_pause = pause;
|
g_pause = pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_server_jpegerror(char *msg)
|
||||||
|
{
|
||||||
|
int msgLen = strnlen_s(msg, 255);
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_ERROR); // Write the type
|
||||||
|
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)(msgLen + 4)); // Write the size
|
||||||
|
memcpy_s(buffer + 4, 512 - 4, msg, msgLen);
|
||||||
|
|
||||||
|
if (write(slave2master[1], buffer, msgLen + 4)) {}
|
||||||
|
fsync(slave2master[1]);
|
||||||
|
}
|
||||||
|
|
||||||
void* kvm_server_mainloop(void* parm)
|
void* kvm_server_mainloop(void* parm)
|
||||||
{
|
{
|
||||||
int x, y, height, width, r, c, count = 0;
|
int x, y, height, width, r, c, count = 0;
|
||||||
@@ -526,6 +535,8 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
int screen_height, screen_width, screen_depth, screen_num;
|
int screen_height, screen_width, screen_depth, screen_num;
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
XShmSegmentInfo shminfo;
|
XShmSegmentInfo shminfo;
|
||||||
|
default_JPEG_error_handler = kvm_server_jpegerror;
|
||||||
|
|
||||||
|
|
||||||
// Init the kvm
|
// Init the kvm
|
||||||
//fprintf(logFile, "Before kvm_init.\n"); fflush(logFile);
|
//fprintf(logFile, "Before kvm_init.\n"); fflush(logFile);
|
||||||
@@ -565,7 +576,7 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
setDisplay(current_display);
|
setDisplay(current_display);
|
||||||
|
|
||||||
sprintf(displayString, ":%d", (int)current_display);
|
sprintf(displayString, ":%d", (int)current_display);
|
||||||
imagedisplay = XOpenDisplay(displayString);
|
imagedisplay = x11_exports->XOpenDisplay(displayString);
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
@@ -601,7 +612,7 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
image = XShmCreateImage(imagedisplay,
|
image = x11ext_exports->XShmCreateImage(imagedisplay,
|
||||||
DefaultVisual(imagedisplay, screen_num), // Use a correct visual. Omitted for brevity
|
DefaultVisual(imagedisplay, screen_num), // Use a correct visual. Omitted for brevity
|
||||||
screen_depth,
|
screen_depth,
|
||||||
ZPixmap, NULL, &shminfo, screen_width, screen_height);
|
ZPixmap, NULL, &shminfo, screen_width, screen_height);
|
||||||
@@ -610,8 +621,9 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
IPC_CREAT | 0777);
|
IPC_CREAT | 0777);
|
||||||
shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
|
shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
|
||||||
shminfo.readOnly = False;
|
shminfo.readOnly = False;
|
||||||
XShmAttach(imagedisplay, &shminfo);
|
x11ext_exports->XShmAttach(imagedisplay, &shminfo);
|
||||||
XShmGetImage(imagedisplay,
|
|
||||||
|
x11ext_exports->XShmGetImage(imagedisplay,
|
||||||
RootWindowOfScreen(DefaultScreenOfDisplay(imagedisplay)),
|
RootWindowOfScreen(DefaultScreenOfDisplay(imagedisplay)),
|
||||||
image,
|
image,
|
||||||
0,
|
0,
|
||||||
@@ -654,15 +666,15 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XShmDetach(imagedisplay, &shminfo);
|
x11ext_exports->XShmDetach(imagedisplay, &shminfo);
|
||||||
XDestroyImage(image); image = NULL;
|
XDestroyImage(image); image = NULL;
|
||||||
shmdt(shminfo.shmaddr);
|
shmdt(shminfo.shmaddr);
|
||||||
shmctl(shminfo.shmid, IPC_RMID, 0);
|
shmctl(shminfo.shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
if (imagedisplay != NULL)
|
if (imagedisplay != NULL)
|
||||||
{
|
{
|
||||||
XCloseDisplay(imagedisplay);
|
x11_exports->XCloseDisplay(imagedisplay);
|
||||||
imagedisplay = NULL;
|
imagedisplay = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +688,7 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
slave2master[1] = 0;
|
slave2master[1] = 0;
|
||||||
master2slave[0] = 0;
|
master2slave[0] = 0;
|
||||||
|
|
||||||
XCloseDisplay(eventdisplay);
|
x11_exports->XCloseDisplay(eventdisplay);
|
||||||
eventdisplay = NULL;
|
eventdisplay = NULL;
|
||||||
pthread_join(kvmthread, NULL);
|
pthread_join(kvmthread, NULL);
|
||||||
kvmthread = (pthread_t)NULL;
|
kvmthread = (pthread_t)NULL;
|
||||||
@@ -692,8 +704,8 @@ void* kvm_server_mainloop(void* parm)
|
|||||||
|
|
||||||
void kvm_relay_readSink(ILibProcessPipe_Pipe sender, char *buffer, int bufferLen, int* bytesConsumed)
|
void kvm_relay_readSink(ILibProcessPipe_Pipe sender, char *buffer, int bufferLen, int* bytesConsumed)
|
||||||
{
|
{
|
||||||
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)ILibMemory_GetExtraMemory(sender, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[0];
|
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)ILibMemory_Extra(sender))[0];
|
||||||
void *reserved = ((void**)ILibMemory_GetExtraMemory(sender, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[1];
|
void *reserved = ((void**)ILibMemory_Extra(sender))[1];
|
||||||
unsigned short size;
|
unsigned short size;
|
||||||
|
|
||||||
if (bufferLen > 4)
|
if (bufferLen > 4)
|
||||||
@@ -709,7 +721,7 @@ void kvm_relay_readSink(ILibProcessPipe_Pipe sender, char *buffer, int bufferLen
|
|||||||
}
|
}
|
||||||
*bytesConsumed = 0;
|
*bytesConsumed = 0;
|
||||||
}
|
}
|
||||||
void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved)
|
void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -726,11 +738,10 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
|
|||||||
r = pipe(master2slave);
|
r = pipe(master2slave);
|
||||||
|
|
||||||
slave_out = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(processPipeMgr, slave2master[0], 2 * sizeof(void*));
|
slave_out = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(processPipeMgr, slave2master[0], 2 * sizeof(void*));
|
||||||
((void**)ILibMemory_GetExtraMemory(slave_out, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[0] = writeHandler;
|
((void**)ILibMemory_Extra(slave_out))[0] = writeHandler;
|
||||||
((void**)ILibMemory_GetExtraMemory(slave_out, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[1] = reserved;
|
((void**)ILibMemory_Extra(slave_out))[1] = reserved;
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(r);
|
UNREFERENCED_PARAMETER(r);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
g_slavekvm = fork();
|
g_slavekvm = fork();
|
||||||
@@ -745,6 +756,7 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
|
|||||||
close(master2slave[1]);
|
close(master2slave[1]);
|
||||||
|
|
||||||
logFile = fopen("/tmp/slave", "w");
|
logFile = fopen("/tmp/slave", "w");
|
||||||
|
if (uid != 0) { ignore_result(setuid(uid)); }
|
||||||
|
|
||||||
//fprintf(logFile, "Starting kvm_server_mainloop\n");
|
//fprintf(logFile, "Starting kvm_server_mainloop\n");
|
||||||
kvm_server_mainloop((void*)0);
|
kvm_server_mainloop((void*)0);
|
||||||
@@ -763,11 +775,11 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
|
|||||||
|
|
||||||
|
|
||||||
// Setup the KVM session. Return 1 if ok, 0 if it could not be setup.
|
// Setup the KVM session. Return 1 if ok, 0 if it could not be setup.
|
||||||
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved)
|
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid)
|
||||||
{
|
{
|
||||||
if (kvmthread != (pthread_t)NULL || g_slavekvm != 0) return 0;
|
if (kvmthread != (pthread_t)NULL || g_slavekvm != 0) return 0;
|
||||||
g_restartcount = 0;
|
g_restartcount = 0;
|
||||||
return kvm_relay_restart(1, processPipeMgr, writeHandler, reserved);
|
return kvm_relay_restart(1, processPipeMgr, writeHandler, reserved, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a KVM reset & refresh
|
// Force a KVM reset & refresh
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ limitations under the License.
|
|||||||
|
|
||||||
typedef ILibTransport_DoneState(*ILibKVM_WriteHandler)(char *buffer, int bufferLen, void *reserved);
|
typedef ILibTransport_DoneState(*ILibKVM_WriteHandler)(char *buffer, int bufferLen, void *reserved);
|
||||||
|
|
||||||
|
void kvm_set_x11_locations(char *libx11, char *libx11tst, char *libx11ext);
|
||||||
int kvm_relay_feeddata(char* buf, int len);
|
int kvm_relay_feeddata(char* buf, int len);
|
||||||
void kvm_pause(int pause);
|
void kvm_pause(int pause);
|
||||||
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved);
|
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid);
|
||||||
void kvm_relay_reset();
|
void kvm_relay_reset();
|
||||||
void kvm_cleanup();
|
void kvm_cleanup();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user