⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pixbuf_to_hicon.c

📁 Ekiga (formely known as GnomeMeeting) is an open source VoIP and video conferencing application for
💻 C
字号:
/* Ekiga -- A VoIP and Video-Conferencing application * Copyright (C) 2000-2006 Damien Sandras * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * * * Ekiga is licensed under the GPL license and as a special exception, * you have permission to link or otherwise combine this program with the * programs OPAL, OpenH323 and PWLIB, and distribute the combination, * without applying the requirements of the GNU GPL to the OPAL, OpenH323 * and PWLIB programs, as long as you do follow the requirements of the * GNU GPL for all the rest of the software thus combined. *//* * Authors: Julien Puydt <jpuydt@free.fr> *//* *                         pixbuf_to_hicon.c  -  description *                         ------------------------ *   begin                : Sat Jan 7 2002 *   copyright            : (C) 2000-2006 by Damien Sandras *   description          : Implementation of an helper function */#include "pixbuf_to_hicon.h"#define WIN32_GDI_FAILED g_warning/* the rest of that code was directly copy-pasted from gtk+'s sources * (more specifically gdk/win32/gdkcursor-win32.c), hence falls under * the same licence, with the same copyrights. It will disappear from * gnomemeeting's own cvs when a version of GTK+ with GtkStatusIcon will be * released. */typedef struct {   DWORD        bV5Size;   LONG         bV5Width;   LONG         bV5Height;   WORD         bV5Planes;   WORD         bV5BitCount;   DWORD        bV5Compression;   DWORD        bV5SizeImage;   LONG         bV5XPelsPerMeter;   LONG         bV5YPelsPerMeter;   DWORD        bV5ClrUsed;   DWORD        bV5ClrImportant;   DWORD        bV5RedMask;   DWORD        bV5GreenMask;   DWORD        bV5BlueMask;   DWORD        bV5AlphaMask;   DWORD        bV5CSType;   CIEXYZTRIPLE bV5Endpoints;   DWORD        bV5GammaRed;   DWORD        bV5GammaGreen;   DWORD        bV5GammaBlue;   DWORD        bV5Intent;   DWORD        bV5ProfileData;   DWORD        bV5ProfileSize;   DWORD        bV5Reserved; } BITMAPV5HEADER;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 HBITMAPcreate_alpha_bitmap (gint width,		     gint height,		     guchar **outdata){  BITMAPV5HEADER bi;  HDC hdc;  HBITMAP hBitmap;  ZeroMemory (&bi, sizeof (BITMAPV5HEADER));  bi.bV5Size = sizeof (BITMAPV5HEADER);  bi.bV5Width = width;  bi.bV5Height = height;  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 HBITMAPcreate_color_bitmap (gint     width,		     gint     height,		     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.bV4Width = width;  bmi.bmiHeader.bV4Height = height;  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 gbooleanpixbuf_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, i, j, rowstride;  guint maskstride, mask_bit;  width = gdk_pixbuf_get_width (pixbuf); /* width of icon */  height = gdk_pixbuf_get_height (pixbuf); /* height of icon */  hColorBitmap = create_alpha_bitmap (width, height, &colordata);  if (!hColorBitmap)    return FALSE;  hMaskBitmap = create_color_bitmap (width, height, &maskdata, 1);  if (!hMaskBitmap)    {      DeleteObject (hColorBitmap);      return FALSE;    }  /* MSDN says mask rows are aligned to "LONG" boundaries */  maskstride = (((width + 31) & ~31) >> 3);  indata = gdk_pixbuf_get_pixels (pixbuf);  rowstride = gdk_pixbuf_get_rowstride (pixbuf);  for (j=0; j<height; j++)    {      colorrow = colordata + 4*j*width;      maskbyte = maskdata + j*maskstride;      mask_bit = 0x80;      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 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, i, j, 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 */  hColorBitmap = create_color_bitmap (width, height, &colordata, 24);  if (!hColorBitmap)    return FALSE;  hMaskBitmap = create_color_bitmap (width, height, &maskdata, 1);  if (!hMaskBitmap)    {      DeleteObject (hColorBitmap);      return FALSE;    }  /* rows are always aligned on 4-byte boundarys */  bmstride = width * 3;  if (bmstride % 4 != 0)    bmstride += 4 - (bmstride % 4);  /* MSDN says mask rows are aligned to "LONG" boundaries */  maskstride = (((width + 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);  for (j=0; j<height; j++)    {      colorrow = colordata + j*bmstride;      maskbyte = maskdata + j*maskstride;      mask_bit = 0x80;      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,		 gboolean   is_icon,		 gint       x,		 gint       y){  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;}HICON_gdk_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf){  return pixbuf_to_hicon (pixbuf, TRUE, 0, 0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -