void view_teardown(View* view) { if (!view) return; for (int i = 0; i < view->subviews->size; i++) { View* view = (View*)array_m_lookup(view->subviews, i); view_teardown(view); Label* label = (Label*)array_m_lookup(view->labels, i); label_teardown(label); Bmp* bmp = (Bmp*)array_m_lookup(view->bmps, i); bmp_teardown(bmp); } //free subviews array array_m_destroy(view->subviews); //free sublabels array_m_destroy(view->labels); //free bmps array_m_destroy(view->bmps); //free backing layer layer_teardown(view->layer); //finally, free view itself kfree(view); }
Window* containing_window(View* v) { //find root window View* view = v; while (view->superview) { view = view->superview; } Screen* screen = gfx_screen(); if (screen->window->title_view == view || screen->window->content_view == view) { return screen->window; } //traverse view hierarchy, find window which has view as its title or content view for (int32_t i = 0; i < screen->window->subviews->size; i++) { Window* window = (Window*)array_m_lookup(screen->window->subviews, i); //if user passed a Window, check against that if (window == (Window*)view) return window; if (window->title_view == view || window->content_view == view) return window; for (int32_t j = 0; j < window->subviews->size; j++) { Window* subwindow = (Window*)array_m_lookup(window->subviews, j); if (subwindow->title_view == view || subwindow->content_view == view) return subwindow; } } return screen->window; }
void test_xserv(Screen* vesa_screen) { Window* window = create_window(rect_make(point_make(50, 50), size_make(400, 500))); window->title = "Color test"; add_subwindow(vesa_screen->window, window); Window* label_win = create_window(rect_make(point_make(350, 100), size_make(500, 200))); label_win->title = "Text test"; Label* test_label = create_label(rect_make(point_make(0, 0), label_win->content_view->frame.size), "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque pulvinar dui bibendum nunc convallis, bibendum venenatis mauris ornare. Donec et libero lacus. Nulla tristique auctor pulvinar. Aenean enim elit, malesuada nec dignissim eget, varius ac nunc. Vestibulum varius lectus nisi, in dignissim orci volutpat in. Aliquam eget eros lorem. Quisque tempor est a rhoncus consequat. Quisque vestibulum finibus sapien. Etiam enim sem, vehicula ac lorem vitae, mattis mollis mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eleifend dui vel nulla suscipit pretium. Suspendisse vel nunc efficitur, lobortis dui convallis, tristique tellus. Ut ut viverra est. Etiam tempor justo risus. Cras laoreet eu sapien et lacinia. Nunc imperdiet blandit purus a semper."); add_sublabel(label_win->content_view, test_label); add_subwindow(vesa_screen->window, label_win); //create evenly spaced subsections for (int i = 0; i < 34; i++) { double height = window->content_view->frame.size.height / 32; View* view = create_view(rect_make(point_make(0, height * i), size_make(window->content_view->frame.size.width, height))); add_subview(window->content_view, view); } for (int i = 0; i < 1000; i++) { for (int j = 0; j < window->content_view->subviews->size; j++) { View* subview = array_m_lookup(window->content_view->subviews, j); set_background_color(subview, color_make(rand() % 256, rand() % 256, rand() % 256)); } sleep(50); } }
void draw_view(View* view) { if (!view) return; //inform subviews that we're being redrawn //dirtied = 1; //fill view with its background color draw_rect(view->layer, rect_make(point_zero(), view->frame.size), view->background_color, THICKNESS_FILLED); //draw any bmps this view has for (int i = 0; i < view->bmps->size; i++) { Bmp* bmp = (Bmp*)array_m_lookup(view->bmps, i); if (bmp) { draw_bmp(view->layer, bmp); } } //draw any labels this view has for (int i = 0; i < view->labels->size; i++) { Label* label = (Label*)array_m_lookup(view->labels, i); draw_label(view->layer, label); } //draw buttons for (int i = 0; i < view->buttons->size; i++) { Button* button = (Button*)array_m_lookup(view->buttons, i); if (button) { draw_button(view->layer, button); } } //draw each subview of this view for (int i = 0; i < view->subviews->size; i++) { View* subview = (View*)array_m_lookup(view->subviews, i); draw_view(subview); blit_layer(view->layer, subview->layer, rect_make(subview->frame.origin, subview->layer->size), rect_make(point_zero(), subview->layer->size)); } view->needs_redraw = 0; }
void dequeue_task(task_small_t* task) { lock(mutex); if (task->queue < 0 || task->queue >= queues->size) { ASSERT(0, "Tried to remove %s from invalid queue %d", task->name, task->queue); } array_m* raw = array_m_lookup(queues, task->queue); int idx = array_m_index(raw, task); if (idx < 0) { printf_err("Tried to dequeue %s from queue %d it didn't belong to!", task->name, task->queue); //fall back on searching all queues for this task for (int i = 0; i < queues->size; i++) { array_m* queue = array_m_lookup(queues, i); for (int j = 0; j < queue->size; j++) { task_t* tmp = array_m_lookup(queue, j); if (task == tmp) { //found task we were looking for printf_info("Task was actually in queue %d", i); array_m_remove(queue, j); unlock(mutex); return; } } } //never found the task! printf_err("Task %s did not exist in any queues!", task->name); return; } array_m_remove(raw, idx); unlock(mutex); //if for some reason this task is still in the queue (if it was added to queue twice), //dequeue it again if (array_m_index(raw, task) != ARR_NOT_FOUND) { dequeue_task(task); } }
void reap_task(task_t* tmp) { Deprecated(); if (tmp->state == ZOMBIE) { array_m* queue = array_m_lookup(queues, tmp->queue); int idx = array_m_index(queue, tmp); if (idx != ARR_NOT_FOUND) { printk("reap() unlisting %s\n", tmp->name); lock(mutex); array_m_remove(queue, idx); unlock(mutex); destroy_task(tmp); } else { //couldn't find task in the queue it said it was in //fall back on searching through each queue bool found = false; for (int i = 0; i < queues->size && !found; i++) { array_m* queue = array_m_lookup(queues, i); for (int j = 0; j < queues->size && !found; j++) { task_t* to_test = array_m_lookup(queue, j); if (to_test == tmp) { lock(mutex); array_m_remove(queue, j); unlock(mutex); destroy_task(tmp); found = true; break; } } } if (!found) { printf_err("Tried to reap task %s[%d] but it didn't exist in a queue", tmp->name, tmp->id); } } } }
void window_teardown(Window* window) { if (!window) return; for (int i = 0; i < window->subviews->size; i++) { Window* window = (Window*)array_m_lookup(window->subviews, i); window_teardown(window); } //free subviews array array_m_destroy(window->subviews); //free the views associated with this window view_teardown(window->title_view); view_teardown(window->content_view); //free backing layer layer_teardown(window->layer); //finally, free window itself kfree(window); }
void enqueue_task(task_small_t* task, int queue) { lock(mutex); if (queue < 0 || queue >= queues->size) { ASSERT(0, "Tried to insert %s into invalid queue %d", task->name, queue); } array_m* raw = array_m_lookup(queues, queue); //ensure task does not already exist in this queue if (array_m_index(raw, task) == ARR_NOT_FOUND) { lock(mutex); array_m_insert(raw, task); unlock(mutex); task->queue = queue; //new queue, reset lifespan task->lifespan = 0; } else { printf_err("Tried to enqueue %s onto queue where it already existed (%d)", task->name, queue); } unlock(mutex); }
bool draw_window(Window* window) { if (window->user_backed) { return true; } //blit_layer(window->layer, window->content_view->layer, rect_make(window->content_view->frame.origin, window->layer->size), rect_make(point_zero(), window->content_view->frame.size)); //return; //if window is invisible, don't bother drawing if (!window->layer->alpha) return false; //if window has a redraw handler, call it if (window->redraw_handler) { //draw_rect(window->content_view->layer, rect_make(point_zero(), window->content_view->frame.size), window->content_view->background_color, THICKNESS_FILLED); event_handler redraw = window->redraw_handler; redraw(window, NULL); blit_layer(window->layer, window->content_view->layer, rect_make(window->content_view->frame.origin, window->layer->size), rect_make(point_zero(), window->content_view->frame.size)); window->last_draw_timestamp = time(); return true; } //if window doesn't need to be redrawn, no work to do if (window->layer->alpha == 1.0 && !window->needs_redraw) { return false; } //dirtied = 1; //paint window draw_rect(window->layer, rect_make(point_zero(), window->frame.size), window->border_color, window->border_width); //only draw a title bar if title_view exists if (window->title_view) { //update title label of window Label* title_label = (Label*)array_m_lookup(window->title_view->labels, 0); title_label->text = window->title; draw_view(window->title_view); blit_layer(window->layer, window->title_view->layer, rect_make(point_zero(), window->layer->size), window->title_view->frame); draw_rect(window->layer, window->title_view->frame, color_gray(), 2); } //only draw the content view if content_view exists if (window->content_view) { draw_view(window->content_view); //if there's a redraw callback, call it if (window->redraw_handler) { event_handler redraw = window->redraw_handler; redraw(window, NULL); } blit_layer(window->layer, window->content_view->layer, rect_make(window->content_view->frame.origin, window->layer->size), rect_make(point_zero(), window->content_view->frame.size)); //draw dividing border between window border and other content if (window->border_width) { //inner border draw_rect(window->content_view->layer, rect_make(point_zero(), window->content_view->frame.size), color_gray(), window->border_width); } } //draw window border draw_rect(window->layer, rect_make(point_zero(), window->frame.size), color_black(), 1); window->needs_redraw = 0; window->last_draw_timestamp = time(); return true; }