Added Windows clipboard support
authorSam Lantinga <slouken@libsdl.org>
Thu, 08 Jul 2010 05:43:34 -0700
changeset 4500eff4e88cc1e8
parent 4499 c2ebe3e020c6
child 4501 0cf025066b6f
Added Windows clipboard support
VisualC/SDL/SDL_VS2005.vcproj
VisualC/SDL/SDL_VS2008.vcproj
VisualC/SDLmain/SDLmain_VS2008.vcproj
src/video/SDL_clipboard.c
src/video/win32/SDL_win32clipboard.c
src/video/win32/SDL_win32clipboard.h
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32events.h
src/video/win32/SDL_win32video.c
src/video/win32/SDL_win32video.h
src/video/win32/SDL_win32window.c
     1.1 --- a/VisualC/SDL/SDL_VS2005.vcproj	Thu Jul 08 00:35:58 2010 -0700
     1.2 +++ b/VisualC/SDL/SDL_VS2005.vcproj	Thu Jul 08 05:43:34 2010 -0700
     1.3 @@ -236,6 +236,10 @@
     1.4  				>
     1.5  			</File>
     1.6  			<File
     1.7 +				RelativePath="..\..\include\SDL_clipboard.h"
     1.8 +				>
     1.9 +			</File>
    1.10 +			<File
    1.11  				RelativePath="..\..\include\SDL_compat.h"
    1.12  				>
    1.13  			</File>
    1.14 @@ -561,6 +565,10 @@
    1.15  			>
    1.16  		</File>
    1.17  		<File
    1.18 +			RelativePath="..\..\src\video\SDL_clipboard.c"
    1.19 +			>
    1.20 +		</File>
    1.21 +		<File
    1.22  			RelativePath="..\..\src\SDL_compat.c"
    1.23  			>
    1.24  		</File>
    1.25 @@ -941,6 +949,14 @@
    1.26  			>
    1.27  		</File>
    1.28  		<File
    1.29 +			RelativePath="..\..\src\video\win32\SDL_win32clipboard.c"
    1.30 +			>
    1.31 +		</File>
    1.32 +		<File
    1.33 +			RelativePath="..\..\src\video\win32\SDL_win32clipboard.h"
    1.34 +			>
    1.35 +		</File>
    1.36 +		<File
    1.37  			RelativePath="..\..\src\video\win32\SDL_win32events.c"
    1.38  			>
    1.39  		</File>
     2.1 --- a/VisualC/SDL/SDL_VS2008.vcproj	Thu Jul 08 00:35:58 2010 -0700
     2.2 +++ b/VisualC/SDL/SDL_VS2008.vcproj	Thu Jul 08 05:43:34 2010 -0700
     2.3 @@ -5,9 +5,6 @@
     2.4  	Name="SDL"
     2.5  	ProjectGUID="{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}"
     2.6  	RootNamespace="SDL"
     2.7 -	SccProjectName="Perforce Project"
     2.8 -	SccLocalPath="..\.."
     2.9 -	SccProvider="MSSCCI:Perforce SCM"
    2.10  	TargetFrameworkVersion="131072"
    2.11  	>
    2.12  	<Platforms>
    2.13 @@ -386,6 +383,10 @@
    2.14  				>
    2.15  			</File>
    2.16  			<File
    2.17 +				RelativePath="..\..\include\SDL_clipboard.h"
    2.18 +				>
    2.19 +			</File>
    2.20 +			<File
    2.21  				RelativePath="..\..\include\SDL_compat.h"
    2.22  				>
    2.23  			</File>
    2.24 @@ -719,6 +720,10 @@
    2.25  			>
    2.26  		</File>
    2.27  		<File
    2.28 +			RelativePath="..\..\src\video\SDL_clipboard.c"
    2.29 +			>
    2.30 +		</File>
    2.31 +		<File
    2.32  			RelativePath="..\..\src\SDL_compat.c"
    2.33  			>
    2.34  		</File>
    2.35 @@ -1099,6 +1104,14 @@
    2.36  			>
    2.37  		</File>
    2.38  		<File
    2.39 +			RelativePath="..\..\src\video\win32\SDL_win32clipboard.c"
    2.40 +			>
    2.41 +		</File>
    2.42 +		<File
    2.43 +			RelativePath="..\..\src\video\win32\SDL_win32clipboard.h"
    2.44 +			>
    2.45 +		</File>
    2.46 +		<File
    2.47  			RelativePath="..\..\src\video\win32\SDL_win32events.c"
    2.48  			>
    2.49  		</File>
     3.1 --- a/VisualC/SDLmain/SDLmain_VS2008.vcproj	Thu Jul 08 00:35:58 2010 -0700
     3.2 +++ b/VisualC/SDLmain/SDLmain_VS2008.vcproj	Thu Jul 08 05:43:34 2010 -0700
     3.3 @@ -4,9 +4,6 @@
     3.4  	Version="9.00"
     3.5  	Name="SDLmain"
     3.6  	ProjectGUID="{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}"
     3.7 -	SccProjectName="Perforce Project"
     3.8 -	SccLocalPath="..\.."
     3.9 -	SccProvider="MSSCCI:Perforce SCM"
    3.10  	TargetFrameworkVersion="131072"
    3.11  	>
    3.12  	<Platforms>
     4.1 --- a/src/video/SDL_clipboard.c	Thu Jul 08 00:35:58 2010 -0700
     4.2 +++ b/src/video/SDL_clipboard.c	Thu Jul 08 05:43:34 2010 -0700
     4.3 @@ -30,6 +30,9 @@
     4.4  {
     4.5      SDL_VideoDevice *_this = SDL_GetVideoDevice();
     4.6  
     4.7 +    if (!text) {
     4.8 +        text = "";
     4.9 +    }
    4.10      if (_this->SetClipboardText) {
    4.11          return _this->SetClipboardText(_this, text);
    4.12      } else {
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/video/win32/SDL_win32clipboard.c	Thu Jul 08 05:43:34 2010 -0700
     5.3 @@ -0,0 +1,144 @@
     5.4 +/*
     5.5 +    SDL - Simple DirectMedia Layer
     5.6 +    Copyright (C) 1997-2010 Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Lesser General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2.1 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Lesser General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Lesser General Public
    5.19 +    License along with this library; if not, write to the Free Software
    5.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    5.21 +
    5.22 +    Sam Lantinga
    5.23 +    slouken@libsdl.org
    5.24 +*/
    5.25 +#include "SDL_config.h"
    5.26 +
    5.27 +#include "SDL_win32video.h"
    5.28 +#include "SDL_win32window.h"
    5.29 +
    5.30 +
    5.31 +#ifdef UNICODE
    5.32 +#define TEXT_FORMAT  CF_UNICODETEXT
    5.33 +#else
    5.34 +#define TEXT_FORMAT  CF_TEXT
    5.35 +#endif
    5.36 +
    5.37 +
    5.38 +/* Get any application owned window handle for clipboard association */
    5.39 +static HWND
    5.40 +GetWindowHandle(_THIS)
    5.41 +{
    5.42 +    SDL_VideoDisplay *display;
    5.43 +    SDL_Window *window;
    5.44 +
    5.45 +    display = _this->displays;
    5.46 +    if (display) {
    5.47 +        window = display->windows;
    5.48 +        if (window) {
    5.49 +            return ((SDL_WindowData *) window->driverdata)->hwnd;
    5.50 +        }
    5.51 +    }
    5.52 +    return NULL;
    5.53 +}
    5.54 +
    5.55 +int
    5.56 +WIN_SetClipboardText(_THIS, const char *text)
    5.57 +{
    5.58 +    int result = 0;
    5.59 +
    5.60 +    if (OpenClipboard(GetWindowHandle(_this))) {
    5.61 +        HANDLE hMem;
    5.62 +        LPTSTR tstr;
    5.63 +        SIZE_T i, size;
    5.64 +
    5.65 +        /* Convert the text from UTF-8 to Windows Unicode */
    5.66 +        tstr = WIN_UTF8ToString(text);
    5.67 +        if (!tstr) {
    5.68 +            return -1;
    5.69 +        }
    5.70 +
    5.71 +        /* Find out the size of the data */
    5.72 +        for (size = 0, i = 0; tstr[i]; ++i, ++size) {
    5.73 +            if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
    5.74 +                /* We're going to insert a carriage return */
    5.75 +                ++size;
    5.76 +            }
    5.77 +        }
    5.78 +        size = (size+1)*sizeof(*tstr);
    5.79 +
    5.80 +        /* Save the data to the clipboard */
    5.81 +        hMem = GlobalAlloc(GMEM_MOVEABLE, size);
    5.82 +        if (hMem) {
    5.83 +            LPTSTR dst = (LPTSTR)GlobalLock(hMem);
    5.84 +            /* Copy the text over, adding carriage returns as necessary */
    5.85 +            for (i = 0; tstr[i]; ++i) {
    5.86 +                if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
    5.87 +                    *dst++ = '\r';
    5.88 +                }
    5.89 +                *dst++ = tstr[i];
    5.90 +            }
    5.91 +            *dst = 0;
    5.92 +            GlobalUnlock(hMem);
    5.93 +
    5.94 +            EmptyClipboard();
    5.95 +            if (!SetClipboardData(TEXT_FORMAT, hMem)) {
    5.96 +                WIN_SetError("Couldn't set clipboard data");
    5.97 +                result = -1;
    5.98 +            }
    5.99 +        }
   5.100 +        SDL_free(tstr);
   5.101 +
   5.102 +        CloseClipboard();
   5.103 +    } else {
   5.104 +        WIN_SetError("Couldn't open clipboard");
   5.105 +        result = -1;
   5.106 +    }
   5.107 +    return result;
   5.108 +}
   5.109 +
   5.110 +char *
   5.111 +WIN_GetClipboardText(_THIS)
   5.112 +{
   5.113 +    char *text;
   5.114 +
   5.115 +    text = NULL;
   5.116 +    if (IsClipboardFormatAvailable(TEXT_FORMAT) &&
   5.117 +        OpenClipboard(GetWindowHandle(_this))) {
   5.118 +        HANDLE hMem;
   5.119 +        LPTSTR tstr;
   5.120 +
   5.121 +        hMem = GetClipboardData(TEXT_FORMAT);
   5.122 +        if (hMem) {
   5.123 +            tstr = (LPTSTR)GlobalLock(hMem);
   5.124 +            text = WIN_StringToUTF8(tstr);
   5.125 +            GlobalUnlock(hMem);
   5.126 +        } else {
   5.127 +            WIN_SetError("Couldn't get clipboard data");
   5.128 +        }
   5.129 +        CloseClipboard();
   5.130 +    }
   5.131 +    if (!text) {
   5.132 +        text = SDL_strdup("");
   5.133 +    }
   5.134 +    return text;
   5.135 +}
   5.136 +
   5.137 +SDL_bool
   5.138 +WIN_HasClipboardText(_THIS)
   5.139 +{
   5.140 +    if (IsClipboardFormatAvailable(TEXT_FORMAT)) {
   5.141 +        return SDL_TRUE;
   5.142 +    } else {
   5.143 +        return SDL_FALSE;
   5.144 +    }
   5.145 +}
   5.146 +
   5.147 +/* vi: set ts=4 sw=4 expandtab: */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/video/win32/SDL_win32clipboard.h	Thu Jul 08 05:43:34 2010 -0700
     6.3 @@ -0,0 +1,33 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997-2010 Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Lesser General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2.1 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Lesser General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Lesser General Public
    6.19 +    License along with this library; if not, write to the Free Software
    6.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +#include "SDL_config.h"
    6.26 +
    6.27 +#ifndef _SDL_win32clipboard_h
    6.28 +#define _SDL_win32clipboard_h
    6.29 +
    6.30 +extern int WIN_SetClipboardText(_THIS, const char *text);
    6.31 +extern char *WIN_GetClipboardText(_THIS);
    6.32 +extern SDL_bool WIN_HasClipboardText(_THIS);
    6.33 +
    6.34 +#endif /* _SDL_win32clipboard_h */
    6.35 +
    6.36 +/* vi: set ts=4 sw=4 expandtab: */
     7.1 --- a/src/video/win32/SDL_win32events.c	Thu Jul 08 00:35:58 2010 -0700
     7.2 +++ b/src/video/win32/SDL_win32events.c	Thu Jul 08 05:43:34 2010 -0700
     7.3 @@ -585,17 +585,4 @@
     7.4      }
     7.5  }
     7.6  
     7.7 -/* Sets an error message based on GetLastError() */
     7.8 -void
     7.9 -WIN_SetError(const char *prefix)
    7.10 -{
    7.11 -    TCHAR buffer[1024];
    7.12 -    char *message;
    7.13 -    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
    7.14 -                  buffer, SDL_arraysize(buffer), NULL);
    7.15 -    message = WIN_StringToUTF8(buffer);
    7.16 -    SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
    7.17 -    SDL_free(message);
    7.18 -}
    7.19 -
    7.20  /* vi: set ts=4 sw=4 expandtab: */
     8.1 --- a/src/video/win32/SDL_win32events.h	Thu Jul 08 00:35:58 2010 -0700
     8.2 +++ b/src/video/win32/SDL_win32events.h	Thu Jul 08 05:43:34 2010 -0700
     8.3 @@ -31,7 +31,6 @@
     8.4  extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
     8.5                                         LPARAM lParam);
     8.6  extern void WIN_PumpEvents(_THIS);
     8.7 -extern void WIN_SetError(const char *prefix);
     8.8  
     8.9  #endif /* _SDL_win32events_h */
    8.10  
     9.1 --- a/src/video/win32/SDL_win32video.c	Thu Jul 08 00:35:58 2010 -0700
     9.2 +++ b/src/video/win32/SDL_win32video.c	Thu Jul 08 05:43:34 2010 -0700
     9.3 @@ -28,6 +28,7 @@
     9.4  #include "../SDL_pixels_c.h"
     9.5  
     9.6  #include "SDL_win32video.h"
     9.7 +#include "SDL_win32clipboard.h"
     9.8  #include "SDL_d3drender.h"
     9.9  #include "SDL_gdirender.h"
    9.10  
    9.11 @@ -35,6 +36,19 @@
    9.12  static int WIN_VideoInit(_THIS);
    9.13  static void WIN_VideoQuit(_THIS);
    9.14  
    9.15 +/* Sets an error message based on GetLastError() */
    9.16 +void
    9.17 +WIN_SetError(const char *prefix)
    9.18 +{
    9.19 +    TCHAR buffer[1024];
    9.20 +    char *message;
    9.21 +    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
    9.22 +                  buffer, SDL_arraysize(buffer), NULL);
    9.23 +    message = WIN_StringToUTF8(buffer);
    9.24 +    SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
    9.25 +    SDL_free(message);
    9.26 +}
    9.27 +
    9.28  /* WIN32 driver bootstrap functions */
    9.29  
    9.30  static int
    9.31 @@ -163,6 +177,10 @@
    9.32      device->GL_DeleteContext = WIN_GL_DeleteContext;
    9.33  #endif
    9.34  
    9.35 +    device->SetClipboardText = WIN_SetClipboardText;
    9.36 +    device->GetClipboardText = WIN_GetClipboardText;
    9.37 +    device->HasClipboardText = WIN_HasClipboardText;
    9.38 +
    9.39      device->free = WIN_DeleteDevice;
    9.40  
    9.41      return device;
    10.1 --- a/src/video/win32/SDL_win32video.h	Thu Jul 08 00:35:58 2010 -0700
    10.2 +++ b/src/video/win32/SDL_win32video.h	Thu Jul 08 05:43:34 2010 -0700
    10.3 @@ -60,6 +60,7 @@
    10.4  #define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1))
    10.5  #define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1)
    10.6  #endif
    10.7 +extern void WIN_SetError(const char *prefix);
    10.8  
    10.9  /* Private display data */
   10.10  
    11.1 --- a/src/video/win32/SDL_win32window.c	Thu Jul 08 00:35:58 2010 -0700
    11.2 +++ b/src/video/win32/SDL_win32window.c	Thu Jul 08 05:43:34 2010 -0700
    11.3 @@ -633,8 +633,7 @@
    11.4      /* Register the class. */
    11.5      SDL_HelperWindowClass = RegisterClass(&wce);
    11.6      if (SDL_HelperWindowClass == 0) {
    11.7 -        SDL_SetError("Unable to create Helper Window Class: error %d.",
    11.8 -                     GetLastError());
    11.9 +        WIN_SetError("Unable to create Helper Window Class");
   11.10          return -1;
   11.11      }
   11.12  
   11.13 @@ -652,8 +651,7 @@
   11.14                                        hInstance, NULL);
   11.15      if (SDL_HelperWindow == NULL) {
   11.16          UnregisterClass(SDL_HelperWindowClassName, hInstance);
   11.17 -        SDL_SetError("Unable to create Helper Window: error %d.",
   11.18 -                     GetLastError());
   11.19 +        WIN_SetError("Unable to create Helper Window");
   11.20          return -1;
   11.21      }
   11.22  
   11.23 @@ -672,8 +670,7 @@
   11.24      /* Destroy the window. */
   11.25      if (SDL_HelperWindow != NULL) {
   11.26          if (DestroyWindow(SDL_HelperWindow) == 0) {
   11.27 -            SDL_SetError("Unable to destroy Helper Window: error %d.",
   11.28 -                         GetLastError());
   11.29 +            WIN_SetError("Unable to destroy Helper Window");
   11.30              return;
   11.31          }
   11.32          SDL_HelperWindow = NULL;
   11.33 @@ -682,8 +679,7 @@
   11.34      /* Unregister the class. */
   11.35      if (SDL_HelperWindowClass != 0) {
   11.36          if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
   11.37 -            SDL_SetError("Unable to destroy Helper Window Class: error %d.",
   11.38 -                         GetLastError());
   11.39 +            WIN_SetError("Unable to destroy Helper Window Class");
   11.40              return;
   11.41          }
   11.42          SDL_HelperWindowClass = 0;