Gtk3: getting the icon file name for a mime type - mime-types

I’m writing a command line program to get the Gtk3 icon file name associated with a mime type... the idea’s to be able to do this:
$ ./gtk-mimetype-icon text/html
Mime type: text/html
Icon file: /usr/share/icons/gnome/48x48/mimetypes/text-html.png
Unfortunately, this is happening instead:
$ ./gtk-mimetype-icon text/html
(process:30041): Gtk-CRITICAL **: gtk_icon_theme_get_for_screen: assertion `GDK_IS_SCREEN (screen)' failed
(process:30041): Gtk-CRITICAL **: gtk_icon_theme_lookup_by_gicon: assertion `GTK_IS_ICON_THEME (icon_theme)' failed
Unable to load icon info, bailing!
After searching through the docs & googling for solutions, I’m bewildered by how to proceed. I am running this in an X terminal, with the DISPLAY properly exported:
$ env |grep DISPLAY
DISPLAY=:0.0
The program’s source is below; I’m building against glib2-2.30.3 and gtk3-3.2.4. Any insight’s appreciated!
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <stdio.h>
// save as gtk-mimetype.c and build w/:
// cc -o gtk-mimetype-icon `pkg-config --cflags --libs glib-2.0 gtk+-3.0` gtk-mimetype.c
// cf. http://unix.stackexchange.com/questions/11152/how-to-get-the-icon-for-a-mime-type
int
main (int argc, char **argv)
{
g_type_init ();
if (argc < 2) {
fprintf (stderr, "Usage: %s <mimetype\n", argv[0]);
return -1;
}
GIcon *icon = g_content_type_get_icon (argv[1]);
GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon (
gtk_icon_theme_get_default (),
icon,
48,
GTK_ICON_LOOKUP_GENERIC_FALLBACK);
const char *filename;
if (icon_info != NULL)
filename = gtk_icon_info_get_filename (icon_info);
else {
fprintf (stderr, "Unable to load icon info, bailing!\n");
return -1;
}
printf ("Mime type: %s\nIcon file: %s\n",
argv[1],
filename);
return 0;
}

you need to initialize the gtk framework, replace g_type_init (); with gtk_init(&argc, &argv);

Related

