のらぬこの日常を描く

ノージャンルのお役立ち情報やアニメとゲームの話、ソフトウェア開発に関する話などを中心としたブログです。

PuTTY ごった煮版で壁紙がうまく表示されないバグを直してみた

表題の通りです。

PuTTY 0.60 ごった煮版 2007年8月6日版*1にて壁紙設定すると、再描画がうまくされなかったり、透過率の設定が効かなかったりといった不具合を修正してみました。

ついでに、ワイド文字(2バイト文字)の背景が透過されない不具合も直してみたり。

GDI絡みのWin32API使い方ミスだった模様。

f:id:mikenekoDX:20100301231632p:image

修正ソース(patch)とwin32実行バイナリのダウンロード

(旧DL場所) http://www1.axfc.net/uploader/File/so/39678.gz

(最新はこっち) http://d.hatena.ne.jp/mikenekoDX/20100305


PuTTY 0.60 ごった煮版 2007年8月6日版からのパッチ

以下のパッチを、本家0.60->ごった煮2007/08/06にパッチ当てしたソースに対して当ててもおk。

diff -crN putty-0.60-jp/windows/window.c putty-0.60-mknk/windows/window.c
*** putty-0.60-jp/windows/window.c	2010-03-01 22:30:52.278375000 +0900
--- putty-0.60-mknk/windows/window.c	2010-03-01 22:36:54.356500000 +0900
***************
*** 155,160 ****
--- 155,162 ----
  
  /* > transparent background patch */
  static HBITMAP background_bmp = NULL;
+ static LONG width_background = 0, height_background = 0;
+ 
  static void xtrans_paint_bg(HDC, int, int, int, int);
  static void (*xtrans_paint_background)(HDC, int, int, int, int) = xtrans_paint_bg;
  /* < */
***************
*** 231,247 ****
  {
      HDC memhdc;
      HBITMAP defbmp;
!     POINT point;
! 
!     point.x = x;
!     point.y = y;
!     ClientToScreen(hwnd, &point);
  
!     memhdc = CreateCompatibleDC(hdc);
      defbmp = SelectObject(memhdc, background_bmp);
  
!     BitBlt(hdc, x, y, width, height, memhdc, point.x, point.y, SRCCOPY);
! 
      SelectObject(memhdc, defbmp);
      DeleteDC(memhdc);
  }
--- 233,264 ----
  {
      HDC memhdc;
      HBITMAP defbmp;
! 	int xIndex = x, yIndex = y;
! 	int w = 0, h = 0;
  
! 	memhdc = CreateCompatibleDC(hdc);
      defbmp = SelectObject(memhdc, background_bmp);
  
! 	w = width;
! 	for( xIndex = x; xIndex < x + width; )
! 	{
! 		int offsetX = xIndex % width_background;
! 		h = height;
! 		for( yIndex = y; yIndex < y + height; )
! 		{
! 			int offsetY = yIndex % height_background;
! 			BitBlt( hdc, 
! 				xIndex, yIndex, 
! 				( w < width_background - offsetX ) ? w : width_background - offsetX,
! 				( h < height_background - offsetY ) ? h : height_background - offsetY,
! 				memhdc,
! 				offsetX, offsetY, SRCCOPY );
! 			yIndex += height_background - offsetY;
! 			h -= height_background - offsetY;
! 		}
! 		xIndex += width_background - offsetX;
! 		w -= width_background - offsetX;
! 	}
      SelectObject(memhdc, defbmp);
      DeleteDC(memhdc);
  }
