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