1 | /* ***** BEGIN LICENSE BLOCK ***** |
---|
2 | * Version: CDDL 1.0/LGPL 2.1 |
---|
3 | * |
---|
4 | * The contents of this file are subject to the COMMON DEVELOPMENT AND |
---|
5 | * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use |
---|
6 | * this file except in compliance with the License. You may obtain a copy of |
---|
7 | * the License at http://www.sun.com/cddl/ |
---|
8 | * |
---|
9 | * Software distributed under the License is distributed on an "AS IS" basis, |
---|
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
---|
11 | * for the specific language governing rights and limitations under the |
---|
12 | * License. |
---|
13 | * |
---|
14 | * The Initial Developer of the Original Code is |
---|
15 | * Eugene Romanenko, netlabs.org. |
---|
16 | * Portions created by the Initial Developer are Copyright (C) 2006 |
---|
17 | * the Initial Developer. All Rights Reserved. |
---|
18 | * |
---|
19 | * Contributor(s): |
---|
20 | * |
---|
21 | * Alternatively, the contents of this file may be used under the terms of |
---|
22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
---|
23 | * in which case the provisions of the LGPL are applicable instead of those |
---|
24 | * above. If you wish to allow use of your version of this file only under the |
---|
25 | * terms of the LGPL, and not to allow others to use your version of this file |
---|
26 | * under the terms of the CDDL, indicate your decision by deleting the |
---|
27 | * provisions above and replace them with the notice and other provisions |
---|
28 | * required by the LGPL. If you do not delete the provisions above, a recipient |
---|
29 | * may use your version of this file under the terms of any one of the CDDL |
---|
30 | * or the LGPL. |
---|
31 | * |
---|
32 | * ***** END LICENSE BLOCK ***** */ |
---|
33 | |
---|
34 | |
---|
35 | #define INCL_WIN |
---|
36 | #define INCL_DOS |
---|
37 | #include <os2.h> |
---|
38 | |
---|
39 | #include <uconv.h> |
---|
40 | #include <unidef.h> |
---|
41 | |
---|
42 | #include <string.h> |
---|
43 | #include <malloc.h> |
---|
44 | #include <stdio.h> |
---|
45 | #include <stdlib.h> |
---|
46 | #include "cpconv.h" |
---|
47 | |
---|
48 | #include "UClip.h" |
---|
49 | |
---|
50 | |
---|
51 | static BOOL APIENTRY (*pUWinOpenClipbrd)(HAB) = NULL; |
---|
52 | static BOOL APIENTRY (*pUWinEmptyClipbrd)(HAB) = NULL; |
---|
53 | static BOOL APIENTRY (*pUWinSetClipbrdData)(HAB,ULONG,ULONG,ULONG) = NULL; |
---|
54 | static BOOL APIENTRY (*pUWinCloseClipbrd)(HAB) = NULL; |
---|
55 | |
---|
56 | static bool loadUClip(); |
---|
57 | |
---|
58 | static HMODULE ucHandle = NULLHANDLE; |
---|
59 | static bool uclipLoaded = loadUClip(); |
---|
60 | |
---|
61 | |
---|
62 | static void freeUClip() |
---|
63 | { |
---|
64 | if ( ucHandle != NULLHANDLE ) { |
---|
65 | DosFreeModule( ucHandle ); |
---|
66 | } |
---|
67 | } |
---|
68 | |
---|
69 | static bool loadUClip() |
---|
70 | { |
---|
71 | bool res = false; |
---|
72 | do |
---|
73 | { |
---|
74 | if ( DosLoadModule( NULL, 0, "UCLIP", &ucHandle ) != 0 ) |
---|
75 | break; |
---|
76 | if (DosQueryProcAddr(ucHandle,0,"UWinOpenClipbrd",(PFN *)&pUWinOpenClipbrd)!= 0) |
---|
77 | break; |
---|
78 | if (DosQueryProcAddr(ucHandle,0,"UWinEmptyClipbrd",(PFN *)&pUWinEmptyClipbrd)!= 0) |
---|
79 | break; |
---|
80 | if (DosQueryProcAddr(ucHandle,0,"UWinSetClipbrdData",(PFN *)&pUWinSetClipbrdData)!= 0) |
---|
81 | break; |
---|
82 | if (DosQueryProcAddr(ucHandle,0,"UWinCloseClipbrd",(PFN *)&pUWinCloseClipbrd)!= 0) |
---|
83 | break; |
---|
84 | |
---|
85 | res = true; |
---|
86 | } while (0); |
---|
87 | |
---|
88 | atexit( freeUClip ); |
---|
89 | |
---|
90 | return res; |
---|
91 | } |
---|
92 | |
---|
93 | |
---|
94 | void textToClipbrd( HAB hab, const char *text ) |
---|
95 | { |
---|
96 | void *objtouni, *objtosys; |
---|
97 | int rc = ULS_SUCCESS; |
---|
98 | rc = UniCreateUconvObject( (UniChar *)L"UTF-8", &objtouni ); |
---|
99 | if ( rc != ULS_SUCCESS ) { |
---|
100 | return; |
---|
101 | } |
---|
102 | rc = UniCreateUconvObject( (UniChar *)L"", &objtosys ); |
---|
103 | if ( rc != ULS_SUCCESS ) { |
---|
104 | UniFreeUconvObject( objtouni ); |
---|
105 | return; |
---|
106 | } |
---|
107 | |
---|
108 | uconv_attribute_t attr; |
---|
109 | UniQueryUconvObject( objtouni, &attr, sizeof(attr), NULL, NULL, NULL ); |
---|
110 | attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH); |
---|
111 | UniSetUconvObject( objtouni, &attr ); |
---|
112 | UniQueryUconvObject( objtosys, &attr, sizeof(attr), NULL, NULL, NULL ); |
---|
113 | attr.options = UCONV_OPTION_SUBSTITUTE_BOTH; |
---|
114 | UniSetUconvObject( objtosys, &attr ); |
---|
115 | |
---|
116 | size_t len = 0; |
---|
117 | size_t olen = 0; |
---|
118 | |
---|
119 | if ( uclipLoaded ? pUWinOpenClipbrd( hab ) : WinOpenClipbrd( hab ) ) |
---|
120 | { |
---|
121 | if ( uclipLoaded ) { |
---|
122 | pUWinEmptyClipbrd( hab ); |
---|
123 | } else { |
---|
124 | WinEmptyClipbrd( hab ); |
---|
125 | } |
---|
126 | |
---|
127 | size_t cSubs = 0; |
---|
128 | len = strlen( text ); |
---|
129 | olen = ( len + 2 ) * 2; |
---|
130 | void *shmemuni = NULL; |
---|
131 | void *shmemsys = NULL; |
---|
132 | |
---|
133 | // place to clipboard as unicode for Odin |
---|
134 | if ( DosAllocSharedMem( &shmemuni, NULL, olen, fALLOCSHR ) == 0 ) |
---|
135 | { |
---|
136 | memset( shmemuni, 0, olen ); |
---|
137 | size_t unilen = olen / sizeof( UniChar ); |
---|
138 | UniChar *tmpuni = (UniChar *)shmemuni; |
---|
139 | UniUconvToUcs( objtouni, (void **)&text, &len, &tmpuni, &unilen, &cSubs ); |
---|
140 | unilen = UniStrlen( (UniChar *)shmemuni ); |
---|
141 | void *memuni = (void *)new char[ olen ]; |
---|
142 | memcpy( memuni, shmemuni, olen ); |
---|
143 | |
---|
144 | if ( uclipLoaded ) { |
---|
145 | pUWinSetClipbrdData( hab,(ULONG)shmemuni,UCLIP_CF_UNICODETEXT,CFI_POINTER ); |
---|
146 | } else { |
---|
147 | DosFreeMem( shmemuni ); |
---|
148 | } |
---|
149 | |
---|
150 | int liglen = uniLigaturesLength( (UniChar *)memuni ); |
---|
151 | if ( liglen > 0 ) // string contain ligature(s) |
---|
152 | { |
---|
153 | unsigned ulen_tmp = ( unilen + liglen + 1 ) * sizeof( UniChar ); |
---|
154 | char *uni_tmp = new char[ ulen_tmp ]; |
---|
155 | uniReplaceLigatures( (UniChar *)memuni, (UniChar *)uni_tmp ); |
---|
156 | delete memuni; |
---|
157 | memuni = uni_tmp; |
---|
158 | unilen = UniStrlen( (UniChar *)memuni ); |
---|
159 | } |
---|
160 | uniConvertSpChars( (UniChar *)memuni ); |
---|
161 | |
---|
162 | // place to clipboard as current codepage |
---|
163 | if ( DosAllocSharedMem( &shmemsys, NULL, olen, fALLOCSHR ) == 0 ) |
---|
164 | { |
---|
165 | memset( shmemsys, 0, olen ); |
---|
166 | |
---|
167 | cSubs = 0; |
---|
168 | tmpuni = (UniChar *)memuni; |
---|
169 | void *tmpsys = shmemsys; |
---|
170 | UniUconvFromUcs( objtosys, &tmpuni, &unilen, &tmpsys, &olen, &cSubs ); |
---|
171 | |
---|
172 | if ( uclipLoaded ) { |
---|
173 | pUWinSetClipbrdData( hab, (ULONG)shmemsys, UCLIP_CF_TEXT, CFI_POINTER ); |
---|
174 | } else { |
---|
175 | WinSetClipbrdData( hab, (ULONG)shmemsys, CF_TEXT, CFI_POINTER ); |
---|
176 | } |
---|
177 | } |
---|
178 | delete memuni; |
---|
179 | } |
---|
180 | |
---|
181 | if ( uclipLoaded ) { |
---|
182 | pUWinCloseClipbrd( hab ); |
---|
183 | } else { |
---|
184 | WinCloseClipbrd( hab ); |
---|
185 | } |
---|
186 | } |
---|
187 | |
---|
188 | UniFreeUconvObject( objtouni ); |
---|
189 | UniFreeUconvObject( objtosys ); |
---|
190 | } |
---|
191 | |
---|