***************
*** 318,328 ****
--- 335,349 ----
  void xtrans_set_bitmap()
  {
      if (cfg.bgimg_file.path[0] != '\0') {
+ 		BITMAP bitmap;
          if (background_bmp)
              xtrans_free_background();
          background_bmp = LoadImage(0, cfg.bgimg_file.path,
                                     IMAGE_BITMAP, 0, 0,
                                     LR_LOADFROMFILE | LR_DEFAULTSIZE);
+ 		GetObject( background_bmp, sizeof(BITMAP), &bitmap );
+ 		width_background = bitmap.bmWidth;
+ 		height_background = bitmap.bmHeight;
      }
  
      if (background_bmp == NULL) {
***************
*** 334,356 ****
          HDC hdc, memhdc, memhdc_mask;
          HBITMAP bmp_mask, defbmp_mask, defbmp;
          BLENDFUNCTION bf = { AC_SRC_OVER, 0, 0, 0 };
-         int width, height;
- 
          bf.SourceConstantAlpha = (BYTE) cfg.shading;
- 
          hdc = GetDC(hwnd);
          memhdc = CreateCompatibleDC(hdc);
          memhdc_mask = CreateCompatibleDC(hdc);
          defbmp = SelectObject(memhdc, background_bmp);
!         width = GetDeviceCaps(memhdc, HORZRES);
!         height = GetDeviceCaps(memhdc, VERTRES);
!         bmp_mask = CreateCompatibleBitmap(hdc, width, height);
          ReleaseDC(hwnd, hdc);
          defbmp_mask = SelectObject(memhdc_mask, bmp_mask);
  
!         xtrans_daub_with_bgcolor(memhdc_mask, width, height);
!         AlphaBlend(memhdc_mask, 0, 0, width, height,
!                    memhdc, 0, 0, width, height, bf);
  
          SelectObject(memhdc_mask, defbmp_mask);
          DeleteDC(memhdc_mask);
--- 355,372 ----
          HDC hdc, memhdc, memhdc_mask;
          HBITMAP bmp_mask, defbmp_mask, defbmp;
          BLENDFUNCTION bf = { AC_SRC_OVER, 0, 0, 0 };
          bf.SourceConstantAlpha = (BYTE) cfg.shading;
          hdc = GetDC(hwnd);
          memhdc = CreateCompatibleDC(hdc);
          memhdc_mask = CreateCompatibleDC(hdc);
          defbmp = SelectObject(memhdc, background_bmp);
!         bmp_mask = CreateCompatibleBitmap(hdc, width_background, height_background);
          ReleaseDC(hwnd, hdc);
          defbmp_mask = SelectObject(memhdc_mask, bmp_mask);
  
!         xtrans_daub_with_bgcolor(memhdc_mask, width_background, height_background);
!         AlphaBlend(memhdc_mask, 0, 0, width_background, height_background,
!                    memhdc, 0, 0, width_background, height_background, bf);
  
          SelectObject(memhdc_mask, defbmp_mask);
          DeleteDC(memhdc_mask);
***************
*** 3897,3903 ****
  
  	/* print Glyphs as they are, without Windows' Shaping*/
  	general_textout2(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
! 			&line_box, wbuf, len, IpDx, !(attr & TATTR_COMBINING), !!(attr & ATTR_WIDE), in_utf (term) && term->ucsdata->iso2022);
  
  	/* And the shadow bold hack. */
  	if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
--- 3913,3922 ----
  
  	/* print Glyphs as they are, without Windows' Shaping*/
  	general_textout2(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
! //			&line_box, wbuf, len, IpDx, !(attr & TATTR_COMBINING), !!(attr & ATTR_WIDE), in_utf (term) && term->ucsdata->iso2022);
! 	/* > transparent background patch */
! 			&line_box, wbuf, len, IpDx, !(attr & TATTR_COMBINING) && !(cfg.transparent_mode && (nbg == 258)), !!(attr & ATTR_WIDE), in_utf (term) && term->ucsdata->iso2022);
! 	/* < */
  
  	/* And the shadow bold hack. */
  	if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {

壁紙画像の拡大縮小(とーぜんアスペクト比保存で)くらいはそのうちやるかも。

追記)

てか、はるか昔に作られていた方がいらっしゃったようでs

http://nanabit.net/softwares/putty-bgi-patch.html