Redtools requester library is a small library that offers simple requesters and
dialogs for user disposal. Detroit engine has bindings to use Redtools library
if it is compiled and installed.
Redtools library can be compiled along with the Detroit engine by giving
--with-redtools parameter to configure script. Redtools library needs
Motif (that is, libXm and libXt) in order to work. Also use of Xft fonts, its
default typeface and size can be given as a configure parameter:
When Redtools library is installed, any program using Detroit engine can use it
to output messages when -pm command line switch is used.
-pm, --popup_messages
Use graphical dialog popup messages if possible.
Redtools requester library can be used with any other program too, it is not
bolted to Detroit engine too tight. Below is working example how to write
standalone program that makes use one of the Redtools requesters. See
engine/redtools/example.c how to use other dialogs offered by Redtools
library. Example pops up a dialog which looks like this:
Simple Redtools dialog
Example source code to produce this and other dialogs. Example code is
available in engine/redtools directory. libredtools.so and its
header file redtools.h must be accessible if you want to try the
examples. Steps to compile it:
$ cd engine/redtools
$ make example
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redtools.h"
int main() {
REDTOOLS rt;
unsigned int c;
/* Predefined dialog buttons */
const char *buttons[] = {
"Cheese", "Ham", "Prawn", "Tuna", "Plain green",
NULL
};
/* Initialize the redtools library, if returned handle is NULL,
initialization was not succesful, and program must not call any
redtools functions */
if((rt = red_initialize()) == NULL) {
fprintf(stderr,
"!\n! failed to initialize redtools library\n!\n");
exit(1);
}
/* Add dialog title... */
(void) red_dialog_add_title(rt,
"What kind of starter salad would you like?");
/* ...then the buttons... */
(void) red_dialog_add_buttons(rt, buttons);
/* ...and display it to the user */
c = red_question_dialog(rt);
if(c != 0) {
fprintf(stdout,
"selected: %u (%s)\n", c, buttons[c - 1]);
}
/* Free resources allocated by the redtools library, library is not
useable after this */
(void) red_finalize(rt);
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redtools.h"
int main() {
REDTOOLS rt;
/* Initialize the redtools library, if returned handle is NULL,
initialization was not succesful, and program must not call any
redtools functions */
if((rt = red_initialize()) == NULL) {
fprintf(stderr,
"!\n! failed to initialize redtools library\n!\n");
exit(1);
}
{ /* Button dialog example */
unsigned int c;
/* Predefined dialog buttons */
const char *buttons[] = {
"Cheese", "Ham", "Prawn", "Tuna", "Plain green",
NULL
};
fprintf(stdout,
"#\n# dialog example\n#\n");
/* Add dialog title... */
(void) red_dialog_add_title(rt,
"What kind of starter salad would you like?");
/* ...then the buttons... */
(void) red_dialog_add_buttons(rt, buttons);
/* ...and display it to the user */
c = red_question_dialog(rt);
if(c != 0) {
fprintf(stdout,
"selected: %u (%s)\n", c, buttons[c - 1]);
}
}
{ /* List example */
int i;
unsigned int *c;
/* Predefined dialog selections */
const char *items[] = {
"Salt", "Pepper", "Vinegar", "Olive oil", "None, thanks",
NULL
};
fprintf(stdout,
"#\n# list example\n#\n");
/* Add dialog title and list header... */
(void) red_list_add_title(rt,
"List example",
"Please select one or more for seasoning the salad");
/* ...then the selections... */
(void) red_list_add_items(rt, items);
/* ...and display it to the user... */
if((c = red_list(rt)) != NULL) {
/* ...then check which ones user selected, zero ends the
returned list of selections, as item index starts
counting from one */
for(i = 0; ; i++) {
if(c[i] == 0) {
break;
}
fprintf(stdout,
"selected: %u (%s)\n", c[i], items[c[i] - 1]);
}
}
/* Free the returned list of selections */
(void) red_list_free(c);
}
{ /* Radio button example */
unsigned int c, p;
/* Predefined dialog selections */
const char *items[] = {
"Chicken parmesan", "Daily soup", "Grilled fish",
"Macaroni and cheese", "Meat loaf", "Pulled pork",
"Sausage gravy", "Houses special", "No, thanks",
NULL
};
/* First item is set by default, zero means no preselection */
p = 1;
fprintf(stdout,
"#\n# radiobutton example\n#\n");
/* Add dialog title and list header... */
(void) red_radio_add_title(rt,
"Radiobutton example",
"Would you like to order the main dish?");
/* ...then the selections and set the item selected by default... */
(void) red_radio_add_items(rt, items);
(void) red_radio_add_preset(rt, p);
/* ...and display dialog to the user */
c = red_radio(rt);
/* Selected item index starts from one, zero means no selection was
made */
if(c != 0) {
fprintf(stdout,
"selected: %u (%s)\n", c, items[c - 1]);
}
}
{ /* Toggle button example */
int i;
unsigned int *c;
unsigned int p[1];
/* Predefined dialog selections */
const char *items[] = {
"Bill, please", "Clean tablecloth", "Chili sauce", "Bread",
"Butter", "Ketchup", "Mustard", "Pepper", "Salt", "Soda water",
"Still water",
NULL
};
/* Second (0x2 = 00010b) and fourth (0x8 = 01000b) items are set by
default, there must be enough int's in array to cover every dialog
selection */
p[0] = 0x2 | 0x8;
fprintf(stdout,
"#\n# togglebutton example\n#\n");
/* Add dialog title and list header... */
(void) red_button_add_title(rt,
"Togglebutton example",
"Any extra wishes?");
/* ...then the selections and set the item(s) selected by default using
bitmask set above... */
(void) red_button_add_items(rt, items);
(void) red_button_add_preset(rt, p);
/* ...and display it to the user... */
if((c = red_button(rt)) != NULL) {
/* ...then check which ones user selected, zero means this item
was not checked */
for(i = 0; ; i++) {
if(items[i] == NULL) {
break;
}
if(c[i] != 0) {
fprintf(stdout,
"selected: %d (%s)\n", i, items[i]);
}
}
}
/* Free the returned list of selections */
(void) red_button_free(c);
}
{ /* Prompt example */
const char *s;
fprintf(stdout,
"#\n# prompt example\n#\n");
/* Add dialog title... */
(void) red_prompt_add_title(rt,
"Prompt example",
"Feedback to the restaurant");
/* ...but do not prefill the text field... */
(void) red_prompt_add_value(rt, NULL);
/* ...then display it to the user... */
if((s = red_prompt(rt)) != NULL) {
fprintf(stdout,
"prompt: %s\n", s);
}
/* ...and free the returned string what user possibly wrote */
(void) red_prompt_free(s);
}
{ /* File selector example */
const char *s;
fprintf(stdout,
"#\n# file selector example\n#\n");
/* Add dialog title... */
(void) red_file_add_title(rt,
"File selection example");
/* ...preselected path and possibly a file selection mask... */
(void) red_file_add_path(rt, "/tmp");
(void) red_file_add_mask(rt, NULL);
/* ...then display it to the user... */
if((s = red_file(rt)) != NULL) {
fprintf(stdout,
"selected: %s\n", s);
}
/* ...and free the file name string what user possibly selected */
(void) red_file_free(s);
}
/* Free resources allocated by the redtools library, library is not
useable after this */
(void) red_finalize(rt);
exit(0);
}
X resources
To get Redtools requesters and dialogs look like the screenshot above,
following .Xresources can be used: