mirror of
https://github.com/azure-rtos/guix.git
synced 2025-02-04 07:13:17 +08:00
310 lines
12 KiB
C
310 lines
12 KiB
C
/* This is a small demo of the high-performance GUIX graphics framework. */
|
|
|
|
#include <stdio.h>
|
|
#include "gx_api.h"
|
|
|
|
#include "guix_keyboard_resources.h"
|
|
#include "guix_keyboard_specifications.h"
|
|
|
|
/* Define prototypes. */
|
|
UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length);
|
|
|
|
/* Define constants specific to this implemenation. */
|
|
#define KEY_PRESS_EVENT GX_FIRST_APP_EVENT
|
|
|
|
extern GX_CONST GX_THEME *display_1_theme_table[];
|
|
|
|
GX_WINDOW_ROOT *root;
|
|
|
|
/* declare a keyboard_key control block, derived from GX_PIXELMAP_BUTTON */
|
|
|
|
typedef struct KEY_WIDGET_STRUCT {
|
|
GX_PIXELMAP_BUTTON_MEMBERS_DECLARE
|
|
GX_RESOURCE_ID icon;
|
|
char *text;
|
|
USHORT key_val;
|
|
} KEY_WIDGET;
|
|
|
|
/* declare a structure to define one keyboard key */
|
|
typedef struct KEY_LAYOUT_ENTRY_STRUCT {
|
|
GX_VALUE xoffset;
|
|
GX_VALUE yoffset;
|
|
GX_RESOURCE_ID normal_background;
|
|
GX_RESOURCE_ID selected_background;
|
|
GX_RESOURCE_ID icon;
|
|
char *text;
|
|
USHORT key_val;
|
|
} KEY_LAYOUT_ENTRY;
|
|
|
|
/* define an array of keys. This array can easily be modified or new versions added to define
|
|
alternative keyboard layouts and keyboard key values
|
|
*/
|
|
#define MAX_KEY_LENGTH 5
|
|
#define NUM_DEFAULT_KEYS 33
|
|
KEY_WIDGET key_control_blocks[NUM_DEFAULT_KEYS];
|
|
|
|
KEY_LAYOUT_ENTRY key_layout_1[NUM_DEFAULT_KEYS + 1] = {
|
|
{ 0, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "A", 'A'},
|
|
{ 67, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "B", 'B'},
|
|
{134, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "C", 'C'},
|
|
{201, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "D", 'D'},
|
|
{268, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "E", 'E'},
|
|
{335, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "F", 'F'},
|
|
{402, 0, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "G", 'G'},
|
|
{ 0, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "H", 'H'},
|
|
{ 67, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "I", 'I'},
|
|
{134, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "J", 'J'},
|
|
{201, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "K", 'K'},
|
|
{268, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "L", 'L'},
|
|
{335, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "M", 'M'},
|
|
{402, 37, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "N", 'N'},
|
|
{ 0, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "O", 'O'},
|
|
{ 67, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "P", 'P'},
|
|
{134, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "Q", 'Q'},
|
|
{201, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "R", 'R'},
|
|
{268, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "S", 'S'},
|
|
{335, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "T", 'T'},
|
|
{402, 74, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "U", 'U'},
|
|
{ 0, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "@", '@'},
|
|
{ 67, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "V", 'V'},
|
|
{134, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "W", 'W'},
|
|
{201, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "X", 'X'},
|
|
{268, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "Y", 'Y'},
|
|
{335, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "Z", 'Z'},
|
|
{402, 111, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "Enter", GX_KEY_SELECT},
|
|
{ 0, 148, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "Home", GX_KEY_HOME},
|
|
{ 67, 148, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, GX_PIXELMAP_ID_I_LEFTARROW, NULL, GX_KEY_LEFT_ARROW},
|
|
{134, 148, GX_PIXELMAP_ID_B_SPACE, GX_PIXELMAP_ID_B_SPACE_H, 0, NULL, GX_KEY_SPACE},
|
|
{335, 148, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, GX_PIXELMAP_ID_I_RIGHTARROW, NULL, GX_KEY_RIGHT_ARROW},
|
|
{402, 148, GX_PIXELMAP_ID_B_KEYBOARD, GX_PIXELMAP_ID_B_KEYBOARD_H, 0, "End", GX_KEY_END},
|
|
{ 0, 0, 0, 0, 0, NULL, 0}
|
|
};
|
|
|
|
/* Define prototypes. */
|
|
|
|
VOID start_guix(VOID);
|
|
VOID PopulateKeyboardButtons(GX_WINDOW *frame, KEY_LAYOUT_ENTRY *layout);
|
|
extern UINT win32_graphics_driver_setup_24xrgb(GX_DISPLAY *display);
|
|
|
|
int main(int argc, char ** argv)
|
|
{
|
|
tx_kernel_enter();
|
|
return(0);
|
|
}
|
|
|
|
VOID tx_application_define(void *first_unused_memory)
|
|
{
|
|
start_guix();
|
|
}
|
|
|
|
VOID start_guix(VOID)
|
|
{
|
|
/* Initialize GUIX. */
|
|
gx_system_initialize();
|
|
|
|
gx_studio_display_configure(DISPLAY_1, win32_graphics_driver_setup_24xrgb,
|
|
LANGUAGE_ENGLISH, DISPLAY_1_DEFAULT_THEME, &root);
|
|
|
|
/* create the keyboard screen */
|
|
gx_studio_named_widget_create("keyboard_screen", (GX_WIDGET *) root, GX_NULL);
|
|
|
|
/* populate buttons into keyboard frame */
|
|
PopulateKeyboardButtons(&keyboard_screen.keyboard_screen_keyboard_frame,
|
|
key_layout_1);
|
|
|
|
gx_single_line_text_input_style_set(&keyboard_screen.keyboard_screen_keyboard_input_field,
|
|
GX_STYLE_ENABLED | GX_STYLE_CURSOR_BLINK | GX_STYLE_CURSOR_ALWAYS);
|
|
|
|
|
|
/* Show the root window to make it visible. */
|
|
gx_widget_show(root);
|
|
|
|
/* start GUIX thread */
|
|
gx_system_start();
|
|
}
|
|
|
|
|
|
VOID key_widget_draw(KEY_WIDGET *key)
|
|
{
|
|
INT x_offset = 0;
|
|
INT y_offset = 1;
|
|
GX_RESOURCE_ID font_id = GX_FONT_ID_MIDSIZE;
|
|
GX_PIXELMAP *map;
|
|
GX_STRING string;
|
|
|
|
gx_pixelmap_button_draw((GX_PIXELMAP_BUTTON *) key);
|
|
|
|
if (key->text)
|
|
{
|
|
string.gx_string_ptr = key->text;
|
|
string.gx_string_length = string_length_get(string.gx_string_ptr, MAX_KEY_LENGTH);
|
|
if (string.gx_string_length > 1)
|
|
{
|
|
font_id = GX_FONT_ID_DEFAULT;
|
|
}
|
|
if (key ->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
|
|
{
|
|
x_offset++;
|
|
y_offset++;
|
|
}
|
|
|
|
gx_widget_text_draw_ext(key, GX_COLOR_ID_WHITE,
|
|
font_id, &string,
|
|
x_offset, y_offset);
|
|
}
|
|
else
|
|
{
|
|
if (key->icon)
|
|
{
|
|
gx_context_pixelmap_get(key->icon, &map);
|
|
|
|
if (map)
|
|
{
|
|
x_offset = key->gx_widget_size.gx_rectangle_right - key->gx_widget_size.gx_rectangle_left + 1;
|
|
x_offset -= map ->gx_pixelmap_width;
|
|
x_offset /=2;
|
|
x_offset += key->gx_widget_size.gx_rectangle_left;
|
|
|
|
y_offset = key->gx_widget_size.gx_rectangle_bottom - key->gx_widget_size.gx_rectangle_top + 1;
|
|
y_offset -= map ->gx_pixelmap_height;
|
|
y_offset /=2;
|
|
y_offset += key->gx_widget_size.gx_rectangle_top;
|
|
|
|
gx_canvas_pixelmap_draw(x_offset, y_offset, map);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID key_widget_select(GX_WIDGET *widget)
|
|
{
|
|
GX_BUTTON *button = (GX_BUTTON *) widget;
|
|
KEY_WIDGET *key = (KEY_WIDGET *) widget;
|
|
|
|
GX_EVENT notification;
|
|
|
|
/* Set style for pen down. */
|
|
button -> gx_widget_style |= GX_STYLE_BUTTON_PUSHED;
|
|
gx_widget_front_move(widget, NULL);
|
|
|
|
/* Mark as dirty. */
|
|
gx_system_dirty_mark(widget);
|
|
|
|
/* send notification to parent keyboard frame */
|
|
notification.gx_event_type = KEY_PRESS_EVENT;
|
|
notification.gx_event_payload.gx_event_ushortdata[0] = key->key_val;
|
|
notification.gx_event_target = 0;
|
|
widget->gx_widget_parent->gx_widget_event_process_function(widget->gx_widget_parent, ¬ification);
|
|
}
|
|
|
|
VOID key_widget_deselect(GX_WIDGET *key, GX_BOOL generate_event)
|
|
{
|
|
/* Set style for pen down. */
|
|
key -> gx_widget_style &= ~GX_STYLE_BUTTON_PUSHED;
|
|
|
|
/* Mark as dirty. */
|
|
gx_system_dirty_mark(key);
|
|
}
|
|
|
|
VOID key_widget_create(KEY_WIDGET *key_widget, USHORT id, KEY_LAYOUT_ENTRY *entry, GX_WIDGET *frame)
|
|
{
|
|
GX_RECTANGLE size;
|
|
INT left;
|
|
INT top;
|
|
const GX_THEME *theme_ptr;
|
|
|
|
GX_PIXELMAP *map;
|
|
theme_ptr = display_1_theme_table[0];
|
|
|
|
map = theme_ptr->theme_pixelmap_table[entry->selected_background];
|
|
left = frame->gx_widget_size.gx_rectangle_left + entry->xoffset;
|
|
top = frame->gx_widget_size.gx_rectangle_top + entry->yoffset;
|
|
|
|
gx_utility_rectangle_define(&size, left, top,
|
|
left + map->gx_pixelmap_width - 1,
|
|
top + map->gx_pixelmap_height - 1);
|
|
|
|
/* first create the base pixelmap button */
|
|
gx_pixelmap_button_create((GX_PIXELMAP_BUTTON *) key_widget,
|
|
NULL, frame,
|
|
entry->normal_background,
|
|
entry->selected_background,
|
|
0, GX_STYLE_HALIGN_CENTER | GX_STYLE_VALIGN_CENTER | GX_STYLE_ENABLED,
|
|
id, &size);
|
|
|
|
/* now initialize the extended fields */
|
|
|
|
key_widget->icon = entry->icon;
|
|
key_widget->text = entry->text;
|
|
key_widget->key_val = entry->key_val;
|
|
gx_widget_draw_set(key_widget, key_widget_draw);
|
|
key_widget->gx_button_select_handler = key_widget_select;
|
|
key_widget->gx_button_deselect_handler = key_widget_deselect;
|
|
}
|
|
|
|
VOID PopulateKeyboardButtons(GX_WINDOW *frame, KEY_LAYOUT_ENTRY *entry)
|
|
{
|
|
INT index = 0;
|
|
|
|
while(entry ->key_val)
|
|
{
|
|
key_widget_create(&key_control_blocks[index], index + 1, entry, (GX_WIDGET *) frame);
|
|
entry++;
|
|
index++;
|
|
}
|
|
}
|
|
|
|
UINT keyboard_frame_event_handler(GX_WINDOW *frame, GX_EVENT *event_ptr)
|
|
{
|
|
GX_EVENT key_event;
|
|
|
|
switch(event_ptr->gx_event_type)
|
|
{
|
|
case KEY_PRESS_EVENT:
|
|
/* these events arrive from the key buttons. generate keyboard input
|
|
events sent to the input field. The key value is held in the gx_event_ushortdata[0] field
|
|
*/
|
|
key_event.gx_event_target = (GX_WIDGET *)&keyboard_screen.keyboard_screen_keyboard_input_field;
|
|
key_event.gx_event_sender = frame ->gx_widget_id;
|
|
key_event.gx_event_payload.gx_event_ushortdata[0] = event_ptr->gx_event_payload.gx_event_ushortdata[0];
|
|
key_event.gx_event_type = GX_EVENT_KEY_DOWN;
|
|
gx_system_event_send(&key_event);
|
|
key_event.gx_event_type = GX_EVENT_KEY_UP;
|
|
gx_system_event_send(&key_event);
|
|
return 0;
|
|
|
|
default:
|
|
return gx_window_event_process(frame, event_ptr);
|
|
}
|
|
}
|
|
|
|
UINT input_field_event_process(GX_SINGLE_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
|
|
{
|
|
if (event_ptr ->gx_event_type == GX_SIGNAL(IDB_BACKSPACE, GX_EVENT_CLICKED))
|
|
{
|
|
gx_single_line_text_input_backspace(text_input);
|
|
return 0;
|
|
}
|
|
|
|
return gx_single_line_text_input_event_process(text_input, event_ptr);
|
|
}
|
|
|
|
UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length)
|
|
{
|
|
UINT length = 0;
|
|
|
|
if (input_string)
|
|
{
|
|
/* Traverse the string. */
|
|
for (length = 0; input_string[length]; length++)
|
|
{
|
|
/* Check if the string length is bigger than the max string length. */
|
|
if (length >= max_string_length)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return length;
|
|
} |