about summary refs log tree commit diff stats
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/core.c86
-rw-r--r--src/ui/ui.h1
-rw-r--r--src/ui/window.h1
-rw-r--r--src/ui/windows.c15
4 files changed, 101 insertions, 2 deletions
diff --git a/src/ui/core.c b/src/ui/core.c
index 4a7bb365..83bcb6ba 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -1601,7 +1601,8 @@ _ui_room_requires_config(const char * const room_jid)
             ui_index = 0;
         }
 
-        win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Room requires configuration, use '/room config accept' or '/room config cancel'");
+        win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "",
+            "Room requires configuration, use '/room config accept' or '/room config destroy'");
 
         // currently in groupchat window
         if (wins_is_current(window)) {
@@ -1870,6 +1871,88 @@ _ui_draw_term_title(void)
 }
 
 static void
+_ui_handle_room_configuration(const char * const room, DataForm *form)
+{
+    GString *title = g_string_new(room);
+    g_string_append(title, " config");
+    ProfWin *window = wins_new(title->str, WIN_MUC_CONFIG);
+    g_string_free(title, TRUE);
+    int num = wins_get_num(window);
+    ui_switch_win(num);
+
+    win_save_vprint(window, '-', NULL, 0, 0, "", "Receieved configuration for room %s.", room);
+
+    if (form->type != NULL) {
+        win_save_vprint(window, '-', NULL, 0, 0, "", "  Type: %s", form->type);
+    }
+    if (form->title != NULL) {
+        win_save_vprint(window, '-', NULL, 0, 0, "", "  Title: %s", form->title);
+    }
+    if (form->instructions != NULL) {
+        win_save_vprint(window, '-', NULL, 0, 0, "", "  Instructions: %s", form->instructions);
+    }
+
+    GSList *fields = form->fields;
+    GSList *curr_field = fields;
+    while (curr_field != NULL) {
+        FormField *field = curr_field->data;
+        win_save_vprint(window, '-', NULL, 0, 0, "", "  Field:");
+
+        if (field->label != NULL) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Label: %s", field->label);
+        }
+        if (field->type != NULL) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Type: %s", field->type);
+        }
+        if (field->var != NULL) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Var: %s", field->var);
+        }
+        if (field->description != NULL) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Description: %s", field->description);
+        }
+
+        if (field->required) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Required: TRUE");
+        } else {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Required: FALSE");
+        }
+
+        GSList *values = field->values;
+        GSList *curr_value = values;
+        if (curr_value != NULL) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Values:");
+        }
+        while (curr_value != NULL) {
+            char *value = curr_value->data;
+            win_save_vprint(window, '-', NULL, 0, 0, "", "      %s", value);
+
+            curr_value = g_slist_next(curr_value);
+        }
+
+        GSList *options = field->options;
+        GSList *curr_option = options;
+        if (curr_option != NULL) {
+            win_save_vprint(window, '-', NULL, 0, 0, "", "    Options:");
+        }
+        while (curr_option != NULL) {
+            FormOption *option = curr_option->data;
+            if (option->label != NULL) {
+                win_save_vprint(window, '-', NULL, 0, 0, "", "      Label: %s", option->label);
+            }
+            if (option->value != NULL) {
+                win_save_vprint(window, '-', NULL, 0, 0, "", "        Value: %s", option->value);
+            }
+
+            curr_option = g_slist_next(curr_option);
+        }
+
+        curr_field = g_slist_next(curr_field);
+    }
+
+    form_destroy(form);
+}
+
+static void
 _win_handle_switch(const wint_t * const ch)
 {
     if (*ch == KEY_F(1)) {
@@ -2106,4 +2189,5 @@ ui_init_module(void)
     ui_update = _ui_update;
     ui_room_requires_config = _ui_room_requires_config;
     ui_room_destroyed = _ui_room_destroyed;
+    ui_handle_room_configuration = _ui_handle_room_configuration;
 }
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 7e8967c0..cb1a92ee 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -160,6 +160,7 @@ void (*ui_handle_recipient_error)(const char * const recipient, const char * con
 void (*ui_handle_error)(const char * const err_msg);
 void (*ui_clear_win_title)(void);
 void (*ui_handle_room_join_error)(const char * const room, const char * const err);
+void (*ui_handle_room_configuration)(const char * const room, DataForm *form);
 
 // contact status functions
 void (*ui_status_room)(const char * const contact);
diff --git a/src/ui/window.h b/src/ui/window.h
index ed0c64b4..5a72f18f 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -58,6 +58,7 @@ typedef enum {
     WIN_CONSOLE,
     WIN_CHAT,
     WIN_MUC,
+    WIN_MUC_CONFIG,
     WIN_PRIVATE,
     WIN_DUCK,
     WIN_XML
diff --git a/src/ui/windows.c b/src/ui/windows.c
index 3d835a0e..5156684b 100644
--- a/src/ui/windows.c
+++ b/src/ui/windows.c
@@ -385,7 +385,11 @@ wins_get_prune_recipients(void)
 
     while (curr != NULL) {
         ProfWin *window = curr->data;
-        if (window->unread == 0 && window->type != WIN_MUC && window->type != WIN_CONSOLE) {
+        if (window->unread == 0 &&
+                window->type != WIN_MUC &&
+                window->type != WIN_MUC_CONFIG &&
+                window->type != WIN_XML &&
+                window->type != WIN_CONSOLE) {
             result = g_slist_append(result, window->from);
         }
         curr = g_list_next(curr);
@@ -539,6 +543,7 @@ wins_create_summary(void)
         GString *chat_string;
         GString *priv_string;
         GString *muc_string;
+        GString *muc_config_string;
         GString *duck_string;
         GString *xml_string;
 
@@ -606,6 +611,14 @@ wins_create_summary(void)
 
                 break;
 
+            case WIN_MUC_CONFIG:
+                muc_config_string = g_string_new("");
+                g_string_printf(muc_config_string, "%d: %s", ui_index, window->from);
+                result = g_slist_append(result, strdup(muc_config_string->str));
+                g_string_free(muc_config_string, TRUE);
+
+                break;
+
             case WIN_DUCK:
                 duck_string = g_string_new("");
                 g_string_printf(duck_string, "%d: DuckDuckGo search", ui_index);
">), x: int, y: int -> _/eax: boolean { # clip at the edge compare x, 0 { break-if->= return 0/false } compare y, 0 { break-if->= return 0/false } compare x, 0x100/width { break-if-< return 0/false } compare y, 0xc0/height { break-if-< return 0/false } var idx/eax: int <- copy y idx <- shift-left 8/log2width idx <- add x var grid/esi: (addr array boolean) <- copy _grid var result/eax: (addr boolean) <- index grid, idx return *result } fn set-state _grid: (addr array boolean), x: int, y: int, val: boolean { # don't bother checking bounds var idx/eax: int <- copy y idx <- shift-left 8/log2width idx <- add x var grid/esi: (addr array boolean) <- copy _grid var result/eax: (addr boolean) <- index grid, idx var src/ecx: boolean <- copy val copy-to *result, src } fn num-live-neighbors grid: (addr array boolean), x: int, y: int -> _/eax: int { var result/edi: int <- copy 0 # row above: zig decrement y decrement x var s/eax: boolean <- state grid, x, y { compare s, 0/false break-if-= result <- increment } increment x s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } increment x s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } # curr row: zag increment y s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } subtract-from x, 2 s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } # row below: zig increment y s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } increment x s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } increment x s <- state grid, x, y { compare s, 0/false break-if-= result <- increment } return result } fn step old-grid: (addr array boolean), new-grid: (addr array boolean) { var y/ecx: int <- copy 0 { compare y, 0xc0/height break-if->= var x/edx: int <- copy 0 { compare x, 0x100/width break-if->= var n/eax: int <- num-live-neighbors old-grid, x, y # if neighbors < 2, die of loneliness { compare n, 2 break-if->= set-state new-grid, x, y, 0/dead } # if neighbors > 3, die of overcrowding { compare n, 3 break-if-<= set-state new-grid, x, y, 0/dead } # if neighbors = 2, preserve state { compare n, 2 break-if-!= var old-state/eax: boolean <- state old-grid, x, y set-state new-grid, x, y, old-state } # if neighbors = 3, cell quickens to life { compare n, 3 break-if-!= set-state new-grid, x, y, 1/live } x <- increment loop } y <- increment loop } } # color a square of size 'side' starting at x*side, y*side fn render-square _x: int, _y: int, color: int { var y/edx: int <- copy _y y <- shift-left 2/log2side var side/ebx: int <- copy 1 side <- shift-left 2/log2side var ymax/ecx: int <- copy y ymax <- add side { compare y, ymax break-if->= { var x/eax: int <- copy _x x <- shift-left 2/log2side var xmax/ecx: int <- copy x xmax <- add side { compare x, xmax break-if->= pixel-on-real-screen x, y, color x <- increment loop } } y <- increment loop } } fn render grid: (addr array boolean) { var y/ecx: int <- copy 0 { compare y, 0xc0/height break-if->= var x/edx: int <- copy 0 { compare x, 0x100/width break-if->= var state/eax: boolean <- state grid, x, y compare state, 0/false { break-if-= render-square x, y, 3/cyan } compare state, 0/false { break-if-!= render-square x, y, 0/black } x <- increment loop } y <- increment loop } } fn main { #? # allocate on the stack #? var grid1-storage: (array boolean 0xc000) # width * height #? var grid1/esi: (addr array boolean) <- address grid1-storage #? var grid2-storage: (array boolean 0xc000) # width * height #? var grid2/edi: (addr array boolean) <- address grid2-storage # allocate on the heap var grid1-storage: (handle array boolean) var grid1-ah/eax: (addr handle array boolean) <- address grid1-storage populate grid1-ah, 0xc000 # width * height var _grid1/eax: (addr array boolean) <- lookup *grid1-ah var grid1/esi: (addr array boolean) <- copy _grid1 var grid2-storage: (handle array boolean) var grid2-ah/eax: (addr handle array boolean) <- address grid2-storage populate grid2-ah, 0xc000 # width * height var _grid2/eax: (addr array boolean) <- lookup *grid2-ah var grid2/edi: (addr array boolean) <- copy _grid2 # initialize grid1 set-state grid1, 0x80, 0x5f, 1/live set-state grid1, 0x81, 0x5f, 1/live set-state grid1, 0x7f, 0x60, 1/live set-state grid1, 0x80, 0x60, 1/live set-state grid1, 0x80, 0x61, 1/live # render grid1 render grid1 { var key/eax: byte <- read-key 0/keyboard compare key, 0 #? loop-if-= # press key to step break-if-!= # press key to quit # iter: grid1 -> grid2 step grid1, grid2 render grid2 # iter: grid2 -> grid1 step grid2, grid1 render grid1 loop } }