syndilights/blib-1.1.7/test/test-module.c

402 lines
10 KiB
C

/* blib - Library of useful things to hack the Blinkenlights
*
* Copyright (C) 2002 The Blinkenlights Crew
* Sven Neumann <sven@gimp.org>
* Daniel Mack <daniel@yoobay.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <string.h>
#define GTK_DISABLE_DEPRECATED
#include <gtk/gtk.h>
#include "blib/blib.h"
/* the HDL setup */
#define WIDTH 18
#define HEIGHT 8
#define ASPECT 0.55
static GtkWidget *main_window = NULL;
static GtkWidget *keys_table = NULL;
static GtkWidget *start_button = NULL;
static GtkWidget *stop_button = NULL;
static gboolean
paint (BModule *module,
guchar *buffer,
gpointer data)
{
b_sender_send_frame (B_SENDER (data), buffer);
return TRUE;
}
static void
key_pressed (GObject *object,
gpointer data)
{
BModuleEvent event;
event.device_id = 0;
event.type = B_EVENT_TYPE_KEY;
event.key = GPOINTER_TO_INT (g_object_get_data (object, "keyval"));
g_print ("KEY %d\n", event.key);
b_module_event (B_MODULE (data), &event);
}
static void
about_cb (GtkWidget *widget,
BModule *module)
{
static GtkWidget *dialog = NULL;
gchar *desc[3];
GString *text;
gint i;
if (dialog)
{
gtk_widget_destroy (dialog);
return;
}
b_module_describe (module, desc, desc + 1, desc + 2);
text = g_string_new (NULL);
for (i = 0; i < 3; i++)
{
if (i == 0)
g_string_append_printf (text,
"<span weight=\"bold\" size=\"larger\">"
"%s"
"</span>", desc[0]);
else if (desc[i])
g_string_append (text, desc[i]);
g_string_append_c (text, '\n');
g_free (desc[i]);
}
dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
text->str);
g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer) &dialog);
g_string_free (text, TRUE);
gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
gtk_window_set_title (GTK_WINDOW (dialog), "About this Module");
gtk_label_set_use_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (dialog)->label),
TRUE);
g_signal_connect_swapped (G_OBJECT (dialog), "response",
G_CALLBACK (gtk_widget_destroy), dialog);
gtk_widget_show (dialog);
}
static void
start_cb (gpointer data)
{
BModuleEvent ev;
gtk_widget_set_sensitive (keys_table, TRUE);
gtk_widget_set_sensitive (start_button, FALSE);
gtk_widget_set_sensitive (stop_button, TRUE);
g_print ("Telling module device 0 joined...");
ev.device_id = 0;
ev.type = B_EVENT_TYPE_PLAYER_ENTERED;
b_module_event (B_MODULE (data), &ev);
g_print ("OK.\n");
}
static void
stop_cb (gpointer data)
{
gtk_widget_set_sensitive (keys_table, FALSE);
gtk_widget_set_sensitive (start_button, TRUE);
gtk_widget_set_sensitive (stop_button, FALSE);
}
static void
dump_cb (GtkWidget *widget,
BModule *module)
{
BMovie *movie;
GError *error = NULL;
movie = g_object_new (B_TYPE_MOVIE_BML, "name", "Module Frame Dump", NULL);
movie->width = module->width;
movie->height = module->height;
movie->channels = module->channels;
movie->maxval = module->maxval;
/* eeque */
movie->load_count = 1;
b_movie_prepend_frame (movie, 1000, module->buffer);
if (!b_movie_save (movie, stdout, &error))
{
g_printerr ("Error writing to stdout: %s\n", error->message);
g_clear_error (&error);
}
g_object_unref (movie);
}
static void
setup_window (BModule *module)
{
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *button;
gint i;
gchar *key[] = { "_1", "_2", "_3", "_4", "_5", "_6",
"_7", "_8", "_9", "_*", "_0", "_#" };
BModuleKey keyval[] = { B_KEY_1,
B_KEY_2,
B_KEY_3,
B_KEY_4,
B_KEY_5,
B_KEY_6,
B_KEY_7,
B_KEY_8,
B_KEY_9,
B_KEY_ASTERISK,
B_KEY_0,
B_KEY_HASH };
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (main_window), "Virtual Cellular Phone");
g_signal_connect (G_OBJECT (main_window), "destroy",
G_CALLBACK (gtk_main_quit),
NULL);
main_vbox = gtk_vbox_new (FALSE, 3);
gtk_container_add (GTK_CONTAINER (main_window), main_vbox);
button = gtk_button_new_with_mnemonic ("_About");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (about_cb), module);
gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
keys_table = gtk_table_new (4, 3, TRUE);
gtk_box_pack_start (GTK_BOX (main_vbox), keys_table, TRUE, TRUE, 0);
for (i = 0; i < 12; i++)
{
GtkWidget *button = gtk_button_new_with_mnemonic (key[i]);
gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 8, 4);
g_object_set_data (G_OBJECT (button),
"keyval", GINT_TO_POINTER (keyval[i]));
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (key_pressed),
module);
gtk_table_attach_defaults (GTK_TABLE (keys_table), button,
i%3, i%3 + 1, i/3, i/3 + 1);
}
gtk_widget_set_sensitive (keys_table, FALSE);
vbox = gtk_vbox_new (TRUE, 2);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
start_button = gtk_button_new_with_mnemonic ("_Start");
g_signal_connect_swapped (G_OBJECT (start_button), "clicked",
G_CALLBACK (b_module_start), module);
gtk_box_pack_start_defaults (GTK_BOX (vbox), start_button);
stop_button = gtk_button_new_from_stock (GTK_STOCK_STOP);
g_signal_connect_swapped (G_OBJECT (stop_button), "clicked",
G_CALLBACK (b_module_stop), module);
gtk_box_pack_start_defaults (GTK_BOX (vbox), stop_button);
button = gtk_button_new_with_mnemonic ("_Dump Frame");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (dump_cb), module);
gtk_box_pack_start_defaults (GTK_BOX (vbox), button);
gtk_widget_set_sensitive (stop_button, FALSE);
gtk_widget_show_all (main_window);
}
int
main (int argc,
char *argv[])
{
BModule *module;
BSender *sender;
GError *error = NULL;
GType type;
gint i;
gint nreceivers = 0;
if (argc < 4)
{
g_printerr ("Usage: %s <dirname> <modulename> [<host>|--property:<key>=<value>]+\n", argv[0]);
return EXIT_FAILURE;
}
b_init ();
gtk_init (&argc, &argv);
i = b_module_infos_scan_dir (argv[1]);
g_print ("b_module_infos_scan_dir() returned %d\n", i);
/* make sure (static) BMoviePlayer is correctly registered. */
g_type_class_peek (B_TYPE_MOVIE_PLAYER);
if (i > 0)
{
GType *child_types;
gint n_child_types;
child_types = g_type_children (B_TYPE_MODULE, &n_child_types);
for (i = 0; i < n_child_types; i++)
{
g_print ("Registered BModule subtype: %s\n",
g_type_name (child_types[i]));
}
g_free (child_types);
}
g_print ("===================\n");
g_print ("Getting type for '%s'\n", argv[2]);
type = g_type_from_name (argv[2]);
if (!type)
{
g_print (" ...failed.\n");
return EXIT_FAILURE;
}
g_print (" ...succeeded.\n");
g_print ("Creating BSender, ");
sender = b_sender_new ();
for (i = 3; i < argc; i++) {
if (strncmp(argv[i], "--", 2) == 0)
continue;
b_sender_add_recipient (sender, -1, argv[i], MCU_LISTENER_PORT, NULL);
nreceivers ++;
}
g_print (" added %d recipients.\n", nreceivers);
b_sender_configure (sender, WIDTH, HEIGHT, 1, 255);
g_print ("Creating object of type '%s' ... ", argv[2]);
module = b_module_new (type, WIDTH, HEIGHT, NULL, paint, sender, &error);
if (! module)
{
g_print ("failed: %s\n", error->message);
return EXIT_FAILURE;
}
g_print ("OK.\n");
b_module_set_aspect (module, ASPECT);
g_print ("Checking for module properties ...\n");
for (i = 3; i < argc; i++)
{
const gchar *p = argv[i];
gchar *value;
gchar buffer[128];
if (strncmp (p, "--property:", 11) != 0)
continue;
strncpy (buffer, p + 11, 128);
value = strchr (buffer, '=');
if (value == NULL )
{
g_print ("%s seems not to be a valid property argument, ignoring\n",
argv[i]);
continue;
}
*value = 0; /* null-terminate key */
value++;
g_print ("Setting object property: \"%s\" = \"%s\"\n", buffer, value);
if (!b_object_set_property (G_OBJECT (module),
buffer, value, NULL, &error))
{
g_print ("Failed: %s\n", error->message);
g_clear_error (&error);
}
}
g_print ("Preparing the module ... ");
if (! b_module_prepare (module, &error))
{
g_print ("failed: %s\n", error->message);
g_object_unref (module);
return EXIT_FAILURE;
}
g_print ("OK.\n");
setup_window (module);
g_signal_connect (G_OBJECT (module), "start", G_CALLBACK (start_cb), module);
g_signal_connect (G_OBJECT (module), "stop", G_CALLBACK (stop_cb), module);
gtk_main ();
g_print ("Quitting.\n");
g_object_unref (module);
return EXIT_SUCCESS;
}