📄 gtkdocklet-win32.c
字号:
*color = hColorBitmap; *mask = hMaskBitmap; return TRUE;}static gbooleanpixbuf_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 HICONpixbuf_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("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_NotifyIcon(NIM_MODIFY, &_nicon_data);}static void systray_remove_nid(void) { Shell_NotifyIcon(NIM_DELETE, &_nicon_data);}static void winpidgin_tray_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending) { int icon_index; g_return_if_fail(image != NULL); if(connecting) icon_index = PURPLE_STATUS_NUM_PRIMITIVES; else if(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; switch (status) { case PURPLE_STATUS_OFFLINE: icon_name = PIDGIN_STOCK_TRAY_OFFLINE; break; case PURPLE_STATUS_AWAY: icon_name = PIDGIN_STOCK_TRAY_AWAY; break; case PURPLE_STATUS_UNAVAILABLE: icon_name = PIDGIN_STOCK_TRAY_BUSY; break; case PURPLE_STATUS_EXTENDED_AWAY: icon_name = PIDGIN_STOCK_TRAY_XA; break; case PURPLE_STATUS_INVISIBLE: icon_name = PIDGIN_STOCK_TRAY_INVISIBLE; break; default: icon_name = PIDGIN_STOCK_TRAY_AVAILABLE; break; } if (pending) icon_name = PIDGIN_STOCK_TRAY_PENDING; if (connecting) icon_name = PIDGIN_STOCK_TRAY_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_NotifyIcon(NIM_MODIFY, &_nicon_data);}static void winpidgin_tray_set_tooltip(gchar *tooltip) { if (tooltip) { char *locenc = NULL; locenc = g_locale_from_utf8(tooltip, -1, NULL, NULL, NULL); lstrcpyn(_nicon_data.szTip, locenc, sizeof(_nicon_data.szTip) / sizeof(TCHAR)); g_free(locenc); } else { lstrcpy(_nicon_data.szTip, PIDGIN_NAME); } Shell_NotifyIcon(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(); image = gtk_image_new();#if GLIB_CHECK_VERSION(2,10,0) g_object_ref_sink(image);#else g_object_ref(image); gtk_object_sink(GTK_OBJECT(image));#endif 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(); 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;}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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -