< prev index next >
src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java
Print this page
*** 94,108 ****
// There's no capability for Win98 to refresh printers.
// See "OpenPrinter" for more info.
if (osName != null && osName.startsWith("Windows 98")) {
return;
}
! // start the printer listener thread
Thread thr = new Thread(null, new PrinterChangeListener(),
"PrinterListener", 0, false);
thr.setDaemon(true);
thr.start();
} /* else condition ought to never happen! */
}
/* Want the PrintService which is default print service to have
* equality of reference with the equivalent in list of print services
--- 94,114 ----
// There's no capability for Win98 to refresh printers.
// See "OpenPrinter" for more info.
if (osName != null && osName.startsWith("Windows 98")) {
return;
}
! // start the local printer listener thread
Thread thr = new Thread(null, new PrinterChangeListener(),
"PrinterListener", 0, false);
thr.setDaemon(true);
thr.start();
+
+ // start the remote printer listener thread
+ Thread remThr = new Thread(null, new RemotePrinterChangeListener(),
+ "RemotePrinterListener", 0, false);
+ remThr.setDaemon(true);
+ remThr.start();
} /* else condition ought to never happen! */
}
/* Want the PrintService which is default print service to have
* equality of reference with the equivalent in list of print services
*** 314,324 ****
if (defaultPrintService == null) {
defaultPrintService = new Win32PrintService(defaultPrinter);
}
return defaultPrintService;
}
-
class PrinterChangeListener implements Runnable {
long chgObj;
PrinterChangeListener() {
chgObj = notifyFirstPrinterChange(null);
}
--- 320,329 ----
*** 341,351 ****
--- 346,422 ----
}
}
}
}
+ /* Windows provides *PrinterChangeNotification* functions that provides
+ information about printer status changes of the local printers but not
+ network printers.
+ Alternatively, Windows provides a way thro' which one can get the
+ network printer status changes by using WMI, RegistryKeyChange combination,
+ which is a slightly complex mechanism.
+ The Windows WMI offers an async and sync method to read thro' registry
+ via the WQL query. The async method is considered dangerous as it leaves
+ open a channel until we close it. But the async method has the advantage of
+ being notified of a change in registry by calling callback without polling for it.
+ The sync method uses the polling mechanism to notify.
+ RegistryValueChange cannot be used in combination with WMI to get registry
+ value change notification because of an error that may be generated because the
+ scope of the query would be too big to handle(at times).
+ Hence an alternative mechanism is choosen via the EnumPrinters by polling for the
+ count of printer status changes(add\remove) and based on it update the printers
+ list.
+ */
+ class RemotePrinterChangeListener implements Runnable {
+ private static final long DELAY = 1000 * 60 * 4; // 4 min pooling
+ private String[] prevRemotePrinters;
+
+ RemotePrinterChangeListener() {
+ prevRemotePrinters = GetRemotePrintersNames();
+ }
+
+ boolean doCompare(String[] str1, String[] str2) {
+ if(str1.length != str2.length) {
+ return true;
+ } else {
+ for(int i = 0;i < str1.length;i++) {
+ for(int j = 0;j < str2.length;j++) {
+ if(!str1[i].equals(str2[j])) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void run() {
+ while(true) {
+ String[] currentRemotePrinters = GetRemotePrintersNames();
+ if(doCompare(prevRemotePrinters, currentRemotePrinters)) {
+
+ // updated the printers data
+ // printers list now contains both local and network printer data
+ refreshServices();
+
+ // store the current data for next comparison
+ prevRemotePrinters = currentRemotePrinters;
+ }
+
+ try {
+ Thread.sleep(DELAY);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+ }
+
private native String getDefaultPrinterName();
private native String[] getAllPrinterNames();
private native long notifyFirstPrinterChange(String printer);
private native void notifyClosePrinterChange(long chgObj);
private native int notifyPrinterChange(long chgObj);
+ private native String[] GetRemotePrintersNames();
}
< prev index next >