Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/vtdisp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10806 - (show annotations) (download) (as text)
Sun Jul 23 07:07:41 2023 UTC (10 months, 1 week 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 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2005- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 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 *
18 * 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 */
29
30 /* TERATERM.EXE, VT terminal display routines */
31 #include "teraterm.h"
32 #include "teraterml.h"
33 #include "tttypes.h"
34 #include <string.h>
35 #include <olectl.h>
36 #include <assert.h>
37 #include <stdio.h>
38
39 #include "ttwinman.h"
40 #include "ttime.h"
41 #include "ttdialog.h"
42 #include "ttcommon.h"
43 #include "compat_win.h"
44 #include "unicode_test.h"
45 #include "setting.h"
46 #include "codeconv.h"
47 #include "libsusieplugin.h"
48 #include "asprintf.h"
49 #include "inifile_com.h"
50 #include "win32helper.h"
51 #include "ttknownfolders.h" // for FOLDERID_Desktop
52 #include "ttlib.h"
53 #if ENABLE_GDIPLUS
54 #include "ttgdiplus.h"
55 #endif
56
57 #include "theme.h"
58 #include "vtdisp.h"
59
60 #define CurWidth 2
61
62 #include "defaultcolortable.c"
63
64 int WinWidth, WinHeight;
65 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 int WinOrgX, WinOrgY, NewOrgX, NewOrgY;
78
79 int NumOfLines, NumOfColumns;
80 int PageStart, BuffEnd;
81
82 static BOOL CursorOnDBCS = FALSE;
83 static BOOL SaveWinSize = FALSE;
84 static int WinWidthOld, WinHeightOld;
85 static HBRUSH Background;
86
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 static COLORREF ANSIColor[256];
98
99 // caret variables
100 static int CaretStatus;
101 static BOOL CaretEnabled = TRUE;
102 BOOL IMEstat; /* IME Status TRUE=IME ON */
103 BOOL IMECompositionState; /* �������� TRUE=������ */
104
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 AttrDefault,
115 AttrDefaultFG,
116 AttrDefaultBG
117 };
118
119 // scrolling
120 static int ScrollCount = 0;
121 static int dScroll = 0;
122 static int SRegionTop;
123 static int SRegionBottom;
124
125 typedef struct _BGSrc
126 {
127 HDC hdc;
128 BOOL enable;
129 BG_TYPE type;
130 BG_PATTERN pattern;
131 BOOL antiAlias;
132 COLORREF color;
133 BYTE alpha;
134 int width;
135 int height;
136 wchar_t *fileW;
137 } BGSrc;
138
139 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
143 static int BGEnable;
144 static BYTE BGReverseTextAlpha;
145
146 static COLORREF BGVTColor[2];
147 static COLORREF BGVTBoldColor[2];
148 static COLORREF BGVTUnderlineColor[2]; // SGR 4
149 static COLORREF BGVTBlinkColor[2];
150 static COLORREF BGVTReverseColor[2];
151 static COLORREF BGURLColor[2]; // URL�����F
152
153 static RECT BGPrevRect;
154
155 static BOOL BGInSizeMove;
156 //static HBRUSH BGBrushInSizeMove;
157
158 static HDC hdcBGWork;
159 static HDC hdcBGBuffer;
160 static HDC hdcBG;
161
162 typedef struct tagWallpaperInfo
163 {
164 wchar_t *filename;
165 int pattern;
166 } WallpaperInfo;
167
168 static BOOL (WINAPI *BGAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
169
170 typedef struct {
171 BOOL bg_enable;
172 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
180 BOOL font_resize_enable;
181 } vtdisp_work_t;
182 static vtdisp_work_t vtdisp_work;
183
184 static HBITMAP GetBitmapHandleW(const wchar_t *File);
185 static void InitColorTable(const COLORREF *ANSIColor16);
186 static void UpdateBGBrush(void);
187 static void GetDrawAttr(const TCharAttr *Attr, BOOL _reverse, COLORREF *fore_color, COLORREF *back_color, BYTE *_alpha);
188
189 // 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 return !IsWindowsVistaOrLater();
197 }
198
199 static HBITMAP CreateScreenCompatibleBitmap(int width,int height)
200 {
201 HDC hdc;
202 HBITMAP hbm;
203
204 #ifdef _DEBUG
205 OutputDebugPrintf("CreateScreenCompatibleBitmap : width = %d height = %d\n",width,height);
206 #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 OutputDebugPrintf("CreateScreenCompatibleBitmap : fail in CreateCompatibleBitmap\n");
217 #endif
218
219 return hbm;
220 }
221
222 static HBITMAP CreateDIB24BPP(int width,int height,unsigned char **buf,int *lenBuf)
223 {
224 HDC hdc;
225 HBITMAP hbm;
226 BITMAPINFO bmi;
227
228 #ifdef _DEBUG
229 OutputDebugPrintf("CreateDIB24BPP : width = %d height = %d\n",width,height);
230 #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 static HDC CreateBitmapDC(HBITMAP hbm)
257 {
258 HDC hdc;
259
260 #ifdef _DEBUG
261 OutputDebugPrintf("CreateBitmapDC : hbm = %p\n",hbm);
262 #endif
263
264 hdc = CreateCompatibleDC(NULL);
265
266 SaveDC(hdc);
267 SelectObject(hdc,hbm);
268
269 return hdc;
270 }
271
272 static void DeleteBitmapDC(HDC *hdc)
273 {
274 HBITMAP hbm;
275
276 #ifdef _DEBUG
277 OutputDebugPrintf("DeleteBitmapDC : *hdc = %p\n",hdc);
278 #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 static void FillBitmapDC(HDC hdc,COLORREF color)
296 {
297 HBITMAP hbm;
298 BITMAP bm;
299 RECT rect;
300 HBRUSH hBrush;
301
302 #ifdef _DEBUG
303 OutputDebugPrintf("FillBitmapDC : hdc = %p color = %08lx\n",hdc,color);
304 #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 static void DebugSaveFile(const wchar_t* fname, HDC hdc, int width, int height)
319 {
320 #if 1
321 (void)fname;
322 (void)hdc;
323 (void)width;
324 (void)height;
325 #else
326 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 }
341
342 /**
343 * BMP�����A�f�o�O���g�������������������c��������
344 */
345 #if 0
346 static BOOL SaveBitmapFile(const char *nameFile,unsigned char *pbuf,BITMAPINFO *pbmi)
347 {
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
360 switch(pbmi->bmiHeader.biBitCount)
361 {
362 case 1:
363 bmiSize += pbmi->bmiHeader.biClrUsed ? sizeof(RGBQUAD) * 2 : 0;
364 break;
365
366 case 2 :
367 bmiSize += sizeof(RGBQUAD) * 4;
368 break;
369
370 case 4 :
371 bmiSize += sizeof(RGBQUAD) * 16;
372 break;
373
374 case 8 :
375 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 #endif
393
394 static HBITMAP CreateBitmapFromBITMAPINFO(const BITMAPINFO *pbmi, const unsigned char *pbuf)
395 {
396 void* pvBits;
397 HBITMAP hBmp = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
398
399 if (pbuf != NULL) {
400 memcpy(pvBits, pbuf, pbmi->bmiHeader.biSizeImage);
401 }
402
403 return hBmp;
404 }
405
406 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 {
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 static void BGPreloadPicture(BGSrc *src)
442 {
443 HBITMAP hbm = NULL;
444 const wchar_t *load_file = src->fileW;
445 const wchar_t *spi_path = ts.EtermLookfeel.BGSPIPathW;
446
447 // Susie plugin ����������
448 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 }
458
459 // GDI+ ���C�u�������g������������
460 #if ENABLE_GDIPLUS
461 if (hbm == NULL) {
462 hbm = GDIPLoad(load_file);
463 }
464 #endif
465
466 // OLE �����p��������(jpeg)������
467 // LoadImage()����������������������������������
468 if (hbm == NULL && !IsLoadImageOnlyEnabled()) {
469 hbm = GetBitmapHandleW(load_file);
470 }
471
472 // LoadImageW() API ����������
473 if (hbm == NULL) {
474 // LoadImageW() API���A
475 // Windows 10 �������������}�C�i�X��bmp�t�@�C�������[�h�����s����
476 // Windows 7 ����������������
477 hbm = LoadImageW(0,load_file,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
478 }
479
480 if(hbm) {
481 BITMAP bm;
482
483 GetObject(hbm,sizeof(bm),&bm);
484
485 src->hdc = CreateBitmapDC(hbm);
486 src->width = bm.bmWidth;
487 src->height = bm.bmHeight;
488 }else{
489 src->type = BG_COLOR;
490 }
491 }
492
493 static void BGGetWallpaperInfo(WallpaperInfo *wi)
494 {
495 DWORD length;
496 int style;
497 int tile;
498 char str[256];
499 HKEY hKey;
500
501 wi->pattern = BG_CENTER;
502 wi->filename = NULL;
503
504 //���W�X�g���L�[���I�[�v��
505 if(RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
506 return;
507
508 //�����t�@�C�����Q�b�g
509 hRegQueryValueExW(hKey, L"Wallpaper", NULL, NULL, (void **)&wi->filename, NULL);
510
511 //�����X�^�C���Q�b�g
512 length = sizeof(str);
513 RegQueryValueExA(hKey,"WallpaperStyle",NULL,NULL,(BYTE*)str,&length);
514 style = atoi(str);
515
516 //�����X�^�C���Q�b�g
517 length = sizeof(str);
518 RegQueryValueExA(hKey,"TileWallpaper" ,NULL,NULL,(BYTE*)str,&length);
519 tile = atoi(str);
520
521 //���W�X�g���L�[���N���[�Y
522 RegCloseKey(hKey);
523
524 //�������������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 }
546
547 /**
548 * OleLoadPicture() ���g����������������
549 * jpeg, bmp ����������������������
550 * (Windows���������������`����������������������)
551 *
552 */
553 // .bmp���O�������t�@�C���������B
554 // ������ .bmp ���O���t�@�C���������������������������B
555 // ���������� Windows 2000 ������������������������������
556 // TODO:
557 // IsLoadImageOnlyEnabled() �� Vista ����������������
558 //
559 static HBITMAP GetBitmapHandleW(const wchar_t *File)
560 {
561 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 HRESULT result;
571
572 hFile=CreateFileW(File,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
573 if (hFile == INVALID_HANDLE_VALUE) {
574 return NULL;
575 }
576 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 result = OleLoadPicture(iStream, nFileSize, FALSE, &IID_IPicture, (LPVOID *)&iPicture);
588 if (result != S_OK || iPicture == NULL) {
589 // �����t�@�C����������,�������������t�@�C������
590 return NULL;
591 }
592
593 iStream->lpVtbl->Release(iStream);
594
595 iPicture->lpVtbl->get_Type(iPicture,&type);
596 if(type==PICTYPE_BITMAP){
597 iPicture->lpVtbl->get_Handle(iPicture,&hOle);
598 }
599
600 hBitmap=(HBITMAP)(UINT_PTR)hOle;
601
602 return hBitmap;
603 }
604
605 // ���`�����@���������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 {
610 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
624 if (GetObject(hbm, sizeof(BITMAP), &bm) == 0)
625 return NULL;
626
627 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 pbBits = (BYTE *)HeapAlloc(GetProcessHeap(), 0,
640 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 b0 = ((ex0 * (c00 & 0xFF)) +
678 (ex1 * (c10 & 0xFF))) >> 8;
679 b1 = ((ex0 * (c01 & 0xFF)) +
680 (ex1 * (c11 & 0xFF))) >> 8;
681 g0 = ((ex0 * ((c00 >> 8) & 0xFF)) +
682 (ex1 * ((c10 >> 8) & 0xFF))) >> 8;
683 g1 = ((ex0 * ((c01 >> 8) & 0xFF)) +
684 (ex1 * ((c11 >> 8) & 0xFF))) >> 8;
685 r0 = ((ex0 * ((c00 >> 16) & 0xFF)) +
686 (ex1 * ((c10 >> 16) & 0xFF))) >> 8;
687 r1 = ((ex0 * ((c01 >> 16) & 0xFF)) +
688 (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 a0 = ((ex0 * ((c00 >> 24) & 0xFF)) +
696 (ex1 * ((c10 >> 24) & 0xFF))) >> 8;
697 a1 = ((ex0 * ((c01 >> 24) & 0xFF)) +
698 (ex1 * ((c11 >> 24) & 0xFF))) >> 8;
699 a0 = (ey0 * a0 + ey1 * a1) >> 8;
700 }
701 ((LPDWORD)pbNewLine)[ix] =
702 MAKELONG(MAKEWORD(b0, g0), MAKEWORD(r0, a0));
703 }
704 }
705 }
706 HeapFree(GetProcessHeap(), 0, pbBits);
707 DeleteDC(hdc);
708 }
709 return hbmNew;
710 }
711
712 static void BGPreloadWallpaper(BGSrc *src)
713 {
714 HBITMAP hbm;
715 WallpaperInfo wi;
716 int s_width, s_height;
717
718 BGGetWallpaperInfo(&wi);
719
720 if (IsLoadImageOnlyEnabled()) {
721 //��������������
722 //LR_CREATEDIBSECTION ���w�����������R�c
723 if (wi.pattern == BG_STRETCH) {
724 hbm = LoadImageW(0, wi.filename, IMAGE_BITMAP, CRTWidth, CRTHeight, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
725 }
726 else {
727 hbm = LoadImageW(0, wi.filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
728 }
729 }
730 else {
731 BITMAP bm;
732 float ratio;
733
734 hbm = GetBitmapHandleW(wi.filename);
735 if (hbm == NULL) {
736 goto load_finish;
737 }
738
739 GetObject(hbm,sizeof(bm),&bm);
740 // ���������������������A�������X�g���b�`�T�C�Y���������B
741 if (wi.pattern == BG_STRETCH) {
742 s_width = CRTWidth;
743 s_height = CRTHeight;
744 } 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 } 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 DeleteObject(hbm);
780 hbm = newhbm;
781
782 wi.pattern = BG_STRETCH;
783 }
784 }
785 load_finish:
786 free(wi.filename);
787
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 }
806
807 static void BGPreloadSrc(BGSrc *src)
808 {
809 if (!src->enable) {
810 return;
811 }
812
813 DeleteBitmapDC(&(src->hdc));
814
815 switch (src->type) {
816 case BG_COLOR:
817 break;
818
819 case BG_WALLPAPER:
820 BGPreloadWallpaper(src);
821 break;
822
823 case BG_PICTURE:
824 BGPreloadPicture(src);
825 break;
826
827 default:
828 break;
829 }
830 }
831
832 static void BGStretchPicture(HDC hdcDest,BGSrc *src,int x,int y,int width,int height,BOOL bAntiAlias)
833 {
834 const wchar_t *filename = src->fileW;
835 if(!hdcDest || !src)
836 return;
837
838 if(bAntiAlias)
839 {
840 if(src->width != width || src->height != height)
841 {
842 HBITMAP hbm;
843
844 if (IsLoadImageOnlyEnabled()) {
845 hbm = LoadImageW(0,filename,IMAGE_BITMAP,width,height,LR_LOADFROMFILE);
846 } else {
847 HBITMAP newhbm;
848 hbm = GetBitmapHandleW(filename);
849 newhbm = CreateStretched32BppBitmapBilinear(hbm, width, height);
850 DeleteObject(hbm);
851 hbm = newhbm;
852 }
853
854 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 }
869
870 static void BGLoadPicture(HDC hdcDest,BGSrc *src)
871 {
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
899 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 static BOOL CALLBACK BGLoadWallpaperEnumFunc(HMONITOR hMonitor,HDC hdcMonitor,LPRECT lprcMonitor,LPARAM dwData)
933 {
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 LoadWallpaperStruct *lws;
944
945 (void)hMonitor;
946 (void)hdcMonitor;
947
948 lws = (LoadWallpaperStruct*)dwData;
949
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
981 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 default:
990 break;
991 }
992
993 //���[�W�������j��
994 RestoreDC(lws->hdcDest,-1);
995 DeleteObject(hRgn);
996
997 return TRUE;
998 }
999
1000 static void BGLoadWallpaper(HDC hdcDest,BGSrc *src)
1001 {
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 if(pEnumDisplayMonitors != NULL)
1030 {
1031 (*pEnumDisplayMonitors)(NULL,NULL,BGLoadWallpaperEnumFunc,(LPARAM)&lws);
1032 }else{
1033 RECT rectMonitor;
1034
1035 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 static void BGLoadSrc(HDC hdcDest, BGSrc *src)
1044 {
1045 switch (src->type) {
1046 case BG_COLOR:
1047 FillBitmapDC(hdcDest, src->color);
1048 break;
1049
1050 case BG_WALLPAPER:
1051 BGLoadWallpaper(hdcDest, src);
1052 break;
1053
1054 case BG_PICTURE:
1055 BGLoadPicture(hdcDest, src);
1056 break;
1057
1058 default:
1059 break;
1060 }
1061 }
1062
1063 /**
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 // hBmp �� SelectObject() ��������������
1112 // ��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 BOOL alpha_valid;
1173
1174 // ���������[�h(�`��)����
1175 BGLoadSrc(hdc_work, &BGDest);
1176 alpha_valid = IsAlphaValidBitmapHDC(BGDest.hdc);
1177
1178 // ���������������\���t����
1179 memset(&bf, 0, sizeof(bf));
1180 bf.BlendOp = AC_SRC_OVER;
1181 bf.SourceConstantAlpha = BGDest.alpha;
1182 bf.AlphaFormat = 0;
1183 if (alpha_valid) {
1184 // 32bit�r�b�g�}�b�v(alpha�l��������������)������alpha�l���Q������
1185 bf.AlphaFormat = AC_SRC_ALPHA;
1186 }
1187 if (!BGSrc1.enable) {
1188 // ���������������������������h��������������
1189 FillBitmapDC(hdc_bg, BGDest.color);
1190 }
1191 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 // ����������
1198 BGLoadSrc(hdc_work, &BGSrc2);
1199
1200 // �\���t����
1201 memset(&bf, 0, sizeof(bf));
1202 bf.BlendOp = AC_SRC_OVER;
1203 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 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 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
1241 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 //���� or �w�i���v�����[�h
1250 BGPreloadSrc(&BGDest);
1251 BGPreloadSrc(&BGSrc1);
1252 BGPreloadSrc(&BGSrc2);
1253
1254 #ifdef _DEBUG
1255 OutputDebugPrintf("BGSetupPrimary : BGInSizeMove = %d\n",BGInSizeMove);
1256 #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 //�w�i HDC
1271 if(hdcBG) {
1272 DeleteBitmapDC(&hdcBG);
1273 }
1274
1275 hdcBG = CreateBGImage(ScreenWidth, ScreenHeight);
1276 }
1277 }
1278
1279 /**
1280 * �e�[�}�t�@�C����������������������
1281 *
1282 * @param file NULL�����t�@�C����������������(�f�t�H���g�l������)
1283 */
1284 static void BGReadIniFile(const wchar_t *file)
1285 {
1286 BGTheme bg_theme;
1287 TColorTheme color_theme;
1288 ThemeLoad(file, &bg_theme, &color_theme);
1289 ThemeSetBG(&bg_theme);
1290 ThemeSetColor(&color_theme);
1291 }
1292
1293 static void BGDestruct(void)
1294 {
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 BGEnable = FALSE;
1306 }
1307
1308 static void BGSetDefaultColor(TTTSet *pts)
1309 {
1310 TColorTheme color_theme;
1311 ThemeGetColorDefaultTS(pts, &color_theme);
1312 ThemeSetColor(&color_theme);
1313 }
1314
1315 /*
1316 * Eterm lookfeel�@�\����������������
1317 *
1318 * initialize_once:
1319 * TRUE: Tera Term���N����
1320 * FALSE: Tera Term���N�������O
1321 */
1322 void BGInitialize(BOOL initialize_once)
1323 {
1324 (void)initialize_once;
1325
1326 InitColorTable(ts.ANSIColor);
1327
1328 BGSetDefaultColor(&ts);
1329
1330 //���\�[�X����
1331 BGDestruct();
1332
1333 // 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
1345 /**
1346 * �e�[�}���������`�F�b�N���� BG�������s����(BGEnable=TRUE/FALSE)��������
1347 */
1348 static void DecideBGEnable(void)
1349 {
1350 vtdisp_work_t *w = &vtdisp_work;
1351
1352 // �w�i�����`�F�b�N
1353 if (BGDest.fileW == NULL || BGDest.fileW[0] == 0) {
1354 // �w�i�������g�p������
1355 BGDest.enable = FALSE;
1356 }
1357
1358 if (BGDest.enable == FALSE && BGSrc1.enable == FALSE && BGSrc2.enable == FALSE) {
1359 // BG���g�p������
1360 BGEnable = FALSE;
1361 w->bg_enable = FALSE;
1362 }
1363 else {
1364 BGEnable = TRUE;
1365 w->bg_enable = TRUE;
1366 }
1367 }
1368
1369 /**
1370 * �e�[�}���������s��
1371 * �e�[�}���������f�t�H���g��������
1372 * �e�[�}���������e�[�}�t�@�C���������o������������
1373 */
1374 void BGLoadThemeFile(const TTTSet *pts)
1375 {
1376 // �R���t�B�O�t�@�C��(�e�[�}�t�@�C��)������
1377 switch(pts->EtermLookfeel.BGEnable) {
1378 case 0:
1379 default:
1380 // �e�[�}����
1381 BGReadIniFile(NULL);
1382 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 }
1406 }
1407
1408 DecideBGEnable();
1409 }
1410
1411 /**
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 HPEN red_pen = CreatePen(PS_SOLID, 0, rgb);
1417 HGDIOBJ old_pen = SelectObject(hdc, red_pen);
1418 width--;
1419 height--;
1420 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 static void BGScrollWindow(HWND hwnd, int xa, int ya, RECT *Rect, RECT *ClipRect)
1485 {
1486 RECT r;
1487
1488 if (BGEnable) {
1489 InvalidateRect(HVTWin, ClipRect, FALSE);
1490 }
1491 else if (IsZoomed(hwnd)) {
1492 // �E�B���h�E����������������������
1493 switch (ts.MaximizedBugTweak) {
1494 case 1: // type 1: ScrollWindow ���g��������������������
1495 InvalidateRect(HVTWin, ClipRect, FALSE);
1496 break;
1497 case 2: // type 2: �X�N���[���������S��(NULL)��������������������������������������
1498 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 }
1509 else {
1510 ScrollWindow(hwnd, xa, ya, Rect, ClipRect);
1511 }
1512 }
1513
1514 void BGOnEnterSizeMove(void)
1515 {
1516 if(!BGEnable || !ts.EtermLookfeel.BGFastSizeMove)
1517 return;
1518
1519 BGInSizeMove = TRUE;
1520 }
1521
1522 void BGOnExitSizeMove(void)
1523 {
1524 if(!BGEnable || !ts.EtermLookfeel.BGFastSizeMove)
1525 return;
1526
1527 BGInSizeMove = FALSE;
1528
1529 BGSetupPrimary(TRUE);
1530 InvalidateRect(HVTWin,NULL,FALSE);
1531
1532 #if 0
1533 //�u���V������
1534 if(BGBrushInSizeMove)
1535 {
1536 DeleteObject(BGBrushInSizeMove);
1537 BGBrushInSizeMove = NULL;
1538 }
1539 #endif
1540 }
1541
1542 /**
1543 * WM_SETTINGCHANGE ���������o��
1544 */
1545 void BGOnSettingChange(void)
1546 {
1547 if(!BGEnable)
1548 return;
1549
1550 // TODO ���j�^(�f�B�X�v���C)�����������T�C�Y����������������?
1551 CRTWidth = GetSystemMetrics(SM_CXSCREEN);
1552 CRTHeight = GetSystemMetrics(SM_CYSCREEN);
1553
1554 BGSetupPrimary(TRUE);
1555 InvalidateRect(HVTWin, NULL, FALSE);
1556 }
1557
1558 /**
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 static const int index256[] = {
1568 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
1576 /**
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 }
1586
1587 /**
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 {
1595 int i;
1596
1597 // 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
1604 // ANSIColor[] ��16�����~��������
1605 for (i=16; i<=255; i++) {
1606 ANSIColor[i] = RGB(DefaultColorTable[i][0], DefaultColorTable[i][1], DefaultColorTable[i][2]);
1607 }
1608 }
1609
1610 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 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 #endif
1635 }
1636
1637 void InitDisp(void)
1638 {
1639 HDC TmpDC;
1640 BOOL bMultiDisplaySupport = FALSE;
1641 vtdisp_work_t *w = &vtdisp_work;
1642
1643 TmpDC = GetDC(NULL);
1644
1645 CRTWidth = GetSystemMetrics(SM_CXSCREEN);
1646 CRTHeight = GetSystemMetrics(SM_CYSCREEN);
1647
1648 BGInitialize(TRUE);
1649
1650 DispSetNearestColors(IdBack, 255, TmpDC);
1651
1652 /* background paintbrush */
1653 Background = CreateSolidBrush(ts.VTColor[1]);
1654 /* CRT width & height */
1655 if (HasMultiMonitorSupport()) {
1656 bMultiDisplaySupport = TRUE;
1657 }
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
1702 w->bg_enable = FALSE;
1703 w->alpha_back = 255;
1704 w->alpha_vtback = 255;
1705 w->debug_drawbox_text = FALSE;
1706 w->debug_drawbox_fillrect = FALSE;
1707 w->font_resize_enable = TRUE;
1708 BGReverseTextAlpha = 255;
1709 }
1710
1711 void EndDisp(void)
1712 {
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
1734 free(BGDest.fileW);
1735 BGDest.fileW = NULL;
1736 }
1737
1738 void DispReset(void)
1739 {
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 static void SetLogFont(LOGFONTA *VTlf, BOOL mul)
1784 {
1785 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 const UINT uDpi = GetMonitorDpiFromWindow(HVTWin);
1800 VTlf->lfWidth = MulDiv(VTlf->lfWidth, uDpi, 96);
1801 VTlf->lfHeight = MulDiv(VTlf->lfHeight, uDpi, 96);
1802 }
1803 }
1804
1805 void ChangeFont(void)
1806 {
1807 int i, j;
1808 LOGFONTA VTlf;
1809
1810 /* 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
1820 /* Normal Font */
1821 SetLogFont(&VTlf, TRUE);
1822 VTFont[AttrDefault] = CreateFontIndirect(&VTlf);
1823
1824 /* set IME font */
1825 SetConversionLogFont(HVTWin, &VTlf);
1826
1827 {
1828 HDC TmpDC = GetDC(HVTWin);
1829 TEXTMETRIC Metrics;
1830
1831 SelectObject(TmpDC, VTFont[AttrDefault]);
1832 GetTextMetrics(TmpDC, &Metrics);
1833 FontWidth = Metrics.tmAveCharWidth + ts.FontDW;
1834 FontHeight = Metrics.tmHeight + ts.FontDH;
1835
1836 ReleaseDC(HVTWin,TmpDC);
1837 }
1838
1839 /* Underline */
1840 if ((ts.FontFlag & FF_UNDERLINE) || (ts.FontFlag & FF_URLUNDERLINE)) {
1841 VTlf.lfUnderline = 1;
1842 VTFont[AttrUnder] = CreateFontIndirect(&VTlf);
1843 }
1844 else {
1845 VTFont[AttrUnder] = VTFont[AttrDefault];
1846 }
1847
1848 if (ts.FontFlag & FF_BOLD) {
1849 /* Bold */
1850 VTlf.lfUnderline = 0;
1851 VTlf.lfWeight = FW_BOLD;
1852 VTFont[AttrBold] = CreateFontIndirect(&VTlf);
1853
1854 /* Bold + Underline */
1855 if (ts.FontFlag & FF_UNDERLINE || ts.FontFlag & FF_URLUNDERLINE) {
1856 VTlf.lfUnderline = 1;
1857 VTFont[AttrBold | AttrUnder] = CreateFontIndirect(&VTlf);
1858 }
1859 else {
1860 VTFont[AttrBold | AttrUnder] = VTFont[AttrBold];
1861 }
1862 }
1863 else {
1864 VTFont[AttrBold] = VTFont[AttrDefault];
1865 VTFont[AttrBold | AttrUnder] = VTFont[AttrUnder];
1866 }
1867
1868 /* 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
1875 strncpy_s(VTlf.lfFaceName, sizeof(VTlf.lfFaceName),"Tera Special", _TRUNCATE);
1876 VTFont[AttrSpecial] = CreateFontIndirect(&VTlf);
1877
1878 /* Special font (Underline) */
1879 if (ts.FontFlag & FF_UNDERLINE || ts.FontFlag & FF_URLUNDERLINE) {
1880 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
1888 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
1895 /* Special font (Bold + Underline) */
1896 if (ts.FontFlag & FF_UNDERLINE || ts.FontFlag & FF_URLUNDERLINE) {
1897 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 }
1905 else {
1906 VTFont[AttrSpecial | AttrBold] = VTFont[AttrSpecial];
1907 VTFont[AttrSpecial | AttrBold | AttrUnder] = VTFont[AttrSpecial | AttrUnder];
1908 }
1909 }
1910
1911 void ResetIME(void)
1912 {
1913 /* reset language for communication */
1914 cv.Language = ts.Language;
1915
1916 /* reset IME */
1917 if ((ts.Language==IdJapanese) || (ts.Language==IdKorean) || (ts.Language==IdUtf8)) //HKS
1918 {
1919 if (ts.UseIME==0)
1920 FreeIME(HVTWin);
1921 else if (! LoadIME()) {
1922 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 WritePrivateProfileStringW(L"Tera Term", L"IME", L"off", ts.SetupFNameW);
1930 ts.UseIME = 0;
1931 }
1932
1933 if (ts.UseIME>0)
1934 {
1935 if (ts.IMEInline>0) {
1936 LOGFONTA VTlf;
1937 SetLogFont(&VTlf, TRUE);
1938 SetConversionLogFont(HVTWin, &VTlf);
1939 }
1940 else
1941 SetConversionWindow(HVTWin,-1,0);
1942 }
1943 }
1944 else
1945 FreeIME(HVTWin);
1946
1947 if (IsCaretOn()) CaretOn();
1948 }
1949
1950 void ChangeCaret(void)
1951 {
1952 UINT T;
1953
1954 if (! Active) return;
1955 DestroyCaret();
1956 switch (ts.CursorShape) {
1957 case IdVCur:
1958 CreateCaret(HVTWin, 0, CurWidth, FontHeight);
1959 break;
1960 case IdHCur:
1961 CreateCaret(HVTWin, 0, FontWidth, CurWidth);
1962 break;
1963 }
1964 if (CaretEnabled) {
1965 CaretStatus = 1;
1966 }
1967 CaretOn();
1968 if (CaretEnabled && (ts.NonblinkingCursor!=0)) {
1969 T = GetCaretBlinkTime() * 2 / 3;
1970 SetTimer(HVTWin,IdCaretTimer,T,NULL);
1971 }
1972 UpdateCaretPosition(TRUE);
1973 }
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 //
2032 // �J�[�\���`�����X��(ChangeCaret)�����������������������A���������X -- 2009/04/17 doda.
2033 //
2034 void UpdateCaretPosition(BOOL enforce)
2035 {
2036 int CaretX, CaretY;
2037 RECT rc;
2038
2039 CaretX = (CursorX-WinOrgX)*FontWidth;
2040 CaretY = (CursorY-WinOrgY)*FontHeight;
2041
2042 if (!enforce && !ts.KillFocusCursor)
2043 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 void CaretOn(void)
2064 // Turn on the cursor
2065 {
2066 #if UNICODE_DEBUG_CARET_OFF
2067 return;
2068 #endif
2069 if (ts.KillFocusCursor == 0 && !Active)
2070 return;
2071
2072 if (! CaretEnabled) return;
2073
2074 if (Active) {
2075 int CaretX, CaretY, H;
2076 HBITMAP color;
2077
2078 /* 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
2092 CaretX = (CursorX-WinOrgX)*FontWidth;
2093 CaretY = (CursorY-WinOrgY)*FontHeight;
2094
2095 if (IMEstat && IMECompositionState) {
2096 // IME ON && ���������������������������B
2097 // ������(�����������E�B���h�E���\����������������)��
2098 // �z�X�g�������G�R�[�����M����caret���u���������������A
2099 // ���������������u���X�V�����K�v�������B
2100 SetConversionWindow(HVTWin,CaretX,CaretY);
2101 }
2102
2103 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 CreateCaret(HVTWin, color, FontWidth*2, H);
2116 }
2117 else {
2118 /* single width caret */
2119 CreateCaret(HVTWin, color, FontWidth, H);
2120 }
2121 CaretStatus = 1;
2122 }
2123 SetCaretPos(CaretX,CaretY);
2124 }
2125
2126 while (CaretStatus > 0) {
2127 if (! Active) {
2128 CaretKillFocus(TRUE);
2129 } else {
2130 ShowCaret(HVTWin);
2131 }
2132 CaretStatus--;
2133 }
2134 }
2135
2136 void CaretOff(void)
2137 {
2138 if (ts.KillFocusCursor == 0 && !Active)
2139 return;
2140
2141 if (CaretStatus == 0) {
2142 if (! Active) {
2143 CaretKillFocus(FALSE);
2144 } else {
2145 HideCaret(HVTWin);
2146 }
2147 CaretStatus++;
2148 }
2149 }
2150
2151 void DispDestroyCaret(void)
2152 {
2153 DestroyCaret();
2154 if (ts.NonblinkingCursor!=0)
2155 KillTimer(HVTWin,IdCaretTimer);
2156 }
2157
2158 BOOL IsCaretOn(void)
2159 // check if caret is on
2160 {
2161 return ((ts.KillFocusCursor || Active) && (CaretStatus==0));
2162 }
2163
2164 void DispEnableCaret(BOOL On)
2165 {
2166 #if UNICODE_DEBUG_CARET_OFF
2167 On = FALSE;
2168 #endif
2169 if (! On) CaretOff();
2170 CaretEnabled = On;
2171 }
2172
2173 BOOL IsCaretEnabled(void)
2174 {
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
2215 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 void DispEndPaint(void)
2300 {
2301 if (VTDC==NULL) return;
2302 SelectObject(VTDC,DCPrevFont);
2303 VTDC = NULL;
2304 }
2305
2306 void DispClearWin(void)
2307 {
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 else
2320 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 void DispChangeBackground(void)
2329 {
2330 DispReleaseDC();
2331
2332 UpdateBGBrush();
2333
2334 InvalidateRect(HVTWin,NULL,TRUE);
2335 }
2336
2337 void DispChangeWin(void)
2338 {
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 void DispInitDC(void)
2355 {
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 void DispReleaseDC(void)
2372 {
2373 if (VTDC==NULL) return;
2374 SelectObject(VTDC, DCPrevFont);
2375 ReleaseDC(HVTWin,VTDC);
2376 VTDC = NULL;
2377 }
2378
2379 /**
2380 * �V�[�P���X��color_index��ANSIColor[]��index����������
2381 *
2382 * 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 *
2392 * @param color_index �F����
2393 * @param pcbold16 0/0���O = 16 color mode PC Style��������/������
2394 * @param pcbold16_bright 0/0���O = �F��������������/����
2395 * @return ANSIColor[]��index (ANSI color 256�F��index)
2396 */
2397 static int Get16ColorIndex(int color_index_256, int pcbold16, int pcbold16_bright)
2398 {
2399 if ((ts.ColorFlag & CF_FULLCOLOR) == 0) {
2400 // 8�F���[�h
2401 // 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 }
2412 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 }
2422 else {
2423 return color_index_256;
2424 }
2425 }
2426 else {
2427 return color_index_256;
2428 }
2429 }
2430 else {
2431 // 16/256�F
2432 return color_index_256;
2433 }
2434 }
2435
2436 /**
2437 * �������A�g���r���[�g�����](�����I��)���������`���F����������
2438 *
2439 * @param[in] Attr ������������
2440 * @param[in] reverse ���](�����I��)����
2441 * @param[out] fore_color �����O�i�F
2442 * @param[out] back_color �����w�i�F
2443 * @param[ot] alpha ��������
2444 */
2445 static void GetDrawAttr(const TCharAttr *Attr, BOOL _reverse, COLORREF *fore_color, COLORREF *back_color, BYTE *_alpha)
2446 {
2447 COLORREF TextColor, BackColor;
2448 WORD AttrFlag; // Attr + Flag
2449 WORD Attr2Flag; // Attr2 + Flag
2450 BOOL reverse;
2451 const BOOL use_normal_bg_color = ts.UseNormalBGColor;
2452 vtdisp_work_t *w = &vtdisp_work;
2453 BYTE alpha;
2454
2455 // ts.ColorFlag �� Attr ���������� Attr ������
2456 AttrFlag = 0;
2457 AttrFlag |= ((ts.ColorFlag & CF_URLCOLOR) && (Attr->Attr & AttrURL)) ? AttrURL : 0;
2458 AttrFlag |= ((ts.ColorFlag & CF_UNDERLINE) && (Attr->Attr & AttrUnder)) ? AttrUnder : 0;
2459 AttrFlag |= ((ts.ColorFlag & CF_BOLDCOLOR) && (Attr->Attr & AttrBold)) ? AttrBold : 0;
2460 AttrFlag |= ((ts.ColorFlag & CF_BLINKCOLOR) && (Attr->Attr & AttrBlink)) ? AttrBlink : 0;
2461 AttrFlag |= (Attr->Attr & AttrReverse) ? AttrReverse : 0;
2462 Attr2Flag = 0;
2463 Attr2Flag |= ((ts.ColorFlag & CF_ANSICOLOR) && (Attr->Attr2 & Attr2Fore)) ? Attr2Fore : 0;
2464 Attr2Flag |= ((ts.ColorFlag & CF_ANSICOLOR) && (Attr->Attr2 & Attr2Back)) ? Attr2Back : 0;
2465
2466 // ���]
2467 reverse = FALSE;
2468 if (_reverse) {
2469 reverse = TRUE;
2470 }
2471 if ((AttrFlag & AttrReverse) != 0) {
2472 reverse = reverse ? FALSE : TRUE;
2473 }
2474 if ((ts.ColorFlag & CF_REVERSEVIDEO) != 0) {
2475 reverse = reverse ? FALSE : TRUE;
2476 }
2477
2478 // �F����������
2479 TextColor = BGVTColor[0];
2480 BackColor = BGVTColor[1];
2481 if ((AttrFlag & (AttrURL | AttrUnder | AttrBold | AttrBlink)) == 0) {
2482 if (!reverse) {
2483 TextColor = BGVTColor[0];
2484 BackColor = BGVTColor[1];
2485 }
2486 else {
2487 if ((ts.ColorFlag & CF_REVERSECOLOR) == 0) {
2488 TextColor = BGVTColor[1];
2489 BackColor = BGVTColor[0];
2490 }
2491 else {
2492 // ���]�����F���L��
2493 TextColor = BGVTReverseColor[0];
2494 BackColor = BGVTReverseColor[1];
2495 }
2496 }
2497 } else if (AttrFlag & AttrBlink) {
2498 if (!reverse) {
2499 TextColor = BGVTBlinkColor[0];
2500 if (!use_normal_bg_color) {
2501 BackColor = BGVTBlinkColor[1];
2502 } else {
2503 BackColor = BGVTColor[1];
2504 }
2505 } else {
2506 if (!use_normal_bg_color) {
2507 TextColor = BGVTBlinkColor[1];
2508 } else {
2509 TextColor = BGVTColor[1];
2510 }
2511 BackColor = BGVTBlinkColor[0];
2512 }
2513 } else if (AttrFlag & AttrBold) {
2514 if (!reverse) {
2515 TextColor = BGVTBoldColor[0];
2516 if (!use_normal_bg_color) {
2517 BackColor = BGVTBoldColor[1];
2518 } else {
2519 BackColor = BGVTColor[1];
2520 }
2521 } else {
2522 if (!use_normal_bg_color) {
2523 TextColor = BGVTBoldColor[1];
2524 } else {
2525 TextColor = BGVTColor[1];
2526 }
2527 BackColor = BGVTBoldColor[0];
2528 }
2529 } else if (AttrFlag & AttrUnder) {
2530 if (!reverse) {
2531 TextColor = BGVTUnderlineColor[0];
2532 if (!use_normal_bg_color) {
2533 BackColor = BGVTUnderlineColor[1];
2534 } else {
2535 BackColor = BGVTColor[1];
2536 }
2537 } else {
2538 if (!use_normal_bg_color) {
2539 TextColor = BGVTUnderlineColor[1];
2540 } else {
2541 TextColor = BGVTColor[1];
2542 }
2543 BackColor = BGVTUnderlineColor[0];
2544 }
2545 } else if (AttrFlag & AttrURL) {
2546 if (!reverse) {
2547 TextColor = BGURLColor[0];
2548 if (!use_normal_bg_color) {
2549 BackColor = BGURLColor[1];
2550 } else {
2551 BackColor = BGVTColor[1];
2552 }
2553 } else {
2554 if (!use_normal_bg_color) {
2555 TextColor = BGURLColor[1];
2556 } else {
2557 TextColor = BGVTColor[1];
2558 }
2559 BackColor = BGURLColor[0];
2560 }
2561 }
2562
2563 // ANSIColor/Fore
2564 if (Attr2Flag & Attr2Fore) {
2565 const int index = Get16ColorIndex(Attr->Fore, ts.ColorFlag & CF_PCBOLD16, AttrFlag & AttrBold);
2566 if (!reverse) {
2567 TextColor = ANSIColor[index];
2568 }
2569 else {
2570 BackColor = ANSIColor[index];
2571 }
2572 }
2573
2574 // ANSIColor/Back
2575 if (Attr2Flag & Attr2Back) {
2576 const int index = Get16ColorIndex(Attr->Back, ts.ColorFlag & CF_PCBOLD16, AttrFlag & AttrBlink);
2577 if (!reverse) {
2578 BackColor = ANSIColor[index];
2579 }
2580 else {
2581 TextColor = ANSIColor[index];
2582 }
2583 }
2584
2585 // UseTextColor=on ������������
2586 // �w�i�F(Back)���l�������������F(Fore)���������X�����A�v�����g��������
2587 // �������������������������������������F�����]���������F���g�p����
2588 if ((ts.ColorFlag & CF_USETEXTCOLOR) !=0) {
2589 if ((Attr2Flag & Attr2Fore) && (Attr2Flag & Attr2Back)) {
2590 const int is_target_color = (Attr->Fore == IdFore || Attr->Fore == IdBack || Attr->Fore == 15);
2591 // const int is_target_color = 1;
2592 if (Attr->Fore == Attr->Back && is_target_color) {
2593 if (!reverse) {
2594 TextColor = BGVTColor[0];
2595 BackColor = BGVTColor[1];
2596 }
2597 else {
2598 TextColor = BGVTReverseColor[0];
2599 BackColor = BGVTReverseColor[1];
2600 }
2601 }
2602 }
2603 }
2604
2605 if (BackColor == BGVTColor[1]) {
2606 // ����(�A�g���r���[�g����)��back
2607 alpha = w->alpha_vtback;
2608 }
2609 else if (!reverse) {
2610 // ����(���]����(SGR 4)���O)��back
2611 alpha = w->alpha_back;
2612 }
2613 else {
2614 // ���]����(SGR 4)��back
2615 alpha = BGReverseTextAlpha;
2616 }
2617
2618 *fore_color = TextColor;
2619 *back_color = BackColor;
2620 *_alpha = alpha;
2621 }
2622
2623 /**
2624 * Setup device context
2625 * Attr: character attributes
2626 * Reverse: true if text is selected (reversed) by mouse
2627 */
2628 void DispSetupDC(TCharAttr Attr, BOOL Reverse)
2629 {
2630 vtdisp_work_t *w = &vtdisp_work;
2631 COLORREF TextColor, BackColor;
2632 BYTE alpha;
2633
2634 GetDrawAttr(&Attr, Reverse, &TextColor, &BackColor, &alpha);
2635
2636 if (VTDC == NULL)
2637 DispInitDC();
2638
2639 // �t�H���g����
2640 if (((ts.FontFlag & FF_URLUNDERLINE) && (Attr.Attr & AttrURL)) ||
2641 ((ts.FontFlag & FF_UNDERLINE) && (Attr.Attr & AttrUnder))) {
2642 SelectObject(VTDC, VTFont[(Attr.Attr & AttrFontMask) | AttrUnder]);
2643 }
2644 else {
2645 SelectObject(VTDC, VTFont[Attr.Attr & (AttrBold|AttrSpecial)]);
2646 }
2647
2648 // �F����
2649 SetTextColor(VTDC, TextColor);
2650 SetBkColor(VTDC, BackColor);
2651
2652 w->DCBackColor = BackColor;
2653 w->DCBackAlpha = alpha;
2654 }
2655
2656 /**
2657 * 1�s�`�� ANSI
2658 */
2659 void DrawStrA(HDC DC, HDC BGDC, const char *StrA, const char *WidthInfo, int Count, int font_width, int font_height, int Y, int *X)
2660 {
2661 int Dx[TermWidthMax];
2662 int HalfCharCount = 0;
2663 int i;
2664 int width;
2665 int height;
2666 BOOL direct_draw;
2667 BYTE alpha = 0;
2668 vtdisp_work_t *w = &vtdisp_work;
2669
2670 {
2671 const char *wp = WidthInfo;
2672 int *d = Dx;
2673 for (i = 0; i < Count; i++) {
2674 int w = *wp++;
2675 int j;
2676 *d++ = font_width;
2677 for (j = 0; j < w - 1; j++) {
2678 *d++ = font_width;
2679 wp++;
2680 i++;
2681 }
2682 HalfCharCount += w;
2683 }
2684 }
2685
2686 direct_draw = FALSE;
2687 if (BGDC == NULL) {
2688 // ���[�N���w���������������`��
2689 direct_draw = TRUE;
2690 }
2691 else {
2692 alpha = w->DCBackAlpha;
2693 if (alpha == 255) {
2694 direct_draw = TRUE;
2695 }
2696 }
2697
2698 // �e�L�X�g�`������
2699 width = HalfCharCount * font_width;
2700 height = font_height;
2701 if (direct_draw) {
2702 RECT RText;
2703 SetRect(&RText, *X, Y, *X + width, Y + height);
2704
2705 ExtTextOutA(DC, *X + ts.FontDX, Y + ts.FontDY, ETO_CLIPPED | ETO_OPAQUE, &RText, StrA, Count, &Dx[0]);
2706 }
2707 else {
2708 HFONT hPrevFont;
2709 RECT rect;
2710
2711 // BGDC���w�i�������`��
2712 const COLORREF BackColor = GetBkColor(DC);
2713 DrawTextBGImage(BGDC, *X, Y, width, height, BackColor, alpha);
2714
2715 // BGDC���������`��
2716 hPrevFont = SelectObject(BGDC, GetCurrentObject(DC, OBJ_FONT));
2717 SetTextColor(BGDC, GetTextColor(DC));
2718 SetBkColor(BGDC, GetBkColor(DC));
2719 SetRect(&rect, 0, 0, 0 + width, 0 + height);
2720 ExtTextOutA(BGDC, ts.FontDX, ts.FontDY, ETO_CLIPPED, &rect, StrA, Count, &Dx[0]);
2721 SelectObject(BGDC, hPrevFont);
2722
2723 // BGDC���`������������Window���\���t��
2724 BitBlt(DC, *X, Y, width, height, BGDC, 0, 0, SRCCOPY);
2725
2726 SelectObject(BGDC, hPrevFont);
2727 }
2728
2729 *X += width;
2730
2731 if (w->debug_drawbox_text) {
2732 DrawBox(DC, *X, Y, width, height, RGB(0xff, 0, 0));
2733 }
2734 }
2735
2736 static void DrawChar(HDC hDC, HDC BGDC, int x, int y, const wchar_t *str, size_t len, int cell)
2737 {
2738 SIZE char_size;
2739 HDC char_dc;
2740 HBITMAP bitmap;
2741 HBITMAP prev_bitmap;
2742 RECT rc;
2743 vtdisp_work_t *w = &vtdisp_work;
2744
2745 GetTextExtentPoint32W(hDC, str, (int)len, &char_size);
2746
2747 char_dc = CreateCompatibleDC(hDC);
2748 SetTextColor(char_dc, GetTextColor(hDC));
2749 SetBkColor(char_dc, GetBkColor(hDC));
2750 SelectObject(char_dc, GetCurrentObject(hDC, OBJ_FONT));
2751 bitmap = CreateCompatibleBitmap(hDC, char_size.cx, char_size.cy);
2752 prev_bitmap = SelectObject(char_dc, bitmap);
2753
2754 rc.top = 0;
2755 rc.left = 0;
2756 rc.right = char_size.cx;
2757 rc.bottom = char_size.cy;
2758 ExtTextOutW(char_dc, 0, 0, ETO_OPAQUE, &rc, str, (UINT)len, 0);
2759
2760 // ����cell��(cell*FontWidth pixel)���g��/�k�������`��
2761 int width = cell * FontWidth;
2762 int height = char_size.cy;
2763 if (pTransparentBlt == NULL || BGDC == NULL || w->DCBackAlpha == 255) {
2764 // �����`��
2765 SetStretchBltMode(hDC, COLORONCOLOR);
2766 StretchBlt(hDC, x, y, width, height, char_dc, 0, 0, char_size.cx, char_size.cy, SRCCOPY);
2767 }
2768 else {
2769 // BGDC���w�i�������`��
2770 const COLORREF BackColor = GetBkColor(hDC);
2771 DrawTextBGImage(BGDC, x, y, width, height, BackColor, w->DCBackAlpha);
2772
2773 // BGDC���������`��
2774 SetStretchBltMode(hDC, COLORONCOLOR);
2775 pTransparentBlt(BGDC, 0, 0, width, height, char_dc, 0, 0, char_size.cx, char_size.cy, GetBkColor(hDC));
2776
2777 // BGDC���`������������Window���\���t��
2778 BitBlt(hDC, x, y, width, height, BGDC, 0, 0, SRCCOPY);
2779 }
2780
2781 SelectObject(char_dc, prev_bitmap);
2782 DeleteObject(bitmap);
2783 DeleteDC(char_dc);
2784 }
2785
2786 static void DrawStrWSub(HDC DC, HDC BGDC, const wchar_t *StrW, const int *Dx,
2787 int Count, int cells, int font_width, int font_height,
2788 int Y, int *X)
2789 {
2790 int HalfCharCount = cells; // �Z����
2791 int width;
2792 int height;
2793 BOOL direct_draw;
2794 BYTE alpha = 0;
2795 vtdisp_work_t *w = &vtdisp_work;
2796
2797 direct_draw = FALSE;
2798 if (BGDC == NULL) {
2799 // ���[�N���w���������������`��
2800 direct_draw = TRUE;
2801 }
2802 else {
2803 alpha = w->DCBackAlpha;
2804 if (alpha == 255) {
2805 direct_draw = TRUE;
2806 }
2807 }
2808 // �e�L�X�g�`������
2809 width = HalfCharCount * font_width;
2810 height = font_height;
2811 if (direct_draw) {
2812 RECT RText;
2813 SetRect(&RText, *X, Y, *X + width, Y + height);
2814 ExtTextOutW(DC, *X + ts.FontDX, Y + ts.FontDY, ETO_CLIPPED | ETO_OPAQUE, &RText, StrW, Count, &Dx[0]);
2815 }
2816 else {
2817 HFONT hPrevFont;
2818 RECT rect;
2819
2820 // BGDC���w�i�������`��
2821 const COLORREF BackColor = GetBkColor(DC);
2822 DrawTextBGImage(BGDC, *X, Y, width, height, BackColor, alpha);
2823
2824 // BGDC���������`��
2825 hPrevFont = SelectObject(BGDC, GetCurrentObject(DC, OBJ_FONT));
2826 SetTextColor(BGDC, GetTextColor(DC));
2827 SetBkColor(BGDC, GetBkColor(DC));
2828 SetRect(&rect, 0, 0, 0 + width, 0 + height);
2829 ExtTextOutW(BGDC, ts.FontDX, ts.FontDY, ETO_CLIPPED, &rect, StrW, Count, &Dx[0]);
2830 SelectObject(BGDC, hPrevFont);
2831
2832 // BGDC���`������������Window���\���t��
2833 BitBlt(DC, *X, Y, width, height, BGDC, 0, 0, SRCCOPY);
2834 }
2835
2836 *X += width;
2837 }
2838
2839
2840 /**
2841 * 1�s�`�� Unicode
2842 * Windows 95 ���� ExtTextOutW() ������������
2843 * ������������������
2844 * TODO ����������������������?
2845 *
2846 * @param DC �`����DC
2847 * @param BGDC �`�������[�NDC
2848 * NULL�������[�N����(=�w�i�`������)
2849 * �v�����^�����o������������NULL
2850 * @param StrW �o������ (wchar_t)
2851 * @param cells[] �o��������cell��
2852 * 1 ���p����
2853 * 0 ��������, Nonspacing Mark
2854 * 2+ �S�p����, ���p + Spacing Mark
2855 * @param len ������
2856 *
2857 * ��
2858 * len=2, L"AB"
2859 * 0 1 2
2860 * StrW 'A' 'B'
2861 * cells 1 1
2862 *
2863 * len=2, U+307B U+309A (L'��' + L'�K')
2864 * 0 1 2
2865 * StrW U+307B U+309A
2866 * cells 0 2
2867 *
2868 */
2869 void DrawStrW(HDC DC, HDC BGDC, const wchar_t *StrW, const char *cells, int len, int font_width, int font_height,
2870 int Y, int *X)
2871 {
2872 int Dx[TermWidthMax];
2873 int cell = 0;
2874 int i;
2875 vtdisp_work_t *w = &vtdisp_work;
2876 int sx = *X;
2877
2878 if (len <= 0) {
2879 return;
2880 }
2881
2882 for (i = 0; i < len; i++) {
2883 cell += cells[i];
2884 Dx[i] = cells[i] * font_width;
2885 }
2886
2887 if (w->font_resize_enable) {
2888 int start_idx = 0;
2889 int cell_count = 0;
2890 int wchar_count = 0;
2891 int zero_count = 0;
2892 for (i = 0; i < len; i++) {
2893 if (cells[i] == 0) {
2894 if (cell_count != 0) {
2895 DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count, font_width, font_height, Y, X);
2896 start_idx = i;
2897 cell_count = 0;
2898 wchar_count = 0;
2899 }
2900 wchar_count++;
2901 zero_count++;
2902 }
2903 #if 0
2904 else if (zero_count > 2) {
2905 wchar_count++;
2906 cell_count += cells[i];
2907 DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count, font_width,
2908 font_height, Y, X);
2909 start_idx = i;
2910 zero_count = 0;
2911 cell_count = 0;
2912 wchar_count = 1;
2913 }
2914 #endif
2915 else {
2916 SIZE size;
2917 GetTextExtentPoint32W(DC, &StrW[i - zero_count], 1 + zero_count, &size);
2918 if ((size.cx == Dx[i])) {
2919 wchar_count++;
2920 cell_count += cells[i];
2921 }
2922 else {
2923 if (cell_count > 0) {
2924 DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count,
2925 font_width, font_height, Y, X);
2926 start_idx += wchar_count;
2927 }
2928 DrawChar(DC, BGDC, *X, Y, &StrW[i - zero_count], 1 + zero_count, cells[i]);
2929 *X += cells[i] * FontWidth;
2930 zero_count = 0;
2931 cell_count = 0;
2932 wchar_count = 0;
2933 start_idx++;
2934 }
2935 }
2936 }
2937 if (cell_count != 0) {
2938 DrawStrWSub(DC, BGDC, &StrW[start_idx], &Dx[start_idx], wchar_count, cell_count, font_width, font_height, Y,
2939 X);
2940 }
2941 }
2942 else {
2943 DrawStrWSub(DC, BGDC, StrW, Dx, len, cell, font_width, font_height, Y, X);
2944 }
2945
2946 if (w->debug_drawbox_text) {
2947 int width = cell * font_width;
2948 int height = font_height;
2949 DrawBox(DC, sx, Y, width, height, RGB(0, 255, 0));
2950 }
2951 }
2952
2953 /**
2954 * Display a string
2955 * @param Buff points the string
2956 * @param Y vertical position in window cordinate
2957 * @param[in] *X horizontal position
2958 * @param[out] *X horizontal position shifted by the width of the string
2959 */
2960 void DispStrA(const char *Buff, const char *WidthInfo, int Count, int Y, int* X)
2961 {
2962 HDC BGDC = BGEnable ? hdcBGBuffer : NULL;
2963 DrawStrA(VTDC, BGDC, Buff, WidthInfo, Count, FontWidth, FontHeight, Y, X);
2964 }
2965
2966 /**
2967 * DispStr() �� wchar_t��
2968 */
2969 void DispStrW(const wchar_t *StrW, const char *WidthInfo, int Count, int Y, int* X)
2970 {
2971 HDC BGDC = BGEnable ? hdcBGBuffer : NULL;
2972 DrawStrW(VTDC, BGDC, StrW, WidthInfo, Count, FontWidth, FontHeight, Y, X);
2973 }
2974
2975 BOOL DispDeleteLines(int Count, int YEnd)
2976 // return value:
2977 // TRUE - screen is successfully updated
2978 // FALSE - screen is not updated
2979 {
2980 RECT R;
2981
2982 if (Active && CompletelyVisible &&
2983 (YEnd+1-WinOrgY <= WinHeight))
2984 {
2985 R.left = 0;
2986 R.right = ScreenWidth;
2987 R.top = (CursorY-WinOrgY)*FontHeight;
2988 R.bottom = (YEnd+1-WinOrgY)*FontHeight;
2989 // ScrollWindow(HVTWin,0,-FontHeight*Count,&R,&R);
2990 BGScrollWindow(HVTWin,0,-FontHeight*Count,&R,&R);
2991 UpdateWindow(HVTWin);
2992 return TRUE;
2993 }
2994 else
2995 return FALSE;
2996 }
2997
2998 BOOL DispInsertLines(int Count, int YEnd)
2999 // return value:
3000 // TRUE - screen is successfully updated
3001 // FALSE - screen is not updated
3002 {
3003 RECT R;
3004
3005 if (Active && CompletelyVisible &&
3006 (CursorY >= WinOrgY))
3007 {
3008 R.left = 0;
3009 R.right = ScreenWidth;
3010 R.top = (CursorY-WinOrgY)*FontHeight;
3011 R.bottom = (YEnd+1-WinOrgY)*FontHeight;
3012 // ScrollWindow(HVTWin,0,FontHeight*Count,&R,&R);
3013 BGScrollWindow(HVTWin,0,FontHeight*Count,&R,&R);
3014 UpdateWindow(HVTWin);
3015 return TRUE;
3016 }
3017 else
3018 return FALSE;
3019 }
3020
3021 BOOL IsLineVisible(int* X, int* Y)
3022 // Check the visibility of a line
3023 // called from UpdateStr()
3024 // *X, *Y: position of a character in the line. screen coord.
3025 // Return: TRUE if the line is visible.
3026 // *X, *Y:
3027 // If the line is visible
3028 // position of the character in window coord.
3029 // Otherwise
3030 // no change. same as input value.
3031 {
3032 if ((dScroll != 0) &&
3033 (*Y>=SRegionTop) &&
3034 (*Y<=SRegionBottom))
3035 {
3036 *Y = *Y + dScroll;
3037 if ((*Y<SRegionTop) || (*Y>SRegionBottom))
3038 return FALSE;
3039 }
3040
3041 if ((*Y<WinOrgY) ||
3042 (*Y>=WinOrgY+WinHeight))
3043 return FALSE;
3044
3045 /* screen coordinate -> window coordinate */
3046 *X = (*X-WinOrgX)*FontWidth;
3047 *Y = (*Y-WinOrgY)*FontHeight;
3048 return TRUE;
3049 }
3050
3051 //-------------- scrolling functions --------------------
3052
3053 void AdjustScrollBar(void) /* called by ChangeWindowSize() */
3054 {
3055 LONG XRange, YRange;
3056 int ScrollPosX, ScrollPosY;
3057
3058 if (NumOfColumns-WinWidth>0)
3059 XRange = NumOfColumns-WinWidth;
3060 else
3061 XRange = 0;
3062
3063 if (BuffEnd-WinHeight>0)
3064 YRange = BuffEnd-WinHeight;
3065 else
3066 YRange = 0;
3067
3068 ScrollPosX = GetScrollPos(HVTWin,SB_HORZ);
3069 ScrollPosY = GetScrollPos(HVTWin,SB_VERT);
3070 if (ScrollPosX > XRange)
3071 ScrollPosX = XRange;
3072 if (ScrollPosY > YRange)
3073 ScrollPosY = YRange;
3074
3075 WinOrgX = ScrollPosX;
3076 WinOrgY = ScrollPosY-PageStart;
3077 NewOrgX = WinOrgX;
3078 NewOrgY = WinOrgY;
3079
3080 DontChangeSize = TRUE;
3081
3082 SetScrollRange(HVTWin,SB_HORZ,0,XRange,FALSE);
3083
3084 if ((YRange == 0) && (ts.EnableScrollBuff>0))
3085 {
3086 SetScrollRange(HVTWin,SB_VERT,0,1,FALSE);
3087 }
3088 else {
3089 SetScrollRange(HVTWin,SB_VERT,0,YRange,FALSE);
3090 }
3091
3092 SetScrollPos(HVTWin,SB_HORZ,ScrollPosX,TRUE);
3093 SetScrollPos(HVTWin,SB_VERT,ScrollPosY,TRUE);
3094
3095 DontChangeSize = FALSE;
3096 }
3097
3098 void DispScrollToCursor(int CurX, int CurY)
3099 {
3100 if (CurX < NewOrgX)
3101 NewOrgX = CurX;
3102 else if (CurX >= NewOrgX+WinWidth)
3103 NewOrgX = CurX + 1 - WinWidth;
3104
3105 if (CurY < NewOrgY)
3106 NewOrgY = CurY;
3107 else if (CurY >= NewOrgY+WinHeight)
3108 NewOrgY = CurY + 1 - WinHeight;
3109 }
3110
3111 void DispScrollNLines(int Top, int Bottom, int Direction)
3112 // Scroll a region of the window by Direction lines
3113 // updates window if necessary
3114 // Top: top line of scroll region
3115 // Bottom: bottom line
3116 // Direction: +: forward, -: backward
3117 {
3118 if (((dScroll * Direction < 0) || (dScroll * Direction > 0)) &&
3119 (((SRegionTop != Top) || (SRegionBottom != Bottom)))) {
3120 DispUpdateScroll();
3121 }
3122 SRegionTop = Top;
3123 SRegionBottom = Bottom;
3124 dScroll = dScroll + Direction;
3125 if (Direction > 0)
3126 DispCountScroll(Direction);
3127 else
3128 DispCountScroll(-Direction);
3129 }
3130
3131 void DispCountScroll(int n)
3132 {
3133 ScrollCount = ScrollCount + n;
3134 if (ScrollCount>=ts.ScrollThreshold) DispUpdateScroll();
3135 }
3136
3137 void DispUpdateScroll(void)
3138 {
3139 int d;
3140 RECT R;
3141
3142 ScrollCount = 0;
3143
3144 /* Update partial scroll */
3145 if (dScroll != 0)
3146 {
3147 d = dScroll * FontHeight;
3148 R.left = 0;
3149 R.right = ScreenWidth;
3150 R.top = (SRegionTop-WinOrgY)*FontHeight;
3151 R.bottom = (SRegionBottom+1-WinOrgY)*FontHeight;
3152 // ScrollWindow(HVTWin,0,-d,&R,&R);
3153 BGScrollWindow(HVTWin,0,-d,&R,&R);
3154
3155 if ((SRegionTop==0) && (dScroll>0))
3156 { // update scroll bar if BuffEnd is changed
3157 if ((BuffEnd==WinHeight) &&
3158 (ts.EnableScrollBuff>0))
3159 SetScrollRange(HVTWin,SB_VERT,0,1,TRUE);
3160 else
3161 SetScrollRange(HVTWin,SB_VERT,0,BuffEnd-WinHeight,FALSE);
3162 SetScrollPos(HVTWin,SB_VERT,WinOrgY+PageStart,TRUE);
3163 }
3164 dScroll = 0;
3165 }
3166
3167 /* Update normal scroll */
3168 if (NewOrgX < 0) NewOrgX = 0;
3169 if (NewOrgX>NumOfColumns-WinWidth)
3170 NewOrgX = NumOfColumns-WinWidth;
3171 if (NewOrgY < -PageStart) NewOrgY = -PageStart;
3172 if (NewOrgY>BuffEnd-WinHeight-PageStart)
3173 NewOrgY = BuffEnd-WinHeight-PageStart;
3174
3175 /* �����s�����������X�N���[����������������
3176 NewOrgY���������������������o�b�t�@�s�����������������X�V���� */
3177 if (ts.AutoScrollOnlyInBottomLine != 0)
3178 {
3179 if ((BuffEnd==WinHeight) &&
3180 (ts.EnableScrollBuff>0))
3181 SetScrollRange(HVTWin,SB_VERT,0,1,TRUE);
3182 else
3183 SetScrollRange(HVTWin,SB_VERT,0,BuffEnd-WinHeight,FALSE);
3184 SetScrollPos(HVTWin,SB_VERT,NewOrgY+PageStart,TRUE);
3185 }
3186
3187 if ((NewOrgX==WinOrgX) &&
3188 (NewOrgY==WinOrgY)) return;
3189
3190 if (NewOrgX==WinOrgX)
3191 {
3192 d = (NewOrgY-WinOrgY) * FontHeight;
3193 // ScrollWindow(HVTWin,0,-d,NULL,NULL);
3194 BGScrollWindow(HVTWin,0,-d,NULL,NULL);
3195 }
3196 else if (NewOrgY==WinOrgY)
3197 {
3198 d = (NewOrgX-WinOrgX) * FontWidth;
3199 // ScrollWindow(HVTWin,-d,0,NULL,NULL);
3200 BGScrollWindow(HVTWin,-d,0,NULL,NULL);
3201 }
3202 else
3203 InvalidateRect(HVTWin,NULL,TRUE);
3204
3205 /* Update scroll bars */
3206 if (NewOrgX!=WinOrgX)
3207 SetScrollPos(HVTWin,SB_HORZ,NewOrgX,TRUE);
3208
3209 if (ts.AutoScrollOnlyInBottomLine == 0 && NewOrgY!=WinOrgY)
3210 {
3211 if ((BuffEnd==WinHeight) &&
3212 (ts.EnableScrollBuff>0))
3213 SetScrollRange(HVTWin,SB_VERT,0,1,TRUE);
3214 else
3215 SetScrollRange(HVTWin,SB_VERT,0,BuffEnd-WinHeight,FALSE);
3216 SetScrollPos(HVTWin,SB_VERT,NewOrgY+PageStart,TRUE);
3217 }
3218
3219 WinOrgX = NewOrgX;
3220 WinOrgY = NewOrgY;
3221
3222 if (IsCaretOn()) CaretOn();
3223 }
3224
3225 void DispScrollHomePos(void)
3226 {
3227 NewOrgX = 0;
3228 NewOrgY = 0;
3229 DispUpdateScroll();
3230 }
3231
3232 void DispAutoScroll(POINT p)
3233 {
3234 int X, Y;
3235
3236 X = (p.x + FontWidth / 2) / FontWidth;
3237 Y = p.y / FontHeight;
3238 if (X<0)
3239 NewOrgX = WinOrgX + X;
3240 else if (X>=WinWidth)
3241 NewOrgX = NewOrgX + X - WinWidth + 1;
3242 if (Y<0)
3243 NewOrgY = WinOrgY + Y;
3244 else if (Y>=WinHeight)
3245 NewOrgY = NewOrgY + Y - WinHeight + 1;
3246
3247 DispUpdateScroll();
3248 }
3249
3250 void DispHScroll(int Func, int Pos)
3251 {
3252 switch (Func) {
3253 case SCROLL_BOTTOM:
3254 NewOrgX = NumOfColumns-WinWidth;
3255 break;
3256 case SCROLL_LINEDOWN: NewOrgX = WinOrgX + 1; break;
3257 case SCROLL_LINEUP: NewOrgX = WinOrgX - 1; break;
3258 case SCROLL_PAGEDOWN:
3259 NewOrgX = WinOrgX + WinWidth - 1;
3260 break;
3261 case SCROLL_PAGEUP:
3262 NewOrgX = WinOrgX - WinWidth + 1;
3263 break;
3264 case SCROLL_POS: NewOrgX = Pos; break;
3265 case SCROLL_TOP: NewOrgX = 0; break;
3266 }
3267 DispUpdateScroll();
3268 }
3269
3270 void DispVScroll(int Func, int Pos)
3271 {
3272 switch (Func) {
3273 case SCROLL_BOTTOM:
3274 NewOrgY = BuffEnd-WinHeight-PageStart