src/video/win32/SDL_win32clipboard.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 08 Jul 2010 23:07:34 -0700
changeset 4504 9faebccfefb3
parent 4500 eff4e88cc1e8
child 4569 e1664f94f026
permissions -rw-r--r--
Amazingly the Windows code is almost identical to the Mac OS X code. :)
slouken@4500
     1
/*
slouken@4500
     2
    SDL - Simple DirectMedia Layer
slouken@4500
     3
    Copyright (C) 1997-2010 Sam Lantinga
slouken@4500
     4
slouken@4500
     5
    This library is free software; you can redistribute it and/or
slouken@4500
     6
    modify it under the terms of the GNU Lesser General Public
slouken@4500
     7
    License as published by the Free Software Foundation; either
slouken@4500
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@4500
     9
slouken@4500
    10
    This library is distributed in the hope that it will be useful,
slouken@4500
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@4500
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@4500
    13
    Lesser General Public License for more details.
slouken@4500
    14
slouken@4500
    15
    You should have received a copy of the GNU Lesser General Public
slouken@4500
    16
    License along with this library; if not, write to the Free Software
slouken@4500
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@4500
    18
slouken@4500
    19
    Sam Lantinga
slouken@4500
    20
    slouken@libsdl.org
slouken@4500
    21
*/
slouken@4500
    22
#include "SDL_config.h"
slouken@4500
    23
slouken@4500
    24
#include "SDL_win32video.h"
slouken@4500
    25
#include "SDL_win32window.h"
slouken@4504
    26
#include "../../events/SDL_clipboardevents_c.h"
slouken@4500
    27
slouken@4500
    28
slouken@4500
    29
#ifdef UNICODE
slouken@4500
    30
#define TEXT_FORMAT  CF_UNICODETEXT
slouken@4500
    31
#else
slouken@4500
    32
#define TEXT_FORMAT  CF_TEXT
slouken@4500
    33
#endif
slouken@4500
    34
slouken@4500
    35
slouken@4500
    36
/* Get any application owned window handle for clipboard association */
slouken@4500
    37
static HWND
slouken@4500
    38
GetWindowHandle(_THIS)
slouken@4500
    39
{
slouken@4500
    40
    SDL_VideoDisplay *display;
slouken@4500
    41
    SDL_Window *window;
slouken@4500
    42
slouken@4500
    43
    display = _this->displays;
slouken@4500
    44
    if (display) {
slouken@4500
    45
        window = display->windows;
slouken@4500
    46
        if (window) {
slouken@4500
    47
            return ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@4500
    48
        }
slouken@4500
    49
    }
slouken@4500
    50
    return NULL;
slouken@4500
    51
}
slouken@4500
    52
slouken@4500
    53
int
slouken@4500
    54
WIN_SetClipboardText(_THIS, const char *text)
slouken@4500
    55
{
slouken@4504
    56
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@4500
    57
    int result = 0;
slouken@4500
    58
slouken@4500
    59
    if (OpenClipboard(GetWindowHandle(_this))) {
slouken@4500
    60
        HANDLE hMem;
slouken@4500
    61
        LPTSTR tstr;
slouken@4500
    62
        SIZE_T i, size;
slouken@4500
    63
slouken@4500
    64
        /* Convert the text from UTF-8 to Windows Unicode */
slouken@4500
    65
        tstr = WIN_UTF8ToString(text);
slouken@4500
    66
        if (!tstr) {
slouken@4500
    67
            return -1;
slouken@4500
    68
        }
slouken@4500
    69
slouken@4500
    70
        /* Find out the size of the data */
slouken@4500
    71
        for (size = 0, i = 0; tstr[i]; ++i, ++size) {
slouken@4500
    72
            if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
slouken@4500
    73
                /* We're going to insert a carriage return */
slouken@4500
    74
                ++size;
slouken@4500
    75
            }
slouken@4500
    76
        }
slouken@4500
    77
        size = (size+1)*sizeof(*tstr);
slouken@4500
    78
slouken@4500
    79
        /* Save the data to the clipboard */
slouken@4500
    80
        hMem = GlobalAlloc(GMEM_MOVEABLE, size);
slouken@4500
    81
        if (hMem) {
slouken@4500
    82
            LPTSTR dst = (LPTSTR)GlobalLock(hMem);
slouken@4500
    83
            /* Copy the text over, adding carriage returns as necessary */
slouken@4500
    84
            for (i = 0; tstr[i]; ++i) {
slouken@4500
    85
                if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
slouken@4500
    86
                    *dst++ = '\r';
slouken@4500
    87
                }
slouken@4500
    88
                *dst++ = tstr[i];
slouken@4500
    89
            }
slouken@4500
    90
            *dst = 0;
slouken@4500
    91
            GlobalUnlock(hMem);
slouken@4500
    92
slouken@4500
    93
            EmptyClipboard();
slouken@4500
    94
            if (!SetClipboardData(TEXT_FORMAT, hMem)) {
slouken@4500
    95
                WIN_SetError("Couldn't set clipboard data");
slouken@4500
    96
                result = -1;
slouken@4500
    97
            }
slouken@4504
    98
            data->clipboard_count = GetClipboardSequenceNumber();
slouken@4500
    99
        }
