📄 cons_in.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "cons_front.h"#include <eros/SleepKey.h>#include <eros/KeyboardKey.h>#include <domain/Runtime.h>const uint32_t __rt_stack_pointer = 0x41000;#define KR_TMP KR_APP(0)#define KR_CONS_FRONT KR_APP(1)#define KR_KBDKEY KR_APP(2)#define KR_CONSOLEKEY KR_APP(3)#define KR_SLEEPKEY KR_APP(4)#define KR_KEYBITS KR_APP(5)#define KR_RK0 KR_ARG(0)#define KR_RK1 KR_ARG(1)#define KR_RK2 KR_ARG(2)struct shared * const kdb_buf = (void *)SH_ADDR;intstrlen(const char *s){ const char *send = s; while (*send) send++; return send - s;}voidWrite(const char *s){ Message msg; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.snd_data = (uint8_t *) s; msg.snd_len = strlen(s); /* omit trailing null! */ msg.rcv_len = 0; /* no data returned */ msg.snd_invKey = KR_CONSOLEKEY; msg.snd_code = 1; (void) CALL(&msg);}#define Sleep(nsec) sl_sleep(KR_SLEEPKEY, (nsec)*1000u)#define IN_EOF 256intgetc(){ char chr[2] = "\0"; /* chr + 0 */ uint32_t result; result = kbd_get(KR_KBDKEY, chr, 1); /* get 1 character */ if (result != RC_OK) return IN_EOF; else return (*chr); /* return the character */}uint32_tnotifyLine(uint32_t oc, uint32_t events) { /* * tell line disp to wake us up when it starts to * empty the buffer -- when it invokes the resume key for our CALL, * the buffer will not be full. */ Message msg; msg.snd_w1 = events; msg.snd_w2 = 0u; msg.snd_w3 = 0u; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.snd_len = 0; /* no data to send */ msg.rcv_len = 0; /* no data to send */ msg.snd_invKey = KR_CONS_FRONT; msg.snd_code = oc; CALL(&msg); if (msg.rcv_code == RC_OK) return 1; else return 0; }voidtty_init (){ /* * intialize various data structs */ kdb_buf->wakeup = SIK_BUFSZ+1; /* set wakeup out of bounds */ kdb_buf->head = 0; kdb_buf->tail = 0; kdb_buf->full = 0; }uint16_taddtoBuf (char chr){ /* * this will be slighly less trivial once * we support more than one chr at a time */ if (kdb_buf->full) return 0; kdb_buf->buf[kdb_buf->head] = chr; if (kdb_buf->head == (SIK_BUFSZ - 1)) kdb_buf->head = 0; else kdb_buf->head++; if (kdb_buf->head == kdb_buf->tail) kdb_buf->full = 1; return 1;}intProcessRequest(Message *msg){ /* * proceed to call the kdb key in an infinite loop * notify linedisp of changes in buffer as we reach critical * (wakeup) points * */ uint32_t Result; uint32_t added; /* flag to indicate whether a char made it into the buffer */ tty_init(); /* intialize various data structs */ for ( ; ; ) { char curChar; /* * currently getc() returns a single character * someday we will be dealing with multiples with early termination * * that is, what we'd like to do is move the COOKED mode * early \n termination logic into the kernel * * until then, COOKED mode is going to be slower than * it could be */ Result = kbd_get(KR_KBDKEY,&curChar,1); if (Result != RC_OK) { DEBUG(unsorted) kdprintf(KR_CONSOLEKEY, "cons_in: kbd_get did not return RC_OK (%08x)\n", Result); continue; /* deal with failure? */ } added = 0; while (!added) { if (addtoBuf(curChar)) { uint32_t events = 0u; added = 1; if (kdb_buf->timeoutMsecs != UINT32_MAX) { if (((kdb_buf->head + SIK_BUFSZ - kdb_buf->tail) % SIK_BUFSZ) == kdb_buf->timeoutChars) { kprintf(KR_CONSOLEKEY, "cons_in: timeoutchars reached\n");#if 0 if (kdb_buf->timeoutMsecs == 0)#endif events |= CharSrc_TimeOutEvent;#if 0 else events |= CharSrc_TimeOutEvent;/* FIXME: support full timeout */#endif } } if (kdb_buf->head == kdb_buf->wakeup) { events |= CharSrc_FilledBufferEvent; } if (CHECK_CHAR(kdb_buf->char_mask,curChar)) { events |= CharSrc_SpecialCharEvent; } else if (curChar == '\r') { DEBUG(unsorted) kdprintf(KR_CONSOLEKEY,"Cons_in: \\r not a special char!\n"); } if (events) { notifyLine(LD_WAKEUP,events); } } else { /* AddtoBuf failed; buffer full */ /* * We need to tell cons_front that the buffer is full, * so we CALL cons_front, which returns when the buffer has * more space. */ notifyLine(LD_NOTIFY,0); /* returned 1 if there was a delay */ } } } return 1;}static uint8_t rcvData[EROS_PAGE_SIZE];intmain(){ Message msg; msg.snd_invKey = KR_VOID; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_data = 0; msg.snd_len = 0; msg.snd_code = 0; msg.snd_w1 = 0; msg.snd_w2 = 0; msg.snd_w3 = 0; msg.rcv_key0 = KR_RK0; msg.rcv_key1 = KR_RK1; msg.rcv_key2 = KR_RK2; msg.rcv_key3 = KR_RETURN; msg.rcv_data = rcvData; msg.rcv_code = 0; msg.rcv_w1 = 0; msg.rcv_w2 = 0; msg.rcv_w3 = 0; msg.rcv_len = EROS_PAGE_SIZE; msg.snd_invKey = KR_RETURN; ProcessRequest(&msg); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -