Browse Source

first working window mgmt

mntmn 8 years ago
parent
commit
ea5552ca40
7 changed files with 341 additions and 168 deletions
  1. 45 0
      devices/sdl2.c
  2. 17 0
      notes/wm_notes.txt
  3. 13 7
      sledge/compiler_new.c
  4. 68 57
      sledge/os/editor.l
  5. 56 51
      sledge/os/gfx.l
  6. 24 17
      sledge/os/mouse.l
  7. 118 36
      sledge/os/shell.l

+ 45 - 0
devices/sdl2.c

@@ -118,6 +118,12 @@ Cell* keyfs_open() {
   return alloc_int(1);
 }
 
+static int mouse_buttons=0;
+static int mouse_x=0;
+static int mouse_y=0;
+static int last_mouse_x=0;
+static int last_mouse_y=0;
+
 #include <time.h>
 #include <unistd.h>
 
@@ -185,6 +191,11 @@ Cell* keyfs_read() {
         }
       }
       break;
+    case SDL_MOUSEMOTION:
+      mouse_x = event.motion.x;
+      mouse_y = event.motion.y;
+      mouse_buttons = event.motion.state;
+      break;
     }
   }
 
@@ -203,7 +214,41 @@ void sdl_mount_keyfs() {
   fs_mount_builtin("/keyboard", keyfs_open, keyfs_read, 0, 0, 0);
 }
 
+
+Cell* mouse_open(Cell* cpath) {
+  if (!cpath || cpath->tag!=TAG_STR) {
+    printf("[usbmouse] open error: non-string path given\r\n");
+    return alloc_nil();
+  }
+
+  return alloc_int(1);
+}
+
+Cell* mouse_read(Cell* stream) {
+  mouse_buttons = SDL_GetMouseState(&mouse_x, &mouse_y);
+
+  int mouse_dx = mouse_x - last_mouse_x;
+  int mouse_dy = mouse_y - last_mouse_y;
+  Cell* res = alloc_cons(alloc_cons(alloc_int(mouse_x/SCALE),alloc_int(mouse_y/SCALE)),alloc_int(mouse_buttons));
+  last_mouse_x = mouse_x;
+  last_mouse_y = mouse_y;
+  return res;
+}
+
+Cell* mouse_write(Cell* arg) {
+  return NULL;
+}
+
+Cell* mouse_mmap(Cell* arg) {
+  return alloc_nil();
+}
+
+void sdl_mount_mousefs() {
+  fs_mount_builtin("/mouse", mouse_open, mouse_read, mouse_write, 0, mouse_mmap);
+}
+
 void dev_sdl_init() {
   sdl_mount_fbfs();
   sdl_mount_keyfs();
+  sdl_mount_mousefs();
 }

+ 17 - 0
notes/wm_notes.txt

@@ -0,0 +1,17 @@
+algoriddim:
+
+1. sage dem task: dirty, rendere in deine surface
+2. blitte alle task surfaces in der richtigen reihenfolge (z) in den fb
+3. task kann selber sagen, ich war dirty, habe gerendert
+
+2 structs:
+
+task (external interface)
+- name
+- focused
+- surface
+- z
+- clobbered
+- painted
+
+opaque state object (internal interface)

+ 13 - 7
sledge/compiler_new.c

@@ -296,6 +296,7 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
   Arg* fn_frame = frame->f;
   Cell* opsym, *args, *orig_args, *signature_args, *op, *orig_op=NULL;
   env_entry* op_env;
+  char* op_name;
   
   int is_let = 0;
   int argi = 0;
@@ -346,10 +347,11 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
     return 0;
   }
 
-  op_env = lookup_global_symbol(opsym->ar.addr);
+  op_name = (char*)opsym->ar.addr;
+  op_env = lookup_global_symbol(op_name);
 
   if (!op_env || !op_env->cell) {
-    printf("<error: undefined symbol %s in operator position>\r\n",(char*)opsym->ar.addr);
+    printf("<error: undefined symbol %s in operator position>\r\n",op_name);
     return 0;
   }
   op = op_env->cell;
