VirtualBox

Changeset 7073 in vbox for trunk/src/VBox/HostServices


Ignore:
Timestamp:
Feb 21, 2008 2:28:28 PM (17 years ago)
Author:
vboxsync
Message:

Added support for the clipboard on Mac OS X hosts. Currently unicode text can be
transfered from and to the host/guest. I'm also separated some functions of linux.cpp
in a separate clipboard-helper.cpp for reuse in the mac parts.

Location:
trunk/src/VBox/HostServices
Files:
5 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/Makefile.kmk

    r6366 r7073  
    2727  include $(PATH_SUB_CURRENT)/SharedOpenGL/Makefile.kmk
    2828 endif
     29endif
     30if1of ($(BUILD_TARGET), win linux solaris darwin)
    2931 ifdef VBOX_WITH_SHARED_CLIPBOARD
    3032  include $(PATH_SUB_CURRENT)/SharedClipboard/Makefile.kmk
  • trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk

    r6773 r7073  
    3333VBoxSharedClipboard_SOURCES.win = \
    3434        win32.cpp
     35VBoxSharedClipboard_SOURCES.darwin = \
     36        darwin.cpp \
     37    clipboard-helper.cpp \
     38    darwin-pasteboard.cpp
    3539if1of ($(BUILD_TARGET),linux solaris)
    3640 ifndef VBOX_HEADLESS
    3741  VBoxSharedClipboard_SOURCES += \
     42    clipboard-helper.cpp \
    3843        linux.cpp
    3944 else
     
    5762endif
    5863
     64VBoxSharedClipboard_LDFLAGS.darwin =  -framework ApplicationServices
     65
    5966include $(PATH_KBUILD)/subfooter.kmk
    6067
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h

    r5999 r7073  
    2121#define LOG_GROUP LOG_GROUP_HGCM
    2222#include <VBox/log.h>
    23 
    24 /** Constants needed for string conversions done by the Linux clipboard code. */
    25 enum {
    26     /** In Linux, lines end with a linefeed character. */
    27     LINEFEED = 0xa,
    28     /** In Windows, lines end with a carriage return and a linefeed character. */
    29     CARRIAGERETURN = 0xd,
    30     /** Little endian "real" Utf16 strings start with this marker. */
    31     UTF16LEMARKER = 0xfeff,
    32     /** Big endian "real" Utf16 strings start with this marker. */
    33     UTF16BEMARKER = 0xfffe
    34 };
    3523
    3624enum {
  • trunk/src/VBox/HostServices/SharedClipboard/linux.cpp

    r6990 r7073  
    3838
    3939#include "VBoxClipboard.h"
     40#include "clipboard-helper.h"
    4041
    4142#include <X11/Xlib.h>
     
    159160/* Only one client is supported. There seems to be no need for more clients. */
    160161static VBOXCLIPBOARDCONTEXT g_ctx;
    161 
    162 /**
    163  * Get the size of the buffer needed to hold a Utf16-LE zero terminated string with Windows EOLs
    164  * converted from a Utf16 string with Linux EOLs.
    165  *
    166  * @returns RT error code
    167  *
    168  * @param   pu16Src  The source Utf16 string
    169  * @param   cwSrc    The length in 16 bit words of the source string
    170  * @retval  pcwDest  The length of the destination string in 16 bit words
    171  */
    172 static int vboxClipboardUtf16GetWinSize(PRTUTF16 pu16Src, size_t cwSrc, size_t *pcwDest)
    173 {
    174     size_t cwDest, i;
    175 
    176     LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc));
    177     if (pu16Src == 0)
    178     {
    179         LogRel(("vboxClipboardUtf16GetWinSize: received a null Utf16 string, returning VERR_INVALID_PARAMETER\n"));
    180         AssertReturn(pu16Src != 0, VERR_INVALID_PARAMETER);
    181     }
    182     /* We only take little endian Utf16 */
    183     if (pu16Src[0] == UTF16BEMARKER)
    184     {
    185         LogRel(("vboxClipboardUtf16GetWinSize: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
    186         AssertReturn(pu16Src[0] != UTF16BEMARKER, VERR_INVALID_PARAMETER);
    187     }
    188     if (cwSrc == 0)
    189     {
    190         *pcwDest = 0;
    191         LogFlowFunc(("empty source string, returning\n"));
    192         return VINF_SUCCESS;
    193     }
    194     cwDest = 0;
    195     /* Calculate the size of the destination text string. */
    196     /* Is this Utf16 or Utf16-LE? */
    197     for (i = (pu16Src[0] == UTF16LEMARKER ? 1 : 0); i < cwSrc; ++i, ++cwDest)
    198     {
    199         if (pu16Src[i] == LINEFEED)
    200             ++cwDest;
    201         if (pu16Src[i] == 0)
    202         {
    203             /* Don't count this, as we do so below. */
    204             break;
    205         }
    206     }
    207     /* Count the terminating null byte. */
    208     ++cwDest;
    209     LogFlowFunc(("returning VINF_SUCCESS, %d 16bit words\n", cwDest));
    210     *pcwDest = cwDest;
    211     return VINF_SUCCESS;
    212 }
    213 
    214 /**
    215  * Convert a Utf16 text with Linux EOLs to null-terminated Utf16-LE with Windows EOLs.  Does no
    216  * checking for validity.
    217  *
    218  * @returns VBox status code
    219  *
    220  * @param   pu16Src  Source Utf16 text to convert
    221  * @param   cwSrc    Size of the source text in 16 bit words
    222  * @retval  pu16Dest Buffer to store the converted text to.
    223  * @retval  pcwDest  Size of the buffer for the converted text in 16 bit words
    224  */
    225 static int vboxClipboardUtf16LinToWin(PRTUTF16 pu16Src, size_t cwSrc, PRTUTF16 pu16Dest,
    226                                       size_t cwDest)
    227 {
    228     size_t i, j;
    229     LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc));
    230     if (!VALID_PTR(pu16Src) || !VALID_PTR(pu16Dest))
    231     {
    232         LogRel(("vboxClipboardUtf16LinToWin: received an invalid pointer, pu16Src=%p, pu16Dest=%p, returning VERR_INVALID_PARAMETER\n", pu16Src, pu16Dest));
    233         AssertReturn(VALID_PTR(pu16Src) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER);
    234     }
    235     /* We only take little endian Utf16 */
    236     if (pu16Src[0] == UTF16BEMARKER)
    237     {
    238         LogRel(("vboxClipboardUtf16LinToWin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
    239         AssertReturn(pu16Src[0] != UTF16BEMARKER, VERR_INVALID_PARAMETER);
    240     }
    241     if (cwSrc == 0)
    242     {
    243         if (cwDest == 0)
    244         {
    245             LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    246             return VERR_BUFFER_OVERFLOW;
    247         }
    248         pu16Dest[0] = 0;
    249         LogFlowFunc(("empty source string, returning\n"));
    250         return VINF_SUCCESS;
    251     }
    252     /* Don't copy the endian marker. */
    253     for (i = (pu16Src[0] == UTF16LEMARKER ? 1 : 0), j = 0; i < cwSrc; ++i, ++j)
    254     {
    255         /* Don't copy the null byte, as we add it below. */
    256         if (pu16Src[i] == 0)
    257             break;
    258         if (j == cwDest)
    259         {
    260             LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    261             return VERR_BUFFER_OVERFLOW;
    262         }
    263         if (pu16Src[i] == LINEFEED)
    264         {
    265             pu16Dest[j] = CARRIAGERETURN;
    266             ++j;
    267             if (j == cwDest)
    268             {
    269                 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    270                 return VERR_BUFFER_OVERFLOW;
    271             }
    272         }
    273         pu16Dest[j] = pu16Src[i];
    274     }
    275     /* Add the trailing null. */
    276     if (j == cwDest)
    277     {
    278         LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    279         return VERR_BUFFER_OVERFLOW;
    280     }
    281     pu16Dest[j] = 0;
    282     LogFlowFunc(("rc=VINF_SUCCESS, pu16Dest=%ls\n", pu16Dest));
    283     return VINF_SUCCESS;
    284 }
    285 
    286 /**
    287  * Get the size of the buffer needed to hold a zero-terminated Utf16 string with Linux EOLs
    288  * converted from a Utf16 string with Windows EOLs.
    289  *
    290  * @returns RT status code
    291  *
    292  * @param   pu16Src  The source Utf16 string
    293  * @param   cwSrc    The length in 16 bit words of the source string
    294  * @retval  pcwDest  The length of the destination string in 16 bit words
    295  */
    296 static int vboxClipboardUtf16GetLinSize(PRTUTF16 pu16Src, size_t cwSrc, size_t *pcwDest)
    297 {
    298     size_t cwDest;
    299 
    300     LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc));
    301     if (!VALID_PTR(pu16Src))
    302     {
    303         LogRel(("vboxClipboardUtf16GetLinSize: received an invalid Utf16 string %p.  Returning VERR_INVALID_PARAMETER.\n", pu16Src));
    304         AssertReturn(VALID_PTR(pu16Src), VERR_INVALID_PARAMETER);
    305     }
    306     /* We only take little endian Utf16 */
    307     if (pu16Src[0] == UTF16BEMARKER)
    308     {
    309         LogRel(("vboxClipboardUtf16GetLinSize: received a big endian Utf16 string.  Returning VERR_INVALID_PARAMETER.\n"));
    310         AssertReturn(pu16Src[0] != UTF16BEMARKER, VERR_INVALID_PARAMETER);
    311     }
    312     if (cwSrc == 0)
    313     {
    314         LogFlowFunc(("empty source string, returning VINF_SUCCESS\n"));
    315         *pcwDest = 0;
    316         return VINF_SUCCESS;
    317     }
    318     /* Calculate the size of the destination text string. */
    319     /* Is this Utf16 or Utf16-LE? */
    320     if (pu16Src[0] == UTF16LEMARKER)
    321         cwDest = 0;
    322     else
    323         cwDest = 1;
    324     for (size_t i = 0; i < cwSrc; ++i, ++cwDest)
    325     {
    326         if (   (i + 1 < cwSrc)
    327             && (pu16Src[i] == CARRIAGERETURN)
    328             && (pu16Src[i + 1] == LINEFEED))
    329         {
    330             ++i;
    331         }
    332         if (pu16Src[i] == 0)
    333         {
    334             break;
    335         }
    336     }
    337     /* Terminating zero */
    338     ++cwDest;
    339     LogFlowFunc(("returning %d\n", cwDest));
    340     *pcwDest = cwDest;
    341     return VINF_SUCCESS;
    342 }
    343 
    344 /**
    345  * Convert Utf16-LE text with Windows EOLs to zero-terminated Utf16 with Linux EOLs.  This
    346  * function does not verify that the Utf16 is valid.
    347  *
    348  * @returns VBox status code
    349  *
    350  * @param   pu16Src       Text to convert
    351  * @param   cwSrc         Size of the source text in 16 bit words
    352  * @param   pu16Dest      The buffer to store the converted text to
    353  * @param   cwDest        The size of the buffer for the destination text in 16 bit words
    354  */
    355 static int vboxClipboardUtf16WinToLin(PRTUTF16 pu16Src, size_t cwSrc, PRTUTF16 pu16Dest,
    356                                       size_t cwDest)
    357 {
    358     size_t cwDestPos;
    359 
    360     LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u, pu16Dest=%p, cwDest=%u\n",
    361                  cwSrc, pu16Src, cwSrc, pu16Dest, cwDest));
    362     /* A buffer of size 0 may not be an error, but it is not a good idea either. */
    363     Assert(cwDest > 0);
    364     if (!VALID_PTR(pu16Src) || !VALID_PTR(pu16Dest))
    365     {
    366         LogRel(("vboxClipboardUtf16WinToLin: received an invalid ptr, pu16Src=%p, pu16Dest=%p, returning VERR_INVALID_PARAMETER\n", pu16Src, pu16Dest));
    367         AssertReturn(VALID_PTR(pu16Src) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER);
    368     }
    369     /* We only take little endian Utf16 */
    370     if (pu16Src[0] == UTF16BEMARKER)
    371     {
    372         LogRel(("vboxClipboardUtf16WinToLin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
    373         AssertMsgFailedReturn(("received a big endian string\n"), VERR_INVALID_PARAMETER);
    374     }
    375     if (cwDest == 0)
    376     {
    377         LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    378         return VERR_BUFFER_OVERFLOW;
    379     }
    380     if (cwSrc == 0)
    381     {
    382         pu16Dest[0] = 0;
    383         LogFlowFunc(("received empty string.  Returning VINF_SUCCESS\n"));
    384         return VINF_SUCCESS;
    385     }
    386     /* Prepend the Utf16 byte order marker if it is missing. */
    387     if (pu16Src[0] == UTF16LEMARKER)
    388     {
    389         cwDestPos = 0;
    390     }
    391     else
    392     {
    393         pu16Dest[0] = UTF16LEMARKER;
    394         cwDestPos = 1;
    395     }
    396     for (size_t i = 0; i < cwSrc; ++i, ++cwDestPos)
    397     {
    398         if (pu16Src[i] == 0)
    399         {
    400             break;
    401         }
    402         if (cwDestPos == cwDest)
    403         {
    404             LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    405             return VERR_BUFFER_OVERFLOW;
    406         }
    407         if (   (i + 1 < cwSrc)
    408             && (pu16Src[i] == CARRIAGERETURN)
    409             && (pu16Src[i + 1] == LINEFEED))
    410         {
    411             ++i;
    412         }
    413         pu16Dest[cwDestPos] = pu16Src[i];
    414     }
    415     /* Terminating zero */
    416     if (cwDestPos == cwDest)
    417     {
    418         LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
    419         return VERR_BUFFER_OVERFLOW;
    420     }
    421     pu16Dest[cwDestPos] = 0;
    422     LogFlowFunc(("set string %ls.  Returning\n", pu16Dest + 1));
    423     return VINF_SUCCESS;
    424 }
    425162
    426163/**
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette