pidgin/pidgin

4a0082640de9
Parents 63bc0e5e2979
Children e58dfcea3500
Delete some more files that are no longer used
--- a/pidgin/meson.build Fri Nov 15 21:52:05 2019 -0600
+++ b/pidgin/meson.build Mon Nov 18 20:37:58 2019 -0600
@@ -118,10 +118,6 @@
'win32/untar.c'
]
- # Files that looks like obsolete (were used in Pidgin2):
- # win32/MinimizeToTray.c
- # win32/MinimizeToTray.h
-
pidgin_exe_rc = configure_file(
input : 'win32/pidgin_exe_rc.rc.in',
output : 'pidgin_exe_rc.rc',
--- a/pidgin/win32/MinimizeToTray.c Fri Nov 15 21:52:05 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/* MinimizeToTray
- *
- * A couple of routines to show how to make it produce a custom caption
- * animation to make it look like we are minimizing to and maximizing
- * from the system tray
- *
- * These routines are public domain, but it would be nice if you dropped
- * me a line if you use them!
- *
- * 1.0 29.06.2000 Initial version
- * 1.1 01.07.2000 The window retains it's place in the Z-order of windows
- * when minimized/hidden. This means that when restored/shown, it doesn't
- * always appear as the foreground window unless we call SetForegroundWindow
- *
- * Copyright 2000 Matthew Ellis <m.t.ellis@bigfoot.com>
- */
-#include <config.h>
-#include <windows.h>
-#include "MinimizeToTray.h"
-
-#define DEFAULT_RECT_WIDTH 150
-#define DEFAULT_RECT_HEIGHT 30
-
-static void GetTrayWndRect(LPRECT lpTrayRect) {
- APPBARDATA appBarData;
- HWND hShellTrayWnd = FindWindowEx(NULL, NULL, TEXT("Shell_TrayWnd"),
- NULL);
-
- if(hShellTrayWnd) {
- HWND hTrayNotifyWnd = FindWindowEx(hShellTrayWnd, NULL,
- TEXT("TrayNotifyWnd"), NULL);
-
- if(hTrayNotifyWnd) {
- GetWindowRect(hTrayNotifyWnd,lpTrayRect);
- return;
- }
- }
-
- appBarData.cbSize = sizeof(appBarData);
- if(SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData)) {
- switch(appBarData.uEdge) {
- case ABE_LEFT:
- case ABE_RIGHT:
- lpTrayRect->top = appBarData.rc.bottom - 100;
- lpTrayRect->bottom = appBarData.rc.bottom - 16;
- lpTrayRect->left = appBarData.rc.left;
- lpTrayRect->right = appBarData.rc.right;
- break;
- case ABE_TOP:
- case ABE_BOTTOM:
- lpTrayRect->top = appBarData.rc.top;
- lpTrayRect->bottom = appBarData.rc.bottom;
- lpTrayRect->left = appBarData.rc.right - 100;
- lpTrayRect->right = appBarData.rc.right - 16;
- break;
- }
- return;
- }
-
- hShellTrayWnd = FindWindowEx(NULL, NULL, TEXT("Shell_TrayWnd"), NULL);
- if(hShellTrayWnd) {
- GetWindowRect(hShellTrayWnd, lpTrayRect);
- if(lpTrayRect->right-lpTrayRect->left > DEFAULT_RECT_WIDTH)
- lpTrayRect->left = lpTrayRect->right - DEFAULT_RECT_WIDTH;
- if(lpTrayRect->bottom-lpTrayRect->top > DEFAULT_RECT_HEIGHT)
- lpTrayRect->top=lpTrayRect->bottom - DEFAULT_RECT_HEIGHT;
-
- return;
- }
-
- SystemParametersInfo(SPI_GETWORKAREA, 0, lpTrayRect, 0);
- lpTrayRect->left = lpTrayRect->right - DEFAULT_RECT_WIDTH;
- lpTrayRect->top = lpTrayRect->bottom - DEFAULT_RECT_HEIGHT;
-}
-
-static BOOL GetDoAnimateMinimize(void) {
- ANIMATIONINFO ai;
-
- ai.cbSize = sizeof(ai);
- SystemParametersInfo(SPI_GETANIMATION, sizeof(ai), &ai, 0);
-
- return ai.iMinAnimate ? TRUE : FALSE;
-}
-
-void MinimizeWndToTray(HWND hWnd) {
-
- if(!IsWindowVisible(hWnd))
- return;
-
- if(GetDoAnimateMinimize()) {
- RECT rcFrom, rcTo;
-
- GetWindowRect(hWnd, &rcFrom);
- GetTrayWndRect(&rcTo);
-
- DrawAnimatedRects(hWnd, IDANI_CAPTION, &rcFrom, &rcTo);
- }
-
- ShowWindow(hWnd, SW_HIDE);
-}
-
-void RestoreWndFromTray(HWND hWnd) {
-
- if(IsWindowVisible(hWnd))
- return;
-
- if(GetDoAnimateMinimize()) {
- RECT rcFrom, rcTo;
- GetTrayWndRect(&rcFrom);
- GetWindowRect(hWnd, &rcTo);
-
- DrawAnimatedRects(hWnd, IDANI_CAPTION, &rcFrom, &rcTo);
- }
-
- ShowWindow(hWnd, SW_SHOW);
- SetActiveWindow(hWnd);
- SetForegroundWindow(hWnd);
-}
-
--- a/pidgin/win32/MinimizeToTray.h Fri Nov 15 21:52:05 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-#ifndef _MINIMIZE_TO_TRAY_H_
-#define _MINIMIZE_TO_TRAY_H_
-
-void MinimizeWndToTray(HWND hWnd);
-void RestoreWndFromTray(HWND hWnd);
-
-#endif /* _MINIMIZE_TO_TRAY_H_ */
--- a/pidgin/win32/gtkdocklet-win32.c Fri Nov 15 21:52:05 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,659 +0,0 @@
-/*
- * System tray icon (aka docklet) plugin for Winpidgin
- *
- * Copyright (C) 2002-3 Robert McQueen <robot101@debian.org>
- * Copyright (C) 2003 Herman Bloggs <hermanator12002@yahoo.com>
- * Inspired by a similar plugin by:
- * John (J5) Palmieri <johnp@martianrock.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02111-1301, USA.
- */
-
-#include <config.h>
-
-#include <windows.h>
-#include <gdk/gdkwin32.h>
-#include <gdk/gdk.h>
-
-#include "internal.h"
-#include "gtkblist.h"
-#include "debug.h"
-
-#include "resource.h"
-#include "MinimizeToTray.h"
-#include "gtkwin32dep.h"
-#include "gtkdocklet.h"
-#include "pidginicon.h"
-
-/*
- * DEFINES, MACROS & DATA TYPES
- */
-#define WM_TRAYMESSAGE WM_USER /* User defined WM Message */
-
-/*
- * LOCALS
- */
-static HWND systray_hwnd = NULL;
-/* additional two cached_icons entries for pending and connecting icons */
-static HICON cached_icons[PURPLE_STATUS_NUM_PRIMITIVES + 3];
-static GtkWidget *image = NULL;
-/* This is used to trigger click events on so they appear to GTK+ as if they are triggered by input */
-static GtkWidget *dummy_button = NULL;
-static GtkWidget *dummy_window = NULL;
-static NOTIFYICONDATAW _nicon_data;
-
-static gboolean dummy_button_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
- pidgin_docklet_clicked(event->button);
- return TRUE;
-}
-
-static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
- static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */
-
- switch(msg) {
- case WM_CREATE:
- purple_debug_info("docklet", "WM_CREATE\n");
- taskbarRestartMsg = RegisterWindowMessageW(L"TaskbarCreated");
- break;
-
- case WM_TIMER:
- purple_debug_info("docklet", "WM_TIMER\n");
- break;
-
- case WM_DESTROY:
- purple_debug_info("docklet", "WM_DESTROY\n");
- break;
-
- case WM_TRAYMESSAGE:
- {
- int type = 0;
- GdkEvent *event;
- GdkEventButton *event_btn;
-
- /* We'll use Double Click - Single click over on linux */
- if(lparam == WM_LBUTTONDBLCLK)
- type = GDK_BUTTOM_PRIMARY;
- else if(lparam == WM_MBUTTONUP)
- type = GDK_BUTTON_MIDDLE;
- else if(lparam == WM_RBUTTONUP)
- type = GDK_BUTTON_SECONDARY;
- else
- break;
-
- gtk_widget_show_all(dummy_window);
- event = gdk_event_new(GDK_BUTTON_PRESS);
- event_btn = (GdkEventButton *) event;
- event_btn->window = g_object_ref (gdk_get_default_root_window());
- event_btn->send_event = TRUE;
- event_btn->time = GetTickCount();
- event_btn->axes = NULL;
- event_btn->state = 0;
- event_btn->button = type;
- event_btn->device = gdk_display_get_default ()->core_pointer;
- event->any.window = g_object_ref(dummy_window->window);
- gdk_window_set_user_data(event->any.window, dummy_button);
-
- gtk_main_do_event((GdkEvent *)event);
- gtk_widget_hide(dummy_window);
- gdk_event_free((GdkEvent *)event);
-
- break;
- }
- default:
- if (msg == taskbarRestartMsg) {
- /* explorer crashed and left us hanging...
- This will put the systray icon back in it's place, when it restarts */
- Shell_NotifyIconW(NIM_ADD, &_nicon_data);
- }
- break;
- }/* end switch */
-
- return DefWindowProc(hwnd, msg, wparam, lparam);
-}
-
-/* Create hidden window to process systray messages */
-static HWND systray_create_hiddenwin() {
- WNDCLASSEXW wcex;
- wchar_t *wname;
-
- wname = L"WinpidginSystrayWinCls";
-
- wcex.cbSize = sizeof(wcex);
- wcex.style = 0;
- wcex.lpfnWndProc = systray_mainmsg_handler;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = winpidgin_exe_hinstance();
- wcex.hIcon = NULL;
- wcex.hCursor = NULL,
- wcex.hbrBackground = NULL;
- wcex.lpszMenuName = NULL;
- wcex.lpszClassName = wname;
- wcex.hIconSm = NULL;
-
- RegisterClassExW(&wcex);
-
- /* Create the window */
- return (CreateWindowW(wname, L"", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, winpidgin_exe_hinstance(), 0));
-}
-
-static void systray_init_icon(HWND hWnd) {
- wchar_t *w;
- ZeroMemory(&_nicon_data, sizeof(_nicon_data));
- _nicon_data.cbSize = sizeof(NOTIFYICONDATAW);
- _nicon_data.hWnd = hWnd;
- _nicon_data.uID = 0;
- _nicon_data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
- _nicon_data.uCallbackMessage = WM_TRAYMESSAGE;
- _nicon_data.hIcon = NULL;
- w = g_utf8_to_utf16(PIDGIN_NAME, -1, NULL, NULL, NULL);
- wcsncpy(_nicon_data.szTip, w, sizeof(_nicon_data.szTip) / sizeof(wchar_t));
- g_free(w);
- Shell_NotifyIconW(NIM_ADD, &_nicon_data);
- pidgin_docklet_embedded();
-}
-
-/* This is ganked from GTK+.
- * When we can use GTK+ 2.10 and the GtkStatusIcon stuff, this will no longer be necesary */
-#define WIN32_GDI_FAILED(api) printf("GDI FAILED %s\n", api)
-
-static gboolean
-_gdk_win32_pixbuf_to_hicon_supports_alpha (void)
-{
- static gboolean is_win_xp=FALSE, is_win_xp_checked=FALSE;
-
- if (!is_win_xp_checked)
- {
- is_win_xp_checked = TRUE;
-
- if (!G_WIN32_IS_NT_BASED ())
- is_win_xp = FALSE;
- else
- {
- OSVERSIONINFO version;
-
- memset (&version, 0, sizeof (version));
- version.dwOSVersionInfoSize = sizeof (version);
- is_win_xp = GetVersionEx (&version)
- && version.dwPlatformId == VER_PLATFORM_WIN32_NT
- && (version.dwMajorVersion > 5
- || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
- }
- }
- return is_win_xp;
-}
-
-static HBITMAP
-create_alpha_bitmap (gint size,
- guchar **outdata)
-{
- BITMAPV5HEADER bi;
- HDC hdc;
- HBITMAP hBitmap;
-
- ZeroMemory (&bi, sizeof (BITMAPV5HEADER));
- bi.bV5Size = sizeof (BITMAPV5HEADER);
- bi.bV5Height = bi.bV5Width = size;
- bi.bV5Planes = 1;
- bi.bV5BitCount = 32;
- bi.bV5Compression = BI_BITFIELDS;
- /* The following mask specification specifies a supported 32 BPP
- * alpha format for Windows XP (BGRA format).
- */
- bi.bV5RedMask = 0x00FF0000;
- bi.bV5GreenMask = 0x0000FF00;
- bi.bV5BlueMask = 0x000000FF;
- bi.bV5AlphaMask = 0xFF000000;
-
- /* Create the DIB section with an alpha channel. */
- hdc = GetDC (NULL);
- if (!hdc)
- {
- WIN32_GDI_FAILED ("GetDC");
- return NULL;
- }
- hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
- (PVOID *) outdata, NULL, (DWORD)0);
- if (hBitmap == NULL)
- WIN32_GDI_FAILED ("CreateDIBSection");
- ReleaseDC (NULL, hdc);
-
- return hBitmap;
-}
-
-static HBITMAP
-create_color_bitmap (gint size,
- guchar **outdata,
- gint bits)
-{
- struct {
- BITMAPV4HEADER bmiHeader;
- RGBQUAD bmiColors[2];
- } bmi;
- HDC hdc;
- HBITMAP hBitmap;
-
- ZeroMemory (&bmi, sizeof (bmi));
- bmi.bmiHeader.bV4Size = sizeof (BITMAPV4HEADER);
- bmi.bmiHeader.bV4Height = bmi.bmiHeader.bV4Width = size;
- bmi.bmiHeader.bV4Planes = 1;
- bmi.bmiHeader.bV4BitCount = bits;
- bmi.bmiHeader.bV4V4Compression = BI_RGB;
-
- /* when bits is 1, these will be used.
- * bmiColors[0] already zeroed from ZeroMemory()
- */
- bmi.bmiColors[1].rgbBlue = 0xFF;
- bmi.bmiColors[1].rgbGreen = 0xFF;
- bmi.bmiColors[1].rgbRed = 0xFF;
-
- hdc = GetDC (NULL);
- if (!hdc)
- {
- WIN32_GDI_FAILED ("GetDC");
- return NULL;
- }
- hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bmi, DIB_RGB_COLORS,
- (PVOID *) outdata, NULL, (DWORD)0);
- if (hBitmap == NULL)
- WIN32_GDI_FAILED ("CreateDIBSection");
- ReleaseDC (NULL, hdc);
-
- return hBitmap;
-}
-
-static gboolean
-pixbuf_to_hbitmaps_alpha_winxp (GdkPixbuf *pixbuf,
- HBITMAP *color,
- HBITMAP *mask)
-{
- /* Based on code from
- * http://www.dotnet247.com/247reference/msgs/13/66301.aspx
- */
- HBITMAP hColorBitmap, hMaskBitmap;
- guchar *indata, *inrow;
- guchar *colordata, *colorrow, *maskdata, *maskbyte;
- gint width, height, size, i, i_offset, j, j_offset, rowstride;
- guint maskstride, mask_bit;
-
- width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
- height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
-
- /* The bitmaps are created square */
- size = MAX (width, height);
-
- hColorBitmap = create_alpha_bitmap (size, &colordata);
- if (!hColorBitmap)
- return FALSE;
- hMaskBitmap = create_color_bitmap (size, &maskdata, 1);
- if (!hMaskBitmap)
- {
- DeleteObject (hColorBitmap);
- return FALSE;
- }
-
- /* MSDN says mask rows are aligned to "LONG" boundaries */
- maskstride = (((size + 31) & ~31) >> 3);
-
- indata = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- if (width > height)
- {
- i_offset = 0;
- j_offset = (width - height) / 2;
- }
- else
- {
- i_offset = (height - width) / 2;
- j_offset = 0;
- }
-
- for (j = 0; j < height; j++)
- {
- colorrow = colordata + 4*(j+j_offset)*size + 4*i_offset;
- maskbyte = maskdata + (j+j_offset)*maskstride + i_offset/8;
- mask_bit = (0x80 >> (i_offset % 8));
- inrow = indata + (height-j-1)*rowstride;
- for (i = 0; i < width; i++)
- {
- colorrow[4*i+0] = inrow[4*i+2];
- colorrow[4*i+1] = inrow[4*i+1];
- colorrow[4*i+2] = inrow[4*i+0];
- colorrow[4*i+3] = inrow[4*i+3];
- if (inrow[4*i+3] == 0)
- maskbyte[0] |= mask_bit; /* turn ON bit */
- else
- maskbyte[0] &= ~mask_bit; /* turn OFF bit */
- mask_bit >>= 1;
- if (mask_bit == 0)
- {
- mask_bit = 0x80;
- maskbyte++;
- }
- }
- }
-
- *color = hColorBitmap;
- *mask = hMaskBitmap;
-
- return TRUE;
-}
-
-static gboolean
-pixbuf_to_hbitmaps_normal (GdkPixbuf *pixbuf,
- HBITMAP *color,
- HBITMAP *mask)
-{
- /* Based on code from
- * http://www.dotnet247.com/247reference/msgs/13/66301.aspx
- */
- HBITMAP hColorBitmap, hMaskBitmap;
- guchar *indata, *inrow;
- guchar *colordata, *colorrow, *maskdata, *maskbyte;
- gint width, height, size, i, i_offset, j, j_offset, rowstride, nc, bmstride;
- gboolean has_alpha;
- guint maskstride, mask_bit;
-
- width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
- height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
-
- /* The bitmaps are created square */
- size = MAX (width, height);
-
- hColorBitmap = create_color_bitmap (size, &colordata, 24);
- if (!hColorBitmap)
- return FALSE;
- hMaskBitmap = create_color_bitmap (size, &maskdata, 1);
- if (!hMaskBitmap)
- {
- DeleteObject (hColorBitmap);
- return FALSE;
- }
-
- /* rows are always aligned on 4-byte boundarys */
- bmstride = size * 3;
- if (bmstride % 4 != 0)
- bmstride += 4 - (bmstride % 4);
-
- /* MSDN says mask rows are aligned to "LONG" boundaries */
- maskstride = (((size + 31) & ~31) >> 3);
-
- indata = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- nc = gdk_pixbuf_get_n_channels (pixbuf);
- has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
-
- if (width > height)
- {
- i_offset = 0;
- j_offset = (width - height) / 2;
- }
- else
- {
- i_offset = (height - width) / 2;
- j_offset = 0;
- }
-
- for (j = 0; j < height; j++)
- {
- colorrow = colordata + (j+j_offset)*bmstride + 3*i_offset;
- maskbyte = maskdata + (j+j_offset)*maskstride + i_offset/8;
- mask_bit = (0x80 >> (i_offset % 8));
- inrow = indata + (height-j-1)*rowstride;
- for (i = 0; i < width; i++)
- {
- if (has_alpha && inrow[nc*i+3] < 128)
- {
- colorrow[3*i+0] = colorrow[3*i+1] = colorrow[3*i+2] = 0;
- maskbyte[0] |= mask_bit; /* turn ON bit */
- }
- else
- {
- colorrow[3*i+0] = inrow[nc*i+2];
- colorrow[3*i+1] = inrow[nc*i+1];
- colorrow[3*i+2] = inrow[nc*i+0];
- maskbyte[0] &= ~mask_bit; /* turn OFF bit */
- }
- mask_bit >>= 1;
- if (mask_bit == 0)
- {
- mask_bit = 0x80;
- maskbyte++;
- }
- }
- }
-
- *color = hColorBitmap;
- *mask = hMaskBitmap;
-
- return TRUE;
-}
-
-static HICON
-pixbuf_to_hicon (GdkPixbuf *pixbuf)
-{
- gint x = 0, y = 0;
- gboolean is_icon = TRUE;
- ICONINFO ii;
- HICON icon;
- gboolean success;
-
- if (pixbuf == NULL)
- return NULL;
-
- if (_gdk_win32_pixbuf_to_hicon_supports_alpha() && gdk_pixbuf_get_has_alpha (pixbuf))
- success = pixbuf_to_hbitmaps_alpha_winxp (pixbuf, &ii.hbmColor, &ii.hbmMask);
- else
- success = pixbuf_to_hbitmaps_normal (pixbuf, &ii.hbmColor, &ii.hbmMask);
-
- if (!success)
- return NULL;
-
- ii.fIcon = is_icon;
- ii.xHotspot = x;
- ii.yHotspot = y;
- icon = CreateIconIndirect (&ii);
- DeleteObject (ii.hbmColor);
- DeleteObject (ii.hbmMask);
- return icon;
-}
-
-static HICON load_hicon_from_stock(const char *stock) {
- HICON hicon = NULL;
- GdkPixbuf *pixbuf = gtk_widget_render_icon(image, stock,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), NULL);
-
- if (pixbuf) {
- hicon = pixbuf_to_hicon(pixbuf);
- g_object_unref(pixbuf);
- } else
- purple_debug_error("docklet", "Unable to load pixbuf for %s.\n", stock);
-
- return hicon;
-}
-
-
-static void systray_change_icon(HICON hicon) {
- g_return_if_fail(hicon != NULL);
-
- _nicon_data.hIcon = hicon;
- Shell_NotifyIconW(NIM_MODIFY, &_nicon_data);
-}
-
-static void systray_remove_nid(void) {
- Shell_NotifyIconW(NIM_DELETE, &_nicon_data);
-}
-
-static void winpidgin_tray_update_icon(PurpleStatusPrimitive status,
- PidginDockletFlag flags) {
-
- int icon_index;
- g_return_if_fail(image != NULL);
-
- if(flags & PIDGIN_DOCKLET_CONNECTING)
- icon_index = PURPLE_STATUS_NUM_PRIMITIVES;
- else if(flags & PIDGIN_DOCKLET_EMAIL_PENDING)
- icon_index = PURPLE_STATUS_NUM_PRIMITIVES+2;
- else if(flags & PIDGIN_DOCKLET_CONV_PENDING)
- icon_index = PURPLE_STATUS_NUM_PRIMITIVES+1;
- else
- icon_index = status;
-
- g_return_if_fail(icon_index < (sizeof(cached_icons) / sizeof(HICON)));
-
- /* Look up and cache the HICON if we don't already have it */
- if (cached_icons[icon_index] == NULL) {
- const gchar *icon_name = NULL;
-
- icon_name = pidgin_status_icon_from_primitive(status);
-
- if (flags & PIDGIN_DOCKLET_EMAIL_PENDING)
- icon_name = PIDGIN_ICON_MAIL_NEW;
- else if (flags & PIDGIN_DOCKLET_CONV_PENDING)
- icon_name = PIDGIN_ICON_MESSAGE_NEW;
- else if (flags & PIDGIN_DOCKLET_CONNECTING)
- icon_name = PIDGIN_ICON_CONNECT;
-
- g_return_if_fail(icon_name != NULL);
-
- cached_icons[icon_index] = load_hicon_from_stock(icon_name);
- }
-
- systray_change_icon(cached_icons[icon_index]);
-}
-
-static void winpidgin_tray_blank_icon() {
- _nicon_data.hIcon = NULL;
- Shell_NotifyIconW(NIM_MODIFY, &_nicon_data);
-}
-
-static void winpidgin_tray_set_tooltip(gchar *tooltip) {
- const char *value = tooltip;
- wchar_t *w;
- if (value == NULL) {
- value = PIDGIN_NAME;
- }
- w = g_utf8_to_utf16(value, -1, NULL, NULL, NULL);
- wcsncpy(_nicon_data.szTip, w, sizeof(_nicon_data.szTip) / sizeof(wchar_t));
- g_free(w);
- Shell_NotifyIconW(NIM_MODIFY, &_nicon_data);
-}
-
-static void winpidgin_tray_minimize(PidginBuddyList *gtkblist) {
- MinimizeWndToTray(GDK_WINDOW_HWND(gtkblist->window->window));
-}
-
-static void winpidgin_tray_maximize(PidginBuddyList *gtkblist) {
- RestoreWndFromTray(GDK_WINDOW_HWND(gtkblist->window->window));
-}
-
-
-static void winpidgin_tray_create() {
- OSVERSIONINFO osinfo;
- /* dummy window to process systray messages */
- systray_hwnd = systray_create_hiddenwin();
-
- dummy_window = gtk_window_new(GTK_WINDOW_POPUP);
- dummy_button = gtk_button_new();
- gtk_container_add(GTK_CONTAINER(dummy_window), dummy_button);
-
- /* We trigger the click event indirectly so that gtk_get_current_event_state() is TRUE when the event is handled */
- g_signal_connect(G_OBJECT(dummy_button), "button-press-event",
- G_CALLBACK(dummy_button_cb), NULL);
-
- image = gtk_image_new();
- g_object_ref_sink(image);
-
- osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osinfo);
-
- /* Load icons, and init systray notify icon
- * NOTE: Windows < XP only supports displaying 4-bit images in the Systray,
- * 2K and ME will use the highest color depth that the desktop will support,
- * but will scale it back to 4-bits for display.
- * That is why we use custom 4-bit icons for pre XP Windowses */
- if (osinfo.dwMajorVersion < 5 || (osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion == 0))
- {
- cached_icons[PURPLE_STATUS_OFFLINE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_OFFLINE_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_AVAILABLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_AVAILABLE_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_AWAY] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_AWAY_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_EXTENDED_AWAY] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_XA_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_UNAVAILABLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_BUSY_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_NUM_PRIMITIVES] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_CONNECTING_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_NUM_PRIMITIVES+1] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_PENDING_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- cached_icons[PURPLE_STATUS_INVISIBLE] = (HICON) LoadImage(winpidgin_dll_hinstance(),
- MAKEINTRESOURCE(PIDGIN_TRAY_INVISIBLE_4BIT), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION);
- }
-
- /* Create icon in systray */
- systray_init_icon(systray_hwnd);
-
- purple_signal_connect(pidgin_blist_get_handle(), "gtkblist-hiding",
- pidgin_docklet_get_handle(), PURPLE_CALLBACK(winpidgin_tray_minimize), NULL);
- purple_signal_connect(pidgin_blist_get_handle(), "gtkblist-unhiding",
- pidgin_docklet_get_handle(), PURPLE_CALLBACK(winpidgin_tray_maximize), NULL);
-
- purple_debug_info("docklet", "created\n");
-}
-
-static void winpidgin_tray_destroy() {
- int cached_cnt = sizeof(cached_icons) / sizeof(HICON);
- systray_remove_nid();
-
- purple_signals_disconnect_by_handle(pidgin_docklet_get_handle());
-
- DestroyWindow(systray_hwnd);
- pidgin_docklet_remove();
-
- while (--cached_cnt >= 0) {
- if (cached_icons[cached_cnt] != NULL)
- DestroyIcon(cached_icons[cached_cnt]);
- cached_icons[cached_cnt] = NULL;
- }
-
- g_object_unref(image);
- image = NULL;
-
- gtk_widget_destroy(dummy_window);
- dummy_button = NULL;
- dummy_window = NULL;
-}
-
-static struct docklet_ui_ops winpidgin_tray_ops =
-{
- winpidgin_tray_create,
- winpidgin_tray_destroy,
- winpidgin_tray_update_icon,
- winpidgin_tray_blank_icon,
- winpidgin_tray_set_tooltip,
- NULL
-};
-
-/* Used by docklet's plugin load func */
-void docklet_ui_init() {
- /* Initialize the cached icons to NULL */
- ZeroMemory(cached_icons, sizeof(cached_icons));
-
- pidgin_docklet_set_ui_ops(&winpidgin_tray_ops);
-}