1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-11 13:53:37 +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:
Bryan Roe
2019-01-11 11:15:22 -08:00
parent 5bbdbf2e48
commit 83c1435512
7 changed files with 198 additions and 122 deletions

View File

@@ -85,10 +85,22 @@ __declspec(dllexport) int mainEx(int argc, char **argv, ExternalDispatch ptr)
while (MeshAgent_Start(agentHost, argc, argv) != 0);
retCode = agentHost->exitCode;
MeshAgent_Destroy(agentHost);
agentHost = NULL;
return(retCode);
}
#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)
{
// Check if .JS file is integrated with executable
@@ -106,6 +118,27 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
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 !defined(WIN32)
@@ -180,6 +213,7 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
while (MeshAgent_Start(agentHost, argc, argv) != 0);
retCode = agentHost->exitCode;
MeshAgent_Destroy(agentHost);
agentHost = NULL;
}
__except (ILib_WindowsExceptionFilter(GetExceptionCode(), GetExceptionInformation(), &winExceptionContext))
{
@@ -193,6 +227,7 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
while (MeshAgent_Start(agentHost, argc, argv) != 0);
retCode = agentHost->exitCode;
MeshAgent_Destroy(agentHost);
agentHost = NULL;
#ifndef _NOILIBSTACKDEBUG
if (crashMemory != NULL) { free(crashMemory); }
#endif

View File

@@ -18,6 +18,17 @@ limitations under the License.
unsigned char *jpeg_buffer = NULL;
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)
{
@@ -67,6 +78,8 @@ int write_JPEG_buffer (JSAMPLE * image_buffer, int image_width, int image_height
int row_stride;
cinfo.err = jpeg_std_error(&jerr);
if (default_JPEG_error_handler != NULL) { jerr.error_exit = jpeg_error_handler; }
jpeg_create_compress(&cinfo);
cinfo.dest = (struct jpeg_destination_mgr *) malloc (sizeof(struct jpeg_destination_mgr));
cinfo.dest->init_destination = &init_destination;

View File

@@ -20,8 +20,8 @@ limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#ifdef __APPLE__
#include "../../libjpeg-turbo/jpeglib.h"
#include "../../libjpeg-turbo/jerror.h"
#include "lib-jpeg-turbo/includes/jpeglib.h"
#include "lib-jpeg-turbo/includes/jerror.h"
#else
#include <jpeglib.h>
#include <jerror.h>
@@ -29,6 +29,9 @@ limitations under the License.
#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_

View File

@@ -18,6 +18,7 @@ limitations under the License.
static const int g_keymapLen = 96; // Modify this when you change anything in g_keymap.
extern int change_display;
x11tst_struct *x11tst_exports = NULL;
static struct keymap_t g_keymap[] = {
{ XK_BackSpace, VK_BACK },
@@ -124,7 +125,7 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
return;
}
if (!XTestFakeMotionEvent(display, -1, absX, absY, CurrentTime )) { return; }
if (!x11tst_exports->XTestFakeMotionEvent(display, -1, absX, absY, CurrentTime )) { return; }
if (button != 0) {
int mouseDown = 1;
@@ -155,7 +156,7 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
break;
}
if (!XTestFakeButtonEvent(display, button, mouseDown, CurrentTime)) { return; }
if (!x11tst_exports->XTestFakeButtonEvent(display, button, mouseDown, CurrentTime)) { return; }
}
else if (wheel != 0) {
if (wheel > 0) {
@@ -165,13 +166,13 @@ void MouseAction(double absX, double absY, int button, short wheel, Display *dis
button = Button5;
}
if (!XTestFakeButtonEvent(display, button, True, CurrentTime)) { return; }
XFlush(display);
if (!x11tst_exports->XTestFakeButtonEvent(display, button, True, CurrentTime)) { return; }
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) {
@@ -190,15 +191,15 @@ void KeyAction(unsigned char vk, int up, Display *display) {
}
}
if (keysym == 0) {
keycode = XKeysymToKeycode(display, vk);
keycode = x11tst_exports->XKeysymToKeycode(display, vk);
}
else {
keycode = XKeysymToKeycode(display, keysym);
keycode = x11tst_exports->XKeysymToKeycode(display, keysym);
}
//printf("%x %x %d %d\n", keysym, vk, keycode, up);
if (keycode != 0) {
if (!XTestFakeKeyEvent(display, keycode, !up, 0)) { return; }
XFlush(display);
if (!x11tst_exports->XTestFakeKeyEvent(display, keycode, !up, 0)) { return; }
x11tst_exports->XFlush(display);
}
}

View File

@@ -24,6 +24,18 @@ limitations under the License.
#include <stdio.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 {
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_RIGHTDOWN = 0x0008,

View File

@@ -25,14 +25,15 @@ limitations under the License.
#include <sys/ipc.h>
#include <sys/shm.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_FAILURE 1
#ifdef _DAEMON
#define _GNU_SOURCE
#endif
int SCREEN_NUM = 0;
int SCREEN_WIDTH = 0;
int SCREEN_HEIGHT = 0;
@@ -63,6 +64,28 @@ int g_enableEvents = 0;
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()
{
char buffer[8];
@@ -95,87 +118,6 @@ void kvm_send_display()
}
#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);
void* kvm_mainloopinput(void* parm)
@@ -326,6 +268,16 @@ void kvm_send_display_list()
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)
{
//fprintf(logFile, "kvm_init called\n"); fflush(logFile);
@@ -334,15 +286,59 @@ int kvm_init(int displayNo)
int dummy1, dummy2, dummy3;
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);
while (setDisplay(displayNo) != 0 && count++ < 10);
if (count == 10) { return -1; }
count = 0;
eventdisplay = XOpenDisplay(displayString);
eventdisplay = x11_exports->XOpenDisplay(displayString);
//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; }
@@ -350,12 +346,12 @@ int kvm_init(int displayNo)
if (getNextDisplay() == -1) { return -1; }
sprintf(displayString, ":%d", (int)current_display);
if (setDisplay(current_display) != 0) { continue; }
eventdisplay = XOpenDisplay(displayString);
eventdisplay = x11_exports->XOpenDisplay(displayString);
}
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"); }
SCREEN_NUM = DefaultScreen(eventdisplay);
@@ -508,6 +504,19 @@ void kvm_pause(int 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)
{
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;
ssize_t written;
XShmSegmentInfo shminfo;
default_JPEG_error_handler = kvm_server_jpegerror;
// Init the kvm
//fprintf(logFile, "Before kvm_init.\n"); fflush(logFile);
@@ -565,7 +576,7 @@ void* kvm_server_mainloop(void* parm)
setDisplay(current_display);
sprintf(displayString, ":%d", (int)current_display);
imagedisplay = XOpenDisplay(displayString);
imagedisplay = x11_exports->XOpenDisplay(displayString);
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
screen_depth,
ZPixmap, NULL, &shminfo, screen_width, screen_height);
@@ -610,8 +621,9 @@ void* kvm_server_mainloop(void* parm)
IPC_CREAT | 0777);
shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
shminfo.readOnly = False;
XShmAttach(imagedisplay, &shminfo);
XShmGetImage(imagedisplay,
x11ext_exports->XShmAttach(imagedisplay, &shminfo);
x11ext_exports->XShmGetImage(imagedisplay,
RootWindowOfScreen(DefaultScreenOfDisplay(imagedisplay)),
image,
0,
@@ -655,14 +667,14 @@ void* kvm_server_mainloop(void* parm)
}
}
XShmDetach(imagedisplay, &shminfo);
x11ext_exports->XShmDetach(imagedisplay, &shminfo);
XDestroyImage(image); image = NULL;
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
if (imagedisplay != NULL)
{
XCloseDisplay(imagedisplay);
x11_exports->XCloseDisplay(imagedisplay);
imagedisplay = NULL;
}
@@ -676,7 +688,7 @@ void* kvm_server_mainloop(void* parm)
slave2master[1] = 0;
master2slave[0] = 0;
XCloseDisplay(eventdisplay);
x11_exports->XCloseDisplay(eventdisplay);
eventdisplay = NULL;
pthread_join(kvmthread, 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)
{
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)ILibMemory_GetExtraMemory(sender, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[0];
void *reserved = ((void**)ILibMemory_GetExtraMemory(sender, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[1];
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)ILibMemory_Extra(sender))[0];
void *reserved = ((void**)ILibMemory_Extra(sender))[1];
unsigned short size;
if (bufferLen > 4)
@@ -709,7 +721,7 @@ void kvm_relay_readSink(ILibProcessPipe_Pipe sender, char *buffer, int bufferLen
}
*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 count = 0;
@@ -726,11 +738,10 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
r = pipe(master2slave);
slave_out = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(processPipeMgr, slave2master[0], 2 * sizeof(void*));
((void**)ILibMemory_GetExtraMemory(slave_out, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[0] = writeHandler;
((void**)ILibMemory_GetExtraMemory(slave_out, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[1] = reserved;
((void**)ILibMemory_Extra(slave_out))[0] = writeHandler;
((void**)ILibMemory_Extra(slave_out))[1] = reserved;
UNREFERENCED_PARAMETER(r);
do
{
g_slavekvm = fork();
@@ -745,6 +756,7 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
close(master2slave[1]);
logFile = fopen("/tmp/slave", "w");
if (uid != 0) { ignore_result(setuid(uid)); }
//fprintf(logFile, "Starting kvm_server_mainloop\n");
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.
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;
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

View File

@@ -37,10 +37,10 @@ limitations under the License.
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);
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_cleanup();