Index: lab5.c
===================================================================
--- lab5.c	(revision 108)
+++ lab5.c	(revision 109)
@@ -7,6 +7,9 @@
 
 #include "graphics.h"
 #include "graphics_macros.h"
+#include "keyboard.h"
+#include "kbc.h"
+#include "kbc_macros.h"
 
 // Any header files included below this line should have been created by you
 
@@ -39,13 +42,6 @@
     if ((r = get_permissions_first_mbyte()))
         panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r);
 
-    if (set_graphics_mode(mode)) {
-        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
-        if (vg_exit())
-            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
-        return 1;
-    };
-
     if (vbe_get_mode_information(mode)) {
         printf("%s: failed to get information for mode %x.\n", __func__, mode);
         if (vg_exit())
@@ -55,6 +51,13 @@
 
     map_vram(); // if function fails it aborts program
 
+    if (set_graphics_mode(mode)) {
+        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
+        if (vg_exit())
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+        return 1;
+    };
+
     tickdelay(micros_to_ticks(delay*1e6));
 
     if (vg_exit()) {
@@ -76,8 +79,17 @@
 int(video_test_rectangle)(uint16_t mode, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color) {
     int r;
     if ((r = get_permissions_first_mbyte()))
-    panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r);
+        panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r);
 
+    if (vbe_get_mode_information(mode)) {
+        printf("%s: failed to get information for mode %x.\n", __func__, mode);
+        if (vg_exit())
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+        return 1;
+    }
+
+    map_vram(); // if function fails it aborts program
+
     if (set_graphics_mode(mode)) {
         printf("%s: failed to set graphic mode %x.\n", __func__, mode);
         if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
@@ -84,13 +96,71 @@
         return 1;
     };
 
-    vg_draw_hline(x, y, width, color);
-    tickdelay(micros_to_ticks(1000000));
+    if (vg_draw_rectangle(x, y, width, height, color)) {
+        if (vg_exit()) {
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+            if (free_memory()) printf("%s: lm_free failed\n", __func__);
+        }
+        return 1;
+    }
+
+    /// loop stuff
+    int ipc_status;
+    message msg;
+    /// Keyboard interrupt handling
+    uint8_t kbc_irq_bit = KBC_IRQ;
+    int kbc_id = 0;
+    int kbc_irq = BIT(kbc_irq_bit);
+    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
+        if (vg_exit()) {
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+            if (free_memory()) printf("%s: lm_free failed\n", __func__);
+        }
+        return 1;
+    }
+    /// cycle
+    int good = 1;
+    while (good) {
+        /* Get a request message. */
+        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
+            printf("driver_receive failed with %d", r);
+            continue;
+        }
+        if (is_ipc_notify(ipc_status)) { /* received notification */
+            switch (_ENDPOINT_P(msg.m_source)) {
+                case HARDWARE: /* hardware interrupt notification */
+                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
+                        kbc_ih();
+                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
+                    }
+                    break;
+                default:
+                    break; /* no other notifications expected: do nothing */
+            }
+        } else { /* received standart message, not a notification */
+            /* no standart message expected: do nothing */
+        }
+    }
+
+    if (unsubscribe_interrupt(&kbc_id)) {
+        if (vg_exit()) {
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+            if (free_memory()) printf("%s: lm_free failed\n", __func__);
+        }
+        return 1;
+    };
+
     if (vg_exit()) {
         printf("%s: vg_exit failed to exit to text mode.\n", __func__);
         if (free_memory()) printf("%s: lm_free failed\n", __func__);
         return 1;
     }
+
+    if (free_memory()) {
+        printf("%s: lm_free failed\n", __func__);
+        return 1;
+    }
+
     return 0;
 }
 
