44 super(new XCreateWindowParams(new Object[] { 45 PARENT, parent, 46 DELAYED, Boolean.TRUE})); 47 } 48 49 void instantPreInit(XCreateWindowParams params) { 50 super.instantPreInit(params); 51 this.parent = (XDecoratedPeer)params.get(PARENT); 52 } 53 54 /** 55 * @return array of XIconsSize structures, caller must free this array after use. 56 */ 57 private XIconSize[] getIconSizes() { 58 XToolkit.awtLock(); 59 try { 60 AwtGraphicsConfigData adata = parent.getGraphicsConfigurationData(); 61 final long screen = adata.get_awt_visInfo().get_screen(); 62 final long display = XToolkit.getDisplay(); 63 64 if (log.isLoggable(PlatformLogger.FINEST)) { 65 log.finest(adata.toString()); 66 } 67 68 long status = 69 XlibWrapper.XGetIconSizes(display, XToolkit.getDefaultRootWindow(), 70 XlibWrapper.larg1, XlibWrapper.iarg1); 71 if (status == 0) { 72 return null; 73 } 74 int count = Native.getInt(XlibWrapper.iarg1); 75 long sizes_ptr = Native.getLong(XlibWrapper.larg1); // XIconSize* 76 if (log.isLoggable(PlatformLogger.FINEST)) { 77 log.finest("count = {1}, sizes_ptr = {0}", Long.valueOf(sizes_ptr), Integer.valueOf(count)); 78 } 79 XIconSize[] res = new XIconSize[count]; 80 for (int i = 0; i < count; i++, sizes_ptr += XIconSize.getSize()) { 81 res[i] = new XIconSize(sizes_ptr); 82 if (log.isLoggable(PlatformLogger.FINEST)) { 83 log.finest("sizes_ptr[{1}] = {0}", res[i], Integer.valueOf(i)); 84 } 85 } 86 return res; 87 } finally { 88 XToolkit.awtUnlock(); 89 } 90 } 91 92 private Dimension calcIconSize(int widthHint, int heightHint) { 93 if (XWM.getWMID() == XWM.ICE_WM) { 94 // ICE_WM has a bug - it only displays icons of the size 95 // 16x16, while reporting 32x32 in its size list 96 log.finest("Returning ICE_WM icon size: 16x16"); 97 return new Dimension(16, 16); 98 } 99 100 XIconSize[] sizeList = getIconSizes(); 101 if (log.isLoggable(PlatformLogger.FINEST)) { 102 log.finest("Icon sizes: {0}", (Object[]) sizeList); 103 } 104 if (sizeList == null) { 105 // No icon sizes so we simply fall back to 16x16 106 return new Dimension(16, 16); 107 } 108 boolean found = false; 109 int dist = 0xffffffff, newDist, diff = 0, closestHeight, closestWidth; 110 int saveWidth = 0, saveHeight = 0; 111 for (int i = 0; i < sizeList.length; i++) { 112 if (widthHint >= sizeList[i].get_min_width() && 113 widthHint <= sizeList[i].get_max_width() && 114 heightHint >= sizeList[i].get_min_height() && 115 heightHint <= sizeList[i].get_max_height()) { 116 found = true; 117 if ((((widthHint-sizeList[i].get_min_width()) 118 % sizeList[i].get_width_inc()) == 0) && 119 (((heightHint-sizeList[i].get_min_height()) 120 % sizeList[i].get_height_inc()) ==0)) { 121 /* Found an exact match */ 130 } else { 131 diff = diff%sizeList[i].get_width_inc(); 132 closestWidth = widthHint - diff; 133 } 134 diff = heightHint - sizeList[i].get_min_height(); 135 if (diff == 0) { 136 closestHeight = heightHint; 137 } else { 138 diff = diff%sizeList[i].get_height_inc(); 139 closestHeight = heightHint - diff; 140 } 141 newDist = closestWidth*closestWidth + 142 closestHeight*closestHeight; 143 if (dist > newDist) { 144 saveWidth = closestWidth; 145 saveHeight = closestHeight; 146 dist = newDist; 147 } 148 } 149 } 150 if (log.isLoggable(PlatformLogger.FINEST)) { 151 log.finest("found=" + found); 152 } 153 if (!found) { 154 if (log.isLoggable(PlatformLogger.FINEST)) { 155 log.finest("widthHint=" + widthHint + ", heightHint=" + heightHint 156 + ", saveWidth=" + saveWidth + ", saveHeight=" + saveHeight 157 + ", max_width=" + sizeList[0].get_max_width() 158 + ", max_height=" + sizeList[0].get_max_height() 159 + ", min_width=" + sizeList[0].get_min_width() 160 + ", min_height=" + sizeList[0].get_min_height()); 161 } 162 163 if (widthHint > sizeList[0].get_max_width() || 164 heightHint > sizeList[0].get_max_height()) 165 { 166 // Icon image too big 167 /* determine which way to scale */ 168 int wdiff = widthHint - sizeList[0].get_max_width(); 169 int hdiff = heightHint - sizeList[0].get_max_height(); 170 if (log.isLoggable(PlatformLogger.FINEST)) { 171 log.finest("wdiff=" + wdiff + ", hdiff=" + hdiff); 172 } 173 if (wdiff >= hdiff) { /* need to scale width more */ 174 saveWidth = sizeList[0].get_max_width(); 175 saveHeight = 176 (int)(((double)sizeList[0].get_max_width()/widthHint) * heightHint); 177 } else { 178 saveWidth = 179 (int)(((double)sizeList[0].get_max_height()/heightHint) * widthHint); 180 saveHeight = sizeList[0].get_max_height(); 181 } 182 } else if (widthHint < sizeList[0].get_min_width() || 183 heightHint < sizeList[0].get_min_height()) 184 { 185 // Icon image too small 186 saveWidth = (sizeList[0].get_min_width()+sizeList[0].get_max_width())/2; 187 saveHeight = (sizeList[0].get_min_height()+sizeList[0].get_max_height())/2; 188 } else { 189 // Icon image fits within right size 190 saveWidth = widthHint; 191 saveHeight = widthHint; 192 } 193 } 194 195 XToolkit.awtLock(); 196 try { 197 XlibWrapper.XFree(sizeList[0].pData); 198 } finally { 199 XToolkit.awtUnlock(); 200 } 201 202 if (log.isLoggable(PlatformLogger.FINEST)) { 203 log.finest("return " + saveWidth + "x" + saveHeight); 204 } 205 return new Dimension(saveWidth, saveHeight); 206 } 207 208 /** 209 * @return preffered icon size calculated from specific icon 210 */ 211 Dimension getIconSize(int widthHint, int heightHint) { 212 if (size == null) { 213 size = calcIconSize(widthHint, heightHint); 214 } 215 return size; 216 } 217 218 /** 219 * This function replaces iconPixmap handle with new image 220 * It does not replace window's hints, so it should be 221 * called only from setIconImage() 222 */ 409 void setIconImages(java.util.List<XIconInfo> icons) { 410 if (icons == null || icons.size() == 0) return; 411 412 int minDiff = Integer.MAX_VALUE; 413 Image min = null; 414 for (XIconInfo iconInfo : icons) { 415 if (iconInfo.isValid()) { 416 Image image = iconInfo.getImage(); 417 Dimension dim = calcIconSize(image.getWidth(null), image.getHeight(null)); 418 int widthDiff = Math.abs(dim.width - image.getWidth(null)); 419 int heightDiff = Math.abs(image.getHeight(null) - dim.height); 420 421 // "=" below allows to select the best matching icon 422 if (minDiff >= (widthDiff + heightDiff)) { 423 minDiff = (widthDiff + heightDiff); 424 min = image; 425 } 426 } 427 } 428 if (min != null) { 429 if (log.isLoggable(PlatformLogger.FINER)) { 430 log.finer("Icon: {0}x{1}", min.getWidth(null), min.getHeight(null)); 431 } 432 setIconImage(min); 433 } 434 } 435 436 void setIconImage(Image img) { 437 if (img == null) { 438 //if image is null, reset to default image 439 replaceImage(null); 440 replaceMask(null); 441 } else { 442 //get image size 443 int width; 444 int height; 445 if (img instanceof ToolkitImage) { 446 ImageRepresentation ir = ((ToolkitImage)img).getImageRep(); 447 ir.reconstruct(ImageObserver.ALLBITS); 448 width = ir.getWidth(); 449 height = ir.getHeight(); 450 } 451 else { 452 width = img.getWidth(null); 453 height = img.getHeight(null); 454 } 455 Dimension iconSize = getIconSize(width, height); 456 if (iconSize != null) { 457 if (log.isLoggable(PlatformLogger.FINEST)) { 458 log.finest("Icon size: {0}", iconSize); 459 } 460 iconWidth = iconSize.width; 461 iconHeight = iconSize.height; 462 } else { 463 log.finest("Error calculating image size"); 464 iconWidth = 0; 465 iconHeight = 0; 466 } 467 replaceImage(img); 468 replaceMask(img); 469 } 470 //create icon window and set XWMHints 471 XToolkit.awtLock(); 472 try { 473 AwtGraphicsConfigData adata = parent.getGraphicsConfigurationData(); 474 awtImageData awtImage = adata.get_awtImage(0); 475 XVisualInfo visInfo = adata.get_awt_visInfo(); 476 XWMHints hints = parent.getWMHints(); 477 window = hints.get_icon_window(); | 44 super(new XCreateWindowParams(new Object[] { 45 PARENT, parent, 46 DELAYED, Boolean.TRUE})); 47 } 48 49 void instantPreInit(XCreateWindowParams params) { 50 super.instantPreInit(params); 51 this.parent = (XDecoratedPeer)params.get(PARENT); 52 } 53 54 /** 55 * @return array of XIconsSize structures, caller must free this array after use. 56 */ 57 private XIconSize[] getIconSizes() { 58 XToolkit.awtLock(); 59 try { 60 AwtGraphicsConfigData adata = parent.getGraphicsConfigurationData(); 61 final long screen = adata.get_awt_visInfo().get_screen(); 62 final long display = XToolkit.getDisplay(); 63 64 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 65 log.finest(adata.toString()); 66 } 67 68 long status = 69 XlibWrapper.XGetIconSizes(display, XToolkit.getDefaultRootWindow(), 70 XlibWrapper.larg1, XlibWrapper.iarg1); 71 if (status == 0) { 72 return null; 73 } 74 int count = Native.getInt(XlibWrapper.iarg1); 75 long sizes_ptr = Native.getLong(XlibWrapper.larg1); // XIconSize* 76 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 77 log.finest("count = {1}, sizes_ptr = {0}", Long.valueOf(sizes_ptr), Integer.valueOf(count)); 78 } 79 XIconSize[] res = new XIconSize[count]; 80 for (int i = 0; i < count; i++, sizes_ptr += XIconSize.getSize()) { 81 res[i] = new XIconSize(sizes_ptr); 82 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 83 log.finest("sizes_ptr[{1}] = {0}", res[i], Integer.valueOf(i)); 84 } 85 } 86 return res; 87 } finally { 88 XToolkit.awtUnlock(); 89 } 90 } 91 92 private Dimension calcIconSize(int widthHint, int heightHint) { 93 if (XWM.getWMID() == XWM.ICE_WM) { 94 // ICE_WM has a bug - it only displays icons of the size 95 // 16x16, while reporting 32x32 in its size list 96 log.finest("Returning ICE_WM icon size: 16x16"); 97 return new Dimension(16, 16); 98 } 99 100 XIconSize[] sizeList = getIconSizes(); 101 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 102 log.finest("Icon sizes: {0}", (Object[]) sizeList); 103 } 104 if (sizeList == null) { 105 // No icon sizes so we simply fall back to 16x16 106 return new Dimension(16, 16); 107 } 108 boolean found = false; 109 int dist = 0xffffffff, newDist, diff = 0, closestHeight, closestWidth; 110 int saveWidth = 0, saveHeight = 0; 111 for (int i = 0; i < sizeList.length; i++) { 112 if (widthHint >= sizeList[i].get_min_width() && 113 widthHint <= sizeList[i].get_max_width() && 114 heightHint >= sizeList[i].get_min_height() && 115 heightHint <= sizeList[i].get_max_height()) { 116 found = true; 117 if ((((widthHint-sizeList[i].get_min_width()) 118 % sizeList[i].get_width_inc()) == 0) && 119 (((heightHint-sizeList[i].get_min_height()) 120 % sizeList[i].get_height_inc()) ==0)) { 121 /* Found an exact match */ 130 } else { 131 diff = diff%sizeList[i].get_width_inc(); 132 closestWidth = widthHint - diff; 133 } 134 diff = heightHint - sizeList[i].get_min_height(); 135 if (diff == 0) { 136 closestHeight = heightHint; 137 } else { 138 diff = diff%sizeList[i].get_height_inc(); 139 closestHeight = heightHint - diff; 140 } 141 newDist = closestWidth*closestWidth + 142 closestHeight*closestHeight; 143 if (dist > newDist) { 144 saveWidth = closestWidth; 145 saveHeight = closestHeight; 146 dist = newDist; 147 } 148 } 149 } 150 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 151 log.finest("found=" + found); 152 } 153 if (!found) { 154 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 155 log.finest("widthHint=" + widthHint + ", heightHint=" + heightHint 156 + ", saveWidth=" + saveWidth + ", saveHeight=" + saveHeight 157 + ", max_width=" + sizeList[0].get_max_width() 158 + ", max_height=" + sizeList[0].get_max_height() 159 + ", min_width=" + sizeList[0].get_min_width() 160 + ", min_height=" + sizeList[0].get_min_height()); 161 } 162 163 if (widthHint > sizeList[0].get_max_width() || 164 heightHint > sizeList[0].get_max_height()) 165 { 166 // Icon image too big 167 /* determine which way to scale */ 168 int wdiff = widthHint - sizeList[0].get_max_width(); 169 int hdiff = heightHint - sizeList[0].get_max_height(); 170 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 171 log.finest("wdiff=" + wdiff + ", hdiff=" + hdiff); 172 } 173 if (wdiff >= hdiff) { /* need to scale width more */ 174 saveWidth = sizeList[0].get_max_width(); 175 saveHeight = 176 (int)(((double)sizeList[0].get_max_width()/widthHint) * heightHint); 177 } else { 178 saveWidth = 179 (int)(((double)sizeList[0].get_max_height()/heightHint) * widthHint); 180 saveHeight = sizeList[0].get_max_height(); 181 } 182 } else if (widthHint < sizeList[0].get_min_width() || 183 heightHint < sizeList[0].get_min_height()) 184 { 185 // Icon image too small 186 saveWidth = (sizeList[0].get_min_width()+sizeList[0].get_max_width())/2; 187 saveHeight = (sizeList[0].get_min_height()+sizeList[0].get_max_height())/2; 188 } else { 189 // Icon image fits within right size 190 saveWidth = widthHint; 191 saveHeight = widthHint; 192 } 193 } 194 195 XToolkit.awtLock(); 196 try { 197 XlibWrapper.XFree(sizeList[0].pData); 198 } finally { 199 XToolkit.awtUnlock(); 200 } 201 202 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 203 log.finest("return " + saveWidth + "x" + saveHeight); 204 } 205 return new Dimension(saveWidth, saveHeight); 206 } 207 208 /** 209 * @return preffered icon size calculated from specific icon 210 */ 211 Dimension getIconSize(int widthHint, int heightHint) { 212 if (size == null) { 213 size = calcIconSize(widthHint, heightHint); 214 } 215 return size; 216 } 217 218 /** 219 * This function replaces iconPixmap handle with new image 220 * It does not replace window's hints, so it should be 221 * called only from setIconImage() 222 */ 409 void setIconImages(java.util.List<XIconInfo> icons) { 410 if (icons == null || icons.size() == 0) return; 411 412 int minDiff = Integer.MAX_VALUE; 413 Image min = null; 414 for (XIconInfo iconInfo : icons) { 415 if (iconInfo.isValid()) { 416 Image image = iconInfo.getImage(); 417 Dimension dim = calcIconSize(image.getWidth(null), image.getHeight(null)); 418 int widthDiff = Math.abs(dim.width - image.getWidth(null)); 419 int heightDiff = Math.abs(image.getHeight(null) - dim.height); 420 421 // "=" below allows to select the best matching icon 422 if (minDiff >= (widthDiff + heightDiff)) { 423 minDiff = (widthDiff + heightDiff); 424 min = image; 425 } 426 } 427 } 428 if (min != null) { 429 if (log.isLoggable(PlatformLogger.Level.FINER)) { 430 log.finer("Icon: {0}x{1}", min.getWidth(null), min.getHeight(null)); 431 } 432 setIconImage(min); 433 } 434 } 435 436 void setIconImage(Image img) { 437 if (img == null) { 438 //if image is null, reset to default image 439 replaceImage(null); 440 replaceMask(null); 441 } else { 442 //get image size 443 int width; 444 int height; 445 if (img instanceof ToolkitImage) { 446 ImageRepresentation ir = ((ToolkitImage)img).getImageRep(); 447 ir.reconstruct(ImageObserver.ALLBITS); 448 width = ir.getWidth(); 449 height = ir.getHeight(); 450 } 451 else { 452 width = img.getWidth(null); 453 height = img.getHeight(null); 454 } 455 Dimension iconSize = getIconSize(width, height); 456 if (iconSize != null) { 457 if (log.isLoggable(PlatformLogger.Level.FINEST)) { 458 log.finest("Icon size: {0}", iconSize); 459 } 460 iconWidth = iconSize.width; 461 iconHeight = iconSize.height; 462 } else { 463 log.finest("Error calculating image size"); 464 iconWidth = 0; 465 iconHeight = 0; 466 } 467 replaceImage(img); 468 replaceMask(img); 469 } 470 //create icon window and set XWMHints 471 XToolkit.awtLock(); 472 try { 473 AwtGraphicsConfigData adata = parent.getGraphicsConfigurationData(); 474 awtImageData awtImage = adata.get_awtImage(0); 475 XVisualInfo visInfo = adata.get_awt_visInfo(); 476 XWMHints hints = parent.getWMHints(); 477 window = hints.get_icon_window(); |