src/windows/native/sun/windows/WPrinterJob.cpp

Print this page




 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     jobjectArray nameArray;
 134 
 135     try {
 136         ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
 137                        NULL, 4, NULL, 0, &cbNeeded, &cReturned);
 138         pPrinterEnum = new BYTE[cbNeeded];
 139         ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
 140                        NULL, 4, pPrinterEnum, cbNeeded, &cbNeeded,
 141                        &cReturned);
 142 
 143         if (cReturned > 0) {
 144             nameArray = env->NewObjectArray(cReturned, clazz, NULL);
 145             if (nameArray == NULL) {
 146                 throw std::bad_alloc();
 147             }
 148         } else {
 149             nameArray = NULL;
 150         }
 151 
 152 


 223     DWORD ret = WaitForSingleObject((HANDLE)chgObject, INFINITE);
 224     if (ret == WAIT_OBJECT_0) {
 225         return(FindNextPrinterChangeNotification((HANDLE)chgObject,
 226                                                   &dwChange, NULL, NULL));
 227     } else {
 228         return 0;
 229     }
 230 }
 231 
 232 
 233 JNIEXPORT jfloatArray JNICALL
 234 Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env,
 235                                                   jobject peer,
 236                                                   jstring printer,
 237                                                   jint  papersize)
 238 {
 239     TRY;
 240 
 241     LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
 242                                                             printer, NULL);



 243 
 244     jfloatArray printableArray = NULL;
 245 
 246     SAVE_CONTROLWORD
 247     HDC pdc = CreateDC(TEXT("WINSPOOL"), printerName, NULL, NULL);
 248     RESTORE_CONTROLWORD
 249     if (pdc) {
 250         HANDLE hPrinter;
 251         /* Start by opening the printer */
 252         if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
 253             JNU_ReleaseStringPlatformChars(env, printer, printerName);
 254             return printableArray;
 255         }
 256 
 257         PDEVMODE pDevMode;
 258 
 259         if (!AwtPrintControl::getDevmode(hPrinter, printerName, &pDevMode)) {
 260             /* if failure, cleanup and return failure */
 261 
 262             if (pDevMode != NULL) {
 263                 ::GlobalFree(pDevMode);
 264             }
 265 
 266             ::ClosePrinter(hPrinter);
 267             JNU_ReleaseStringPlatformChars(env, printer, printerName);
 268             return printableArray;
 269         }
 270 
 271         pDevMode->dmFields |= (DM_PAPERSIZE | DM_ORIENTATION);
 272         pDevMode->dmPaperSize = (short)papersize;
 273         pDevMode->dmOrientation = DMORIENT_PORTRAIT;
 274         ::ResetDC(pdc, pDevMode);
 275         RESTORE_CONTROLWORD
 276 
 277         int left = GetDeviceCaps(pdc, PHYSICALOFFSETX);
 278         int top = GetDeviceCaps(pdc, PHYSICALOFFSETY);
 279         int width = GetDeviceCaps(pdc, HORZRES);
 280         int height = GetDeviceCaps(pdc, VERTRES);
 281 
 282         int resx = GetDeviceCaps(pdc, LOGPIXELSX);
 283         int resy = GetDeviceCaps(pdc, LOGPIXELSY);
 284 
 285         printableArray=env->NewFloatArray(4);
 286         if (printableArray == NULL) {
 287             throw std::bad_alloc();
 288         }
 289         jboolean isCopy;
 290         jfloat *iPrintables = env->GetFloatArrayElements(printableArray,
 291                                                          &isCopy),
 292             *savePrintables = iPrintables;
 293 
 294         iPrintables[0] = (float)left/resx;
 295         iPrintables[1] = (float)top/resy;
 296         iPrintables[2] = (float)width/resx;
 297         iPrintables[3] = (float)height/resy;
 298 
 299         env->ReleaseFloatArrayElements(printableArray, savePrintables, 0);
 300 
 301         GlobalFree(pDevMode);

 302     }
 303 
 304     DeleteDC(pdc);
 305     JNU_ReleaseStringPlatformChars(env, printer, printerName);
 306 
 307     return printableArray;
 308 
 309     CATCH_BAD_ALLOC_RET(NULL);
 310 }
 311 
 312 
 313 JNIEXPORT jintArray JNICALL
 314 Java_sun_print_Win32PrintService_getAllMediaIDs(JNIEnv *env,
 315                                                 jobject peer,
 316                                                 jstring printer,
 317                                                 jstring port)
 318 {
 319   TRY;
 320 
 321   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);
 322   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 323   jintArray mediasizeArray = NULL;









 324 
 325   SAVE_CONTROLWORD
 326   int numSizes = ::DeviceCapabilities(printerName, printerPort,
 327                                       DC_PAPERS,   NULL, NULL);
 328   RESTORE_CONTROLWORD
 329 
 330   if (numSizes > 0) {
 331 
 332     mediasizeArray = env->NewIntArray(numSizes);
 333     if (mediasizeArray == NULL) {
 334       throw std::bad_alloc();







 335     }
 336 
 337     jboolean isCopy;
 338     jint *jpcIndices = env->GetIntArrayElements(mediasizeArray,
 339                                        &isCopy), *saveFormats = jpcIndices;
 340     LPTSTR papersBuf = (LPTSTR)new char[numSizes * sizeof(WORD)];
 341     if (::DeviceCapabilities(printerName, printerPort,
 342                              DC_PAPERS, papersBuf, NULL) != -1) {





 343       RESTORE_CONTROLWORD
 344       WORD *pDmPaperSize = (WORD *)papersBuf;
 345       for (int i = 0; i < numSizes; i++, pDmPaperSize++) {
 346         jpcIndices[i] = *pDmPaperSize;
 347       }
 348     }
 349     delete[] papersBuf;
 350     env->ReleaseIntArrayElements(mediasizeArray, saveFormats, 0);
 351   }
 352 
 353   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 354   JNU_ReleaseStringPlatformChars(env, port, printerPort);
 355   return mediasizeArray;

 356 
 357   CATCH_BAD_ALLOC_RET(NULL);






 358 }
 359 
 360 
 361 JNIEXPORT jintArray JNICALL
 362 Java_sun_print_Win32PrintService_getAllMediaTrays(JNIEnv *env,
 363                                                   jobject peer,
 364                                                   jstring printer,
 365                                                   jstring port)
 366 {
 367   TRY;
 368 
 369   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
 370                                                           printer, NULL);
 371   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 372 
 373   jintArray mediaTrayArray = NULL;
 374 
 375   SAVE_CONTROLWORD
 376   int nBins = ::DeviceCapabilities(printerName, printerPort,
 377                                    DC_BINS,   NULL, NULL) ;
 378   RESTORE_CONTROLWORD
 379   if (nBins > 0) {
 380     mediaTrayArray = env->NewIntArray(nBins);
 381     if (mediaTrayArray == NULL) {
 382       throw std::bad_alloc();
 383     }
 384 
 385     jboolean isCopy;
 386     jint *jpcIndices = env->GetIntArrayElements(mediaTrayArray,
 387                                            &isCopy), *saveFormats = jpcIndices;
 388 
 389     LPTSTR buf = (LPTSTR)new char[nBins * sizeof(WORD)];
 390 
 391     if (::DeviceCapabilities(printerName, printerPort,
 392                              DC_BINS, buf, NULL) != -1) {
 393       RESTORE_CONTROLWORD
 394       WORD *pBins = (WORD *)buf;
 395       for (int i = 0; i < nBins; i++) {
 396         jpcIndices[i] = *(pBins+i);
 397       }
 398     }
 399     delete[] buf;
 400     env->ReleaseIntArrayElements(mediaTrayArray, saveFormats, 0);
 401   }
 402 
 403   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 404   JNU_ReleaseStringPlatformChars(env, port, printerPort);
 405   return mediaTrayArray;
 406 
 407   CATCH_BAD_ALLOC_RET(NULL);
 408 }
 409 
 410 
 411 JNIEXPORT jintArray JNICALL
 412 Java_sun_print_Win32PrintService_getAllMediaSizes(JNIEnv *env,
 413                                                   jobject peer,
 414                                                   jstring printer,
 415                                                   jstring port)
 416 {
 417   TRY;
 418 
 419   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
 420                                                           printer, NULL);
 421   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 422 
 423   jintArray mediaArray = NULL;








 424 
 425   SAVE_CONTROLWORD
 426   int nPapers = ::DeviceCapabilities(printerName, printerPort,
 427                                       DC_PAPERSIZE,   NULL, NULL) ;
 428   RESTORE_CONTROLWORD




 429   if (nPapers > 0) {
 430     mediaArray = env->NewIntArray(nPapers*2);
 431     if (mediaArray == NULL) {
 432       throw std::bad_alloc();







 433     }
 434 
 435     jboolean isCopy;
 436     jint *jpcIndices = env->GetIntArrayElements(mediaArray,
 437                                           &isCopy), *saveFormats = jpcIndices;
 438 
 439     LPTSTR buf = (LPTSTR)new char[nPapers * sizeof(POINT)]; // array of POINTs
 440 
 441     if (::DeviceCapabilities(printerName, printerPort,
 442                              DC_PAPERSIZE, buf, NULL) != -1) {
 443 
 444       POINT *pDim = (POINT *)buf;
 445       for (int i = 0; i < nPapers; i++) {
 446         jpcIndices[i*2] = (pDim+i)->x;
 447         jpcIndices[i*2+1] = (pDim+i)->y;
 448       }
 449     }
 450     RESTORE_CONTROLWORD
 451     delete[] buf;

 452     env->ReleaseIntArrayElements(mediaArray, saveFormats, 0);



 453   }
 454 
 455   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 456   JNU_ReleaseStringPlatformChars(env, port, printerPort);



 457   return mediaArray;
 458 
 459   CATCH_BAD_ALLOC_RET(NULL);
 460 }
 461 
 462 
 463 jobjectArray getAllDCNames(JNIEnv *env, jobject peer, jstring printer,
 464                  jstring port, unsigned int dc_id, unsigned int buf_len)
 465 {
 466   TRY;
 467 
 468   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env,
 469                                                           printer, NULL);
 470   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 471 










 472   jstring utf_str;
 473   jclass cls = env->FindClass("java/lang/String");
 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 

 482     buf = (LPTSTR)new char[cReturned * buf_len * sizeof(TCHAR)];



 483     if (buf == NULL) {
 484       throw std::bad_alloc();



 485     }
 486 
 487     cReturned = ::DeviceCapabilities(printerName, printerPort,
 488                                      dc_id, buf, NULL);
 489     RESTORE_CONTROLWORD
 490 



 491     if (cReturned > 0) {


 492       names = env->NewObjectArray(cReturned, cls, NULL);
 493       if (names == NULL) {
 494         throw std::bad_alloc();


 495       }
 496 
 497       for (int i = 0; i < cReturned; i++) {
 498         utf_str = JNU_NewStringPlatform(env, buf+(buf_len*i));
 499         if (utf_str == NULL) {
 500           throw std::bad_alloc();

 501         }
 502         env->SetObjectArrayElement(names, i, utf_str);
 503         env->DeleteLocalRef(utf_str);
 504       }
 505     }
 506     delete[] buf;
 507   }
 508   return names;
 509 
 510   CATCH_BAD_ALLOC_RET(NULL);
 511 }
 512 
 513 
 514 JNIEXPORT jobjectArray JNICALL
 515 Java_sun_print_Win32PrintService_getAllMediaNames(JNIEnv *env,
 516                                                   jobject peer,
 517                                                   jstring printer,
 518                                                   jstring port)
 519 {
 520   return getAllDCNames(env, peer, printer, port, DC_PAPERNAMES, PAPERNAME_LENGTH);
 521 }
 522 
 523 
 524 JNIEXPORT jobjectArray JNICALL
 525 Java_sun_print_Win32PrintService_getAllMediaTrayNames(JNIEnv *env,
 526                                                   jobject peer,
 527                                                   jstring printer,
 528                                                   jstring port)
 529 {
 530   return getAllDCNames(env, peer, printer, port, DC_BINNAMES, TRAYNAME_LENGTH);
 531 }
 532 
 533 
 534 JNIEXPORT jint JNICALL
 535 Java_sun_print_Win32PrintService_getCopiesSupported(JNIEnv *env,
 536                                                     jobject peer,
 537                                                     jstring printer,
 538                                                     jstring port)
 539 {
 540   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);
 541   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 542 










 543   SAVE_CONTROLWORD
 544   int numCopies = ::DeviceCapabilities(printerName, printerPort,
 545                                        DC_COPIES,   NULL, NULL);
 546   RESTORE_CONTROLWORD
 547 
 548   if (numCopies == -1)
 549     return 1; // default
 550 
 551   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 552   JNU_ReleaseStringPlatformChars(env, port, printerPort);
 553 
 554   return numCopies;
 555 }
 556 
 557 
 558 /*
 559 PostScript Drivers return wrong support info for the following code:
 560 
 561  DWORD dmFields = (::DeviceCapabilities(printerName,
 562                                          NULL, DC_FIELDS,   NULL, NULL)) ;
 563 
 564   if ((dmFields & DM_YRESOLUTION) )
 565     isSupported = true;
 566 
 567 Returns not supported even if it supports resolution. Therefore, we use the
 568 function _getAllResolutions.
 569 */
 570 JNIEXPORT jintArray JNICALL
 571 Java_sun_print_Win32PrintService_getAllResolutions(JNIEnv *env,
 572                                                    jobject peer,
 573                                                    jstring printer,
 574                                                    jstring port)
 575 {
 576   TRY;
 577 
 578   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);
 579   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 580 
 581   jintArray resolutionArray = NULL;








 582 
 583   SAVE_CONTROLWORD
 584   int nResolutions = ::DeviceCapabilities(printerName, printerPort,
 585                                           DC_ENUMRESOLUTIONS, NULL, NULL);
 586   RESTORE_CONTROLWORD


 587   if (nResolutions > 0) {
 588     resolutionArray = env->NewIntArray(nResolutions*2);
 589     if (resolutionArray == NULL) {
 590       throw std::bad_alloc();







 591     }
 592 
 593     jboolean isCopy;
 594     jint *jpcIndices = env->GetIntArrayElements(resolutionArray,
 595                                           &isCopy), *saveFormats = jpcIndices;
 596 
 597     LPTSTR resBuf = (LPTSTR)new char[nResolutions * sizeof(LONG) * 2]; // pairs of long
 598 
 599     if (::DeviceCapabilities(printerName, printerPort,
 600                              DC_ENUMRESOLUTIONS, resBuf, NULL) != -1) {
 601 
 602       LONG *pResolution = (LONG *)resBuf;
 603       for (int i = 0; i < nResolutions; i++) {
 604         jpcIndices[i*2] = *pResolution++;
 605         jpcIndices[i*2+1] = *pResolution++;
 606       }
 607     }
 608     RESTORE_CONTROLWORD
 609     delete[] resBuf;

 610     env->ReleaseIntArrayElements(resolutionArray, saveFormats, 0);
 611   }


 612 
 613   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 614   JNU_ReleaseStringPlatformChars(env, printer, printerPort);
 615   return resolutionArray;
 616 
 617   CATCH_BAD_ALLOC_RET(NULL);
 618 }
 619 
 620 
 621 static BOOL IsDCPostscript( HDC hDC )
 622 {
 623     int         nEscapeCode;
 624     CHAR        szTechnology[MAX_PATH] = "";
 625 
 626     // If it supports POSTSCRIPT_PASSTHROUGH, it must be PS.
 627     nEscapeCode = POSTSCRIPT_PASSTHROUGH;
 628     if( ::ExtEscape( hDC, QUERYESCSUPPORT, sizeof(int),
 629                      (LPCSTR)&nEscapeCode, 0, NULL ) > 0 )
 630         return TRUE;
 631 
 632     // If it doesn't support GETTECHNOLOGY, we won't be able to tell.
 633     nEscapeCode = GETTECHNOLOGY;
 634     if( ::ExtEscape( hDC, QUERYESCSUPPORT, sizeof(int),
 635                      (LPCSTR)&nEscapeCode, 0, NULL ) <= 0 )
 636         return FALSE;
 637 


 655                                                 jstring printer)
 656 {
 657 
 658   if (printer == NULL) {
 659     return NULL;
 660   }
 661 
 662   jstring jPort;
 663   LPTSTR printerName = NULL, printerPort = TEXT("LPT1");
 664   LPBYTE buffer = NULL;
 665   DWORD cbBuf = 0;
 666 
 667   try {
 668     VERIFY(AwtPrintControl::FindPrinter(NULL, NULL, &cbBuf, NULL, NULL));
 669     buffer = new BYTE[cbBuf];
 670     AwtPrintControl::FindPrinter(printer, buffer, &cbBuf,
 671                                       &printerName, &printerPort);
 672   } catch (std::bad_alloc&) {
 673     delete [] buffer;
 674     JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");

 675   }
 676 
 677   if (printerPort == NULL) {
 678     printerPort = TEXT("LPT1");
 679   }
 680   jPort = JNU_NewStringPlatform(env, printerPort);
 681   delete [] buffer;
 682   return jPort;
 683 
 684 }
 685 
 686 
 687 JNIEXPORT jint JNICALL
 688 Java_sun_print_Win32PrintService_getCapabilities(JNIEnv *env,
 689                                                  jobject peer,
 690                                                  jstring printer,
 691                                                  jstring port)
 692 {
 693   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);
 694   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);











 695   // 0x1000 is a flag to indicate that getCapabilities has already been called.
 696   // 0x0001 is a flag for color support and supported is the default.
 697   jint ret = 0x1001;
 698   DWORD dmFields;
 699 
 700   // get Duplex
 701   SAVE_CONTROLWORD
 702   DWORD isDuplex = (::DeviceCapabilities(printerName, printerPort,
 703                                          DC_DUPLEX,   NULL, NULL)) ;
 704 
 705   /*
 706     Check if duplexer is installed either physically or manually thru the
 707     printer setting dialog by checking if DM_DUPLEX is set.
 708   */
 709   dmFields = (::DeviceCapabilities(printerName, printerPort,
 710                                    DC_FIELDS,   NULL, NULL)) ;
 711 
 712   if ((dmFields & DM_DUPLEX) && isDuplex) {
 713       ret |= 0x0002;
 714   }


 744 
 745   RESTORE_CONTROLWORD
 746   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 747   JNU_ReleaseStringPlatformChars(env, printer, printerPort);
 748   return ret;
 749 }
 750 
 751 
 752 #define GETDEFAULT_ERROR        -50
 753 #define NDEFAULT 9
 754 
 755 JNIEXPORT jintArray JNICALL
 756 Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env,
 757                                                     jobject peer,
 758                                                     jstring printer,
 759                                                     jstring port)
 760 {
 761   HANDLE      hPrinter;
 762   LPDEVMODE   pDevMode = NULL;
 763 
 764   TRY;
 765 
 766   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);
 767   LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL);
 768 











 769   jintArray defaultArray = env->NewIntArray(NDEFAULT);
 770   if (defaultArray == NULL) {
 771       throw std::bad_alloc();





 772   }
 773 
 774   jboolean isCopy;
 775   jint *defIndices = env->GetIntArrayElements(defaultArray,
 776                                           &isCopy), *saveFormats = defIndices;
 777 
 778   for (int i=0; i<NDEFAULT; i++) {
 779       defIndices[i]=GETDEFAULT_ERROR;
 780   }
 781 
 782   /* Start by opening the printer */
 783   if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
 784       env->ReleaseIntArrayElements(defaultArray, saveFormats, 0);
 785       JNU_ReleaseStringPlatformChars(env, printer, printerName);

 786       return defaultArray;
 787   }
 788 
 789   if (!AwtPrintControl::getDevmode(hPrinter, printerName, &pDevMode)) {
 790       /* if failure, cleanup and return failure */
 791       if (pDevMode != NULL) {
 792           ::GlobalFree(pDevMode);
 793       }
 794       ::ClosePrinter(hPrinter);
 795       env->ReleaseIntArrayElements(defaultArray, saveFormats, 0);
 796       JNU_ReleaseStringPlatformChars(env, printer, printerName);

 797       return defaultArray;
 798   }
 799 
 800   /* Have seen one driver which reports a default paper id which is not
 801    * one of their supported paper ids. If what is returned is not
 802    * a supported paper, use one of the supported sizes instead.
 803    *
 804    */
 805   if (pDevMode->dmFields & DM_PAPERSIZE) {
 806       defIndices[0] = pDevMode->dmPaperSize;
 807 
 808       SAVE_CONTROLWORD
 809 
 810       int numSizes = ::DeviceCapabilities(printerName, printerPort,
 811                                           DC_PAPERS, NULL, NULL);
 812       if (numSizes > 0) {
 813           LPTSTR papers = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, numSizes, sizeof(WORD));
 814           if (papers != NULL &&
 815               ::DeviceCapabilities(printerName, printerPort,
 816                                    DC_PAPERS, papers, NULL) != -1) {


 846   if (pDevMode->dmFields & DM_COPIES) {
 847       defIndices[4] = pDevMode->dmCopies;
 848   }
 849 
 850   if (pDevMode->dmFields & DM_ORIENTATION) {
 851       defIndices[5] = pDevMode->dmOrientation;
 852   }
 853 
 854   if (pDevMode->dmFields & DM_DUPLEX) {
 855       defIndices[6] = pDevMode->dmDuplex;
 856   }
 857 
 858   if (pDevMode->dmFields & DM_COLLATE) {
 859       defIndices[7] = pDevMode->dmCollate;
 860   }
 861 
 862   if (pDevMode->dmFields & DM_COLOR) {
 863       defIndices[8] = pDevMode->dmColor;
 864   }
 865 
 866 
 867   GlobalFree(pDevMode);
 868   ::ClosePrinter(hPrinter);
 869 
 870   env->ReleaseIntArrayElements(defaultArray, saveFormats, 0);
 871 
 872   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 873   JNU_ReleaseStringPlatformChars(env, port, printerPort);
 874 
 875   return defaultArray;
 876 
 877   CATCH_BAD_ALLOC_RET(NULL);
 878 }
 879 
 880 
 881 JNIEXPORT jint JNICALL
 882 Java_sun_print_Win32PrintService_getJobStatus(JNIEnv *env,
 883                                           jobject peer,
 884                                           jstring printer,
 885                                           jint type)
 886 {
 887     HANDLE hPrinter;
 888     DWORD  cByteNeeded;
 889     DWORD  cByteUsed;
 890     PRINTER_INFO_2 *pPrinterInfo = NULL;
 891     int ret=0;
 892 
 893     LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);



 894 
 895     // Start by opening the printer
 896     if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
 897         JNU_ReleaseStringPlatformChars(env, printer, printerName);
 898         return -1;
 899     }
 900 
 901     if (!::GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded)) {
 902         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
 903             ::ClosePrinter(hPrinter);
 904             JNU_ReleaseStringPlatformChars(env, printer, printerName);
 905             return -1;
 906         }
 907     }
 908 
 909     pPrinterInfo = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR, cByteNeeded);
 910     if (!(pPrinterInfo)) {
 911         /* failure to allocate memory */
 912         ::ClosePrinter(hPrinter);
 913         JNU_ReleaseStringPlatformChars(env, printer, printerName);


 942              PRINTER_STATUS_DOOR_OPEN)) {
 943             ret = 0;
 944         }
 945         else {
 946             ret = 1;
 947         }
 948     }
 949 
 950     ::GlobalFree(pPrinterInfo);
 951     ::ClosePrinter(hPrinter);
 952     JNU_ReleaseStringPlatformChars(env, printer, printerName);
 953     return ret;
 954 }
 955 
 956 
 957 static jfieldID getIdOfLongField(JNIEnv *env, jobject self,
 958                                  const char *fieldName) {
 959   jclass myClass = env->GetObjectClass(self);
 960   jfieldID fieldId = env->GetFieldID(myClass, fieldName, "J");
 961   DASSERT(fieldId != 0);
 962 
 963   return fieldId;
 964 }
 965 
 966 
 967 static inline HANDLE getHPrinter(JNIEnv *env, jobject self) {
 968   jfieldID fieldId = getIdOfLongField(env, self, HPRINTER_STR);



 969   return (HANDLE)(env->GetLongField(self, fieldId));
 970 }
 971 
 972 
 973 JNIEXPORT jboolean JNICALL
 974 Java_sun_print_Win32PrintJob_startPrintRawData(JNIEnv *env,
 975                                                jobject peer,
 976                                                jstring printer,
 977                                                jstring jobname)
 978 {
 979   HANDLE      hPrinter;
 980   DOC_INFO_1  DocInfo;
 981   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);



 982   DASSERT(jobname != NULL);
 983   LPTSTR lpJobName = (LPTSTR)JNU_GetStringPlatformChars(env, jobname, NULL);
 984   LPTSTR jname = _tcsdup(lpJobName);
 985   JNU_ReleaseStringPlatformChars(env, jobname, lpJobName);
 986 
 987   // Start by opening the printer
 988   if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
 989     JNU_ReleaseStringPlatformChars(env, printer, printerName);
 990     free((LPTSTR)jname);
 991     return false;
 992   }
 993 
 994   JNU_ReleaseStringPlatformChars(env, printer, printerName);
 995 
 996   // Fill in the structure with info about this "document."
 997   DocInfo.pDocName = jname;
 998   DocInfo.pOutputFile = NULL;
 999   DocInfo.pDatatype = TEXT("RAW");
