• R/O
  • SSH
  • HTTPS

nos: 提交


Commit MetaInfo

修訂370 (tree)
時間2009-10-29 13:43:07
作者uchan_nos

Log Message

コマンド履歴、スクロール機能追加

Change Summary

差異

--- bitnos5/trunk/kernel/console.cpp (revision 369)
+++ bitnos5/trunk/kernel/console.cpp (revision 370)
@@ -16,6 +16,7 @@
1616 #include <bitnos/timer.h>
1717 #include <bitnos/specialtask.h>
1818 #include <bitnos/pit.h>
19+#include <bitnos/scancode.h>
1920
2021 namespace TaskConsole
2122 {
@@ -108,6 +109,14 @@
108109 /* end of class ScreenBuffer */
109110
110111
112+// 定数
113+const uint32_t TIMERDATA_CURSOR = 1;
114+const uint32_t TIMERDATA_BEEP = 2;
115+
116+const int COMMAND_MAXLENGTH = 127; // コマンド最大文字数
117+const int COMMAND_HISTORYSIZE = 32; // 履歴を記憶する最大数
118+
119+
111120 struct Valiables
112121 {
113122 Console cons;
@@ -114,7 +123,7 @@
114123 Image* img;
115124 Sheet* sht;
116125
117- char cmdline[128];
126+ char cmdline[COMMAND_MAXLENGTH + 1];
118127 int cmdlineBegin;
119128
120129 Timer* tim;
@@ -134,7 +143,7 @@
134143
135144 void PutString0(Valiables* o, const char* str, int len);
136145
137-void ConsoleRefreshScreen(Valiables* o, int begin);
146+void ConsoleRefreshScreen(Valiables* o, int begin, int printBegin = -1);
138147
139148 void RunCommand(Valiables* o);
140149
@@ -143,6 +152,14 @@
143152
144153 void ConsoleMakeBorderLine(Image* img);
145154
155+void PrintHistoryUp(Valiables* o);
156+void PrintHistoryDown(Valiables* o);
157+
158+void ClearInputString(Valiables* o);
159+
160+void ScrollUp(Valiables* o, int lines);
161+void ScrollDown(Valiables* o, int lines);
162+
146163 /*
147164 * コンソールコマンド関数
148165 */
@@ -157,9 +174,6 @@
157174 static void cat(Valiables* o, const char* arg);
158175 };
159176
160-const uint32_t TIMERDATA_CURSOR = 1;
161-const uint32_t TIMERDATA_BEEP = 2;
162-
163177 void Init(void* obj)
164178 {
165179 static int initialPosX = 110, initialPosY = 50;
@@ -185,7 +199,7 @@
185199 o->active = SpecialTask::Get(SpecialTask::Active) == task;
186200
187201 // 文字列バッファの準備
188- o->cons.sbuf.Init(o->cons.width, 20);
202+ o->cons.sbuf.Init(o->cons.width, 50);
189203
190204 // バッファ内の書き込み位置
191205 o->cons.wPos = Point(0, 0);
@@ -193,6 +207,14 @@
193207 // 画面内の表示位置
194208 o->cons.pPos = Point(0, 0);
195209
210+ o->cons.rLine = 0;
211+
212+ // コマンド履歴バッファ関連
213+ o->cons.History.buf.Init(COMMAND_MAXLENGTH, COMMAND_HISTORYSIZE);
214+
215+ o->cons.History.wPos = Point(0, 0);
216+ o->cons.History.rPos = Point(0, 0);
217+
196218 // 画面のバッファ
197219 o->img = new Image(
198220 8 + fontHankaku->GetWidth() * o->cons.width,
@@ -231,12 +253,20 @@
231253
232254 if (msg->from == Message::From::Keyboard) {
233255 if (msg->arg1 != 0) {
234- //if (o->cursor) {
256+ if (msg->arg1 < 0x80) {
235257 EraseCursor(o);
236- //}
237- PutChar(o, msg->arg1);
238- if (o->cursor) {
239- ShowCursor(o);
258+ PutChar(o, msg->arg1);
259+ if (o->cursor) {
260+ ShowCursor(o);
261+ }
262+ } else if (msg->arg1 == (uint32_t)ScanCode::Keys::KeyArrowUp) {
263+ PrintHistoryUp(o);
264+ } else if (msg->arg1 == (uint32_t)ScanCode::Keys::KeyArrowDown) {
265+ PrintHistoryDown(o);
266+ } else if (msg->arg1 == (uint32_t)ScanCode::Keys::KeyPageUp) {
267+ ScrollUp(o, o->cons.height - 2);
268+ } else if (msg->arg1 == (uint32_t)ScanCode::Keys::KeyPageDown) {
269+ ScrollDown(o, o->cons.height - 2);
240270 }
241271 }
242272 } else if (msg->from == Message::From::Timer) {
@@ -275,6 +305,12 @@
275305 o->cons.sbuf.Write(Point(0, o->cons.sbuf.GetHeight() - 1), '\0');
276306 o->cmdlineBegin--;
277307 }
308+ if (o->cons.wPos.Y >= o->cons.height - 1) {
309+ o->cons.rLine = o->cons.wPos.Y - o->cons.height + 1;
310+ Debug::WriteLine("set rline to %d", o->cons.rLine);
311+ } else {
312+ o->cons.rLine = 0;
313+ }
278314 o->cons.wPos.X = 0;
279315 o->cons.pPos.X = 0;
280316 if (o->cons.pPos.Y < o->cons.height - 1) {
@@ -321,7 +357,9 @@
321357 NewLine(o);
322358
323359 if (pposy == o->cons.pPos.Y) {
324- ConsoleRefreshScreen(o, -1);
360+ // スクロールしたとき
361+ //ConsoleRefreshScreen(o, -1);
362+ ConsoleRefreshScreen(o, o->cons.rLine);
325363 }
326364
327365 } else {
@@ -344,11 +382,23 @@
344382 for (int line = o->cmdlineBegin, x = 1; line <= o->cons.wPos.Y; line++) {
345383 for (; (c = o->cons.sbuf.Read(Point(x, line))) != '\0'; x++) {
346384 o->cmdline[i++] = c;
385+ if (i == COMMAND_MAXLENGTH) {
386+ break;
387+ }
347388 }
348389 x = 0;
349390 }
350391 o->cmdline[i] = '\0';
351392
393+ // 履歴を保存
394+ o->cons.History.buf.Write(o->cons.History.wPos, o->cmdline);
395+ if (o->cons.History.wPos.Y < o->cons.History.buf.GetHeight() - 1) {
396+ o->cons.History.wPos.Y++;
397+ o->cons.History.rPos = o->cons.History.wPos;
398+ } else {
399+ o->cons.History.buf.Scroll(1);
400+ }
401+
352402 RunCommand(o);
353403
354404 o->cmdlineBegin = o->cons.wPos.Y;
@@ -371,7 +421,11 @@
371421 }
372422 }
373423
374-void ConsoleRefreshScreen(Valiables* o, int begin)
424+/*
425+ * begin : 文字列バッファ内の開始位置
426+ * printBegin : 画面内の開始位置
427+ */
428+void ConsoleRefreshScreen(Valiables* o, int begin, int printBegin)
375429 {
376430 if (begin < 0) {
377431 // 自動計算モード
@@ -381,15 +435,26 @@
381435 }
382436 }
383437
438+ if (printBegin < 0) {
439+ printBegin = 0;
440+ }
441+
384442 // 画面全消去
385443 o->img->DrawRectangleFill(
386- o->cons.backColor, Point(4, 25 + 4), Point(o->img->GetWidth() - 1 - 4, o->img->GetHeight() - 1 - 4));
444+ o->cons.backColor,
445+ Point(4, 25 + 4 + printBegin * fontHankaku->GetHeight()),
446+ Point(o->img->GetWidth() - 1 - 4, o->img->GetHeight() - 1 - 4));
387447
388448 // 文字列描画
389- for (int lines = 0; begin + lines <= o->cons.sbuf.GetHeight() && lines < o->cons.height; lines++) {
449+ const char* p = 0;
450+ for (int lines = printBegin; begin + lines <= o->cons.sbuf.GetHeight() && lines < o->cons.height; lines++) {
451+ p = o->cons.sbuf.GetPointer(Point(0, begin + lines));
452+ if (p == 0) {
453+ break;
454+ }
390455 o->img->DrawString(
391456 o->cons.textColor,
392- o->cons.sbuf.GetPointer(Point(0, begin + lines)),
457+ p,
393458 Point(4, 25 + 4 + lines * fontHankaku->GetHeight()),
394459 fontHankaku);
395460 }
@@ -433,6 +498,10 @@
433498
434499 void ShowCursor(Valiables* o)
435500 {
501+ if (o->cons.pPos.X < 0 || o->cons.width <= o->cons.pPos.X ||
502+ o->cons.pPos.Y < 0 || o->cons.height <= o->cons.pPos.Y) {
503+ return;
504+ }
436505 Point pos;
437506 pos = Point(4 + o->cons.pPos.X * fontHankaku->GetWidth(), 25 + 4 + o->cons.pPos.Y * fontHankaku->GetHeight());
438507 o->sht->DrawRectangleFill(
@@ -443,6 +512,10 @@
443512
444513 void EraseCursor(Valiables* o)
445514 {
515+ if (o->cons.pPos.X < 0 || o->cons.width <= o->cons.pPos.X ||
516+ o->cons.pPos.Y < 0 || o->cons.height <= o->cons.pPos.Y) {
517+ return;
518+ }
446519 Point pos;
447520 pos = Point(4 + o->cons.pPos.X * fontHankaku->GetWidth(), 25 + 4 + o->cons.pPos.Y * fontHankaku->GetHeight());
448521 o->sht->DrawRectangleFill(
@@ -572,4 +645,59 @@
572645 PutString0(o, " {_.-``-' {_/\n");
573646 }
574647
648+void PrintHistoryUp(Valiables* o)
649+{
650+ if (o->cons.History.rPos.Y >= 0) {
651+ if (o->cons.History.rPos.Y > 0) {
652+ o->cons.History.rPos.Y--;
653+ }
654+ ClearInputString(o);
655+ PutString0(o, o->cons.History.buf.GetPointer(o->cons.History.rPos));
656+ }
575657 }
658+
659+void PrintHistoryDown(Valiables* o)
660+{
661+ if (o->cons.History.rPos.Y < o->cons.History.wPos.Y) {
662+ if (o->cons.History.rPos.Y < o->cons.History.wPos.Y - 1) {
663+ o->cons.History.rPos.Y++;
664+ }
665+ ClearInputString(o);
666+ PutString0(o, o->cons.History.buf.GetPointer(o->cons.History.rPos));
667+ }
668+}
669+
670+void ClearInputString(Valiables* o)
671+{
672+ o->cons.pPos.Y += o->cmdlineBegin - o->cons.wPos.Y;
673+ o->cons.pPos.X = 1;
674+ o->cons.wPos.Y = o->cmdlineBegin;
675+ o->cons.wPos.X = 1;
676+ o->cons.sbuf.Write(o->cons.wPos, '\0');
677+ ConsoleRefreshScreen(o, -1, o->cons.pPos.Y);
678+}
679+
680+void ScrollUp(Valiables* o, int lines)
681+{
682+ int oldRLine = o->cons.rLine;
683+ o->cons.rLine -= lines;
684+ if (o->cons.rLine < 0) {
685+ o->cons.rLine = 0;
686+ }
687+ Debug::WriteLine("new rline = %d, old = %d", o->cons.rLine, oldRLine);
688+ o->cons.pPos.Y += oldRLine - o->cons.rLine;
689+ ConsoleRefreshScreen(o, o->cons.rLine);
690+}
691+
692+void ScrollDown(Valiables* o, int lines)
693+{
694+ int oldRLine = o->cons.rLine;
695+ o->cons.rLine += lines;
696+ if (o->cons.rLine > o->cons.wPos.Y) {
697+ o->cons.rLine = o->cons.wPos.Y;
698+ }
699+ o->cons.pPos.Y += oldRLine - o->cons.rLine;
700+ ConsoleRefreshScreen(o, o->cons.rLine);
701+}
702+
703+}
--- bitnos5/trunk/include/bitnos/console.h (revision 369)
+++ bitnos5/trunk/include/bitnos/console.h (revision 370)
@@ -71,6 +71,15 @@
7171 ScreenBuffer sbuf;
7272 Point wPos; // 書き込みの位置
7373 Point pPos; // 表示の位置
74+
75+ int rLine; // バッファ内の表示開始行
76+
77+ struct {
78+ ScreenBuffer buf; // コマンド履歴バッファ
79+ Point wPos; // 書き込みの位置
80+ Point rPos; // 読み込みの位置
81+ } History;
82+
7483 };
7584 }
7685
Show on old repository browser