src/video/windows/SDL_windowsclipboard.c
author Andreas Schiffler <aschiffler@ferzkopp.net>
Sat, 29 Oct 2011 23:43:59 -0700
changeset 6036 f2a89f2a6157
parent 5535 96594ac5fd1a
child 6044 35448a5ea044
permissions -rw-r--r--
Update SDL_HasClipboardText functions to return value based on clipboard content; Fix memory leak in fallback SetClipboard implementation
slouken@4500
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@5535
     3
  Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
slouken@4500
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@4500
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@4500
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@4500
    20
*/
slouken@4500
    21
#include "SDL_config.h"
slouken@4500
    22
slouken@5062
    23
#include "SDL_windowsvideo.h"
slouken@5062
    24
#include "SDL_windowswindow.h"
slouken@4504
    25
#include "../../events/SDL_clipboardevents_c.h"
slouken@4500
    26
slouken@4500
    27
slouken@4500
    28
#ifdef UNICODE
slouken@4500
    29
#define TEXT_FORMAT  CF_UNICODETEXT
slouken@4500
    30
#else
slouken@4500
    31
#define TEXT_FORMAT  CF_TEXT
slouken@4500
    32
#endif
slouken@4500
    33
slouken@4500
    34
slouken@4500
    35
/* Get any application owned window handle for clipboard association */
slouken@4500
    36
static HWND
slouken@4500
    37
GetWindowHandle(_THIS)
slouken@4500
    38
{
slouken@4500
    39
    SDL_Window *window;
slouken@4500
    40
slouken@5250
    41
    window = _this->windows;
slouken@5250
    42
    if (window) {
slouken@5250
    43
        return ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@4500
    44
    }
slouken@4500
    45
    return NULL;
slouken@4500
    46
}
slouken@4500
    47
slouken@4500
    48
int
slouken@4500
    49
WIN_SetClipboardText(_THIS, const char *text)
slouken@4500
    50
{
slouken@4504
    51
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@4500
    52
    int result = 0;
slouken@4500
    53
slouken@4500
    54
    if (OpenClipboard(GetWindowHandle(_this))) {
slouken@4500
    55
        HANDLE hMem;
slouken@4500
    56
        LPTSTR tstr;
slouken@4500
    57
        SIZE_T i, size;
slouken@4500
    58
slouken@4500
    59
        /* Convert the text from UTF-8 to Windows Unicode */
slouken@4500
    60
        tstr = WIN_UTF8ToString(text);
slouken@4500
    61
        if (!tstr) {
slouken@4500
    62
            return -1;
slouken@4500
    63
        }
slouken@4500
    64
slouken@4500
    65
        /* Find out the size of the data */
slouken@4500
    66
        for (size = 0, i = 0; tstr[i]; ++i, ++size) {
slouken@4500
    67
            if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
slouken@4500
    68
                /* We're going to insert a carriage return */
slouken@4500
    69
                ++size;
slouken@4500
    70
            }
slouken@4500
    71
        }
slouken@4500
    72
        size = (size+1)*sizeof(*tstr);
slouken@4500
    73
slouken@4500
    74
        /* Save the data to the clipboard */
slouken@4500
    75
        hMem = GlobalAlloc(GMEM_MOVEABLE, size);
slouken@4500
    76
        if (hMem) {
slouken@4500
    77
            LPTSTR dst = (LPTSTR)GlobalLock(hMem);
slouken@4500
    78
            /* Copy the text over, adding carriage returns as necessary */
slouken@4500
    79
            for (i = 0; tstr[i]; ++i) {
slouken@4500
    80
                if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
slouken@4500
    81
                    *dst++ = '\r';
slouken@4500
    82
                }
slouken@4500
    83
                *dst++ = tstr[i];
slouken@4500
    84
            }
slouken@4500
    85
            *dst = 0;
slouken@4500
    86
            GlobalUnlock(hMem);
slouken@4500
    87
slouken@4500
    88
            EmptyClipboard();
slouken@4500
    89
            if (!SetClipboardData(TEXT_FORMAT, hMem)) {
slouken@4500
    90
                WIN_SetError("Couldn't set clipboard data");
slouken@4500
    91
                result = -1;
slouken@4500
    92
            }
slouken@4569
    93
#ifdef _WIN32_WCE
slouken@4569
    94
            data->clipboard_count = 0;
slouken@4569
    95
#else
slouken@4504
    96
            data->clipboard_count = GetClipboardSequenceNumber();
slouken@4569
    97
#endif
slouken@4500
    98
        }