@@ -440,10 +442,12 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
           //printf("INT mode of let\r\n");
           // let prefers raw integers!
           sig_tag = TAG_INT;
+          signature_arg = prototype_int;
         } else {
           //printf("ANY mode of let\r\n");
           // but cells are ok, too
           sig_tag = TAG_ANY;
+          signature_arg = prototype_any;
         }
       }
 
@@ -506,7 +510,7 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
         //printf("arg_frame_idx: %d\n",arg_frame_idx);
 
         if (!argdefs[argi].env && arg_frame_idx<0) {
-          printf("<undefined symbol %s given for argument %s>\r\n",(char*)arg->ar.addr,arg_name);
+          printf("<undefined symbol %s given for argument %s of %s>\r\n",(char*)arg->ar.addr,arg_name,op_name);
           return 0;
         }
       }
@@ -523,17 +527,17 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
         // check if we can typecast
         // else, fail with type error
 
-        printf("<type mismatch for argument %s (given %s, expected %s)>\r\n",arg_name,tag_to_str(given_tag),tag_to_str(sig_tag));
+        printf("<type mismatch for argument %s of %s (given %s, expected %s)>\r\n",arg_name,op_name,tag_to_str(given_tag),tag_to_str(sig_tag));
         return 0;
       }
     } else {
       if (!arg && signature_arg) {
         // missing arguments
-        printf("<argument %s missing!>\r\n",arg_name);
+        printf("<argument %s of %s missing!>\r\n",arg_name,op_name);
         return 0;
       } else if (arg && !signature_arg) {
         // surplus arguments
-        printf("<surplus arguments!>\r\n");
+        printf("<surplus arguments to %s!>\r\n",op_name);
         return 0;
       }
     }
@@ -1170,6 +1174,8 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
 
       jit_lea(ARGR0,arg);
       jit_call(alloc_struct,"new:alloc_struct");
+
+      compiled_type = alloc_struct(arg); // prototype
       
       break;
     }
