Skip to content
Snippets Groups Projects
Commit 6a907f6f authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

More development...

Add setwinsize and setwinpos
Move blit from rect into gdi_thread
Add beep support
Add (non-functional) settitle support
parent 0e335a02
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #4148 passed
......@@ -8,15 +8,21 @@
#include "win32cio.h"
#include "scale.h"
HBITMAP bmp;
HWND win;
HANDLE rch;
HANDLE wch;
static HWND win;
static HANDLE rch;
static HANDLE wch;
static FILE *debug;
static uint8_t *title;
#define WM_USER_INVALIDATE WM_USER
#define WM_USER_SETSIZE (WM_USER + 1)
#define WM_USER_SETPOS (WM_USER + 2)
#define LCS_WINDOWS_COLOR_SPACE 0x57696E20
// Used to create a DI bitmap from bitmap_con data
BITMAPV5HEADER b5hdr = {
static BITMAPV5HEADER b5hdr = {
.bV5Size = sizeof(BITMAPV5HEADER),
.bV5Width = 640,
.bV5Height = -400,
......@@ -34,12 +40,41 @@ BITMAPV5HEADER b5hdr = {
extern HINSTANCE WinMainHInst;
static struct rectlist *update_list = NULL;
static struct rectlist *update_list_tail = NULL;
static struct rectlist *last = NULL;
static struct rectlist *next = NULL;
static pthread_mutex_t gdi_headlock;
static pthread_mutex_t bmp_lock;
static int bitmap_width,bitmap_height;
static pthread_mutex_t rect_lock;
// Internal implementation
static struct rectlist *
get_rect(void)
{
struct rectlist *ret;
pthread_mutex_lock(&rect_lock);
if (next != NULL) {
if (last != NULL)
bitmap_drv_free_rect(last);
last = next;
ret = next;
next = NULL;
}
else
ret = last;
pthread_mutex_unlock(&rect_lock);
return ret;
}
static void
next_rect(struct rectlist *rect)
{
pthread_mutex_lock(&rect_lock);
if (next != NULL)
bitmap_drv_free_rect(next);
next = rect;
pthread_mutex_unlock(&rect_lock);
}
static void
add_key(uint16_t key)
{
......@@ -47,6 +82,7 @@ add_key(uint16_t key)
uint8_t *bp = buf;
DWORD added;
DWORD remain;
if (key < 256) {
buf[0] = key;
remain = 1;
......@@ -72,31 +108,40 @@ sp_to_codepoint(uint16_t high, uint16_t low)
static LRESULT CALLBACK
gdi_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HBITMAP obmp;
HDC memDC;
HDC winDC;
HBITMAP di;
static HDC memDC = NULL;
WPARAM highpair;
uint32_t cp;
uint8_t ch;
uint16_t repeat;
uint16_t i;
bool alt;
HDC winDC;
struct rectlist *list;
int w,h;
switch(msg) {
case WM_PAINT:
list = get_rect();
if (list == NULL)
return 0;
winDC = BeginPaint(hwnd, &ps);
if (memDC == NULL)
memDC = CreateCompatibleDC(winDC);
pthread_mutex_lock(&bmp_lock);
obmp = SelectObject(memDC, bmp);
b5hdr.bV5Width = list->rect.width;
b5hdr.bV5Height = -list->rect.height;
b5hdr.bV5SizeImage = list->rect.width * list->rect.height * 4;
di = CreateDIBitmap(winDC, (BITMAPINFOHEADER *)&b5hdr, CBM_INIT, list->data, (BITMAPINFO *)&b5hdr, 0/*DIB_RGB_COLORS*/);
di = SelectObject(memDC, di);
pthread_mutex_lock(&vstatlock);
//BitBlt(winDC, 0, 0, vstat.winwidth, vstat.winheight, memDC, 0, 0, SRCCOPY);
StretchBlt(winDC, 0, 0, vstat.winwidth, vstat.winheight, memDC, 0, 0, vstat.scrnwidth, vstat.scrnheight, SRCCOPY);
w = vstat.winwidth;
h = vstat.winheight;
pthread_mutex_unlock(&vstatlock);
SelectObject(memDC, obmp);
pthread_mutex_unlock(&bmp_lock);
DeleteDC(memDC);
StretchBlt(winDC, 0, 0, w, h, memDC, 0, 0, list->rect.width, list->rect.height, SRCCOPY);
di = SelectObject(memDC, di);
DeleteObject(di);
EndPaint(hwnd, &ps);
break;
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
......@@ -125,24 +170,6 @@ gdi_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
// Must be called with vstatlock held
static void
setup_bitmaps(void)
{
HDC winDC;
pthread_mutex_lock(&bmp_lock);
if (bmp)
DeleteObject(bmp);
winDC = GetDC(win);
bmp = CreateCompatibleBitmap(winDC, vstat.scrnwidth, vstat.scrnheight);
ReleaseDC(win, winDC);
pthread_mutex_unlock(&bmp_lock);
b5hdr.bV5Width = vstat.scrnwidth;
b5hdr.bV5Height = -vstat.scrnheight;
b5hdr.bV5SizeImage = b5hdr.bV5Width * b5hdr.bV5Height * 4;
}
#define WMOD_CTRL 1
#define WMOD_LCTRL 2
#define WMOD_RCTRL 4
......@@ -156,10 +183,29 @@ magic_message(MSG msg)
size_t i;
uint8_t set = 0;
int *hack;
RECT r;
// TODO: When window gets focus, poll mods... *sigh*
// TODO: Check "extended" for RCTRL and RSHIFT
if (msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) {
switch(msg.message) {
case WM_USER_INVALIDATE:
InvalidateRect(win, NULL, FALSE);
return true;
case WM_USER_SETSIZE:
pthread_mutex_lock(&vstatlock);
// Now make the inside of the window the size we want (sigh)
r.left = r.top = 0;
r.right = vstat.winwidth = msg.wParam;
r.bottom = vstat.winheight = msg.lParam;
pthread_mutex_unlock(&vstatlock);
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
SetWindowPos(win, NULL, 0, 0, r.right - r.left, r.bottom - r.top, SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
return true;
case WM_USER_SETPOS:
SetWindowPos(win, NULL, msg.wParam, msg.lParam, 0, 0, SWP_NOSIZE|SWP_NOOWNERZORDER|SWP_NOZORDER);
return true;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
switch (msg.wParam) {
case VK_CONTROL:
set = WMOD_CTRL;
......@@ -187,14 +233,12 @@ magic_message(MSG msg)
mods &= ~set;
return false;
}
if (msg.message == WM_KEYUP)
return false;
while (keyval[i].VirtualKeyCode != 0) {
if (keyval[i].VirtualKeyCode == msg.wParam)
break;
i++;
}
if (keyval[i].VirtualKeyCode != 0) {
for (i = 0; keyval[i].VirtualKeyCode != 0; i++) {
if (keyval[i].VirtualKeyCode == msg.wParam) {
if (msg.lParam & (0x2000)) {
if (keyval[i].ALT > 255) {
add_key(keyval[i].ALT);
......@@ -219,7 +263,10 @@ magic_message(MSG msg)
return true;
}
}
break;
}
}
break;
}
return false;
......@@ -241,18 +288,17 @@ gdi_thread(void *arg)
wc.hCursor = LoadCursor(0, IDC_IBEAM);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = L"SyncTERM";
wc.lpszClassName = L"SyncConsole";
RegisterClassW(&wc);
pthread_mutex_lock(&vstatlock);
setup_bitmaps();
// Now make the inside of the window the size we want (sigh)
r.left = r.top = 0;
r.right = vstat.winwidth;
r.bottom = vstat.winheight;
pthread_mutex_unlock(&vstatlock);
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
win = CreateWindowW(wc.lpszClassName, L"SyncTERM", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, wc.hInstance, NULL);
win = CreateWindowW(wc.lpszClassName, L"SyncConsole", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, wc.hInstance, NULL);
while (GetMessage(&msg, NULL, 0, 0)) {
if (!magic_message(msg)) {
......@@ -271,7 +317,7 @@ gdi_thread(void *arg)
int
gdi_kbhit(void)
{
DWORD avail;
DWORD avail = 0;
PeekNamedPipe(rch, NULL, 0, NULL, &avail, NULL);
return (avail > 0);
......@@ -283,15 +329,16 @@ gdi_getch(void)
uint8_t ch;
DWORD got;
do {
ReadFile(rch, &ch, 1, &got, NULL);
} while (got == 0);
if (got == 0)
return 0;
return ch;
}
void
gdi_beep(void)
{
MessageBeep(MB_ICONWARNING);
}
void
......@@ -311,7 +358,7 @@ gdi_textmode(int mode)
pthread_mutex_lock(&vstatlock);
oldcols = vstat.cols;
bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
bitmap_drv_init_mode(mode, NULL, NULL);
if (vstat.scrnwidth > 0) {
for (scaling = 1; (scaling + 1) * vstat.scrnwidth < vstat.winwidth; scaling++)
;
......@@ -341,7 +388,10 @@ gdi_textmode(int mode)
vstat.winwidth = vstat.scrnwidth;
if (vstat.winheight < vstat.scrnheight)
vstat.winheight = vstat.scrnheight;
// TODO: This is called before there's a window...
gdi_setwinsize(vstat.winwidth, vstat.winheight);
pthread_mutex_unlock(&vstatlock);
bitmap_drv_request_pixels();
return;
}
......@@ -352,8 +402,19 @@ gdi_setname(const char *name)
}
void
gdi_settitle(const char *title)
gdi_settitle(const char *newTitle)
{
uint8_t *utf8;
size_t sz;
free(title);
utf8 = cp_to_utf8(getcodepage(), newTitle, strlen(newTitle), NULL);
// Overkill
sz = strlen(utf8) * 4;
title = malloc(sz);
if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, (LPWSTR)title, sz / 2))
PostMessageW(win, WM_SETTEXT, 0, (LPARAM)title);
free(utf8);
}
void
......@@ -375,6 +436,19 @@ gdi_getcliptext(void)
int
gdi_get_window_info(int *width, int *height, int *xpos, int *ypos)
{
pthread_mutex_lock(&vstatlock);
if(width)
*width=vstat.winwidth;
if(height)
*height=vstat.winheight;
// TODO
if(xpos)
*xpos=0;
if(ypos)
*ypos=0;
pthread_mutex_unlock(&vstatlock);
return(1);
}
int
......@@ -388,7 +462,7 @@ gdi_init(int mode)
_beginthread(gdi_thread, 0, NULL);
cio_api.mode=CIOLIB_MODE_GDI;
FreeConsole();
//FreeConsole();
cio_api.options |= CONIO_OPT_PALETTE_SETTING | CONIO_OPT_SET_TITLE | CONIO_OPT_SET_NAME | CONIO_OPT_SET_ICON;
return(0);
}
......@@ -396,8 +470,9 @@ gdi_init(int mode)
int
gdi_initciolib(int mode)
{
debug = fopen("gdi.log", "w");
pthread_mutex_init(&gdi_headlock, NULL);
pthread_mutex_init(&bmp_lock, NULL);
pthread_mutex_init(&rect_lock, NULL);
return(gdi_init(mode));
}
......@@ -421,9 +496,6 @@ gdi_flush(void)
{
struct rectlist *list;
struct rectlist *old_next;
HBITMAP di;
HDC mDC1, mDC2, winDC;
HBITMAP obmp1, obmp2;
pthread_mutex_lock(&gdi_headlock);
list = update_list;
......@@ -432,24 +504,10 @@ gdi_flush(void)
for (; list; list = old_next) {
old_next = list->next;
if (list->next == NULL) {
// Create the DI bitmap and blit to bitmap, then update
winDC = GetDC(win);
mDC1 = CreateCompatibleDC(winDC);
mDC2 = CreateCompatibleDC(mDC1);
di = CreateDIBitmap(winDC, (BITMAPINFOHEADER *)&b5hdr, CBM_INIT, list->data, (BITMAPINFO *)&b5hdr, 0/*DIB_RGB_COLORS*/);
ReleaseDC(win, winDC);
obmp1 = SelectObject(mDC1, di);
pthread_mutex_lock(&bmp_lock);
obmp2 = SelectObject(mDC2, bmp);
BitBlt(mDC2, list->rect.x, list->rect.y, list->rect.width, list->rect.height, mDC1, 0, 0, SRCCOPY);
SelectObject(mDC1, obmp1);
SelectObject(mDC2, obmp2);
pthread_mutex_unlock(&bmp_lock);
DeleteObject(di);
DeleteDC(mDC2);
DeleteDC(mDC1);
InvalidateRect(win, NULL, FALSE);
next_rect(list);
PostMessageW(win, WM_USER_INVALIDATE, 0, 0);
}
else
bitmap_drv_free_rect(list);
}
}
......@@ -468,7 +526,7 @@ gdi_getscaling(void)
int
gdi_mousepointer(enum ciolib_mouse_ptr type)
{
return -1;// 0 on success
return 0;
}
int
......@@ -486,9 +544,11 @@ gdi_hidemouse(void)
void
gdi_setwinposition(int x, int y)
{
PostMessageW(win, WM_USER_SETPOS, x, y);
}
void
gdi_setwinsize(int w, int h)
{
PostMessageW(win, WM_USER_SETSIZE, w, h);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment