27
28 #include "stdhdrs.h"
29 #include <commdlg.h>
30 #include <winspool.h>
31 #include <limits.h>
32 #include <float.h>
33
34 #include "awt_Toolkit.h"
35 #include "awt_PrintControl.h"
36
37 /* values for parameter "type" of XXX_getJobStatus() */
38 #define GETJOBCOUNT 1
39 #define ACCEPTJOB 2
40
41 static const char *HPRINTER_STR = "hPrintJob";
42
43 /* constants for DeviceCapability buffer lengths */
44 #define PAPERNAME_LENGTH 64
45 #define TRAYNAME_LENGTH 24
46
47
48 static BOOL IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) {
49 BOOL isSupported = FALSE;
50 DWORD cbBuf = 0;
51 LPBYTE pPrinter = NULL;
52
53 DASSERT(hPrinter != NULL);
54
55 VERIFY(::GetPrinter(hPrinter, dwLevel, NULL, 0, &cbBuf) == 0);
56 if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
57 pPrinter = new BYTE[cbBuf];
58 if (::GetPrinter(hPrinter, dwLevel, pPrinter, cbBuf, &cbBuf)) {
59 isSupported = TRUE;
60 }
61 delete[] pPrinter;
62 }
63
64 return isSupported;
65 }
66
67
100 int len = lstrlen(cBuffer);
101 while ((index < len) && cBuffer[index] != _T(',')) {
102 index++;
103 }
104 if (index==0) {
105 return NULL;
106 }
107
108 pPrinterName = (LPTSTR)GlobalAlloc(GPTR, (index+1)*sizeof(TCHAR));
109 lstrcpyn(pPrinterName, cBuffer, index+1);
110 jPrinterName = JNU_NewStringPlatform(env, pPrinterName);
111 GlobalFree(pPrinterName);
112 return jPrinterName;
113 } else {
114 return NULL;
115 }
116
117 CATCH_BAD_ALLOC_RET(NULL);
118 }
119
120
121 JNIEXPORT jobjectArray JNICALL
122 Java_sun_print_PrintServiceLookupProvider_getAllPrinterNames(JNIEnv *env,
123 jobject peer)
124 {
125 TRY;
126
127 DWORD cbNeeded = 0;
128 DWORD cReturned = 0;
129 LPBYTE pPrinterEnum = NULL;
130
131 jstring utf_str;
132 jclass clazz = env->FindClass("java/lang/String");
133 if (clazz == NULL) {
134 return NULL;
135 }
136 jobjectArray nameArray;
137
138 try {
139 ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
157 PRINTER_INFO_4 *info4 = (PRINTER_INFO_4 *)
158 (pPrinterEnum + i * sizeof(PRINTER_INFO_4));
159 utf_str = JNU_NewStringPlatform(env, info4->pPrinterName);
160 if (utf_str == NULL) {
161 throw std::bad_alloc();
162 }
163 env->SetObjectArrayElement(nameArray, i, utf_str);
164 env->DeleteLocalRef(utf_str);
165 }
166 } catch (std::bad_alloc&) {
167 delete [] pPrinterEnum;
168 throw;
169 }
170
171 delete [] pPrinterEnum;
172 return nameArray;
173
174 CATCH_BAD_ALLOC_RET(NULL);
175 }
176
177
178 JNIEXPORT jlong JNICALL
179 Java_sun_print_PrintServiceLookupProvider_notifyFirstPrinterChange(JNIEnv *env,
180 jobject peer,
181 jstring printer) {
182 HANDLE hPrinter;
183
184 LPTSTR printerName = NULL;
185 if (printer != NULL) {
186 printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
187 printer,
188 NULL);
189 JNU_ReleaseStringPlatformChars(env, printer, printerName);
190 }
191
192 // printerName - "Win NT/2K/XP: If NULL, it indicates the local printer
193 // server" - MSDN. Win9x : OpenPrinter returns 0.
194 BOOL ret = OpenPrinter(printerName, &hPrinter, NULL);
195 if (!ret) {
196 return (jlong)-1;
197 }
198
199 // PRINTER_CHANGE_PRINTER = PRINTER_CHANGE_ADD_PRINTER |
200 // PRINTER_CHANGE_SET_PRINTER |
201 // PRINTER_CHANGE_DELETE_PRINTER |
202 // PRINTER_CHANGE_FAILED_CONNECTION_PRINTER
203 HANDLE chgObj = FindFirstPrinterChangeNotification(hPrinter,
204 PRINTER_CHANGE_PRINTER,
205 0,
206 NULL);
207 return (chgObj == INVALID_HANDLE_VALUE) ? (jlong)-1 : (jlong)chgObj;
208 }
209
210
211
212 JNIEXPORT void JNICALL
213 Java_sun_print_PrintServiceLookupProvider_notifyClosePrinterChange(JNIEnv *env,
214 jobject peer,
215 jlong chgObject) {
216 FindClosePrinterChangeNotification((HANDLE)chgObject);
217 }
218
219
220 JNIEXPORT jint JNICALL
221 Java_sun_print_PrintServiceLookupProvider_notifyPrinterChange(JNIEnv *env,
222 jobject peer,
223 jlong chgObject) {
224 DWORD dwChange;
225
226 DWORD ret = WaitForSingleObject((HANDLE)chgObject, INFINITE);
227 if (ret == WAIT_OBJECT_0) {
228 return(FindNextPrinterChangeNotification((HANDLE)chgObject,
229 &dwChange, NULL, NULL));
230 } else {
231 return 0;
232 }
233 }
234
235
236 JNIEXPORT jfloatArray JNICALL
237 Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env,
238 jobject peer,
239 jstring printer,
240 jint papersize)
241 {
242 TRY;
243
244 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
245 printer, NULL);
246 if (printerName == NULL) {
247 return NULL;
248 }
249
250 jfloatArray printableArray = NULL;
251
252 SAVE_CONTROLWORD
253 HDC pdc = CreateDC(TEXT("WINSPOOL"), printerName, NULL, NULL);
254 RESTORE_CONTROLWORD
|
27
28 #include "stdhdrs.h"
29 #include <commdlg.h>
30 #include <winspool.h>
31 #include <limits.h>
32 #include <float.h>
33
34 #include "awt_Toolkit.h"
35 #include "awt_PrintControl.h"
36
37 /* values for parameter "type" of XXX_getJobStatus() */
38 #define GETJOBCOUNT 1
39 #define ACCEPTJOB 2
40
41 static const char *HPRINTER_STR = "hPrintJob";
42
43 /* constants for DeviceCapability buffer lengths */
44 #define PAPERNAME_LENGTH 64
45 #define TRAYNAME_LENGTH 24
46
47 static BOOL IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) {
48 BOOL isSupported = FALSE;
49 DWORD cbBuf = 0;
50 LPBYTE pPrinter = NULL;
51
52 DASSERT(hPrinter != NULL);
53
54 VERIFY(::GetPrinter(hPrinter, dwLevel, NULL, 0, &cbBuf) == 0);
55 if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
56 pPrinter = new BYTE[cbBuf];
57 if (::GetPrinter(hPrinter, dwLevel, pPrinter, cbBuf, &cbBuf)) {
58 isSupported = TRUE;
59 }
60 delete[] pPrinter;
61 }
62
63 return isSupported;
64 }
65
66
99 int len = lstrlen(cBuffer);
100 while ((index < len) && cBuffer[index] != _T(',')) {
101 index++;
102 }
103 if (index==0) {
104 return NULL;
105 }
106
107 pPrinterName = (LPTSTR)GlobalAlloc(GPTR, (index+1)*sizeof(TCHAR));
108 lstrcpyn(pPrinterName, cBuffer, index+1);
109 jPrinterName = JNU_NewStringPlatform(env, pPrinterName);
110 GlobalFree(pPrinterName);
111 return jPrinterName;
112 } else {
113 return NULL;
114 }
115
116 CATCH_BAD_ALLOC_RET(NULL);
117 }
118
119 JNIEXPORT jlong JNICALL
120 Java_sun_print_PrintServiceLookupProvider_notifyFirstPrinterChange(JNIEnv *env,
121 jobject peer,
122 jstring printer) {
123 HANDLE hPrinter;
124
125 LPTSTR printerName = NULL;
126 if (printer != NULL) {
127 printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
128 printer,
129 NULL);
130 JNU_ReleaseStringPlatformChars(env, printer, printerName);
131 }
132
133 // printerName - "Win NT/2K/XP: If NULL, it indicates the local printer
134 // server" - MSDN. Win9x : OpenPrinter returns 0.
135 BOOL ret = OpenPrinter(printerName, &hPrinter, NULL);
136 if (!ret) {
137 return (jlong)-1;
138 }
139
140 // PRINTER_CHANGE_PRINTER = PRINTER_CHANGE_ADD_PRINTER |
141 // PRINTER_CHANGE_SET_PRINTER |
142 // PRINTER_CHANGE_DELETE_PRINTER |
143 // PRINTER_CHANGE_FAILED_CONNECTION_PRINTER
144 HANDLE chgObj = FindFirstPrinterChangeNotification(hPrinter,
145 PRINTER_CHANGE_PRINTER,
146 0,
147 NULL);
148 return (chgObj == INVALID_HANDLE_VALUE) ? (jlong)-1 : (jlong)chgObj;
149 }
150
151
152
153 JNIEXPORT void JNICALL
154 Java_sun_print_PrintServiceLookupProvider_notifyClosePrinterChange(JNIEnv *env,
155 jobject peer,
156 jlong chgObject) {
157 FindClosePrinterChangeNotification((HANDLE)chgObject);
158 }
159
160
161 JNIEXPORT jint JNICALL
162 Java_sun_print_PrintServiceLookupProvider_notifyPrinterChange(JNIEnv *env,
163 jobject peer,
164 jlong chgObject) {
165 DWORD dwChange;
166
167 DWORD ret = WaitForSingleObject((HANDLE)chgObject, INFINITE);
168 if (ret == WAIT_OBJECT_0) {
169 return(FindNextPrinterChangeNotification((HANDLE)chgObject,
170 &dwChange, NULL, NULL));
171 } else {
172 return 0;
173 }
174 }
175
176 JNIEXPORT jobjectArray JNICALL
177 Java_sun_print_PrintServiceLookupProvider_getAllPrinterNames(JNIEnv *env,
178 jobject peer)
179 {
180 TRY;
181
182 DWORD cbNeeded = 0;
183 DWORD cReturned = 0;
184 LPBYTE pPrinterEnum = NULL;
185
186 jstring utf_str;
187 jclass clazz = env->FindClass("java/lang/String");
188 if (clazz == NULL) {
189 return NULL;
190 }
191 jobjectArray nameArray;
192
193 try {
194 ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
212 PRINTER_INFO_4 *info4 = (PRINTER_INFO_4 *)
213 (pPrinterEnum + i * sizeof(PRINTER_INFO_4));
214 utf_str = JNU_NewStringPlatform(env, info4->pPrinterName);
215 if (utf_str == NULL) {
216 throw std::bad_alloc();
217 }
218 env->SetObjectArrayElement(nameArray, i, utf_str);
219 env->DeleteLocalRef(utf_str);
220 }
221 } catch (std::bad_alloc&) {
222 delete [] pPrinterEnum;
223 throw;
224 }
225
226 delete [] pPrinterEnum;
227 return nameArray;
228
229 CATCH_BAD_ALLOC_RET(NULL);
230 }
231
232 JNIEXPORT jobjectArray JNICALL
233 Java_sun_print_PrintServiceLookupProvider_GetRemotePrintersNames(JNIEnv *env,
234 jobject peer)
235 {
236 TRY;
237
238 int remotePrintersCount = 0;
239 DWORD cbNeeded = 0;
240 DWORD cReturned = 0;
241 LPBYTE pPrinterEnum = NULL;
242 LPBYTE pNetworkPrinterLoc = NULL;
243
244 jstring utf_str;
245 jclass clazz = env->FindClass("java/lang/String");
246 if (clazz == NULL) {
247 return NULL;
248 }
249 jobjectArray nameArray;
250
251 try {
252 ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
253 NULL, 4, NULL, 0, &cbNeeded, &cReturned);
254 pPrinterEnum = new BYTE[cbNeeded];
255 pNetworkPrinterLoc = new BYTE[cbNeeded/sizeof(PRINTER_INFO_4)];
256 ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
257 NULL, 4, pPrinterEnum, cbNeeded, &cbNeeded,
258 &cReturned);
259
260 if (cReturned > 0) {
261 for (DWORD i = 0; i < cReturned; i++) {
262 PRINTER_INFO_4 *info4 = (PRINTER_INFO_4 *) (pPrinterEnum + i * sizeof(PRINTER_INFO_4));
263
264 // PRINTER_ATTRIBUTE_NETWORK = 0x00000010
265 // Store the network printers indexes
266 if(info4->Attributes & 0x00000010) {
267 pNetworkPrinterLoc[remotePrintersCount++] = i;
268 }
269 }
270
271 // Allocate space only for the network type printers
272 nameArray = env->NewObjectArray(remotePrintersCount, clazz, NULL);
273 if (nameArray == NULL) {
274 throw std::bad_alloc();
275 }
276 } else {
277 nameArray = NULL;
278 }
279
280 // Loop thro' network printers list only
281 for (int i = 0; i < remotePrintersCount; i++) {
282 PRINTER_INFO_4 *info4 = (PRINTER_INFO_4 *)
283 (pPrinterEnum + pNetworkPrinterLoc[i] * sizeof(PRINTER_INFO_4));
284 utf_str = JNU_NewStringPlatform(env, info4->pPrinterName);
285 if (utf_str == NULL) {
286 throw std::bad_alloc();
287 }
288 env->SetObjectArrayElement(nameArray, i, utf_str);
289 env->DeleteLocalRef(utf_str);
290 }
291 } catch (std::bad_alloc&) {
292 delete [] pPrinterEnum;
293 delete [] pNetworkPrinterLoc;
294 throw;
295 }
296
297 delete [] pPrinterEnum;
298 delete [] pNetworkPrinterLoc;
299 return nameArray;
300
301 CATCH_BAD_ALLOC_RET(NULL);
302 }
303
304 JNIEXPORT jfloatArray JNICALL
305 Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env,
306 jobject peer,
307 jstring printer,
308 jint papersize)
309 {
310 TRY;
311
312 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
313 printer, NULL);
314 if (printerName == NULL) {
315 return NULL;
316 }
317
318 jfloatArray printableArray = NULL;
319
320 SAVE_CONTROLWORD
321 HDC pdc = CreateDC(TEXT("WINSPOOL"), printerName, NULL, NULL);
322 RESTORE_CONTROLWORD
|