Selaa lähdekoodia

Add very basic KeyDown events to the GUI event stream.

The Terminal program now hosts an interactive shell. :^)
Andreas Kling 6 vuotta sitten
vanhempi
commit
78696236d3
4 muutettua tiedostoa jossa 33 lisäystä ja 8 poistoa
  1. 16 3
      Kernel/GUITypes.h
  2. 3 0
      Kernel/Process.cpp
  3. 10 5
      Terminal/main.cpp
  4. 4 0
      Widgets/Window.cpp

+ 16 - 3
Kernel/GUITypes.h

@@ -42,11 +42,18 @@ struct GUI_WindowBackingStoreInfo {
 
 enum class GUI_MouseButton : unsigned char {
     NoButton = 0,
-    Left = 1,
-    Right = 2,
-    Middle = 4,
+    Left     = 1,
+    Right    = 2,
+    Middle   = 4,
 };
 
+struct GUI_KeyModifiers { enum {
+    Shift = 1 << 0,
+    Alt   = 1 << 1,
+    Ctrl  = 1 << 2,
+}; };
+
+
 struct GUI_Event {
     enum Type : unsigned {
         Invalid,
@@ -54,6 +61,8 @@ struct GUI_Event {
         MouseMove,
         MouseDown,
         MouseUp,
+        KeyDown,
+        KeyUp,
     };
     Type type { Invalid };
     int window_id { -1 };
@@ -66,6 +75,10 @@ struct GUI_Event {
             GUI_Point position;
             GUI_MouseButton button;
         } mouse;
+        struct {
+            char character;
+            unsigned modifiers;
+        } key;
     };
 };
 

+ 3 - 0
Kernel/Process.cpp

@@ -1173,6 +1173,7 @@ int Process::sys$fcntl(int fd, int cmd, dword arg)
     case F_GETFL:
         return descriptor->file_flags();
     case F_SETFL:
+        // FIXME: Support changing O_NONBLOCK
         descriptor->set_file_flags(arg);
         break;
     default:
@@ -1294,6 +1295,8 @@ int Process::sys$open(const char* path, int options)
         return error;
     if (options & O_DIRECTORY && !descriptor->is_directory())
         return -ENOTDIR; // FIXME: This should be handled by VFS::open.
+    if (options & O_NONBLOCK)
+        descriptor->set_blocking(false);
 
     int fd = 0;
     for (; fd < (int)m_max_open_file_descriptors; ++fd) {

+ 10 - 5
Terminal/main.cpp

@@ -43,7 +43,7 @@ static void make_shell(int ptm_fd)
 
 int main(int, char**)
 {
-    int ptm_fd = open("/dev/ptm0", O_RDWR);
+    int ptm_fd = open("/dev/ptm0", O_RDWR | O_NONBLOCK);
     if (ptm_fd < 0) {
         perror("open");
         return 1;
@@ -53,7 +53,7 @@ int main(int, char**)
 
     make_shell(ptm_fd);
 
-    int event_fd = open("/dev/gui_events", O_RDONLY);
+    int event_fd = open("/dev/gui_events", O_RDONLY | O_NONBLOCK);
     if (event_fd < 0) {
         perror("open");
         return 1;
@@ -72,13 +72,15 @@ int main(int, char**)
             }
             terminal.paint();
         }
-#if 0
+
         GUI_Event event;
         ssize_t nread = read(event_fd, &event, sizeof(event));
         if (nread < 0) {
             perror("read");
             return 1;
         }
+        if (nread == 0)
+            continue;
         assert(nread == sizeof(event));
         dbgprintf("(Terminal:%d) ", getpid());
         switch (event.type) {
@@ -86,13 +88,16 @@ int main(int, char**)
         case GUI_Event::Type::MouseDown: dbgprintf("WID=%x MouseDown %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); break;
         case GUI_Event::Type::MouseUp: dbgprintf("WID=%x MouseUp %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); break;
         case GUI_Event::Type::MouseMove: dbgprintf("WID=%x MouseMove %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); break;
+        case GUI_Event::Type::KeyDown: dbgprintf("WID=%x KeyDown 0x%b (%c)\n", event.window_id, event.key.character, event.key.character); break;
         default:
             ASSERT_NOT_REACHED();
         }
 
-        if (event.type == GUI_Event::Type::MouseDown)
+        if (event.type == GUI_Event::Type::Paint) {
             terminal.paint();
-#endif
+        } else if (event.type == GUI_Event::Type::KeyDown) {
+            write(ptm_fd, &event.key.character, 1);
+        }
     }
     return 0;
 }

+ 4 - 0
Widgets/Window.cpp

@@ -72,6 +72,10 @@ void Window::event(Event& event)
         gui_event.mouse.position = static_cast<MouseEvent&>(event).position();
         gui_event.mouse.button = to_api(static_cast<MouseEvent&>(event).button());
         break;
+    case Event::KeyDown:
+        gui_event.type = GUI_Event::Type::KeyDown;
+        gui_event.key.character = static_cast<KeyEvent&>(event).text()[0];
+        break;
     }
 
     if (gui_event.type == GUI_Event::Type::Invalid)