Skip to content

Commit

Permalink
rdp shell: SVG rendering at system-distro name space (#145)
Browse files Browse the repository at this point in the history
* SVG rendering at system-distro name space

* move fclose call

---------

Co-authored-by: Hideyuki Nagase <hideyukn@HIDEYUKN-SB3>
  • Loading branch information
hideyukn88 and Hideyuki Nagase authored May 8, 2023
1 parent b5e22ba commit 75aea1a
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 25 deletions.
45 changes: 39 additions & 6 deletions rdprail-shell/app-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

#include "shell.h"
#include "shared/helpers.h"
#include "shared/image-loader.h"

#if HAVE_GLIB
#include <glib.h>
Expand Down Expand Up @@ -118,6 +119,7 @@ struct app_entry {
char *working_dir;
char *icon_name;
char *icon_file;
bool is_icon_file_svg;
pixman_image_t* icon_image;
uint32_t icon_retry_count;
};
Expand Down Expand Up @@ -285,10 +287,12 @@ find_icon_file(struct app_entry *entry)
if (is_file_exist(buf))
goto Found;

#ifdef HAVE_LIBRSVG2
/* if not found, try again with .svg extension appended */
copy_string(&buf[len], sizeof buf - len, ".svg");
if (is_file_exist(buf))
goto Found;
#endif // HAVE_LIBRSVG2
}
}

Expand All @@ -301,8 +305,16 @@ find_icon_file(struct app_entry *entry)
return false;

Found:
len = strlen(icon_file);
if (len > 4) {
/* TODO: file contents should be verified */
char *ext = &icon_file[len - 4];
entry->is_icon_file_svg = strcasecmp(ext, ".svg") == 0;
}

if (entry->icon_retry_count)
context->icon_retry_count--;

