From a7a5824cfedfa2a9f81b2206bf24cc28cb6640cc Mon Sep 17 00:00:00 2001 From: ashmew2 Date: Mon, 11 Apr 2016 13:38:48 +0000 Subject: [PATCH] Add C Layer to SVN git-svn-id: svn://kolibrios.org@6391 a494cfbc-eb01-0410-851d-a64ba20cac60 --- contrib/C_Layer/README | 16 +++ contrib/C_Layer/libguic_kolibri/README | 57 ++++++++ contrib/C_Layer/libguic_kolibri/boardmsg.c | 57 ++++++++ .../C_Layer/libguic_kolibri/kolibri_boxlib.h | 18 +++ .../C_Layer/libguic_kolibri/kolibri_button.h | 46 ++++++ .../libguic_kolibri/kolibri_checkbox.h | 43 ++++++ .../C_Layer/libguic_kolibri/kolibri_colors.h | 28 ++++ .../C_Layer/libguic_kolibri/kolibri_debug.h | 20 +++ .../C_Layer/libguic_kolibri/kolibri_editbox.h | 90 ++++++++++++ contrib/C_Layer/libguic_kolibri/kolibri_gui.h | 129 +++++++++++++++++ .../libguic_kolibri/kolibri_gui_elements.h | 126 ++++++++++++++++ contrib/C_Layer/libguic_kolibri/kolwin.c | 57 ++++++++ .../C_Layer/libguic_kolibri/loadboxlib.asm | 135 ++++++++++++++++++ contrib/C_Layer/libguic_kolibri/quirks | 6 + 14 files changed, 828 insertions(+) create mode 100644 contrib/C_Layer/README create mode 100644 contrib/C_Layer/libguic_kolibri/README create mode 100644 contrib/C_Layer/libguic_kolibri/boardmsg.c create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_boxlib.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_button.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_checkbox.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_colors.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_debug.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_editbox.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_gui.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolibri_gui_elements.h create mode 100644 contrib/C_Layer/libguic_kolibri/kolwin.c create mode 100644 contrib/C_Layer/libguic_kolibri/loadboxlib.asm create mode 100644 contrib/C_Layer/libguic_kolibri/quirks diff --git a/contrib/C_Layer/README b/contrib/C_Layer/README new file mode 100644 index 0000000000..51423e47d2 --- /dev/null +++ b/contrib/C_Layer/README @@ -0,0 +1,16 @@ +This is the C Layer for KolibriOS. + +Along with the C Library we have, this will serve as the backbone to easily use libraries aand programs available in C. +This is also useful for porting. +Also useful for new developers who don't know assembly but know C. + +And the beauty is, this is NOT a reimplementation of assembly libraries in C. +It is only a wrapper on top of C. + +As all new things, this will have issues and bugs! +Please fix it. +Please let the other developers know what's wrong and how to fix it. +If you can, fix it yourself! + +- ashmew2 +2016-04-11 \ No newline at end of file diff --git a/contrib/C_Layer/libguic_kolibri/README b/contrib/C_Layer/libguic_kolibri/README new file mode 100644 index 0000000000..d53558b248 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/README @@ -0,0 +1,57 @@ +Welcome to the README for GUI LIBRARY FOR KOLIBRIOS IN C. + +This library tries to use the wealth of code already written for KolibriOS in assembly. + +The files currently available are : + +0) loadboxlib.asm : + This is a wrapper created so that C can call assembly functions. + Assemble this to loadboxlib.obj and use with cross compiler linker the .obj file + to create correct executables which use this GUI library. + +1) kolibri_boxlib.h : + This file contains functions for initializing boxlib from C. This is used by the + function kolibri_gui_init() in kolibri_gui.h + +2)kolibri_button.h: + This file contains functions to create and use kolibriOS buttons. + +3)kolibri_checkbox.h: + This file contains functions to create and use Check boxes from BOXLIB. + +4)kolibri_editbox.h: + This file contains functions for creating text boxes (edit boxes from Boxlib) + +5)kolibri_colors.h: + This file has functions to initialize global kolibri color table + so that the GUI can use colors from the System theme. + +6)kolibri_gui_elements.h: + This defines generic containers for GUI elements so that ANY element + (buttons, editboxes, checkboxes, etc) can have their redraw/mouse/key event + functions. This helps create a list of all the elements and draw them together. + +ALL FILES ABOVE ARE INCLUDED IN KOLIBRI_GUI.H SO THEY DO NOT NEED TO BE INCLUDED IN THE CODE YOU WRITE. + +7)kolibri_gui.h: + This is the master file we use. This baby contains everything you need (all GUI elements are included). + This also contains event handlers that can be simply called from the main application loop. + This will make your life easy on KolibriOS ;) USE IT! + The function kolibri_gui_init() needs to be called from all applications using this library. + +8)boardmsg.c: + Sample application written to show off the library. + This application sends messages to Debug Board on KolibriOS. + Enter a msg and press the button with the mouse to send messages! + This is the first of many applications to come with this library. + +--- +NOTES + +Refer to boardmsg.c to see how the library is used. +Use instructions from here to build files in C : http://board.kolibrios.org/viewtopic.php?f=24&t=3117 + +--- +Suggestions, Feedback and Ideas are welcome and appreciated! +Please contact : ashmew2 (on board.kolibrios.org) or ashmew2 at gmail dot com for discussing, +Or post on : http://board.kolibrios.org/viewtopic.php?f=24&t=3117#p62536 so that everyone can participate! diff --git a/contrib/C_Layer/libguic_kolibri/boardmsg.c b/contrib/C_Layer/libguic_kolibri/boardmsg.c new file mode 100644 index 0000000000..57d74b4795 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/boardmsg.c @@ -0,0 +1,57 @@ +#include "kolibri_gui.h" + +int main() +{ + /* Load all libraries, initialize global tables like system color table and + operations table. kolibri_gui_init() will EXIT with mcall -1 if it fails + to do it's job. This is all you need to call and all libraries and GUI + elements can be used after a successful call to this function + */ + kolibri_gui_init(); + + /* Set gui_event to REDRAW so that window is drawn in first iteration */ + unsigned int gui_event = KOLIBRI_EVENT_REDRAW; + + struct kolibri_window *main_window = kolibri_new_window(50, 50, 400, 100, "BoardMsg: Send msg to debug board"); + struct check_box *checkbox = kolibri_new_check_box(20, 40, 12, 12, "Append BOARDMSG to entered message."); + struct edit_box *textbox = kolibri_new_edit_box(20, 55, 40); + struct kolibri_button *button = kolibri_new_button(310, 55, 14, 14, 0x00123456, kolibri_color_table.color_work_button); + + kolibri_window_add_element(main_window, KOLIBRI_EDIT_BOX, textbox); + kolibri_window_add_element(main_window, KOLIBRI_CHECK_BOX, checkbox); + kolibri_window_add_element(main_window, KOLIBRI_BUTTON, button); + + do /* Start of main activity loop */ + { + if(gui_event == KOLIBRI_EVENT_REDRAW) + { + kolibri_handle_event_redraw(main_window); + } + else if(gui_event == KOLIBRI_EVENT_KEY) + { + kolibri_handle_event_key(main_window); + } + else if(gui_event == KOLIBRI_EVENT_BUTTON) + { + unsigned int pressed_button = kolibri_button_get_identifier(); + + if(pressed_button = 0x00123456) /* Our button was pressed */ + { + if(checkbox -> flags & CHECKBOX_IS_SET) /* Append BoardMsg checkbox is set */ + debug_board_write_str("BOARDMSG: "); + + debug_board_write_str(textbox->text); + debug_board_write_str("\n"); + } + } + else if(gui_event == KOLIBRI_EVENT_MOUSE) + { + kolibri_handle_event_mouse(main_window); + } + + } while(gui_event = get_os_event()); /* End of main activity loop */ + + /* kolibri_quit(); */ + + return 0; +} diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_boxlib.h b/contrib/C_Layer/libguic_kolibri/kolibri_boxlib.h new file mode 100644 index 0000000000..b820788efb --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_boxlib.h @@ -0,0 +1,18 @@ +#ifndef KOLIBRI_BOXLIB_H +#define KOLIBRI_BOXLIB_H + +extern int init_boxlib_asm(void); + +int kolibri_boxlib_init(void) +{ + int asm_init_status = init_boxlib_asm(); + + /* just return asm_init_status? or return init_boxlib_asm() ?*/ + + if(asm_init_status == 0) + return 0; + else + return 1; +} + +#endif /* KOLIBRI_BOXLIB_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_button.h b/contrib/C_Layer/libguic_kolibri/kolibri_button.h new file mode 100644 index 0000000000..fa5a868201 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_button.h @@ -0,0 +1,46 @@ +#ifndef KOLIBRI_BUTTON_H +#define KOLIBRI_BUTTON_H + +struct kolibri_button { + unsigned int x65536sizex; + unsigned int y65536sizey; + unsigned int color; + unsigned int identifier; + unsigned int XY; +}; + +struct kolibri_button *kolibri_new_button(unsigned int tlx, unsigned int tly, unsigned int sizex, unsigned int sizey, + unsigned int identifier, unsigned int color) +{ + struct kolibri_button* new_button = (struct kolibri_button *)malloc(sizeof(struct kolibri_button)); + new_button -> x65536sizex = (tlx << 16) + sizex; + new_button -> y65536sizey = (tly << 16) + sizey; + new_button -> color = color; + new_button -> identifier = identifier; + new_button -> XY = 0; +} + +void draw_button(struct kolibri_button *some_button) +{ + define_button(some_button -> x65536sizex, some_button -> y65536sizey, some_button -> identifier, some_button -> color); +} + +unsigned int kolibri_button_get_identifier(void) +{ + unsigned int identifier; + + __asm__ __volatile__( + "int $0x40" + :"=a"(identifier) + :"a"(17) + ); + /* If no button pressed, returns 1 */ + /* Otherwise, returns identifier of button */ + + if(identifier != 1) /* Button was detected indeed */ + return identifier>>8; + else + return identifier; /* No button detected */ +} + +#endif /* KOLIBRI_BUTTON_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_checkbox.h b/contrib/C_Layer/libguic_kolibri/kolibri_checkbox.h new file mode 100644 index 0000000000..cc02481501 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_checkbox.h @@ -0,0 +1,43 @@ +#ifndef KOLIBRI_CHECKBOX_H +#define KOLIBRI_CHECKBOX_H + +#include "kolibri_colors.h" + +enum CHECKBOX_FLAGS { + CHECKBOX_IS_SET = 0x00000002 + /* Add more flags later */ +}; + +struct check_box { + unsigned int left_s; + unsigned int top_s; + unsigned int ch_text_margin; + unsigned int color; + unsigned int border_color; + unsigned int text_color; + char *text; + unsigned int flags; + + /* Users can use members above this */ + unsigned int size_of_str; +}; + +struct check_box* kolibri_new_check_box(unsigned int tlx, unsigned int tly, unsigned int sizex, unsigned int sizey, char *label_text) +{ + struct check_box* new_checkbox = (struct check_box *)malloc(sizeof(struct check_box)); + new_checkbox -> left_s = (tlx << 16) + sizex; + new_checkbox -> top_s = (tly << 16) + sizey; + new_checkbox -> ch_text_margin = 10; + new_checkbox -> color = 0xFFFFFFFF; + new_checkbox -> border_color = kolibri_color_table.color_work_graph; + new_checkbox -> text_color = kolibri_color_table.color_work_text; + new_checkbox -> text = label_text; + new_checkbox -> flags = 0x00000008; + + return new_checkbox; +} + +extern void (*check_box_draw2)(struct check_box *) __attribute__((__stdcall__)); +extern void (*check_box_mouse2)(struct check_box *)__attribute__((__stdcall__)); + +#endif /* KOLIBRI_CHECKBOX_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_colors.h b/contrib/C_Layer/libguic_kolibri/kolibri_colors.h new file mode 100644 index 0000000000..7a16a4024e --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_colors.h @@ -0,0 +1,28 @@ +#ifndef KOLIBRI_COLORS_H +#define KOLIBRI_COLORS_H +struct kolibri_system_colors { + unsigned int color_frame_area; + unsigned int color_grab_bar; + unsigned int color_grab_bar_button; + unsigned int color_grab_button_text; + unsigned int color_grab_text; + unsigned int color_work_area; + unsigned int color_work_button; + unsigned int color_work_button_text; + unsigned int color_work_text; + unsigned int color_work_graph; +}; + +struct kolibri_system_colors kolibri_color_table; + +void kolibri_get_system_colors(struct kolibri_system_colors *color_table) +{ + __asm__ volatile ("int $0x40" + : + :"a"(48),"b"(3),"c"(color_table),"d"(40) + ); + + /* color_table should point to the system color table */ +} + +#endif /* KOLIBRI_COLORS_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_debug.h b/contrib/C_Layer/libguic_kolibri/kolibri_debug.h new file mode 100644 index 0000000000..afab39cd32 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_debug.h @@ -0,0 +1,20 @@ +#ifndef KOLIBRI_DEBUG_H +#define KOLIBRI_DEBUG_H + +/* Write a printf() like function (variable argument list) for + writing to debug board */ + +inline void debug_board_write_byte(const char ch){ + __asm__ __volatile__( + "int $0x40" + : + :"a"(63), "b"(1), "c"(ch)); +} + +inline void debug_board_write_str(const char* str){ + while(*str) + debug_board_write_byte(*str++); +} + + +#endif /* KOLIBRI_DEBUG_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_editbox.h b/contrib/C_Layer/libguic_kolibri/kolibri_editbox.h new file mode 100644 index 0000000000..a281ad7dfe --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_editbox.h @@ -0,0 +1,90 @@ +#ifndef KOLIBRI_EDITBOX_H +#define KOLIBRI_EDITBOX_H + +#include "kolibri_colors.h" + +struct edit_box { + unsigned int width; + unsigned int left; + unsigned int top; + unsigned int color; + unsigned int shift_color; + unsigned int focus_border_color; + unsigned int blur_border_color; + unsigned int text_color; + unsigned int max; + char *text; + unsigned int mouse_variable; + unsigned int flags; + +/* The following struct members are not used by the users of API */ + unsigned int size; + unsigned int pos; + unsigned int offset; + unsigned int cl_curs_x; + unsigned int cl_curs_y; + unsigned int shift; + unsigned int shift_old; +}; + +/* Initializes an Editbox with sane settings, sufficient for most use. + This will let you create a box and position it somewhere on the screen. + The text_buffer is a pointer to a character array and needs to be as long as + AT LEAST MAX_CHARS + 1.If the text_buffer is smaller, it will crash if user + types more characters than what will fit into the text buffer. + + Allocating buffer space automatically so that programmer can be carefree now. + This also automatically adjusts the size of edit box so that it can hold enough characters. + + All you need is : + + tlx,tly = Coordinates of the beginning of the edit box. + max_chars = Limit of number of characters user can enter into edit box. +*/ + +struct edit_box* kolibri_new_edit_box(unsigned int tlx, unsigned int tly, unsigned int max_chars) +{ + unsigned int PIXELS_PER_CHAR = 7; + struct edit_box *new_textbox = (struct edit_box *)malloc(sizeof(struct edit_box)); + char *text_buffer = (char *)calloc(max_chars + 1, sizeof(char)); + + /* Update blur_border_color and shift_color from box_lib.mac macro */ + /* edit_boxes_set_sys_color */ + + new_textbox -> width = max_chars * PIXELS_PER_CHAR; + new_textbox -> left = tlx; + new_textbox -> top = tly; + new_textbox -> color = 0xFFFFFF; /* Always make white edit boxes */ + new_textbox -> shift_color = 0x6a9480; + new_textbox -> focus_border_color = kolibri_color_table.color_work_graph; + new_textbox -> blur_border_color = 0x6a9480; + new_textbox -> text_color = kolibri_color_table.color_work_text; /* Always black text when typing */ + new_textbox -> max = max_chars; + new_textbox -> text = text_buffer; + new_textbox -> mouse_variable = 1; /* let the mouse take control? */ + new_textbox -> flags = 0x00004002; /*ed_focus + ed_always_focus */ + + /* If these lines are uncommented, the executable will crash for no reason at start */ + /* Even though these lines are not ever read it ALWAYS causes a crash, even crashes MTDBG. What gives? */ + + new_textbox -> size = 0; + new_textbox -> pos = 0; + new_textbox -> offset = 0; + new_textbox -> cl_curs_x = 0; + new_textbox -> cl_curs_y = 0; + new_textbox -> shift = 0; + new_textbox -> shift_old = 0; + + return new_textbox; +} + +extern void (*edit_box_draw)(struct edit_box *) __attribute__((__stdcall__)); + +/* editbox_key is a wrapper written in assembly to handle key press events for editboxes */ +/* because inline assembly in GCC is a PITA and interferes with the EAX (AH) register */ +/* which edit_box_key requires */ +extern void editbox_key(struct edit_box *) __attribute__((__stdcall__)); + +extern void (*edit_box_mouse)(struct edit_box *) __attribute__((__stdcall__)); + +#endif /* KOLIBRI_EDITBOX_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_gui.h b/contrib/C_Layer/libguic_kolibri/kolibri_gui.h new file mode 100644 index 0000000000..14b12392a7 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_gui.h @@ -0,0 +1,129 @@ +#ifndef KOLIBRI_GUI_H +#define KOLIBRI_GUI_H + +#include "stdlib.h" /* for malloc() */ +#include + +#include "kolibri_debug.h" /* work with debug board */ + +/* boxlib loader */ +#include "kolibri_boxlib.h" + +/* All supported GUI elements included */ +#include "kolibri_gui_elements.h" + +enum KOLIBRI_GUI_EVENTS { + KOLIBRI_EVENT_REDRAW = 1, /* Window and window elements should be redrawn */ + KOLIBRI_EVENT_KEY = 2, /* A key on the keyboard was pressed */ + KOLIBRI_EVENT_BUTTON = 3, /* A button was clicked with the mouse */ + KOLIBRI_EVENT_MOUSE = 6 /* Mouse activity (movement, button press) was detected */ +}; + +void kolibri_handle_event_redraw(struct kolibri_window* some_window) +{ + /* Draw windows with system color table. */ + + BeginDraw(); + + DrawWindow(some_window->topleftx, some_window->toplefty, + some_window->sizex, some_window->sizey, + some_window->window_title, + kolibri_color_table.color_work_area, some_window->XY); + + /* Enumerate and draw all window elements here */ + if(some_window->elements) /* Draw all elements added to window */ + { + struct kolibri_window_element* current_element = some_window -> elements; + + do + { + /* The redraw_fn serves as draw_fn on initial draw */ + if(kolibri_gui_op_table[current_element -> type].redraw_fn) + kolibri_gui_op_table[current_element -> type].redraw_fn(current_element -> element); + + switch(current_element -> type) + { + case KOLIBRI_EDIT_BOX: + case KOLIBRI_CHECK_BOX: + __asm__ volatile("push $0x13371337"::); /* Random value pushed to balance stack */ + /* otherwise edit_box_draw leaves stack unbalanced */ + /* and GCC jumps like a crazy motha' fucka' */ + break; + } + + current_element = current_element -> next; + + } while(current_element != some_window->elements); /* Have we covered all elements? */ + } +} + +void kolibri_handle_event_key(struct kolibri_window* some_window) +{ + /* Enumerate and trigger key handling functions of window elements here */ + if(some_window->elements) + { + struct kolibri_window_element *current_element = some_window -> elements; + + do + { + /* Only execute if the function pointer isn't NULL */ + if(kolibri_gui_op_table[current_element -> type].key_fn) + kolibri_gui_op_table[current_element -> type].key_fn(current_element -> element); + + current_element = current_element -> next; + } while(current_element != some_window->elements); /* Have we covered all elements? */ + } +} + +void kolibri_handle_event_mouse(struct kolibri_window* some_window) +{ + /* Enumerate and trigger mouse handling functions of window elements here */ + if(some_window->elements) + { + struct kolibri_window_element *current_element = some_window -> elements; + + do + { + + if(kolibri_gui_op_table[current_element -> type].mouse_fn) + kolibri_gui_op_table[current_element -> type].mouse_fn(current_element -> element); + + current_element = current_element -> next; + } while(current_element != some_window->elements); /* Have we covered all elements? */ + } +} + +void kolibri_exit(void) +{ + __asm__ volatile ("int $0x40"::"a"(-1)); +} + +int kolibri_gui_init(void) +{ + int boxlib_init_status = kolibri_boxlib_init(); + + if(boxlib_init_status == 0) + debug_board_write_str("ashmew2 is happy: Kolibri GUI Successfully Initialized.\n"); + else + { + debug_board_write_str("ashmew2 is sad: Kolibri GUI Failed to initialize.\n"); + kolibri_exit(); + } + + /* Initialize the global operation table which handles event functions of */ + /* each individual element type */ + kolibri_init_gui_op_table(); + + /* Get the current color table for Kolibri and store in global table*/ + kolibri_get_system_colors(&kolibri_color_table); + + /* Set up system events for buttons, mouse and keyboard and redraw */ + /* Also set filters so that window receives mouse events only when active + and mouse inside window */ + __asm__ volatile("int $0x40"::"a"(40), "b"(0xC0000027)); +} + +/* Note: The current implementation tries to automatically colors + GUI elements with system theme */ + +#endif /* KOLIBRI_GUI_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolibri_gui_elements.h b/contrib/C_Layer/libguic_kolibri/kolibri_gui_elements.h new file mode 100644 index 0000000000..d82b734af4 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolibri_gui_elements.h @@ -0,0 +1,126 @@ +#ifndef KOLIBRI_GUI_ELEMENTS_H +#define KOLIBRI_GUI_ELEMENTS_H + +/* GUI Elements being used */ +#include "kolibri_editbox.h" +#include "kolibri_checkbox.h" +#include "kolibri_button.h" + +/* enum KOLIBRI_GUI_ELEMENT_TYPE contains all available GUI items from box_lib */ +/* More elements can be added from other libraries as required */ +enum KOLIBRI_GUI_ELEMENT_TYPE { + KOLIBRI_EDIT_BOX, + KOLIBRI_CHECK_BOX, + KOLIBRI_RADIO_BUTTON, + KOLIBRI_SCROLL_BAR, + KOLIBRI_DYNAMIC_BUTTON, + KOLIBRI_MENU_BAR, + KOLIBRI_FILE_BROWSER, + KOLIBRI_TREE_LIST, + KOLIBRI_PATH_SHOW, + KOLIBRI_TEXT_EDITOR, + KOLIBRI_FRAME, + KOLIBRI_PROGRESS_BAR, + + KOLIBRI_BUTTON, + + /* Add elements above this element in order to let KOLIBRI_NUM_GUI_ELEMENTS */ + /* stay at correct value */ + + KOLIBRI_NUM_GUI_ELEMENTS +}; + +/* Linked list which connects together all the elements drawn inside a GUI window */ +struct kolibri_window_element { + enum KOLIBRI_GUI_ELEMENT_TYPE type; + void *element; + struct kolibri_window_element *next, *prev; +}; + +/* Generic structure for supporting functions on various elements of Kolibri's GUI */ +struct kolibri_element_operations { + void (*redraw_fn)(void *); + void (*mouse_fn)(void *); + void (*key_fn)(void *); +}; + +/* Structure for a GUI Window on Kolibri. It also contains all the elements drawn in window */ +struct kolibri_window { + unsigned int topleftx, toplefty; + unsigned int sizex, sizey; + char *window_title; + + /* Refer to sysfuncs, value to be stored in EDX (Function 0) */ + unsigned int XY; + + struct kolibri_window_element *elements; +}; + +/*---------------------End of Structure and enum definitions---------------*/ +/*---------------------Define various functions for initializing GUI-------*/ + +/* Master table containing operations for various GUI elements in one place */ +struct kolibri_element_operations kolibri_gui_op_table[KOLIBRI_NUM_GUI_ELEMENTS]; + +void kolibri_init_gui_op_table(void) +{ +/* Setting up functions for edit box GUI elements*/ +kolibri_gui_op_table[KOLIBRI_EDIT_BOX].redraw_fn = edit_box_draw; +kolibri_gui_op_table[KOLIBRI_EDIT_BOX].mouse_fn = edit_box_mouse; +kolibri_gui_op_table[KOLIBRI_EDIT_BOX].key_fn = editbox_key; + +/* Setting up functions for check box GUI elements*/ +kolibri_gui_op_table[KOLIBRI_CHECK_BOX].redraw_fn = check_box_draw2; +kolibri_gui_op_table[KOLIBRI_CHECK_BOX].mouse_fn = check_box_mouse2; +kolibri_gui_op_table[KOLIBRI_CHECK_BOX].key_fn = NULL; + +/* Setting up functions for Kolibri Buttons ( SysFunc 8 )*/ +kolibri_gui_op_table[KOLIBRI_BUTTON].redraw_fn = draw_button; +kolibri_gui_op_table[KOLIBRI_BUTTON].mouse_fn = NULL; +kolibri_gui_op_table[KOLIBRI_BUTTON].key_fn = NULL; +} + +/* Create a new main GUI window for KolibriOS */ +/* tl stands for TOP LEFT. x and y are coordinates. */ + +struct kolibri_window * kolibri_new_window(int tlx, int tly, int sizex, int sizey, char *title) +{ + struct kolibri_window *new_win = (struct kolibri_window *)malloc(sizeof(struct kolibri_window)); + + new_win->topleftx = tlx; + new_win->toplefty = tly; + new_win->sizex = sizex; + new_win->sizey = sizey; + new_win->window_title = title; + new_win->XY = 0x00000013; /* All windows are skinned windows with caption for now */ + new_win->elements = NULL; + + return new_win; +} + +/* Add an element to an existing window */ +void kolibri_window_add_element(struct kolibri_window *some_window, enum KOLIBRI_GUI_ELEMENT_TYPE element_type, void *some_gui_element) +{ + struct kolibri_window_element *new_element = (struct kolibri_window_element *)malloc(sizeof(struct kolibri_window_element)); + + new_element -> type = element_type; + new_element -> element = some_gui_element; + + if(!(some_window->elements)) /* No elements in window yet */ + { + some_window->elements = new_element; + some_window->elements -> prev = some_window->elements; + some_window->elements -> next = some_window->elements; + } + else + { + struct kolibri_window_element *last_element = some_window -> elements -> prev; + + last_element -> next = new_element; + new_element -> next = some_window -> elements; /* start of linked list */ + some_window -> elements -> prev = new_element; + new_element -> prev = last_element; + } +} + +#endif /* KOLIBRI_GUI_ELEMENTS_H */ diff --git a/contrib/C_Layer/libguic_kolibri/kolwin.c b/contrib/C_Layer/libguic_kolibri/kolwin.c new file mode 100644 index 0000000000..57d74b4795 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/kolwin.c @@ -0,0 +1,57 @@ +#include "kolibri_gui.h" + +int main() +{ + /* Load all libraries, initialize global tables like system color table and + operations table. kolibri_gui_init() will EXIT with mcall -1 if it fails + to do it's job. This is all you need to call and all libraries and GUI + elements can be used after a successful call to this function + */ + kolibri_gui_init(); + + /* Set gui_event to REDRAW so that window is drawn in first iteration */ + unsigned int gui_event = KOLIBRI_EVENT_REDRAW; + + struct kolibri_window *main_window = kolibri_new_window(50, 50, 400, 100, "BoardMsg: Send msg to debug board"); + struct check_box *checkbox = kolibri_new_check_box(20, 40, 12, 12, "Append BOARDMSG to entered message."); + struct edit_box *textbox = kolibri_new_edit_box(20, 55, 40); + struct kolibri_button *button = kolibri_new_button(310, 55, 14, 14, 0x00123456, kolibri_color_table.color_work_button); + + kolibri_window_add_element(main_window, KOLIBRI_EDIT_BOX, textbox); + kolibri_window_add_element(main_window, KOLIBRI_CHECK_BOX, checkbox); + kolibri_window_add_element(main_window, KOLIBRI_BUTTON, button); + + do /* Start of main activity loop */ + { + if(gui_event == KOLIBRI_EVENT_REDRAW) + { + kolibri_handle_event_redraw(main_window); + } + else if(gui_event == KOLIBRI_EVENT_KEY) + { + kolibri_handle_event_key(main_window); + } + else if(gui_event == KOLIBRI_EVENT_BUTTON) + { + unsigned int pressed_button = kolibri_button_get_identifier(); + + if(pressed_button = 0x00123456) /* Our button was pressed */ + { + if(checkbox -> flags & CHECKBOX_IS_SET) /* Append BoardMsg checkbox is set */ + debug_board_write_str("BOARDMSG: "); + + debug_board_write_str(textbox->text); + debug_board_write_str("\n"); + } + } + else if(gui_event == KOLIBRI_EVENT_MOUSE) + { + kolibri_handle_event_mouse(main_window); + } + + } while(gui_event = get_os_event()); /* End of main activity loop */ + + /* kolibri_quit(); */ + + return 0; +} diff --git a/contrib/C_Layer/libguic_kolibri/loadboxlib.asm b/contrib/C_Layer/libguic_kolibri/loadboxlib.asm new file mode 100644 index 0000000000..faeadb002d --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/loadboxlib.asm @@ -0,0 +1,135 @@ +format coff +use32 ; Tell compiler to use 32 bit instructions + +section '.init' code ; Keep this line before includes or GCC messes up call addresses + +include 'proc32.inc' +include 'macros.inc' +purge section,mov,add,sub + +include 'box_lib.mac' +include 'txtbut.inc' +include 'dll.inc' + +public init_boxlib as '_init_boxlib_asm' +public editbox_key as '_editbox_key@4' + +;;; Returns 0 on success. -1 on failure. + +proc init_boxlib + + mcall 68,11 + + stdcall dll.Load, @IMPORT + test eax, eax + jnz error + + mov eax, 0 + ret + +error: + mov eax, -1 + ret +endp + +;; Wrapper to handle edit_box_key function for editboxes. +;; Call this baby from C (refer kolibri_editbox.h for details) +editbox_key: + mov [oldebp], ebp ;Save ebp because GCC is crazy for it otherwise. + pop ebp ;Save return address in ebp. Stack top is param now. + mcall 2 + call [edit_box_key] ; The pointer we passed should be on the stack already. + push ebp ;push the return address back to stack + mov ebp, [oldebp] + ret + +oldebp dd ? + +@IMPORT: +library lib_boxlib, 'box_lib.obj' + +import lib_boxlib, \ + edit_box_draw, 'edit_box' , \ + edit_box_key, 'edit_box_key' , \ + edit_box_mouse, 'edit_box_mouse', \ + edit_box_set_text, 'edit_box_set_text' , \ + init_checkbox2, 'init_checkbox2' , \ + check_box_draw2, 'check_box_draw2' , \ + check_box_mouse2, 'check_box_mouse2' , \ + option_box_draw, 'option_box_draw' , \ + option_box_mouse, 'option_box_mouse' , \ + scroll_bar_vertical_draw, 'scrollbar_ver_draw' , \ + scroll_bar_vertical_mouse, 'scrollbar_ver_mouse' , \ + scroll_bar_horizontal_draw, 'scrollbar_hor_draw' , \ + scroll_bar_horizontal_mouse, 'scrollbar_hor_mouse' , \ + dinamic_button_draw, 'dbutton_draw' , \ + dinamic_button_mouse, 'dbutton_mouse' , \ + menu_bar_draw, 'menu_bar_draw' , \ + menu_bar_mouse, 'menu_bar_mouse' , \ + menu_bar_activate, 'menu_bar_activate' , \ + fb_draw_panel, 'filebrowser_draw' , \ + fb_mouse, 'filebrowser_mouse' , \ + fb_key, 'filebrowser_key' , \ + tl_data_init, 'tl_data_init' , \ + tl_data_clear, 'tl_data_clear' , \ + tl_info_clear, 'tl_info_clear' , \ + tl_key, 'tl_key' , \ + tl_mouse, 'tl_mouse' , \ + tl_draw, 'tl_draw' , \ + tl_info_undo, 'tl_info_undo' , \ + tl_info_redo, 'tl_info_redo' , \ + tl_node_add, 'tl_node_add' , \ + tl_node_set_data, 'tl_node_set_data' , \ + tl_node_get_data, 'tl_node_get_data' , \ + tl_node_delete, 'tl_node_delete' , \ + tl_cur_beg, 'tl_cur_beg' , \ + tl_cur_next, 'tl_cur_next' , \ + tl_cur_perv, 'tl_cur_perv' , \ + tl_node_close_open, 'tl_node_close_open' , \ + tl_node_lev_inc, 'tl_node_lev_inc' , \ + tl_node_lev_dec, 'tl_node_lev_dec' , \ + tl_node_move_up, 'tl_node_move_up' , \ + tl_node_move_down, 'tl_node_move_down' , \ + tl_node_poi_get_info, 'tl_node_poi_get_info' , \ + tl_node_poi_get_next_info, 'tl_node_poi_get_next_info' , \ + tl_node_poi_get_data, 'tl_node_poi_get_data' , \ + tl_save_mem, 'tl_save_mem' , \ + tl_load_mem, 'tl_load_mem' , \ + tl_get_mem_size, 'tl_get_mem_size' , \ + path_show_prepare, 'pathshow_prepare' , \ + path_show_draw, 'pathshow_draw' , \ + ted_but_sumb_upper, 'ted_but_sumb_upper' , \ + ted_but_sumb_lover, 'ted_but_sumb_lover' , \ + ted_but_convert_by_table, 'ted_but_convert_by_table' , \ + ted_can_save, 'ted_can_save' , \ + ted_clear, 'ted_clear' , \ + ted_delete, 'ted_delete' , \ + ted_draw, 'ted_draw' , \ + ted_init, 'ted_init' , \ + ted_init_scroll_bars, 'ted_init_scroll_bars' , \ + ted_init_syntax_file, 'ted_init_syntax_file' , \ + ted_is_select, 'ted_is_select' , \ + ted_key, 'ted_key' , \ + ted_mouse, 'ted_mouse' , \ + ted_open_file, 'ted_open_file' , \ + ted_save_file, 'ted_save_file' , \ + ted_text_add, 'ted_text_add' , \ + ted_but_select_word, 'ted_but_select_word' , \ + ted_but_cut, 'ted_but_cut' , \ + ted_but_copy, 'ted_but_copy' , \ + ted_but_paste, 'ted_but_paste' , \ + ted_but_undo, 'ted_but_undo' , \ + ted_but_redo, 'ted_but_redo' , \ + ted_but_reverse, 'ted_but_reverse' , \ + ted_but_find_next, 'ted_but_find_next' , \ + ted_text_colored, 'ted_text_colored' , \ + frame_draw, 'frame_draw' , \ + progressbar_draw,'progressbar_draw' , \ + progressbar_progress, 'progressbar_progress' + +public edit_box_draw as '_edit_box_draw' +public edit_box_key as '_edit_box_key' +public edit_box_mouse as '_edit_box_mouse' + +public check_box_draw2 as '_check_box_draw2' +public check_box_mouse2 as '_check_box_mouse2' diff --git a/contrib/C_Layer/libguic_kolibri/quirks b/contrib/C_Layer/libguic_kolibri/quirks new file mode 100644 index 0000000000..123a22f105 --- /dev/null +++ b/contrib/C_Layer/libguic_kolibri/quirks @@ -0,0 +1,6 @@ +USE .section '.init' code for writing loader asm C mixed code (in FASM) +Got to know this by checking out the linker script on KGCC. -Xlinker -verbose . +Inside the .text section that is being assembled, the .init is placed at the very beginning. +Let the macros expand, GCC simply places .init on the top and therefore it works. + +Inexplicable errors if .init is not used and .text or .flat is used... Took 4 hours to figure out.