3

System: Linux, Language: C, Toolkit: GTK

I am working to create an emulator for an embedded machine's display. The display is a smart 800x400 pixel RGB display. The machine sends commands to control the display over a serial port in binary.

The first command sent will be to create the area for the text to be displayed:

createLabel LabelID X Y Width Height Rot Vjst Hjst Font R G B

Example commands from the embedded system:

CreateLabel 1 325 0  150 40  0 2 2 1 214 215 216
CreateLabel 2 565 0  220 40  0 2 1 1 214 215 216
CreateLabel 3 15  0  300 40  0 2 0 1 214 215 216

The numbers may look a little strange, but this is typical of what the embedded system transmits.

  • Label #3 is on the left side of the screen, with the horizontal justification set to left (Hjst=0) and vertical justification set to the middle (Vjst=2) within the 40 pixel 'box' of the label.

  • Label #2 is on the right side of the screen, with horizontal justification set to right (Hjst=1) and vertically centered in the middle of the 40 pixel box (Vjst=2).

  • Label #1 is centered on the screen around pixel 400 (Hjst=2, calculated as 325+(150/2)), and is also vertically centered in the 40 pixel box (Vjst=2).

I have tried gtk_label_set_max_width_chars() and gtk_widget_set_halign(), but neither seem to have any effect.

I can also set the font and color using gtk_label_set_markup(). The color seems to stick when I replace the text using gtk_label_set_text(), but the font reverts to the default when I use gtk_label_set_text() later on.

I also tried to draw a rectangle but could not get this to work. The code draws a png file to create the rectangle.

It seems like I am fighting the GTK libraries rather than working with them. To decode the color request from the embedded controller in binary to integer variables to convert them to hex encoding in a string to pass to the libraries seems a little obfuscated.

What I need to do is emulate the display not re-imagine it. This emulator will be used to create screen shots, otherwise I would use a tool like glade to create a new interface from scratch.

#include <gtk-3.0/gtk/gtk.h>
#include <gtk-3.0/gtk/gtkimage.h>

#define GTT_MAX_X 800
#define GTT_MAX_Y 480
#define FHIGHT 14 /* height of font */
#define VJST ((40-FHIGHT)/2) 
#define APPLICATION_ID "org.gtk.example"

GtkWidget *label1;
GtkWidget *label2;
GtkWidget *label3;
GtkWidget *labelxx;

static void
print_new (GtkWidget *widget, gpointer   data)
{
    static int index;
    static char *message[] = {"New text from embedded machine","more text","less","stuff"};
    g_print ("Print_new() text from machine %d\n", index);
    gtk_label_set_text (GTK_LABEL(labelxx), message[index]);
    index = (++index) & 0x3;
}

