#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "interface.h"
#include "mcp.h"
#include "mcpgui.h"
#include "externs.h"
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif /* HAVE_MALLOC_H */
typedef struct DlogValue_t {
struct DlogValue_t *next;
char *name;
int lines;
char **value;
} DlogValue;
typedef struct DlogData_t {
struct DlogData_t *next;
struct DlogData_t **prev;
char *id;
int descr;
int dismissed;
DlogValue *values;
Gui_CB callback;
GuiErr_CB error_cb;
void *context;
} DlogData;
DlogData *dialog_list = NULL;
DlogData *dialog_last_accessed = NULL;
void gui_pkg_callback(McpFrame * mfr, McpMesg * msg, McpVer ver, void *context);
void
gui_initialize(void)
{
McpVer minver = { 1, 0 }; /* { major, minor } */
McpVer maxver = { 1, 3 }; /* { major, minor } */
mcp_package_register(GUI_PACKAGE, minver, maxver, gui_pkg_callback, NULL, NULL);
}
DlogData *
gui_dlog_find(const char *dlogid)
{
DlogData *ptr;
ptr = dialog_last_accessed;
if (ptr && !strcmp(ptr->id, dlogid)) {
return ptr;
}
ptr = dialog_list;
while (ptr) {
if (!strcmp(ptr->id, dlogid)) {
dialog_last_accessed = ptr;
return ptr;
}
ptr = ptr->next;
}
return NULL;
}
void*
gui_dlog_get_context(const char *dlogid)
{
DlogData *ptr = gui_dlog_find(dlogid);
if (ptr) {
return ptr->context;
} else {
return NULL;
}
}
int
gui_dlog_get_descr(const char *dlogid)
{
DlogData *ptr = gui_dlog_find(dlogid);
if (ptr) {
return ptr->descr;
} else {
return EGUINODLOG;
}
}
int
GuiClosed(const char *dlogid)
{
DlogData *ptr = gui_dlog_find(dlogid);
if (ptr) {
return ptr->dismissed;
} else {
return EGUINODLOG;
}
}
int
gui_value_linecount(const char *dlogid, const char *id)
{
DlogValue *ptr;
DlogData *ddata = gui_dlog_find(dlogid);
if (!ddata) {
return EGUINODLOG;
}
ptr = ddata->values;
while (ptr && strcmp(ptr->name, id)) {
ptr = ptr->next;
}
if (!ptr) {
return 0;
}
return ptr->lines;
}
const char *
GuiValueFirst(const char *dlogid)
{
DlogData *ddata = gui_dlog_find(dlogid);
if (!ddata || !ddata->values) {
return NULL;
}
return ddata->values->name;
}
const char *
GuiValueNext(const char *dlogid, const char *id)
{
DlogValue *ptr;
DlogData *ddata = gui_dlog_find(dlogid);
if (!ddata) {
return NULL;
}
ptr = ddata->values;
while (ptr && strcmp(ptr->name, id)) {
ptr = ptr->next;
}
if (!ptr || !ptr->next) {
return NULL;
}
return ptr->next->name;
}
const char *
gui_value_get(const char *dlogid, const char *id, int line)
{
DlogValue *ptr;
DlogData *ddata = gui_dlog_find(dlogid);
if (!ddata) {
return NULL;
}
ptr = ddata->values;
while (ptr && strcmp(ptr->name, id)) {
ptr = ptr->next;
}
if (!ptr || line < 0 || line >= ptr->lines) {
return NULL;
}
return ptr->value[line];
}
void
gui_value_set_local(const char *dlogid, const char *id, int lines, const char **value)
{
DlogValue *ptr;
DlogData *ddata = gui_dlog_find(dlogid);
int i;
int limit = 256;
if (!ddata) {
return;
}
ptr = ddata->values;
while (ptr && strcmp(ptr->name, id)) {
ptr = ptr->next;
if (!limit--) {
return;
}
}
if (ptr) {
for (i = 0; i < ptr->lines; i++) {
free(ptr->value[i]);
}
free(ptr->value);
} else {
ptr = (DlogValue *) malloc(sizeof(DlogValue));
ptr->name = (char *) malloc(strlen(id) + 1);
strcpy(ptr->name, id);
ptr->next = ddata->values;
ddata->values = ptr;
}
ptr->lines = lines;
ptr->value = (char **) malloc(sizeof(char *) * lines);
for (i = 0; i < lines; i++) {
ptr->value[i] = (char *) malloc(strlen(value[i]) + 1);
strcpy(ptr->value[i], value[i]);
}
}
void
gui_value_free(DlogValue * ptr)
{
int i;
free(ptr->name);
for (i = 0; i < ptr->lines; i++) {
free(ptr->value[i]);
}
free(ptr->value);
}
void
gui_pkg_callback(McpFrame * mfr, McpMesg * msg, McpVer ver, void *context)
{
DlogData *dat;
const char *dlogid = mcp_mesg_arg_getline(msg, "dlogid", 0);
const char *id = mcp_mesg_arg_getline(msg, "id", 0);
if (!dlogid || !*dlogid) {
show_mcp_error(mfr, msg->mesgname, "Missing dialog ID.");
return;
}
dat = gui_dlog_find(dlogid);
if (!dat) {
show_mcp_error(mfr, msg->mesgname, "Invalid dialog ID.");
return;
}
if (!string_compare(msg->mesgname, "ctrl-value")) {
int valcount = mcp_mesg_arg_linecount(msg, "value");
int i;
const char **value = (const char **) malloc(sizeof(const char *) * valcount);
if (!id || !*id) {
show_mcp_error(mfr, msg->mesgname, "Missing control ID.");
return;
}
for (i = 0; i < valcount; i++) {
value[i] = mcp_mesg_arg_getline(msg, "value", i);
}
gui_value_set_local(dlogid, id, valcount, value);
free(value);
} else if (!string_compare(msg->mesgname, "ctrl-event")) {
const char *evt = mcp_mesg_arg_getline(msg, "event", 0);
const char *dismissed = mcp_mesg_arg_getline(msg, "dismissed", 0);
int did_dismiss = 1;
if (!id || !*id) {
show_mcp_error(mfr, msg->mesgname, "Missing control ID.");
return;
}
if (!evt || !*evt) {
evt = "buttonpress";
}
if (NULL != dismissed) {
if (!string_compare(dismissed, "false")) {
did_dismiss = 0;
} else if (!string_compare(dismissed, "0")) {
did_dismiss = 0;
}
}
if (did_dismiss) {
dat->dismissed = 1;
}
if (dat->callback) {
dat->callback(dat->descr, dlogid, id, evt, msg, did_dismiss, dat->context);
}
} else if (!string_compare(msg->mesgname, "error")) {
const char *err = mcp_mesg_arg_getline(msg, "errcode", 0);
const char *text = mcp_mesg_arg_getline(msg, "errtext", 0);
const char *id = mcp_mesg_arg_getline(msg, "id", 0);
if (!err) {
err = "";
}
if (!text) {
text = "";
}
if (dat->error_cb) {
dat->error_cb(dat->descr, dlogid, id, err, text, dat->context);
}
}
}
const char *
gui_dlog_alloc(int descr, Gui_CB callback, GuiErr_CB error_cb, void *context)
{
char tmpid[32];
DlogData *ptr;
while (1) {
snprintf(tmpid, sizeof(tmpid), "%08lX", (unsigned long)RANDOM());
if (!gui_dlog_find(tmpid)) {
break;
}
}
ptr = (DlogData *) malloc(sizeof(DlogData));
ptr->id = (char *) malloc(strlen(tmpid) + 1);
strcpy(ptr->id, tmpid);
ptr->descr = descr;
ptr->dismissed = 0;
ptr->callback = callback;
ptr->error_cb = error_cb;
ptr->context = context;
ptr->values = NULL;
ptr->prev = &dialog_list;
ptr->next = dialog_list;
if (dialog_list)
dialog_list->prev = &ptr->next;
dialog_list = ptr;
dialog_last_accessed = ptr;
return ptr->id;
}
int
GuiFree(const char *id)
{
DlogData *ptr;
DlogValue *valptr;
DlogValue *nextval;
ptr = gui_dlog_find(id);
if (!ptr) {
return EGUINODLOG;
}
*ptr->prev = ptr->next;
if (ptr->next)
ptr->next->prev = ptr->prev;
ptr->next = NULL;
ptr->prev = NULL;
free(ptr->id);
valptr = ptr->values;
while (valptr) {
nextval = valptr->next;
gui_value_free(valptr);
valptr = nextval;
}
ptr->values = NULL;
ptr->descr = 0;
if (dialog_last_accessed == ptr) {
dialog_last_accessed = NULL;
}
free(ptr);
return 0;
}
int
gui_dlog_closeall_descr(int descr)
{
DlogData *ptr;
McpMesg msg;
ptr = dialog_list;
while (ptr) {
while (ptr) {
if (ptr->descr == descr) {
break;
}
ptr = ptr->next;
}
if (!ptr) {
return 0;
}
if (ptr->callback) {
mcp_mesg_init(&msg, GUI_PACKAGE, "ctrl-event");
mcp_mesg_arg_append(&msg, "dlogid", ptr->id);
mcp_mesg_arg_append(&msg, "id", "_closed");
mcp_mesg_arg_append(&msg, "dismissed", "1");
mcp_mesg_arg_append(&msg, "event", "buttonpress");
ptr->callback(ptr->descr, ptr->id, "_closed", "buttonpress", &msg, 1, ptr->context);
mcp_mesg_clear(&msg);
}
ptr = ptr->next;
}
return 0;
}
int
gui_dlog_freeall_descr(int descr)
{
DlogData *ptr;
DlogData *next;
DlogValue *valptr;
ptr = dialog_list;
while (ptr) {
while (ptr) {
if (ptr->descr == descr) {
break;
}
ptr = ptr->next;
}
if (!ptr) {
return 0;
}
next = ptr->next;
*ptr->prev = next;
if (next)
next->prev = ptr->prev;
ptr->next = NULL;
ptr->prev = NULL;
if (dialog_last_accessed == ptr) {
dialog_last_accessed = NULL;
}
free(ptr->id);
valptr = ptr->values;
while (valptr) {
ptr->values = valptr->next;
gui_value_free(valptr);
valptr = ptr->values;
}
ptr->values = NULL;
ptr->descr = 0;
free(ptr);
ptr = next;
}
return 0;
}
McpVer
GuiVersion(int descr)
{
McpVer supp = { 0, 0 };
McpFrame *mfr;
mfr = descr_mcpframe(descr);
if (mfr) {
supp = mcp_frame_package_supported(mfr, GUI_PACKAGE);
}
return supp;
}
int
GuiSupported(int descr)
{
McpVer supp;
McpFrame *mfr;
mfr = descr_mcpframe(descr);
if (mfr) {
supp = mcp_frame_package_supported(mfr, GUI_PACKAGE);
if (supp.verminor != 0 || supp.vermajor != 0) {
return 1;
}
}
return 0;
}
const char *
GuiSimple(int descr, const char *title, Gui_CB callback, GuiErr_CB error_cb, void *context)
{
McpMesg msg;
McpFrame *mfr = descr_mcpframe(descr);
const char *id;
if (!mfr) {
return NULL;
}
if (GuiSupported(descr)) {
id = gui_dlog_alloc(descr, callback, error_cb, context);
mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-create");
mcp_mesg_arg_append(&msg, "dlogid", id);
mcp_mesg_arg_append(&msg, "type", "simple");
mcp_mesg_arg_append(&msg, "title", title);
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return id;
} else {
return NULL;
}
}
const char *
GuiTabbed(int descr,
const char *title,
int pagecount, const char **pagenames, const char **pageids,
Gui_CB callback, GuiErr_CB error_cb, void *context)
{
McpMesg msg;
McpFrame *mfr = descr_mcpframe(descr);
const char *id;
int i;
if (!mfr) {
return NULL;
}
if (GuiSupported(descr)) {
id = gui_dlog_alloc(descr, callback, error_cb, context);
mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-create");
mcp_mesg_arg_append(&msg, "dlogid", id);
mcp_mesg_arg_append(&msg, "type", "tabbed");
mcp_mesg_arg_append(&msg, "title", title);
for (i = 0; i < pagecount; i++) {
mcp_mesg_arg_append(&msg, "panes", pageids[i]);
mcp_mesg_arg_append(&msg, "names", pagenames[i]);
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return id;
} else {
return NULL;
}
}
const char *
GuiHelper(int descr,
const char *title,
int pagecount, const char **pagenames, const char **pageids,
Gui_CB callback, GuiErr_CB error_cb, void *context)
{
McpMesg msg;
McpFrame *mfr = descr_mcpframe(descr);
const char *id;
int i;
if (!mfr) {
return NULL;
}
if (GuiSupported(descr)) {
id = gui_dlog_alloc(descr, callback, error_cb, context);
mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-create");
mcp_mesg_arg_append(&msg, "dlogid", id);
mcp_mesg_arg_append(&msg, "type", "helper");
mcp_mesg_arg_append(&msg, "title", title);
for (i = 0; i < pagecount; i++) {
mcp_mesg_arg_append(&msg, "panes", pageids[i]);
mcp_mesg_arg_append(&msg, "names", pagenames[i]);
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return id;
} else {
return NULL;
}
}
int
GuiShow(const char *id)
{
McpMesg msg;
McpFrame *mfr;
int descr = gui_dlog_get_descr(id);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
if (!GuiClosed(id)) {
mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-show");
mcp_mesg_arg_append(&msg, "dlogid", id);
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
}
return 0;
}
return EGUINOSUPPORT;
}
int
GuiClose(const char *id)
{
McpMesg msg;
McpFrame *mfr;
int descr = gui_dlog_get_descr(id);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
if (!GuiClosed(id)) {
mcp_mesg_init(&msg, GUI_PACKAGE, "dlog-close");
mcp_mesg_arg_append(&msg, "dlogid", id);
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
}
return 0;
}
return EGUINOSUPPORT;
}
int
GuiSetVal(const char *dlogid, const char *id, int lines, const char **value)
{
McpMesg msg;
McpFrame *mfr;
int i;
int descr = gui_dlog_get_descr(dlogid);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
mcp_mesg_init(&msg, GUI_PACKAGE, "ctrl-value");
mcp_mesg_arg_append(&msg, "dlogid", dlogid);
mcp_mesg_arg_append(&msg, "id", id);
for (i = 0; i < lines; i++) {
mcp_mesg_arg_append(&msg, "value", value[i]);
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
gui_value_set_local(dlogid, id, lines, value);
return 0;
}
return EGUINOSUPPORT;
}
int
GuiListInsert(const char *dlogid, const char *id, int after, int lines, const char **value)
{
McpMesg msg;
McpFrame *mfr;
char numbuf[32];
int i;
int descr = gui_dlog_get_descr(dlogid);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
mcp_mesg_init(&msg, GUI_PACKAGE, "list-insert");
mcp_mesg_arg_append(&msg, "dlogid", dlogid);
mcp_mesg_arg_append(&msg, "id", id);
if (after > 0) {
snprintf(numbuf, sizeof(numbuf), "%d", after);
mcp_mesg_arg_append(&msg, "after", numbuf);
}
for (i = 0; i < lines; i++) {
mcp_mesg_arg_append(&msg, "values", value[i]);
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return 0;
}
return EGUINOSUPPORT;
}
int
GuiListDel(const char *dlogid, const char *id, int from, int to)
{
McpMesg msg;
McpFrame *mfr;
char numbuf[32];
int descr = gui_dlog_get_descr(dlogid);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
mcp_mesg_init(&msg, GUI_PACKAGE, "list-delete");
mcp_mesg_arg_append(&msg, "dlogid", dlogid);
mcp_mesg_arg_append(&msg, "id", id);
if (from == GUI_LIST_END) {
mcp_mesg_arg_append(&msg, "from", "end");
} else {
snprintf(numbuf, sizeof(numbuf), "%d", from);
mcp_mesg_arg_append(&msg, "from", numbuf);
}
if (to == GUI_LIST_END) {
mcp_mesg_arg_append(&msg, "to", "end");
} else {
snprintf(numbuf, sizeof(numbuf), "%d", to);
mcp_mesg_arg_append(&msg, "to", numbuf);
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return 0;
}
return EGUINOSUPPORT;
}
int
GuiMenuItem(const char *dlogid, const char *id, const char *type, const char *name, const char **args)
{
McpMesg msg;
McpFrame *mfr;
int i;
int descr = gui_dlog_get_descr(dlogid);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
mcp_mesg_init(&msg, GUI_PACKAGE, "menu-item");
mcp_mesg_arg_append(&msg, "dlogid", dlogid);
mcp_mesg_arg_append(&msg, "id", id);
mcp_mesg_arg_append(&msg, "name", name);
mcp_mesg_arg_append(&msg, "type", name);
i = 0;
while (args && args[i]) {
const char *arg = args[i];
const char *val = args[i + 1];
mcp_mesg_arg_append(&msg, arg, val);
i += 2;
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return 0;
}
return EGUINOSUPPORT;
}
int
GuiMenuCmd(const char *dlogid, const char *id, const char *name)
{
return GuiMenuItem(dlogid, id, "command", name, NULL);
}
int
GuiMenuCheckBtn(const char *dlogid, const char *id, const char *name, const char **args)
{
return GuiMenuItem(dlogid, id, "checkbutton", name, args);
}
void
gui_ctrl_process_layout(McpMesg * msg, int layout)
{
char buf[32];
buf[0] = '\0';
if ((layout & GUI_N))
strcatn(buf, sizeof(buf), "n");
if ((layout & GUI_S))
strcatn(buf, sizeof(buf), "s");
if ((layout & GUI_E))
strcatn(buf, sizeof(buf), "e");
if ((layout & GUI_W))
strcatn(buf, sizeof(buf), "w");
if (strcmp(buf, ""))
mcp_mesg_arg_append(msg, "sticky", buf);
snprintf(buf, sizeof(buf), "%d", GET_COLSKIP(layout));
if (strcmp(buf, "0"))
mcp_mesg_arg_append(msg, "colskip", buf);
snprintf(buf, sizeof(buf), "%d", GET_COLSPAN(layout));
if (strcmp(buf, "1"))
mcp_mesg_arg_append(msg, "colspan", buf);
snprintf(buf, sizeof(buf), "%d", GET_ROWSPAN(layout));
if (strcmp(buf, "1"))
mcp_mesg_arg_append(msg, "rowspan", buf);
snprintf(buf, sizeof(buf), "%d", GET_LEFTPAD(layout));
if (strcmp(buf, "0"))
mcp_mesg_arg_append(msg, "leftpad", buf);
snprintf(buf, sizeof(buf), "%d", GET_TOPPAD(layout));
if (strcmp(buf, "0"))
mcp_mesg_arg_append(msg, "toppad", buf);
if ((layout & GUI_NONL))
mcp_mesg_arg_append(msg, "newline", "0");
if ((layout & GUI_HEXP))
mcp_mesg_arg_append(msg, "hweight", "1");
if ((layout & GUI_VEXP))
mcp_mesg_arg_append(msg, "vweight", "1");
if ((layout & GUI_REPORT))
mcp_mesg_arg_append(msg, "report", "1");
if ((layout & GUI_REQUIRED))
mcp_mesg_arg_append(msg, "required", "1");
}
int
gui_ctrl_make_v(const char *dlogid, const char *type, const char *pane,
const char *id, const char *text, const char *value,
int layout, const char **args)
{
McpMesg msg;
McpFrame *mfr;
int descr;
int i;
descr = gui_dlog_get_descr(dlogid);
mfr = descr_mcpframe(descr);
if (!mfr) {
return EGUINODLOG;
}
if (GuiSupported(descr)) {
char cmdname[64];
snprintf(cmdname, sizeof(cmdname), "ctrl-%.55s", type);
mcp_mesg_init(&msg, GUI_PACKAGE, cmdname);
gui_ctrl_process_layout(&msg, layout);
mcp_mesg_arg_append(&msg, "dlogid", dlogid);
mcp_mesg_arg_append(&msg, "id", id);
if (text)
mcp_mesg_arg_append(&msg, "text", text);
if (value) {
mcp_mesg_arg_append(&msg, "value", value);
if (id) {
gui_value_set_local(dlogid, id, 1, &value);
}
}
if (pane)
mcp_mesg_arg_append(&msg, "pane", pane);
i = 0;
while (args && args[i]) {
const char *arg = args[i];
const char *val = args[i + 1];
if (id && !string_compare(arg, "value")) {
gui_value_set_local(dlogid, id, 1, &val);
}
mcp_mesg_arg_append(&msg, arg, val);
i += 2;
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
return 0;
}
return EGUINOSUPPORT;
}
int
gui_ctrl_make_l(const char *dlogid, const char *type, const char *pane, const char *id, const char *text, const char *value,
int layout, ...)
{
va_list ap;
McpMesg msg;
McpFrame *mfr;
int descr;
va_start(ap, layout);
descr = gui_dlog_get_descr(dlogid);
mfr = descr_mcpframe(descr);
if (!mfr) {
va_end(ap);
return EGUINODLOG;
}
if (GuiSupported(descr)) {
char cmdname[64];
snprintf(cmdname, sizeof(cmdname), "ctrl-%.55s", type);
mcp_mesg_init(&msg, GUI_PACKAGE, cmdname);
gui_ctrl_process_layout(&msg, layout);
mcp_mesg_arg_append(&msg, "dlogid", dlogid);
mcp_mesg_arg_append(&msg, "id", id);
if (text)
mcp_mesg_arg_append(&msg, "text", text);
if (value) {
mcp_mesg_arg_append(&msg, "value", value);
if (id) {
gui_value_set_local(dlogid, id, 1, &value);
}
}
if (pane)
mcp_mesg_arg_append(&msg, "pane", pane);
while (1) {
const char *val;
const char *arg;
arg = va_arg(ap, const char *);
if (!arg)
break;
val = va_arg(ap, const char *);
mcp_mesg_arg_append(&msg, arg, val);
}
mcp_frame_output_mesg(mfr, &msg);
mcp_mesg_clear(&msg);
va_end(ap);
return 0;
}
va_end(ap);
return EGUINOSUPPORT;
}
int
GuiEdit(const char *dlogid, const char *pane, const char *id, const char *text, const char *value, int width, int layout)
{
char buf[32];
snprintf(buf, sizeof(buf), "%d", width);
return gui_ctrl_make_l(dlogid, "edit", pane, id, text, value, layout, "width", buf, NULL);
}
int
GuiText(const char *dlogid, const char *pane, const char *id, const char *value, int width, int layout)
{
char widthbuf[32];
snprintf(widthbuf, sizeof(widthbuf), "%d", width);
return gui_ctrl_make_l(dlogid, "text", pane, id, NULL, value, layout, "width", widthbuf, NULL);
}
int
GuiSpinner(const char *dlogid, const char *pane, const char *id, const char *text, int value, int width, int min,
int max, int layout)
{
char widthbuf[32];
char valbuf[32];
char minbuf[32];
char maxbuf[32];
snprintf(widthbuf, sizeof(widthbuf), "%d", width);
snprintf(valbuf, sizeof(valbuf), "%d", value);
snprintf(minbuf, sizeof(minbuf), "%d", min);
snprintf(maxbuf, sizeof(maxbuf), "%d", max);
return gui_ctrl_make_l(dlogid, "spinner", pane, id, text, valbuf, layout,
"width", widthbuf, "min", minbuf, "max", maxbuf, NULL);
}
int
GuiCombo(const char *dlogid, const char *pane, const char *id, const char *text, const char *value, int width, int editable,
int layout)
{
char buf[32];
snprintf(buf, sizeof(buf), "%d", width);
return gui_ctrl_make_l(dlogid, "combobox", pane, id, text, value, layout,
"width", buf, "editable", editable ? "1" : "0", NULL);
}
int
GuiMulti(const char *dlogid, const char *pane, const char *id, const char *value, int width, int height, int fixed,
int layout)
{
char widthbuf[32];
char heightbuf[32];
snprintf(widthbuf, sizeof(widthbuf), "%d", width);
snprintf(heightbuf, sizeof(heightbuf), "%d", height);
return gui_ctrl_make_l(dlogid, "multiedit", pane, id, NULL, value, layout,
"width", widthbuf,
"height", heightbuf, "font", (fixed ? "fixed" : "variable"), NULL);
}
int
GuiHRule(const char *dlogid, const char *pane, const char *id, int height, int layout)
{
char heightbuf[32];
snprintf(heightbuf, sizeof(heightbuf), "%d", height);
return gui_ctrl_make_l(dlogid, "hrule", pane, id, NULL, NULL, layout, "height", heightbuf, NULL);
}
int
GuiVRule(const char *dlogid, const char *pane, const char *id, int thickness, int layout)
{
char widthbuf[32];
snprintf(widthbuf, sizeof(widthbuf), "%d", thickness);
return gui_ctrl_make_l(dlogid, "vrule", pane, id, NULL, NULL, layout, "width", widthbuf, NULL);
}
int
GuiFrame(const char *dlogid, const char *pane, const char *id, int layout)
{
return gui_ctrl_make_l(dlogid, "frame", pane, id, NULL, NULL, layout, NULL);
}
int
GuiGroupBox(const char *dlogid, const char *pane, const char *id, const char *text, int collapsible, int collapsed,
int layout)
{
return gui_ctrl_make_l(dlogid, "frame", pane, id, text, NULL, layout,
"visible", "1",
"collapsible", collapsible ? "1" : "0",
"collapsed", collapsed ? "1" : "0", NULL);
}
int
GuiButton(const char *dlogid, const char *pane, const char *id, const char *text, int width, int dismiss, int layout)
{
char widthbuf[32];
snprintf(widthbuf, sizeof(widthbuf), "%d", width);
return gui_ctrl_make_l(dlogid, "button", pane, id, text, NULL, layout,
"width", widthbuf, "dismiss", dismiss ? "1" : "0", NULL);
}
/******************************************************************************************/
/* MUF gui functions
**********************/
void
muf_dlog_add(struct frame *fr, const char *dlogid)
{
struct dlogidlist *item = (struct dlogidlist *) malloc(sizeof(struct dlogidlist));
strcpy(item->dlogid, dlogid);
item->next = fr->dlogids;
fr->dlogids = item;
}
void
muf_dlog_remove(struct frame *fr, const char *dlogid)
{
struct dlogidlist **prev = &fr->dlogids;
while (*prev) {
if (!string_compare(dlogid, (*prev)->dlogid)) {
struct dlogidlist *tmp = *prev;
*prev = (*prev)->next;
free(tmp);
} else {
prev = &((*prev)->next);
}
}
GuiFree(dlogid);
}
void
muf_dlog_purge(struct frame *fr)
{
while (fr->dlogids) {
struct dlogidlist *tmp = fr->dlogids;
GuiClose(fr->dlogids->dlogid);
GuiFree(fr->dlogids->dlogid);
fr->dlogids = fr->dlogids->next;
free(tmp);
}
}
/***************************************************************************
***************************************************************************
***************************************************************************/
void
post_dlog_cb(GUI_EVENT_CB_ARGS)
{
if (!string_compare(id, "post")) {
char buf[BUFFER_LEN];
const char *subject = gui_value_get(dlogid, "subj", 0);
const char *keywords = gui_value_get(dlogid, "keywd", 0);
/* int bodycnt = gui_value_linecount(dlogid, "body"); */
snprintf(buf, sizeof(buf), "Subject: %s", subject);
pnotify(pdescrcon(descr), buf);
snprintf(buf, sizeof(buf), "Keywords: %s", keywords);
pnotify(pdescrcon(descr), buf);
} else if (!string_compare(id, "cancel")) {
pnotify(pdescrcon(descr), "Posting cancelled.");
} else {
pnotify(pdescrcon(descr), "Invalid event!");
}
if (did_dismiss) {
GuiFree(dlogid);
}
}
void
do_post_dlog(int descr, const char *text)
{
const char *keywords[] = { "Misc.", "Wedding", "Party", "Toading", "New MUCK" };
const char *dlg = GuiSimple(descr, "A demonstration dialog", post_dlog_cb, NULL, NULL);
GuiEdit(dlg, NULL, "subj", "Subject", text, 60, GUI_EW);
GuiCombo(dlg, NULL, "keywd", "Keywords", "Misc.", 60, 1, GUI_EW | GUI_HEXP);
GuiListInsert(dlg, "keywd", GUI_LIST_END, 5, keywords);
GuiMulti(dlg, NULL, "body", NULL, 80, 12, 1, GUI_NSEW | GUI_VEXP | COLSPAN(2));
GuiHRule(dlg, NULL, NULL, 2, COLSPAN(2));
GuiFrame(dlg, NULL, "bfr", GUI_EW | COLSPAN(2) | TOPPAD(0));
GuiFrame(dlg, "bfr", NULL, GUI_EW | GUI_HEXP | GUI_NONL);
GuiVRule(dlg, NULL, NULL, 2, GUI_NONL);
GuiButton(dlg, NULL, "post", "Post", 8, 1, GUI_E | GUI_NONL);
GuiButton(dlg, NULL, "cancel", "Cancel", 8, 1, GUI_E | TOPPAD(0));
GuiShow(dlg);
}