1000 
1001   // Inform the spooler the document is beginning.
1002   if( (::StartDocPrinter(hPrinter, 1, (LPBYTE)&DocInfo)) == 0 ) {
1003     ::ClosePrinter( hPrinter );
1004     free((LPTSTR)jname);
1005     return false;
1006   }
1007 
1008   free((LPTSTR)jname);
1009 
1010   // Start a page.
1011   if( ! ::StartPagePrinter( hPrinter ) ) {
1012     ::EndDocPrinter( hPrinter );
1013     ::ClosePrinter( hPrinter );
1014     return false;
1015   }
1016 
1017   // store handle
1018   jfieldID fieldId = getIdOfLongField(env, peer, HPRINTER_STR);



1019   env->SetLongField(peer, fieldId, reinterpret_cast<jlong>(hPrinter));
1020   return true;

1021 }
1022 
1023 
1024 JNIEXPORT jboolean JNICALL
1025 Java_sun_print_Win32PrintJob_printRawData(JNIEnv *env,
1026                                           jobject peer,
1027                                           jbyteArray dataArray,
1028                                           jint count)
1029 {
1030   jboolean  ret=true;
1031   jint      dwBytesWritten;
1032   jbyte*    data = NULL;
1033 
1034   // retrieve handle
1035   HANDLE    hPrinter = getHPrinter(env, peer);
1036   if (hPrinter == NULL) {
1037     return false;
1038   }
1039 
1040   try {
1041     data=(jbyte *)env->GetPrimitiveArrayCritical(dataArray, 0);



1042 
1043     // Send the data to the printer.
1044     if( ! ::WritePrinter(hPrinter, data, count,(LPDWORD)&dwBytesWritten)) {
1045       env->ReleasePrimitiveArrayCritical(dataArray, data, 0);
1046       return false;
1047     }
1048 
1049     // Check to see if correct number of bytes were written.
1050     if( dwBytesWritten != count ) {
1051       ret = false;
1052     }
1053 
1054   } catch (...) {
1055     if (data != NULL) {
1056       env->ReleasePrimitiveArrayCritical(dataArray, data, 0);
1057     }
1058     JNU_ThrowInternalError(env, "Problem in Win32PrintJob_printRawData");
1059     return false;
1060   }
1061 




 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 


 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 


 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   }


 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) {


 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);


