ui/server/toolkit.c

Wed, 10 Dec 2025 19:04:46 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 10 Dec 2025 19:04:46 +0100
changeset 982
9102a53c5385
parent 981
1d47e71f26b6
child 985
93f07ccfd997
permissions
-rw-r--r--

implement window (Server)

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2025 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#include "toolkit.h"

#include "../common/message.h"
#include "../common/threadpool.h"
#include "../common/app.h"

#include <cx/hash_map.h>
#include <cx/printf.h>

static const char *ui_app_name;

static UiMessageHandler *message_handler;

static ui_callback onstartup;
static void *onstartupdata;

static UiQueue *event_queue;

static CxMap *srv_obj_map;
static uint64_t srv_obj_id_counter = 0;

void ui_init(const char *appname, int argc, char **argv) {
    ui_app_name = appname;
    
    message_handler = uic_simple_msg_handler(STDIN_FILENO, STDOUT_FILENO, ui_server_message_received);
    
    srv_obj_map = cxHashMapCreateSimple(CX_STORE_POINTERS);
}

const char* ui_appname() {
    return ui_app_name;
}

void ui_add_styledata(const char *styledata, int len) {
    // NOOP
}


void ui_server_message_received(cxstring msg) {
    
}

void ui_main(void) {
    uic_simple_msg_handler_start(message_handler);
    uic_application_startup(NULL);
    event_queue = ui_queue_create();
    UiServerEvent *event = NULL;
    while((event = ui_queue_get_wait(event_queue)) != NULL) {
        if(event->callback) {
            event->callback(&event->event, event->userdata);
        }
    }
    ui_queue_free(event_queue);
}

typedef struct CallMain {
    UiServerEvent event;
    ui_threadfunc func;
    void *data;
} CallMain;

static void mainthr(UiServerEventData *event, void *userdata) {
    CallMain *c = userdata;
    if(c->func) {
        c->func(c->data);
    }
    free(c);
}

void ui_call_mainthread(ui_threadfunc tf, void* td) {
    CallMain *c = malloc(sizeof(CallMain));
    c->func = tf;
    c->data = td;
    ui_queue_put(event_queue, c);
}

void ui_show(UiObject *obj) {
    if(!obj->widget->sent) {
        cxmutstr msg = obj->widget->serialize(obj->widget);
        obj->widget->sent = TRUE;
        uic_message_send(message_handler, msg);
        free(msg.ptr);
    }
    cxmutstr msg = cx_asprintf("{\"type\":\"show\", \"obj\":\"%s\"}", obj->widget->obj->id.ptr);
    obj->widget->visible = TRUE;
    uic_message_send(message_handler, msg);
    free(msg.ptr);
}

UiSrvObj* ui_create_server_object(UiContext *ctx) {
    const CxAllocator *a = ctx->allocator;
    UiSrvObj *obj = cxZalloc(a, sizeof(UiSrvObj));
    
    char id[32];
    snprintf(id, 32, "%" PRIu64, srv_obj_id_counter++);
    obj->id = cx_strdup_a(a, id);
    obj->ctx = ctx;
    
    obj->widgets = cxHashMapCreate(a, CX_STORE_POINTERS, 64);
    
    return obj;
}

void ui_reg_widget(UiWidget *widget) {
    UiSrvObj *obj = widget->obj;
    
    char id[32];
    snprintf(id, 32, "%" PRIu64, obj->widget_id_counter++);
    
    widget->id = cx_strdup_a(widget->obj->ctx->allocator, cx_str(id));
    cxMapPut(obj->widgets, id, widget);
}

mercurial