summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2018-07-26 11:14:03 +0200
committerChristian Beier <dontmind@freeshell.org>2018-07-30 19:15:13 +0200
commitbfdb850bfb73ac08146fb7a5d4415c91116eccda (patch)
tree0ab4de84de43147fa49f34d646aeb1c62e6ca919
parent8f1b565dbeab0afd2965ef2fe8af86aabb1275dc (diff)
downloadlibtdevnc-bfdb850bfb73ac08146fb7a5d4415c91116eccda.tar.gz
libtdevnc-bfdb850bfb73ac08146fb7a5d4415c91116eccda.zip
SDLvncviewer: use SDL2 for clipboard handling
By using this, we can get rid of our own homebrewn solution scrap.[c|h] and drop X11 from the build system.
-rw-r--r--CMakeLists.txt9
-rw-r--r--client_examples/SDLvncviewer.c54
-rw-r--r--client_examples/scrap.c559
-rw-r--r--client_examples/scrap.h18
4 files changed, 26 insertions, 614 deletions
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 <SDL.h>
#include <signal.h>
#include <rfb/rfbclient.h>
-#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 <stdio.h>
-#include <limits.h>
-
-#ifdef WIN32
-#include <SDL.h>
-#include <SDL_syswm.h>
-#else
-#include <SDL/SDL.h>
-#include <SDL/SDL_syswm.h>
-#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 */