diff --git a/CMakeLists.txt b/CMakeLists.txt index c831ee9..86038d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,6 @@ option(WITH_ZLIB "Search for the zlib compression library to support additional option(WITH_JPEG "Search for the libjpeg compression library to support additional encodings" ON) option(WITH_PNG "Search for the PNG compression library to support additional encodings" ON) option(WITH_SDL "Search for the Simple Direct Media Layer library to build an example SDL vnc client" ON) -option(WITH_X11 "Search for X11 to build the example SDL vnc client with clipboard support" ON) option(WITH_THREADS "Search for a threading library to build with multithreading support" ON) option(WITH_GNUTLS "Search for the GnuTLS secure communications library to support encryption" ON) option(WITH_OPENSSL "Search for the OpenSSL cryptography library to support encryption" ON) @@ -105,11 +104,6 @@ if(WITH_SDL) endif(WITH_SDL) -if(WITH_X11) - find_package(X11) -endif(WITH_X11) - - if(WITH_THREADS) find_package(Threads) endif(WITH_THREADS) @@ -506,7 +500,6 @@ if(SDL2_FOUND) ${LIBVNCCLIENT_EXAMPLES} SDLvncviewer ) - set(SDLvncviewer_EXTRA_SOURCES scrap.c) endif(SDL2_FOUND) if(FFMPEG_FOUND) @@ -530,7 +523,7 @@ foreach(e ${LIBVNCCLIENT_EXAMPLES}) add_executable(client_examples_${e} ${LIBVNCCLIEXAMPLE_DIR}/${e}.c ${LIBVNCCLIEXAMPLE_DIR}/${${e}_EXTRA_SOURCES} ) set_target_properties(client_examples_${e} PROPERTIES OUTPUT_NAME ${e}) set_target_properties(client_examples_${e} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/client_examples) - target_link_libraries(client_examples_${e} vncclient ${CMAKE_THREAD_LIBS_INIT} ${SDL2_LIBRARY} ${X11_LIBRARIES} ${FFMPEG_LIBRARIES}) + target_link_libraries(client_examples_${e} vncclient ${CMAKE_THREAD_LIBS_INIT} ${SDL2_LIBRARY} ${FFMPEG_LIBRARIES}) endforeach(e ${LIBVNCCLIENT_EXAMPLES}) diff --git a/client_examples/SDLvncviewer.c b/client_examples/SDLvncviewer.c index 2908e4c..ff0543c 100644 --- a/client_examples/SDLvncviewer.c +++ b/client_examples/SDLvncviewer.c @@ -5,7 +5,6 @@ #include #include #include -#include "scrap.h" struct { int sdl; int rfb; } buttonMapping[]={ {1, rfbButton1Mask}, @@ -410,6 +409,28 @@ static rfbBool handleSDLEvent(rfbClient *cl, SDL_Event *e) SendFramebufferUpdateRequest(cl, 0, 0, cl->width, cl->height, FALSE); break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + if (SDL_HasClipboardText()) { + char *text = SDL_GetClipboardText(); + if(text) { + rfbClientLog("sending clipboard text '%s'\n", text); + SendClientCutText(cl, text, strlen(text)); + } + } + + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + if (rightAltKeyDown) { + SendKeyEvent(cl, XK_Alt_R, FALSE); + rightAltKeyDown = FALSE; + rfbClientLog("released right Alt key\n"); + } + if (leftAltKeyDown) { + SendKeyEvent(cl, XK_Alt_L, FALSE); + leftAltKeyDown = FALSE; + rfbClientLog("released left Alt key\n"); + } + break; } break; case SDL_MOUSEBUTTONUP: @@ -473,31 +494,6 @@ static rfbBool handleSDLEvent(rfbClient *cl, SDL_Event *e) exit(0); } /*FIXME - case SDL_ACTIVEEVENT: - if (!e->active.gain && rightAltKeyDown) { - SendKeyEvent(cl, XK_Alt_R, FALSE); - rightAltKeyDown = FALSE; - rfbClientLog("released right Alt key\n"); - } - if (!e->active.gain && leftAltKeyDown) { - SendKeyEvent(cl, XK_Alt_L, FALSE); - leftAltKeyDown = FALSE; - rfbClientLog("released left Alt key\n"); - } - - if (e->active.gain && lost_scrap()) { - static char *data = NULL; - static int len = 0; - get_scrap(T('T', 'E', 'X', 'T'), &len, &data); - if (len) - SendClientCutText(cl, data, len); - } - break; - */ - case SDL_SYSWMEVENT: - clipboard_filter(e); - break; - /*FIXME case SDL_VIDEORESIZE: setRealDimension(cl, e->resize.w, e->resize.h); break; @@ -510,7 +506,9 @@ static rfbBool handleSDLEvent(rfbClient *cl, SDL_Event *e) static void got_selection(rfbClient *cl, const char *text, int len) { - //FIXMEput_scrap(T('T', 'E', 'X', 'T'), len, text); + rfbClientLog("received clipboard text '%s'\n", text); + if(SDL_SetClipboardText(text) != 0) + rfbClientErr("could not set received clipboard text: %s\n", SDL_GetError()); } @@ -593,8 +591,6 @@ int main(int argc,char** argv) { break; } - init_scrap(); - while(1) { if(SDL_PollEvent(&e)) { /* diff --git a/client_examples/scrap.c b/client_examples/scrap.c deleted file mode 100644 index 1344b75..0000000 --- a/client_examples/scrap.c +++ /dev/null @@ -1,559 +0,0 @@ -/* Handle clipboard text and data in arbitrary formats */ - -#include -#include - -#ifdef WIN32 -#include -#include -#else -#include -#include -#endif -#include "scrap.h" -#include "rfb/rfbconfig.h" - -/* Determine what type of clipboard we are using */ -#if defined(__unix__) && !defined(__QNXNTO__) && defined(SDL_VIDEO_DRIVER_X11) -#define X11_SCRAP -#elif defined(__WIN32__) -#define WIN_SCRAP -#elif defined(__QNXNTO__) -#define QNX_SCRAP -#else -#warning Unknown window manager for clipboard handling -#endif /* scrap type */ - -/* System dependent data types */ -#if defined(X11_SCRAP) -typedef Atom scrap_type; -static Atom XA_TARGETS, XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING; -#elif defined(WIN_SCRAP) -typedef UINT scrap_type; -#elif defined(QNX_SCRAP) -typedef uint32_t scrap_type; -#define Ph_CL_TEXT T('T', 'E', 'X', 'T') -#else -typedef int scrap_type; -#endif /* scrap type */ - -/* System dependent variables */ -#if defined(X11_SCRAP) -static Display *SDL_Display; -static Window SDL_Window; -static void (*Lock_Display)(void); -static void (*Unlock_Display)(void); -static Atom XA_UTF8_STRING; -#elif defined(WIN_SCRAP) -static HWND SDL_Window; -#elif defined(QNX_SCRAP) -static unsigned short InputGroup; -#endif /* scrap type */ - -#define FORMAT_PREFIX "SDL_scrap_0x" - -static scrap_type convert_format(int type) -{ - switch (type) { - case T('T', 'E', 'X', 'T'): -#if defined(X11_SCRAP) - return XA_UTF8_STRING ? XA_UTF8_STRING : XA_STRING; -#elif defined(WIN_SCRAP) - return CF_TEXT; -#elif defined(QNX_SCRAP) - return Ph_CL_TEXT; -#endif /* scrap type */ - default: - { - char format[sizeof(FORMAT_PREFIX)+8+1]; - - sprintf(format, "%s%08lx", FORMAT_PREFIX, - (unsigned long)type); -#if defined(X11_SCRAP) - return XInternAtom(SDL_Display, format, False); -#elif defined(WIN_SCRAP) - return RegisterClipboardFormat(format); -#endif /* scrap type */ - } - } -} - -/* Convert internal data to scrap format */ -static int convert_data(int type, char *dst, const char *src, int srclen) -{ - int dstlen; - - dstlen = 0; - switch (type) { - case T('T', 'E', 'X', 'T'): - if (dst) { - while (--srclen >= 0) { -#if defined(__unix__) - if (*src == '\r') { - *dst++ = '\n'; - ++dstlen; - } - else -#elif defined(__WIN32__) - if (*src == '\r') { - *dst++ = '\r'; - ++dstlen; - *dst++ = '\n'; - ++dstlen; - } - else -#endif - { - *dst++ = *src; - ++dstlen; - } - ++src; - } - *dst = '\0'; - ++dstlen; - } - else { - while (--srclen >= 0) { -#if defined(__unix__) - if (*src == '\r') - ++dstlen; - else -#elif defined(__WIN32__) - if (*src == '\r') { - ++dstlen; - ++dstlen; - } - else -#endif - { - ++dstlen; - } - ++src; - } - ++dstlen; - } - break; - default: - if (dst) { - *(int *)dst = srclen; - dst += sizeof(int); - memcpy(dst, src, srclen); - } - dstlen = sizeof(int)+srclen; - break; - } - return(dstlen); -} - -/* Convert scrap data to internal format */ -static int convert_scrap(int type, char *dst, char *src, int srclen) -{ - int dstlen; - - dstlen = 0; - switch (type) { - case T('T', 'E', 'X', 'T'): - { - if (srclen == 0) - srclen = strlen(src); - if (dst) { - while (--srclen >= 0) { -#if defined(__WIN32__) - if (*src == '\r') - /* drop extraneous '\r' */; - else -#endif - if (*src == '\n') { - *dst++ = '\r'; - ++dstlen; - } - else { - *dst++ = *src; - ++dstlen; - } - ++src; - } - *dst = '\0'; - ++dstlen; - } - else { - while (--srclen >= 0) { -#if defined(__WIN32__) - /* drop extraneous '\r' */; - if (*src != '\r') -#endif - ++dstlen; - ++src; - } - ++dstlen; - } - break; - } - default: - dstlen = *(int *)src; - if (dst) - memcpy(dst, src + sizeof(int), - srclen ? srclen - sizeof(int) : dstlen); - break; - } - return dstlen; -} - -int init_scrap(void) -{ - SDL_SysWMinfo info; - int retval; - - /* Grab the window manager specific information */ - retval = -1; - SDL_SetError("SDL is not running on known window manager"); - - SDL_VERSION(&info.version); - //FIXMEif (SDL_GetWMInfo(&info)) - { - /* Save the information for later use */ -#if defined(X11_SCRAP) - if (info.subsystem == SDL_SYSWM_X11) { - SDL_Display = info.info.x11.display; - SDL_Window = info.info.x11.window; - Lock_Display = info.info.x11.lock_func; - Unlock_Display = info.info.x11.unlock_func; - - /* Enable the special window hook events */ - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - SDL_SetEventFilter(clipboard_filter); - - XA_TARGETS = XInternAtom(SDL_Display, "TARGETS", False); - XA_TEXT = XInternAtom(SDL_Display, "TEXT", False); - XA_COMPOUND_TEXT = XInternAtom(SDL_Display, - "COMPOUND_TEXT", False); - XA_UTF8_STRING = XInternAtom(SDL_Display, - "UTF8_STRING", False); - - retval = 0; - } - else - SDL_SetError("SDL is not running on X11"); -#elif defined(WIN_SCRAP) - SDL_Window = info.window; - retval = 0; -#elif defined(QNX_SCRAP) - InputGroup = PhInputGroup(NULL); - retval = 0; -#endif /* scrap type */ - } - return(retval); -} - -int lost_scrap(void) -{ - int retval; - -#if defined(X11_SCRAP) - if (Lock_Display) - Lock_Display(); - retval = (XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window); - if (Unlock_Display) - Unlock_Display(); -#elif defined(WIN_SCRAP) - retval = (GetClipboardOwner() != SDL_Window); -#elif defined(QNX_SCRAP) - retval = (PhInputGroup(NULL) != InputGroup); -#endif /* scrap type */ - - return(retval); -} - -void put_scrap(int type, int srclen, const char *src) -{ - scrap_type format; - int dstlen; - char *dst; - - format = convert_format(type); - dstlen = convert_data(type, NULL, src, srclen); - -#if defined(X11_SCRAP) - dst = (char *)malloc(dstlen); - if (dst != NULL) { - if (Lock_Display) - Lock_Display(); - convert_data(type, dst, src, srclen); - XChangeProperty(SDL_Display, DefaultRootWindow(SDL_Display), - XA_CUT_BUFFER0, format, 8, PropModeReplace, - (unsigned char *)dst, dstlen); - free(dst); - if (lost_scrap()) - XSetSelectionOwner(SDL_Display, XA_PRIMARY, - SDL_Window, CurrentTime); - if (Unlock_Display) - Unlock_Display(); - } -#elif defined(WIN_SCRAP) - if (OpenClipboard(SDL_Window)) { - HANDLE hMem; - - hMem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), dstlen); - if (hMem != NULL) { - dst = (char *)GlobalLock(hMem); - convert_data(type, dst, src, srclen); - GlobalUnlock(hMem); - EmptyClipboard(); - SetClipboardData(format, hMem); - } - CloseClipboard(); - } -#elif defined(QNX_SCRAP) -#if (_NTO_VERSION < 620) /* before 6.2.0 releases */ -#define PhClipboardHdr PhClipHeader -#endif - { - PhClipboardHdr clheader = { Ph_CLIPBOARD_TYPE_TEXT, 0, NULL }; - int* cldata; - int status; - - dst = (char *)malloc(dstlen+4); - if (dst != NULL) { - cldata = (int*)dst; - *cldata = type; - convert_data(type, dst+4, src, srclen); - clheader.data = dst; -#if (_NTO_VERSION < 620) /* before 6.2.0 releases */ - if (dstlen > 65535) - /* maximum photon clipboard size :(*/ - clheader.length = 65535; - else -#endif - clheader.length = dstlen+4; - status = PhClipboardCopy(InputGroup, 1, &clheader); - if (status == -1) - fprintf(stderr, - "Photon: copy to clipboard failed!\n"); - free(dst); - } - } -#endif /* scrap type */ -} - -void get_scrap(int type, int *dstlen, char **dst) -{ - scrap_type format; - - *dstlen = 0; - format = convert_format(type); - -#if defined(X11_SCRAP) - { - Window owner; - Atom selection; - Atom seln_type; - int seln_format; - unsigned long nbytes; - unsigned long overflow; - char *src; - - if (Lock_Display) - Lock_Display(); - owner = XGetSelectionOwner(SDL_Display, XA_PRIMARY); - if (Unlock_Display) - Unlock_Display(); - if ((owner == None) || (owner == SDL_Window)) { - owner = DefaultRootWindow(SDL_Display); - selection = XA_CUT_BUFFER0; - } - else { - int selection_response = 0; - SDL_Event event; - - owner = SDL_Window; - if (Lock_Display) - Lock_Display(); - selection = XInternAtom(SDL_Display, "SDL_SELECTION", - False); - XConvertSelection(SDL_Display, XA_PRIMARY, format, - selection, owner, CurrentTime); - if (Unlock_Display) - Unlock_Display(); - while (!selection_response) { - SDL_WaitEvent(&event); - if (event.type == SDL_SYSWMEVENT) { - XEvent xevent = - event.syswm.msg->event.xevent; - - if ((xevent.type == SelectionNotify) && - (xevent.xselection.requestor - == owner)) - selection_response = 1; - } - } - } - if (Lock_Display) - Lock_Display(); - if (XGetWindowProperty(SDL_Display, owner, selection, - 0, INT_MAX/4, False, format, &seln_type, - &seln_format, &nbytes, &overflow, - (unsigned char **)&src) == Success) { - if (seln_type == format) { - *dstlen = convert_scrap(type, NULL, - src, nbytes); - *dst = (char *)realloc(*dst, *dstlen); - if (*dst == NULL) - *dstlen = 0; - else - convert_scrap(type, *dst, src, nbytes); - } - XFree(src); - } - } - if (Unlock_Display) - Unlock_Display(); -#elif defined(WIN_SCRAP) - if (IsClipboardFormatAvailable(format) && OpenClipboard(SDL_Window)) { - HANDLE hMem; - char *src; - - hMem = GetClipboardData(format); - if (hMem != NULL) { - src = (char *)GlobalLock(hMem); - *dstlen = convert_scrap(type, NULL, src, 0); - *dst = (char *)realloc(*dst, *dstlen); - if (*dst == NULL) - *dstlen = 0; - else - convert_scrap(type, *dst, src, 0); - GlobalUnlock(hMem); - } - CloseClipboard(); - } -#elif defined(QNX_SCRAP) -#if (_NTO_VERSION < 620) /* before 6.2.0 releases */ - { - void* clhandle; - PhClipHeader* clheader; - int* cldata; - - clhandle = PhClipboardPasteStart(InputGroup); - if (clhandle != NULL) { - clheader = PhClipboardPasteType(clhandle, - Ph_CLIPBOARD_TYPE_TEXT); - if (clheader != NULL) { - cldata = clheader->data; - if ((clheader->length>4) && (*cldata == type)) { - *dstlen = convert_scrap(type, NULL, - (char*)clheader->data+4, - clheader->length-4); - *dst = (char *)realloc(*dst, *dstlen); - if (*dst == NULL) - *dstlen = 0; - else - convert_scrap(type, *dst, - (char*)clheader->data+4, - clheader->length-4); - } - } - PhClipboardPasteFinish(clhandle); - } - } -#else /* 6.2.0 and 6.2.1 and future releases */ - { - void* clhandle; - PhClipboardHdr* clheader; - int* cldata; - - clheader=PhClipboardRead(InputGroup, Ph_CLIPBOARD_TYPE_TEXT); - if (clheader!=NULL) { - cldata=clheader->data; - if ((clheader->length>4) && (*cldata==type)) { - *dstlen = convert_scrap(type, NULL, - (char*)clheader->data+4, - clheader->length-4); - *dst = (char *)realloc(*dst, *dstlen); - if (*dst == NULL) - *dstlen = 0; - else - convert_scrap(type, *dst, - (char*)clheader->data+4, - clheader->length-4); - } - } - } -#endif -#endif /* scrap type */ -} - -int clipboard_filter(const SDL_Event *event) -{ -#if defined(X11_SCRAP) - /* Post all non-window manager specific events */ - if (event->type != SDL_SYSWMEVENT) - return(1); - - /* Handle window-manager specific clipboard events */ - switch (event->syswm.msg->event.xevent.type) { - /* Copy the selection from XA_CUT_BUFFER0 to the requested property */ - case SelectionRequest: { - XSelectionRequestEvent *req; - XEvent sevent; - int seln_format; - unsigned long nbytes; - unsigned long overflow; - unsigned char *seln_data; - - req = &event->syswm.msg->event.xevent.xselectionrequest; - if (req->target == XA_TARGETS) { - Atom supported[] = { - XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING, - XA_TARGETS, XA_STRING - }; - XEvent response; - - XChangeProperty(SDL_Display, req->requestor, - req->property, req->target, 32, PropModeReplace, - (unsigned char*)supported, - sizeof(supported) / sizeof(supported[0])); - response.xselection.property=None; - response.xselection.type= SelectionNotify; - response.xselection.display= req->display; - response.xselection.requestor= req->requestor; - response.xselection.selection=req->selection; - response.xselection.target= req->target; - response.xselection.time = req->time; - XSendEvent (SDL_Display, req->requestor,0,0,&response); - XFlush (SDL_Display); - return 1; - } - - sevent.xselection.type = SelectionNotify; - sevent.xselection.display = req->display; - sevent.xselection.selection = req->selection; - sevent.xselection.target = None; - sevent.xselection.property = req->property; - sevent.xselection.requestor = req->requestor; - sevent.xselection.time = req->time; - if (XGetWindowProperty(SDL_Display, - DefaultRootWindow(SDL_Display), XA_CUT_BUFFER0, - 0, INT_MAX/4, False, req->target, - &sevent.xselection.target, &seln_format, - &nbytes, &overflow, &seln_data) == Success) { - if (sevent.xselection.target == req->target) { - if (sevent.xselection.target == XA_STRING && - nbytes > 0 && - seln_data[nbytes-1] == '\0') - --nbytes; - XChangeProperty(SDL_Display, req->requestor, - req->property, sevent.xselection.target, - seln_format, PropModeReplace, - seln_data, nbytes); - sevent.xselection.property = req->property; - } - XFree(seln_data); - } - XSendEvent(SDL_Display,req->requestor,False,0,&sevent); - XSync(SDL_Display, False); - break; - } - } - /* Post the event for X11 clipboard reading above */ -#endif /* X11_SCRAP */ - return(1); -} diff --git a/client_examples/scrap.h b/client_examples/scrap.h deleted file mode 100644 index 647bd74..0000000 --- a/client_examples/scrap.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Handle clipboard text and data in arbitrary formats */ - -/* Miscellaneous defines */ -#define T(A, B, C, D) (int)((A<<24)|(B<<16)|(C<<8)|(D<<0)) - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern int init_scrap(void); -extern int lost_scrap(void); -extern void put_scrap(int type, int srclen, const char *src); -extern void get_scrap(int type, int *dstlen, char **dst); -extern int clipboard_filter(const SDL_Event *event); - -#ifdef __cplusplus -} -#endif /* __cplusplus */