#include #include #include #include #include GtkEntryBuffer *pathBarContent = NULL; GtkWidget *render = NULL; GtkWidget *scrollbar = NULL; char links[1024][20]; static void makeRender (FILE *file); static void loadPage (const char *link) { char *cursor = strchr (link, ':'); if (cursor == NULL) { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "Invalid URL !"); } else { int len = cursor - link; char scheme[30]; strncpy (scheme, link, len); scheme[len] = '\0'; if (strcmp (scheme, "gemini") == 0) { FILE *file = tmpfile (); if (file != NULL) { Url *url = urllib_init (); if (url != NULL) { if (!urllib_parse (url, link)) { char request[1030]; char host[1024]; sprintf (request, "%s\r\n", link); sprintf (host, "%s:%s", url->host, url->port ? url->port : "1965"); GEM_send_request (request, host, file); makeRender (file); fclose (file); } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "Invalid Gemini URL !"); } urllib_free (url); } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "Failed to create URL !"); } } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "Failed to open a temp file !"); } } else if (strcmp (scheme, "file") == 0) { cursor++; len = strlen (cursor); if (len >= 2 && cursor[0] == '/' && cursor[1] != '/') { FILE *file = fopen (cursor, "r"); if (file != NULL) { makeRender (file); fclose (file); } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "Failed to open the file !"); } } else if (len > 3 && cursor[0] == '/' && cursor[1] == '/' && cursor[2] == '/') { FILE *file; cursor += 2; file = fopen (cursor, "r"); if (file != NULL) { makeRender (file); fclose (file); } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "Failed to open the file !"); } } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "File url not supported !"); } } else { gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); addH1 (render, "This type of URL is not supported yet"); } } gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_show_all, NULL); } void linkAction (GtkWidget *widget, gpointer data) { loadPage ((const char*)data); } static void goAction (GtkWidget *widget, gpointer data) { loadPage ((const char*)gtk_entry_buffer_get_text (pathBarContent)); } static void makeRender (FILE *file) { if (render == NULL) { render = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (scrollbar), render); } else gtk_container_foreach (GTK_CONTAINER (render), (GtkCallback)gtk_widget_destroy, NULL); parseFile (file); } /* This function's goal is to build the main interface */ static void build_interface (GtkWidget *window, char *path) { GtkWidget *pathBar; GtkWidget *headerBar; GtkWidget *goButtonBox; GtkWidget *goButton; FILE *file = fopen (path, "r"); /* Building title bar */ scrollbar = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (window), scrollbar); headerBar = gtk_header_bar_new (); gtk_header_bar_set_title(GTK_HEADER_BAR (headerBar), "Scorpius"); gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerBar), TRUE); gtk_window_set_titlebar (GTK_WINDOW (window), headerBar); pathBarContent = gtk_entry_buffer_new (NULL, -1); pathBar = gtk_entry_new_with_buffer (pathBarContent); goButtonBox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); goButton = gtk_button_new_with_label ("Go !"); g_signal_connect (goButton, "clicked", G_CALLBACK (goAction), NULL); gtk_container_add (GTK_CONTAINER (goButtonBox), goButton); gtk_container_add (GTK_CONTAINER (headerBar), pathBar); gtk_container_add (GTK_CONTAINER (headerBar), goButtonBox); if (file != NULL) { makeRender (file); fclose (file); } } /* This function's goal is to create the window then show it */ static void activate (GtkApplication *app, gpointer user_data) { GtkWidget *window; window = gtk_application_window_new (app); gtk_window_set_title (GTK_WINDOW (window), "Scorpius"); gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); build_interface (window, (char *)user_data); gtk_widget_show_all (window); } int main (int argc, char **argv) { GtkApplication *app; int status; app = gtk_application_new ("ovh.rdelaage.mdviewer", G_APPLICATION_FLAGS_NONE); g_signal_connect (app, "activate", G_CALLBACK (activate), (argc >= 2) ? argv[1] : "readme.gmi"); status = g_application_run(G_APPLICATION (app), 1, argv); g_object_unref (app); return status; }