1
2
3
4
5
6 using System;
7 using System.Os;
8 using System.Message;
9
10 namespace System.Screen
11 {
12 string MakeApplicationMessageQueueName()
13 {
14 return "system.screen.msg.queue." + ToString(GetPid());
15 }
16
17 public class Application
18 {
19 static Application() : instance(new Application())
20 {
21 }
22 public ~Application()
23 {
24 try
25 {
26 UnbindTerminal();
27 CloseMsgQ(msgQ);
28 }
29 catch (const Exception& ex)
30 {
31 }
32 }
33 public static Application& Instance()
34 {
35 return *instance;
36 }
37 private Application() : msgQ(MsgQ(MakeApplicationMessageQueueName().Chars())), menuBar(null), focusedControl(null), lastDefaultWriteScreenMessageWindow(-1)
38 {
39 RegisterMessage<KeyPressedMessage>(systemScreenKeyPressedMessageId);
40 BindTerminal(msgQ);
41 }
42 public nothrow Window* MainWindow()
43 {
44 return mainWindow;
45 }
46 public nothrow MenuBar* GetMenuBar() const
47 {
48 return menuBar;
49 }
50 public nothrow void SetMenuBar(MenuBar* menuBar_)
51 {
52 menuBar = menuBar_;
53 menuBarWindowHandle = menuBar->Handle();
54 }
55 public nothrow void SetStatusBar(StatusBar* statusBar_)
56 {
57 statusBar = statusBar_;
58 statusBarWindowHandle = statusBar->Handle();
59 }
60 public WindowManager& GetWindowManager() const
61 {
62 return windowManager;
63 }
64 public void Run(Window& mainWindow_)
65 {
66 mainWindow = &mainWindow_;
67 mainWindow->SetMainWindow();
68 mainWindow->SetLocation(Point(0, 0));
69 mainWindow->SetSize(Size(TerminalWindowWidth(), TerminalWindowHeight()));
70 mainWindow->Invalidate();
71 UniquePtr<Message> message = ReadMessage();
72 while (!(message.Get() is QuitMessage*))
73 {
74 bool handled = false;
75 if (message->TargetWindowHandle() != -1)
76 {
77 Control* control = windowManager.GetWindow(message->TargetWindowHandle());
78 if (control != null)
79 {
80 handled = control->HandleMessage(message.Get());
81 }
82 }
83 if (!handled)
84 {
85 handled = mainWindow->HandleMessage(message.Get());
86 }
87 message = ReadMessage();
88 }
89 Terminal.Out() << ResetColors();
90 ClearScreen(TerminalWindowWidth(), TerminalWindowHeight());
91 SetCursorPos(0, 0);
92 }
93 public void RunDialog(Window* window)
94 {
95 WriteScreenMessage writeScreenMessage(Rect.Default(), InvalidateKind.invalidateIfNotDefault);
96 mainWindow->HandleWriteScreen(&writeScreenMessage);
97 UniquePtr<Message> message = ReadMessage();
98 while (!(message.Get() is QuitMessage*))
99 {
100 bool handled = window->HandleMessage(message.Get());
101 if (handled)
102 {
103 if (window->GetDialogResult() != DialogResult.none)
104 {
105 WriteScreenMessage writeScreenMessage(window->GetRect(), InvalidateKind.invalidateIfNotDefault);
106 mainWindow->HandleWriteScreen(&writeScreenMessage);
107 return;
108 }
109 }
110 message = ReadMessage();
111 }
112 }
113 public void Exit()
114 {
115 QuitMessage quitMessage;
116 PostMessage(quitMessage);
117 }
118 public void PostMessage(Message& message)
119 {
120 if (message.TargetWindowHandle() != menuBarWindowHandle && message.TargetWindowHandle() != statusBarWindowHandle)
121 {
122 if (message.IsDefaultWriteScreenMessage())
123 {
124 if (lastDefaultWriteScreenMessageWindow == message.TargetWindowHandle())
125 {
126 return;
127 }
128 else
129 {
130 lastDefaultWriteScreenMessageWindow = message.TargetWindowHandle();
131 }
132 }
133 else
134 {
135 lastDefaultWriteScreenMessageWindow = -1;
136 }
137 }
138 int msgSize = message.Size();
139 UniquePtr<byte> msg(cast<byte*>(MemAlloc(msgSize)));
140 MemoryWriter writer(msg.Get(), msgSize);
141 message.Write(writer);
142 PutMsg(msgQ, msg.Get(), msgSize);
143 }
144 public UniquePtr<Message> ReadMessage()
145 {
146 WaitMsg(msgQ);
147 return GetMessage();
148 }
149 public void Timer(const Duration& duration, Control* control, int timerId)
150 {
151 TimerMessage message(timerId);
152 message.SetTargetWindowHandle(control->Handle());
153 int msgSize = message.Size();
154 UniquePtr<byte> msg(cast<byte*>(MemAlloc(msgSize)));
155 MemoryWriter writer(msg.Get(), msgSize);
156 message.Write(writer);
157 TimerMsg(duration, msgQ, msg.Get(), msgSize);
158 }
159 public nothrow Control* FocusedControl() const
160 {
161 return focusedControl;
162 }
163 public nothrow void SetFocusedControl(Control* focusedControl_)
164 {
165 focusedControl = focusedControl_;
166 }
167 private UniquePtr<Message> GetMessage()
168 {
169 int qlen = GetMsgQLength(msgQ);
170 if (qlen > 0)
171 {
172 int msgSize = GetMsgSize(msgQ);
173 if (msgSize > 0)
174 {
175 UniquePtr<byte> msgData(cast<byte*>(MemAlloc(msgSize)));
176 GetMsg(msgQ, msgData.Get());
177 UniquePtr<Message> message(ReadMessage(msgData.Get(), msgSize));
178 return message;
179 }
180 else
181 {
182 throw Exception("invalid message size 0");
183 }
184 }
185 else
186 {
187 throw Exception("message queue " + ToString(msgQ) + " is empty");
188 }
189 }
190 private static UniquePtr<Application> instance;
191 private int msgQ;
192 private Window* mainWindow;
193 private WindowManager windowManager;
194 private MenuBar* menuBar;
195 private StatusBar* statusBar;
196 private Control* focusedControl;
197 private int lastDefaultWriteScreenMessageWindow;
198 private int menuBarWindowHandle;
199 private int statusBarWindowHandle;
200 }
201 }