src/video/windows/SDL_windowsclipboard.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 04 Jan 2019 22:01:14 -0800
changeset 12503 806492103856
parent 11811 5d94cb6b24d3
permissions -rw-r--r--
Updated copyright for 2019
slouken@4500
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@12503
     3
  Copyright (C) 1997-2019 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
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@4500
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@6044
    24
slouken@5062
    25
#include "SDL_windowsvideo.h"
slouken@5062
    26
#include "SDL_windowswindow.h"
slouken@4504
    27
#include "../../events/SDL_clipboardevents_c.h"
slouken@4500
    28
slouken@4500
    29
slouken@4500
    30
#ifdef UNICODE
slouken@4500
    31
#define TEXT_FORMAT  CF_UNICODETEXT
slouken@4500
    32
#else
slouken@4500
    33
#define TEXT_FORMAT  CF_TEXT
slouken@4500
    34
#endif
slouken@4500
    35
slouken@4500
    36
slouken@4500
    37
/* Get any application owned window handle for clipboard association */
slouken@4500
    38
static HWND
slouken@4500
    39
GetWindowHandle(_THIS)
slouken@4500
    40
{
slouken@4500
    41
    SDL_Window *window;
slouken@4500
    42
slouken@5250
    43
    window = _this->windows;
slouken@5250
    44
    if (window) {
slouken@5250
    45
        return ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@4500
    46
    }
slouken@4500
    47
    return NULL;
slouken@4500
    48
}
slouken@4500
    49
slouken@4500
    50
int
slouken@4500
    51
WIN_SetClipboardText(_THIS, const char *text)
slouken@4500
    52
{
slouken@4504
    53
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@4500
    54
    int result = 0;
slouken@4500
    55
slouken@4500
    56
    if (OpenClipboard(GetWindowHandle(_this))) {
slouken@4500
    57
        HANDLE hMem;
slouken@4500
    58
        LPTSTR tstr;
slouken@4500
    59
        SIZE_T i, size;
slouken@4500
    60
slouken@4500
    61
        /* Convert the text from UTF-8 to Windows Unicode */
slouken@4500
    62
        tstr = WIN_UTF8ToString(text);
slouken@4500
    63
        if (!tstr) {
slouken@4500
    64
            return -1;
slouken@4500
    65
        }
slouken@4500
    66
slouken@4500
    67
        /* Find out the size of the data */
slouken@4500
    68
        for (size = 0, i = 0; tstr[i]; ++i, ++size) {
slouken@4500
    69
            if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
slouken@4500
    70
                /* We're going to insert a carriage return */
slouken@4500
    71
                ++size;
slouken@4500
    72
            }
slouken@4500
    73
        }
slouken@4500
    74
        size = (size+1)*sizeof(*tstr);
slouken@4500
    75
slouken@4500
    76
        /* Save the data to the clipboard */
slouken@4500
    77
        hMem = GlobalAlloc(GMEM_MOVEABLE, size);
slouken@4500
    78
        if (hMem) {
slouken@4500
    79
            LPTSTR dst = (LPTSTR)GlobalLock(hMem);
slouken@7332
    80
            if (dst) {
slouken@7332
    81
                /* Copy the text over, adding carriage returns as necessary */
slouken@7332
    82
                for (i = 0; tstr[i]; ++i) {
slouken@7332
    83
                    if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
slouken@7332
    84
                        *dst++ = '\r';
slouken@7332
    85
                    }
slouken@7332
    86
                    *dst++ = tstr[i];
slouken@4500
    87
                }
slouken@7332
    88
                *dst = 0;
slouken@7332
    89
                GlobalUnlock(hMem);
slouken@4500
    90
            }
slouken@4500
    91
slouken@4500
    92
            EmptyClipboard();
slouken@4500
    93
            if (!SetClipboardData(TEXT_FORMAT, hMem)) {
icculus@7037
    94
                result = WIN_SetError("Couldn't set clipboard data");
slouken@4500
    95
            }
slouken@4504
    96
            data->clipboard_count = GetClipboardSequenceNumber();
slouken@4500
    97
        }
slouken@4500
    98
        SDL_free(tstr);
slouken@4500
    99
slouken@4500
   100
        CloseClipboard();
slouken@4500
   101
    } else {
icculus@7037
   102
        result = WIN_SetError("Couldn't open clipboard");
slouken@4500
   103
    }
slouken@4500
   104
    return result;
slouken@4500
   105
}
slouken@4500
   106
slouken@4500
   107
char *
slouken@4500
   108
WIN_GetClipboardText(_THIS)
slouken@4500
   109
{
slouken@4500
   110
    char *text;
slouken@4500
   111
slouken@4500
   112
    text = NULL;
slouken@4500
   113
    if (IsClipboardFormatAvailable(TEXT_FORMAT) &&
slouken@4500
   114
        OpenClipboard(GetWindowHandle(_this))) {
slouken@4500
   115
        HANDLE hMem;
slouken@4500
   116
        LPTSTR tstr;
slouken@4500
   117
slouken@4500
   118
        hMem = GetClipboardData(TEXT_FORMAT);
slouken@4500
   119
        if (hMem) {
slouken@4500
   120
            tstr = (LPTSTR)GlobalLock(hMem);
slouken@4500
   121
            text = WIN_StringToUTF8(tstr);
slouken@4500
   122
            GlobalUnlock(hMem);
slouken@4500
   123
        } else {
slouken@4500
   124
            WIN_SetError("Couldn't get clipboard data");
slouken@4500
   125
        }
slouken@4500
   126
        CloseClipboard();
slouken@4500
   127
    }
slouken@4500
   128
    if (!text) {
slouken@4500
   129
        text = SDL_strdup("");
slouken@4500
   130
    }
slouken@4500
   131
    return text;
slouken@4500
   132
}
slouken@4500
   133
slouken@4500
   134
SDL_bool
slouken@4500
   135
WIN_HasClipboardText(_THIS)
slouken@4500
   136
{
aschiffler@6036
   137
    SDL_bool result = SDL_FALSE;
aschiffler@6036
   138
    char *text = WIN_GetClipboardText(_this);
aschiffler@6036
   139
    if (text) {
slouken@7721
   140
        result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
aschiffler@6036
   141
        SDL_free(text);
slouken@7191
   142
    }
aschiffler@6036
   143
    return result;
slouken@4500
   144
}
slouken@4500
   145
slouken@4504
   146
void
slouken@4504
   147
WIN_CheckClipboardUpdate(struct SDL_VideoData * data)
slouken@4504
   148
{
icculus@6430
   149
    const DWORD count = GetClipboardSequenceNumber();
slouken@4504
   150
    if (count != data->clipboard_count) {
slouken@4504
   151
        if (data->clipboard_count) {
slouken@4504
   152
            SDL_SendClipboardUpdate();
slouken@4504
   153
        }
slouken@4504
   154
        data->clipboard_count = count;
slouken@4504
   155
    }
slouken@4504
   156
}
slouken@4504
   157
slouken@6044
   158
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   159
slouken@4500
   160
/* vi: set ts=4 sw=4 expandtab: */