So I found some tutorials on how to configure gtk to dev c++. I followed that tutorial very closely but when i tried to run this:
#include <gtk/gtk.h>
static void hello( GtkWidget *widget,
gpointer data )
{
g_print ("Hello World\n");
}
static gboolean delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
g_print ("delete event occurred\n");
return TRUE;
}
static void destroy( GtkWidget *widget,
gpointer data )
{
gtk_main_quit ();
}
int main( int argc,
char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (window, "delete-event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (window, "destroy",
G_CALLBACK (destroy), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked",
G_CALLBACK (hello), NULL);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy),
window);
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main ();
return 0;
}
It produces linker error like this:
[Linker error] undefined reference to g_print
And many more of this type.
How can I fix this?
Related
My ultimate goal is to compile and build a GTK application for Windows using only the C programming language
I'm using a Macbook Pro with the M1 chip. So instead of developing on Mac and cross compiling for windows, I decided to try and develop on Windows for windows.
I'm using parallels to run a Windows 10 virtual machine and after a lot of trial and error I was finally able to compile and execute a GTK program using msys2.
There is just one problem: No keyboard functionality in the GTK application. With the error message in the command prompt: "Failed to load keyboard layout DLL for layout A0000409: C:\WINDOWS\system32\KbdPrlUS.dll"
I solved my previous DLL issue by adding a path to the system variables. How might I approach addressing this keyboard layout DLL issue? The file definitely already exists at that location.
EDIT Here is the code that compiles (and works) but doesn't register and letter keypress from the keyboard. The same code works on Mac OS just fine.
#include <gtk/gtk.h>
static GtkTextBuffer *tb = NULL;
static GtkTextBuffer *tb2 = NULL;
static void
quit_activated(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *app = G_APPLICATION (user_data);
g_application_quit (app);
}
static void
click1_cb (GtkButton *btn,
gpointer user_data)
{
GtkTextIter start, end;
gtk_text_buffer_get_bounds(tb, &start, &end);
const GtkTextIter* start2 = &start;
const GtkTextIter* end2 = &end;
char* text = gtk_text_buffer_get_text(tb,start2,end2,false);
gtk_text_buffer_set_text (tb2, text, -1);
}
static void
app_activate (GApplication *app,
gpointer user_data)
{
GtkWidget *win;
GtkWidget *tv;
GtkWidget *tv2;
GtkWidget *box;
GtkWidget *btn;
GtkWidget *btn2;
gchar *text;
text =
"Input some text "
"As many lines as you want\n"
"One day, he went into a mountain and found a shining bamboo. "
"\"What a mysterious bamboo it is!,\" he said. "
"He cut it, then there was a small cute baby girl in it. "
"The girl was shining faintly. "
"He thought this baby girl is a gift from Heaven and took her home.\n"
"His wife was surprized at his tale. "
"They were very happy because they had no children. "
;
win = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_title (GTK_WINDOW (win), "Taketori");
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
gtk_window_set_child (GTK_WINDOW (win), box);
btn = gtk_button_new_with_label ("Execute.");
g_signal_connect (btn, "clicked", G_CALLBACK (click1_cb), NULL);
tv = gtk_text_view_new ();
tv2 = gtk_text_view_new ();
tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
tb2 = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv2));
gtk_text_buffer_set_text (tb2, "", -1);
gtk_text_buffer_set_text (tb, text, -1);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv2), GTK_WRAP_WORD_CHAR);
gtk_box_append (GTK_BOX (box),tv);
gtk_box_append (GTK_BOX (box), tv2);
gtk_box_append (GTK_BOX (box), btn);
/*
GSimpleAction *act_quit = g_simple_action_new ("quit", NULL);
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION(act_quit));
g_signal_connect (act_quit,"activate",G_CALLBACK (quit_activated),app);
GMenu *menubar = g_menu_new();
GMenuItem *menu_item_menu = g_menu_item_new ("Menu",NULL);
GMenu *menu = g_menu_new();
GMenuItem *menu_item_quit = g_menu_item_new ("Quit","app.quit");
g_menu_append_item (menu, menu_item_quit);
g_object_unref (menu_item_quit);
g_menu_set_submenu (menu_item_menu,G_MENU_MODEL(menu));
g_menu_append_item (menubar,menu_item_menu);
g_object_unref(menu_item_menu);*/
//gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar));
//gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);
gtk_widget_show (win);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int stat;
app = gtk_application_new ("com.gitbut.fff", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
stat = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return stat;
}
I am trying to show the gstreamer video in qt frameless window .
My gstreamer pipeline for which i am creating code is : gst-launch-1.0 -v rtspsrc location=rtsp://192.168.1.15:8554/test ! rtpjitterbuffer ! rtph264depay ! avdec_h264 ! d3dvideosink sync=false
This is my first question please answer me. My code is as below
My code is working for a qt window. It is showing the video which it is receiving
from rtsp link but i have two major issues in it:
1. When i minimize this window, It loses it's output video and starts to show a blank screen. 2. I want to open this video in a frameless window but if i do so then it displays nothing.
I am using Qt-4.8.12 and gstreamer version 1.4.5 for windows 7 64 bit. Any help regarding these two issues is highly appreciated. Thanks in Advance.
#include <glib.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
#include <QApplication>
#include <QTimer>
#include <QWidget>
#include <stdio.h>
#include "qmainwindow.h"
static void on_pad_added (GstElement *element, GstPad *pad, gpointer data);
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data);
int main(int argc, char *argv[])
{
if (!g_thread_supported ())
g_thread_init (NULL);
/* Initialize GStreamer */
gst_init (&argc, &argv);
QApplication app(argc, argv);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
/* Creating Elements */
//GstElement *pipeLine = gst_pipeline_new ("xvoverlay");
QWidget window;
// QMainWindow window;
window.resize(1024,768);
WId xwinid=window.winId();
GMainLoop *loop;
GstElement *pipeLine, *rtspSrc, *rtpJitterBuffer, *rtpH264Depay, *avDecH264, *videoSink;
rtspSrc = gst_element_factory_make("rtspsrc", NULL);
rtpJitterBuffer = gst_element_factory_make("rtpjitterbuffer", NULL);
rtpH264Depay = gst_element_factory_make("rtph264depay", NULL);
avDecH264 = gst_element_factory_make("avdec_h264", NULL);
videoSink = gst_element_factory_make("d3dvideosink", NULL);
loop = g_main_loop_new (NULL, FALSE);
if (!rtspSrc || !rtpJitterBuffer || !rtpH264Depay || !avDecH264 || !videoSink)
{
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Set element properties */
g_object_set( rtspSrc, "location", "rtsp://192.168.1.16:8554/test" , NULL);
g_object_set( videoSink, "sync", false, NULL);
/*Initializing Pipeline*/
pipeLine = gst_pipeline_new ("TestPipeLine");
if (!pipeLine)
{
g_printerr ("Pipeline could not be created.");
}
/* we add a message handler */
GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeLine));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/*Adding Components to the pipeline */
gst_bin_add_many (GST_BIN(pipeLine),
rtspSrc,
rtpJitterBuffer,
rtpH264Depay,
avDecH264,
videoSink,
NULL);
/* if (gst_element_link (rtspSrc, rtpJitterBuffer) != TRUE)
{
g_printerr ("rtspSrc & rtpJitterBuffer could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
}
*/
if (gst_element_link (rtpJitterBuffer, rtpH264Depay) != TRUE)
{
g_printerr ("rtpJitterBuffer and rtpH264Depay could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
}
if (gst_element_link (rtpH264Depay, avDecH264) != TRUE)
{
g_printerr ("rtpH264Depay and avDecH264 could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
}
if (gst_element_link (avDecH264, videoSink) != TRUE)
{
g_printerr ("avDecH264 and videoSink could not be linked.\n");
gst_object_unref (pipeLine);
return -1;
}
g_signal_connect (rtspSrc, "pad-added", G_CALLBACK (on_pad_added), rtpJitterBuffer);
window.setWindowFlags(Qt::FramelessWindowHint);
// else
// g_printerr("Pipeline created");zz
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY(videoSink), guintptr(xwinid));
window.show();
/* Set the pipeline to "playing" state*/
g_print ("Now playing: %s\n", argv[1]);
gst_element_set_state (pipeLine, GST_STATE_PLAYING);
app.exec();
/* Iterate */
g_print ("Running...\n");
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeLine, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeLine));
return 0;
}
static void on_pad_added (GstElement *element, GstPad *pad, gpointer data)
{
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
/* We can now link this pad with the vorbis-decoder sink pad */
g_print ("Dynamic pad created, linking demuxer/decoder\n");
sinkpad = gst_element_get_static_pad (decoder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
If you switch back to using QWindow, this will work:
window.setWindowFlags (Qt::FramelessWindowHint);
I'm not sure how, but I think something similar is available for QWidget.
I am using glade to make an user interface.
i have successfully generated the glade file
Now i have to include this file in my C code.
I am using following code:
#include <stdlib.h>
#include<gtk/gtk.h>
int main (int argc, char *argv[])
{
GtkWidget *builder,*window,*button;
gtk_init (&argc, &argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"shiv.glade",NULL);
window=GTK_WIDGET (gtk_builder_get_object(builder,"window1")) ;
button=GTK_WIDGET (gtk_builder_get_object(builder,"button1"));
g_object_unref(G_OBJECT(builder));
gtk_widget_show(button);
gtk_widget_show(window);
gtk_main ();
return 0;
}
My UI is a simple window having a button without any callback function.
I am getting following errors on execution
GTK-CRITICAL **: IA__gtk_widget_show assertion 'GTK_IS_WIDGET(widget)' failed
Change:
GtkWidget *builder,*window,*button;
with:
GtkWidget *window,*button;
GtkBuilder *builder;
this should fix.
Example:
#include <stdlib.h>
#include <gtk/gtk.h>
static void
close_window ( GtkWidget *widget, gpointer window)
{
printf("application close...\n");
gtk_widget_destroy((GtkWidget*)window);
}
int main (int argc, char *argv[])
{
GtkWidget *window, *button;
GtkBuilder *builder;
gtk_init (&argc, &argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"a.glade",NULL);
window = GTK_WIDGET (gtk_builder_get_object(builder,"window1")) ;
button = GTK_WIDGET (gtk_builder_get_object(builder,"button1"));
g_signal_connect (G_OBJECT (button), "clicked",G_CALLBACK (close_window),window);
g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window));
g_object_unref(G_OBJECT(builder));
gtk_widget_show_all( window );
gtk_main ();
return 0;
}
From GTK3 reference manual:
GtkBuilder — Build an interface from an XML UI definition;
GtkWidget — Base class for all widgets
I found out that Color Selector from the GTK+ Code Demos is a quite nice color chooser. Thus, I would like to use it as a standalone application without having to run gtk-demos every time.
I tried to compile the example code which is:
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkWidget *da;
static GdkColor color;
static GtkWidget *frame;
/* Expose callback for the drawing area
*/
static gboolean
expose_event_callback (GtkWidget *widget,
GdkEventExpose *event,
gpointer data)
{
GdkWindow *window = gtk_widget_get_window (widget);
if (window)
{
GtkStyle *style;
cairo_t *cr;
style = gtk_widget_get_style (widget);
cr = gdk_cairo_create (window);
gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
gdk_cairo_rectangle (cr, &event->area);
cairo_fill (cr);
cairo_destroy (cr);
}
return TRUE;
}
static void
change_color_callback (GtkWidget *button,
gpointer data)
{
GtkWidget *dialog;
GtkColorSelection *colorsel;
gint response;
dialog = gtk_color_selection_dialog_new ("Changing color");
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
colorsel =
GTK_COLOR_SELECTION (gtk_color_selection_dialog_get_color_selection (GTK_COLOR_SELECTION_DIALOG (dialog)));
gtk_color_selection_set_previous_color (colorsel, &color);
gtk_color_selection_set_current_color (colorsel, &color);
gtk_color_selection_set_has_palette (colorsel, TRUE);
response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response == GTK_RESPONSE_OK)
{
gtk_color_selection_get_current_color (colorsel,
&color);
gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &color);
}
gtk_widget_destroy (dialog);
}
GtkWidget *
do_colorsel (GtkWidget *do_widget)
{
GtkWidget *vbox;
GtkWidget *button;
GtkWidget *alignment;
if (!window)
{
color.red = 0;
color.blue = 65535;
color.green = 0;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_screen (GTK_WINDOW (window),
gtk_widget_get_screen (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Color Selection");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
vbox = gtk_vbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
gtk_container_add (GTK_CONTAINER (window), vbox);
/*
* Create the color swatch area
*/
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
da = gtk_drawing_area_new ();
g_signal_connect (da, "expose_event",
G_CALLBACK (expose_event_callback), NULL);
/* set a minimum size */
gtk_widget_set_size_request (da, 200, 200);
/* set the color */
gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &color);
gtk_container_add (GTK_CONTAINER (frame), da);
alignment = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
button = gtk_button_new_with_mnemonic ("_Change the above color");
gtk_container_add (GTK_CONTAINER (alignment), button);
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
g_signal_connect (button, "clicked",
G_CALLBACK (change_color_callback), NULL);
}
if (!gtk_widget_get_visible (window))
{
gtk_widget_show_all (window);
}
else
{
gtk_widget_destroy (window);
window = NULL;
}
return window;
}
The error is:
[orschiro#thinkpad ~]$ gcc `pkg-config --cflags --libs gtk+-3.0` -o colorSelector colorSelector.ccolorSelector.c: In function ‘expose_event_callback’:
colorSelector.c:26:7: warning: ‘gdk_cairo_set_source_color’ is deprecated (declared at /usr/include/gtk-3.0/gdk/gdkcairo.h:58): Use 'gdk_cairo_set_source_rgba' instead [-Wdeprecated-declarations]
colorSelector.c: In function ‘change_color_callback’:
colorSelector.c:44:3: warning: ‘gtk_color_selection_dialog_new’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkcolorseldialog.h:73): Use 'gtk_color_chooser_dialog_new' instead [-Wdeprecated-declarations]
colorSelector.c:49:5: warning: ‘gtk_color_selection_dialog_get_color_selection’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkcolorseldialog.h:75): Use 'GtkColorChooser' instead [-Wdeprecated-declarations]
colorSelector.c:51:3: warning: ‘gtk_color_selection_set_previous_color’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkcolorsel.h:148) [-Wdeprecated-declarations]
colorSelector.c:52:3: warning: ‘gtk_color_selection_set_current_color’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkcolorsel.h:142): Use 'gtk_color_chooser_set_rgba' instead [-Wdeprecated-declarations]
colorSelector.c:53:3: warning: ‘gtk_color_selection_set_has_palette’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkcolorsel.h:100) [-Wdeprecated-declarations]
colorSelector.c:59:7: warning: ‘gtk_color_selection_get_current_color’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkcolorsel.h:145): Use 'gtk_color_chooser_get_rgba' instead [-Wdeprecated-declarations]
colorSelector.c: In function ‘do_colorsel’:
colorSelector.c:91:7: warning: ‘gtk_vbox_new’ is deprecated (declared at /usr/include/gtk-3.0/gtk/deprecated/gtkvbox.h:60): Use 'gtk_box_new' instead [-Wdeprecated-declarations]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Installed packages:
gtk2 2.24.14-1
gtk3 3.6.2-1
gcc-libs-multilib 4.7.2-2
gcc-multilib 4.7.2-2
Could someone please explain me the error?
Your source code is incomplete, the main function is missing. gtk-demo is organised so it has a single main that calls some submodules and processes them the same way, and you're missing that main.
The other warning come from the fact that this example code you're trying to compile was done for GTK 2, and you're trying to build it against GTK 3.
You'll find all the missing parts in the gtk-demo directory of the GTK+ repository.
I've been trying to detect click on a Gtk::Image with gtkmm for over 2 hours, but I couldn't get it to work. It does compile and execute fine, but the event is never triggered.
Some stuff I tried, that compiles, does not crash, but doesn't work:
m_image = manage(new Gtk::Image(Gtk::Stock::APPLY, Gtk::ICON_SIZE_BUTTON));
m_image->add_events(Gdk::ALL_EVENTS_MASK);
m_hbox->pack_start(*m_image, Gtk::PACK_SHRINK);
m_image->signal_button_release_event()
.connect(sigc::hide(sigc::mem_fun(*this, &Todo::switchStatus)));
m_image->show();
or
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/button.h>
#include <gtkmm/stock.h>
#include <gtkmm/image.h>
#include <iostream>
using namespace std;
class Win : public Gtk::Window
{
public:
Win();
bool link(GdkEventButton* e);
private:
Gtk::Image image;
};
Win::Win()
: image(Gtk::Stock::APPLY, Gtk::ICON_SIZE_BUTTON)
{
cerr << "created" << endl;
image.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
image.signal_button_release_event().connect(sigc::mem_fun(*this, &Win::link));
image.show();
add(image);
}
bool Win::link(GdkEventButton* e)
{
cerr << "kuh" << endl;
}
int main(int argc, char *argv[])
{
Gtk::Main app(argc, argv);
Gtk::Window window;
window.resize(300, 500);
Win win;
Gtk::Main::run(win);
return 0;
}
From http://developer.gnome.org/gtkmm/unstable/classGtk_1_1Image.html:
Gtk::Image is a "no window" widget (has no Gdk::Window of its own), so by default does not receive events. If you want to receive events on the image, such as button clicks, place the image inside a Gtk::EventBox, then connect to the event signals on the event box
So I guess try to put a signal on an eventbox after wrapping the image with the EventBox.
I like to put a button overtop of the image with an opacity of 0. Then you can use the click event from it instead.
This thread is quite old but still popular. I came across the same problem and I coded this code, maybe it can help someone save tim. My code detects the click ONLY if the pointer is hovering the image.
#include <gtk/gtk.h>
//compile with cc `pkg-config --cflags gtk+-3.0` text.c `pkg-config --libs gtk+-3.0` -o text
static void click_callback(GtkWidget *widget, GdkEventButton *event, gpointer );
static gboolean inRange(gint value, gint min, gint max);
static gboolean pointInRect(gint mouseX, gint mouseY, gint wx, gint wy, gint width, gint height);
GtkWidget *image;
GtkWidget *image2;
int main (int argc, char *argv[])
{
GtkWidget *event_box;
GtkWidget *window;
GtkWidget *box;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
/* GTK_ALIGN_CENTER is necessary otherwise
* the callback triggers from the space on
* the top and the bottom of the image */
gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
image = gtk_image_new_from_file("image1.png");
image2 = gtk_image_new_from_file("image2.png");
gtk_box_pack_start(GTK_BOX(box), image, TRUE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), image2, TRUE, FALSE, 0);
event_box = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (event_box), box);
gtk_container_add (GTK_CONTAINER (window), event_box);
g_signal_connect(window, "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect( event_box, "button_press_event", G_CALLBACK( click_callback ), image);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(window), "Image click event");
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void click_callback(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
GtkAllocation alloc;
GtkAllocation alloc2;
gtk_widget_get_allocation(image, &alloc);
gtk_widget_get_allocation(image2, &alloc2);
if (pointInRect(event->x, event->y, alloc.x, alloc.y, alloc.width, alloc.height))
g_print("You clicked from image\n");
if (pointInRect(event->x, event->y, alloc2.x, alloc2.y, alloc2.width, alloc2.height))
g_print("You clicked from image2\n");
}
static gboolean pointInRect(gint mouseX, gint mouseY, gint wx, gint wy, gint width, gint height)
{
return inRange(mouseX, wx, wx + width) &&
inRange(mouseY, wy, wy + height);
}
static gboolean inRange(gint value, gint min, gint max)
{
return (value >= min && value <= max);
}