Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/vtdisp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10806 - (hide annotations) (download) (as text)
Sun Jul 23 07:07:41 2023 UTC (8 months, 2 weeks ago) by zmatsuo
File MIME type: text/x-csrc
File size: 102063 byte(s)
文字を拡大縮小して描画できるようにした

- 拡大縮小して描画できるようにした
  - 2cell幅の文字を1cell幅に縮小して描画
  - 1cell幅の文字を2cell幅に拡大して描画,等
- フォントプロパティーページに設定を追加
  - "Drawing resized font to fit cell width" checkbox
- compat_win.cpp に TransparentBlt() (msimg32.dll) を追加
- ヘルプ追加(enはjaのコピー)
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3 nmaya 9048 * (C) 2005- TeraTerm Project
4 doda 6806 * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3227
30     /* TERATERM.EXE, VT terminal display routines */
31     #include "teraterm.h"
32 zmatsuo 10349 #include "teraterml.h"
33 maya 3227 #include "tttypes.h"
34 zmatsuo 8814 #include <string.h>
35     #include <olectl.h>
36 zmatsuo 10308 #include <assert.h>
37 zmatsuo 10333 #include <stdio.h>
38 maya 3227
39     #include "ttwinman.h"
40     #include "ttime.h"
41     #include "ttdialog.h"
42     #include "ttcommon.h"
43 zmatsuo 7457 #include "compat_win.h"
44 zmatsuo 8814 #include "unicode_test.h"
45     #include "setting.h"
46     #include "codeconv.h"
47     #include "libsusieplugin.h"
48 zmatsuo 9959 #include "asprintf.h"
49 zmatsuo 9958 #include "inifile_com.h"
50     #include "win32helper.h"
51 zmatsuo 10134 #include "ttknownfolders.h" // for FOLDERID_Desktop
52 zmatsuo 10333 #include "ttlib.h"
53 zmatsuo 10349 #if ENABLE_GDIPLUS
54     #include "ttgdiplus.h"
55     #endif
56 maya 3227
57 zmatsuo 10333 #include "theme.h"
58 maya 3227 #include "vtdisp.h"
59    
60     #define CurWidth 2
61    
62 zmatsuo 10333 #include "defaultcolortable.c"
63 doda 4770
64 zmatsuo 7499 int WinWidth, WinHeight;
65 maya 3227 static BOOL Active = FALSE;
66     static BOOL CompletelyVisible;
67     HFONT VTFont[AttrFontMask+1];
68     int FontHeight, FontWidth, ScreenWidth, ScreenHeight;
69     BOOL AdjustSize;
70     BOOL DontChangeSize=FALSE;
71     static int CRTWidth, CRTHeight;
72     int CursorX, CursorY;
73     /* Virtual screen region */
74     RECT VirtualScreen;
75    
76     // --- scrolling status flags
77 zmatsuo 7499 int WinOrgX, WinOrgY, NewOrgX, NewOrgY;
78 maya 3227
79 zmatsuo 7499 int NumOfLines, NumOfColumns;
80     int PageStart, BuffEnd;
81 maya 3227
82     static BOOL CursorOnDBCS = FALSE;
83     static BOOL SaveWinSize = FALSE;
84     static int WinWidthOld, WinHeightOld;
85     static HBRUSH Background;
86 zmatsuo 10274
87     /*
88     * ANSI color table
89     * 0 ��,Black
90     * 1-6 ���������F(Red, Green, Yellow, Blue, Magenta, Cyan)
91     * 7 Gray (15��������,8����������)
92     * 8 Gray (7��������,0����������)
93     * 9-14 �������F,���F (Bright Red, Green, Yellow, Blue, Magenta, Cyan)
94     * 15 ��,White 255 (Bright White)
95     * 16-255 DefaultColorTable[16-255]
96     */
97 maya 3227 static COLORREF ANSIColor[256];
98    
99     // caret variables
100     static int CaretStatus;
101     static BOOL CaretEnabled = TRUE;
102 zmatsuo 7459 BOOL IMEstat; /* IME Status TRUE=IME ON */
103 zmatsuo 7534 BOOL IMECompositionState; /* �������� TRUE=������ */
104 maya 3227
105     // ---- device context and status flags
106     static HDC VTDC = NULL; /* Device context for VT window */
107     static TCharAttr DCAttr;
108     static TCharAttr CurCharAttr;
109     static HFONT DCPrevFont;
110    
111     TCharAttr DefCharAttr = {
112     AttrDefault,
113     AttrDefault,
114 doda 8445 AttrDefault,
115 maya 3227 AttrDefaultFG,
116     AttrDefaultBG
117     };
118    
119     // scrolling
120     static int ScrollCount = 0;
121 zmatsuo 7499 static int dScroll = 0;
122 maya 3227 static int SRegionTop;
123     static int SRegionBottom;
124    
125     typedef struct _BGSrc
126     {
127 zmatsuo 10365 HDC hdc;
128 zmatsuo 10385 BOOL enable;
129 zmatsuo 10365 BG_TYPE type;
130     BG_PATTERN pattern;
131     BOOL antiAlias;
132     COLORREF color;
133     BYTE alpha;
134     int width;
135     int height;
136 zmatsuo 10374 wchar_t *fileW;
137 zmatsuo 10365 } BGSrc;
138 maya 3227
139 zmatsuo 10385 static BGSrc BGDest; // �w�i�����p
140     static BGSrc BGSrc1; // ����(Windows���f�X�N�g�b�v�w�i)�p
141     static BGSrc BGSrc2; // fill color�p
142 maya 3227
143 zmatsuo 10134 static int BGEnable;
144 zmatsuo 10274 static BYTE BGReverseTextAlpha;
145 maya 3227
146 zmatsuo 7545 static COLORREF BGVTColor[2];
147     static COLORREF BGVTBoldColor[2];
148 zmatsuo 10214 static COLORREF BGVTUnderlineColor[2]; // SGR 4
149 zmatsuo 7545 static COLORREF BGVTBlinkColor[2];
150     static COLORREF BGVTReverseColor[2];
151 zmatsuo 10214 static COLORREF BGURLColor[2]; // URL�����F
152 maya 3227
153 zmatsuo 7545 static RECT BGPrevRect;
154 maya 3227
155 zmatsuo 7545 static BOOL BGInSizeMove;
156 zmatsuo 10338 //static HBRUSH BGBrushInSizeMove;
157 maya 3227
158 zmatsuo 7545 static HDC hdcBGWork;
159     static HDC hdcBGBuffer;
160     static HDC hdcBG;
161 maya 3227
162     typedef struct tagWallpaperInfo
163     {
164 zmatsuo 10363 wchar_t *filename;
165     int pattern;
166     } WallpaperInfo;
167 maya 3227
168 zmatsuo 7457 static BOOL (WINAPI *BGAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
169 maya 3227
170 zmatsuo 10334 typedef struct {
171     BOOL bg_enable;
172 zmatsuo 10338 BYTE alpha_vtback;
173     BYTE alpha_back;
174     BOOL debug_drawbox_text;
175     BOOL debug_drawbox_fillrect;
176     //
177     BYTE DCBackAlpha;
178     COLORREF DCBackColor;
179 zmatsuo 10806
180     BOOL font_resize_enable;
181 zmatsuo 10334 } vtdisp_work_t;
182     static vtdisp_work_t vtdisp_work;
183    
184 zmatsuo 10353 static HBITMAP GetBitmapHandleW(const wchar_t *File);
185 zmatsuo 10274 static void InitColorTable(const COLORREF *ANSIColor16);
186     static void UpdateBGBrush(void);
187 zmatsuo 10338 static void GetDrawAttr(const TCharAttr *Attr, BOOL _reverse, COLORREF *fore_color, COLORREF *back_color, BYTE *_alpha);
188 maya 3227
189 yutakapon 5570 // LoadImage() �����g�����������������������������B
190     // LoadImage()���� .bmp ���O�������t�@�C�����������������v�����B
191     // (2014.4.20 yutaka)
192     static BOOL IsLoadImageOnlyEnabled(void)
193     {
194     // Vista ���������������A������������������������������������
195     // cf. SVN#4571(2011.8.4)
196 yutakapon 6286 return !IsWindowsVistaOrLater();
197 yutakapon 5570 }
198    
199 zmatsuo 9943 static HBITMAP CreateScreenCompatibleBitmap(int width,int height)
200 maya 3227 {
201     HDC hdc;
202     HBITMAP hbm;
203    
204     #ifdef _DEBUG
205 zmatsuo 7645 OutputDebugPrintf("CreateScreenCompatibleBitmap : width = %d height = %d\n",width,height);
206 maya 3227 #endif
207    
208     hdc = GetDC(NULL);
209    
210     hbm = CreateCompatibleBitmap(hdc,width,height);
211    
212     ReleaseDC(NULL,hdc);
213    
214     #ifdef _DEBUG
215     if(!hbm)
216 zmatsuo 7645 OutputDebugPrintf("CreateScreenCompatibleBitmap : fail in CreateCompatibleBitmap\n");
217 maya 3227 #endif
218    
219     return hbm;
220     }
221    
222 zmatsuo 9943 static HBITMAP CreateDIB24BPP(int width,int height,unsigned char **buf,int *lenBuf)
223 maya 3227 {
224     HDC hdc;
225     HBITMAP hbm;
226     BITMAPINFO bmi;
227    
228     #ifdef _DEBUG
229 zmatsuo 7645 OutputDebugPrintf("CreateDIB24BPP : width = %d height = %d\n",width,height);
230 maya 3227 #endif
231    
232     if(!width || !height)
233     return NULL;
234    
235     ZeroMemory(&bmi,sizeof(bmi));
236    
237     *lenBuf = ((width * 3 + 3) & ~3) * height;
238    
239     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
240     bmi.bmiHeader.biWidth = width;
241     bmi.bmiHeader.biHeight = height;
242     bmi.bmiHeader.biPlanes = 1;
243     bmi.bmiHeader.biBitCount = 24;
244     bmi.bmiHeader.biSizeImage = *lenBuf;
245     bmi.bmiHeader.biCompression = BI_RGB;
246    
247     hdc = GetDC(NULL);
248    
249     hbm = CreateDIBSection(hdc,&bmi,DIB_RGB_COLORS,(void**)buf,NULL,0);
250    
251     ReleaseDC(NULL,hdc);
252    
253     return hbm;
254     }
255    
256 zmatsuo 9943 static HDC CreateBitmapDC(HBITMAP hbm)
257 maya 3227 {
258     HDC hdc;
259    
260     #ifdef _DEBUG
261 zmatsuo 7645 OutputDebugPrintf("CreateBitmapDC : hbm = %p\n",hbm);
262 maya 3227 #endif
263    
264     hdc = CreateCompatibleDC(NULL);
265    
266     SaveDC(hdc);
267     SelectObject(hdc,hbm);
268    
269     return hdc;
270     }
271    
272 zmatsuo 9943 static void DeleteBitmapDC(HDC *hdc)
273 maya 3227 {
274     HBITMAP hbm;
275    
276     #ifdef _DEBUG
277 zmatsuo 7645 OutputDebugPrintf("DeleteBitmapDC : *hdc = %p\n",hdc);
278 maya 3227 #endif
279    
280     if(!hdc)
281     return;
282    
283     if(!(*hdc))
284     return;
285    
286     hbm = GetCurrentObject(*hdc,OBJ_BITMAP);
287    
288     RestoreDC(*hdc,-1);
289     DeleteObject(hbm);
290     DeleteDC(*hdc);
291    
292     *hdc = 0;
293     }
294    
295 zmatsuo 9943 static void FillBitmapDC(HDC hdc,COLORREF color)
296 maya 3227 {
297     HBITMAP hbm;
298     BITMAP bm;
299     RECT rect;
300     HBRUSH hBrush;
301    
302     #ifdef _DEBUG
303 zmatsuo 10338 OutputDebugPrintf("FillBitmapDC : hdc = %p color = %08lx\n",hdc,color);
304 maya 3227 #endif
305    
306     if(!hdc)
307     return;
308    
309     hbm = GetCurrentObject(hdc,OBJ_BITMAP);
310     GetObject(hbm,sizeof(bm),&bm);
311    
312     SetRect(&rect,0,0,bm.bmWidth,bm.bmHeight);
313     hBrush = CreateSolidBrush(color);
314     FillRect(hdc,&rect,hBrush);
315     DeleteObject(hBrush);
316     }
317    
318 zmatsuo 10134 static void DebugSaveFile(const wchar_t* fname, HDC hdc, int width, int height)
319     {
320 zmatsuo 10255 #if 1
321     (void)fname;
322     (void)hdc;
323     (void)width;
324     (void)height;
325     #else
326 zmatsuo 10134 if (IsRelativePathW(fname)) {
327     wchar_t *desktop;
328     wchar_t *bmpfile;
329     _SHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_CREATE, NULL, &desktop);
330     bmpfile = NULL;
331     awcscats(&bmpfile, desktop, L"\\", fname, NULL);
332     free(desktop);
333     SaveBmpFromHDC(bmpfile, hdc, width, height);
334     free(bmpfile);
335     }
336     else {
337     SaveBmpFromHDC(fname, hdc, width, height);
338     }
339     #endif
340 maya 3227 }
341    
342 zmatsuo 10352 /**
343     * BMP�����A�f�o�O���g�������������������c��������
344     */
345     #if 0
346 zmatsuo 8814 static BOOL SaveBitmapFile(const char *nameFile,unsigned char *pbuf,BITMAPINFO *pbmi)
347 maya 3227 {
348     int bmiSize;
349     DWORD writtenByte;
350     HANDLE hFile;
351     BITMAPFILEHEADER bfh;
352    
353     hFile = CreateFile(nameFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
354    
355     if(hFile == INVALID_HANDLE_VALUE)
356     return FALSE;
357    
358     bmiSize = pbmi->bmiHeader.biSize;
359 doda 6435
360 maya 3227 switch(pbmi->bmiHeader.biBitCount)
361     {
362     case 1:
363     bmiSize += pbmi->bmiHeader.biClrUsed ? sizeof(RGBQUAD) * 2 : 0;
364     break;
365 doda 6435
366 maya 3227 case 2 :
367     bmiSize += sizeof(RGBQUAD) * 4;
368     break;
369    
370     case 4 :
371     bmiSize += sizeof(RGBQUAD) * 16;
372     break;
373    
374 doda 6435 case 8 :
375 maya 3227 bmiSize += sizeof(RGBQUAD) * 256;
376     break;
377     }
378    
379     ZeroMemory(&bfh,sizeof(bfh));
380     bfh.bfType = MAKEWORD('B','M');
381     bfh.bfOffBits = sizeof(bfh) + bmiSize;
382     bfh.bfSize = bfh.bfOffBits + pbmi->bmiHeader.biSizeImage;
383    
384     WriteFile(hFile,&bfh,sizeof(bfh) ,&writtenByte,0);
385     WriteFile(hFile,pbmi,bmiSize ,&writtenByte,0);
386     WriteFile(hFile,pbuf,pbmi->bmiHeader.biSizeImage,&writtenByte,0);
387    
388     CloseHandle(hFile);
389    
390     return TRUE;
391     }
392 zmatsuo 10352 #endif
393 maya 3227
394 zmatsuo 10352 static HBITMAP CreateBitmapFromBITMAPINFO(const BITMAPINFO *pbmi, const unsigned char *pbuf)
395 zmatsuo 8814 {
396 zmatsuo 10352 void* pvBits;
397     HBITMAP hBmp = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
398 zmatsuo 8814
399 zmatsuo 10352 if (pbuf != NULL) {
400     memcpy(pvBits, pbuf, pbmi->bmiHeader.biSizeImage);
401 zmatsuo 8814 }
402    
403 zmatsuo 10352 return hBmp;
404 zmatsuo 8814 }
405    
406 zmatsuo 7457 static BOOL WINAPI AlphaBlendWithoutAPI(HDC hdcDest,int dx,int dy,int width,int height,HDC hdcSrc,int sx,int sy,int sw,int sh,BLENDFUNCTION bf)
407 maya 3227 {
408     HDC hdcDestWork,hdcSrcWork;
409     int i,invAlpha,alpha;
410     int lenBuf;
411     unsigned char *bufDest;
412     unsigned char *bufSrc;
413    
414     if(dx != 0 || dy != 0 || sx != 0 || sy != 0 || width != sw || height != sh)
415     return FALSE;
416    
417     hdcDestWork = CreateBitmapDC(CreateDIB24BPP(width,height,&bufDest,&lenBuf));
418     hdcSrcWork = CreateBitmapDC(CreateDIB24BPP(width,height,&bufSrc ,&lenBuf));
419    
420     if(!bufDest || !bufSrc)
421     return FALSE;
422    
423     BitBlt(hdcDestWork,0,0,width,height,hdcDest,0,0,SRCCOPY);
424     BitBlt(hdcSrcWork ,0,0,width,height,hdcSrc ,0,0,SRCCOPY);
425    
426     alpha = bf.SourceConstantAlpha;
427     invAlpha = 255 - alpha;
428    
429     for(i = 0;i < lenBuf;i++,bufDest++,bufSrc++)
430     *bufDest = (*bufDest * invAlpha + *bufSrc * alpha)>>8;
431    
432     BitBlt(hdcDest,0,0,width,height,hdcDestWork,0,0,SRCCOPY);
433    
434     DeleteBitmapDC(&hdcDestWork);
435     DeleteBitmapDC(&hdcSrcWork);
436    
437     return TRUE;
438     }
439    
440     // ���������������W
441 zmatsuo 7652 static void BGPreloadPicture(BGSrc *src)
442 maya 3227 {
443 zmatsuo 10346 HBITMAP hbm = NULL;
444 zmatsuo 10365 const wchar_t *load_file = src->fileW;
445 zmatsuo 10346 const wchar_t *spi_path = ts.EtermLookfeel.BGSPIPathW;
446 maya 3227
447 zmatsuo 10346 // Susie plugin ����������
448 zmatsuo 10352 if (hbm == NULL) {
449     HANDLE hbmi;
450     HANDLE hbuf;
451     BOOL r = SusieLoadPicture(load_file, spi_path, &hbmi, &hbuf);
452     if (r != FALSE) {
453     hbm = CreateBitmapFromBITMAPINFO(hbmi, hbuf);
454     LocalFree(hbmi);
455     LocalFree(hbuf);
456     }
457 zmatsuo 10346 }
458 maya 3227
459 zmatsuo 10352 // GDI+ ���C�u�������g������������
460 zmatsuo 10349 #if ENABLE_GDIPLUS
461     if (hbm == NULL) {
462     hbm = GDIPLoad(load_file);
463     }
464     #endif
465    
466 zmatsuo 10352 // OLE �����p��������(jpeg)������
467     // LoadImage()����������������������������������
468 zmatsuo 10346 if (hbm == NULL && !IsLoadImageOnlyEnabled()) {
469 zmatsuo 10353 hbm = GetBitmapHandleW(load_file);
470 zmatsuo 10346 }
471 maya 3227
472 zmatsuo 10352 // LoadImageW() API ����������
473 zmatsuo 10346 if (hbm == NULL) {
474 zmatsuo 10352 // LoadImageW() API���A
475     // Windows 10 �������������}�C�i�X��bmp�t�@�C�������[�h�����s����
476     // Windows 7 ����������������
477 zmatsuo 10346 hbm = LoadImageW(0,load_file,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
478     }
479 yutakapon 5570
480 zmatsuo 10346 if(hbm) {
481     BITMAP bm;
482 maya 3227
483 zmatsuo 10346 GetObject(hbm,sizeof(bm),&bm);
484 maya 3227
485 zmatsuo 10346 src->hdc = CreateBitmapDC(hbm);
486     src->width = bm.bmWidth;
487     src->height = bm.bmHeight;
488     }else{
489     src->type = BG_COLOR;
490     }
491 maya 3227 }
492    
493 zmatsuo 7652 static void BGGetWallpaperInfo(WallpaperInfo *wi)
494 maya 3227 {
495 zmatsuo 10363 DWORD length;
496     int style;
497     int tile;
498     char str[256];
499     HKEY hKey;
500 maya 3227
501 zmatsuo 10363 wi->pattern = BG_CENTER;
502     wi->filename = NULL;
503 maya 3227
504 zmatsuo 10363 //���W�X�g���L�[���I�[�v��
505     if(RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
506     return;
507 maya 3227
508 zmatsuo 10363 //�����t�@�C�����Q�b�g
509 zmatsuo 10385 hRegQueryValueExW(hKey, L"Wallpaper", NULL, NULL, (void **)&wi->filename, NULL);
510 maya 3227
511 zmatsuo 10363 //�����X�^�C���Q�b�g
512     length = sizeof(str);
513     RegQueryValueExA(hKey,"WallpaperStyle",NULL,NULL,(BYTE*)str,&length);
514     style = atoi(str);
515 maya 3227
516 zmatsuo 10363 //�����X�^�C���Q�b�g
517     length = sizeof(str);
518     RegQueryValueExA(hKey,"TileWallpaper" ,NULL,NULL,(BYTE*)str,&length);
519     tile = atoi(str);
520 maya 3227
521 zmatsuo 10363 //���W�X�g���L�[���N���[�Y
522     RegCloseKey(hKey);
523 maya 3227
524 zmatsuo 10363 //�������������H
525     if(tile)
526     wi->pattern = BG_TILE;
527     else {
528     switch (style) {
529     case 0: // Center(�������\��)
530     wi->pattern = BG_CENTER;
531     break;
532     case 2: // Stretch(���������������L�k) �A�X�y�N�g��������������
533     wi->pattern = BG_STRETCH;
534     break;
535     case 10: // Fill(�y�[�W��������������) ���������A�a������������
536     // �A�X�y�N�g�������������A�����o�������������\������
537     wi->pattern = BG_AUTOFILL;
538     break;
539     case 6: // Fit(�y�[�W�c������������) ���������A�a������������
540     // �A�X�y�N�g�������������A�����o�����������������\������
541     wi->pattern = BG_AUTOFIT;
542     break;
543     }
544     }
545 maya 3227 }
546    
547 zmatsuo 10363 /**
548     * OleLoadPicture() ���g����������������
549     * jpeg, bmp ����������������������
550     * (Windows���������������`����������������������)
551     *
552     */
553 yutakapon 4568 // .bmp���O�������t�@�C���������B
554     // ������ .bmp ���O���t�@�C���������������������������B
555 maya 4571 // ���������� Windows 2000 ������������������������������
556 zmatsuo 10346 // TODO:
557     // IsLoadImageOnlyEnabled() �� Vista ����������������
558     //
559 zmatsuo 10353 static HBITMAP GetBitmapHandleW(const wchar_t *File)
560 maya 4571 {
561 yutakapon 4568 OLE_HANDLE hOle = 0;
562     IStream *iStream=NULL;
563     IPicture *iPicture;
564     HGLOBAL hMem;
565     LPVOID pvData;
566     DWORD nReadByte=0,nFileSize;
567     HANDLE hFile;
568     short type;
569     HBITMAP hBitmap = NULL;
570 zmatsuo 9898 HRESULT result;
571 yutakapon 4568
572 zmatsuo 10353 hFile=CreateFileW(File,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
573 maya 4582 if (hFile == INVALID_HANDLE_VALUE) {
574 zmatsuo 7977 return NULL;
575 maya 4582 }
576 yutakapon 4568 nFileSize=GetFileSize(hFile,NULL);
577     hMem=GlobalAlloc(GMEM_MOVEABLE,nFileSize);
578     pvData=GlobalLock(hMem);
579    
580     ReadFile(hFile,pvData,nFileSize,&nReadByte,NULL);
581    
582     GlobalUnlock(hMem);
583     CloseHandle(hFile);
584    
585     CreateStreamOnHGlobal(hMem,TRUE,&iStream);
586    
587 zmatsuo 9898 result = OleLoadPicture(iStream, nFileSize, FALSE, &IID_IPicture, (LPVOID *)&iPicture);
588     if (result != S_OK || iPicture == NULL) {
589     // �����t�@�C����������,�������������t�@�C������
590 zmatsuo 7977 return NULL;
591 zmatsuo 9898 }
592 yutakapon 6190
593 zmatsuo 7977 iStream->lpVtbl->Release(iStream);
594 yutakapon 4568
595     iPicture->lpVtbl->get_Type(iPicture,&type);
596     if(type==PICTYPE_BITMAP){
597     iPicture->lpVtbl->get_Handle(iPicture,&hOle);
598     }
599    
600 zmatsuo 10274 hBitmap=(HBITMAP)(UINT_PTR)hOle;
601 yutakapon 4568
602 zmatsuo 7977 return hBitmap;
603 yutakapon 4568 }
604    
605 yutakapon 4578 // ���`�����@���������r�I�N�����r�b�g�}�b�v���g���E�k�������B
606     // Windows 9x/NT����
607     // cf.http://katahiromz.web.fc2.com/win32/bilinear.html
608     static HBITMAP CreateStretched32BppBitmapBilinear(HBITMAP hbm, INT cxNew, INT cyNew)
609 maya 3227 {
610 yutakapon 4578 INT ix, iy, x0, y0, x1, y1;
611     DWORD x, y;
612     BITMAP bm;
613     HBITMAP hbmNew;
614     HDC hdc;
615     BITMAPINFO bi;
616     BYTE *pbNewBits, *pbBits, *pbNewLine, *pbLine0, *pbLine1;
617     DWORD wfactor, hfactor;
618     DWORD ex0, ey0, ex1, ey1;
619     DWORD r0, g0, b0, a0, r1, g1, b1, a1;
620     DWORD c00, c01, c10, c11;
621     LONG nWidthBytes, nWidthBytesNew;
622     BOOL fAlpha;
623 maya 3227
624 yutakapon 4578 if (GetObject(hbm, sizeof(BITMAP), &bm) == 0)
625     return NULL;
626 maya 3227
627 yutakapon 4578 hbmNew = NULL;
628     hdc = CreateCompatibleDC(NULL);
629     if (hdc != NULL)
630     {
631     nWidthBytes = bm.bmWidth * 4;
632     ZeroMemory(&bi, sizeof(BITMAPINFOHEADER));
633     bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
634     bi.bmiHeader.biWidth = bm.bmWidth;
635     bi.bmiHeader.biHeight = bm.bmHeight;
636     bi.bmiHeader.biPlanes = 1;
637     bi.bmiHeader.biBitCount = 32;
638     fAlpha = (bm.bmBitsPixel == 32);
639 doda 6435 pbBits = (BYTE *)HeapAlloc(GetProcessHeap(), 0,
640 yutakapon 4578 nWidthBytes * bm.bmHeight);
641     if (pbBits == NULL)
642     return NULL;
643     GetDIBits(hdc, hbm, 0, bm.bmHeight, pbBits, &bi, DIB_RGB_COLORS);
644     bi.bmiHeader.biWidth = cxNew;
645     bi.bmiHeader.biHeight = cyNew;
646     hbmNew = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS,
647     (VOID **)&pbNewBits, NULL, 0);
648     if (hbmNew != NULL)
649     {
650     nWidthBytesNew = cxNew * 4;
651     wfactor = (bm.bmWidth << 8) / cxNew;
652     hfactor = (bm.bmHeight << 8) / cyNew;
653     if (!fAlpha)
654     a0 = 255;
655     for(iy = 0; iy < cyNew; iy++)
656     {
657     y = hfactor * iy;
658     y0 = y >> 8;
659     y1 = min(y0 + 1, (INT)bm.bmHeight - 1);
660     ey1 = y & 0xFF;
661     ey0 = 0x100 - ey1;
662     pbNewLine = pbNewBits + iy * nWidthBytesNew;
663     pbLine0 = pbBits + y0 * nWidthBytes;
664     pbLine1 = pbBits + y1 * nWidthBytes;
665     for(ix = 0; ix < cxNew; ix++)
666     {
667     x = wfactor * ix;
668     x0 = x >> 8;
669     x1 = min(x0 + 1, (INT)bm.bmWidth - 1);
670     ex1 = x & 0xFF;
671     ex0 = 0x100 - ex1;
672     c00 = ((LPDWORD)pbLine0)[x0];
673     c01 = ((LPDWORD)pbLine1)[x0];
674     c10 = ((LPDWORD)pbLine0)[x1];
675     c11 = ((LPDWORD)pbLine1)[x1];
676    
677 doda 6435 b0 = ((ex0 * (c00 & 0xFF)) +
678 yutakapon 4578 (ex1 * (c10 & 0xFF))) >> 8;
679 doda 6435 b1 = ((ex0 * (c01 & 0xFF)) +
680 yutakapon 4578 (ex1 * (c11 & 0xFF))) >> 8;
681 doda 6435 g0 = ((ex0 * ((c00 >> 8) & 0xFF)) +
682 yutakapon 4578 (ex1 * ((c10 >> 8) & 0xFF))) >> 8;
683 doda 6435 g1 = ((ex0 * ((c01 >> 8) & 0xFF)) +
684 yutakapon 4578 (ex1 * ((c11 >> 8) & 0xFF))) >> 8;
685 doda 6435 r0 = ((ex0 * ((c00 >> 16) & 0xFF)) +
686 yutakapon 4578 (ex1 * ((c10 >> 16) & 0xFF))) >> 8;
687 doda 6435 r1 = ((ex0 * ((c01 >> 16) & 0xFF)) +
688 yutakapon 4578 (ex1 * ((c11 >> 16) & 0xFF))) >> 8;
689     b0 = (ey0 * b0 + ey1 * b1) >> 8;
690     g0 = (ey0 * g0 + ey1 * g1) >> 8;
691     r0 = (ey0 * r0 + ey1 * r1) >> 8;
692    
693     if (fAlpha)
694     {
695 doda 6435 a0 = ((ex0 * ((c00 >> 24) & 0xFF)) +
696 yutakapon 4578 (ex1 * ((c10 >> 24) & 0xFF))) >> 8;
697 doda 6435 a1 = ((ex0 * ((c01 >> 24) & 0xFF)) +
698 yutakapon 4578 (ex1 * ((c11 >> 24) & 0xFF))) >> 8;
699     a0 = (ey0 * a0 + ey1 * a1) >> 8;
700     }
701 doda 6435 ((LPDWORD)pbNewLine)[ix] =
702 yutakapon 4578 MAKELONG(MAKEWORD(b0, g0), MAKEWORD(r0, a0));
703     }
704     }
705     }
706     HeapFree(GetProcessHeap(), 0, pbBits);
707     DeleteDC(hdc);
708 maya 4571 }
709 yutakapon 4578 return hbmNew;
710     }
711 maya 3227
712 zmatsuo 7652 static void BGPreloadWallpaper(BGSrc *src)
713 yutakapon 4578 {
714     HBITMAP hbm;
715     WallpaperInfo wi;
716 yutakapon 4579 int s_width, s_height;
717 maya 3227
718 yutakapon 4578 BGGetWallpaperInfo(&wi);
719 maya 3227
720 yutakapon 5570 if (IsLoadImageOnlyEnabled()) {
721 yutakapon 4578 //��������������
722     //LR_CREATEDIBSECTION ���w�����������R�c
723     if (wi.pattern == BG_STRETCH) {
724 zmatsuo 10363 hbm = LoadImageW(0, wi.filename, IMAGE_BITMAP, CRTWidth, CRTHeight, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
725 yutakapon 4578 }
726     else {
727 zmatsuo 10363 hbm = LoadImageW(0, wi.filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
728 yutakapon 4578 }
729     }
730     else {
731 yutakapon 4579 BITMAP bm;
732     float ratio;
733    
734 zmatsuo 10363 hbm = GetBitmapHandleW(wi.filename);
735 maya 4582 if (hbm == NULL) {
736 zmatsuo 10363 goto load_finish;
737 maya 4582 }
738 maya 3227
739 yutakapon 4579 GetObject(hbm,sizeof(bm),&bm);
740     // ���������������������A�������X�g���b�`�T�C�Y���������B
741 yutakapon 4578 if (wi.pattern == BG_STRETCH) {
742 yutakapon 4579 s_width = CRTWidth;
743     s_height = CRTHeight;
744 maya 4581 } else if (wi.pattern == BG_AUTOFILL || wi.pattern == BG_AUTOFIT) {
745     if (wi.pattern == BG_AUTOFILL) {
746     if ((bm.bmHeight * CRTWidth) < (bm.bmWidth * CRTHeight)) {
747     wi.pattern = BG_FIT_HEIGHT;
748     }
749     else {
750     wi.pattern = BG_FIT_WIDTH;
751     }
752     }
753     if (wi.pattern == BG_AUTOFIT) {
754     if ((bm.bmHeight * CRTWidth) < (bm.bmWidth * CRTHeight)) {
755     wi.pattern = BG_FIT_WIDTH;
756     }
757     else {
758     wi.pattern = BG_FIT_HEIGHT;
759     }
760     }
761     if (wi.pattern == BG_FIT_WIDTH) {
762     ratio = (float)CRTWidth / bm.bmWidth;
763     s_width = CRTWidth;
764     s_height = (int)(bm.bmHeight * ratio);
765     }
766     else {
767     ratio = (float)CRTHeight / bm.bmHeight;
768     s_width = (int)(bm.bmWidth * ratio);
769     s_height = CRTHeight;
770     }
771    
772 yutakapon 4579 } else {
773     s_width = 0;
774     s_height = 0;
775     }
776    
777     if (s_width && s_height) {
778     HBITMAP newhbm = CreateStretched32BppBitmapBilinear(hbm, s_width, s_height);
779 yutakapon 4578 DeleteObject(hbm);
780     hbm = newhbm;
781 yutakapon 4579
782 doda 6435 wi.pattern = BG_STRETCH;
783 yutakapon 4578 }
784     }
785 zmatsuo 10363 load_finish:
786     free(wi.filename);
787 yutakapon 4578
788     //����DC������
789     if(hbm)
790     {
791     BITMAP bm;
792    
793     GetObject(hbm,sizeof(bm),&bm);
794    
795     src->hdc = CreateBitmapDC(hbm);
796     src->width = bm.bmWidth;
797     src->height = bm.bmHeight;
798     src->pattern = wi.pattern;
799    
800     }else{
801     src->hdc = NULL;
802     }
803    
804     src->color = GetSysColor(COLOR_DESKTOP);
805 maya 3227 }
806    
807 zmatsuo 7652 static void BGPreloadSrc(BGSrc *src)
808 maya 3227 {
809 zmatsuo 10391 if (!src->enable) {
810     return;
811     }
812    
813 zmatsuo 10336 DeleteBitmapDC(&(src->hdc));
814 maya 3227
815 zmatsuo 10336 switch (src->type) {
816     case BG_COLOR:
817     break;
818 maya 3227
819 zmatsuo 10336 case BG_WALLPAPER:
820     BGPreloadWallpaper(src);
821     break;
822 maya 3227
823 zmatsuo 10336 case BG_PICTURE:
824     BGPreloadPicture(src);
825     break;
826    
827     default:
828     break;
829     }
830 maya 3227 }
831    
832 zmatsuo 7652 static void BGStretchPicture(HDC hdcDest,BGSrc *src,int x,int y,int width,int height,BOOL bAntiAlias)
833 maya 3227 {
834 zmatsuo 10365 const wchar_t *filename = src->fileW;
835 yutakapon 5570 if(!hdcDest || !src)
836     return;
837 maya 3227
838 yutakapon 5570 if(bAntiAlias)
839     {
840     if(src->width != width || src->height != height)
841     {
842     HBITMAP hbm;
843 maya 3227
844 yutakapon 5570 if (IsLoadImageOnlyEnabled()) {
845 zmatsuo 10365 hbm = LoadImageW(0,filename,IMAGE_BITMAP,width,height,LR_LOADFROMFILE);
846 yutakapon 5570 } else {
847     HBITMAP newhbm;
848 zmatsuo 10365 hbm = GetBitmapHandleW(filename);
849 yutakapon 5570 newhbm = CreateStretched32BppBitmapBilinear(hbm, width, height);
850     DeleteObject(hbm);
851     hbm = newhbm;
852     }
853 maya 3227
854 yutakapon 5570 if(!hbm)
855     return;
856    
857     DeleteBitmapDC(&(src->hdc));
858     src->hdc = CreateBitmapDC(hbm);
859     src->width = width;
860     src->height = height;
861     }
862    
863     BitBlt(hdcDest,x,y,width,height,src->hdc,0,0,SRCCOPY);
864     }else{
865     SetStretchBltMode(src->hdc,COLORONCOLOR);
866     StretchBlt(hdcDest,x,y,width,height,src->hdc,0,0,src->width,src->height,SRCCOPY);
867     }
868 maya 3227 }
869    
870 zmatsuo 7652 static void BGLoadPicture(HDC hdcDest,BGSrc *src)
871 maya 3227 {
872     int x,y,width,height,pattern;
873    
874     FillBitmapDC(hdcDest,src->color);
875    
876     if(!src->height || !src->width)
877     return;
878    
879     if(src->pattern == BG_AUTOFIT){
880     if((src->height * ScreenWidth) > (ScreenHeight * src->width))
881     pattern = BG_FIT_WIDTH;
882     else
883     pattern = BG_FIT_HEIGHT;
884     }else{
885     pattern = src->pattern;
886     }
887    
888     switch(pattern)
889     {
890     case BG_STRETCH :
891     BGStretchPicture(hdcDest,src,0,0,ScreenWidth,ScreenHeight,src->antiAlias);
892     break;
893    
894     case BG_FIT_WIDTH :
895    
896     height = (src->height * ScreenWidth) / src->width;
897     y = (ScreenHeight - height) / 2;
898 doda 6435
899 maya 3227 BGStretchPicture(hdcDest,src,0,y,ScreenWidth,height,src->antiAlias);
900     break;
901    
902     case BG_FIT_HEIGHT :
903    
904     width = (src->width * ScreenHeight) / src->height;
905     x = (ScreenWidth - width) / 2;
906    
907     BGStretchPicture(hdcDest,src,x,0,width,ScreenHeight,src->antiAlias);
908     break;
909    
910     case BG_TILE :
911     for(x = 0;x < ScreenWidth ;x += src->width )
912     for(y = 0;y < ScreenHeight;y += src->height)
913     BitBlt(hdcDest,x,y,src->width,src->height,src->hdc,0,0,SRCCOPY);
914     break;
915    
916     case BG_CENTER :
917     x = (ScreenWidth - src->width) / 2;
918     y = (ScreenHeight - src->height) / 2;
919    
920     BitBlt(hdcDest,x,y,src->width,src->height,src->hdc,0,0,SRCCOPY);
921     break;
922     }
923     }
924    
925     typedef struct tagLoadWallpaperStruct
926     {
927     RECT *rectClient;
928     HDC hdcDest;
929     BGSrc *src;
930     }LoadWallpaperStruct;
931    
932 zmatsuo 7652 static BOOL CALLBACK BGLoadWallpaperEnumFunc(HMONITOR hMonitor,HDC hdcMonitor,LPRECT lprcMonitor,LPARAM dwData)
933 maya 3227 {
934     RECT rectDest;
935     RECT rectRgn;
936     int monitorWidth;
937     int monitorHeight;
938     int destWidth;
939     int destHeight;
940     HRGN hRgn;
941     int x;
942     int y;
943 zmatsuo 10337 LoadWallpaperStruct *lws;
944    
945 zmatsuo 10334 (void)hMonitor;
946     (void)hdcMonitor;
947 maya 3227
948 zmatsuo 10337 lws = (LoadWallpaperStruct*)dwData;
949 maya 3227
950     if(!IntersectRect(&rectDest,lprcMonitor,lws->rectClient))
951     return TRUE;
952    
953     //���j�^�[�������������������}�X�N
954     SaveDC(lws->hdcDest);
955     CopyRect(&rectRgn,&rectDest);
956     OffsetRect(&rectRgn,- lws->rectClient->left,- lws->rectClient->top);
957     hRgn = CreateRectRgnIndirect(&rectRgn);
958     SelectObject(lws->hdcDest,hRgn);
959    
960     //���j�^�[��������
961     monitorWidth = lprcMonitor->right - lprcMonitor->left;
962     monitorHeight = lprcMonitor->bottom - lprcMonitor->top;
963    
964     destWidth = rectDest.right - rectDest.left;
965     destHeight = rectDest.bottom - rectDest.top;
966    
967     switch(lws->src->pattern)
968     {
969     case BG_CENTER :
970     case BG_STRETCH :
971    
972     SetWindowOrgEx(lws->src->hdc,
973     lprcMonitor->left + (monitorWidth - lws->src->width )/2,
974     lprcMonitor->top + (monitorHeight - lws->src->height)/2,NULL);
975     BitBlt(lws->hdcDest ,rectDest.left,rectDest.top,destWidth,destHeight,
976     lws->src->hdc,rectDest.left,rectDest.top,SRCCOPY);
977    
978     break;
979     case BG_TILE :
980 doda 6435
981 maya 3227 SetWindowOrgEx(lws->src->hdc,0,0,NULL);
982    
983     for(x = rectDest.left - (rectDest.left % lws->src->width ) - lws->src->width ;
984     x < rectDest.right ;x += lws->src->width )
985     for(y = rectDest.top - (rectDest.top % lws->src->height) - lws->src->height;
986     y < rectDest.bottom;y += lws->src->height)
987     BitBlt(lws->hdcDest,x,y,lws->src->width,lws->src->height,lws->src->hdc,0,0,SRCCOPY);
988     break;
989 zmatsuo 10336 default:
990     break;
991 maya 3227 }
992    
993     //���[�W�������j��
994     RestoreDC(lws->hdcDest,-1);
995     DeleteObject(hRgn);
996    
997     return TRUE;
998     }
999    
1000 zmatsuo 9943 static void BGLoadWallpaper(HDC hdcDest,BGSrc *src)
1001 maya 3227 {
1002     RECT rectClient;
1003     POINT point;
1004     LoadWallpaperStruct lws;
1005    
1006     //�����������f�X�N�g�b�v�F���h��������
1007     FillBitmapDC(hdcDest,src->color);
1008    
1009     //����������������������
1010     if(!src->hdc)
1011     return;
1012    
1013     //hdcDest�����W�n�����z�X�N���[������������
1014     point.x = 0;
1015     point.y = 0;
1016     ClientToScreen(HVTWin,&point);
1017    
1018     SetWindowOrgEx(hdcDest,point.x,point.y,NULL);
1019    
1020     //���z�X�N���[�������N���C�A���g����
1021     GetClientRect(HVTWin,&rectClient);
1022     OffsetRect(&rectClient,point.x,point.y);
1023    
1024     //���j�^�[������
1025     lws.rectClient = &rectClient;
1026     lws.src = src;
1027     lws.hdcDest = hdcDest;
1028    
1029 zmatsuo 7457 if(pEnumDisplayMonitors != NULL)
1030 maya 3227 {
1031 zmatsuo 7457 (*pEnumDisplayMonitors)(NULL,NULL,BGLoadWallpaperEnumFunc,(LPARAM)&lws);
1032 maya 3227 }else{
1033     RECT rectMonitor;
1034 doda 6435
1035 maya 3227 SetRect(&rectMonitor,0,0,CRTWidth,CRTHeight);
1036     BGLoadWallpaperEnumFunc(NULL,NULL,&rectMonitor,(LPARAM)&lws);
1037     }
1038    
1039     //���W�n������
1040     SetWindowOrgEx(hdcDest,0,0,NULL);
1041     }
1042    
1043 zmatsuo 10336 static void BGLoadSrc(HDC hdcDest, BGSrc *src)
1044 maya 3227 {
1045 zmatsuo 10336 switch (src->type) {
1046     case BG_COLOR:
1047     FillBitmapDC(hdcDest, src->color);
1048     break;
1049 maya 3227
1050 zmatsuo 10336 case BG_WALLPAPER:
1051     BGLoadWallpaper(hdcDest, src);
1052     break;
1053 maya 3227
1054 zmatsuo 10336 case BG_PICTURE:
1055     BGLoadPicture(hdcDest, src);
1056     break;
1057 zmatsuo 10391
1058 zmatsuo 10336 default:
1059     break;
1060     }
1061 maya 3227 }
1062    
1063 zmatsuo 10385 /**
1064     * 32bit bitmap ���� alpha���g�p������������������
1065     * �s������bitmap�����l������
1066     */
1067     static BOOL IsAlphaValidBitmap(HBITMAP hBmp)
1068     {
1069     BITMAP bm;
1070     BOOL alpha = FALSE;
1071    
1072     assert(hBmp != NULL);
1073    
1074     // 1pixel��������bit�����`�F�b�N����
1075     GetObject(hBmp, sizeof(bm), &bm);
1076     if (bm.bmBitsPixel != 32) {
1077     // 32bit/pixel ���O������ alpha ����������
1078     return FALSE;
1079     }
1080    
1081     // alpha�������g�p�������������`�F�b�N����
1082     // ���������s�N�Z�����s������������������������
1083     {
1084     // DIB���������� hBmp ���R�s�[��
1085     // hBmp �� DDB ������ pixel�������`�F�b�N������������ DIB ���R�s�[(BitBlt)����
1086     LONG width;
1087     LONG height;
1088     BITMAPINFO bmi;
1089     void* pvBits;
1090     HBITMAP hBmpDIB;
1091     HBITMAP hBmpCopy;
1092     HDC HDCDest;
1093     HDC HDCSrc;
1094     HBITMAP prev1;
1095     HBITMAP prev2;
1096     DWORD *p;
1097     LONG i;
1098    
1099     width = bm.bmWidth;
1100     height = bm.bmHeight;
1101     memset(&bmi, 0, sizeof(bmi));
1102     bmi.bmiHeader.biSize = sizeof(bmi);
1103     bmi.bmiHeader.biWidth = width;
1104     bmi.bmiHeader.biHeight = height;
1105     bmi.bmiHeader.biPlanes = 1;
1106     bmi.bmiHeader.biBitCount = 32; // = 8*4
1107     bmi.bmiHeader.biCompression = BI_RGB;
1108     bmi.bmiHeader.biSizeImage = width * height * 4;
1109     hBmpDIB = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
1110    
1111 zmatsuo 10391 // hBmp �� SelectObject() ��������������
1112 zmatsuo 10385 // ��HDC��SelectObject()�������������R�s�[��������
1113     hBmpCopy = (HBITMAP)CopyImage(hBmp, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
1114    
1115     // hBmp(hBmpCopy)��DIB���R�s�[(BitBlt)����
1116     HDCDest = CreateCompatibleDC(NULL);
1117     HDCSrc = CreateCompatibleDC(NULL);
1118     prev1 = SelectObject(HDCDest, hBmpDIB);
1119     prev2 = SelectObject(HDCSrc, hBmpCopy);
1120     BitBlt(HDCDest, 0, 0, width, height, HDCSrc, 0, 0, SRCCOPY);
1121    
1122     // alpha�l���`�F�b�N����
1123     p = pvBits;
1124     for (i = 0; i < width * height; i++) {
1125     DWORD pix = *p++;
1126     if ((pix & 0xff000000) != 0xff000000) {
1127     alpha = TRUE;
1128     break;
1129     }
1130     }
1131    
1132     // �j��
1133     SelectObject(HDCDest, prev1);
1134     SelectObject(HDCSrc, prev2);
1135     DeleteObject(hBmpDIB);
1136     DeleteObject(hBmpCopy);
1137     DeleteDC(HDCDest);
1138     DeleteDC(HDCSrc);
1139     }
1140     return alpha;
1141     }
1142    
1143     static BOOL IsAlphaValidBitmapHDC(HDC hDC)
1144     {
1145     HBITMAP hBmp;
1146    
1147     assert(hDC != NULL);
1148     hBmp = GetCurrentObject(hDC, OBJ_BITMAP);
1149     return IsAlphaValidBitmap(hBmp);
1150     }
1151    
1152     /**
1153     * �w�i��������
1154     */
1155     static HDC CreateBGImage(int width, int height)
1156     {
1157     BLENDFUNCTION bf;
1158     HDC hdc_work;
1159     HDC hdc_bg;
1160    
1161     hdc_bg = CreateBitmapDC(CreateScreenCompatibleBitmap(width, height));
1162     hdc_work = CreateBitmapDC(CreateScreenCompatibleBitmap(width, height));
1163    
1164     // ����(Windows���f�X�N�g�b�v�w�i)
1165     if (BGSrc1.enable) {
1166     BGLoadSrc(hdc_bg, &BGSrc1);
1167     }
1168     DebugSaveFile(L"bg_1.bmp", hdc_bg, width, height);
1169    
1170     // �w������
1171     if (BGDest.enable && BGDest.hdc != NULL) {
1172 zmatsuo 10391 BOOL alpha_valid;
1173    
1174     // ���������[�h(�`��)����
1175     BGLoadSrc(hdc_work, &BGDest);
1176     alpha_valid = IsAlphaValidBitmapHDC(BGDest.hdc);
1177    
1178     // ���������������\���t����
1179 zmatsuo 10385 memset(&bf, 0, sizeof(bf));
1180     bf.BlendOp = AC_SRC_OVER;
1181     bf.SourceConstantAlpha = BGDest.alpha;
1182     bf.AlphaFormat = 0;
1183 zmatsuo 10391 if (alpha_valid) {
1184 zmatsuo 10385 // 32bit�r�b�g�}�b�v(alpha�l��������������)������alpha�l���Q������
1185     bf.AlphaFormat = AC_SRC_ALPHA;
1186     }
1187 zmatsuo 10396 if (!BGSrc1.enable) {
1188     // ���������������������������h��������������
1189     FillBitmapDC(hdc_bg, BGDest.color);
1190     }
1191 zmatsuo 10385 BGAlphaBlend(hdc_bg, 0, 0, width, height, hdc_work, 0, 0, width, height, bf);
1192     }
1193     DebugSaveFile(L"bg_2.bmp", hdc_bg, width, height);
1194    
1195     // �P�F�v���[��
1196     if (BGSrc2.enable) {
1197 zmatsuo 10391 // ����������
1198     BGLoadSrc(hdc_work, &BGSrc2);
1199    
1200     // �\���t����
1201 zmatsuo 10385 memset(&bf, 0, sizeof(bf));
1202     bf.BlendOp = AC_SRC_OVER;
1203 zmatsuo 10399 if (BGDest.enable || BGSrc1.enable) {
1204     bf.SourceConstantAlpha = BGSrc2.alpha;
1205     }
1206     else {
1207     // �u�����h������������������alpha���g������(�P�����h��������)
1208     bf.SourceConstantAlpha = 255;
1209     }
1210 zmatsuo 10385 bf.AlphaFormat = 0;
1211     BGAlphaBlend(hdc_bg, 0, 0, width, height, hdc_work, 0, 0, width, height, bf);
1212     }
1213     DebugSaveFile(L"bg_3.bmp", hdc_bg, width, height);
1214    
1215     DeleteBitmapDC(&hdc_work);
1216    
1217     return hdc_bg;
1218     }
1219    
1220     /**
1221     *
1222     * ThemeSetBG(), ThemeSetColor() ���������R�[������
1223     *
1224     * @param forceSetup FALSE WM_PAINT��
1225     * TRUE ���O
1226     *
1227     */
1228 maya 3227 void BGSetupPrimary(BOOL forceSetup)
1229     {
1230     POINT point;
1231     RECT rect;
1232    
1233     if(!BGEnable)
1234     return;
1235    
1236     //�������u�A�������������������`�F�b�N
1237     point.x = 0;
1238     point.y = 0;
1239     ClientToScreen(HVTWin,&point);
1240 doda 6435
1241 maya 3227 GetClientRect(HVTWin,&rect);
1242     OffsetRect(&rect,point.x,point.y);
1243    
1244     if(!forceSetup && EqualRect(&rect,&BGPrevRect))
1245     return;
1246    
1247     CopyRect(&BGPrevRect,&rect);
1248    
1249 zmatsuo 10134 //���� or �w�i���v�����[�h
1250     BGPreloadSrc(&BGDest);
1251     BGPreloadSrc(&BGSrc1);
1252     BGPreloadSrc(&BGSrc2);
1253    
1254 maya 3227 #ifdef _DEBUG
1255 zmatsuo 7645 OutputDebugPrintf("BGSetupPrimary : BGInSizeMove = %d\n",BGInSizeMove);
1256 maya 3227 #endif
1257    
1258     //�����p DC ����
1259     if(hdcBGWork) DeleteBitmapDC(&hdcBGWork);
1260     if(hdcBGBuffer) DeleteBitmapDC(&hdcBGBuffer);
1261    
1262     hdcBGWork = CreateBitmapDC(CreateScreenCompatibleBitmap(ScreenWidth,FontHeight));
1263     hdcBGBuffer = CreateBitmapDC(CreateScreenCompatibleBitmap(ScreenWidth,FontHeight));
1264    
1265     //hdcBGBuffer ����������
1266     SetBkMode(hdcBGBuffer,TRANSPARENT);
1267    
1268     if(!BGInSizeMove)
1269     {
1270 zmatsuo 10385 //�w�i HDC
1271     if(hdcBG) {
1272     DeleteBitmapDC(&hdcBG);
1273     }
1274 maya 3227
1275 zmatsuo 10385 hdcBG = CreateBGImage(ScreenWidth, ScreenHeight);
1276 maya 3227 }
1277     }
1278    
1279 zmatsuo 10134 /**
1280 zmatsuo 10256 * �e�[�}�t�@�C����������������������
1281     *
1282     * @param file NULL�����t�@�C����������������(�f�t�H���g�l������)
1283 zmatsuo 10134 */
1284 zmatsuo 9958 static void BGReadIniFile(const wchar_t *file)
1285 maya 3227 {
1286 zmatsuo 10256 BGTheme bg_theme;
1287     TColorTheme color_theme;
1288     ThemeLoad(file, &bg_theme, &color_theme);
1289     ThemeSetBG(&bg_theme);
1290     ThemeSetColor(&color_theme);
1291 maya 3227 }
1292    
1293 zmatsuo 9992 static void BGDestruct(void)
1294 maya 3227 {
1295     if(!BGEnable)
1296     return;
1297    
1298     DeleteBitmapDC(&hdcBGBuffer);
1299     DeleteBitmapDC(&hdcBGWork);
1300     DeleteBitmapDC(&hdcBG);
1301     DeleteBitmapDC(&(BGDest.hdc));
1302     DeleteBitmapDC(&(BGSrc1.hdc));
1303     DeleteBitmapDC(&(BGSrc2.hdc));
1304    
1305 zmatsuo 10134 BGEnable = FALSE;
1306 maya 3227 }
1307    
1308 zmatsuo 10134 static void BGSetDefaultColor(TTTSet *pts)
1309     {
1310 zmatsuo 10256 TColorTheme color_theme;
1311     ThemeGetColorDefaultTS(pts, &color_theme);
1312     ThemeSetColor(&color_theme);
1313 zmatsuo 10134 }
1314    
1315 yutakapon 8106 /*
1316     * Eterm lookfeel�@�\����������������
1317     *
1318 zmatsuo 8814 * initialize_once:
1319 yutakapon 8106 * TRUE: Tera Term���N����
1320     * FALSE: Tera Term���N�������O
1321     */
1322     void BGInitialize(BOOL initialize_once)
1323 maya 3227 {
1324 zmatsuo 10134 (void)initialize_once;
1325 maya 3227
1326 zmatsuo 10274 InitColorTable(ts.ANSIColor);
1327 zmatsuo 10256
1328 zmatsuo 10134 BGSetDefaultColor(&ts);
1329 yutakapon 8106
1330 zmatsuo 9943 //���\�[�X����
1331     BGDestruct();
1332 maya 3227
1333 zmatsuo 10134 // AlphaBlend ���A�h���X����������
1334     if (ts.EtermLookfeel.BGUseAlphaBlendAPI) {
1335     if (pAlphaBlend != NULL)
1336     BGAlphaBlend = pAlphaBlend;
1337     else
1338     BGAlphaBlend = AlphaBlendWithoutAPI;
1339     }
1340     else {
1341     BGAlphaBlend = AlphaBlendWithoutAPI;
1342     }
1343     }
1344 maya 3227
1345 zmatsuo 10134 /**
1346     * �e�[�}���������`�F�b�N���� BG�������s����(BGEnable=TRUE/FALSE)��������
1347     */
1348     static void DecideBGEnable(void)
1349     {
1350 zmatsuo 10334 vtdisp_work_t *w = &vtdisp_work;
1351    
1352 zmatsuo 10134 // �w�i�����`�F�b�N
1353 zmatsuo 10365 if (BGDest.fileW == NULL || BGDest.fileW[0] == 0) {
1354 zmatsuo 10134 // �w�i�������g�p������
1355 zmatsuo 10385 BGDest.enable = FALSE;
1356 zmatsuo 10134 }
1357 maya 3227
1358 zmatsuo 10385 if (BGDest.enable == FALSE && BGSrc1.enable == FALSE && BGSrc2.enable == FALSE) {
1359 zmatsuo 10134 // BG���g�p������
1360     BGEnable = FALSE;
1361 zmatsuo 10334 w->bg_enable = FALSE;
1362 zmatsuo 9943 }
1363 zmatsuo 10134 else {
1364     BGEnable = TRUE;
1365 zmatsuo 10334 w->bg_enable = TRUE;
1366 zmatsuo 10134 }
1367     }
1368 maya 3227
1369 zmatsuo 10256 /**
1370     * �e�[�}���������s��
1371     * �e�[�}���������f�t�H���g��������
1372     * �e�[�}���������e�[�}�t�@�C���������o������������
1373     */
1374 zmatsuo 10385 void BGLoadThemeFile(const TTTSet *pts)
1375 zmatsuo 10134 {
1376     // �R���t�B�O�t�@�C��(�e�[�}�t�@�C��)������
1377     switch(pts->EtermLookfeel.BGEnable) {
1378     case 0:
1379     default:
1380 zmatsuo 10256 // �e�[�}����
1381     BGReadIniFile(NULL);
1382 zmatsuo 10134 BGEnable = FALSE;
1383     break;
1384     case 1:
1385     if (pts->EtermLookfeel.BGThemeFileW != NULL) {
1386     // �e�[�}�t�@�C�����w��������
1387     BGReadIniFile(pts->EtermLookfeel.BGThemeFileW);
1388     BGEnable = TRUE;
1389     }
1390     else {
1391     BGEnable = FALSE;
1392     }
1393     break;
1394     case 2: {
1395     // �����_���e�[�} (or �e�[�}�t�@�C�����w��������)
1396     wchar_t *theme_mask;
1397     wchar_t *theme_file;
1398     aswprintf(&theme_mask, L"%s\\theme\\*.ini", pts->HomeDirW);
1399     theme_file = RandomFileW(theme_mask);
1400     free(theme_mask);
1401     BGReadIniFile(theme_file);
1402     free(theme_file);
1403     BGEnable = TRUE;
1404     break;
1405 zmatsuo 9943 }
1406     }
1407 zmatsuo 10134
1408     DecideBGEnable();
1409 maya 3227 }
1410    
1411 zmatsuo 10338 /**
1412     * �f�o�O�p�Abox���`������
1413     */
1414     static void DrawBox(HDC hdc, int sx, int sy, int width, int height, COLORREF rgb)
1415     {
1416 zmatsuo 10775 HPEN red_pen = CreatePen(PS_SOLID, 0, rgb);
1417     HGDIOBJ old_pen = SelectObject(hdc, red_pen);
1418 zmatsuo 10728 width--;
1419     height--;
1420 zmatsuo 10338 MoveToEx(hdc, sx, sy, NULL);
1421     LineTo(hdc, sx + width, sy);
1422     LineTo(hdc, sx + width, sy + height);
1423     LineTo(hdc, sx, sy + height);
1424     LineTo(hdc, sx, sy);
1425     MoveToEx(hdc, sx, sy, NULL);
1426     LineTo(hdc, sx + width, sy + height);
1427     MoveToEx(hdc, sx + width, sy, NULL);
1428     LineTo(hdc, sx, sy + height);
1429     SelectObject(hdc, old_pen);
1430     DeleteObject(red_pen);
1431     }
1432    
1433     /**
1434     * @brief �������w�i����������
1435     * hdc �� (0,0)-(width,height) �������w�i����������
1436     * alpha���l���������w�i����(hdcBG)���u�����h����
1437     *
1438     * @param hdc �`������hdc
1439     * @param X �������u(�w�i���������u)
1440     * @param Y
1441     * @param width �����T�C�Y
1442     * @param height
1443     * @param alpha �w�i�������s�����x 0..255
1444     * 0=�w�i���������������]��������
1445     * 255=�w�i������(�e������)
1446     */
1447     static void DrawTextBGImage(HDC hdc, int X, int Y, int width, int height, COLORREF color, unsigned char alpha)
1448     {
1449     HBRUSH hbr = CreateSolidBrush(color);
1450    
1451     // hdc���w�i�������`��
1452     if (BGInSizeMove) {
1453     // BGInSizeMove!=0��(���������A���T�C�Y��)
1454     RECT rect;
1455     SetRect(&rect, 0, 0, width, height);
1456     //FillRect(hdc, &rect, BGBrushInSizeMove); // �w�i�� BGBrushInSizeMove ���h��������
1457     FillRect(hdc, &rect, hbr);
1458     }
1459     else {
1460     RECT rect;
1461     BLENDFUNCTION bf;
1462     BOOL r;
1463    
1464     // ���[�NDC���������w�i���`��
1465     SetRect(&rect, 0, 0, width, height);
1466     FillRect(hdcBGWork, &rect, hbr);
1467    
1468     // �s������
1469     // �w�i�������������������w�i���]��
1470     BitBlt(hdc, 0, 0, width, height, hdcBG, X, Y, SRCCOPY);
1471    
1472     // hdc�����[�NDC���p�������������w�i��alphablend
1473     ZeroMemory(&bf, sizeof(bf));
1474     bf.BlendOp = AC_SRC_OVER;
1475     bf.SourceConstantAlpha = alpha;
1476     r = BGAlphaBlend(hdc, 0, 0, width, height, hdcBGWork, 0, 0, width, height, bf);
1477     assert(r == TRUE);
1478     (void)r;
1479     }
1480    
1481     DeleteObject(hbr);
1482     }
1483    
1484 zmatsuo 9992 static void BGScrollWindow(HWND hwnd, int xa, int ya, RECT *Rect, RECT *ClipRect)
1485 maya 3227 {
1486 doda 6672 RECT r;
1487    
1488 doda 6669 if (BGEnable) {
1489     InvalidateRect(HVTWin, ClipRect, FALSE);
1490 maya 3227 }
1491 doda 6672 else if (IsZoomed(hwnd)) {
1492 doda 6669 // �E�B���h�E����������������������
1493 doda 6672 switch (ts.MaximizedBugTweak) {
1494     case 1: // type 1: ScrollWindow ���g��������������������
1495     InvalidateRect(HVTWin, ClipRect, FALSE);
1496     break;
1497 doda 6730 case 2: // type 2: �X�N���[���������S��(NULL)��������������������������������������
1498 doda 6672 if (Rect == NULL) {
1499     GetClientRect(hwnd, &r);
1500     r.bottom -= r.bottom % ts.TerminalHeight;
1501     Rect = &r;
1502     }
1503     /* FALLTHROUGH */
1504     default:
1505     ScrollWindow(hwnd, xa, ya, Rect, ClipRect);
1506     break;
1507     }
1508 doda 6669 }
1509     else {
1510     ScrollWindow(hwnd, xa, ya, Rect, ClipRect);
1511     }
1512 maya 3227 }
1513    
1514     void BGOnEnterSizeMove(void)
1515     {
1516 zmatsuo 10134 if(!BGEnable || !ts.EtermLookfeel.BGFastSizeMove)
1517 maya 3227 return;
1518    
1519     BGInSizeMove = TRUE;
1520     }
1521    
1522     void BGOnExitSizeMove(void)
1523     {
1524 zmatsuo 10134 if(!BGEnable || !ts.EtermLookfeel.BGFastSizeMove)
1525 maya 3227 return;
1526    
1527     BGInSizeMove = FALSE;
1528    
1529     BGSetupPrimary(TRUE);
1530     InvalidateRect(HVTWin,NULL,FALSE);
1531    
1532 zmatsuo 10338 #if 0
1533 maya 3227 //�u���V������
1534     if(BGBrushInSizeMove)
1535     {
1536     DeleteObject(BGBrushInSizeMove);
1537     BGBrushInSizeMove = NULL;
1538     }
1539 zmatsuo 10338 #endif
1540 maya 3227 }
1541    
1542 zmatsuo 10385 /**
1543     * WM_SETTINGCHANGE ���������o��
1544     */
1545 maya 3227 void BGOnSettingChange(void)
1546     {
1547 zmatsuo 10385 if(!BGEnable)
1548     return;
1549 maya 3227
1550 zmatsuo 10385 // TODO ���j�^(�f�B�X�v���C)�����������T�C�Y����������������?
1551     CRTWidth = GetSystemMetrics(SM_CXSCREEN);
1552     CRTHeight = GetSystemMetrics(SM_CYSCREEN);
1553 maya 3227
1554 zmatsuo 10385 BGSetupPrimary(TRUE);
1555     InvalidateRect(HVTWin, NULL, FALSE);
1556 maya 3227 }
1557    
1558 zmatsuo 10274 /**
1559     * ��16�F�J���[�e�[�u��(ts.ANSIColor[16])���F��������
1560     * 256�F�J���[�e�[�u��(ANSIColor[256])���F����������
1561     *
1562     * @param index16 16�F���F����
1563     */
1564     static int GetIndex256From16(int index16)
1565     {
1566     // ANSIColor16���A������/�����O���[�v������������������
1567 zmatsuo 10332 static const int index256[] = {
1568 zmatsuo 10274 0,
1569     9, 10, 11, 12, 13, 14, 15,
1570     8,
1571     1, 2, 3, 4, 5, 6, 7
1572     };
1573     return index16 < _countof(index256) ? index256[index16] : index16;
1574     }
1575 maya 3227
1576 zmatsuo 10274 /**
1577     * 256�F�J���[�e�[�u��(ANSIColor[256])���F��������
1578     * ��16�F�J���[�e�[�u��(ts.ANSIColor[16])���F����������
1579     *
1580     * @param index256 256�F���F����
1581     */
1582     static int GetIndex16From256(int index256)
1583     {
1584     return GetIndex256From16(index256);
1585 maya 3227 }
1586    
1587 zmatsuo 10274 /**
1588     * ANSI�J���[�e�[�u��(ANSIColor[256])������������
1589     *
1590     * @param ANSIColor16 ts.ANSIColor[16]
1591     * ��16�F�J���[�e�[�u��
1592     */
1593     static void InitColorTable(const COLORREF *ANSIColor16)
1594 maya 3227 {
1595 zmatsuo 10274 int i;
1596 doda 5700
1597 zmatsuo 10274 // ANSIColor[] ������16�F��������
1598     // ANSIColor16��16�F�J���[�e�[�u��
1599     for (i = 0 ; i < 16 ; i++) {
1600     int i256 = GetIndex256From16(i);
1601     ANSIColor[i256] = ANSIColor16[i];
1602     }
1603 doda 5700
1604 zmatsuo 10274 // ANSIColor[] ��16�����~��������
1605     for (i=16; i<=255; i++) {
1606     ANSIColor[i] = RGB(DefaultColorTable[i][0], DefaultColorTable[i][1], DefaultColorTable[i][2]);
1607     }
1608 maya 3227 }
1609    
1610 zmatsuo 10274 static void DispSetNearestColors(int start, int end, HDC DispCtx)
1611     {
1612     #if 1
1613     // ������
1614     (void)start;
1615     (void)end;
1616     (void)DispCtx;
1617     #else
1618 maya 3227 HDC TmpDC;
1619     int i;
1620    
1621     if (DispCtx) {
1622     TmpDC = DispCtx;
1623     }
1624     else {
1625     TmpDC = GetDC(NULL);
1626     }
1627    
1628     for (i = start ; i <= end; i++)
1629     ANSIColor[i] = GetNearestColor(TmpDC, ANSIColor[i]);
1630    
1631     if (!DispCtx) {
1632     ReleaseDC(NULL, TmpDC);
1633     }
1634 zmatsuo 10274 #endif
1635 maya 3227 }
1636    
1637 zmatsuo 9991 void InitDisp(void)
1638 maya 3227 {
1639     HDC TmpDC;
1640     BOOL bMultiDisplaySupport = FALSE;
1641 zmatsuo 10334 vtdisp_work_t *w = &vtdisp_work;
1642 maya 3227
1643     TmpDC = GetDC(NULL);
1644    
1645     CRTWidth = GetSystemMetrics(SM_CXSCREEN);
1646     CRTHeight = GetSystemMetrics(SM_CYSCREEN);
1647    
1648 yutakapon 8106 BGInitialize(TRUE);
1649 maya 3227
1650     DispSetNearestColors(IdBack, 255, TmpDC);
1651    
1652     /* background paintbrush */
1653     Background = CreateSolidBrush(ts.VTColor[1]);
1654     /* CRT width & height */
1655 yutakapon 6286 if (HasMultiMonitorSupport()) {
1656     bMultiDisplaySupport = TRUE;
1657 maya 3227 }
1658     if( bMultiDisplaySupport ) {
1659     VirtualScreen.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
1660     VirtualScreen.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
1661     VirtualScreen.right = VirtualScreen.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
1662     VirtualScreen.bottom = VirtualScreen.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
1663     } else {
1664     VirtualScreen.left = 0;
1665     VirtualScreen.top = 0;
1666     VirtualScreen.right = GetDeviceCaps(TmpDC,HORZRES);
1667     VirtualScreen.bottom = GetDeviceCaps(TmpDC,VERTRES);
1668     }
1669    
1670     ReleaseDC(NULL, TmpDC);
1671    
1672     if ( (ts.VTPos.x > VirtualScreen.right) || (ts.VTPos.y > VirtualScreen.bottom) )
1673     {
1674     ts.VTPos.x = CW_USEDEFAULT;
1675     ts.VTPos.y = CW_USEDEFAULT;
1676     }
1677     else if ( (ts.VTPos.x < VirtualScreen.left-20) || (ts.VTPos.y < VirtualScreen.top-20) )
1678     {
1679     ts.VTPos.x = CW_USEDEFAULT;
1680     ts.VTPos.y = CW_USEDEFAULT;
1681     }
1682     else {
1683     if ( ts.VTPos.x < VirtualScreen.left ) ts.VTPos.x = VirtualScreen.left;
1684     if ( ts.VTPos.y < VirtualScreen.top ) ts.VTPos.y = VirtualScreen.top;
1685     }
1686    
1687     if ( (ts.TEKPos.x > VirtualScreen.right) || (ts.TEKPos.y > VirtualScreen.bottom) )
1688     {
1689     ts.TEKPos.x = CW_USEDEFAULT;
1690     ts.TEKPos.y = CW_USEDEFAULT;
1691     }
1692     else if ( (ts.TEKPos.x < VirtualScreen.left-20) || (ts.TEKPos.y < VirtualScreen.top-20) )
1693     {
1694     ts.TEKPos.x = CW_USEDEFAULT;
1695     ts.TEKPos.y = CW_USEDEFAULT;
1696     }
1697     else {
1698     if ( ts.TEKPos.x < VirtualScreen.left ) ts.TEKPos.x = VirtualScreen.left;
1699     if ( ts.TEKPos.y < VirtualScreen.top ) ts.TEKPos.y = VirtualScreen.top;
1700     }
1701 zmatsuo 10334
1702     w->bg_enable = FALSE;
1703 zmatsuo 10338 w->alpha_back = 255;
1704     w->alpha_vtback = 255;
1705     w->debug_drawbox_text = FALSE;
1706     w->debug_drawbox_fillrect = FALSE;
1707 zmatsuo 10806 w->font_resize_enable = TRUE;
1708 zmatsuo 10338 BGReverseTextAlpha = 255;
1709 maya 3227 }
1710    
1711 zmatsuo 9991 void EndDisp(void)
1712 maya 3227 {
1713     int i, j;
1714    
1715     if (VTDC!=NULL) DispReleaseDC();
1716    
1717     /* Delete fonts */
1718     for (i = 0 ; i <= AttrFontMask; i++)
1719     {
1720     for (j = i+1 ; j <= AttrFontMask ; j++)
1721     if (VTFont[j]==VTFont[i])
1722     VTFont[j] = 0;
1723     if (VTFont[i]!=0) DeleteObject(VTFont[i]);
1724     }
1725    
1726     if (Background!=0)
1727     {
1728     DeleteObject(Background);
1729     Background = 0;
1730     }
1731    
1732     BGDestruct();
1733 zmatsuo 10374
1734     free(BGDest.fileW);
1735     BGDest.fileW = NULL;
1736 maya 3227 }
1737    
1738 zmatsuo 9991 void DispReset(void)
1739 maya 3227 {
1740     /* Cursor */
1741     CursorX = 0;
1742     CursorY = 0;
1743    
1744     /* Scroll status */
1745     ScrollCount = 0;
1746     dScroll = 0;
1747    
1748     if (IsCaretOn()) CaretOn();
1749     DispEnableCaret(TRUE); // enable caret
1750     }
1751    
1752     void DispConvWinToScreen
1753     (int Xw, int Yw, int *Xs, int *Ys, PBOOL Right)
1754     // Converts window coordinate to screen cordinate
1755     // Xs: horizontal position in window coordinate (pixels)
1756     // Ys: vertical
1757     // Output
1758     // Xs, Ys: screen coordinate
1759     // Right: TRUE if the (Xs,Ys) is on the right half of
1760     // a character cell.
1761     {
1762     if (Xs!=NULL)
1763     *Xs = Xw / FontWidth + WinOrgX;
1764     *Ys = Yw / FontHeight + WinOrgY;
1765     if ((Xs!=NULL) && (Right!=NULL))
1766     *Right = (Xw - (*Xs-WinOrgX)*FontWidth) >= FontWidth/2;
1767     }
1768    
1769     void DispConvScreenToWin
1770     (int Xs, int Ys, int *Xw, int *Yw)
1771     // Converts screen coordinate to window cordinate
1772     // Xs: horizontal position in screen coordinate (characters)
1773     // Ys: vertical
1774     // Output
1775     // Xw, Yw: window coordinate
1776     {
1777     if (Xw!=NULL)
1778     *Xw = (Xs - WinOrgX) * FontWidth;
1779     if (Yw!=NULL)
1780     *Yw = (Ys - WinOrgY) * FontHeight;
1781     }
1782    
1783 zmatsuo 7545 static void SetLogFont(LOGFONTA *VTlf, BOOL mul)
1784 maya 3227 {
1785 zmatsuo 7545 memset(VTlf, 0, sizeof(*VTlf));
1786     VTlf->lfWeight = FW_NORMAL;
1787     VTlf->lfItalic = 0;
1788     VTlf->lfUnderline = 0;
1789     VTlf->lfStrikeOut = 0;
1790     VTlf->lfWidth = ts.VTFontSize.x;
1791     VTlf->lfHeight = ts.VTFontSize.y;
1792     VTlf->lfCharSet = ts.VTFontCharSet;
1793     VTlf->lfOutPrecision = OUT_CHARACTER_PRECIS;
1794     VTlf->lfClipPrecision = CLIP_CHARACTER_PRECIS;
1795     VTlf->lfQuality = (BYTE)ts.FontQuality;
1796     VTlf->lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1797     strncpy_s(VTlf->lfFaceName, sizeof(VTlf->lfFaceName),ts.VTFont, _TRUNCATE);
1798     if (mul) {
1799 zmatsuo 7723 const UINT uDpi = GetMonitorDpiFromWindow(HVTWin);
1800     VTlf->lfWidth = MulDiv(VTlf->lfWidth, uDpi, 96);
1801     VTlf->lfHeight = MulDiv(VTlf->lfHeight, uDpi, 96);
1802 zmatsuo 7545 }
1803 maya 3227 }
1804    
1805 zmatsuo 9991 void ChangeFont(void)
1806 maya 3227 {
1807 zmatsuo 7545 int i, j;
1808     LOGFONTA VTlf;
1809 maya 3227
1810 zmatsuo 7545 /* Delete Old Fonts */
1811     for (i = 0 ; i <= AttrFontMask ; i++)
1812     {
1813     for (j = i+1 ; j <= AttrFontMask ; j++)
1814     if (VTFont[j]==VTFont[i])
1815     VTFont[j] = 0;
1816     if (VTFont[i]!=0)
1817     DeleteObject(VTFont[i]);
1818     }
1819 maya 3227
1820 zmatsuo 9944 /* Normal Font */
1821     SetLogFont(&VTlf, TRUE);
1822 nmaya 10211 VTFont[AttrDefault] = CreateFontIndirect(&VTlf);
1823 zmatsuo 9944
1824     /* set IME font */
1825     SetConversionLogFont(HVTWin, &VTlf);
1826    
1827 zmatsuo 7545 {
1828     HDC TmpDC = GetDC(HVTWin);
1829 zmatsuo 9944 TEXTMETRIC Metrics;
1830 maya 3227
1831 nmaya 10211 SelectObject(TmpDC, VTFont[AttrDefault]);
1832 zmatsuo 7545 GetTextMetrics(TmpDC, &Metrics);
1833     FontWidth = Metrics.tmAveCharWidth + ts.FontDW;
1834     FontHeight = Metrics.tmHeight + ts.FontDH;
1835 maya 3227
1836 zmatsuo 7545 ReleaseDC(HVTWin,TmpDC);
1837     }
1838 maya 3227
1839 zmatsuo 7545 /* Underline */
1840 zmatsuo 10214 if ((ts.FontFlag & FF_UNDERLINE) || (ts.FontFlag & FF_URLUNDERLINE)) {
1841 zmatsuo 10157 VTlf.lfUnderline = 1;
1842     VTFont[AttrUnder] = CreateFontIndirect(&VTlf);
1843     }
1844     else {
1845 nmaya 10211 VTFont[AttrUnder] = VTFont[AttrDefault];
1846 zmatsuo 10157 }
1847 maya 3227
1848 zmatsuo 7545 if (ts.FontFlag & FF_BOLD) {
1849     /* Bold */
1850     VTlf.lfUnderline = 0;
1851     VTlf.lfWeight = FW_BOLD;
1852     VTFont[AttrBold] = CreateFontIndirect(&VTlf);
1853 nmaya 10210
1854 zmatsuo 7545 /* Bold + Underline */
1855 zmatsuo 10214 if (ts.FontFlag & FF_UNDERLINE || ts.FontFlag & FF_URLUNDERLINE) {
1856 nmaya 10210 VTlf.lfUnderline = 1;
1857     VTFont[AttrBold | AttrUnder] = CreateFontIndirect(&VTlf);
1858     }
1859     else {
1860     VTFont[AttrBold | AttrUnder] = VTFont[AttrBold];
1861     }
1862 zmatsuo 7545 }
1863     else {
1864     VTFont[AttrBold] = VTFont[AttrDefault];
1865     VTFont[AttrBold | AttrUnder] = VTFont[AttrUnder];
1866     }
1867 maya 3227
1868 zmatsuo 7545 /* Special font */
1869     VTlf.lfWeight = FW_NORMAL;
1870     VTlf.lfUnderline = 0;
1871     VTlf.lfWidth = FontWidth + 1; /* adjust width */
1872     VTlf.lfHeight = FontHeight;
1873     VTlf.lfCharSet = SYMBOL_CHARSET;
1874 maya 3227
1875 zmatsuo 7545 strncpy_s(VTlf.lfFaceName, sizeof(VTlf.lfFaceName),"Tera Special", _TRUNCATE);
1876     VTFont[AttrSpecial] = CreateFontIndirect(&VTlf);
1877 maya 3227
1878 zmatsuo 7545 /* Special font (Underline) */
1879 zmatsuo 10214 if (ts.FontFlag & FF_UNDERLINE || ts.FontFlag & FF_URLUNDERLINE) {
1880 nmaya 10210 VTlf.lfUnderline = 1;
1881     VTlf.lfHeight = FontHeight - 1; // adjust for underline
1882     VTFont[AttrSpecial | AttrUnder] = CreateFontIndirect(&VTlf);
1883     }
1884     else {
1885     VTFont[AttrSpecial | AttrUnder] = VTFont[AttrSpecial];
1886     }
1887 doda 4412
1888 zmatsuo 7545 if (ts.FontFlag & FF_BOLD) {
1889     /* Special font (Bold) */
1890     VTlf.lfUnderline = 0;
1891     VTlf.lfHeight = FontHeight;
1892     VTlf.lfWeight = FW_BOLD;
1893     VTFont[AttrSpecial | AttrBold] = CreateFontIndirect(&VTlf);
1894 nmaya 10210
1895 zmatsuo 7545 /* Special font (Bold + Underline) */
1896 zmatsuo 10214 if (ts.FontFlag & FF_UNDERLINE || ts.FontFlag & FF_URLUNDERLINE) {
1897 nmaya 10210 VTlf.lfUnderline = 1;
1898     VTlf.lfHeight = FontHeight - 1; // adjust for underline
1899     VTFont[AttrSpecial | AttrBold | AttrUnder] = CreateFontIndirect(&VTlf);
1900     }
1901     else {
1902     VTFont[AttrSpecial | AttrBold | AttrUnder] = VTFont[AttrSpecial | AttrBold];
1903     }
1904 zmatsuo 7545 }
1905     else {
1906     VTFont[AttrSpecial | AttrBold] = VTFont[AttrSpecial];
1907     VTFont[AttrSpecial | AttrBold | AttrUnder] = VTFont[AttrSpecial | AttrUnder];
1908     }
1909 maya 3227 }
1910    
1911 zmatsuo 9991 void ResetIME(void)
1912 maya 3227 {
1913 doda 3366 /* reset language for communication */
1914     cv.Language = ts.Language;
1915 maya 3227
1916 doda 3366 /* reset IME */
1917 doda 3407 if ((ts.Language==IdJapanese) || (ts.Language==IdKorean) || (ts.Language==IdUtf8)) //HKS
1918 doda 3366 {
1919     if (ts.UseIME==0)
1920 zmatsuo 7485 FreeIME(HVTWin);
1921 zmatsuo 7486 else if (! LoadIME()) {
1922 zmatsuo 9354 static const TTMessageBoxInfoW info = {
1923     "Tera Term",
1924     "MSG_TT_ERROR", L"Tera Term: Error",
1925     "MSG_USE_IME_ERROR", L"Can't use IME",
1926     MB_ICONEXCLAMATION
1927     };
1928     TTMessageBoxW(0, &info, ts.UILanguageFileW);
1929 zmatsuo 9383 WritePrivateProfileStringW(L"Tera Term", L"IME", L"off", ts.SetupFNameW);
1930 doda 3366 ts.UseIME = 0;
1931 zmatsuo 7486 }
1932 maya 3227
1933 doda 3366 if (ts.UseIME>0)
1934     {
1935 zmatsuo 7545 if (ts.IMEInline>0) {
1936     LOGFONTA VTlf;
1937     SetLogFont(&VTlf, TRUE);
1938 zmatsuo 7458 SetConversionLogFont(HVTWin, &VTlf);
1939 zmatsuo 7545 }
1940 doda 3366 else
1941     SetConversionWindow(HVTWin,-1,0);
1942     }
1943 maya 3227 }
1944 doda 3366 else
1945 zmatsuo 7485 FreeIME(HVTWin);
1946 maya 3227
1947 doda 3366 if (IsCaretOn()) CaretOn();
1948 maya 3227 }
1949    
1950 zmatsuo 9991 void ChangeCaret(void)
1951 maya 3227 {
1952     UINT T;
1953    
1954     if (! Active) return;
1955 doda 4718 DestroyCaret();
1956     switch (ts.CursorShape) {
1957     case IdVCur:
1958 doda 6435 CreateCaret(HVTWin, 0, CurWidth, FontHeight);
1959     break;
1960 doda 4718 case IdHCur:
1961 doda 6435 CreateCaret(HVTWin, 0, FontWidth, CurWidth);
1962     break;
1963 doda 4718 }
1964     if (CaretEnabled) {
1965 maya 3227 CaretStatus = 1;
1966     }
1967     CaretOn();
1968 doda 4718 if (CaretEnabled && (ts.NonblinkingCursor!=0)) {
1969 maya 3227 T = GetCaretBlinkTime() * 2 / 3;
1970     SetTimer(HVTWin,IdCaretTimer,T,NULL);
1971     }
1972 doda 3322 UpdateCaretPosition(TRUE);
1973 maya 3227 }
1974    
1975     // WM_KILLFOCUS�������������J�[�\�����������`��
1976     void CaretKillFocus(BOOL show)
1977     {
1978     int CaretX, CaretY;
1979     POINT p[5];
1980     HPEN oldpen;
1981     HDC hdc;
1982    
1983     if (ts.KillFocusCursor == 0)
1984     return;
1985    
1986     // Eterm lookfeel������������������
1987     if (BGEnable)
1988     return;
1989    
1990     /* Get Device Context */
1991     DispInitDC();
1992     hdc = VTDC;
1993    
1994     CaretX = (CursorX-WinOrgX)*FontWidth;
1995     CaretY = (CursorY-WinOrgY)*FontHeight;
1996    
1997     p[0].x = CaretX;
1998     p[0].y = CaretY;
1999     p[1].x = CaretX;
2000     p[1].y = CaretY + FontHeight - 1;
2001     if (CursorOnDBCS)
2002     p[2].x = CaretX + FontWidth*2 - 1;
2003     else
2004     p[2].x = CaretX + FontWidth - 1;
2005     p[2].y = CaretY + FontHeight - 1;
2006     if (CursorOnDBCS)
2007     p[3].x = CaretX + FontWidth*2 - 1;
2008     else
2009     p[3].x = CaretX + FontWidth - 1;
2010     p[3].y = CaretY;
2011     p[4].x = CaretX;
2012     p[4].y = CaretY;
2013    
2014     if (show) { // �|���S���J�[�\�����\���i���t�H�[�J�X���j
2015     oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, ts.VTColor[0]));
2016     } else {
2017     oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, ts.VTColor[1]));
2018     }
2019     Polyline(VTDC, p, 5);
2020     oldpen = SelectObject(hdc, oldpen);
2021     DeleteObject(oldpen);
2022    
2023     /* release device context */
2024     DispReleaseDC();
2025     }
2026    
2027     // �|���S���J�[�\�����������������A�������������������`�������B
2028     //
2029     // CaretOff()�����������������BCaretOff()�������������A�������A�����o���������A
2030     // stack overflow�������B
2031 doda 3322 //
2032     // �J�[�\���`�����X��(ChangeCaret)�����������������������A���������X -- 2009/04/17 doda.
2033     //
2034     void UpdateCaretPosition(BOOL enforce)
2035 maya 3227 {
2036     int CaretX, CaretY;
2037     RECT rc;
2038    
2039     CaretX = (CursorX-WinOrgX)*FontWidth;
2040     CaretY = (CursorY-WinOrgY)*FontHeight;
2041    
2042 doda 3322 if (!enforce && !ts.KillFocusCursor)
2043 maya 3227 return;
2044    
2045     // Eterm lookfeel������������������
2046     if (BGEnable)
2047     return;
2048    
2049     if (enforce == TRUE || !Active) {
2050     rc.left = CaretX;
2051     rc.top = CaretY;
2052     if (CursorOnDBCS)
2053     rc.right = CaretX + FontWidth*2;
2054     else
2055     rc.right = CaretX + FontWidth;
2056     rc.bottom = CaretY + FontHeight;
2057     // �w��������1�s�N�Z�����������������`������������
2058     // rc �� right, bottom ��1�s�N�Z�����������������B
2059     InvalidateRect(HVTWin, &rc, FALSE);
2060     }
2061     }
2062    
2063 zmatsuo 9991 void CaretOn(void)
2064 maya 3227 // Turn on the cursor
2065     {
2066 doda 8445 #if UNICODE_DEBUG_CARET_OFF
2067     return;
2068     #endif
2069 doda 3366 if (ts.KillFocusCursor == 0 && !Active)
2070     return;
2071 maya 3227
2072 zmatsuo 7434 if (! CaretEnabled) return;
2073 yutakapon 3898
2074 zmatsuo 7434 if (Active) {
2075     int CaretX, CaretY, H;
2076     HBITMAP color;
2077 maya 3227
2078 zmatsuo 7434 /* IME��on/off�����������A�J�[�\�����F�����X�����B
2079     * WM_INPUTLANGCHANGE, WM_IME_NOTIFY �����J�[�\�������`�������s���B
2080     * (2010.5.20 yutaka)
2081     */
2082     if ((ts.WindowFlag & WF_IMECURSORCHANGE) == 0) {
2083     color = 0;
2084     } else {
2085     if (IMEstat) {
2086     color = (HBITMAP)1;
2087     } else {
2088     color = 0;
2089     }
2090     }
2091 maya 3227
2092 zmatsuo 7434 CaretX = (CursorX-WinOrgX)*FontWidth;
2093     CaretY = (CursorY-WinOrgY)*FontHeight;
2094 zmatsuo 7458
2095 zmatsuo 7534 if (IMEstat && IMECompositionState) {
2096     // IME ON && ���������������������������B
2097     // ������(�����������E�B���h�E���\����������������)��
2098 zmatsuo 7458 // �z�X�g�������G�R�[�����M����caret���u���������������A
2099 zmatsuo 7534 // ���������������u���X�V�����K�v�������B
2100 zmatsuo 7458 SetConversionWindow(HVTWin,CaretX,CaretY);
2101     }
2102    
2103 doda 3366 if (ts.CursorShape!=IdVCur) {
2104     if (ts.CursorShape==IdHCur) {
2105     CaretY = CaretY+FontHeight-CurWidth;
2106     H = CurWidth;
2107     }
2108     else {
2109     H = FontHeight;
2110     }
2111    
2112     DestroyCaret();
2113     if (CursorOnDBCS) {
2114     /* double width caret */
2115 yutakapon 3898 CreateCaret(HVTWin, color, FontWidth*2, H);
2116 doda 3366 }
2117     else {
2118     /* single width caret */
2119 yutakapon 3898 CreateCaret(HVTWin, color, FontWidth, H);
2120 doda 3366 }
2121     CaretStatus = 1;
2122 maya 3227 }
2123 doda 3366 SetCaretPos(CaretX,CaretY);
2124     }
2125 maya 3227
2126 doda 3366 while (CaretStatus > 0) {
2127     if (! Active) {
2128     CaretKillFocus(TRUE);
2129     } else {
2130     ShowCaret(HVTWin);
2131     }
2132     CaretStatus--;
2133     }
2134 maya 3227 }
2135    
2136 zmatsuo 9991 void CaretOff(void)
2137 maya 3227 {
2138 doda 3366 if (ts.KillFocusCursor == 0 && !Active)
2139     return;
2140 maya 3227
2141 doda 3366 if (CaretStatus == 0) {
2142     if (! Active) {
2143     CaretKillFocus(FALSE);
2144     } else {
2145     HideCaret(HVTWin);
2146     }
2147     CaretStatus++;
2148     }
2149 maya 3227 }
2150    
2151 zmatsuo 9991 void DispDestroyCaret(void)
2152 maya 3227 {
2153     DestroyCaret();
2154     if (ts.NonblinkingCursor!=0)
2155     KillTimer(HVTWin,IdCaretTimer);
2156     }
2157    
2158 zmatsuo 9991 BOOL IsCaretOn(void)
2159 maya 3227 // check if caret is on
2160     {
2161 doda 4716 return ((ts.KillFocusCursor || Active) && (CaretStatus==0));
2162 maya 3227 }
2163    
2164     void DispEnableCaret(BOOL On)
2165     {
2166 doda 8445 #if UNICODE_DEBUG_CARET_OFF
2167     On = FALSE;
2168     #endif
2169 maya 3227 if (! On) CaretOff();
2170     CaretEnabled = On;
2171     }
2172    
2173 zmatsuo 9991 BOOL IsCaretEnabled(void)
2174 maya 3227 {
2175     return CaretEnabled;
2176     }
2177    
2178     void DispSetCaretWidth(BOOL DW)
2179     {
2180     /* TRUE if cursor is on a DBCS character */
2181     CursorOnDBCS = DW;
2182     }
2183    
2184     void DispChangeWinSize(int Nx, int Ny)
2185     {
2186     LONG W,H,dW,dH;
2187     RECT R;
2188    
2189     if (SaveWinSize)
2190     {
2191     WinWidthOld = WinWidth;
2192     WinHeightOld = WinHeight;
2193     SaveWinSize = FALSE;
2194     }
2195     else {
2196     WinWidthOld = NumOfColumns;
2197     WinHeightOld = NumOfLines;
2198     }
2199    
2200     WinWidth = Nx;
2201     WinHeight = Ny;
2202    
2203     ScreenWidth = WinWidth*FontWidth;
2204     ScreenHeight = WinHeight*FontHeight;
2205    
2206     AdjustScrollBar();
2207    
2208     GetWindowRect(HVTWin,&R);
2209     W = R.right-R.left;
2210     H = R.bottom-R.top;
2211     GetClientRect(HVTWin,&R);
2212     dW = ScreenWidth - R.right + R.left;
2213     dH = ScreenHeight - R.bottom + R.top;
2214 doda 6435
2215 maya 3227 if ((dW!=0) || (dH!=0))
2216     {
2217     AdjustSize = TRUE;
2218    
2219     // SWP_NOMOVE ���w�������������������� 0,0 �����f�����A
2220     // �}���`�f�B�X�v���C���������v���C�}�����j�^��
2221     // �������������������C�� (2008.5.29 maya)
2222     //SetWindowPos(HVTWin,HWND_TOP,0,0,W+dW,H+dH,SWP_NOMOVE);
2223    
2224     // �}���`�f�B�X�v���C�����������������������A
2225     // �����f�B�X�v���C���E�B���h�E���[�������o���������C�� (2008.5.30 maya)
2226     // �����A���L�������������������������E�B���h�E�������������������o�����B
2227     if (!IsZoomed(HVTWin)) {
2228     SetWindowPos(HVTWin,HWND_TOP,R.left,R.top,W+dW,H+dH,SWP_NOMOVE);
2229     }
2230     }
2231     else
2232     InvalidateRect(HVTWin,NULL,FALSE);
2233     }
2234    
2235     void ResizeWindow(int x, int y, int w, int h, int cw, int ch)
2236     {
2237     int dw,dh, NewX, NewY;
2238     POINT Point;
2239    
2240     if (! AdjustSize) return;
2241     dw = ScreenWidth - cw;
2242     dh = ScreenHeight - ch;
2243     if ((dw!=0) || (dh!=0)) {
2244     SetWindowPos(HVTWin,HWND_TOP,x,y,w+dw,h+dh,SWP_NOMOVE);
2245     AdjustSize = FALSE;
2246     }
2247     else {
2248     AdjustSize = FALSE;
2249    
2250     NewX = x;
2251     NewY = y;
2252     if (x+w > VirtualScreen.right)
2253     {
2254     NewX = VirtualScreen.right-w;
2255     if (NewX < 0) NewX = 0;
2256     }
2257     if (y+h > VirtualScreen.bottom)
2258     {
2259     NewY = VirtualScreen.bottom-h;
2260     if (NewY < 0) NewY = 0;
2261     }
2262     if ((NewX!=x) || (NewY!=y))
2263     SetWindowPos(HVTWin,HWND_TOP,NewX,NewY,w,h,SWP_NOSIZE);
2264    
2265     Point.x = 0;
2266     Point.y = ScreenHeight;
2267     ClientToScreen(HVTWin,&Point);
2268     CompletelyVisible = (Point.y <= VirtualScreen.bottom);
2269     if (IsCaretOn()) CaretOn();
2270     }
2271     }
2272    
2273     void PaintWindow(HDC PaintDC, RECT PaintRect, BOOL fBkGnd,
2274     int* Xs, int* Ys, int* Xe, int* Ye)
2275     // Paint window with background color &
2276     // convert paint region from window coord. to screen coord.
2277     // Called from WM_PAINT handler
2278     // PaintRect: Paint region in window coordinate
2279     // Return:
2280     // *Xs, *Ys: upper left corner of the region
2281     // in screen coord.
2282     // *Xe, *Ye: lower right
2283     {
2284     if (VTDC!=NULL)
2285     DispReleaseDC();
2286     VTDC = PaintDC;
2287     DCPrevFont = SelectObject(VTDC, VTFont[0]);
2288     DispInitDC();
2289    
2290     if(!BGEnable && fBkGnd)
2291     FillRect(VTDC, &PaintRect,Background);
2292    
2293     *Xs = PaintRect.left / FontWidth + WinOrgX;
2294     *Ys = PaintRect.top / FontHeight + WinOrgY;
2295     *Xe = (PaintRect.right-1) / FontWidth + WinOrgX;
2296     *Ye = (PaintRect.bottom-1) / FontHeight + WinOrgY;
2297     }
2298    
2299 zmatsuo 9991 void DispEndPaint(void)
2300 maya 3227 {
2301     if (VTDC==NULL) return;
2302     SelectObject(VTDC,DCPrevFont);
2303     VTDC = NULL;
2304     }
2305    
2306 zmatsuo 9991 void DispClearWin(void)
2307 maya 3227 {
2308     InvalidateRect(HVTWin,NULL,FALSE);
2309    
2310     ScrollCount = 0;
2311     dScroll = 0;
2312     if (WinHeight > NumOfLines)
2313     DispChangeWinSize(NumOfColumns,NumOfLines);
2314     else {
2315     if ((NumOfLines==WinHeight) && (ts.EnableScrollBuff>0))
2316     {
2317     SetScrollRange(HVTWin,SB_VERT,0,1,FALSE);
2318     }
2319 doda 6435 else
2320 maya 3227 SetScrollRange(HVTWin,SB_VERT,0,NumOfLines-WinHeight,FALSE);
2321    
2322     SetScrollPos(HVTWin,SB_HORZ,0,TRUE);
2323     SetScrollPos(HVTWin,SB_VERT,0,TRUE);
2324     }
2325     if (IsCaretOn()) CaretOn();
2326     }
2327    
2328 zmatsuo 9991 void DispChangeBackground(void)
2329 maya 3227 {
2330 zmatsuo 10338 DispReleaseDC();
2331 zmatsuo 10274
2332 zmatsuo 10338 UpdateBGBrush();
2333 maya 3227
2334 zmatsuo 10338 InvalidateRect(HVTWin,NULL,TRUE);
2335 maya 3227 }
2336    
2337 zmatsuo 9991 void DispChangeWin(void)
2338 maya 3227 {
2339     /* Change window caption */
2340     ChangeTitle();
2341    
2342     /* Menu bar / Popup menu */
2343     SwitchMenu();
2344    
2345     SwitchTitleBar();
2346    
2347     /* Change caret shape */
2348     ChangeCaret();
2349    
2350     /* change background color */
2351     DispChangeBackground();
2352     }
2353    
2354 zmatsuo 9991 void DispInitDC(void)
2355 maya 3227 {
2356     if (VTDC==NULL)
2357     {
2358     VTDC = GetDC(HVTWin);
2359     DCPrevFont = SelectObject(VTDC, VTFont[0]);
2360     }
2361     else
2362     SelectObject(VTDC, VTFont[0]);
2363    
2364     SetTextColor(VTDC, BGVTColor[0]);
2365     SetBkColor(VTDC, BGVTColor[1]);
2366    
2367     SetBkMode(VTDC,OPAQUE);
2368     DCAttr = DefCharAttr;
2369     }
2370    
2371 zmatsuo 9991 void DispReleaseDC(void)
2372 maya 3227 {
2373     if (VTDC==NULL) return;
2374     SelectObject(VTDC, DCPrevFont);
2375     ReleaseDC(HVTWin,VTDC);
2376     VTDC = NULL;
2377     }
2378    
2379 zmatsuo 10203 /**
2380     * �V�[�P���X��color_index��ANSIColor[]��index����������
2381     *
2382 zmatsuo 10274 * 8�F���[�h
2383     * ���F(�������F)���g������
2384     * 16�F������PC-style 16 colors���O
2385     * ���� color_index �� ANSIColor[] ��index��������
2386     * PC-style 16 colors (pcbold16��0���O����)
2387     * pcbold16_bright �� 0 ������
2388     * ���������F
2389     * pcbold16_bright �� 0 ���O(Bold���� or Blonk����)������
2390     * �����F����(0-7)���g���������������������F���\��
2391 zmatsuo 10222 *
2392 zmatsuo 10274 * @param color_index �F����
2393 zmatsuo 10203 * @param pcbold16 0/0���O = 16 color mode PC Style��������/������
2394     * @param pcbold16_bright 0/0���O = �F��������������/����
2395 zmatsuo 10274 * @return ANSIColor[]��index (ANSI color 256�F��index)
2396     */
2397     static int Get16ColorIndex(int color_index_256, int pcbold16, int pcbold16_bright)
2398 zmatsuo 10203 {
2399     if ((ts.ColorFlag & CF_FULLCOLOR) == 0) {
2400     // 8�F���[�h
2401 zmatsuo 10274 // input output
2402     // 0 0 ��,Black
2403     // 1-7 9-14 �������F,���F (Bright color)
2404     if (color_index_256 == 0) {
2405     return 0;
2406     } else if (color_index_256 < 8) {
2407     return color_index_256 + 8;
2408     } else {
2409     return color_index_256;
2410     }
2411 zmatsuo 10203 }
2412 zmatsuo 10274 else if (pcbold16) {
2413     // 16 color mode PC Style
2414     if (color_index_256 == 0) {
2415     // black -> black
2416     return 0;
2417     }
2418     else if (color_index_256 < 8) {
2419     if (pcbold16_bright) {
2420     return color_index_256 + 8;
2421 zmatsuo 10203 }
2422     else {
2423 zmatsuo 10274 return color_index_256;
2424 zmatsuo 10203 }
2425     }
2426