entry->icon_file = strdup(icon_file);
return (entry->icon_file != NULL);
}
Expand Down Expand Up @@ -451,12 +463,22 @@ retry_find_icon_file(struct desktop_shell *shell)
entry->icon_name &&
entry->icon_file == NULL &&
entry->icon_retry_count < MAX_ICON_RETRY_COUNT) {
void *data = NULL;
uint32_t data_len = 0;
shell_rdp_debug(entry->shell, "%s: icon (%s) retry count (%d)\n",
__func__, entry->icon_name, entry->icon_retry_count);
attach_app_list_namespace(shell);
if (find_icon_file(entry))
entry->icon_image = load_icon_image(shell, entry->icon_file);
if (find_icon_file(entry)) {
if (entry->is_icon_file_svg)
data = load_file_svg(shell, entry->icon_file, &data_len);
else
entry->icon_image = load_image(entry->icon_file);
}
detach_app_list_namespace(shell);
if (entry->is_icon_file_svg && data)
entry->icon_image = load_image_svg(shell, data, data_len, entry->icon_file);
if (data)
free(data);
if (entry->icon_image)
send_app_entry(shell, *cur, entry, false, false, false, false, false, false);
}
Expand Down Expand Up @@ -580,10 +602,20 @@ update_app_entry(struct desktop_shell *shell, char *file, struct app_entry *entr
entry->working_dir = g_key_file_get_string(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_PATH, NULL);
entry->icon_name = g_key_file_get_locale_string(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, lang_id, NULL);
if (entry->icon_name) {
void *data = NULL;
uint32_t data_len = 0;
attach_app_list_namespace(shell);
if (find_icon_file(entry))
entry->icon_image = load_icon_image(shell, entry->icon_file);
if (find_icon_file(entry)) {
if (entry->is_icon_file_svg)
data = load_file_svg(shell, entry->icon_file, &data_len);
else
entry->icon_image = load_image(entry->icon_file);
}
detach_app_list_namespace(shell);
if (entry->is_icon_file_svg && data)
entry->icon_image = load_image_svg(shell, data, data_len, entry->icon_file);
if (data)
free(data);
}
g_key_file_free(key_file);

Expand All @@ -593,6 +625,7 @@ update_app_entry(struct desktop_shell *shell, char *file, struct app_entry *entr
shell_rdp_debug(shell, " TryExec:%s\n", entry->try_exec);
shell_rdp_debug(shell, " WorkingDir:%s\n", entry->working_dir);
shell_rdp_debug(shell, " Icon name:%s\n", entry->icon_name);
shell_rdp_debug(shell, " Icon SVG :%d\n", entry->is_icon_file_svg);
shell_rdp_debug(shell, " Icon file:%s\n", entry->icon_file);
shell_rdp_debug(shell, " Icon image:%p\n", entry->icon_image);

Expand Down Expand Up @@ -1505,11 +1538,11 @@ void app_list_init(struct desktop_shell *shell)
/* load default icon */
iconpath = getenv("WSL2_DEFAULT_APP_ICON");
if (iconpath && (strcmp(iconpath, "disabled") != 0))
context->default_icon = load_icon_image(shell, iconpath);
context->default_icon = load_image(iconpath);

iconpath = getenv("WSL2_DEFAULT_APP_OVERLAY_ICON");
if (iconpath && (strcmp(iconpath, "disabled") != 0))
context->default_overlay_icon = load_icon_image(shell, iconpath);
context->default_overlay_icon = load_image(iconpath);

/* preblend default icon with overlay icon if requested */
if (shell->is_blend_overlay_icon_app_list &&
Expand Down
96 changes: 80 additions & 16 deletions rdprail-shell/img-load.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,34 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#ifdef HAVE_LIBRSVG2
#include <librsvg/rsvg.h>
#endif // HAVE_LIBRSVG2

#include "shell.h"

#include "shared/image-loader.h"

#ifdef HAVE_LIBRSVG2
static pixman_image_t *
load_svg(struct desktop_shell *shell, const char *filename)
pixman_image_t *
load_image_svg(struct desktop_shell *shell, const void *data, uint32_t data_len, const char *filename)
{
GError *error = NULL;
RsvgHandle *rsvg = NULL;
cairo_surface_t *surface = NULL;
cairo_t *cr = NULL;
pixman_image_t *image = NULL;
cairo_status_t status;

/* DEPRECATED: g_type_init(); rsvg_init(); */
/* rsvg_init has been deprecated since version 2.36 and should not be used
in newly-written code. Use g_type_init() */
/* g_type_init has been deprecated since version 2.36 and should not be used
in newly-written code. the type system is now initialised automatically. */
rsvg = rsvg_handle_new_from_file(filename, &error);
rsvg = rsvg_handle_new_from_data(data, data_len, &error);
if (!rsvg) {
shell_rdp_debug(shell, "%s: rsvg_handle_new_from_file failed %s\n",
__func__, filename);
shell_rdp_debug(shell, "%s: rsvg_handle_new_from_file failed %s %s\n",
__func__, filename, error ? error->message : "(no error message)");
goto Exit;
}

Expand Down Expand Up @@ -102,6 +102,12 @@ load_svg(struct desktop_shell *shell, const char *filename)
pixman_image_ref(image);

Exit:
status = cairo_status(cr);
if (status != CAIRO_STATUS_SUCCESS) {
shell_rdp_debug(shell, "%s: cairo status error %s\n",
__func__, cairo_status_to_string(status));
}

if (cr)
cairo_destroy(cr);

Expand All @@ -123,18 +129,76 @@ load_svg(struct desktop_shell *shell, const char *filename)
/* rsvg_term has been deprecated since version 2.36 and should not be used
in newly-written code. There is no need to de-initialize librsvg. */

if (error)
g_error_free(error);

return image;
}
#endif // HAVE_LIBRSVG2

void *
load_file_svg(struct desktop_shell *shell, const char *filename, uint32_t *data_len)
{
FILE *fp;
void *data = NULL;
int len, ret;

fp = fopen(filename, "rb");
if (!fp) {
shell_rdp_debug(shell, "%s: fopen failed %s %s\n",
__func__, filename, strerror(errno));
goto Fail;
}

if (fseek(fp, 0, SEEK_END) != 0) {
shell_rdp_debug(shell, "%s: fseek failed %s %s\n",
__func__, filename, strerror(errno));
goto Fail;
}
len = ftell(fp);
rewind(fp);

data = malloc(len);
if (!data) {
shell_rdp_debug(shell, "%s: malloc(%d) failed %s %s\n",
__func__, len, filename, strerror(errno));
goto Fail;
}

ret = fread(data, 1, len, fp);
if (ret != len) {
shell_rdp_debug(shell, "%s: fread failed, expect %d but returned %d %s %s\n",
__func__, len, ret, filename, strerror(errno));
goto Fail;
}

goto Exit;

Fail:
if (data)
free(data);

data = NULL;
len = 0;

Exit:
if (fp)
fclose(fp);

*data_len = len;

return data;
}
#else
pixman_image_t *
load_icon_image(struct desktop_shell *shell, const char *filename)
load_image_svg(struct desktop_shell *, const void *, uint32_t)
{
pixman_image_t *image;
image = load_image(filename);
#ifdef HAVE_LIBRSVG2
if (!image)
image = load_svg(shell, filename);
#endif // HAVE_LIBRSVG2
return image;
return NULL;
}

void *
load_file_svg(struct desktop_shell *, const char *, uint32_t *data_len)
{
*data_len = 0;
return NULL;
}
#endif // HAVE_LIBRSVG2
5 changes: 3 additions & 2 deletions rdprail-shell/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <libweston/config-parser.h>
#include "shared/helpers.h"
#include "shared/timespec-util.h"
#include "shared/image-loader.h"
#include <libweston-desktop/libweston-desktop.h>
#include <libweston/libweston.h>
#include <libweston/backend.h>
Expand Down Expand Up @@ -802,14 +803,14 @@ shell_configuration(struct desktop_shell *shell)
/* default icon path is provided from WSL via enviromment variable */
s = getenv("WSL2_DEFAULT_APP_ICON");
if (s && (strcmp(s, "disabled") != 0))
shell->image_default_app_icon = load_icon_image(shell, s);
shell->image_default_app_icon = load_image(s);
shell_rdp_debug(shell, "RDPRAIL-shell: WSL2_DEFAULT_APP_ICON:%s (loaded:%s)\n",
s, shell->image_default_app_icon ? "yes" : "no");

/* default overlay icon path is provided from WSL via enviromment variable */
s = getenv("WSL2_DEFAULT_APP_OVERLAY_ICON");
if (s && (strcmp(s, "disabled") != 0))
shell->image_default_app_overlay_icon = load_icon_image(shell, s);
shell->image_default_app_overlay_icon = load_image(s);
shell_rdp_debug(shell, "RDPRAIL-shell: WSL2_DEFAULT_APP_OVERLAY_ICON:%s (loaded:%s)\n",
s, shell->image_default_app_overlay_icon ? "yes" : "no");

Expand Down
3 changes: 2 additions & 1 deletion rdprail-shell/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,5 @@ void app_list_stop_backend_update(struct desktop_shell *shell);
void app_list_find_image_name(struct desktop_shell *shell, pid_t pid, char *image_name, size_t image_name_size, bool is_wayland);
void app_list_associate_window_app_id(struct desktop_shell *shell, pid_t pid, char *app_id, uint32_t window_id);
// img-load.c
pixman_image_t *load_icon_image(struct desktop_shell *shell, const char *filename);
pixman_image_t *load_image_svg(struct desktop_shell *shell, const void *data, uint32_t data_len, const char *filename);
void *load_file_svg(struct desktop_shell *shell, const char *filename, uint32_t *data_len);

0 comments on commit 75aea1a

Please sign in to comment.