@@ -1247,7 +1253,7 @@ Cell* compile_expr(Cell* expr, Frame* frame, Cell* return_type) {
         if (type_env) {
           struct_def = type_env->cell;
         } else {
-          printf("<type not found.>");
+          printf("<sput: struct type %s not found.>\r\n",argdefs[0].type_name);
           return 0;
         }
       } else {

+ 68 - 57
sledge/os/editor.l

@@ -1,7 +1,7 @@
 (
 (struct editor
   buffer "hello world!"
-  surf (surface)
+  font unifont
   cursor 0
   cursor-char 32
   cursor-x 0
@@ -12,38 +12,37 @@
   scroll-y 0
   scroll-dirty 0
   buf-dirty 1
-  focused 0
 )
 
 (def find-prev (fn buf rune pos (do
   (let p pos)
-  (while (and (gt p 0) (not (eq rune (get buf p))))
+  (while (and (gt p 0) (not (eq rune (get8 buf p))))
     (let p (- p 1)))
   (+ p 0)
 )))
 
 (def find-next (fn buf rune pos (do
   (let p pos)
-  (while (and (lt p (size buf)) (not (eq rune (get buf p))))
+  (while (and (lt p (size buf)) (not (eq rune (get8 buf p))))
     (let p (+ p 1)))
   (+ p 0)
 )))
 
 (def find-prev-ws (fn buf pos (do
   (let p (+ pos 0))
-  (while (and (gt p 0) (not (or (eq 10 (get buf p)) (eq 32 (get buf p)))))
+  (while (and (gt p 0) (not (or (eq 10 (get8 buf p)) (eq 32 (get8 buf p)))))
     (let p (- p 1)))
   (if (eq p 0) 0 (+ p 1))
 )))
 
 (def find-next-ws (fn buf pos (do
   (let p (+ pos 0))
-  (while (and (lt p (size buf)) (not (or (eq 10 (get buf p)) (eq 32 (get buf p)))))
+  (while (and (lt p (size buf)) (not (or (eq 10 (get8 buf p)) (eq 32 (get8 buf p)))))
     (let p (+ p 1)))
   (+ p 0)
 )))
 
-(def buf-render (fn (this editor) (do
+(def buf-render (fn (surf surface) (this editor) (do
   (let buffer (sget this buffer))
   (let lines (split buffer [0a]))
   (let i 0)
@@ -52,20 +51,19 @@
   (let nextpos 0)
   (let x 0)
   (let y 0)
-  (let x (+ 0 (sget this win-x)))
-  (let y (+ 0 (sget this win-y)))
-  (let maxx (+ x (sget this win-w)))
-  (let maxy (+ y (sget this win-h)))
+  (let maxx (sget surf width))
+  (let maxy (sget surf height))
   (let cursor (sget this cursor))
   (let scroll-dirty (sget this scroll-dirty))
   (let scroll-y (sget this scroll-y))
   (let render-all 0)
+  (let font (sget this font))
   
   ; number of lines changed? then rerender
   (if (or scroll-dirty (not (eq (sget this last-num-lines) (list-size lines)))) (do
       (let render-all 1)
-      (boxfill x y maxx maxy 0xffff)
-      (box (- x 1) (- y 1) (+ maxx 2) (+ maxy 2) 0x0)
+      (print "editor boxfill")
+      (boxfill surf x y maxx maxy 0xffff)
       (sput this scroll-dirty 0)
     )
   0)
@@ -84,8 +82,8 @@
       (sput this cursor-abs-y (+ y 0))
       (sput this cursor-x (- cursor pos))
       (sput this cursor-y (- (- i 1) scroll-y ))
-      (sput this cursor-abs-x (+ (sget this win-x) (* rune-spacing (sget this cursor-x))))
-      (sput this cursor-char (get ln (sget this cursor-x)))
+      (sput this cursor-abs-x (+ 0 (* (sget font spacing) (sget this cursor-x))))
+      (sput this cursor-char (get8 ln (sget this cursor-x)))
       (let is-current-line 1)
 
       ; blank out the line
@@ -96,7 +94,7 @@
     
     (if (or render-all is-current-line) (do
       (if (and (lt y maxy) (not (gt scroll-y i)))
-        (blit-str ln (sget this win-x) y maxx maxy)
+        (blit-str surf font ln 0 y)
         0)
     ) 0)
     
@@ -124,31 +122,35 @@
   (sput this buf-dirty 1)
 ) 0)))
 
-(def repair-at-cursor (fn (this editor) (do
-  (print "repair-at-cursor")
+(def repair-at-cursor (fn (surf surface) (this editor) (do
   (let term-x (sget this cursor-abs-x))
   (let term-y (sget this cursor-abs-y))
+  (print (list "repair-at-cursor" term-x term-y))
   (let cursor-char (sget this cursor-char))
+  (let font (sget this font))
+  (let rune (if (eq cursor-char 0) 32 cursor-char))
+
+  (print (list rune surf font))
   
-  (blit-char (if (eq cursor-char 0) 32 cursor-char) term-x term-y)
+  (blit-char16 surf font rune term-x term-y)
 )))
 
-(def cursor-left (fn (this editor) (do
-  (repair-at-cursor this)
+(def cursor-left (fn (surf surface) (this editor) (do
+  (repair-at-cursor surf this)
   (sput this cursor (- (sget this cursor) 1))
   (sput this buf-dirty 1)
 )))
 
-(def cursor-right (fn (this editor) (do
-  (repair-at-cursor this)
+(def cursor-right (fn (surf surface) (this editor) (do
+  (repair-at-cursor surf this)
   (sput this cursor (+ (sget this cursor) 1))
   (sput this buf-dirty 1)
 )))
 
 (def scroll-speed 5)
 
-(def cursor-up (fn (this editor) (do
-  (repair-at-cursor this)
+(def cursor-up (fn (surf surface) (this editor) (do
+  (repair-at-cursor surf this)
   (let buf (sget this buffer))
   
   (sput this cursor (find-prev buf 10 (- (sget this cursor) 1)))
@@ -160,18 +162,20 @@
   (sput this buf-dirty 1)
 )))
 
-(def cursor-down (fn (this editor) (do
-  (repair-at-cursor this)
+(def cursor-down (fn (surf surface) (this editor) (do
+  (repair-at-cursor surf this)
   (let cursor (sget this cursor))
   (let last-num-lines (sget this last-num-lines))
   (let buf (sget this buffer))
+  (let font (sget this font))
+  (let rune-h (sget font rune-h))
   
   (let nextzero (find-next buf 0 (+ cursor 1)))
   (let nextnl   (find-next buf 10 (+ cursor 1)))
 
-  (let y (+ 0 (sget this win-y)))
-  (let maxy (+ y (sget this win-h)))
-  (let maxlines (/ maxy rune-h))
+  (let y 0)
+  (let maxy (+ y (sget surf height)))
+  (let maxlines (- (/ maxy rune-h) 1))
   
   (sput this cursor (if (lt nextzero nextnl) cursor nextnl))
   (if (and (gt (sget this cursor-y) maxlines) (lt (sget this scroll-y) (sget this last-num-lines))) (do
@@ -186,18 +190,20 @@
   (print "exit-editor")
 )))
 
-(def editor-yield-focus (fn (this editor) (do
+(def editor-yield-focus (fn (task-obj task) (do
   (print "yield focus")
-  (sput this focused 0)
+  (sput task-obj focused 0)
 )))
 
-(def handle-editor-key (fn (this editor) k (do
-  (if (eq k 20) (cursor-right this)
-    (if (eq k 19) (cursor-left this)
+(def handle-editor-key (fn (task-obj task) (this editor) k (do
+  (let surf (sget task-obj surface))
+
+  (if (eq k 20) (cursor-right surf this)
+    (if (eq k 19) (cursor-left surf this)
       (if (eq k 0x7f) (backspace this)
-        (if (eq k 17) (cursor-up this)
-          (if (eq k 18) (cursor-down this)
-            (if (eq k 9) (editor-yield-focus this)
+        (if (eq k 17) (cursor-up surf this)
+          (if (eq k 18) (cursor-down surf this)
+            (if (eq k 9) (editor-yield-focus task)
 
   (if (and (gt k 0) (lt k 250))
     (do
@@ -215,45 +221,50 @@
 
 (def handle-command-key (fn 0))
 
-(def edit-main (fn (this editor) focused (do
-  (sput this focused focused)
+(def editor-task (fn (task-obj task) (this editor) (do
   (let cursor (sget this cursor))
   (let buf (sget this buffer))
+
+  (let focused (sget task-obj focused))
+  (let surf (sget task-obj surface))
   
   (if focused (do
     (let str (recv keyboard))
-    (let k (get str 0))
-    (handle-editor-key this k)
+    (let k (get8 str 0))
+    (handle-editor-key task-obj this k)
     ) 0)
   
   (if (lt cursor 0) (sput this cursor 0) 0)
   (if (gt cursor (size buf)) (sput this cursor (size buf)) 0)
 
   (if (sget this buf-dirty) (do
-                    (buf-render this)
+                    (buf-render surf this)
                     (sput this buf-dirty 0)
+                    (sput task-obj redrawn 1)
                   ) 0)
 
   (let term-x (sget this cursor-abs-x))
   (let term-y (sget this cursor-abs-y))
   (let cursor-char (sget this cursor-char))
-  
-  (if (and focused (eq cursor-blink (/ cursor-blink-delay 2)))
-      (blit-char 0x2588 term-x term-y)
-  (if (eq cursor-blink 0)
-        (blit-char (if (eq cursor-char 0) 32 cursor-char) term-x term-y) 0))
-  (let focused (sget this focused))
-  focused
-)))
+  (let font (sget this font))
 
-(def editor-task (fn state (do
-  (let s state)
-  (let focused (car s)) (let s (cdr s))
-  (let this (car s))
-  (let focused (edit-main this focused))
-  (list focused this)
+  (write (list (quote ed) cursor (quote /) (size buf)) (sget task-obj name))
+
+  (if focused
+  (if (eq cursor-blink (/ cursor-blink-delay 2))
+    (do
+      (blit-char16 surf font 0x2588 term-x term-y)
+      (sput task-obj redrawn 1))
+
+    (if (eq cursor-blink 0)
+      (do
+        (blit-char16 surf font (if (eq cursor-char 0) 32 cursor-char) term-x term-y)
+        (sput task-obj redrawn 1))
+      0)) 0)
+  0
 )))
 
+
 ;(def edit-file (fn path (do
 ;  (let content (load path))
 ;  (edit content)

+ 56 - 51
sledge/os/gfx.l

@@ -4,6 +4,8 @@
         height 0
         shift  1
         pitch  0
+        x      0
+        y      0
         pixels [])
 
 (struct font
@@ -98,8 +100,6 @@
 
   (let rune-ww (shl rune-spacing 1))
 
-  (print (list "rune" rune so do font-pitch screen-pitch x y))
-  
   (while (lt iy rune-h) (do
     (let ix 0)
     (while (lt ix rune-ww) (do
@@ -208,31 +208,61 @@
 ;   ))
 ;   res
 ; )))
+(def boxfill (fn (surf surface) x y w h color (do
+  (let ofs 0)
+  (let xi 0)
+  (let yi 0)
+  (let xi (+ x 0)) ; TODO get rid of this
+  (let yi (+ y 0))
+  (let xx (+ x w))
+  (let yy (+ y h))
+  (let ww (shl w 1))
+  (let pitch (sget surf pitch))
+  (let ofs (+ (* y pitch) (shl x 1)))
+  (let pixels (sget surf pixels))
 
-; (def paste (fn from x y w h (do
-;   (let xx 0)
-;   (let yy 0)
-;   (let di 0)
-;   (let si 0)
-;   (let yy (+ y 0))
-;   (let xw (+ x w))
-;   (let yh (+ y h))
-;   (let to grab-from)
-;   (let pitch (+ grab-pitch 0))
-;   (while (lt yy yh) (do
-;     (let xx (+ x 0))
-;     (while (lt xx xw) (do
-;       (let di (+ xx (* pitch yy)))
-;       (put to di (get from si))
-;       (put to (+ di 1) (get from (+ si 1)))
-;       (let si (+ si 2))
-;       (let di (+ di 2))
-;       (let xx (+ xx 1))
-;     ))
-;     (let yy (+ yy 1))
-;   ))
-;   1
-; )))
+  (while (lt yi yy) (do
+    (let xi (+ x 0))
+    (while (lt xi xx) (do
+      (put16 pixels ofs color)
+      (let xi (+ xi 1))
+      (let ofs (+ ofs 2))
+    ))
+    (let ofs (- (+ ofs pitch) ww))
+    (let yi (+ yi 1))
+  ))
+  0 ; FIXME crashes x64 if this is not here
+)))
+
+(def blit (fn (dest surface) (from surface) (do
+  (let xx 0)
+  (let yy 0)
+  (let di 0)
+  (let si 0)
+  (let yy (+ (sget from y) 0))
+  (let xw (+ (sget from x) (sget from width)))
+  (let yh (+ (sget from y) (sget from height)))
+  (let to (sget dest pixels))
+  (let shift (sget dest shift))
+  (let pitch (- (sget dest pitch) (shl (sget from width) shift)))
+  (let di (+ (shl (sget from x) shift) (* yy (sget dest pitch))))
+  (let c 0)
+  (let pixels (sget from pixels))
+  
+  (while (lt yy yh) (do
+    (let xx (+ (sget from x) 0))
+    (while (lt xx xw) (do
+      (let c (get16 pixels si))
+      (put16 to di c)
+      (let si (+ si 2))
+      (let di (+ di 2))
+      (let xx (+ xx 1))
+    ))
+    (let yy (+ yy 1))
+    (let di (+ di pitch))
+  ))
+  1
+)))
 
 (def blit-str (fn (surf surface) (font font) str x y (do
   (let i 0)
@@ -265,31 +295,6 @@
   yy
 )))
 
-(def boxfill (fn (surf surface) x y w h color (do
-  (let ofs 0)
-  (let xi 0)
-  (let yi 0)
-  (let xi (+ x 0)) ; TODO get rid of this
-  (let yi (+ y 0))
-  (let xx (+ x w))
-  (let yy (+ y h))
-  (let pitch (sget surf pitch))
-  (let ofs (+ (* y pitch) (shl x 1)))
-  (let ww (shl w 1))
-  (let pixels (sget surf pixels))
-
-  (while (lt yi yy) (do
-    (let xi (+ x 0))
-    (while (lt xi xx) (do
-      (put16 pixels ofs color)
-      (let xi (+ xi 1))
-      (let ofs (+ ofs 2))
-    ))
-    (let ofs (- (+ ofs pitch) ww))
-    (let yi (+ yi 1))
-  ))
-  0 ; FIXME crashes x64 if this is not here
-)))
 
 (def triangle (fn (surf surface) a b c color (do
   (line surf a b color)

+ 24 - 17
sledge/os/mouse.l

@@ -2,28 +2,35 @@
 (def mouse (open "/mouse"))
 (def mouse-x 0)
 (def mouse-y 0)
+(def mouse-oldx 0)
+(def mouse-oldy 0)
 (def mouse-dx 0)
 (def mouse-dy 0)
 (def mouse-btn 0)
-(def mouse-task (fn (do
-  (add-task (fn (do
-    (blit-char 32 mouse-x mouse-y)
+(def mouse-dragging 0)
+(def mouse-func (fn (t task) dummy (do
+  (blit-char16 fb unifont 32 mouse-x mouse-y)
     
-    (let mouse-info (recv mouse))
-    (def mouse-dx (car (car mouse-info)))
-    (def mouse-dy (cdr (car mouse-info)))
-    (def mouse-x (+ mouse-x mouse-dx))
-    (def mouse-y (+ mouse-y mouse-dy))
-    (if (lt mouse-x 0) (def mouse-x 0) 0)
-    (if (lt mouse-y 0) (def mouse-y 0) 0)
-    (if (gt mouse-x (- screen-width 1))  (def mouse-x (- screen-width 1)) 0)
-    (if (gt mouse-y (- screen-height 1)) (def mouse-y (- screen-height 1)) 0)
-    
-    (def mouse-btn (cdr mouse-info))
+  (let mouse-info (recv mouse))
+  (def mouse-x (car (car mouse-info)))
+  (def mouse-y (cdr (car mouse-info)))
 
-    (if mouse-btn (blit-char 0x219c mouse-x mouse-y)
-      (blit-char 0x2196 mouse-x mouse-y))
+  (def mouse-dx (- mouse-x mouse-oldx))
+  (def mouse-dy (- mouse-y mouse-oldy))
+  (def mouse-oldx (+ mouse-x 0))
+  (def mouse-oldy (+ mouse-y 0))
+  
+  ;(def mouse-x (+ mouse-x mouse-dx))
+  ;(def mouse-y (+ mouse-y mouse-dy))
+  ;(if (lt mouse-x 0) (def mouse-x 0) 0)
+  ;(if (lt mouse-y 0) (def mouse-y 0) 0)
+  ;(if (gt mouse-x (- screen-width 1))  (def mouse-x (- screen-width 1)) 0)
+  ;(if (gt mouse-y (- screen-height 1)) (def mouse-y (- screen-height 1)) 0)
+    
+  (def mouse-btn (cdr mouse-info))
+  (def mouse-dragging mouse-btn)
 
-  )) (list))
+  (if mouse-btn (blit-char16 fb unifont 0x219c mouse-x mouse-y)
+    (blit-char16 fb unifont 0x2196 mouse-x mouse-y))
 )))
 )

+ 118 - 36
sledge/os/shell.l

@@ -3,6 +3,14 @@
   (split (load "/sd/") [0a])
 )))
 
+(struct task
+  name "untitled task"
+  focused 0
+  z 0
+  needs-redraw 0
+  redrawn 0
+  surface (surface))
+
 (def draw-logo (fn ox oy (do
   (let c 0xff8e)
   (line fb (pt (+ ox 16) (- oy 38)) (pt (+ ox 16) (- oy 102)) c)
@@ -15,31 +23,94 @@
   (line fb (pt (+ ox 208) (- oy 102)) (pt (+ ox 272) (- oy 102)) c)
 )))
 
-(draw-logo (- (/ (sget fb width) 2) 140) (/ (sget fb height) 2))
-(draw-logo (- (/ (sget fb width) 2) 139) (/ (sget fb height) 2))
-(draw-logo (- (/ (sget fb width) 2) 140) (+ 1 (/ (sget fb height) 2)))
-(send screen 0)
+(def desktop-task (fn (t task) (do
+  (if (sget t needs-redraw) (do
+    (clear)
+    (draw-logo (- (/ (sget fb width) 2) 140) (/ (sget fb height) 2))
+    (draw-logo (- (/ (sget fb width) 2) 139) (/ (sget fb height) 2))
+    (draw-logo (- (/ (sget fb width) 2) 140) (+ 1 (/ (sget fb height) 2)))
+    (send screen 0)
+  ) 0)
+  0
+)))
 
 (def keyboard (open "/keyboard"))
 
+(import "/sd/os/mouse.l")
+
 ;; (def evbuf (alloc-str 4096))
 ;; (def p (fn xp x y maxx maxy (do
 ;;   (write xp evbuf)
 ;;   (blit-str evbuf x y maxx maxy)
 ;; )))
 
+(draw-logo (- (/ (sget fb width) 2) 140) (/ (sget fb height) 2))
 (blit-str fb unifont "hello" 100 100)
 
 (def tasks (list))
 (def new-tasks (list))
 
-(def add-task (fn t initial-state (do
-  (def new-tasks (cons (cons t initial-state) new-tasks))
-  (list-size new-tasks)
+(def add-task (fn task-func task-obj task-state (do
+  (def tasks (cons (list task-func task-obj task-state) tasks))
+  (list-size tasks)
 )))
 
-(def task-func (fn state (print "empty task-func")))
-(def give-focus 0)
+(def task-func (fn task-obj task-state (print "empty task-func")))
+
+(def paint-task (fn (t task) (do
+  (if (sget t redrawn)
+    (do
+      (let task-surf (sget t surface))
+      (blit fb task-surf)
+      (let x (- (sget task-surf x) 1))
+      (let y (- (sget task-surf y) 1))
+      (let w (+ (sget task-surf width) 2))
+      (let h (+ (sget task-surf height) 2))
+      (box fb x y (+ x w) (+ y h) 0)
+      (box fb x (- y 20) (+ x w) y 0)
+      (blit-str fb unifont (sget t name) (+ x 2) (- y 18))
+      (sput t redrawn 0))
+    0)
+  0
+)))
+
+(def check-task-focus (fn (t task) (do
+  (let surf  (sget t surface))
+  (let x (sget surf x))
+  (let y (sget surf y))
+  (let x2 (+ x (sget surf width)))
+  (let y2 (+ y (sget surf height)))
+
+  (let dbg "            ")
+  (write mouse-btn dbg)
+  (blit-str fb unifont dbg 0 0)
+
+  (sput t focused 0)
+  (if (gt mouse-x x)
+    (if (gt mouse-y y)
+      (if (lt mouse-x x2)
+        (if (lt mouse-y y2)
+          (do
+            (sput t focused 1)
+            (if mouse-dragging (do
+              (boxfill fb (- x 2) (- y 22) (+ (- x2 x) 4) (+ (- y2 y) 24) 0xffff)
+              (if (lt mouse-y (- y2 16))
+                (do ; move
+                  (sput surf x (+ mouse-dx x))
+                  (sput surf y (+ mouse-dy y)))
+                (do ; resize
+                  (let nw (+ (sget surf width) mouse-dx))
+                  (let nh (+ (sget surf height) mouse-dy))
+                  (sput surf width nw)
+                  (sput surf height nh)
+                  (sput surf pitch (* 2 nw))
+                  (sput surf pixels (alloc (* 2 (* nw nh))))
+                  ))
+              (sput t redrawn 1)
+            ) 0)
+          ) 0) 0) 0) 0)
+  0
+)))
 
 (def run-tasks (fn (do
   (let tl tasks)
@@ -47,28 +118,19 @@
   (let i 0)
   
   (while (car tl) (do
-    (def task-func (car (car tl)))
-    (let task-state (cdr (car tl)))
-    (let had-focus (car task-state))
-    (let had-focus (or had-focus give-focus))
-    (let task-state (cons had-focus (cdr task-state)))
-    (let new-state (task-func task-state))
-    (def give-focus (and had-focus (not (car new-state))))
-    (if give-focus
-      (print (list "task yields focus " i)) 0)
-    (let tl (cdr tl))
-    (let new-tl (cons (cons task-func new-state) new-tl))
-    (let i (+ i 1))
-  ))
+    (let task-item  (car tl))
+    (def task-func  (car task-item))
+    (let task-obj   (car (cdr task-item)))
+    (let task-state (car (cdr (cdr task-item))))
 
-  ; spawn new tasks
-  (let tl new-tasks)
-  (while (car tl) (do
-    (let new-tl (cons (car tl) new-tl))
+    (check-task-focus task-obj)
+
+    (task-func task-obj task-state)
+    (paint-task task-obj)
+    
+    (let i (+ i 1))
     (let tl (cdr tl))
   ))
-  (def new-tasks (list))
-  (def tasks (reverse new-tl))
 )))
 
 ;(def zz (fn (import "/sd/tests/gtn.l")))
@@ -79,15 +141,35 @@
 ;(import "/sd/os/repl.l")
 (import "/sd/os/editor.l")
 
+(def make-surface (fn x y w h (do
+  (let surf (new surface))
+  (sput surf pixels (alloc (* 2 (* w h))))
+  (sput surf x x)
+  (sput surf y y)
+  (sput surf width w)
+  (sput surf height h)
+  (sput surf pitch (shl w 1))
+  surf
+)))
+
 ;(add-task repl-task (repl-make 1 432 32 200 300))
-(add-task editor-task (list 1 (new editor)))
-;(def ed2 (new editor))
-;(sput ed2 win-y 300)
-;(add-task editor-task (list 0 ed2))
-
-;(def newshell (fn x y 
-;  (add-task repl-task (repl-make 0 x y 400 100))
-;))
+
+(def spawn-editor (fn x y title focused (do
+  (let my-editor (new editor))
+  (let my-editor-task (new task))
+  (sput my-editor-task name title)
+  (sput my-editor buffer " ")
+  (sput my-editor-task focused focused)
+  (sput my-editor-task surface (make-surface x y 400 240))
+  (add-task editor-task my-editor-task my-editor)
+)))
+
+(spawn-editor 32 32 "editor               " 0)
+(spawn-editor 32 300 "editor               " 1)
+
+(def mouse-task (new task))
+(sput mouse-task name "mouse")
+(add-task mouse-func mouse-task 0)
 
 (def main (fn (while 1 (do
   (run-tasks)