How to find file type(format) without extension file using c program? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have the image, txt file without extension. They are,
flower (image)
simple (txt)
I need to find file format for the above files using c.
currently i am working in linux.
Any one help me.
/* This program used to find the file format for without extention file */
#include <stdio.h>
#include <error.h>
#include <errno.h>
int main(int argc, char *argv[])
{
FILE *fp;
struct image image_bmp;
if (argc != 2) {
perror("Error in commandline argument\n");
exit(1);
}
fp = fopen(argv[1], "r");
if (fp == NULL)
error(1, errno, "Error in file open\n");
/* i am try to display argv[1] file format for without extention file
Ex: argv[1] is a txt file
argv[2] is a image file
*/
fclose(fp);
error(1, errno, "Error in file close\n");
return 0;
}
i know file command is solve this problem. But i am trying using c.
You can use the libmagic library (on Ubuntu, install libmagic-dev for headers). This is the library that also backs the file command; instead of using popen to run the file command you should use this library directly.
The following code shows an example on how to detect the file type of a named file (please note that error checking is omitted from function calls other than the magic_file call:
#include <magic.h>
#include <stdio.h>
int main(void) {
// open the magic library, with MAGIC_MIME_TYPE flag
// so that the mime type of the file is returned instead
// of human readable information
magic_t m = magic_open(MAGIC_MIME_TYPE);
// load the default database
magic_load(m, NULL);
// detect the mime type of a file named `a_file_without_extension`
const char *type = magic_file(m, "a_file_without_extension");
if (type) {
printf("The recognized type is %s\n", type);
}
else {
printf("An error occurred: %s\n", magic_error(m));
}
// close the database; in a long-running program you wouldn't
// need to close the handle all the time.
magic_close(m);
}
Prints out the mime type of the file named a_file_without_extension; e.g. say:
The recognized type is image/png
You can use popen() to run the file command, e.g.:
#include <stdio.h>
#include <limits.h>
int main(int argc, char *argv[])
{
char cmd[PATH_MAX];
char result[PATH_MAX];
int i;
for (i = 1; i < argc; ++i)
{
FILE *fp = NULL;
sprintf(cmd, "file '%s'", argv[i]);
fp = popen(cmd, "r");
if (fp == NULL)
{
perror("popen");
}
else
{
fgets(result, PATH_MAX, fp);
pclose(fp);
fputs(result, stdout);
}
}
return 0;
}
This works on pretty much any *nix-like OS (Linux, Mac OS X, FreeBSD, Solaris, etc).
Compile and run:
$ gcc -Wall popen_file.c
$ ./a.out a.out
a.out: Mach-O 64-bit executable x86_64
$ ./a.out foo
foo: directory
$ ./a.out chart
chart: PNG image data, 1249 x 961, 8-bit/color RGBA, non-interlaced

Why is GTK spewing a ton of (seemingly) irrelevant warnings?

Here is a very simple GTK application that creates an application indicator:
#include <gtk/gtk.h>
#include <libappindicator/app-indicator.h>
int main()
{
AppIndicator *indicator;
GtkWidget *menu;
GtkWidget *item1;
GtkWidget *item2;
GtkWidget *separator;
indicator = app_indicator_new("testapp", "distributor-logo", APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
menu = gtk_menu_new();
app_indicator_set_menu(indicator, GTK_MENU(menu));
app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE);
item1 = gtk_menu_item_new_with_label("Item 1");
item2 = gtk_menu_item_new_with_label("Item 2");
separator = gtk_separator_menu_item_new();
gtk_widget_show(item1);
gtk_widget_show(item2);
gtk_widget_show(separator);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item1);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item2);
gtk_main();
return 0;
}
I compiled the application with the following command:
gcc `pkg-config --cflags appindicator-0.1` -o testapp testapp.c \
`pkg-config --libs appindicator-0.1`
The application runs and displays the indicator as expected. However, it spews a ton of warnings that don't seem to have anything to do with my application. You can view the full list here, but here are the first few:
(process:17410): Gtk-CRITICAL **: IA__gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:17410): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:17410): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:17410): GLib-GObject-WARNING **: invalid (NULL) pointer instance
What do these warnings mean and how do I fix my application to prevent them from being raised in the first place?
I was able to make all of the warnings disappear by adding the following line to the beginning:
gtk_init(&argc, &argv);
I also modified the signature of main() to main(int argc, char **argv).

ANSI C compile error: expected expression before ‘,’ token

