1 namespace gui::drivers;
7 #define WIN32_LEAN_AND_MEAN
19 WINBASEAPI HWND WINAPI GetConsoleWindow ();
23 static HANDLE hStdin, hStdout, hInactive;
24 static byte keys[256];
25 static Point mousePosition;
26 static Box mouseRange;
29 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit;
30 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown;
31 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp;
33 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove;
34 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown;
35 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown;
36 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown;
37 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick;
38 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick;
39 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick;
40 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp;
41 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp;
42 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp;
46 /****************************************************************************
47 /// DRIVER IMPLEMENTATION /////////////
48 ****************************************************************************/
50 class Win32ConsoleInterface : Interface
52 class_property(name) = "Win32Console";
54 // --- User Interface System ---
57 CONSOLE_CURSOR_INFO cursor;
62 WINDOWPLACEMENT placement = { 0 };
64 placement.length = sizeof(WINDOWPLACEMENT);
65 placement.showCmd = SW_NORMAL;
66 placement.rcNormalPosition.top = 10;
67 placement.rcNormalPosition.left = 10;
68 placement.rcNormalPosition.right = 810;
69 placement.rcNormalPosition.bottom = 610;
70 SetWindowPlacement(GetConsoleWindow(), &placement);
71 ShowWindow(GetConsoleWindow(), SW_SHOW);
72 SetForegroundWindow(GetConsoleWindow());
75 hStdin = GetStdHandle(STD_INPUT_HANDLE);
76 SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
77 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
78 //SetConsoleMode(hStdout, 0);
79 FillBytes(keys, 0, sizeof(keys));
81 SetConsoleTitle(guiApp.desktop.text ? guiApp.desktop.text : "");
82 cursor.bVisible = FALSE;
84 SetConsoleCursorInfo(hStdout, &cursor);
85 SetTimer(null, 0, (uint)(1000.0 / 18.2), null);
92 CONSOLE_CURSOR_INFO cursor;
93 SetConsoleMode(hStdout, ENABLE_PROCESSED_OUTPUT);
94 cursor.bVisible = TRUE;
96 SetConsoleCursorInfo(hStdout, &cursor);
99 // ShowWindow(GetConsoleWindow(), SW_HIDE);
105 // SetForegroundWindow(GetActiveWindow());
106 WINDOWPLACEMENT placement = { 0 };
107 placement.length = sizeof(WINDOWPLACEMENT);
108 placement.showCmd = SW_HIDE;
109 SetWindowPlacement(GetConsoleWindow(), &placement);
113 bool ProcessInput(bool processAll)
116 GetNumberOfConsoleInputEvents(hStdin, &numInput);
119 for(c = 0; c<numInput; c++)
123 ReadConsoleInput(hStdin, &event, 1, &readInputs);
124 switch(event.EventType)
128 byte key = (byte)event.Event.KeyEvent.wVirtualScanCode;
129 byte ch = event.Event.KeyEvent.uChar.AsciiChar;
132 if(event.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)
133 key = (byte)GetExtendedKey(key);
136 if(event.Event.KeyEvent.dwControlKeyState&SHIFT_PRESSED)
137 keyFlags.shift = true;
138 if(event.Event.KeyEvent.dwControlKeyState&LEFT_ALT_PRESSED ||
139 event.Event.KeyEvent.dwControlKeyState&RIGHT_ALT_PRESSED)
141 if(event.Event.KeyEvent.dwControlKeyState&LEFT_CTRL_PRESSED ||
142 event.Event.KeyEvent.dwControlKeyState&RIGHT_CTRL_PRESSED)
143 keyFlags.ctrl = true;
145 if(event.Event.KeyEvent.bKeyDown)
148 guiApp.desktop.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit,keyFlags,ch);
151 keys[key] = (byte)bool::true;
152 guiApp.desktop.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown,keyFlags,ch);
157 keys[key] = (byte)bool::false;
158 guiApp.desktop.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp,keyFlags,ch);
164 Modifiers keyFlags = 0;
165 static MouseButtons lastButtonState = 0;
166 MouseButtons buttonState = event.Event.MouseEvent.dwButtonState;
168 if(event.Event.MouseEvent.dwControlKeyState&SHIFT_PRESSED)
169 keyFlags.shift = true;
170 if(event.Event.MouseEvent.dwControlKeyState&LEFT_ALT_PRESSED ||
171 event.Event.MouseEvent.dwControlKeyState&RIGHT_ALT_PRESSED)
173 if(event.Event.MouseEvent.dwControlKeyState&LEFT_CTRL_PRESSED ||
174 event.Event.MouseEvent.dwControlKeyState&RIGHT_CTRL_PRESSED)
175 keyFlags.ctrl = true;
177 switch(event.Event.MouseEvent.dwEventFlags)
181 int x = event.Event.MouseEvent.dwMousePosition.X * textCellW;
182 int y = event.Event.MouseEvent.dwMousePosition.Y * textCellH;
184 x = Min(Max(x, mouseRange.left), mouseRange.right);
185 y = Min(Max(y, mouseRange.top), mouseRange.bottom);
187 if(x != mousePosition.x || y != mousePosition.y)
191 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x, y, &keyFlags, false, false);
196 if(buttonState.left && !(lastButtonState.left))
198 if(!guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick,
199 mousePosition.x, mousePosition.y, &keyFlags, false, true))
202 else if(buttonState.middle && !(lastButtonState.middle))
204 if(!guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick,
205 mousePosition.x, mousePosition.y, &keyFlags, false, true))
208 else if(buttonState.right && !(lastButtonState.right))
210 if(!guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick,
211 mousePosition.x, mousePosition.y, &keyFlags, false, true))
215 if(buttonState.left && !(lastButtonState.left))
216 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown,
217 mousePosition.x, mousePosition.y, &keyFlags, false,
218 (event.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) ? false : true) ;
219 else if(buttonState.middle && !(lastButtonState.middle))
220 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown,
221 mousePosition.x, mousePosition.y, &keyFlags, false,
222 (event.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) ? false : true);
223 else if(buttonState.right && !(lastButtonState.right))
224 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown,
225 mousePosition.x, mousePosition.y, &keyFlags, false,
226 (event.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) ? false : true);
227 else if(!(buttonState.left) && lastButtonState.left)
228 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp,
229 mousePosition.x, mousePosition.y, &keyFlags, false, false);
230 else if(!(buttonState.middle) && lastButtonState.middle)
231 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp,
232 mousePosition.x, mousePosition.y, &keyFlags, false, false);
233 else if(!(buttonState.right) && lastButtonState.right)
234 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp,
235 mousePosition.x, mousePosition.y, &keyFlags, false, false);
237 lastButtonState = buttonState;
240 case WINDOW_BUFFER_SIZE_EVENT:
244 event.Event.WindowBufferSizeEvent.dwSize.X,
245 event.Event.WindowBufferSizeEvent.dwSize.Y
247 SetConsoleScreenBufferSize(hStdout,coord);
248 guiApp.SetDesktopPosition(0,0, coord.X * textCellW, coord.Y * textCellH, true);
253 if(!processAll) break;
262 void * objects[2] = { hStdin, *((uint **)guiApp.semaphore) };
263 if(MsgWaitForMultipleObjects(2, objects, FALSE, INFINITE, QS_TIMER) == WAIT_OBJECT_0 + 2)
266 GetMessage(&msg, null,0,0);
270 void Lock(Window window)
275 void Unlock(Window window)
280 char ** GraphicsDrivers(int * numDrivers)
282 static char *graphicsDrivers[] = { "Win32Console" };
283 *numDrivers = sizeof(graphicsDrivers) / sizeof(char *);
284 return (char **)graphicsDrivers;
287 void GetCurrentMode(bool * fullScreen, Resolution * resolution, PixelFormat * colorDepth, int * refreshRate)
290 *colorDepth = pixelFormatText;
293 void EnsureFullScreen(bool *fullScreen)
298 bool ScreenMode(bool fullScreen, Resolution resolution, PixelFormat colorDepth, int refreshRate, bool * textMode)
302 CONSOLE_SCREEN_BUFFER_INFO info;
304 ChangeDisplaySettings(null, 0);
306 if(GetConsoleScreenBufferInfo(hStdout, &info))
309 coord.X = info.srWindow.Right+1;
310 coord.Y = info.srWindow.Bottom+1;
311 SetConsoleScreenBufferSize(hStdout,coord);
312 guiApp.SetDesktopPosition(0,0, coord.X * textCellW, coord.Y * textCellH, false);
314 mouseRange.right = MAXINT;
315 mouseRange.bottom = MAXINT;
322 // --- Window Creation ---
323 void * CreateRootWindow(Window window)
325 return (void *) hStdout;
328 void DestroyRootWindow(void * windowHandle)
332 // -- Window manipulation ---
334 void SetRootWindowCaption(void * windowHandle, char * name)
336 if(windowHandle == guiApp.desktop)
337 SetConsoleTitle(name);
340 void PositionRootWindow(void * windowHandle, int x, int y, int w, int h, bool move, bool resize)
344 void OrderRootWindow(void * windowHandle, bool topMost)
348 void SetRootWindowColor(Window window)
352 void OffsetWindow(void * windowHandle, int * x, int * y)
357 void UpdateRootWindow(void * windowHandle)
361 void SetRootWindowState(void * windowHandle, int state, bool visible)
365 void ActivateRootWindow(void * windowHandle)
369 // --- Mouse-based window movement ---
371 void StartMoving(void * windowHandle, int x, int y, bool fromKeyBoard)
375 void StopMoving(void * windowHandle)
379 // -- Mouse manipulation ---
381 void GetMousePosition(int *x, int *y)
383 *x = mousePosition.x;
384 *y = mousePosition.y;
387 void SetMousePosition(int x, int y)
393 void SetMouseRange(Window window, Box box)
401 mouseRange.left = mouseRange.top = 0;
402 mouseRange.right = mouseRange.bottom = MAXINT;
406 void SetMouseCapture(void * windowHandle)
411 // -- Mouse cursor ---
413 void SetMouseCursor(int cursor)
420 void SetCaret(int x, int y, int size)
422 COORD coords = { (short)(x / textCellW), (short)(y / textCellH) };
423 CONSOLE_CURSOR_INFO cursor =
426 (size && x >= 0 && y >= 0 && x < guiApp.desktop.clientSize.w && y < guiApp.desktop.clientSize.h) ? TRUE : FALSE
428 SetConsoleCursorInfo(hStdout, &cursor);
429 SetConsoleCursorPosition(hStdout, coords);
432 // --- Clipboard manipulation ---
434 void ClearClipboard()
436 if(OpenClipboard(null))
443 bool AllocateClipboard(ClipBoard clipBoard, uint size)
446 clipBoard.handle=GlobalAlloc(GHND | GMEM_DDESHARE, size);
449 clipBoard.text=GlobalLock(clipBoard.handle);
453 GlobalFree(clipBoard.handle);
458 bool SaveClipboard(ClipBoard clipBoard)
463 GlobalUnlock(clipBoard.handle);
464 if(OpenClipboard(null))
467 if(SetClipboardData(CF_TEXT,clipBoard.handle))
474 GlobalFree(clipBoard.handle);
479 bool LoadClipboard(ClipBoard clipBoard)
482 if(OpenClipboard(null))
484 if(clipBoard.handle = GetClipboardData(CF_TEXT))
486 if(clipBoard.text = GlobalLock(clipBoard.handle))
494 void UnloadClipboard(ClipBoard clipBoard)
497 GlobalUnlock(clipBoard.handle);
500 // --- State based input ---
502 bool AcquireInput(void * windowHandle, bool state)
507 bool GetMouseState(MouseButtons * buttons, int * x, int * y)
514 bool GetJoystickState(int device, Joystick joystick)
521 bool GetKeyState(Key key)
525 else if(key == capsState)
526 return GetKeyState(VK_CAPITAL) & 0x00000001;
527 else if(key == numState)
528 return GetKeyState(VK_NUMLOCK) & 0x00000001;
529 else if(key == scrollState)
530 return GetKeyState(VK_SCROLL) & 0x00000001;