summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-03-08 16:46:22 -0500
committerBenji Dial <benji6283@gmail.com>2021-03-08 16:46:22 -0500
commit920f1f010284d59bad86f78355ed90ac2f3e1d2c (patch)
tree19e2abcf6f546e251151582c700cfce312224eb1
parentaf52ddac750311ace3bd997245771b26119e1659 (diff)
downloadportland-os-920f1f010284d59bad86f78355ed90ac2f3e1d2c.tar.gz
mouse movement in raleigh, with colorpicker dragging example
-rw-r--r--doc/ints.txt1
-rw-r--r--src/kernel/idt.c3
-rw-r--r--src/kernel/isrs.asm2
-rw-r--r--src/kernel/window.c16
-rw-r--r--src/kernel/window.h2
-rw-r--r--src/shared/include/winact.h9
-rw-r--r--src/user/include/cxx/raleigh/w/button.h1
-rw-r--r--src/user/include/cxx/raleigh/w/colorpicker.h3
-rw-r--r--src/user/include/cxx/raleigh/w/padding.h1
-rw-r--r--src/user/include/cxx/raleigh/w/vbox.h1
-rw-r--r--src/user/include/cxx/raleigh/widget.h1
-rw-r--r--src/user/include/pland/syscall.h7
-rw-r--r--src/user/raleigh/w/button.cpp8
-rw-r--r--src/user/raleigh/w/colorpicker.cpp46
-rw-r--r--src/user/raleigh/w/padding.cpp8
-rw-r--r--src/user/raleigh/w/vbox.cpp11
-rw-r--r--src/user/raleigh/widget.cpp1
-rw-r--r--src/user/raleigh/window.cpp3
18 files changed, 117 insertions, 7 deletions
diff --git a/doc/ints.txt b/doc/ints.txt
index a2625ae..eed79fa 100644
--- a/doc/ints.txt
+++ b/doc/ints.txt
@@ -61,6 +61,7 @@ table 1:
get timestamp | 0x19 | secs since 2000 | | | | |
file write | 0x1a | written | handle | file offset | count | buffer |
set file size | 0x1b | | handle | new file size | | |
+ want mouse moves | 0x1c | | window handle | | | |
table 2:
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
index f07ef1d..8de5448 100644
--- a/src/kernel/idt.c
+++ b/src/kernel/idt.c
@@ -208,7 +208,8 @@ void const *syscall_table[] = {
&sc_is_task_running,
&sc_get_timestamp,
&sc_file_write,
- &sc_file_set_size
+ &sc_file_set_size,
+ &window_wants_mouse_movements
};
//these aren't really void ()'s, but gcc complains if we take an address of a void, so we give it a type
diff --git a/src/kernel/isrs.asm b/src/kernel/isrs.asm
index 70bab19..673e891 100644
--- a/src/kernel/isrs.asm
+++ b/src/kernel/isrs.asm
@@ -26,7 +26,7 @@ extern exception_halt
extern pf_check_stack
extern dump
-n_syscalls equ 0x1c
+n_syscalls equ 0x1d
;section .bss
;_debug_is_start_task resb 1
diff --git a/src/kernel/window.c b/src/kernel/window.c
index b1d5f92..4b01bc4 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -38,6 +38,7 @@ static struct window {
struct window *below;
struct task_state *from_task;
+ bool wants_mouse_movements;
} windows[MAX_WINDOWS];
static struct window *bottom_window = 0;
@@ -322,6 +323,7 @@ got_window:
send_action(top_window, (struct window_action){.action_type = FOCUS_ENTER});
w->from_task = active_task;
+ w->wants_mouse_movements = false;
paint_and_above(w);
return w;
@@ -544,6 +546,16 @@ void move_mouse_by(int16_t y, int16_t x) {
blit(old_x, old_x + MOUSE_WIDTH > VBE_MODE_INFO->width ? VBE_MODE_INFO->width : old_x + MOUSE_WIDTH,
old_y, old_y + MOUSE_HEIGHT > VBE_MODE_INFO->height ? VBE_MODE_INFO->height : old_y + MOUSE_HEIGHT);
blit_mouse();
+ struct window *const moving_over = buffer[mouse_y * VBE_MODE_INFO->width + mouse_x].from_window;
+ if (moving_over && moving_over->wants_mouse_movements &&
+ (mouse_y >= moving_over->ypos) && (mouse_y < moving_over->ypos + moving_over->height) &&
+ (mouse_x >= moving_over->xpos) && (mouse_x < moving_over->xpos + moving_over->width))
+ send_action(moving_over, (struct window_action){
+ .action_type = MOUSE_MOVE, .moved_to = {
+ .x = mouse_x - moving_over->xpos,
+ .y = mouse_y - moving_over->ypos
+ }
+ });
}
switch_to_task_cr3();
//logf(LOG_INFO, "new mouse coords: (%d, %d)", mouse_x, mouse_y);
@@ -628,4 +640,8 @@ void mouse_button(enum mouse_button which, bool up) {
}
send_action(clicked_on, (struct window_action){.action_type = up ? MOUSE_UP : MOUSE_DOWN, .as_mouse = {.y = mouse_y - clicked_on->ypos, .x = mouse_x - clicked_on->xpos, .which = which}});
}
+}
+
+void window_wants_mouse_movements(struct window *w) {
+ w->wants_mouse_movements = true;
} \ No newline at end of file
diff --git a/src/kernel/window.h b/src/kernel/window.h
index a1f9716..a1d6be3 100644
--- a/src/kernel/window.h
+++ b/src/kernel/window.h
@@ -36,4 +36,6 @@ void show_shutdown();
void move_mouse_by(int16_t y, int16_t x);
void mouse_button(enum mouse_button which, bool up);
+void window_wants_mouse_movements(struct window *w);
+
#endif
diff --git a/src/shared/include/winact.h b/src/shared/include/winact.h
index 9486efc..13e07f5 100644
--- a/src/shared/include/winact.h
+++ b/src/shared/include/winact.h
@@ -7,7 +7,7 @@ struct mouse_packet {
uint16_t y;
uint16_t x;
enum mouse_button {LEFT, RIGHT, MIDDLE} which;
-};
+} __attribute__ ((__packed__));
struct window_action {
enum {
@@ -17,11 +17,16 @@ struct window_action {
FOCUS_ENTER,
FOCUS_LEAVE,
MOUSE_DOWN,
- MOUSE_UP
+ MOUSE_UP,
+ MOUSE_MOVE
} action_type;
union {
struct key_packet as_key;
struct mouse_packet as_mouse;
+ struct {
+ uint32_t y;
+ uint32_t x;
+ } moved_to;
};
} __attribute__ ((__packed__));
diff --git a/src/user/include/cxx/raleigh/w/button.h b/src/user/include/cxx/raleigh/w/button.h
index 71ccae2..0e40f81 100644
--- a/src/user/include/cxx/raleigh/w/button.h
+++ b/src/user/include/cxx/raleigh/w/button.h
@@ -14,6 +14,7 @@ namespace raleigh {
void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override;
void notify_child_size_change(widget &child, coord old_size) override;
void notify_has_opaque_parent(widget *parent) override;
+ void on_mouse_move(coord window_coords) override;
private:
widget &inner;
void (*on_click)(button &);
diff --git a/src/user/include/cxx/raleigh/w/colorpicker.h b/src/user/include/cxx/raleigh/w/colorpicker.h
index c33288e..a282c9e 100644
--- a/src/user/include/cxx/raleigh/w/colorpicker.h
+++ b/src/user/include/cxx/raleigh/w/colorpicker.h
@@ -12,11 +12,14 @@ namespace raleigh {
void paint(_pixel_t *pixbuf, uint32_t pitch) override;
void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override;
void notify_has_opaque_parent(widget *parent) override;
+ void on_mouse_move(coord window_coords) override;
private:
_pixel_t picked_color;
uint8_t resolution;
uint8_t inv_res;
+
+ enum {NO, R, G, B} selected;
};
}
diff --git a/src/user/include/cxx/raleigh/w/padding.h b/src/user/include/cxx/raleigh/w/padding.h
index 1bdb9ee..ab732f1 100644
--- a/src/user/include/cxx/raleigh/w/padding.h
+++ b/src/user/include/cxx/raleigh/w/padding.h
@@ -13,6 +13,7 @@ namespace raleigh {
void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override;
void notify_has_opaque_parent(widget *parent) override;
void notify_child_size_change(widget &child, coord old_size) override;
+ void on_mouse_move(coord window_coords) override;
private:
widget &inner;
uint32_t pad_by;
diff --git a/src/user/include/cxx/raleigh/w/vbox.h b/src/user/include/cxx/raleigh/w/vbox.h
index f715f95..39f89e9 100644
--- a/src/user/include/cxx/raleigh/w/vbox.h
+++ b/src/user/include/cxx/raleigh/w/vbox.h
@@ -15,6 +15,7 @@ namespace raleigh {
void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override;
void notify_has_opaque_parent(widget *parent) override;
void notify_child_size_change(widget &from, coord old_size) override;
+ void on_mouse_move(coord window_coords) override;
private:
dllist<widget &> widgets;
};
diff --git a/src/user/include/cxx/raleigh/widget.h b/src/user/include/cxx/raleigh/widget.h
index 1b2cf6f..d499ed4 100644
--- a/src/user/include/cxx/raleigh/widget.h
+++ b/src/user/include/cxx/raleigh/widget.h
@@ -36,6 +36,7 @@ namespace raleigh {
virtual void handle_key(struct key_packet kp);
virtual void on_focus();
virtual void on_unfocus();
+ virtual void on_mouse_move(coord window_coords);
//this next one is not to be called by child widgets
//they should call window::notify_widget_size_change(widget &), which will call this if necessary
virtual void notify_child_size_change(widget &child, coord old_size);
diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h
index d7dfd77..1e040f4 100644
--- a/src/user/include/pland/syscall.h
+++ b/src/user/include/pland/syscall.h
@@ -57,7 +57,8 @@ enum _scn {
_SCN_IS_TASK_RUNNING,
_SCN_GET_TIMESTAMP,
_SCN_FILE_WRITE,
- _SCN_SET_FILE_SIZE
+ _SCN_SET_FILE_SIZE,
+ _SCN_WANTS_MOUSE_MOVES
};
static inline uint32_t _sc0(enum _scn eax) {
@@ -254,6 +255,10 @@ static inline void _set_file_size(_file_handle_t handle, uint32_t new_size) {
_sc2(_SCN_SET_FILE_SIZE, handle, new_size);
}
+static inline void _wants_mouse_moves(_window_handle_t window) {
+ _sc1(_SCN_WANTS_MOUSE_MOVES, (uint32_t)window);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/user/raleigh/w/button.cpp b/src/user/raleigh/w/button.cpp
index 2abf9a9..224b930 100644
--- a/src/user/raleigh/w/button.cpp
+++ b/src/user/raleigh/w/button.cpp
@@ -55,4 +55,12 @@ namespace raleigh {
}
void button::notify_has_opaque_parent(widget *parent) {}
+
+ void button::on_mouse_move(coord window_coords) {
+ if ((window_coords.x >= inner.window_offset.x) &&
+ (window_coords.y >= inner.window_offset.y) &&
+ (window_coords.x < inner.window_offset.x + inner.size.x) &&
+ (window_coords.y < inner.window_offset.y + inner.size.y))
+ inner.on_mouse_move(window_coords);
+ }
} \ No newline at end of file
diff --git a/src/user/raleigh/w/colorpicker.cpp b/src/user/raleigh/w/colorpicker.cpp
index faa720e..4ccd0ce 100644
--- a/src/user/raleigh/w/colorpicker.cpp
+++ b/src/user/raleigh/w/colorpicker.cpp
@@ -2,7 +2,8 @@
namespace raleigh {
colorpicker::colorpicker(_pixel_t default_color, uint8_t resolution)
- : picked_color(default_color), resolution(resolution), inv_res(256 / resolution) {
+ : picked_color(default_color), resolution(resolution),
+ inv_res(256 / resolution), selected(NO) {
size = coord(inv_res * 2, inv_res * 2);
closest_opaque = this;
}
@@ -32,19 +33,26 @@ namespace raleigh {
}
void colorpicker::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) {
- if (up || (click_type != mouse_packet::LEFT))
+ if (click_type != mouse_packet::LEFT)
return;
+ if (up) {
+ selected = NO;
+ return;
+ }
window_coords.x -= window_offset.x;
window_coords.y -= window_offset.y;
if ((window_coords.x < inv_res) && (window_coords.y < inv_res)) {
+ selected = R;
picked_color.g = window_coords.x * resolution;
picked_color.b = window_coords.y * resolution;
}
else if (window_coords.y < inv_res) {
+ selected = G;
picked_color.b = (window_coords.x - inv_res) * resolution;
picked_color.r = window_coords.y * resolution;
}
else if (window_coords.x < inv_res) {
+ selected = B;
picked_color.r = window_coords.x * resolution;
picked_color.g = (window_coords.y - inv_res) * resolution;
}
@@ -52,4 +60,38 @@ namespace raleigh {
}
void colorpicker::notify_has_opaque_parent(widget *parent) {}
+
+ void colorpicker::on_mouse_move(coord window_coords) {
+ uint32_t x = window_coords.x - window_offset.x;
+ uint32_t y = window_coords.y - window_offset.y;
+ switch (selected) {
+ case NO:
+ return;
+ case R:
+ if (x >= inv_res)
+ x = inv_res - 1;
+ if (y >= inv_res)
+ y = inv_res - 1;
+ picked_color.g = x * resolution;
+ picked_color.b = y * resolution;
+ break;
+ case G:
+ if (x < inv_res)
+ x = inv_res;
+ if (y >= inv_res)
+ y = inv_res - 1;
+ picked_color.b = x * resolution;
+ picked_color.r = y * resolution;
+ break;
+ case B:
+ if (x >= inv_res)
+ x = inv_res - 1;
+ if (y < inv_res)
+ y = inv_res;
+ picked_color.r = x * resolution;
+ picked_color.g = y * resolution;
+ break;
+ }
+ w->notify_needs_paint(*this);
+ }
} \ No newline at end of file
diff --git a/src/user/raleigh/w/padding.cpp b/src/user/raleigh/w/padding.cpp
index c1f7b85..782a8a9 100644
--- a/src/user/raleigh/w/padding.cpp
+++ b/src/user/raleigh/w/padding.cpp
@@ -34,4 +34,12 @@ namespace raleigh {
void padding::notify_child_size_change(widget &child, coord old_size) {
set_size(coord(inner.size.x + pad_by * 2, inner.size.y + pad_by * 2));
}
+
+ void padding::on_mouse_move(coord window_coords) {
+ if ((window_coords.x >= inner.window_offset.x) &&
+ (window_coords.y >= inner.window_offset.y) &&
+ (window_coords.x < inner.window_offset.x + inner.size.x) &&
+ (window_coords.y < inner.window_offset.y + inner.size.y))
+ inner.on_mouse_move(window_coords);
+ }
} \ No newline at end of file
diff --git a/src/user/raleigh/w/vbox.cpp b/src/user/raleigh/w/vbox.cpp
index 263da2a..77ce592 100644
--- a/src/user/raleigh/w/vbox.cpp
+++ b/src/user/raleigh/w/vbox.cpp
@@ -63,4 +63,15 @@ namespace raleigh {
notify_window_change();
}
}
+
+ void vbox::on_mouse_move(coord window_coords) {
+ for (dllist<widget &>::node *n = widgets.first; n; n = n->next)
+ if ((window_coords.x >= n->d.window_offset.x) &&
+ (window_coords.y >= n->d.window_offset.y) &&
+ (window_coords.x < n->d.window_offset.x + n->d.size.x) &&
+ (window_coords.y < n->d.window_offset.y + n->d.size.y)) {
+ n->d.on_mouse_move(window_coords);
+ return;
+ }
+ }
} \ No newline at end of file
diff --git a/src/user/raleigh/widget.cpp b/src/user/raleigh/widget.cpp
index 719cc06..0a47c3b 100644
--- a/src/user/raleigh/widget.cpp
+++ b/src/user/raleigh/widget.cpp
@@ -11,6 +11,7 @@ namespace raleigh {
void widget::handle_key(struct key_packet kp) {}
void widget::on_focus() {}
void widget::on_unfocus() {}
+ void widget::on_mouse_move(coord window_coords) {}
void widget::notify_child_size_change(widget &child, coord old_size) {}
void widget::set_size(coord new_size) {
diff --git a/src/user/raleigh/window.cpp b/src/user/raleigh/window.cpp
index 5d1a3de..cb9f363 100644
--- a/src/user/raleigh/window.cpp
+++ b/src/user/raleigh/window.cpp
@@ -57,6 +57,8 @@ namespace raleigh {
focussed->on_focus();
else if (wa.action_type == wa.FOCUS_LEAVE)
focussed->on_unfocus();
+ else if (wa.action_type == wa.MOUSE_MOVE)
+ root.on_mouse_move(coord(wa.moved_to.x, wa.moved_to.y));
}
}
@@ -78,6 +80,7 @@ namespace raleigh {
if (handle)
return;
handle = _new_window(size.x, size.y, pixbuf);
+ _wants_mouse_moves(handle);
if (!handle)
show_error_and_quitf("Failed to get window handle for requested window.");
open_windows.add_front(*this);