I continue to get this error when attempting to compile a bit of code I wrote up, with the location in the file being totally unhelpful. This uses gtk 2.0.
The following is what I receive at compile time:
charles#draton-generico:~/Documents/C89$ gcc -x c -ansi -g bahbahbah.c -o bahbahbah pkg-config --cflags --libs gtk+-2.0
bahbahbah.c: In function ‘main’:
bahbahbah.c:28:1: error: expected expression before ‘,’ token
The following is the code I am trying to compile:
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
void closure(void)
{
gtk_main_quit();
printf("gtk_main_quit() has been called.\n");
}
void main(int argc, char* argv[])
{
gboolean check = gtk_init_check(&argc, &argv);
if (check == FALSE)
{
printf("Failed to initialize toolkit.\nTerminating.\n");
exit(EXIT_FAILURE);
}
else
{
printf("Initialized toolkit.\n");
GtkWidget* main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title((GtkWindow*)main_window, "BLAH");
gtk_window_set_default_size((GtkWindow*)main_window, 700, 700);
g_signal_connect(main_window, "delete-event", closure, void);
gtk_widget_show(main_window);
printf("Window created, sleeping in gtk_main().\n");
gtk_main();
}
printf("Exiting.\n");
exit(EXIT_SUCCESS);
}
Please help. :(
Use NULL replace void in line 28.
g_signal_connect(main_window, "delete-event", closure, NULL);
void is a Key-word!
There is the describe of g_signal_connect():
#define g_signal_connect(instance, detailed_signal, c_handler, data)
Connects a GCallback function to a signal for a particular object.
The handler will be called before the default handler of the signal.
instance :
the instance to connect to.
detailed_signal :
a string of the form "signal-name::detail".
c_handler :
the GCallback to connect.
data :
data to pass to c_handler calls.
Returns :
the handler id
So, you just want pass nothing to this func? Then you should use NULL.

Segmentation fault at GTK+ program

I am trying to make an example of a simple GTK+ viewer using poppler and cairo which I found at gtkforums.com work. However I am getting a segmentation fault (I use anjuta).
When I use the debugger I get this:
ID:1
File: /usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0
Line: 0
Function: ??
Address: 0x1d3f16 (dont think that matters anyway)
terminal message while debugging:
Debug Terminal for the process:
------------------------------- &"warning: GDB: Failed to set controlling terminal: Operation not permitted\n"
GLib-GObject-WARNING **: cannot register existing type `GdkWindow'
GLib-GObject-CRITICAL **: g_object_new: assertion `G_TYPE_IS_OBJECT
(object_type)' failed
Here is my code:
#include <config.h>
#include <glib/gi18n.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <cairo.h>
#include <poppler.h>
/* gcc `pkg-config --cflags --libs gtk+-2.0 poppler-glib` -o pdfviewer pdfviewer.c */
static PopplerDocument* doc;
static PopplerPage* page;
static void
on_destroy(GtkWidget* w, gpointer data) {
gtk_main_quit();
}
static gboolean
on_expose(GtkWidget* w, GdkEventExpose* e, gpointer data) {
cairo_t* cr;
cr = gdk_cairo_create(w->window);
poppler_page_render(page, cr);
cairo_destroy(cr);
return FALSE;
}
int main(int argc, char* argv[]) {
GtkWidget* win;
GError* err = NULL;
gtk_init(&argc, &argv);
doc = poppler_document_new_from_file("file:///home/user/test.pdf", NULL, &err);
if (!doc) {
printf("%s\n", err->message);
g_object_unref(err);
return 2;
}
page = poppler_document_get_page(doc, 0);
if(!page) {
printf("Could not open first page of document\n");
g_object_unref(doc);
return 3;
}
int pages = poppler_document_get_n_pages(doc);
printf("There are %d pages in this pdf.\n", pages);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL);
g_signal_connect(G_OBJECT(win), "expose-event", G_CALLBACK(on_expose), NULL);
gtk_widget_set_app_paintable(win, TRUE);
gtk_widget_show_all(win);
gtk_main();
g_object_unref(page);
g_object_unref(doc);
return 0;
}
Based upon your comment it ("Cannot access memory at address 0x0") appears that the program has a function that fails, but you didn't check the function's return value to ensure it is not NULL before using it.
Based purely on the code example above the first case of that would be if gtk_window_new failed; then the g_signal_connect and other functions cannot use the win value sensibly.
When I compiled the snippet, it compiled fine without warnings, and executed correctly. There was a poppler error message about the PDF document, but it wasn't relevant to your problems.
So your problem is likely either elsewhere (not within the included example) or a trivial mistake.
One way to get more information is to set a breakpoint on g_log in the debugger and get a backtrace of the warning / critical. With the backtrace you'll be able to see where exactly your code is calling the gtk+ function that is failing.

How to use the "pcap_lookupdev()" in libpcap?

The code cant find any device, I want to know what does pcap_lookupdev() do ? thanks
#include <pcap.h>
int main(int argc, char *argv[])
{
pcap_t *handle;
char *dev;// = "eth0";
char errbuf[PCAP_ERRBUF_SIZE];
dev = pcap_lookupdev(errbuf);
if (dev == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
return(2);
}
printf("Device: %s\n", dev);
return(0);
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return(2);
}
}
pcap_lookupdev seems to just return the first device it can find(if any) except the loopback device.
Do you run this as root ? Normal users won't be allowed to open or inspect these devices.
Personally I find pcap_lookupdev rather useless as you don't really have control over what device it gives you.
When you are compiling the pcap programming. You need to mention -lpcap at the end of the programe file with root privilege. For example.
#gcc YourFileName.c -lpcap
#./a.out
or
#gcc -Wall -o YourFileName YourFileName.c -lpcap
#./YourFileName
Here, # indicate root user, gcc is GNU Compiler Collection, -lpcap indicate use libpcap library
The code has to be compiled, linked and executed as root:
sudo gcc -o dev-find dev-find.c lpcap
worked for me.

Resources