215 lines
5.2 KiB
C
215 lines
5.2 KiB
C
#include <gtk/gtk.h>
|
|
|
|
#include <gemgui.h>
|
|
#include <gemparse.h>
|
|
#include <gemini.h>
|
|
#include <url.h>
|
|
|
|
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;
|
|
}
|