mirror of https://github.com/sipwise/jitsi.git
parent
7f08c0d239
commit
5c24dad320
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright @ 2015 Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/package net.java.sip.communicator.impl.osdependent.windows;
|
||||
|
||||
import java.awt.image.*;
|
||||
import java.nio.*;
|
||||
|
||||
import com.sun.jna.*;
|
||||
import com.sun.jna.platform.win32.*;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
|
||||
/**
|
||||
* Image conversion utilities.
|
||||
*
|
||||
* Parts of this code are based on AppIcon.java from IntelliJ community.
|
||||
* Licensed under Apache 2.0, Copyright 2000-2016 JetBrains s.r.o.
|
||||
*/
|
||||
public class ImageConverter
|
||||
{
|
||||
/**
|
||||
* Converts the <tt>BufferedImage</tt> to an ICONDIR structure.
|
||||
* @param src The source image to convert
|
||||
* @return an ICONDIR structure with the data of the passed source image
|
||||
*/
|
||||
public static byte[] writeTransparentIcoImage(BufferedImage src)
|
||||
{
|
||||
int bitCount = 32;
|
||||
|
||||
int scanline_size = (bitCount * src.getWidth() + 7) / 8;
|
||||
if ((scanline_size % 4) != 0)
|
||||
scanline_size += 4 - (scanline_size % 4); // pad scanline to 4 byte
|
||||
// size.
|
||||
int t_scanline_size = (src.getWidth() + 7) / 8;
|
||||
if ((t_scanline_size % 4) != 0)
|
||||
t_scanline_size += 4 - (t_scanline_size % 4); // pad scanline to 4
|
||||
// byte size.
|
||||
int imageSize = 40 + src.getHeight() * scanline_size
|
||||
+ src.getHeight() * t_scanline_size;
|
||||
|
||||
// sizeof(ICONDIR)
|
||||
// + sizeof(ICONDIRENTRY)
|
||||
// + (sizeof(BITMAPINFOHEADER)+data)
|
||||
ByteBuffer bos = ByteBuffer.allocate(6 + 16 + imageSize);
|
||||
bos.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// ICONDIR
|
||||
bos.putShort((short) 0); // reserved
|
||||
bos.putShort((short) 1); // 1=ICO, 2=CUR
|
||||
bos.putShort((short) 1); // count
|
||||
|
||||
// ICONDIRENTRY
|
||||
int iconDirEntryWidth = src.getWidth();
|
||||
int iconDirEntryHeight = src.getHeight();
|
||||
if (iconDirEntryWidth > 255 || iconDirEntryHeight > 255)
|
||||
{
|
||||
iconDirEntryWidth = 0;
|
||||
iconDirEntryHeight = 0;
|
||||
}
|
||||
bos.put((byte) iconDirEntryWidth);
|
||||
bos.put((byte) iconDirEntryHeight);
|
||||
bos.put((byte) 0);
|
||||
bos.put((byte) 0); // reserved
|
||||
bos.putShort((short) 1); // color planes
|
||||
bos.putShort((short) bitCount);
|
||||
bos.putInt(imageSize);
|
||||
bos.putInt(22); // image offset
|
||||
|
||||
// BITMAPINFOHEADER
|
||||
bos.putInt(40); // size
|
||||
bos.putInt(src.getWidth());
|
||||
bos.putInt(2 * src.getHeight());
|
||||
bos.putShort((short) 1); // planes
|
||||
bos.putShort((short) bitCount);
|
||||
bos.putInt(0); // compression
|
||||
bos.putInt(0); // image size
|
||||
bos.putInt(0); // x pixels per meter
|
||||
bos.putInt(0); // y pixels per meter
|
||||
bos.putInt(0); // colors used, 0 = (1 << bitCount) (ignored)
|
||||
bos.putInt(0); // colors important
|
||||
|
||||
int bit_cache = 0;
|
||||
int bits_in_cache = 0;
|
||||
int row_padding = scanline_size - (bitCount * src.getWidth() + 7) / 8;
|
||||
for (int y = src.getHeight() - 1; y >= 0; y--)
|
||||
{
|
||||
for (int x = 0; x < src.getWidth(); x++)
|
||||
{
|
||||
int argb = src.getRGB(x, y);
|
||||
|
||||
bos.put((byte) (0xff & argb));
|
||||
bos.put((byte) (0xff & (argb >> 8)));
|
||||
bos.put((byte) (0xff & (argb >> 16)));
|
||||
bos.put((byte) (0xff & (argb >> 24)));
|
||||
}
|
||||
|
||||
for (int x = 0; x < row_padding; x++)
|
||||
bos.put((byte) 0);
|
||||
}
|
||||
|
||||
int t_row_padding = t_scanline_size - (src.getWidth() + 7) / 8;
|
||||
for (int y = src.getHeight() - 1; y >= 0; y--)
|
||||
{
|
||||
for (int x = 0; x < src.getWidth(); x++)
|
||||
{
|
||||
int argb = src.getRGB(x, y);
|
||||
int alpha = 0xff & (argb >> 24);
|
||||
bit_cache <<= 1;
|
||||
if (alpha == 0)
|
||||
bit_cache |= 1;
|
||||
bits_in_cache++;
|
||||
if (bits_in_cache >= 8)
|
||||
{
|
||||
bos.put((byte) (0xff & bit_cache));
|
||||
bit_cache = 0;
|
||||
bits_in_cache = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits_in_cache > 0)
|
||||
{
|
||||
bit_cache <<= (8 - bits_in_cache);
|
||||
bos.put((byte) (0xff & bit_cache));
|
||||
bit_cache = 0;
|
||||
bits_in_cache = 0;
|
||||
}
|
||||
|
||||
for (int x = 0; x < t_row_padding; x++)
|
||||
bos.put((byte) 0);
|
||||
}
|
||||
|
||||
byte[] result = new byte[bos.position()];
|
||||
System.arraycopy(bos.array(), 0, result, 0, bos.position());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an ICONDIR ico to an HICON handle
|
||||
* @param ico the image data
|
||||
* @return A Windows HICON handle
|
||||
*/
|
||||
public static HICON createIcon(byte[] ico)
|
||||
{
|
||||
Memory buffer = new Memory(ico.length);
|
||||
buffer.write(0, ico, 0, ico.length);
|
||||
int nSize = 100;
|
||||
int offset = User32Ex.INSTANCE.LookupIconIdFromDirectoryEx(buffer, true,
|
||||
nSize, nSize, 0);
|
||||
if (offset != 0)
|
||||
{
|
||||
return User32Ex.INSTANCE.CreateIconFromResourceEx(
|
||||
buffer.share(offset), new WinDef.DWORD(0), true,
|
||||
new WinDef.DWORD(0x00030000), nSize, nSize, 0);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Copyright @ 2015 Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.osdependent.windows;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
import org.jitsi.util.*;
|
||||
|
||||
import com.sun.jna.*;
|
||||
import com.sun.jna.platform.win32.*;
|
||||
import com.sun.jna.platform.win32.COM.*;
|
||||
import com.sun.jna.platform.win32.Guid.*;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.platform.win32.WinNT.*;
|
||||
import com.sun.jna.ptr.*;
|
||||
|
||||
/**
|
||||
* JNA wrapper for the ITaskBarList3 COM interface.
|
||||
* https://msdn.microsoft.com/en-us/library/dd391696(v=vs.85).aspx
|
||||
*
|
||||
* @author Ingo Bauersachs
|
||||
*/
|
||||
public class TaskBarList3
|
||||
extends Unknown
|
||||
{
|
||||
private static final GUID CLSID_TaskbarList =
|
||||
new GUID("{56FDF344-FD6D-11d0-958A-006097C9A090}");
|
||||
|
||||
private static final GUID IID_ITaskbarList3 =
|
||||
new GUID("{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}");
|
||||
|
||||
private static TaskBarList3 instance;
|
||||
|
||||
/**
|
||||
* Gets the ITaskBarList3 interface and initializes it with HrInit
|
||||
* @return A ready to use TaskBarList3 object.
|
||||
* @throws COMException when the interface could not be accessed
|
||||
*/
|
||||
public static TaskBarList3 getInstance()
|
||||
{
|
||||
if (instance == null && OSUtils.IS_WINDOWS)
|
||||
{
|
||||
Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, 0);
|
||||
PointerByReference p = new PointerByReference();
|
||||
WinNT.HRESULT hr =
|
||||
Ole32.INSTANCE.CoCreateInstance(CLSID_TaskbarList, Pointer.NULL,
|
||||
ObjBase.CLSCTX_ALL, IID_ITaskbarList3, p);
|
||||
COMUtils.checkRC(hr);
|
||||
instance = new TaskBarList3(p.getValue());
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private TaskBarList3(Pointer p)
|
||||
{
|
||||
super(p);
|
||||
HrInit();
|
||||
}
|
||||
|
||||
// VTable
|
||||
// ------
|
||||
// IUnknown:
|
||||
// 0: AddRef
|
||||
// 1: QueryInterface
|
||||
// 2: Release
|
||||
//
|
||||
// ITaskBarList:
|
||||
// 3: HrInit
|
||||
// 4: AddTab
|
||||
// 5: DeleteTab
|
||||
// 6: ActivateTab
|
||||
// 7: SetActiveAlt
|
||||
//
|
||||
// ITaskBarList2
|
||||
// 8: MarkFullscreenWindow
|
||||
//
|
||||
// ITaskBarList3:
|
||||
// 9: SetProgressValue
|
||||
// 10: SetProgressState
|
||||
// 11: RegisterTab
|
||||
// 12: UnregisterTab
|
||||
// 13: SetTabOrder
|
||||
// 14: SetTabActive
|
||||
// 15: ThumbBarAddButtons
|
||||
// 16: ThumbBarAddButtons
|
||||
// 17: ThumbBarSetImageList
|
||||
// 18: SetOverlayIcon
|
||||
// 19: SetThumbnailTooltip
|
||||
// 20: SetThumbnailClip
|
||||
//
|
||||
// ITaskbarList4:
|
||||
// 21: SetTabProperties
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/bb774650(v=vs.85).aspx
|
||||
*/
|
||||
private void HrInit()
|
||||
{
|
||||
int hr = this._invokeNativeInt(3, new Object[]
|
||||
{ this.getPointer() });
|
||||
COMUtils.checkRC(new HRESULT(hr));
|
||||
}
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/dd391696(v=vs.85).aspx
|
||||
*/
|
||||
private void SetOverlayIcon(HWND hwnd, HICON hIcon, String pszDescription)
|
||||
{
|
||||
int hr = this._invokeNativeInt(18, new Object[]
|
||||
{ this.getPointer(), hwnd, hIcon, pszDescription });
|
||||
COMUtils.checkRC(new HRESULT(hr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an overlay image to the taskbar icon.
|
||||
* @param frame The window that should receive the overlay
|
||||
* @param image The overlay image, can be <tt>null</tt> to clear the overlay
|
||||
* @param description An optional tooltip text, can be <tt>null</tt>
|
||||
*/
|
||||
public void SetOverlayIcon(Component frame, BufferedImage image,
|
||||
String description)
|
||||
{
|
||||
HICON ico = null;
|
||||
if (image != null)
|
||||
{
|
||||
byte[] iconBytes = ImageConverter.writeTransparentIcoImage(image);
|
||||
ico = ImageConverter.createIcon(iconBytes);
|
||||
}
|
||||
|
||||
HWND hwnd = new HWND(Native.getComponentPointer(frame));
|
||||
SetOverlayIcon(hwnd, ico, description);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Copyright @ 2015 Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.osdependent.windows;
|
||||
|
||||
import com.sun.jna.*;
|
||||
import com.sun.jna.platform.win32.*;
|
||||
import com.sun.jna.win32.*;
|
||||
|
||||
/**
|
||||
* Extension to missing user32 Windows APIs
|
||||
*
|
||||
* @author Ingo Bauersachs
|
||||
*/
|
||||
interface User32Ex
|
||||
extends StdCallLibrary
|
||||
{
|
||||
User32Ex INSTANCE = (User32Ex) Native.loadLibrary("user32", User32Ex.class,
|
||||
W32APIOptions.DEFAULT_OPTIONS);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms648074(v=vs.85).aspx
|
||||
*/
|
||||
int LookupIconIdFromDirectoryEx(Memory presbits, boolean fIcon,
|
||||
int cxDesired, int cyDesired, int Flags);
|
||||
|
||||
/**
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms648061(v=vs.85).aspx
|
||||
*/
|
||||
WinDef.HICON CreateIconFromResourceEx(Pointer pbIconBits,
|
||||
WinDef.DWORD cbIconBits, boolean fIcon, WinDef.DWORD dwVersion,
|
||||
int cxDesired, int cyDesired, int uFlags);
|
||||
}
|
||||
Loading…
Reference in new issue