Subversion Repositories Kolibri OS

Rev

Rev 643 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. {}
  2.  
  3. procedure OpenStdout(var f: TextRec); forward;
  4. procedure WriteStdout(var f: TextRec); forward;
  5. procedure FlushStdout(var f: TextRec); forward;
  6. procedure CloseStdout(var f: TextRec); forward;
  7.  
  8. procedure OpenStdin(var f: TextRec); forward;
  9. procedure ReadStdin(var f: TextRec); forward;
  10. procedure CloseStdin(var f: TextRec); forward;
  11.  
  12.  
  13.  
  14. procedure AssignStdout(var f: Text);
  15. begin
  16.   Assign(f, '');
  17.   TextRec(f).OpenFunc := @OpenStdout;
  18.   Rewrite(f);
  19. end;
  20.  
  21. procedure OpenStdout(var f: TextRec);
  22. begin
  23.   TextRec(f).InOutFunc := @WriteStdout;
  24.   TextRec(f).FlushFunc := @FlushStdout;
  25.   TextRec(f).CloseFunc := @CloseStdout;
  26. end;
  27.  
  28. procedure WriteStdout(var f: TextRec);
  29. var
  30.   msg: String;
  31. begin
  32.   msg := StrPas(PChar(f.bufptr));
  33.   SetLength(msg, f.bufpos);
  34.   f.bufpos := 0;
  35.   Konsole.Write(msg);
  36. end;
  37.  
  38. procedure FlushStdout(var f: TextRec);
  39. begin
  40.   WriteStdout(f);
  41.   Konsole.Flush;
  42. end;
  43.  
  44. procedure CloseStdout(var f: TextRec);
  45. begin
  46. end;
  47.  
  48.  
  49.  
  50. procedure AssignStdin(var f: Text);
  51. begin
  52.   Assign(f, '');
  53.   TextRec(f).OpenFunc := @OpenStdin;
  54.   Reset(f);
  55. end;
  56.  
  57. procedure OpenStdin(var f: TextRec);
  58. begin
  59.   TextRec(f).InOutFunc := @ReadStdin;
  60.   TextRec(f).FlushFunc := nil;
  61.   TextRec(f).CloseFunc := @CloseStdin;
  62. end;
  63.  
  64. procedure ReadStdin(var f: TextRec);
  65. var
  66.   max, curpos: Longint;
  67.   c: Longint;
  68. begin
  69.   max := f.bufsize - Length(LineEnding);
  70.   curpos := 0;
  71.   repeat
  72.     c := 13{l4_getc()};
  73.     case c of
  74.       13:
  75.       begin
  76.         {f.bufptr^[curpos] := LineEnding;}
  77.         Inc(curpos);
  78.         f.bufpos := 0;
  79.         f.bufend := curpos;
  80.         {l4_putc(Longint(LineEnding));}
  81.         break;
  82.       end;
  83.       32..126: if curpos < max then
  84.       begin
  85.         f.bufptr^[curpos] := Char(c);
  86.         Inc(curpos);
  87.         {l4_putc(c);}
  88.       end;
  89.     end;
  90.   until False;
  91. end;
  92.  
  93. procedure CloseStdin(var f: TextRec);
  94. begin
  95. end;
  96.  
  97.  
  98. { TKonsole }
  99.  
  100. procedure KonsoleThreadMain(Console: PKonsole);
  101. { ¡®ç¨© 横« ª®­á®«¨}
  102. var
  103.   ThreadInfo: TKosThreadInfo;
  104.   Message: ShortString;
  105.   Event: DWord;
  106. begin
  107.   kos_maskevents(ME_PAINT or ME_KEYBOARD or ME_IPC);
  108.   kos_threadinfo(@ThreadInfo);
  109.   Console^.FThreadSlot := kos_getthreadslot(ThreadInfo.ThreadID);
  110.  
  111.   kos_initipc(Console^.FIPCBuffer, Console^.FIPCBufferSize);
  112.  
  113.   {áࠧ㠮⮡ࠧ¨âì ¨  ªâ¨¢¨à®¢ âì ®ª­®}
  114.   Console^.Paint();
  115.   {$ifndef EMULATOR}
  116.   kos_setactivewindow(Console^.FThreadSlot);
  117.   {$endif}
  118.  
  119.   {£®â®¢ ª ®¡à ¡®âª¥ ᮡë⨩}
  120.   Console^.FOpened := True;
  121.   while not Console^.FTerminate do
  122.   begin
  123.     Event := kos_getevent();
  124.     Console^.FOnAir := True;
  125.     if not Console^.FTerminate then
  126.     case Event of
  127.       SE_PAINT: Console^.Paint();
  128.       SE_KEYBOARD: Console^.ProcessKeyboard(kos_getkey());
  129.       SE_IPC: while Console^.ReceiveMessage(Message) do Console^.ProcessMessage(Message);
  130.     end;
  131.     Console^.FOnAir := False;
  132.   end;
  133.   Console^.FOpened := False;
  134. end;
  135.  
  136. constructor TKonsole.Init(ACaption: String);
  137. const
  138.   IPC_SIZE = 4096;
  139. var
  140.   ThreadInfo: TKosThreadInfo;
  141. begin
  142.   if ACaption <> '' then
  143.     FCaption := ACaption else
  144.   begin
  145.     kos_threadinfo(@ThreadInfo);
  146.     FCaption := StrPas(ThreadInfo.AppName);
  147.   end;
  148.   SetLength(FLines, 1);
  149.   FLines[0] := '';
  150.   FCursor.X := 1;
  151.   FCursor.Y := 0;
  152.   FMaxLines := 150;
  153.   FTerminate := False;
  154.   FOpened := False;
  155.   FOnAir  := False;
  156.   FIPCBufferSize := SizeOf(TKosIPC) + IPC_SIZE;
  157.   FIPCBuffer := GetMem(FIPCBufferSize);
  158.   FIPCBuffer^.Lock := False;
  159.   FIPCBuffer^.Size := 0;
  160.   FThreadSlot := -1;
  161.   FThreadID := BeginThread(TThreadFunc(@KonsoleThreadMain), @Self);
  162.   if FThreadID <> 0 then
  163.     {XXX: ¬®¦¥â § ¢¨á­ãâì}
  164.     while not FOpened do ThreadSwitch;
  165. end;
  166.  
  167. destructor TKonsole.Done();
  168. begin
  169.   FTerminate := True;
  170.   if FOpened then begin Self.Write(#0); kos_delay(01); end;
  171.   if FOpened then begin Self.Write(#0); kos_delay(10); end;
  172.   if FOpened then begin Self.Write(#0); kos_delay(20); end;
  173.   if FOpened then
  174.   begin
  175.     FOpened := False;
  176.     FOnAir  := False;
  177.     KillThread(FThreadID);
  178.   end;
  179.   {FreeMem(FIPCBuffer);
  180.   SetLength(FLines, 0);}
  181. end;
  182.  
  183. function TKonsole.ReceiveMessage(var Message: ShortString): Boolean;
  184. {ˆ§¢«¥çì ¯¥à¢®¥ á®®¡é¥­¨¥ ¨§ ¡ãä¥à }
  185. var
  186.   PMsg: PKosMessage;
  187.   Size: Longword;
  188. begin
  189.   FIPCBuffer^.Lock := True;
  190.  
  191.   if FIPCBuffer^.Size > 0 then
  192.   begin
  193.     PMsg := Pointer(Longword(FIPCBuffer) + SizeOf(TKosIPC));
  194.     {TODO: ¯à®¢¥àª  PMsg^.SenderID}
  195.     {Size := PMsg^.Size;
  196.     Dec(FIPCBuffer^.Size, Size + SizeOf(TKosMessage));
  197.     if Size > 255 then Size := 255;
  198.     SetLength(Message, Size);
  199.     Move(Pointer(Longword(PMsg) + SizeOf(TKosMessage))^, Message[1], Size);
  200.     if FIPCBuffer^.Size > 0 then
  201.       Move(Pointer(Longword(PMsg) + SizeOf(TKosMessage) + PMsg^.Size)^, PMsg^, FIPCBuffer^.Size);}
  202.  
  203.     {XXX}
  204.     Size := FIPCBuffer^.Size;
  205.     Dec(FIPCBuffer^.Size, Size);
  206.     if Size > 255 then Size := 255;
  207.     SetLength(Message, Size);
  208.     Move(PMsg^, Message[1], Size);
  209.  
  210.     Result := True;
  211.   end else
  212.   begin
  213.     Message := '';
  214.     Result := False;
  215.   end;
  216.  
  217.   {FIXME: ¥á«¨ FIPCBuffer^.Size = 0, â® FIPCBuffer^.Lock ¢á¥ à ¢­® > 0}
  218.   FIPCBuffer^.Lock := False;
  219. end;
  220.  
  221. procedure TKonsole.ProcessMessage(Message: ShortString);
  222. { ‚뢥á⨠ᮮ¡é¥­¨¥ ­  ª®­á®«ì }
  223. var
  224.   OnlyBottomLine: Boolean = True;
  225.  
  226.   procedure PutChar(C: Char);
  227.   var
  228.     LinesCount: Longint;
  229.     PLine: PShortString;
  230.     I: Longint;
  231.   begin
  232.     { ¯¥à¥¢®¤ ª®à¥âª¨ ­  ¯®§¨æ¨î ¢«¥¢® }
  233.     if C = #8 then
  234.     begin
  235.       if FCursor.X > 1 then
  236.         Dec(FCursor.X);
  237.     end else
  238.  
  239.     { ¯¥à¥¢®¤ ª®à¥âª¨ ­  á«¥¤ãîéãî áâபã }
  240.     if C = #10 then
  241.     begin
  242.       OnlyBottomLine := False;
  243.       Inc(FCursor.Y);
  244.       LinesCount := Length(FLines);
  245.       while FCursor.Y >= FMaxLines do Dec(FCursor.Y, FMaxLines);
  246.       if FCursor.Y < LinesCount then FLines[FCursor.Y] := '';
  247.       while FCursor.Y >= LinesCount do
  248.       begin
  249.         SetLength(FLines, LinesCount + 1);
  250.         FLines[LinesCount] := '';
  251.         Inc(LinesCount);
  252.       end;
  253.     end else
  254.  
  255.     { ¯¥à¥¢®¤ ª®à¥âª¨ ¢ ­ ç «® áâப¨ }
  256.     if C = #13 then
  257.       FCursor.X := 1 else
  258.  
  259.     { ¯®¬¥é¥­¨¥ ᨬ¢®«  ¢ áâபã }
  260.     begin
  261.       if FCursor.X > 200 then
  262.       begin
  263.         PutChar(#13);
  264.         PutChar(#10);
  265.       end;
  266.  
  267.       { FIXME: …᫨ ¢ PascalMain ⮫쪮 ®¤¨­ Write/Ln, â® § ¢¨á®­.
  268.         á¬. FPC_DO_EXIT, InternalExit }
  269.       PLine := @FLines[FCursor.Y];
  270.       I := Length(PLine^);
  271.       if FCursor.X > I then
  272.       begin
  273.         SetLength(PLine^, FCursor.X);
  274.         Inc(I);
  275.         while I < FCursor.X do
  276.         begin
  277.           PLine^[I] := ' ';
  278.           Inc(I);
  279.         end;
  280.       end;
  281.       FLines[FCursor.Y][FCursor.X] := C;
  282.  
  283.       Inc(FCursor.X);
  284.     end;
  285.   end;
  286.  
  287. var
  288.   I: Longint;
  289. begin
  290.   for I := 1 to Length(Message) do
  291.     PutChar(Message[I]);
  292.   Paint(OnlyBottomLine);
  293. end;
  294.  
  295. procedure TKonsole.ProcessKeyboard(Key: Word);
  296. begin
  297.   FKeyPressed := Key;
  298. end;
  299.  
  300. function TKonsole.GetRect(): TKosRect;
  301. var
  302.   ThreadInfo: TKosThreadInfo;
  303. begin
  304.   kos_threadinfo(@ThreadInfo, FThreadSlot);
  305.   Result := ThreadInfo.WindowRect;
  306. end;
  307.  
  308. function TKonsole.GetKeyPressed(): Word;
  309. begin
  310.   Result := FKeyPressed;
  311.   FKeyPressed := 0;
  312. end;
  313.  
  314. procedure TKonsole.Paint(BottomRow: Boolean);
  315. var
  316.   Buffer: array[Byte] of Char;
  317.   Rect: TKosRect;
  318.   J: Longint;
  319.   Width, Height, Row: Longint;
  320.   CaptionHeight, BorderWidth, FontWidth, FontHeight: Longint;
  321. begin
  322.   CaptionHeight := 16;
  323.   BorderWidth := 5;
  324.   FontWidth := 6;
  325.   FontHeight := 9;
  326.  
  327.   kos_begindraw();
  328.  
  329.   if not BottomRow then
  330.   begin
  331.     {®âà¨á®¢ª  ®ª­ }
  332.     kos_definewindow(60, 60, 400, 400, $63000000);
  333.     {¢ë¢®¤ § £®«®¢ª }
  334.     Move(FCaption[1], Buffer, Length(FCaption));
  335.     Buffer[Length(FCaption)] := #0;
  336.     kos_setcaption(Buffer);
  337.   end;
  338.  
  339.   {¯®¤£®â®¢ª  ª ¢ë¢®¤ã áâப}
  340.   Rect := GetRect();
  341.   Dec(Rect.Width, BorderWidth * 2);
  342.   Dec(Rect.Height, CaptionHeight + BorderWidth * 2);
  343.   Width  := Rect.Width div FontWidth;
  344.   Height := Rect.Height - FontHeight;
  345.   Row := FCursor.Y;
  346.  
  347.   while Height > 0 do
  348.   begin
  349.     {¢ë¢®¤ ®¤­®© áâப¨}
  350.     J := Length(FLines[Row]);
  351.     if J > Width then J := Width;
  352.     kos_drawtext(0, Height, Copy(FLines[Row], 1, J), $00DD00, $FF000000);
  353.     {§ «¨¢ª  ®á⠢襣®áï ¯à®áâà ­á⢠ ¢ áâப¥}
  354.     J := J * FontWidth;
  355.     kos_drawrect(J, Height, Rect.Width - J + 1, FontHeight, $000000);
  356.     {¯®¤£®â®¢ª  ª ¢ë¢®¤ã á«¥¤ãî饩 áâப¨}
  357.     Dec(Height, FontHeight);
  358.     Dec(Row);
  359.     if BottomRow or ((Row < 0) and (Length(FLines) < FMaxLines)) then Break;
  360.     while Row < 0 do Inc(Row, FMaxLines);
  361.   end;
  362.   if FCursor.X <= Width then
  363.     {®âà¨á®¢ª  ªãàá®à }
  364.     kos_drawrect((FCursor.X - 1) * FontWidth, Rect.Height - 2, FontWidth, 2, $FFFFFF);
  365.   if not BottomRow then
  366.     {§ «¨¢ª  ®á⠢襩áï ç á⨠®ª­ }
  367.     kos_drawrect(0, 0, Rect.Width + 1, Height + FontHeight, $000000);
  368.  
  369.   kos_enddraw();
  370. end;
  371.  
  372. procedure TKonsole.Write(Message: ShortString);
  373. var
  374.   I: Integer;
  375. begin
  376.   {XXX: ¢®§¬®¦­  á¨âã æ¨ï ¯à¨ ª®â®à®© á®®¡é¥­¨¥ ­¥ ¡ã¤¥â ®â¯à ¢«¥­®}
  377.   if FOpened then
  378.   begin
  379.     I := 100;
  380.     while (kos_sendmsg(FThreadID, @Message[1], Length(Message)) = 2) and (I > 0) do
  381.     begin
  382.       Dec(I);
  383.       ThreadSwitch;
  384.     end;
  385.   end;
  386. end;
  387.  
  388. procedure TKonsole.Flush();
  389. begin
  390.   while FOnAir do ThreadSwitch;
  391. end;
  392.