1005              PRINTER_STATUS_DOOR_OPEN)) {
1006             ret = 0;
1007         }
1008         else {
1009             ret = 1;
1010         }
1011     }
1012 
1013     ::GlobalFree(pPrinterInfo);
1014     ::ClosePrinter(hPrinter);
1015     JNU_ReleaseStringPlatformChars(env, printer, printerName);
1016     return ret;
1017 }
1018 
1019 
1020 static jfieldID getIdOfLongField(JNIEnv *env, jobject self,
1021                                  const char *fieldName) {
1022   jclass myClass = env->GetObjectClass(self);
1023   jfieldID fieldId = env->GetFieldID(myClass, fieldName, "J");
1024   DASSERT(fieldId != 0);

1025   return fieldId;
1026 }
1027 
1028 
1029 static inline HANDLE getHPrinter(JNIEnv *env, jobject self) {
1030   jfieldID fieldId = getIdOfLongField(env, self, HPRINTER_STR);
1031   if (fieldId == (jfieldID)0) {
1032       return (HANDLE)NULL;
1033   }
1034   return (HANDLE)(env->GetLongField(self, fieldId));
1035 }
1036 
1037 
1038 JNIEXPORT jboolean JNICALL
1039 Java_sun_print_Win32PrintJob_startPrintRawData(JNIEnv *env,
1040                                                jobject peer,
1041                                                jstring printer,
1042                                                jstring jobname)
1043 {
1044   HANDLE      hPrinter;
1045   DOC_INFO_1  DocInfo;
1046   LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL);
1047   if (printerName == NULL) {
1048       return false;
1049   }
1050   DASSERT(jobname != NULL);
1051   LPTSTR lpJobName = (LPTSTR)JNU_GetStringPlatformChars(env, jobname, NULL);
1052   LPTSTR jname = _tcsdup(lpJobName);
1053   JNU_ReleaseStringPlatformChars(env, jobname, lpJobName);
1054 
1055   // Start by opening the printer
1056   if (!::OpenPrinter(printerName, &hPrinter, NULL)) {
1057     JNU_ReleaseStringPlatformChars(env, printer, printerName);
1058     free((LPTSTR)jname);
1059     return false;
1060   }
1061 
1062   JNU_ReleaseStringPlatformChars(env, printer, printerName);
1063 
1064   // Fill in the structure with info about this "document."
1065   DocInfo.pDocName = jname;
1066   DocInfo.pOutputFile = NULL;
1067   DocInfo.pDatatype = TEXT("RAW");
1068 
1069   // Inform the spooler the document is beginning.
1070   if( (::StartDocPrinter(hPrinter, 1, (LPBYTE)&DocInfo)) == 0 ) {
1071     ::ClosePrinter( hPrinter );
1072     free((LPTSTR)jname);
1073     return false;
1074   }
1075 
1076   free((LPTSTR)jname);
1077 
1078   // Start a page.
1079   if( ! ::StartPagePrinter( hPrinter ) ) {
1080     ::EndDocPrinter( hPrinter );
1081     ::ClosePrinter( hPrinter );
1082     return false;
1083   }
1084 
1085   // store handle
1086   jfieldID fieldId = getIdOfLongField(env, peer, HPRINTER_STR);
1087   if (fieldId == (jfieldID)0) {
1088       return false;
1089   } else {
1090       env->SetLongField(peer, fieldId, reinterpret_cast<jlong>(hPrinter));
1091       return true;
1092   }
1093 }
1094 
1095 
1096 JNIEXPORT jboolean JNICALL
1097 Java_sun_print_Win32PrintJob_printRawData(JNIEnv *env,
1098                                           jobject peer,
1099                                           jbyteArray dataArray,
1100                                           jint count)
1101 {
1102   jboolean  ret=true;
1103   jint      dwBytesWritten;
1104   jbyte*    data = NULL;
1105 
1106   // retrieve handle
1107   HANDLE    hPrinter = getHPrinter(env, peer);
1108   if (hPrinter == NULL) {
1109     return false;
1110   }
1111 
1112   try {
1113     data=(jbyte *)env->GetPrimitiveArrayCritical(dataArray, 0);
1114     if (data == NULL) {
1115         return false;
1116     }
1117 
1118     // Send the data to the printer.
1119     if( ! ::WritePrinter(hPrinter, data, count,(LPDWORD)&dwBytesWritten)) {
1120       env->ReleasePrimitiveArrayCritical(dataArray, data, 0);
1121       return false;
1122     }
1123 
1124     // Check to see if correct number of bytes were written.
1125     if( dwBytesWritten != count ) {
1126       ret = false;
1127     }
1128 
1129   } catch (...) {
1130     if (data != NULL) {
1131       env->ReleasePrimitiveArrayCritical(dataArray, data, 0);
1132     }
1133     JNU_ThrowInternalError(env, "Problem in Win32PrintJob_printRawData");
1134     return false;
1135   }
1136