Files
HMCLOCK/fontool/gdifb.c
2025-08-17 23:41:34 +08:00

292 lines
5.0 KiB
C

#define WINVER 0x0500
#include <windows.h>
#include <wingdi.h>
#include <stdio.h>
#include <unistd.h>
/*************************************************************/
static int width;
static int height;
unsigned char *gdifbuf;
static int gdifb_ready;
static HINSTANCE hInst;
static HBITMAP hbmp;
static HDC hmemdc;
static HANDLE h_gdifb;
static HANDLE h_window;
static DWORD gdifb_id;
static HWND gdifb;
static ATOM MyRegisterClass(void);
static BOOL InitInstance(void);
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static int vkey;
/*************************************************************/
DWORD WINAPI gdifb_main(LPVOID lpParam)
{
MSG msg;
hInst = GetModuleHandle(0);
MyRegisterClass();
if (!InitInstance ()) {
return FALSE;
}
gdifb_ready = 1;
// Main message loop:
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
ATOM MyRegisterClass()
{
WNDCLASS wc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "GDI_FB";
return RegisterClass(&wc);
}
void memdc_create(HWND hwnd)
{
BITMAPINFOHEADER bh;
HDC hdc;
memset(&bh, 0, sizeof(bh));
bh.biSize = sizeof(bh);
bh.biHeight = -(height+256);
//bh.biWidth = width;
bh.biWidth = 2048;
bh.biPlanes = 1;
bh.biBitCount = 32;
bh.biCompression = BI_RGB;
hdc = GetDC(hwnd);
hbmp = CreateDIBSection (hdc, (LPBITMAPINFO)&bh, DIB_RGB_COLORS, (void**)&gdifbuf, NULL, 0) ;
hmemdc = CreateCompatibleDC(hdc);
SelectObject(hmemdc, hbmp);
ReleaseDC(hwnd, hdc);
}
BOOL InitInstance()
{
DWORD style = WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_MAXIMIZEBOX;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = width;
rect.bottom = height;
AdjustWindowRect(&rect, style, FALSE);
h_window = CreateWindow("GDI_FB", "GDI_FB", style, CW_USEDEFAULT, 0,
rect.right-rect.left, rect.bottom-rect.top,
0, 0, hInst, 0);
if (!h_window){
return FALSE;
}
memdc_create(h_window);
ShowWindow(h_window, SW_SHOWDEFAULT);
UpdateWindow(h_window);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
BitBlt(hdc, 0, 0, width, height, hmemdc, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN:
vkey = wParam;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
/*************************************************************/
void gdifb_textout(int x, int y, char *text)
{
TextOut(hmemdc, x, y, text, strlen(text));
}
void gdifb_pixel(int x, int y, int color)
{
*(DWORD*)(gdifbuf + (y*2048 + x)*4) = color;
}
void gdifb_line(int x1, int y1, int x2, int y2, int color)
{
HPEN pen, old_pen;
pen = CreatePen(PS_SOLID, 1, color);
old_pen = SelectObject(hmemdc, pen);
MoveToEx(hmemdc, x1, y1, NULL);
LineTo(hmemdc, x2, y2);
SetPixel(hmemdc, x2, y2, color);
SelectObject(hmemdc, old_pen);
}
void gdifb_rect(int x1, int y1, int x2, int y2, int color)
{
HPEN pen, old_pen;
pen = CreatePen(PS_SOLID, 1, color);
old_pen = SelectObject(hmemdc, pen);
MoveToEx(hmemdc, x1, y1, NULL);
LineTo(hmemdc, x2, y1);
LineTo(hmemdc, x2, y2);
LineTo(hmemdc, x1, y2);
LineTo(hmemdc, x1, y1);
SelectObject(hmemdc, old_pen);
}
void gdifb_box(int x1, int y1, int x2, int y2, int color)
{
HPEN pen, old_pen;
HBRUSH brush;
RECT rect;
pen = CreatePen(PS_SOLID, 1, color);
old_pen = SelectObject(hmemdc, pen);
brush = CreateSolidBrush(color);
rect.left = x1;
rect.right = x2+1;
rect.top = y1;
rect.bottom = y2+1;
FillRect(hmemdc, &rect, brush);
SelectObject(hmemdc, old_pen);
}
void gdifb_flush(void)
{
InvalidateRect(gdifb, NULL, TRUE);
}
int gdifb_waitkey(void)
{
vkey = 0;
while(vkey==0);
return vkey;
}
/*************************************************************/
int gdifb_init(int w, int h)
{
width = w;
height = h;
gdifb_ready = 0;
h_gdifb = CreateThread(NULL, 0, gdifb_main, NULL, 0, &gdifb_id);
while(1){
gdifb = FindWindow(NULL, "GDI_FB");
if(gdifb)
break;
}
while(gdifb_ready==0);
return 0;
}
int gdifb_exit(int force)
{
if(force){
SendMessage(h_window, WM_CLOSE, 0, 0);
}
WaitForSingleObject(h_gdifb,INFINITE);
CloseHandle(h_gdifb);
return 0;
}
/*************************************************************/
#ifdef TEST_GDIFB
int main(int argc, char *argv[])
{
gdifb_init(320, 240);
gdifb_textout(48, 48, "gdifb_test!");
int i;
for(i=0; i<100; i++){
gdifb_pixel(20+i, 200, 0xff00ff);
}
gdifb_line(10, 10, 100, 100, 0x00FF0000);
gdifb_rect(5, 5, 300, 235, 0x000000FF);
gdifb_box(120, 120, 140, 140, 0x0000FF00);
gdifb_flush();
gdifb_exit();
return 0;
}
#endif
/*************************************************************/