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, 8 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

# User Rev Content
1 gbeauche 1.1 /*
2     * clip_macosx.cpp - Clipboard handling, MacOS X (Carbon) implementation
3     *
4 gbeauche 1.7 * Basilisk II (C) 1997-2008 Christian Bauer
5 gbeauche 1.1 *
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 gbeauche 1.2 // Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the MacOS X side
34 gbeauche 1.1 static bool we_put_this_data = false;
35    
36    
37 asvitkine 1.6 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 gbeauche 1.1 /*
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 gbeauche 1.3 D(bug(" could not open scrap\n"));
105     return;
106 gbeauche 1.1 }
107    
108     Size byteCount;
109     if (GetScrapFlavorSize(theScrap, type, &byteCount) == noErr) {
110    
111 gbeauche 1.5 // 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 asvitkine 1.6 SwapScrapData(type, data, byteCount, FALSE);
122 gbeauche 1.5 // 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 gbeauche 1.1 }
154     }
155    
156    
157     /*
158     * Mac application wrote to clipboard
159     */
160    
161     void PutScrap(uint32 type, void *scrap, int32 length)
162     {
163 asvitkine 1.8 static bool clear = true;
164     D(bug("PutScrap type %4.4s, data %08lx, length %ld\n", &type, scrap, length));
165 gbeauche 1.1 ScrapRef theScrap;
166    
167     if (we_put_this_data) {
168 gbeauche 1.3 we_put_this_data = false;
169 asvitkine 1.8 clear = true;
170 gbeauche 1.3 return;
171 gbeauche 1.1 }
172     if (length <= 0)
173     return;
174    
175 asvitkine 1.8 if (clear) {
176     D(bug(" calling ClearCurrentScrap\n"));
177     ClearCurrentScrap();
178     }
179 gbeauche 1.1 if (GetCurrentScrap(&theScrap) != noErr) {
180     D(bug(" could not open scrap\n"));
181     return;
182     }
183    
184 asvitkine 1.6 SwapScrapData(type, scrap, length, TRUE);
185 gbeauche 1.1 if (PutScrapFlavor(theScrap, type, kScrapFlavorMaskNone, length, scrap) != noErr) {
186     D(bug(" could not put to scrap\n"));
187 asvitkine 1.8 //return;
188 gbeauche 1.1 }
189 asvitkine 1.8 SwapScrapData(type, scrap, length, FALSE); // swap it back
190 gbeauche 1.1 }