slouken@4500
   100
        SDL_free(tstr);
slouken@4500
   101
slouken@4500
   102
        CloseClipboard();
slouken@4500
   103
    } else {
slouken@4500
   104
        WIN_SetError("Couldn't open clipboard");
slouken@4500
   105
        result = -1;
slouken@4500
   106
    }
slouken@4500
   107
    return result;
slouken@4500
   108
}
slouken@4500
   109
slouken@4500
   110
char *
slouken@4500
   111
WIN_GetClipboardText(_THIS)
slouken@4500
   112
{
slouken@4500
   113
    char *text;
slouken@4500
   114
slouken@4500
   115
    text = NULL;
slouken@4500
   116
    if (IsClipboardFormatAvailable(TEXT_FORMAT) &&
slouken@4500
   117
        OpenClipboard(GetWindowHandle(_this))) {
slouken@4500
   118
        HANDLE hMem;
slouken@4500
   119
        LPTSTR tstr;
slouken@4500
   120
slouken@4500
   121
        hMem = GetClipboardData(TEXT_FORMAT);
slouken@4500
   122
        if (hMem) {
slouken@4500
   123
            tstr = (LPTSTR)GlobalLock(hMem);
slouken@4500
   124
            text = WIN_StringToUTF8(tstr);
slouken@4500
   125
            GlobalUnlock(hMem);
slouken@4500
   126
        } else {
slouken@4500
   127
            WIN_SetError("Couldn't get clipboard data");
slouken@4500
   128
        }
slouken@4500
   129
        CloseClipboard();
slouken@4500
   130
    }
slouken@4500
   131
    if (!text) {
slouken@4500
   132
        text = SDL_strdup("");
slouken@4500
   133
    }
slouken@4500
   134
    return text;
slouken@4500
   135
}
slouken@4500
   136
slouken@4500
   137
SDL_bool
slouken@4500
   138
WIN_HasClipboardText(_THIS)
slouken@4500
   139
{
slouken@4500
   140
    if (IsClipboardFormatAvailable(TEXT_FORMAT)) {
slouken@4500
   141
        return SDL_TRUE;
slouken@4500
   142
    } else {
slouken@4500
   143
        return SDL_FALSE;
slouken@4500
   144
    }
slouken@4500
   145
}
slouken@4500
   146
slouken@4504
   147
void
slouken@4504
   148
WIN_CheckClipboardUpdate(struct SDL_VideoData * data)
slouken@4504
   149
{
slouken@4504
   150
    DWORD count;
slouken@4504
   151
slouken@4504
   152
    count = GetClipboardSequenceNumber();
slouken@4504
   153
    if (count != data->clipboard_count) {
slouken@4504
   154
        if (data->clipboard_count) {
slouken@4504
   155
            SDL_SendClipboardUpdate();
slouken@4504
   156
        }
slouken@4504
   157
        data->clipboard_count = count;
slouken@4504
   158
    }
slouken@4504
   159
}
slouken@4504
   160
slouken@4500
   161
/* vi: set ts=4 sw=4 expandtab: */