ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/clip_macosx.cpp
Revision: 1.8
Committed: 2009-10-18T01:22:33Z (14 years, 11 months ago) by asvitkine
Branch: MAIN
Changes since 1.7: +9 -3 lines
Log Message:
trying to get slightly better clip behaviour - swap the data back after
giving it to the host OS, and don't clear clipboard every time as some
apps will put many varieties of the same data in succession...
however, a better fix would be to patch the ROM ZeroScrap function in a
similar way as we patch GetScrap/PutScrap

File Contents

# Content
1 /*
2 * clip_macosx.cpp - Clipboard handling, MacOS X (Carbon) implementation
3 *
4 * Basilisk II (C) 1997-2008 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22 #include <Carbon/Carbon.h>
23
24 #include "clip.h"
25 #include "main.h"
26 #include "cpu_emulation.h"
27 #include "emul_op.h"
28
29 #define DEBUG 0
30 #include "debug.h"
31
32
33 // Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the MacOS X side
34 static bool we_put_this_data = false;
35
36
37 static void SwapScrapData(uint32 type, void *data, int32 length, int from_host) {
38 #if BYTE_ORDER != BIG_ENDIAN
39 if (type == kScrapFlavorTypeTextStyle) {
40 uint16 *sdata = (uint16 *) data;
41 // the first short stores the number of runs
42 uint16 runs = sdata[0];
43 sdata[0] = htons(sdata[0]);
44 if (from_host)
45 runs = sdata[0];
46 sdata++;
47 // loop through each run
48 for (int i = 0; i < runs; i++) {
49 struct style_data {
50 uint32 offset;
51 uint16 line_height;
52 uint16 line_ascent;
53 uint16 font_family;
54 uint16 character_style; // not swapped
55 uint16 point_size;
56 uint16 red;
57 uint16 green;
58 uint16 blue;
59 } *style = (struct style_data *) (sdata + i*10);
60 style->offset = htonl(style->offset);
61 style->line_height = htons(style->line_height);
62 style->line_ascent = htons(style->line_ascent);
63 style->font_family = htons(style->font_family);
64 style->point_size = htons(style->point_size);
65 style->red = htons(style->red);
66 style->green = htons(style->green);
67 style->blue = htons(style->blue);
68 }
69 } else {
70 // add byteswapping code for other flavor types here ...
71 }
72 #endif
73 }
74
75
76 /*
77 * Initialization
78 */
79
80 void ClipInit(void)
81 {
82 }
83
84
85 /*
86 * Deinitialization
87 */
88
89 void ClipExit(void)
90 {
91 }
92
93
94 /*
95 * Mac application reads clipboard
96 */
97
98 void GetScrap(void **handle, uint32 type, int32 offset)
99 {
100 D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset));
101 ScrapRef theScrap;
102
103 if (GetCurrentScrap(&theScrap) != noErr) {
104 D(bug(" could not open scrap\n"));
105 return;
106 }
107
108 Size byteCount;
109 if (GetScrapFlavorSize(theScrap, type, &byteCount) == noErr) {
110
111 // Allocate space for new scrap in MacOS side
112 M68kRegisters r;
113 r.d[0] = byteCount;
114 Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
115 uint32 scrap_area = r.a[0];
116
117 // Get the native clipboard data
118 if (scrap_area) {
119 uint8 * const data = Mac2HostAddr(scrap_area);
120 if (GetScrapFlavorData(theScrap, type, &byteCount, data) == noErr) {
121 SwapScrapData(type, data, byteCount, FALSE);
122 // Add new data to clipboard
123 static uint8 proc[] = {
124 0x59, 0x8f, // subq.l #4,sp
125 0xa9, 0xfc, // ZeroScrap()
126 0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp)
127 0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp)
128 0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp)
129 0xa9, 0xfe, // PutScrap()
130 0x58, 0x8f, // addq.l #4,sp
131 M68K_RTS >> 8, M68K_RTS
132 };
133 r.d[0] = sizeof(proc);
134 Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
135 uint32 proc_area = r.a[0];
136
137 if (proc_area) {
138 Host2Mac_memcpy(proc_area, proc, sizeof(proc));
139 WriteMacInt32(proc_area + 6, byteCount);
140 WriteMacInt32(proc_area + 12, type);
141 WriteMacInt32(proc_area + 18, scrap_area);
142 we_put_this_data = true;
143 Execute68k(proc_area, &r);
144
145 r.a[0] = proc_area;
146 Execute68kTrap(0xa01f, &r); // DisposePtr
147 }
148 }
149
150 r.a[0] = scrap_area;
151 Execute68kTrap(0xa01f, &r); // DisposePtr
152 }
153 }
154 }
155
156
157 /*
158 * Mac application wrote to clipboard
159 */
160
161 void PutScrap(uint32 type, void *scrap, int32 length)
162 {
163 static bool clear = true;
164 D(bug("PutScrap type %4.4s, data %08lx, length %ld\n", &type, scrap, length));
165 ScrapRef theScrap;
166
167 if (we_put_this_data) {
168 we_put_this_data = false;
169 clear = true;
170 return;
171 }
172 if (length <= 0)
173 return;
174
175 if (clear) {
176 D(bug(" calling ClearCurrentScrap\n"));
177 ClearCurrentScrap();
178 }
179 if (GetCurrentScrap(&theScrap) != noErr) {
180 D(bug(" could not open scrap\n"));
181 return;
182 }
183
184 SwapScrapData(type, scrap, length, TRUE);
185 if (PutScrapFlavor(theScrap, type, kScrapFlavorMaskNone, length, scrap) != noErr) {
186 D(bug(" could not put to scrap\n"));
187 //return;
188 }
189 SwapScrapData(type, scrap, length, FALSE); // swap it back
190 }