slouken@4500
    99
        SDL_free(tstr);
slouken@4500
   100
slouken@4500
   101
        CloseClipboard();
slouken@4500
   102
    } else {
slouken@4500
   103
        WIN_SetError("Couldn't open clipboard");
slouken@4500
   104
        result = -1;
slouken@4500
   105
    }
slouken@4500
   106
    return result;
slouken@4500
   107
}
slouken@4500
   108
slouken@4500
   109
char *
slouken@4500
   110
WIN_GetClipboardText(_THIS)
slouken@4500
   111
{
slouken@4500
   112
    char *text;
slouken@4500
   113
slouken@4500
   114
    text = NULL;
slouken@4500
   115
    if (IsClipboardFormatAvailable(TEXT_FORMAT) &&
slouken@4500
   116
        OpenClipboard(GetWindowHandle(_this))) {
slouken@4500
   117
        HANDLE hMem;
slouken@4500
   118
        LPTSTR tstr;
slouken@4500
   119
slouken@4500
   120
        hMem = GetClipboardData(TEXT_FORMAT);
slouken@4500
   121
        if (hMem) {
slouken@4500
   122
            tstr = (LPTSTR)GlobalLock(hMem);
slouken@4500
   123
            text = WIN_StringToUTF8(tstr);
slouken@4500
   124
            GlobalUnlock(hMem);
slouken@4500
   125
        } else {
slouken@4500
   126
            WIN_SetError("Couldn't get clipboard data");
slouken@4500
   127
        }
slouken@4500
   128
        CloseClipboard();
slouken@4500
   129
    }
slouken@4500
   130
    if (!text) {
slouken@4500
   131
        text = SDL_strdup("");
slouken@4500
   132
    }
slouken@4500
   133
    return text;
slouken@4500
   134
}
slouken@4500
   135
slouken@4500
   136
SDL_bool
slouken@4500
   137
WIN_HasClipboardText(_THIS)
slouken@4500
   138
{
aschiffler@6036
   139
    SDL_bool result = SDL_FALSE;
aschiffler@6036
   140
    char *text = WIN_GetClipboardText(_this);
aschiffler@6036
   141
    if (text) {
aschiffler@6036
   142
        result = (SDL_strlen(text)>0) ? SDL_TRUE : SDL_FALSE;
aschiffler@6036
   143
        SDL_free(text);
aschiffler@6036
   144
    } 
aschiffler@6036
   145
    return result;
slouken@4500
   146
}
slouken@4500
   147
slouken@4504
   148
void
slouken@4504
   149
WIN_CheckClipboardUpdate(struct SDL_VideoData * data)
slouken@4504
   150
{
slouken@4504
   151
    DWORD count;
slouken@4504
   152
slouken@4569
   153
#ifdef _WIN32_WCE
slouken@4569
   154
    count = 0;
slouken@4569
   155
#else
slouken@4504
   156
    count = GetClipboardSequenceNumber();
slouken@4569
   157
#endif
slouken@4504
   158
    if (count != data->clipboard_count) {
slouken@4504
   159
        if (data->clipboard_count) {
slouken@4504
   160
            SDL_SendClipboardUpdate();
slouken@4504
   161
        }
slouken@4504
   162
        data->clipboard_count = count;
slouken@4504
   163
    }
slouken@4504
   164
}
slouken@4504
   165
slouken@4500
   166
/* vi: set ts=4 sw=4 expandtab: */