85e91f9ae39cb89b4777497cc2c413267398bc03
[xboard.git] / winboard-dm-beta4 / wclipbrd.c
1 /*
2  * wclipbrd.c -- Clipboard routines for WinBoard
3  * $Id$
4  *
5  * Copyright 2000 Free Software Foundation, Inc.
6  *
7  * ------------------------------------------------------------------------
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  * ------------------------------------------------------------------------
22  */
23
24 #include "config.h"
25
26 #include <windows.h>   /* required for all Windows applications */
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <malloc.h>
30 #include <io.h>
31 #include <sys/stat.h>
32
33 #include "common.h"
34 #include "winboard.h"
35 #include "frontend.h"
36 #include "backend.h"
37 #include "wclipbrd.h"
38
39 /* Imports from winboard.c */
40 extern HWND hwndMain;
41
42 /* File globals */
43 static char *copyTemp;
44 static char *pasteTemp;
45
46 VOID 
47 CopyFENToClipboard()
48 {
49   char *fen = NULL;
50
51   fen = PositionToFEN(currentMove);
52   if (!fen) {
53     DisplayError("Unable to convert position to FEN.", 0);
54     return;
55   }
56   if (!CopyTextToClipboard(fen))
57       DisplayError("Unable to copy FEN to clipboard.", 0);
58   free(fen);
59 }
60
61
62 VOID
63 CopyGameToClipboard()
64 {
65   /* A rather cheesy hack here. Write the game to a file, then read from the
66    * file into the clipboard.
67    */
68   char *buf = NULL;
69   FILE *f;
70   unsigned long size;
71   size_t len;
72   struct stat st;
73
74   if (!copyTemp) {
75     copyTemp = tmpnam(NULL);
76   }
77   if (!copyTemp) {
78       DisplayError("Cannot create temporary file name.",0);
79       return;
80   }
81   f = fopen(copyTemp, "w"); 
82   if (!f) {
83     DisplayError("Cannot open temporary file.", 0);
84     return;
85   }
86   if (!SaveGame(f,0,"")) {                      /* call into backend */
87     DisplayError("Cannot write to temporary file.", 0);
88     goto copy_game_to_clipboard_cleanup;
89   }
90   f = fopen(copyTemp, "rb");
91   if (!f) {
92     DisplayError("Cannot reopen temporary file.", 0);
93     goto copy_game_to_clipboard_cleanup;
94   }
95   if (fstat(fileno(f), &st) < 0) {
96     DisplayError("Cannot determine size of file.", 0);
97     goto copy_game_to_clipboard_cleanup;
98   }
99   size = st.st_size;
100   if (size == -1) {
101     DisplayError("Cannot determine size of file.", 0);
102     goto copy_game_to_clipboard_cleanup;
103   }
104   rewind(f);
105   buf = (char*)malloc(size+1);
106   if (!buf) {
107     DisplayError("Cannot allocate clipboard buffer.", 0);
108     goto copy_game_to_clipboard_cleanup;
109   }
110   len = fread(buf, sizeof(char), size, f);
111   if (len == -1) {
112     DisplayError("Cannot read from temporary file.", 0);
113     goto copy_game_to_clipboard_cleanup;
114   }
115   if ((unsigned long)size != (unsigned long)len) { /* sigh */ 
116       DisplayError("Error reading from temporary file.", 0);
117       goto copy_game_to_clipboard_cleanup;
118   }
119   buf[size] = 0;
120   if (!CopyTextToClipboard(buf)) {
121       DisplayError("Cannot copy text to clipboard", 0);
122   }
123
124 copy_game_to_clipboard_cleanup:
125   if (buf) free(buf);
126   if (f) fclose(f);
127 }
128
129
130 int 
131 CopyTextToClipboard(char *text)
132 {
133   /* some (most?) of the error checking may be overkill, 
134    * but hey, this is Windows 
135    */
136   HGLOBAL hGlobalMem;
137   LPVOID lpGlobalMem;
138   BOOL locked;
139   UINT lockCount;
140   DWORD err;
141
142   hGlobalMem = GlobalAlloc(GHND, (DWORD)lstrlen(text)+1);
143   if (hGlobalMem == NULL) {
144     DisplayError("Unable to allocate memory for clipboard.", 0);
145     return FALSE;
146   }
147   lpGlobalMem = GlobalLock(hGlobalMem);
148   if (lpGlobalMem == NULL) {
149     DisplayError("Unable to lock clipboard memory.", 0);
150     GlobalFree(hGlobalMem);
151     return FALSE;
152   }
153   lstrcpy(lpGlobalMem, text);
154   if (appData.debugMode) {
155     lockCount = GlobalFlags(hGlobalMem) & GMEM_LOCKCOUNT;
156     fprintf(debugFP, "CopyTextToClipboard(): lock count %d\n", lockCount);
157   }
158   SetLastError(NO_ERROR);
159   locked = GlobalUnlock(hGlobalMem);
160   err = GetLastError();
161   if (appData.debugMode) {
162     lockCount = GlobalFlags(hGlobalMem) & GMEM_LOCKCOUNT;
163     fprintf(debugFP, "CopyTextToClipboard(): lock count %d\n", lockCount);
164   }
165   if (!locked) {
166     locked = !((err == NO_ERROR) || (err == ERROR_NOT_LOCKED));
167     if (appData.debugMode) {
168       fprintf(debugFP, 
169               "CopyTextToClipboard(): err %d locked %d\n", err, locked);
170     }
171   }
172   if (locked) {
173     DisplayError("Cannot unlock clipboard memory.", 0);
174     GlobalFree(hGlobalMem);
175     return FALSE;
176   }
177   if (!OpenClipboard(hwndMain)) {
178     DisplayError("Cannot open clipboard.", 0);
179     GlobalFree(hGlobalMem);
180     return FALSE;
181   }
182   if (!EmptyClipboard()) {
183     DisplayError("Cannot empty clipboard.", 0);
184     return FALSE;
185   }
186   if (hGlobalMem != SetClipboardData(CF_TEXT, hGlobalMem)) {
187     DisplayError("Cannot copy text to clipboard.", 0);
188     CloseClipboard();
189     GlobalFree(hGlobalMem);
190     return FALSE;
191   }
192   if (!CloseClipboard())
193     DisplayError("Cannot close clipboard.", 0);
194   
195   return TRUE;
196 }
197
198
199
200 VOID
201 PasteFENFromClipboard()
202 {
203   char *fen = NULL;
204   if (!PasteTextFromClipboard(&fen)) {
205       DisplayError("Unable to paste FEN from clipboard.", 0);
206       return;
207   }
208   if (appData.debugMode) {
209     fprintf(debugFP, "PasteFenFromClipboard(): fen '%s'\n", fen);
210   }
211   EditPositionPasteFEN(fen); /* call into backend */
212   free(fen);
213 }
214
215
216 VOID
217 PasteGameFromClipboard()
218 {
219   /* Write the clipboard to a temp file, then let LoadGameFromFile()
220    * do all the work.  */
221   char *buf;
222   FILE *f;
223   size_t len;
224   if (!PasteTextFromClipboard(&buf)) {
225     return;
226   }
227   if (!pasteTemp) {
228     pasteTemp = tmpnam(NULL);
229   }
230   f = fopen(pasteTemp, "wb+");
231   if (!f) {
232     DisplayError("Unable to create temporary file.", 0);
233     return;
234   }
235   len = fwrite(buf, sizeof(char), strlen(buf), f);
236   fclose(f);
237   if (len != strlen(buf)) {
238     DisplayError("Error writing to temporary file.", 0);
239     return;
240   }
241   LoadGameFromFile(pasteTemp, 0, "Clipboard", TRUE);
242 }
243
244
245 int 
246 PasteTextFromClipboard(char **text)
247 {
248   /* some (most?) of the error checking may be overkill, 
249    * but hey, this is Windows 
250    */
251   HANDLE hClipMem;
252   LPVOID lpClipMem;
253   BOOL locked = FALSE;
254   DWORD err;
255   UINT lockCount;
256
257   if (!OpenClipboard(hwndMain)) {
258     DisplayError("Unable to open clipboard.", 0);
259     return FALSE;
260   }
261   hClipMem = GetClipboardData(CF_TEXT);
262   if (hClipMem == NULL) {
263     CloseClipboard();
264     DisplayError("No text in clipboard.", 0);
265     return FALSE;
266   }
267   lpClipMem = GlobalLock(hClipMem);
268   if (lpClipMem == NULL) {
269     CloseClipboard();
270     DisplayError("Unable to lock clipboard memory.", 0);
271     return FALSE;
272   }
273   *text = (char *) malloc(GlobalSize(hClipMem)+1);
274   if (!*text) {
275     DisplayError("Unable to allocate memory for text string.", 0);
276     CloseClipboard();
277     return FALSE;
278   }
279   lstrcpy(*text, lpClipMem);
280   if (appData.debugMode) {
281     lockCount = GlobalFlags(hClipMem) & GMEM_LOCKCOUNT;
282     fprintf(debugFP, "PasteTextFromClipboard(): lock count %d\n", lockCount);
283   }
284   SetLastError(NO_ERROR);
285 #if 1
286   /*suggested by Wilkin Ng*/
287   lockCount = GlobalFlags(hClipMem) & GMEM_LOCKCOUNT;
288   if (lockCount) {
289     locked = GlobalUnlock(hClipMem);
290   }
291 #else
292   locked = GlobalUnlock(hClipMem);
293 #endif
294   err = GetLastError();
295   if (appData.debugMode) {
296     lockCount = GlobalFlags(hClipMem) & GMEM_LOCKCOUNT;
297     fprintf(debugFP, "PasteTextFromClipboard(): lock count %d\n", lockCount);
298   }
299   if (!locked) {
300     locked = !((err == NO_ERROR) || (err == ERROR_NOT_LOCKED));
301     if (appData.debugMode) {
302       fprintf(debugFP, 
303               "PasteTextFromClipboard(): err %d locked %d\n", err, locked);
304     }
305   }
306   if (locked) 
307     DisplayError("Unable to unlock clipboard memory.", 0);
308   
309   if (!CloseClipboard())
310     DisplayError("Unable to close clipboard.", 0);
311   
312   return TRUE;
313 }
314
315 VOID
316 DeleteClipboardTempFiles()
317 {
318   if (copyTemp) remove(copyTemp);
319   if (pasteTemp) remove(pasteTemp);
320 }