I'm trying to compile my web app as a native desktop application in C. However I'm having a bit of trouble grabbing the file path in C.
In PyGTK I would use...
import webkit, pygtk, gtk, os
path=os.getcwd()
print path
web_view.open("file://" + path + "/index.html")
However I'm not sure if I'm just looking in the wrong places or what, but when I search Google I haven't been able to find out how to grab the file path in C which I want to use like this.
gchar* uri = (gchar*) (argc > 1 ? argv[1] : "file://" + path + "app/index.html");
Instead of linking to it in a grotesque manner like so...
gchar* uri = (gchar*) (argc > 1 ? argv[1] : "file://" + /home/michael/Desktop/kodeWeave/linux/app/index.html");
webkit_web_view_open (web_view, uri);
Here's my full project (if helpful).
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <webkit/webkit.h>
static WebKitWebView* web_view;
void on_window_destroy (GtkObject *object, gpointer user_data) {
gtk_main_quit();
}
int main (int argc, char *argv[]) {
GtkBuilder *builder;
GtkWidget *window;
GtkWidget *scrolled_window;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "browser.xml", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
scrolled_window = GTK_WIDGET (gtk_builder_get_object (builder, "scrolledwindow1"));
g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
gtk_window_set_title(GTK_WINDOW(window), "kodeWeave");
web_view = WEBKIT_WEB_VIEW (webkit_web_view_new());
gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));
gtk_builder_connect_signals (builder, NULL);
g_object_unref (G_OBJECT (builder));
gchar* uri = (gchar*) (argc > 1 ? argv[1] : "file:///home/michael/Desktop/kodeWeave/linux/app/index.html");
webkit_web_view_open (web_view, uri);
gtk_widget_grab_focus (GTK_WIDGET (web_view));
gtk_widget_show_all (window);
gtk_main();
return 0;
}
You can't use the + operator to concatenate strings in c, you may need snprintf instead, first you need a large enough buffer, may be the constant PATH_MAX will work, it's defined in limits.h, so for example
char uri[PATH_MAX];
char cwd[PATH_MAX];
getcwd(cwd, sizeof(cwd));
if (argc > 1)
snprintf(uri, sizeof(uri), "%s", argv[1]);
else
snprintf(uri, sizeof(uri), "file://%s/index.html", cwd);
/* ^ %s specifier for ^ this char pointer */
the + operator works with your operands, but in a different way, it just performs pointer arithmetic, because the operands are pointers.
Related
EDIT
This question ended up being two problems packed into one. Yet, I cannot delete the question. The scope of the original question regarding pointers was solved by #David Ranieri. The mmap/fork/gtk problem will be the scope of a new question and will not be addressed here.
I want to print a value I have stored in memory in a GTK window. The integer must be stored using mmap to be retained during a fork elsewhere in the code. I cannot reference this memory mapped address from GTK without getting a SegFault. Am I doing something wrong here? Is there a better way?
My current strategy:
Reserve memory for an int with mmap at *VAL
Fork process, one half modifies VAL the other half runs GTK
Pass *VAL to app in userdata slot
The userdata now called localval in activate()
Print the value at address localval by converting from gpointer to int.
MWE (this causes a segfault, run at your own risk):
/*
* MMAP Variable SegFault
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static void activate (GtkApplication *app, gpointer *localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *exit_button;
// Text
GtkWidget *text_status;
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
exit_button = gtk_button_new_with_label ("Exit");
gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
// Define text status
char msg[32]={0};
// The "print" line
g_snprintf(msg, sizeof msg, "val: %d\n", GPOINTER_TO_INT(*localval));
text_status = gtk_label_new(msg);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
//Activate!
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
In a non-working alternative to this code, I tried changing the print line to:
g_snprintf(msg, sizeof msg, "val: %d\n", &GPOINTER_TO_INT(*localval));
But the compiler thinks I want to use the & as a comparator.
You are passing a dereferenced pointer (a value) to a function expecting a pointer:
int *VAL = ...;
...
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
switch to
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL); // Do not use a wrong cast (void **)
also, gpointer is an alias of void *, using gpointer *data you get a void **data, not what you want, so
static void activate (GtkApplication *app, gpointer *localval) {
should be
static void activate (GtkApplication *app, gpointer localval) { // without *
finally, to print the value of the pointer use
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
I would like to update a GtkLabel with data imported from a text file, but it doesn't evaluate \n as a newline character, as it should normally do.
The file contains (for example):
This is a\nnewline.
How do I get this \n understood by GtkLabel ?
This is my complete code:
#include <gtk/gtk.h>
#include <string.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *label, *window;
gchar* test_char;
ssize_t len;
FILE* fh;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Test GTK");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 100);
label = gtk_label_new ("");
fh = fopen ("file.txt", "r");
getline (&test_char, &len, fh);
gtk_label_set_text (GTK_LABEL (label), test_char);
gtk_container_add (GTK_CONTAINER (window), label);
gtk_widget_show_all (window);
fclose (fh);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", 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;
}
The key is converting the literal \n to \n.
There are two ways to do this I can come up with (I leave out the file reading part):
Text in test file:
That's\na\ntest,\nfolks!
1.
gchar *new_txt = g_strcompress (test_char);
gtk_label_set_text (GTK_LABEL (label), new_txt);
g_free (new_txt);
2.
GRegex *regex = g_regex_new ("\\\\n", 0, 0, NULL);
gchar *new_txt = g_regex_replace (regex, test_char, -1, 0, "\\n", 0, NULL);
gtk_label_set_text (GTK_LABEL (label), new_txt);
g_free (new_txt);
g_regex_unref (regex);
Note that you have to escape twice: first for C, then for the regex engine, so that the latter sees: replace \\n with \n. You have to escape both backslashes of \\n for C, that's why you get four backslashes in the string that has to be replaced.
Result for both:
Both ways need a newly-allocated string to store the converted text, so you have to free the memory after usage.
I'm trying to create a c application with code::block that use Gtk 3 as a graphics library
This version of gtk is a bit different from gtk 2 and not so much tutorials or exampes are avaiable online. I want to use a type named GdkPixmap that permit to load gifs into your windows, after googled it i have found that the type is deprecated and have been eliminated from gtk new version (3). From official documentation (migrate from gtk2 to gtk3) i have found that is possible to use cairo functions to make the works made by GdkPixmap but i havent found how change and migrate.
This code founded on stackoverflow is an example of loading gif into window using gtk2 that doesnt work on gtk3 compiler said : error unknown type name 'GdkPixmap'
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
GdkPixbuf *load_pixbuf_from_file (const char *filename)
{
GError *error = NULL;
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, &error);
if (pixbuf == NULL)
{
g_print ("Error loading file: %d : %s\n", error->code, error->message);
g_error_free (error);
exit (1);
}
return pixbuf;
}
GdkPixbufAnimation *load_pixbuf_animation_from_file (const char *filename)
{
GError *error = NULL;
GdkPixbufAnimation *pixbuf = gdk_pixbuf_animation_new_from_file (filename, &error);
if (pixbuf == NULL)
{
g_print ("Error loading file: %d : %s\n", error->code, error->message);
g_error_free (error);
exit (1);
}
return pixbuf;
}
int main (int argc, char **argv)
{
GtkWidget *window = NULL;
GdkPixbuf *image = NULL;
GdkPixbufAnimation * anim = NULL;
GtkWidget *widget = NULL;
GdkPixmap *background = NULL;
GtkStyle *style = NULL;
gtk_init (&argc, &argv);
/* Load a non animated gif */
image = load_pixbuf_from_file ("C://Users//Pcc//Downloads//66.gif");
// widget = gtk_image_new_from_pixbuf (image);
gdk_pixbuf_render_pixmap_and_mask (image, &background, NULL, 0);
style = gtk_style_new ();
style->bg_pixmap [0] = background;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "Load Image");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_set_style (GTK_WIDGET(window), GTK_STYLE (style));
gtk_window_set_transient_for (GTK_WINDOW (window), NULL);
GtkWidget *hbox = NULL;
hbox = gtk_hbox_new (0, FALSE);
gtk_container_add (GTK_CONTAINER(window), hbox);
GtkWidget *button = NULL;
button = gtk_button_new_with_label ("Sonic");
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Use and install a obsolete gtk i dont think is good
Please to post examples of code that works on gtk3 that load gifs
There's a specific GdkPixmap to Cairo migration guide right inside the official GTK 3 documentation.
I am new to GTK and GALDE. I am making a normal GUI in which I have one start button and one update button, so that if I click on start button, start should be displayed in text entry and same for the update button.I am using text entry and its buffer for start and update. Everything is running fine but I am getting warning
passing argument 1 of ‘gtk_entry_get_buffer’ from incompatible pointer type [enabled by default] and
assignment from incompatible pointer type [enabled by default]
Please help in removing these errors.!
Below is the code which I am using
GtkBuilder *builder;
GtkWidget *main_window;
GtkWidget *start_button;
GtkWidget *update_button;
GtkWidget *start_entry;
GtkWidget *update_entry;
GtkWidget *start_entry_buffer;
GtkWidget *update_entry_buffer;
void on_start_button_clicked(GtkButton *start_button)
{
gtk_entry_buffer_set_text (start_entry_buffer,"start ",-1); //error
}
void on_update_button_clicked(GtkButton *update_button)
{
gtk_entry_buffer_set_text (update_entry_buffer,"update ",-1);//error
}
int main(int argc, char *argv[])
{
gtk_init (&argc, &argv);
builder = gtk_builder_new();
if(gtk_builder_add_from_file (builder, "example.glade", NULL) == 0)
{
printf("Error Glade File not Found\n");
exit(0);
}
main_window = GTK_WIDGET (gtk_builder_get_object (builder, "main_window"));
start_button = GTK_WIDGET (gtk_builder_get_object (builder, "start_button"));
update_button = GTK_WIDGET (gtk_builder_get_object (builder, "update_button"));
start_entry = GTK_WIDGET (gtk_builder_get_object (builder, "start_entry"));
start_entry_buffer = gtk_entry_get_buffer (start_entry);//error
update_entry = GTK_WIDGET (gtk_builder_get_object (builder, "update_entry"));
update_entry_buffer = gtk_entry_get_buffer (update_entry);//error
gtk_builder_connect_signals(builder, NULL);
g_object_unref (G_OBJECT (builder));
gtk_widget_show (main_window);
gtk_main ();
return 0;
}
Thanks.!
Did you notice the GTK_WIDGET(...) casts around all your gtk_builder_get_object() calls? It's the same idea for casting a GtkWidget to a GtkEntry: wrap your variable around a GTK_ENTRY(...) and it should work. There's one of these for every GTK+ and GLib type. In addition, using these function casts will give you warnings at runtime if you use the wrong variable in your cast.
Hello everyone,
I'm currently trying to convert my PyGTK application to C, everything was
working as expected until I hit an issue with retrieving label name of my notebook widget.
Below is a short example of what I'm trying to achieve..
GtkBuilder *builder = NULL;
GtkWidget *window = NULL;
GtkWidget *notebook = NULL;
GError *error = NULL;
void on_page_switch(GtkNotebook *notebook, gpointer data)
{
// gtk_notebook_get_tab_label_text(GtkNotebook *notebook,GtkWidget *child)
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
if( ! gtk_builder_add_from_file( builder, "data/glade.glade", &error ) )
{
g_warning( "%s", error->message );
g_free( error );
return( 1 );
}
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
g_signal_connect(window, "destroy", GTK_SIGNAL_FUNC (on_window_destroy), NULL);
notebook = GTK_WIDGET (gtk_builder_get_object (builder, "notebook1"));
g_signal_connect(GTK_NOTEBOOK (notebook), "switch-page", GTK_SIGNAL_FUNC(on_page_switch), NULL);
gtk_builder_connect_signals (builder, NULL);
g_object_unref (G_OBJECT (builder));
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
Could you please give me some pointers as how to get the current tab's label name?
I believe it should be this function gtk_notebook_get_tab_label_text(GtkNotebook *notebook, GtkWidget *child) , however I was unable to get it working too.
Apologies for my bad english.
Thanks in advance,
Alex
/// EDIT ////
It was actualy the call-back function it self that was wrong..
I have missed couple of pointers that are passed with the "switch-page" event.
void on_page_switch(GtkNotebook * notebook, GtkWidget *page, guint page_num, gpointer user_data)
{
GtkWidget * child = gtk_notebook_get_nth_page(notebook, page_num);
printf(" -> %i \n", gtk_notebook_page_num(notebook, child));
}
Correct, you should be able to use gtk_notebook_get_tab_label_text() to do this.
You need a pointer to the child widget (page content) whose label you're interested in, you can use gtk_notebook_get_nth_page() to get that if you don't have the notebook children handy.
It's hard to help more since you didn't specify what problems you ran in to when you tried it.