mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-05-01 03:31:33 +00:00
Cleaning: Fixes #130, Refactor util.c in Start menu plugin
This commit is contained in:
@@ -26,8 +26,14 @@ pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
|
||||
|
||||
add_library(
|
||||
wintc-exec
|
||||
src/action.h
|
||||
src/action.c
|
||||
src/desktop.h
|
||||
src/desktop.c
|
||||
src/exec.h
|
||||
src/exec.c
|
||||
src/mime.h
|
||||
src/mime.c
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
|
||||
@@ -4,24 +4,66 @@
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib.h>
|
||||
|
||||
//
|
||||
// Actions
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
WINTC_ACTION_MYDOCS,
|
||||
WINTC_ACTION_MYRECENTS,
|
||||
WINTC_ACTION_MYPICS,
|
||||
WINTC_ACTION_MYMUSIC,
|
||||
WINTC_ACTION_MYCOMP,
|
||||
WINTC_ACTION_CONTROL,
|
||||
WINTC_ACTION_MIMEMGMT,
|
||||
WINTC_ACTION_CONNECTTO,
|
||||
WINTC_ACTION_PRINTERS,
|
||||
WINTC_ACTION_HELP,
|
||||
WINTC_ACTION_SEARCH,
|
||||
WINTC_ACTION_RUN,
|
||||
WINTC_ACTION_LOGOFF,
|
||||
WINTC_ACTION_SHUTDOWN
|
||||
} WinTCAction;
|
||||
|
||||
gboolean wintc_launch_action(
|
||||
WinTCAction action_id,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
//
|
||||
// Desktop entries
|
||||
//
|
||||
gchar* wintc_desktop_app_info_get_command(
|
||||
GDesktopAppInfo* entry
|
||||
);
|
||||
|
||||
gchar* wintc_expand_desktop_entry_cmdline(
|
||||
const gchar* cmdline,
|
||||
const gchar* name,
|
||||
const gchar* icon_name,
|
||||
const gchar* entry_path,
|
||||
gboolean needs_terminal
|
||||
);
|
||||
|
||||
//
|
||||
// Execution
|
||||
//
|
||||
gboolean wintc_launch_command(
|
||||
const gchar* command,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
//
|
||||
// MIME types
|
||||
//
|
||||
gchar* wintc_query_mime_for_file(
|
||||
const gchar* filepath,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
gchar* wintc_query_mime_handler(
|
||||
const gchar* mime_query,
|
||||
GError** out_error,
|
||||
GDesktopAppInfo** out_entry
|
||||
GDesktopAppInfo* wintc_query_mime_handler(
|
||||
const gchar* mime_query,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
82
shared/exec/src/action.c
Normal file
82
shared/exec/src/action.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <glib.h>
|
||||
#include <wintc-comgtk.h>
|
||||
|
||||
#include "action.h"
|
||||
#include "exec.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gboolean wintc_launch_action(
|
||||
WinTCAction action_id,
|
||||
GError** out_error
|
||||
)
|
||||
{
|
||||
const gchar* cmdline;
|
||||
|
||||
switch (action_id)
|
||||
{
|
||||
case WINTC_ACTION_MYDOCS:
|
||||
cmdline = "exo-open --launch FileManager Documents";
|
||||
break;
|
||||
|
||||
case WINTC_ACTION_MYPICS:
|
||||
cmdline = "exo-open --launch FileManager Pictures";
|
||||
break;
|
||||
|
||||
case WINTC_ACTION_MYMUSIC:
|
||||
cmdline = "exo-open --launch FileManager Music";
|
||||
break;
|
||||
|
||||
// TODO: There isn't really a good option for this at the moment, maybe if we
|
||||
// implement an Explorer replica we can have it open a view of disks
|
||||
//
|
||||
case WINTC_ACTION_MYCOMP:
|
||||
cmdline = "exo-open --launch FileManager /";
|
||||
break;
|
||||
|
||||
case WINTC_ACTION_CONTROL:
|
||||
cmdline = "xfce4-settings-manager";
|
||||
break;
|
||||
|
||||
case WINTC_ACTION_MIMEMGMT:
|
||||
cmdline = "xfce4-mime-settings";
|
||||
break;
|
||||
|
||||
case WINTC_ACTION_PRINTERS:
|
||||
cmdline = "system-config-printer";
|
||||
break;
|
||||
|
||||
case WINTC_ACTION_RUN:
|
||||
// TODO: In future we will handle missing components gracefully (say, if
|
||||
// the Run component is missing here)
|
||||
//
|
||||
// See issue #134 for details
|
||||
//
|
||||
cmdline = "run";
|
||||
break;
|
||||
|
||||
// TODO: One day write our own log off and shut down dialogs, and execute
|
||||
// them here
|
||||
//
|
||||
case WINTC_ACTION_LOGOFF:
|
||||
case WINTC_ACTION_SHUTDOWN:
|
||||
cmdline = "xfce4-session-logout";
|
||||
break;
|
||||
|
||||
// Default to 'not implemented' error
|
||||
//
|
||||
default:
|
||||
g_set_error(
|
||||
out_error,
|
||||
WINTC_GENERAL_ERROR,
|
||||
WINTC_GENERAL_ERROR_NOTIMPL,
|
||||
"Action code is not implemented: %d",
|
||||
action_id
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return wintc_launch_command(cmdline, out_error);
|
||||
}
|
||||
29
shared/exec/src/action.h
Normal file
29
shared/exec/src/action.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __ACTIONS_H__
|
||||
#define __ACTIONS_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WINTC_ACTION_MYDOCS,
|
||||
WINTC_ACTION_MYRECENTS,
|
||||
WINTC_ACTION_MYPICS,
|
||||
WINTC_ACTION_MYMUSIC,
|
||||
WINTC_ACTION_MYCOMP,
|
||||
WINTC_ACTION_CONTROL,
|
||||
WINTC_ACTION_MIMEMGMT,
|
||||
WINTC_ACTION_CONNECTTO,
|
||||
WINTC_ACTION_PRINTERS,
|
||||
WINTC_ACTION_HELP,
|
||||
WINTC_ACTION_SEARCH,
|
||||
WINTC_ACTION_RUN,
|
||||
WINTC_ACTION_LOGOFF,
|
||||
WINTC_ACTION_SHUTDOWN
|
||||
} WinTCAction;
|
||||
|
||||
gboolean wintc_launch_action(
|
||||
WinTCAction action_id,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
#endif
|
||||
115
shared/exec/src/desktop.c
Normal file
115
shared/exec/src/desktop.c
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "desktop.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gchar* wintc_desktop_app_info_get_command(
|
||||
GDesktopAppInfo* entry
|
||||
)
|
||||
{
|
||||
GAppInfo* app_info = G_APP_INFO(entry);
|
||||
|
||||
const gchar* cmd_line = g_app_info_get_commandline(app_info);
|
||||
const gchar* exe_path = g_app_info_get_executable(app_info);
|
||||
|
||||
if (cmd_line != NULL)
|
||||
{
|
||||
gchar* expanded;
|
||||
gchar* icon_name = g_path_get_basename(exe_path);
|
||||
|
||||
expanded =
|
||||
wintc_expand_desktop_entry_cmdline(
|
||||
cmd_line,
|
||||
g_app_info_get_name(app_info),
|
||||
icon_name,
|
||||
g_desktop_app_info_get_filename(entry),
|
||||
FALSE
|
||||
);
|
||||
|
||||
g_free(icon_name);
|
||||
|
||||
return expanded;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_strdup(exe_path);
|
||||
}
|
||||
}
|
||||
|
||||
gchar* wintc_expand_desktop_entry_cmdline(
|
||||
const gchar* cmdline,
|
||||
const gchar* name,
|
||||
const gchar* icon_name,
|
||||
const gchar* entry_path,
|
||||
gboolean needs_terminal
|
||||
)
|
||||
{
|
||||
GString* expanded = g_string_sized_new(250);
|
||||
|
||||
if (needs_terminal)
|
||||
{
|
||||
g_string_append(
|
||||
expanded,
|
||||
"exo-open --launch TerminalEmulator"
|
||||
);
|
||||
}
|
||||
|
||||
// Iterate through cmdline character by character to expand shortcodes
|
||||
//
|
||||
const gchar* iter;
|
||||
|
||||
for (iter = cmdline; *iter != '\0'; iter++)
|
||||
{
|
||||
if (
|
||||
iter[0] == '%' &&
|
||||
iter[1] != '\0'
|
||||
)
|
||||
{
|
||||
switch (*++iter)
|
||||
{
|
||||
case 'c':
|
||||
if (name != NULL)
|
||||
{
|
||||
g_string_append(
|
||||
expanded,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (icon_name != NULL)
|
||||
{
|
||||
g_string_append(
|
||||
expanded,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
g_string_append(
|
||||
expanded,
|
||||
entry_path
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case '%':
|
||||
g_string_append_c(expanded, '%');
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_c(expanded, *iter);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free(expanded, FALSE);
|
||||
}
|
||||
19
shared/exec/src/desktop.h
Normal file
19
shared/exec/src/desktop.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __DESKTOP_H__
|
||||
#define __DESKTOP_H__
|
||||
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib.h>
|
||||
|
||||
gchar* wintc_desktop_app_info_get_command(
|
||||
GDesktopAppInfo* entry
|
||||
);
|
||||
|
||||
gchar* wintc_expand_desktop_entry_cmdline(
|
||||
const gchar* cmdline,
|
||||
const gchar* name,
|
||||
const gchar* icon_name,
|
||||
const gchar* entry_path,
|
||||
gboolean needs_terminal
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <sys/wait.h>
|
||||
#include <wintc-comgtk.h>
|
||||
|
||||
#include "desktop.h"
|
||||
#include "mime.h"
|
||||
#include "exec.h"
|
||||
|
||||
//
|
||||
@@ -18,14 +20,6 @@ typedef gboolean (*CmdParseFunc) (
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static gchar* expand_desktop_entry_cmdline(
|
||||
const gchar* cmdline,
|
||||
const gchar* name,
|
||||
const gchar* icon_name,
|
||||
const gchar* entry_path,
|
||||
gboolean needs_terminal
|
||||
);
|
||||
|
||||
static gboolean parse_file_in_cmdline(
|
||||
const gchar* cmdline,
|
||||
gchar** out_cmdline,
|
||||
@@ -66,39 +60,6 @@ static CmdParseFunc parsers[] = {
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gchar* wintc_desktop_app_info_get_command(
|
||||
GDesktopAppInfo* entry
|
||||
)
|
||||
{
|
||||
GAppInfo* app_info = G_APP_INFO(entry);
|
||||
|
||||
const gchar* cmd_line = g_app_info_get_commandline(app_info);
|
||||
const gchar* exe_path = g_app_info_get_executable(app_info);
|
||||
|
||||
if (cmd_line != NULL)
|
||||
{
|
||||
gchar* expanded;
|
||||
gchar* icon_name = g_path_get_basename(exe_path);
|
||||
|
||||
expanded =
|
||||
expand_desktop_entry_cmdline(
|
||||
cmd_line,
|
||||
g_app_info_get_name(app_info),
|
||||
icon_name,
|
||||
g_desktop_app_info_get_filename(entry),
|
||||
FALSE
|
||||
);
|
||||
|
||||
g_free(icon_name);
|
||||
|
||||
return expanded;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_strdup(exe_path);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean wintc_launch_command(
|
||||
const gchar* cmdline,
|
||||
GError** out_error
|
||||
@@ -193,285 +154,19 @@ gboolean wintc_launch_command(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gchar* wintc_query_mime_for_file(
|
||||
const gchar* filepath,
|
||||
GError** out_error
|
||||
)
|
||||
{
|
||||
gchar* xdg_query_cmd =
|
||||
g_strconcat(
|
||||
"xdg-mime query filetype \"",
|
||||
filepath,
|
||||
"\"",
|
||||
NULL
|
||||
);
|
||||
|
||||
gchar* cmd_output = NULL;
|
||||
GError* error = NULL;
|
||||
gint status;
|
||||
gboolean success = FALSE;
|
||||
|
||||
WINTC_LOG_DEBUG("Querying MIME type for: %s", filepath);
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(out_error);
|
||||
|
||||
// Run the query
|
||||
//
|
||||
success =
|
||||
g_spawn_command_line_sync(
|
||||
xdg_query_cmd,
|
||||
&cmd_output,
|
||||
NULL,
|
||||
&status,
|
||||
&error
|
||||
);
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
|
||||
g_free(xdg_query_cmd);
|
||||
|
||||
if (success && status == 0)
|
||||
{
|
||||
g_strstrip(cmd_output);
|
||||
|
||||
WINTC_LOG_DEBUG("Determined: %s", cmd_output);
|
||||
|
||||
return cmd_output;
|
||||
}
|
||||
|
||||
// Handle errors
|
||||
//
|
||||
if (error != NULL)
|
||||
{
|
||||
WINTC_LOG_DEBUG("An error occurred: %s", error->message);
|
||||
|
||||
g_propagate_error(out_error, error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINTC_LOG_DEBUG("Failed with code %d", status);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case 2: // File not found
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_NOENT,
|
||||
"Cannot find file or folder '%s'.",
|
||||
filepath
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
"Unknown error occurred."
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar* wintc_query_mime_handler(
|
||||
const gchar* mime_query,
|
||||
GError** out_error,
|
||||
GDesktopAppInfo** out_entry
|
||||
)
|
||||
{
|
||||
gchar* xdg_query_cmd =
|
||||
g_strconcat(
|
||||
"xdg-mime query default ",
|
||||
mime_query,
|
||||
NULL
|
||||
);
|
||||
|
||||
GDesktopAppInfo* entry = NULL;
|
||||
gchar* cmd_output = NULL;
|
||||
GError* error = NULL;
|
||||
gchar* filename = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
WINTC_LOG_DEBUG("Querying handler for MIME type %s", mime_query);
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(out_error);
|
||||
WINTC_SAFE_REF_CLEAR(out_entry);
|
||||
|
||||
// Run the query
|
||||
//
|
||||
success =
|
||||
g_spawn_command_line_sync(
|
||||
xdg_query_cmd,
|
||||
&cmd_output,
|
||||
NULL,
|
||||
NULL,
|
||||
&error
|
||||
);
|
||||
|
||||
g_free(xdg_query_cmd);
|
||||
|
||||
if (success)
|
||||
{
|
||||
// Did we actually get anything?
|
||||
//
|
||||
gint output_length = g_utf8_strlen(cmd_output, -1);
|
||||
|
||||
if (output_length == 0)
|
||||
{
|
||||
WINTC_LOG_DEBUG("No handler found!");
|
||||
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_NOSYS,
|
||||
"No program is mapped to MIME type '%s'.",
|
||||
mime_query
|
||||
);
|
||||
|
||||
g_free(cmd_output);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We did! It's a desktop entry, so retrieve it
|
||||
//
|
||||
filename = g_utf8_substring(
|
||||
cmd_output,
|
||||
0,
|
||||
g_utf8_strlen(cmd_output, -1) - 1
|
||||
);
|
||||
entry = g_desktop_app_info_new(
|
||||
filename
|
||||
);
|
||||
|
||||
WINTC_LOG_DEBUG("Query returned: %s", filename);
|
||||
|
||||
g_free(cmd_output);
|
||||
g_free(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
WINTC_LOG_DEBUG("Failed to query MIME type: %s", error->message);
|
||||
|
||||
g_propagate_error(out_error, error);
|
||||
|
||||
g_free(cmd_output);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
"Unable to load desktop entry for MIME type handler '%s'.",
|
||||
mime_query
|
||||
);
|
||||
|
||||
WINTC_LOG_DEBUG("Failed to load desktop entry!?");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINTC_SAFE_REF_SET(out_entry, entry);
|
||||
|
||||
return wintc_desktop_app_info_get_command(entry);
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static gchar* expand_desktop_entry_cmdline(
|
||||
const gchar* cmdline,
|
||||
const gchar* name,
|
||||
const gchar* icon_name,
|
||||
const gchar* entry_path,
|
||||
gboolean needs_terminal
|
||||
)
|
||||
{
|
||||
GString* expanded = g_string_sized_new(250);
|
||||
|
||||
if (needs_terminal)
|
||||
{
|
||||
g_string_append(
|
||||
expanded,
|
||||
"exo-open --launch TerminalEmulator"
|
||||
);
|
||||
}
|
||||
|
||||
// Iterate through cmdline character by character to expand shortcodes
|
||||
//
|
||||
const gchar* iter;
|
||||
|
||||
for (iter = cmdline; *iter != '\0'; iter++)
|
||||
{
|
||||
if (
|
||||
iter[0] == '%' &&
|
||||
iter[1] != '\0'
|
||||
)
|
||||
{
|
||||
switch (*++iter)
|
||||
{
|
||||
case 'c':
|
||||
if (name != NULL)
|
||||
{
|
||||
g_string_append(
|
||||
expanded,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (icon_name != NULL)
|
||||
{
|
||||
g_string_append(
|
||||
expanded,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
g_string_append(
|
||||
expanded,
|
||||
entry_path
|
||||
);
|
||||
break;
|
||||
|
||||
case '%':
|
||||
g_string_append_c(expanded, '%');
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_c(expanded, *iter);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free(expanded, FALSE);
|
||||
}
|
||||
|
||||
static gboolean parse_file_in_cmdline(
|
||||
const gchar* cmdline,
|
||||
gchar** out_cmdline,
|
||||
GError** out_error
|
||||
)
|
||||
{
|
||||
GError* error = NULL;
|
||||
gchar* file_handler;
|
||||
gchar* file_mime;
|
||||
GError* error = NULL;
|
||||
gchar* file_mime;
|
||||
gchar* handler_cmdline;
|
||||
GDesktopAppInfo* handler_entry;
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(out_cmdline);
|
||||
WINTC_SAFE_REF_CLEAR(out_error);
|
||||
@@ -508,14 +203,13 @@ static gboolean parse_file_in_cmdline(
|
||||
{
|
||||
WINTC_LOG_DEBUG("Not an executable, will look for handler.");
|
||||
|
||||
file_handler =
|
||||
handler_entry =
|
||||
wintc_query_mime_handler(
|
||||
file_mime,
|
||||
&error,
|
||||
NULL
|
||||
&error
|
||||
);
|
||||
|
||||
if (file_handler == NULL)
|
||||
if (handler_entry == NULL)
|
||||
{
|
||||
WINTC_LOG_DEBUG("I have nothing to handle the file!");
|
||||
|
||||
@@ -529,18 +223,19 @@ static gboolean parse_file_in_cmdline(
|
||||
|
||||
// We found a handler, build the cmdline now and return
|
||||
//
|
||||
handler_cmdline = wintc_desktop_app_info_get_command(handler_entry);
|
||||
|
||||
WINTC_SAFE_REF_SET(
|
||||
out_cmdline,
|
||||
g_strconcat(
|
||||
file_handler,
|
||||
" \"",
|
||||
cmdline,
|
||||
"\"",
|
||||
NULL
|
||||
g_strdup_printf(
|
||||
"%s \"%s\"",
|
||||
handler_cmdline,
|
||||
cmdline
|
||||
)
|
||||
);
|
||||
|
||||
g_free(file_handler);
|
||||
g_clear_object(&handler_entry);
|
||||
g_free(handler_cmdline);
|
||||
g_free(file_mime);
|
||||
|
||||
return TRUE;
|
||||
@@ -657,12 +352,12 @@ static gboolean parse_url_in_cmdline(
|
||||
{
|
||||
static GRegex* url_regex = NULL;
|
||||
|
||||
gchar* app_name;
|
||||
GError* error = NULL;
|
||||
GString* final_cmdline;
|
||||
GMatchInfo* match_info;
|
||||
gchar* mime_type;
|
||||
gchar* uri_scheme;
|
||||
GError* error = NULL;
|
||||
GDesktopAppInfo* handler_entry;
|
||||
gchar* handler_cmdline;
|
||||
GMatchInfo* match_info;
|
||||
gchar* mime_type;
|
||||
gchar* uri_scheme;
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(out_cmdline);
|
||||
WINTC_SAFE_REF_CLEAR(out_error);
|
||||
@@ -708,23 +403,23 @@ static gboolean parse_url_in_cmdline(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Command line IS a URL, retrieve the scheme, query the handling program, return
|
||||
// program with URI as argument
|
||||
// Command line IS a URL, retrieve the scheme, query the handling program...
|
||||
//
|
||||
WINTC_LOG_DEBUG("Yeah, looks like a URL.");
|
||||
|
||||
uri_scheme = g_match_info_fetch(match_info, 1);
|
||||
mime_type = g_strconcat(
|
||||
"x-scheme-handler/",
|
||||
uri_scheme,
|
||||
NULL
|
||||
mime_type = g_strdup_printf(
|
||||
"x-scheme-handler/%s",
|
||||
uri_scheme
|
||||
);
|
||||
|
||||
app_name = wintc_query_mime_handler(mime_type, &error, NULL);
|
||||
handler_entry = wintc_query_mime_handler(mime_type, &error);
|
||||
|
||||
g_match_info_free(match_info);
|
||||
g_free(mime_type);
|
||||
g_free(uri_scheme);
|
||||
|
||||
if (app_name == NULL)
|
||||
if (handler_entry == NULL)
|
||||
{
|
||||
WINTC_LOG_DEBUG("I have nothing to handle the URL!");
|
||||
|
||||
@@ -733,13 +428,22 @@ static gboolean parse_url_in_cmdline(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
final_cmdline = g_string_sized_new(500);
|
||||
// Output the constructed cmdline, the application cmdline with the URL as the
|
||||
// argument
|
||||
//
|
||||
handler_cmdline = wintc_desktop_app_info_get_command(handler_entry);
|
||||
|
||||
g_string_append(final_cmdline, app_name);
|
||||
g_string_append(final_cmdline, " ");
|
||||
g_string_append(final_cmdline, cmdline);
|
||||
WINTC_SAFE_REF_SET(
|
||||
out_cmdline,
|
||||
g_strdup_printf(
|
||||
"%s %s",
|
||||
handler_cmdline,
|
||||
cmdline
|
||||
)
|
||||
);
|
||||
|
||||
WINTC_SAFE_REF_SET(out_cmdline, g_string_free(final_cmdline, FALSE));
|
||||
g_clear_object(&handler_entry);
|
||||
g_free(handler_cmdline);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,11 @@
|
||||
#ifndef __EXEC_H__
|
||||
#define __EXEC_H__
|
||||
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib.h>
|
||||
|
||||
gchar* wintc_desktop_app_info_get_command(
|
||||
GDesktopAppInfo* entry
|
||||
);
|
||||
|
||||
gboolean wintc_launch_command(
|
||||
const gchar* command,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
gchar* wintc_query_mime_for_file(
|
||||
const gchar* filepath,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
gchar* wintc_query_mime_handler(
|
||||
const gchar* mime_query,
|
||||
GError** out_error,
|
||||
GDesktopAppInfo** out_entry
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
191
shared/exec/src/mime.c
Normal file
191
shared/exec/src/mime.c
Normal file
@@ -0,0 +1,191 @@
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <wintc-comgtk.h>
|
||||
|
||||
#include "mime.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gchar* wintc_query_mime_for_file(
|
||||
const gchar* filepath,
|
||||
GError** out_error
|
||||
)
|
||||
{
|
||||
gchar* xdg_query_cmd =
|
||||
g_strdup_printf(
|
||||
"xdg-mime query filetype \"%s\"",
|
||||
filepath
|
||||
);
|
||||
|
||||
gchar* cmd_output = NULL;
|
||||
GError* error = NULL;
|
||||
gint status;
|
||||
gboolean success = FALSE;
|
||||
|
||||
WINTC_LOG_DEBUG("Querying MIME type for: %s", filepath);
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(out_error);
|
||||
|
||||
// Run the query
|
||||
//
|
||||
success =
|
||||
g_spawn_command_line_sync(
|
||||
xdg_query_cmd,
|
||||
&cmd_output,
|
||||
NULL,
|
||||
&status,
|
||||
&error
|
||||
);
|
||||
|
||||
status = WEXITSTATUS(status);
|
||||
|
||||
g_free(xdg_query_cmd);
|
||||
|
||||
if (success && status == 0)
|
||||
{
|
||||
g_strstrip(cmd_output);
|
||||
|
||||
WINTC_LOG_DEBUG("Determined: %s", cmd_output);
|
||||
|
||||
return cmd_output;
|
||||
}
|
||||
|
||||
// Handle errors
|
||||
//
|
||||
if (error != NULL)
|
||||
{
|
||||
WINTC_LOG_DEBUG("An error occurred: %s", error->message);
|
||||
|
||||
g_propagate_error(out_error, error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINTC_LOG_DEBUG("Failed with code %d", status);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case 2: // File not found
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_NOENT,
|
||||
"Cannot find file or folder '%s'.",
|
||||
filepath
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
"Unknown error occurred."
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GDesktopAppInfo* wintc_query_mime_handler(
|
||||
const gchar* mime_query,
|
||||
GError** out_error
|
||||
)
|
||||
{
|
||||
gchar* xdg_query_cmd =
|
||||
g_strdup_printf(
|
||||
"xdg-mime query default %s",
|
||||
mime_query
|
||||
);
|
||||
|
||||
gchar* cmd_output = NULL;
|
||||
GDesktopAppInfo* entry = NULL;
|
||||
GError* error = NULL;
|
||||
gchar* filename = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
WINTC_LOG_DEBUG("Querying handler for MIME type %s", mime_query);
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(out_error);
|
||||
|
||||
// Run query
|
||||
//
|
||||
success =
|
||||
g_spawn_command_line_sync(
|
||||
xdg_query_cmd,
|
||||
&cmd_output,
|
||||
NULL,
|
||||
NULL,
|
||||
&error
|
||||
);
|
||||
|
||||
g_free(xdg_query_cmd);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
WINTC_LOG_DEBUG("Failed to query MIME type: %s", error->message);
|
||||
|
||||
g_propagate_error(out_error, error);
|
||||
|
||||
g_free(cmd_output);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Did we really get anything
|
||||
//
|
||||
gint output_length = g_utf8_strlen(cmd_output, -1);
|
||||
|
||||
if (output_length == 0)
|
||||
{
|
||||
WINTC_LOG_DEBUG("No handler found!");
|
||||
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_NOSYS,
|
||||
"No program is mapped to MIME type '%s'.",
|
||||
mime_query
|
||||
);
|
||||
|
||||
g_free(cmd_output);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We did! It's a desktop entry, so retrieve it
|
||||
//
|
||||
filename = g_utf8_substring(
|
||||
cmd_output,
|
||||
0,
|
||||
g_utf8_strlen(cmd_output, -1) - 1
|
||||
);
|
||||
entry = g_desktop_app_info_new(filename);
|
||||
|
||||
WINTC_LOG_DEBUG("Query returned: %s", filename);
|
||||
|
||||
g_free(cmd_output);
|
||||
g_free(filename);
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
g_set_error(
|
||||
out_error,
|
||||
G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
"Unable to load desktop entry for MIME type handler '%s'.",
|
||||
mime_query
|
||||
);
|
||||
|
||||
WINTC_LOG_DEBUG("Association found, but the desktop entry doesn't exist.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
17
shared/exec/src/mime.h
Normal file
17
shared/exec/src/mime.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef __MIME_H__
|
||||
#define __MIME_H__
|
||||
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <glib.h>
|
||||
|
||||
gchar* wintc_query_mime_for_file(
|
||||
const gchar* filepath,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
GDesktopAppInfo* wintc_query_mime_handler(
|
||||
const gchar* mime_query,
|
||||
GError** out_error
|
||||
);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user