static void
activate (GtkApplication *app, gpointer user_data)
{
    GtkWidget *button_box;
    GtkWidget *button1;
    GtkWidget *button2;
    GtkWidget *Rectangle;
    GtkWidget *label;
    GtkWidget *window;
    GtkFixed  *fixed;
    GtkWidget *image;

    // create the base window
    window = gtk_application_window_new (app);
    gtk_window_set_title(GTK_WINDOW (window), "Machine99");    // name of machine were attached to
    gtk_window_set_default_size (GTK_WINDOW (window), GTT_MAX_X, GTT_MAX_Y);    // size of GTT display
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);    // don't let it resize

    fixed = (GtkFixed  *)gtk_fixed_new();
    /*
     * load the background image
     * code from machine: LoadBitmap 1 Images/en/Screens/39.bmp
     *                    DisplayBitmap 1 0 0
     */
    image = gtk_image_new_from_file ("data/Screens/39.bmp");
    gtk_fixed_put(fixed, image, 0, 0);

    /*
     * code from machine: FillRectangle 700 85 140 45
     * gtk_draw_rectangle(GdkDrawable *drawable, GdkGC *gc, gint filled, gint x, gint y, gint width, gint height);
    */
    Rectangle = gtk_image_new_from_file ("data/Screens/textbox1.png");
    gtk_fixed_put(fixed, Rectangle, 90, 85);

    /*
     * code from machine: CreateLabel 1 15  0  300 40  0 2 0 1 214 215 216
     *                    CreateLabel 2 325 0  150 40  0 2 2 1 214 215 216
     *                    CreateLabel 3 565 0  220 40  0 2 1 1 214 215 216
     */
        
    label1 = gtk_label_new("Inital Text1");
    gtk_label_set_markup(GTK_LABEL(label1),
            "<span font='Oxygen Mono' foreground='#D6D7D8' size='large'><b>Left Text</b></span>");
    gtk_label_set_max_width_chars((GtkLabel *)label1, 10);
    g_print("label1 width = %d\n", gtk_label_get_max_width_chars((GtkLabel*)label1));
    gtk_fixed_put(fixed, label1, 15,0+VJST);

    label2 = gtk_label_new("Inital Text2");
    gtk_label_set_markup(GTK_LABEL(label2),
        "<span font='Oxygen Mono' foreground='#D6D7D8' size='large'><b>Center</b></span>");
    gtk_label_set_max_width_chars((GtkLabel *)label2, 10);
    g_print("label2 width = %d\n", gtk_label_get_max_width_chars((GtkLabel*)label2));
    gtk_widget_set_halign (label2,  GTK_ALIGN_CENTER);
    gtk_fixed_put(fixed, label2, 325,0+VJST);

    label3 = gtk_label_new("Inital Text3");
    gtk_label_set_markup(GTK_LABEL(label3),
        "<span font='Oxygen Mono' foreground='#D6D7D8' size='large'><b>Right Text</b></span>");
    gtk_widget_set_halign (label3,  GTK_ALIGN_END);
    gtk_fixed_put(fixed, label3, 565,0+VJST);

    labelxx = gtk_label_new("This is an example Label");
    gtk_fixed_put(fixed, labelxx, 90+10,85+VJST);
    gtk_label_set_markup(GTK_LABEL(labelxx),
        "<span font='FONT NAME' foreground='#000000' size='large'>Text From Remote Here</span>");

    gtk_container_add (GTK_CONTAINER (window), (GtkWidget *)fixed);

    // need to add a task bar below the 'screen' with open connection quit any other controlls
    button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_fixed_put(fixed, button_box, 0, 483);
    
    button1 = gtk_button_new_with_label ("Quit");
    g_signal_connect_swapped(button1, "clicked", G_CALLBACK (gtk_widget_destroy), window);
    
    button2 = gtk_button_new_with_label ("New Text");
    g_signal_connect (button2, "clicked", G_CALLBACK (print_new), NULL);
    
    gtk_container_add (GTK_CONTAINER (button_box), button2);
    gtk_container_add (GTK_CONTAINER (button_box), button1);

    gtk_widget_show_all (window);
}

int
main (int argc, char **argv)
{
    GtkApplication *app;
    int status;
    
    app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}
Here is the screen created by the code as posted.
The second image shows what happens when more text than will fit. it causes the entire screen to resize.
7
  • It isn't clear what the problem is. If the displayed text is not to your liking, show a screenshot, and probably a shot of the desired result too. Commented Nov 13 at 6:40
  • 1
    What "embedded system" and what processor? Are you sure that it supports what compiling with gtk is spitting out? How was the gtk library compiled to support your "embedded system"? Can you dump what is being sent as hex and verify the instructions being sent are what you think they are? I ask because it seems like some of the gtk commands are properly translated for your display, but others don't seem to work. That makes me suspect there is some incompatibility in the toolchain you are using to translate the gtk commands into something your embedded systems can handle properly. Commented Nov 13 at 7:59
  • I tried adding screen shots, but I must be doing something wrong as I cannot see them. As I am new to this forum I may take me a couple of tries. I did manage to get my avatar to update for what its worth. Commented Nov 13 at 8:04
  • Also, using set_text() will replace all text that is present (including the embedded markup setting the font, etc..). You need to use set_markup() with the embedded cairo markup wanted for the font, etc. to keep the font modifications. Commented Nov 13 at 8:20
  • 1
    If you can't post screenshots in the traditional way, you can always rely on imgur. Commented Nov 13 at 8:42

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.