1 /* 2 * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "awt.h" 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 68 extern "C" { 69 70 JNIEXPORT jstring JNICALL 71 Java_sun_print_Win32PrintServiceLookup_getDefaultPrinterName(JNIEnv *env, 72 jobject peer) 73 { 74 TRY; 75 76 TCHAR cBuffer[250]; 77 OSVERSIONINFO osv; 78 PRINTER_INFO_2 *ppi2 = NULL; 79 DWORD dwNeeded = 0; 80 DWORD dwReturned = 0; 81 LPTSTR pPrinterName = NULL; 82 jstring jPrinterName; 83 84 // What version of Windows are you running? 85 osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 86 GetVersionEx(&osv); 87 88 // If Windows 2000, XP, Vista 89 if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) { 90 91 // Retrieve the default string from Win.ini (the registry). 92 // String will be in form "printername,drivername,portname". 93 94 if (GetProfileString(TEXT("windows"), TEXT("device"), TEXT(",,,"), 95 cBuffer, 250) <= 0) { 96 return NULL; 97 } 98 // Copy printer name into passed-in buffer... 99 int index = 0; 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_Win32PrintServiceLookup_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, 140 NULL, 4, NULL, 0, &cbNeeded, &cReturned); 141 pPrinterEnum = new BYTE[cbNeeded]; 142 ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, 143 NULL, 4, pPrinterEnum, cbNeeded, &cbNeeded, 144 &cReturned); 145 146 if (cReturned > 0) { 147 nameArray = env->NewObjectArray(cReturned, clazz, NULL); 148 if (nameArray == NULL) { 149 throw std::bad_alloc(); 150 } 151 } else { 152 nameArray = NULL; 153 } 154 155 156 for (DWORD i = 0; i < cReturned; i++) { 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_Win32PrintServiceLookup_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_Win32PrintServiceLookup_notifyClosePrinterChange(JNIEnv *env, 214 jobject peer, 215 jlong chgObject) { 216 FindClosePrinterChangeNotification((HANDLE)chgObject); 217 } 218 219 220 JNIEXPORT jint JNICALL 221 Java_sun_print_Win32PrintServiceLookup_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 255 if (pdc) { 256 HANDLE hPrinter; 257 /* Start by opening the printer */ 258 if (!::OpenPrinter(printerName, &hPrinter, NULL)) { 259 JNU_ReleaseStringPlatformChars(env, printer, printerName); 260 return printableArray; 261 } 262 263 PDEVMODE pDevMode; 264 265 if (!AwtPrintControl::getDevmode(hPrinter, printerName, &pDevMode)) { 266 /* if failure, cleanup and return failure */ 267 268 if (pDevMode != NULL) { 269 ::GlobalFree(pDevMode); 270 } 271 DeleteDC(pdc); 272 ::ClosePrinter(hPrinter); 273 JNU_ReleaseStringPlatformChars(env, printer, printerName); 274 return printableArray; 275 } 276 277 pDevMode->dmFields |= (DM_PAPERSIZE | DM_ORIENTATION); 278 pDevMode->dmPaperSize = (short)papersize; 279 pDevMode->dmOrientation = DMORIENT_PORTRAIT; 280 ::ResetDC(pdc, pDevMode); 281 RESTORE_CONTROLWORD 282 283 int left = GetDeviceCaps(pdc, PHYSICALOFFSETX); 284 int top = GetDeviceCaps(pdc, PHYSICALOFFSETY); 285 int width = GetDeviceCaps(pdc, HORZRES); 286 int height = GetDeviceCaps(pdc, VERTRES); 287 288 int resx = GetDeviceCaps(pdc, LOGPIXELSX); 289 int resy = GetDeviceCaps(pdc, LOGPIXELSY); 290 291 printableArray=env->NewFloatArray(4); 292 if (printableArray != NULL) { 293 jfloat *iPrintables = 294 env->GetFloatArrayElements(printableArray, NULL); 295 if (iPrintables != NULL) { 296 iPrintables[0] = (float)left/resx; 297 iPrintables[1] = (float)top/resy; 298 iPrintables[2] = (float)width/resx; 299 iPrintables[3] = (float)height/resy; 300 env->ReleaseFloatArrayElements(printableArray, iPrintables, 0); 301 } 302 } 303 GlobalFree(pDevMode); 304 DeleteDC(pdc); 305 } 306 307 JNU_ReleaseStringPlatformChars(env, printer, printerName); 308 309 return printableArray; 310 311 CATCH_BAD_ALLOC_RET(NULL); 312 } 313 314 jintArray getIDs(JNIEnv *env, jstring printer, jstring port, int dm_id) 315 { 316 317 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 318 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 319 320 if (printerName == NULL || printerPort == NULL) { 321 if (printerName != NULL) { 322 JNU_ReleaseStringPlatformChars(env, printer, printerName); 323 } 324 if (printerPort != NULL) { 325 JNU_ReleaseStringPlatformChars(env, port, printerPort); 326 } 327 return NULL; 328 } 329 330 SAVE_CONTROLWORD 331 int numIDs = ::DeviceCapabilities(printerName, printerPort, dm_id, 332 NULL, NULL); 333 RESTORE_CONTROLWORD 334 335 jintArray idArray = NULL; 336 if (numIDs > 0) { 337 idArray = env->NewIntArray(numIDs); 338 if (idArray != NULL) { 339 jint *jpcIndices = env->GetIntArrayElements(idArray, NULL); 340 if (jpcIndices != NULL) { 341 jint *saveFormats = jpcIndices; 342 LPTSTR buf = NULL; 343 try { 344 buf = (LPTSTR)new char[numIDs * sizeof(WORD)]; 345 } catch (std::bad_alloc&) { 346 buf = NULL; 347 } 348 if (buf != NULL) { 349 if (::DeviceCapabilities(printerName, printerPort, 350 dm_id, buf, NULL) != -1) { 351 WORD *id = (WORD *)buf; 352 for (int i = 0; i < numIDs; i++, id++) { 353 jpcIndices[i] = *id; 354 } 355 } 356 RESTORE_CONTROLWORD 357 delete[] buf; 358 } 359 env->ReleaseIntArrayElements(idArray, saveFormats, 0); 360 } 361 } 362 } 363 364 JNU_ReleaseStringPlatformChars(env, printer, printerName); 365 JNU_ReleaseStringPlatformChars(env, port, printerPort); 366 return idArray; 367 } 368 369 JNIEXPORT jintArray JNICALL 370 Java_sun_print_Win32PrintService_getAllMediaIDs(JNIEnv *env, 371 jobject peer, 372 jstring printer, 373 jstring port) 374 { 375 return getIDs(env, printer, port, DC_PAPERS); 376 } 377 378 379 JNIEXPORT jintArray JNICALL 380 Java_sun_print_Win32PrintService_getAllMediaTrays(JNIEnv *env, 381 jobject peer, 382 jstring printer, 383 jstring port) 384 { 385 return getIDs(env, printer, port, DC_BINS); 386 } 387 388 389 JNIEXPORT jintArray JNICALL 390 Java_sun_print_Win32PrintService_getAllMediaSizes(JNIEnv *env, 391 jobject peer, 392 jstring printer, 393 jstring port) 394 { 395 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 396 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 397 398 if (printerName == NULL || printerPort == NULL) { 399 if (printerName != NULL) { 400 JNU_ReleaseStringPlatformChars(env, printer, printerName); 401 } 402 if (printerPort != NULL) { 403 JNU_ReleaseStringPlatformChars(env, port, printerPort); 404 } 405 return NULL; 406 } 407 408 SAVE_CONTROLWORD 409 int nPapers = ::DeviceCapabilities(printerName, printerPort, DC_PAPERSIZE, 410 NULL, NULL) ; 411 RESTORE_CONTROLWORD 412 413 jintArray mediaArray = NULL; 414 jint *saveFormats = NULL; 415 416 if (nPapers > 0) { 417 mediaArray = env->NewIntArray(nPapers*2); 418 if (mediaArray != NULL) { 419 jint *jpcIndices = env->GetIntArrayElements(mediaArray, NULL); 420 if (jpcIndices != NULL) { 421 saveFormats = jpcIndices; 422 LPTSTR buf = NULL; 423 try { 424 buf = (LPTSTR)new char[nPapers * sizeof(POINT)]; 425 } catch (std::bad_alloc&) { 426 buf = NULL; 427 } 428 if (buf != NULL) { 429 if (::DeviceCapabilities(printerName, printerPort, 430 DC_PAPERSIZE, buf, NULL) != -1) { 431 POINT *pDim = (POINT *)buf; 432 for (int i = 0; i < nPapers; i++) { 433 jpcIndices[i*2] = (pDim+i)->x; 434 jpcIndices[i*2+1] = (pDim+i)->y; 435 } 436 } 437 RESTORE_CONTROLWORD 438 delete[] buf; 439 } 440 env->ReleaseIntArrayElements(mediaArray, saveFormats, 0); 441 saveFormats = NULL; 442 } 443 } 444 } 445 446 JNU_ReleaseStringPlatformChars(env, printer, printerName); 447 JNU_ReleaseStringPlatformChars(env, port, printerPort); 448 if (mediaArray != NULL && saveFormats != NULL) { 449 env->ReleaseIntArrayElements(mediaArray, saveFormats, 0); 450 } 451 return mediaArray; 452 453 } 454 455 456 jobjectArray getAllDCNames(JNIEnv *env, jobject peer, jstring printer, 457 jstring port, unsigned int dc_id, unsigned int buf_len) 458 { 459 460 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 461 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 462 463 if (printerName == NULL || printerPort == NULL) { 464 if (printerName != NULL) { 465 JNU_ReleaseStringPlatformChars(env, printer, printerName); 466 } 467 if (printerPort != NULL) { 468 JNU_ReleaseStringPlatformChars(env, port, printerPort); 469 } 470 return NULL; 471 } 472 473 jstring utf_str; 474 jobjectArray names = NULL; 475 LPTSTR buf = NULL; 476 SAVE_CONTROLWORD 477 int cReturned = ::DeviceCapabilities(printerName, printerPort, 478 dc_id, NULL, NULL); 479 RESTORE_CONTROLWORD 480 if (cReturned <= 0) { 481 JNU_ReleaseStringPlatformChars(env, printer, printerName); 482 JNU_ReleaseStringPlatformChars(env, port, printerPort); 483 return NULL; 484 } 485 486 try { 487 buf = (LPTSTR)new char[cReturned * buf_len * sizeof(TCHAR)]; 488 } catch (std::bad_alloc&) { 489 buf = NULL; 490 } 491 if (buf == NULL) { 492 JNU_ReleaseStringPlatformChars(env, printer, printerName); 493 JNU_ReleaseStringPlatformChars(env, port, printerPort); 494 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 495 return NULL; 496 } 497 498 cReturned = ::DeviceCapabilities(printerName, printerPort, 499 dc_id, buf, NULL); 500 RESTORE_CONTROLWORD 501 502 JNU_ReleaseStringPlatformChars(env, printer, printerName); 503 JNU_ReleaseStringPlatformChars(env, port, printerPort); 504 505 if (cReturned > 0) { 506 jclass cls = env->FindClass("java/lang/String"); 507 if (cls != NULL) { 508 names = env->NewObjectArray(cReturned, cls, NULL); 509 } 510 if (names == NULL || cls == NULL) { 511 delete buf; 512 return names; 513 } 514 515 for (int i = 0; i < cReturned; i++) { 516 utf_str = JNU_NewStringPlatform(env, buf+(buf_len*i)); 517 if (utf_str == NULL) { 518 delete buf; 519 return names; 520 } 521 env->SetObjectArrayElement(names, i, utf_str); 522 env->DeleteLocalRef(utf_str); 523 } 524 } 525 delete[] buf; 526 return names; 527 528 } 529 530 531 JNIEXPORT jobjectArray JNICALL 532 Java_sun_print_Win32PrintService_getAllMediaNames(JNIEnv *env, 533 jobject peer, 534 jstring printer, 535 jstring port) 536 { 537 return getAllDCNames(env, peer, printer, port, DC_PAPERNAMES, PAPERNAME_LENGTH); 538 } 539 540 541 JNIEXPORT jobjectArray JNICALL 542 Java_sun_print_Win32PrintService_getAllMediaTrayNames(JNIEnv *env, 543 jobject peer, 544 jstring printer, 545 jstring port) 546 { 547 return getAllDCNames(env, peer, printer, port, DC_BINNAMES, TRAYNAME_LENGTH); 548 } 549 550 551 JNIEXPORT jint JNICALL 552 Java_sun_print_Win32PrintService_getCopiesSupported(JNIEnv *env, 553 jobject peer, 554 jstring printer, 555 jstring port) 556 { 557 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 558 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 559 560 if (printerName == NULL || printerPort == NULL) { 561 if (printerName != NULL) { 562 JNU_ReleaseStringPlatformChars(env, printer, printerName); 563 } 564 if (printerPort != NULL) { 565 JNU_ReleaseStringPlatformChars(env, port, printerPort); 566 } 567 return 1; 568 } 569 570 SAVE_CONTROLWORD 571 int numCopies = ::DeviceCapabilities(printerName, printerPort, 572 DC_COPIES, NULL, NULL); 573 RESTORE_CONTROLWORD 574 575 if (numCopies == -1) 576 return 1; // default 577 578 JNU_ReleaseStringPlatformChars(env, printer, printerName); 579 JNU_ReleaseStringPlatformChars(env, port, printerPort); 580 581 return numCopies; 582 } 583 584 585 /* 586 PostScript Drivers return wrong support info for the following code: 587 588 DWORD dmFields = (::DeviceCapabilities(printerName, 589 NULL, DC_FIELDS, NULL, NULL)) ; 590 591 if ((dmFields & DM_YRESOLUTION) ) 592 isSupported = true; 593 594 Returns not supported even if it supports resolution. Therefore, we use the 595 function _getAllResolutions. 596 */ 597 JNIEXPORT jintArray JNICALL 598 Java_sun_print_Win32PrintService_getAllResolutions(JNIEnv *env, 599 jobject peer, 600 jstring printer, 601 jstring port) 602 { 603 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 604 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 605 606 if (printerName == NULL || printerPort == NULL) { 607 if (printerName != NULL) { 608 JNU_ReleaseStringPlatformChars(env, printer, printerName); 609 } 610 if (printerPort != NULL) { 611 JNU_ReleaseStringPlatformChars(env, port, printerPort); 612 } 613 return NULL; 614 } 615 616 SAVE_CONTROLWORD 617 int nResolutions = ::DeviceCapabilities(printerName, printerPort, 618 DC_ENUMRESOLUTIONS, NULL, NULL); 619 RESTORE_CONTROLWORD 620 621 jintArray resolutionArray = NULL; 622 if (nResolutions > 0) { 623 resolutionArray = env->NewIntArray(nResolutions*2); 624 if (resolutionArray != NULL) { 625 jint *jpcIndices = env->GetIntArrayElements(resolutionArray, NULL); 626 if (jpcIndices != NULL) { 627 jint *saveFormats = jpcIndices; 628 LPTSTR resBuf = NULL; 629 try { 630 resBuf = (LPTSTR)new char[nResolutions * sizeof(LONG) * 2]; 631 } catch (std::bad_alloc&) { 632 resBuf = NULL; 633 } 634 if (resBuf != NULL) { 635 if (::DeviceCapabilities(printerName, printerPort, 636 DC_ENUMRESOLUTIONS, resBuf, 637 NULL) != -1) { 638 LONG *pResolution = (LONG *)resBuf; 639 for (int i = 0; i < nResolutions; i++) { 640 jpcIndices[i*2] = *pResolution++; 641 jpcIndices[i*2+1] = *pResolution++; 642 } 643 } 644 RESTORE_CONTROLWORD 645 delete[] resBuf; 646 } 647 env->ReleaseIntArrayElements(resolutionArray, saveFormats, 0); 648 } 649 } 650 } 651 652 JNU_ReleaseStringPlatformChars(env, printer, printerName); 653 JNU_ReleaseStringPlatformChars(env, printer, printerPort); 654 return resolutionArray; 655 } 656 657 658 static BOOL IsDCPostscript( HDC hDC ) 659 { 660 int nEscapeCode; 661 CHAR szTechnology[MAX_PATH] = ""; 662 663 // If it supports POSTSCRIPT_PASSTHROUGH, it must be PS. 664 nEscapeCode = POSTSCRIPT_PASSTHROUGH; 665 if( ::ExtEscape( hDC, QUERYESCSUPPORT, sizeof(int), 666 (LPCSTR)&nEscapeCode, 0, NULL ) > 0 ) 667 return TRUE; 668 669 // If it doesn't support GETTECHNOLOGY, we won't be able to tell. 670 nEscapeCode = GETTECHNOLOGY; 671 if( ::ExtEscape( hDC, QUERYESCSUPPORT, sizeof(int), 672 (LPCSTR)&nEscapeCode, 0, NULL ) <= 0 ) 673 return FALSE; 674 675 // Get the technology string and check if the word "postscript" is in it. 676 if( ::ExtEscape( hDC, GETTECHNOLOGY, 0, NULL, MAX_PATH, 677 (LPSTR)szTechnology ) <= 0 ) 678 return FALSE; 679 _strupr_s(szTechnology, MAX_PATH); 680 if(!strstr( szTechnology, "POSTSCRIPT" ) == NULL ) 681 return TRUE; 682 683 // The word "postscript" was not found and it didn't support 684 // POSTSCRIPT_PASSTHROUGH, so it's not a PS printer. 685 return FALSE; 686 } 687 688 689 JNIEXPORT jstring JNICALL 690 Java_sun_print_Win32PrintService_getPrinterPort(JNIEnv *env, 691 jobject peer, 692 jstring printer) 693 { 694 695 if (printer == NULL) { 696 return NULL; 697 } 698 699 jstring jPort; 700 LPTSTR printerName = NULL, printerPort = TEXT("LPT1"); 701 LPBYTE buffer = NULL; 702 DWORD cbBuf = 0; 703 704 try { 705 VERIFY(AwtPrintControl::FindPrinter(NULL, NULL, &cbBuf, NULL, NULL)); 706 buffer = new BYTE[cbBuf]; 707 AwtPrintControl::FindPrinter(printer, buffer, &cbBuf, 708 &printerName, &printerPort); 709 } catch (std::bad_alloc&) { 710 delete [] buffer; 711 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); 712 return NULL; 713 } 714 715 if (printerPort == NULL) { 716 printerPort = TEXT("LPT1"); 717 } 718 jPort = JNU_NewStringPlatform(env, printerPort); 719 delete [] buffer; 720 return jPort; 721 722 } 723 724 725 JNIEXPORT jint JNICALL 726 Java_sun_print_Win32PrintService_getCapabilities(JNIEnv *env, 727 jobject peer, 728 jstring printer, 729 jstring port) 730 { 731 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 732 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 733 734 if (printerName == NULL || printerPort == NULL) { 735 if (printerName != NULL) { 736 JNU_ReleaseStringPlatformChars(env, printer, printerName); 737 } 738 if (printerPort != NULL) { 739 JNU_ReleaseStringPlatformChars(env, port, printerPort); 740 } 741 return NULL; 742 } 743 744 // 0x1000 is a flag to indicate that getCapabilities has already been called. 745 // 0x0001 is a flag for color support and supported is the default. 746 jint ret = 0x1001; 747 DWORD dmFields; 748 749 // get Duplex 750 SAVE_CONTROLWORD 751 DWORD isDuplex = (::DeviceCapabilities(printerName, printerPort, 752 DC_DUPLEX, NULL, NULL)) ; 753 754 /* 755 Check if duplexer is installed either physically or manually thru the 756 printer setting dialog by checking if DM_DUPLEX is set. 757 */ 758 dmFields = (::DeviceCapabilities(printerName, printerPort, 759 DC_FIELDS, NULL, NULL)) ; 760 761 if ((dmFields & DM_DUPLEX) && isDuplex) { 762 ret |= 0x0002; 763 } 764 765 // get Collation 766 if ((dmFields & DM_COLLATE) ) { 767 ret |= 0x0004; 768 } 769 770 // get Print Quality 771 if ((dmFields & DM_PRINTQUALITY) ) { 772 ret |= 0x0008; 773 } 774 775 HDC pdc = CreateDC(TEXT("WINSPOOL"), printerName, NULL, NULL); 776 if (pdc != NULL) { 777 // get Color 778 int bpp = GetDeviceCaps(pdc, BITSPIXEL); 779 int nColors = GetDeviceCaps(pdc, NUMCOLORS); 780 781 if (!(dmFields & DM_COLOR) || ((bpp == 1) 782 && ((nColors == 2) || (nColors == 256)))) { 783 ret &= ~0x0001; 784 } 785 786 // check support for PostScript 787 if (IsDCPostscript(pdc)) { 788 ret |= 0x0010; 789 } 790 791 DeleteDC(pdc); 792 } 793 794 RESTORE_CONTROLWORD 795 JNU_ReleaseStringPlatformChars(env, printer, printerName); 796 JNU_ReleaseStringPlatformChars(env, printer, printerPort); 797 return ret; 798 } 799 800 801 #define GETDEFAULT_ERROR -50 802 #define NDEFAULT 9 803 804 JNIEXPORT jintArray JNICALL 805 Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, 806 jobject peer, 807 jstring printer, 808 jstring port) 809 { 810 HANDLE hPrinter; 811 LPDEVMODE pDevMode = NULL; 812 813 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 814 LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); 815 816 if (printerName == NULL || printerPort == NULL) { 817 if (printerName != NULL) { 818 JNU_ReleaseStringPlatformChars(env, printer, printerName); 819 } 820 if (printerPort != NULL) { 821 JNU_ReleaseStringPlatformChars(env, port, printerPort); 822 } 823 return NULL; 824 } 825 826 jint* defIndices = NULL; 827 jintArray defaultArray = env->NewIntArray(NDEFAULT); 828 if (defaultArray != NULL) { 829 defIndices = env->GetIntArrayElements(defaultArray, NULL); 830 } 831 if (defIndices == NULL) { 832 JNU_ReleaseStringPlatformChars(env, printer, printerName); 833 JNU_ReleaseStringPlatformChars(env, port, printerPort); 834 return NULL; 835 } 836 837 jint *saveFormats = defIndices; 838 839 for (int i=0; i < NDEFAULT; i++) { 840 defIndices[i] = GETDEFAULT_ERROR; 841 } 842 843 /* Start by opening the printer */ 844 if (!::OpenPrinter(printerName, &hPrinter, NULL)) { 845 env->ReleaseIntArrayElements(defaultArray, saveFormats, 0); 846 JNU_ReleaseStringPlatformChars(env, printer, printerName); 847 JNU_ReleaseStringPlatformChars(env, port, printerPort); 848 return defaultArray; 849 } 850 851 if (!AwtPrintControl::getDevmode(hPrinter, printerName, &pDevMode)) { 852 /* if failure, cleanup and return failure */ 853 if (pDevMode != NULL) { 854 ::GlobalFree(pDevMode); 855 } 856 ::ClosePrinter(hPrinter); 857 env->ReleaseIntArrayElements(defaultArray, saveFormats, 0); 858 JNU_ReleaseStringPlatformChars(env, printer, printerName); 859 JNU_ReleaseStringPlatformChars(env, port, printerPort); 860 return defaultArray; 861 } 862 863 /* Have seen one driver which reports a default paper id which is not 864 * one of their supported paper ids. If what is returned is not 865 * a supported paper, use one of the supported sizes instead. 866 * 867 */ 868 if (pDevMode->dmFields & DM_PAPERSIZE) { 869 defIndices[0] = pDevMode->dmPaperSize; 870 871 SAVE_CONTROLWORD 872 873 int numSizes = ::DeviceCapabilities(printerName, printerPort, 874 DC_PAPERS, NULL, NULL); 875 if (numSizes > 0) { 876 LPTSTR papers = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, numSizes, sizeof(WORD)); 877 if (papers != NULL && 878 ::DeviceCapabilities(printerName, printerPort, 879 DC_PAPERS, papers, NULL) != -1) { 880 int present = 0; 881 for (int i=0;i<numSizes;i++) { 882 if (papers[i] == pDevMode->dmPaperSize) { 883 present = 1; 884 } 885 } 886 if (!present) { 887 defIndices[0] = papers[0]; 888 } 889 if (papers != NULL) { 890 free((char*)papers); 891 } 892 } 893 } 894 RESTORE_CONTROLWORD 895 } 896 897 if (pDevMode->dmFields & DM_MEDIATYPE) { 898 defIndices[1] = pDevMode->dmMediaType; 899 } 900 901 if (pDevMode->dmFields & DM_YRESOLUTION) { 902 defIndices[2] = pDevMode->dmYResolution; 903 } 904 905 if (pDevMode->dmFields & DM_PRINTQUALITY) { 906 defIndices[3] = pDevMode->dmPrintQuality; 907 } 908 909 if (pDevMode->dmFields & DM_COPIES) { 910 defIndices[4] = pDevMode->dmCopies; 911 } 912 913 if (pDevMode->dmFields & DM_ORIENTATION) { 914 defIndices[5] = pDevMode->dmOrientation; 915 } 916 917 if (pDevMode->dmFields & DM_DUPLEX) { 918 defIndices[6] = pDevMode->dmDuplex; 919 } 920 921 if (pDevMode->dmFields & DM_COLLATE) { 922 defIndices[7] = pDevMode->dmCollate; 923 } 924 925 if (pDevMode->dmFields & DM_COLOR) { 926 defIndices[8] = pDevMode->dmColor; 927 } 928 929 GlobalFree(pDevMode); 930 ::ClosePrinter(hPrinter); 931 932 env->ReleaseIntArrayElements(defaultArray, saveFormats, 0); 933 934 JNU_ReleaseStringPlatformChars(env, printer, printerName); 935 JNU_ReleaseStringPlatformChars(env, port, printerPort); 936 937 return defaultArray; 938 } 939 940 941 JNIEXPORT jint JNICALL 942 Java_sun_print_Win32PrintService_getJobStatus(JNIEnv *env, 943 jobject peer, 944 jstring printer, 945 jint type) 946 { 947 HANDLE hPrinter; 948 DWORD cByteNeeded; 949 DWORD cByteUsed; 950 PRINTER_INFO_2 *pPrinterInfo = NULL; 951 int ret=0; 952 953 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 954 if (printerName == NULL) { 955 return -1; 956 } 957 958 // Start by opening the printer 959 if (!::OpenPrinter(printerName, &hPrinter, NULL)) { 960 JNU_ReleaseStringPlatformChars(env, printer, printerName); 961 return -1; 962 } 963 964 if (!::GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded)) { 965 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 966 ::ClosePrinter(hPrinter); 967 JNU_ReleaseStringPlatformChars(env, printer, printerName); 968 return -1; 969 } 970 } 971 972 pPrinterInfo = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR, cByteNeeded); 973 if (!(pPrinterInfo)) { 974 /* failure to allocate memory */ 975 ::ClosePrinter(hPrinter); 976 JNU_ReleaseStringPlatformChars(env, printer, printerName); 977 return -1; 978 } 979 980 /* get the printer info */ 981 if (!::GetPrinter(hPrinter, 982 2, 983 (LPBYTE)pPrinterInfo, 984 cByteNeeded, 985 &cByteUsed)) 986 { 987 /* failure to access the printer */ 988 ::GlobalFree(pPrinterInfo); 989 pPrinterInfo = NULL; 990 ::ClosePrinter(hPrinter); 991 JNU_ReleaseStringPlatformChars(env, printer, printerName); 992 return -1; 993 } 994 995 if (type == GETJOBCOUNT) { 996 ret = pPrinterInfo->cJobs; 997 } else if (type == ACCEPTJOB) { 998 if (pPrinterInfo->Status & PRINTER_STATUS_PENDING_DELETION) { 999 ret = 0; 1000 } 1001 else { 1002 ret = 1; 1003 } 1004 } 1005 1006 ::GlobalFree(pPrinterInfo); 1007 ::ClosePrinter(hPrinter); 1008 JNU_ReleaseStringPlatformChars(env, printer, printerName); 1009 return ret; 1010 } 1011 1012 1013 static jfieldID getIdOfLongField(JNIEnv *env, jobject self, 1014 const char *fieldName) { 1015 jclass myClass = env->GetObjectClass(self); 1016 jfieldID fieldId = env->GetFieldID(myClass, fieldName, "J"); 1017 DASSERT(fieldId != 0); 1018 return fieldId; 1019 } 1020 1021 1022 static inline HANDLE getHPrinter(JNIEnv *env, jobject self) { 1023 jfieldID fieldId = getIdOfLongField(env, self, HPRINTER_STR); 1024 if (fieldId == (jfieldID)0) { 1025 return (HANDLE)NULL; 1026 } 1027 return (HANDLE)(env->GetLongField(self, fieldId)); 1028 } 1029 1030 1031 JNIEXPORT jboolean JNICALL 1032 Java_sun_print_Win32PrintJob_startPrintRawData(JNIEnv *env, 1033 jobject peer, 1034 jstring printer, 1035 jstring jobname) 1036 { 1037 HANDLE hPrinter; 1038 DOC_INFO_1 DocInfo; 1039 LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); 1040 if (printerName == NULL) { 1041 return false; 1042 } 1043 DASSERT(jobname != NULL); 1044 LPTSTR lpJobName = (LPTSTR)JNU_GetStringPlatformChars(env, jobname, NULL); 1045 LPTSTR jname = _tcsdup(lpJobName); 1046 JNU_ReleaseStringPlatformChars(env, jobname, lpJobName); 1047 1048 // Start by opening the printer 1049 if (!::OpenPrinter(printerName, &hPrinter, NULL)) { 1050 JNU_ReleaseStringPlatformChars(env, printer, printerName); 1051 free((LPTSTR)jname); 1052 return false; 1053 } 1054 1055 JNU_ReleaseStringPlatformChars(env, printer, printerName); 1056 1057 // Fill in the structure with info about this "document." 1058 DocInfo.pDocName = jname; 1059 DocInfo.pOutputFile = NULL; 1060 DocInfo.pDatatype = TEXT("RAW"); 1061 1062 // Inform the spooler the document is beginning. 1063 if( (::StartDocPrinter(hPrinter, 1, (LPBYTE)&DocInfo)) == 0 ) { 1064 ::ClosePrinter( hPrinter ); 1065 free((LPTSTR)jname); 1066 return false; 1067 } 1068 1069 free((LPTSTR)jname); 1070 1071 // Start a page. 1072 if( ! ::StartPagePrinter( hPrinter ) ) { 1073 ::EndDocPrinter( hPrinter ); 1074 ::ClosePrinter( hPrinter ); 1075 return false; 1076 } 1077 1078 // store handle 1079 jfieldID fieldId = getIdOfLongField(env, peer, HPRINTER_STR); 1080 if (fieldId == (jfieldID)0) { 1081 return false; 1082 } else { 1083 env->SetLongField(peer, fieldId, reinterpret_cast<jlong>(hPrinter)); 1084 return true; 1085 } 1086 } 1087 1088 1089 JNIEXPORT jboolean JNICALL 1090 Java_sun_print_Win32PrintJob_printRawData(JNIEnv *env, 1091 jobject peer, 1092 jbyteArray dataArray, 1093 jint count) 1094 { 1095 jboolean ret=true; 1096 jint dwBytesWritten; 1097 jbyte* data = NULL; 1098 1099 // retrieve handle 1100 HANDLE hPrinter = getHPrinter(env, peer); 1101 if (hPrinter == NULL) { 1102 return false; 1103 } 1104 1105 try { 1106 data=(jbyte *)env->GetPrimitiveArrayCritical(dataArray, 0); 1107 if (data == NULL) { 1108 return false; 1109 } 1110 1111 // Send the data to the printer. 1112 if( ! ::WritePrinter(hPrinter, data, count,(LPDWORD)&dwBytesWritten)) { 1113 env->ReleasePrimitiveArrayCritical(dataArray, data, 0); 1114 return false; 1115 } 1116 1117 // Check to see if correct number of bytes were written. 1118 if( dwBytesWritten != count ) { 1119 ret = false; 1120 } 1121 1122 } catch (...) { 1123 if (data != NULL) { 1124 env->ReleasePrimitiveArrayCritical(dataArray, data, 0); 1125 } 1126 JNU_ThrowInternalError(env, "Problem in Win32PrintJob_printRawData"); 1127 return false; 1128 } 1129 1130 env->ReleasePrimitiveArrayCritical(dataArray, data, 0); 1131 return ret; 1132 } 1133 1134 1135 JNIEXPORT jboolean JNICALL 1136 Java_sun_print_Win32PrintJob_endPrintRawData(JNIEnv *env, 1137 jobject peer) 1138 { 1139 // retrieve handle 1140 HANDLE hPrinter = getHPrinter(env, peer); 1141 if (hPrinter == NULL) { 1142 return false; 1143 } 1144 1145 if ((::EndPagePrinter(hPrinter) != 0) && 1146 (::EndDocPrinter(hPrinter) != 0) && 1147 (::ClosePrinter(hPrinter) != 0)) { 1148 return true; 1149 } else { 1150 return false; 1151 } 1152 } 1153 1154 } /* extern "C" */