1 namespace gui::drivers;
7 #define WIN32_LEAN_AND_MEAN
19 WINBASEAPI HWND WINAPI GetConsoleWindow ();
23 static HANDLE hStdin, hStdout;
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)
117 GetNumberOfConsoleInputEvents(hStdin, &numInput);
120 for(c = 0; c<numInput; c++)
124 ReadConsoleInput(hStdin, &event, 1, &readInputs);
125 switch(event.EventType)
129 byte key = (byte)event.Event.KeyEvent.wVirtualScanCode;
130 byte ch = event.Event.KeyEvent.uChar.AsciiChar;
133 if(event.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)
134 key = (byte)GetExtendedKey(key);
137 if(event.Event.KeyEvent.dwControlKeyState&SHIFT_PRESSED)
138 keyFlags.shift = true;
139 if(event.Event.KeyEvent.dwControlKeyState&LEFT_ALT_PRESSED ||
140 event.Event.KeyEvent.dwControlKeyState&RIGHT_ALT_PRESSED)
142 if(event.Event.KeyEvent.dwControlKeyState&LEFT_CTRL_PRESSED ||
143 event.Event.KeyEvent.dwControlKeyState&RIGHT_CTRL_PRESSED)
144 keyFlags.ctrl = true;
146 if(event.Event.KeyEvent.bKeyDown)
149 guiApp.desktop.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit,keyFlags,ch);
152 keys[key] = (byte)bool::true;
153 guiApp.desktop.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown,keyFlags,ch);
158 keys[key] = (byte)bool::false;
159 guiApp.desktop.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp,keyFlags,ch);
165 Modifiers keyFlags = 0;
166 static MouseButtons lastButtonState = 0;
167 MouseButtons buttonState = event.Event.MouseEvent.dwButtonState;
169 if(event.Event.MouseEvent.dwControlKeyState&SHIFT_PRESSED)
170 keyFlags.shift = true;
171 if(event.Event.MouseEvent.dwControlKeyState&LEFT_ALT_PRESSED ||
172 event.Event.MouseEvent.dwControlKeyState&RIGHT_ALT_PRESSED)
174 if(event.Event.MouseEvent.dwControlKeyState&LEFT_CTRL_PRESSED ||
175 event.Event.MouseEvent.dwControlKeyState&RIGHT_CTRL_PRESSED)
176 keyFlags.ctrl = true;
178 switch(event.Event.MouseEvent.dwEventFlags)
182 int x = event.Event.MouseEvent.dwMousePosition.X * textCellW;
183 int y = event.Event.MouseEvent.dwMousePosition.Y * textCellH;
185 x = Min(Max(x, mouseRange.left), mouseRange.right);
186 y = Min(Max(y, mouseRange.top), mouseRange.bottom);
188 if(x != mousePosition.x || y != mousePosition.y)
192 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x, y, &keyFlags, false, false);
197 if(buttonState.left && !(lastButtonState.left))
199 if(!guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick,
200 mousePosition.x, mousePosition.y, &keyFlags, false, true))
203 else if(buttonState.middle && !(lastButtonState.middle))
205 if(!guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick,
206 mousePosition.x, mousePosition.y, &keyFlags, false, true))
209 else if(buttonState.right && !(lastButtonState.right))
211 if(!guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick,
212 mousePosition.x, mousePosition.y, &keyFlags, false, true))
216 if(buttonState.left && !(lastButtonState.left))
217 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown,
218 mousePosition.x, mousePosition.y, &keyFlags, false,
219 (event.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) ? false : true) ;
220 else if(buttonState.middle && !(lastButtonState.middle))
221 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown,
222 mousePosition.x, mousePosition.y, &keyFlags, false,
223 (event.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) ? false : true);
224 else if(buttonState.right && !(lastButtonState.right))
225 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown,
226 mousePosition.x, mousePosition.y, &keyFlags, false,
227 (event.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) ? false : true);
228 else if(!(buttonState.left) && lastButtonState.left)
229 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp,
230 mousePosition.x, mousePosition.y, &keyFlags, false, false);
231 else if(!(buttonState.middle) && lastButtonState.middle)
232 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp,
233 mousePosition.x, mousePosition.y, &keyFlags, false, false);
234 else if(!(buttonState.right) && lastButtonState.right)
235 guiApp.desktop.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp,
236 mousePosition.x, mousePosition.y, &keyFlags, false, false);
238 lastButtonState = buttonState;
241 case WINDOW_BUFFER_SIZE_EVENT:
245 event.Event.WindowBufferSizeEvent.dwSize.X,
246 event.Event.WindowBufferSizeEvent.dwSize.Y
248 SetConsoleScreenBufferSize(hStdout,coord);
249 guiApp.SetDesktopPosition(0,0, coord.X * textCellW, coord.Y * textCellH, true);
254 if(!processAll) break;
263 void * objects[2] = { hStdin, *((uint **)guiApp.semaphore) };
264 if(MsgWaitForMultipleObjects(2, objects, FALSE, INFINITE, QS_TIMER) == WAIT_OBJECT_0 + 2)
267 GetMessage(&msg, null,0,0);
271 void Lock(Window window)
276 void Unlock(Window window)
281 const char ** GraphicsDrivers(int * numDrivers)
283 static const char *graphicsDrivers[] = { "Win32Console" };
284 *numDrivers = sizeof(graphicsDrivers) / sizeof(char *);
285 return (const char **)graphicsDrivers;
288 void GetCurrentMode(bool * fullScreen, Resolution * resolution, PixelFormat * colorDepth, int * refreshRate)
291 *colorDepth = pixelFormatText;
294 void EnsureFullScreen(bool *fullScreen)
299 bool ScreenMode(bool fullScreen, Resolution resolution, PixelFormat colorDepth, int refreshRate, bool * textMode)
303 CONSOLE_SCREEN_BUFFER_INFO info;
305 ChangeDisplaySettings(null, 0);
307 if(GetConsoleScreenBufferInfo(hStdout, &info))
310 coord.X = info.srWindow.Right+1;
311 coord.Y = info.srWindow.Bottom+1;
312 SetConsoleScreenBufferSize(hStdout,coord);
313 guiApp.SetDesktopPosition(0,0, coord.X * textCellW, coord.Y * textCellH, false);
315 mouseRange.right = MAXINT;
316 mouseRange.bottom = MAXINT;
323 // --- Window Creation ---
324 void * CreateRootWindow(Window window)
326 return (void *) hStdout;
329 void DestroyRootWindow(void * windowHandle)
333 // -- Window manipulation ---
335 void SetRootWindowCaption(void * windowHandle, const char * name)
337 if(windowHandle == guiApp.desktop)
338 SetConsoleTitle(name);
341 void PositionRootWindow(void * windowHandle, int x, int y, int w, int h, bool move, bool resize)
345 void OrderRootWindow(void * windowHandle, bool topMost)
349 void SetRootWindowColor(Window window)
353 void OffsetWindow(void * windowHandle, int * x, int * y)
358 void UpdateRootWindow(void * windowHandle)
362 void SetRootWindowState(void * windowHandle, int state, bool visible)
366 void ActivateRootWindow(void * windowHandle)
370 // --- Mouse-based window movement ---
372 void StartMoving(void * windowHandle, int x, int y, bool fromKeyBoard)
376 void StopMoving(void * windowHandle)
380 // -- Mouse manipulation ---
382 void GetMousePosition(int *x, int *y)
384 *x = mousePosition.x;
385 *y = mousePosition.y;
388 void SetMousePosition(int x, int y)
394 void SetMouseRange(Window window, Box box)
402 mouseRange.left = mouseRange.top = 0;
403 mouseRange.right = mouseRange.bottom = MAXINT;
407 void SetMouseCapture(void * windowHandle)
412 // -- Mouse cursor ---
414 void SetMouseCursor(Window window, int cursor)
421 void SetCaret(int x, int y, int size)
423 COORD coords = { (short)(x / textCellW), (short)(y / textCellH) };
424 CONSOLE_CURSOR_INFO cursor =
427 (size && x >= 0 && y >= 0 && x < guiApp.desktop.clientSize.w && y < guiApp.desktop.clientSize.h) ? TRUE : FALSE
429 SetConsoleCursorInfo(hStdout, &cursor);
430 SetConsoleCursorPosition(hStdout, coords);
433 // --- Clipboard manipulation ---
435 void ClearClipboard()
437 if(OpenClipboard(null))
444 bool AllocateClipboard(ClipBoard clipBoard, uint size)
447 clipBoard.handle=GlobalAlloc(GHND | GMEM_DDESHARE, size);
450 clipBoard.text=GlobalLock(clipBoard.handle);
454 GlobalFree(clipBoard.handle);
459 bool SaveClipboard(ClipBoard clipBoard)
464 GlobalUnlock(clipBoard.handle);
465 if(OpenClipboard(null))
468 if(SetClipboardData(CF_TEXT,clipBoard.handle))
475 GlobalFree(clipBoard.handle);
480 bool LoadClipboard(ClipBoard clipBoard)
483 if(OpenClipboard(null))
485 if((clipBoard.handle = GetClipboardData(CF_TEXT)))
487 if((clipBoard.text = GlobalLock(clipBoard.handle)))
495 void UnloadClipboard(ClipBoard clipBoard)
498 GlobalUnlock(clipBoard.handle);
501 // --- State based input ---
503 bool AcquireInput(void * windowHandle, bool state)
508 bool GetMouseState(MouseButtons * buttons, int * x, int * y)
515 bool GetJoystickState(int device, Joystick joystick)
522 bool GetKeyState(Key key)
525 return keys[key] != 0;
526 else if(key == capsState)
527 return GetKeyState(VK_CAPITAL) & 0x00000001;
528 else if(key == numState)
529 return GetKeyState(VK_NUMLOCK) & 0x00000001;
530 else if(key == scrollState)
531 return GetKeyState(VK_SCROLL) & 0x00000001;