Enhancement: Fixes #180, Make winver less rubbish

This commit is contained in:
Rory Fewell
2024-12-08 01:53:03 +00:00
parent e3011c86f4
commit 0085270e93
23 changed files with 813 additions and 327 deletions

View File

@@ -501,6 +501,7 @@
<property name="can-focus">False</property>
<property name="label" translatable="yes">About Windows</property>
<property name="use-underline">True</property>
<property name="action-name">win.about</property>
</object>
</child>
</object>

View File

@@ -82,6 +82,11 @@ static void switch_mode_to(
WinTCExplorerWindowMode mode
);
static void action_about(
GSimpleAction* action,
GVariant* parameter,
gpointer user_data
);
static void action_nav_go(
GSimpleAction* action,
GVariant* parameter,
@@ -121,6 +126,13 @@ static const gchar* S_TITLE_FORMAT_INTERNET =
"%s - Microsoft Internet Explorer";
static GActionEntry s_window_actions[] = {
{
.name = "about",
.activate = action_about,
.parameter_type = NULL,
.state = NULL,
.change_state = NULL
},
{
.name = "nav-go",
.activate = action_nav_go,
@@ -1025,6 +1037,17 @@ static void switch_mode_to(
//
// CALLBACKS
//
static void action_about(
WINTC_UNUSED(GSimpleAction* action),
WINTC_UNUSED(GVariant* parameter),
gpointer user_data
)
{
WinTCExplorerWindow* wnd = WINTC_EXPLORER_WINDOW(user_data);
wintc_sh_about(GTK_WINDOW(wnd), "Windows", NULL, NULL);
}
static void action_nav_go(
WINTC_UNUSED(GSimpleAction* action),
GVariant* parameter,

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(
wintc-shell-winver
wintc-winver
VERSION 1.0
DESCRIPTION "Windows Total Conversion 'About Windows' utility."
LANGUAGES C
@@ -24,26 +24,29 @@ wintc_resolve_library(glib-2.0 GLIB)
wintc_resolve_library(gtk+-3.0 GTK3)
wintc_resolve_library(wintc-comctl WINTC_COMCTL)
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
wintc_resolve_library(wintc-shell WINTC_SHELL)
wintc_resolve_library(wintc-winbrand WINTC_WINBRAND)
add_executable(
wintc-shell-winver
src/winver.c
wintc-winver
src/application.c
src/application.h
src/main.c
)
set_target_properties(
wintc-shell-winver
wintc-winver
PROPERTIES
OUTPUT_NAME winver
)
target_compile_options(
wintc-shell-winver
wintc-winver
PRIVATE ${WINTC_COMPILE_OPTIONS}
)
target_include_directories(
wintc-shell-winver
wintc-winver
SYSTEM
BEFORE
PRIVATE ${GDK_PIXBUF_INCLUDE_DIRS}
@@ -51,26 +54,29 @@ target_include_directories(
PRIVATE ${GTK3_INCLUDE_DIRS}
PRIVATE ${WINTC_COMCTL_INCLUDE_DIRS}
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
PRIVATE ${WINTC_SHELL_INCLUDE_DIRS}
PRIVATE ${WINTC_WINBRAND_INCLUDE_DIRS}
)
target_link_directories(
wintc-shell-winver
wintc-winver
PRIVATE ${GDK_PIXBUF_LIBRARY_DIRS}
PRIVATE ${GLIB_LIBRARY_DIRS}
PRIVATE ${GTK3_LIBRARY_DIRS}
PRIVATE ${WINTC_COMCTL_LIBRARY_DIRS}
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
PRIVATE ${WINTC_SHELL_LIBRARY_DIRS}
PRIVATE ${WINTC_WINBRAND_LIBRARY_DIRS}
)
target_link_libraries(
wintc-shell-winver
wintc-winver
PRIVATE ${GDK_PIXBUF_LIBRARIES}
PRIVATE ${GLIB_LIBRARIES}
PRIVATE ${GTK3_LIBRARIES}
PRIVATE ${WINTC_COMCTL_LIBRARIES}
PRIVATE ${WINTC_COMGTK_LIBRARIES}
PRIVATE ${WINTC_SHELL_LIBRARIES}
PRIVATE ${WINTC_WINBRAND_LIBRARIES}
)
@@ -80,15 +86,15 @@ if (${WINTC_PKGMGR} STREQUAL "bsdpkg")
wintc_resolve_library(libsysinfo SYSINFO)
target_include_directories(
wintc-shell-winver
wintc-winver
PRIVATE ${SYSINFO_INCLUDE_DIRS}
)
target_link_directories(
wintc-shell-winver
wintc-winver
PRIVATE ${SYSINFO_LIBRARY_DIRS}
)
target_link_libraries(
wintc-shell-winver
wintc-winver
PRIVATE ${SYSINFO_LIBRARIES}
)
endif()
@@ -102,6 +108,6 @@ install(
DESTINATION ${WINTC_ASSETS_INSTALL_DIR}/shell-res
)
install(
TARGETS wintc-shell-winver
TARGETS wintc-winver
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View File

@@ -0,0 +1,72 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shell.h>
#include "application.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCWinverApplicationClass
{
GtkApplicationClass __parent__;
};
struct _WinTCWinverApplication
{
GtkApplication __parent__;
};
//
// FORWARD DECLARATIONS
//
static void wintc_winver_application_activate(
GApplication* application
);
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCWinverApplication,
wintc_winver_application,
GTK_TYPE_APPLICATION
)
static void wintc_winver_application_class_init(
WinTCWinverApplicationClass* klass
)
{
GApplicationClass* application_class = G_APPLICATION_CLASS(klass);
application_class->activate = wintc_winver_application_activate;
}
static void wintc_winver_application_init(
WINTC_UNUSED(WinTCWinverApplication* self)
) { }
//
// CLASS VIRTUAL METHODS
//
static void wintc_winver_application_activate(
WINTC_UNUSED(GApplication* application)
)
{
wintc_sh_about(NULL, "Windows", NULL, NULL);
}
//
// PUBLIC FUNCTIONS
//
WinTCWinverApplication* wintc_winver_application_new(void)
{
return WINTC_WINVER_APPLICATION(
g_object_new(
wintc_winver_application_get_type(),
"application-id", "uk.oddmatics.wintc.winver",
NULL
)
);
}

View File

@@ -0,0 +1,27 @@
#ifndef __APPLICATION_H__
#define __APPLICATION_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCWinverApplicationClass WinTCWinverApplicationClass;
typedef struct _WinTCWinverApplication WinTCWinverApplication;
#define WINTC_TYPE_WINVER_APPLICATION (wintc_winver_application_get_type())
#define WINTC_WINVER_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_WINVER_APPLICATION, WinTCWinverApplication))
#define WINTC_WINVER_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_WINVER_APPLICATION, WinTCWinverApplicationClass))
#define IS_WINTC_WINVER_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_WINVER_APPLICATION))
#define IS_WINTC_WINVER_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_WINVER_APPLICATION))
#define WINTC_WINVER_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_WINVER_APPLICATION, WinTCWinverApplicationClass))
GType wintc_winver_application_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
WinTCWinverApplication* wintc_winver_application_new(void);
#endif

20
shell/winver/src/main.c Normal file
View File

@@ -0,0 +1,20 @@
#include <glib.h>
#include "application.h"
int main(
int argc,
char* argv[]
)
{
WinTCWinverApplication* app = wintc_winver_application_new();
int status;
g_set_application_name("Winver");
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}

View File

@@ -1,313 +0,0 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <gtk/gtk.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <pwd.h>
#include <wintc/comctl.h>
#include <wintc/comgtk.h>
#include <wintc/winbrand.h>
//
// FORWARD DECLARATIONS
//
static void apply_box_model_style(
GtkWidget* widget,
const gchar* model_part,
const gchar* side,
guint margin
);
static void apply_winver_margin_style(
GtkWidget* widget
);
static GtkWidget* create_winver_label(
const gchar* text
);
static void on_ok_button_clicked(
GtkButton* button,
gpointer user_data
);
static void on_window_destroyed(
GtkWidget* widget,
gpointer user_data
);
//
// ENTRY POINT
//
int main(
int argc,
char* argv[]
)
{
GtkWidget* banner;
GtkWidget* banner_strip;
GtkWidget* box;
GtkWidget* box_buttons;
GtkWidget* button_ok;
GtkWidget* label_copyright;
GtkWidget* label_eula;
GtkWidget* label_eula_user;
GtkWidget* label_memory;
GtkWidget* label_product;
GtkWidget* label_version;
GtkWidget* separator;
GtkWidget* window;
struct sysinfo stats;
struct utsname kernel_info;
gtk_init(&argc, &argv);
wintc_ctl_install_default_styles();
// Create the window
//
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(window, 413, 322);
gtk_window_set_icon_name(GTK_WINDOW(window), "help-browser");
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_window_set_title(GTK_WINDOW(window), "About Windows");
gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG);
g_signal_connect(
window,
"destroy",
G_CALLBACK(on_window_destroyed),
NULL
);
// Create banner
//
GError* banner_error = NULL;
GdkPixbuf* banner_pixbuf = NULL;
GError* strip_error = NULL;
GdkPixbuf* strip_pixbuf = NULL;
banner_pixbuf = wintc_brand_get_brand_pixmap(
WINTC_BRAND_PART_BANNER,
&banner_error
);
strip_pixbuf = wintc_brand_get_brand_pixmap(
WINTC_BRAND_PART_STRIP_STATIC,
&strip_error
);
// FIXME: Handle missing branding properly... bleh!
//
if (banner_pixbuf == NULL)
{
wintc_log_error_and_clear(&banner_error);
return 1;
}
if (strip_pixbuf == NULL)
{
wintc_log_error_and_clear(&strip_error);
return 1;
}
banner = gtk_image_new_from_pixbuf(banner_pixbuf);
banner_strip = gtk_image_new_from_pixbuf(strip_pixbuf);
apply_box_model_style(banner_strip, "margin", "bottom", 4);
g_object_unref(banner_pixbuf);
g_object_unref(strip_pixbuf);
// Get kernel info
//
gchar* kernel_version;
uname(&kernel_info);
kernel_version =
g_strdup_printf(
"Version %s (%s)%s",
kernel_info.release,
wintc_build_get_tag(),
wintc_build_is_debug() ? " (Debug)" : ""
);
// Get system info
//
gchar* system_stats;
sysinfo(&stats);
system_stats =
g_strdup_printf(
"Physical memory available to Windows: %lu KB",
stats.totalram / 1024
);
// Create labels
//
struct passwd *user_pwd = getpwuid(getuid());
label_product = create_winver_label("Microsoft ® Windows");
label_version = create_winver_label(kernel_version);
label_copyright = create_winver_label("Copyright © 1985-2005 Microsoft Corporation");
label_eula = create_winver_label("This product is licensed under the terms of the End User License Agreement to:");
label_eula_user = create_winver_label(user_pwd->pw_name);
label_memory = create_winver_label(system_stats);
apply_box_model_style(label_product, "margin", "top", 4);
apply_box_model_style(label_eula, "margin", "top", 30);
apply_box_model_style(label_eula_user, "margin", "left", 60);
apply_box_model_style(label_eula_user, "margin", "bottom", 16);
apply_box_model_style(label_memory, "margin", "top", 4);
// Create separator
//
separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
apply_box_model_style(separator, "margin", "right", 8);
apply_winver_margin_style(separator);
// Create OK button
//
button_ok = gtk_button_new_with_label("OK");
g_signal_connect(
button_ok,
"clicked",
G_CALLBACK(on_ok_button_clicked),
window
);
// Build window contents
//
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
box_buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add(GTK_CONTAINER(window), box);
gtk_box_pack_start(GTK_BOX(box), banner, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), banner_strip, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), label_product, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), label_version, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), label_copyright, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), label_eula, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), label_eula_user, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), separator, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), label_memory, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(box), box_buttons, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(box_buttons), button_ok, FALSE, FALSE, 0);
wintc_widget_add_style_class(
box_buttons,
WINTC_CTL_BUTTON_BOX_CSS_CLASS
);
wintc_widget_add_style_class(
box_buttons,
WINTC_CTL_MARGINB_LG_CSS_CLASS
);
wintc_widget_add_style_class(
box_buttons,
WINTC_CTL_MARGINR_LG_CSS_CLASS
);
// Clear mem
//
g_free(kernel_version);
g_free(system_stats);
// Launch now
//
gtk_widget_show_all(window);
gtk_main();
return 0;
}
//
// PRIVATE FUNCTIONS
//
static void apply_box_model_style(
GtkWidget* widget,
const gchar* model_part,
const gchar* side,
guint margin
)
{
GtkCssProvider* provider = gtk_css_provider_new();
GtkStyleContext* style = gtk_widget_get_style_context(widget);
gchar* style_css = g_slice_alloc0(
sizeof(char) * 40
);
g_sprintf(
style_css,
"* { %s-%s: %dpx; }",
model_part,
side,
margin
);
gtk_css_provider_load_from_data(
provider,
style_css,
-1,
NULL
);
gtk_style_context_add_provider(
style,
GTK_STYLE_PROVIDER(provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
g_object_unref(provider);
g_slice_free1(sizeof(char) * 40, style_css);
}
static void apply_winver_margin_style(
GtkWidget* widget
)
{
apply_box_model_style(widget, "margin", "bottom", 2);
apply_box_model_style(widget, "margin", "left", 52);
apply_box_model_style(widget, "margin", "top", 2);
}
static GtkWidget* create_winver_label(
const gchar* text
)
{
GtkWidget* label = gtk_label_new(text);
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_label_set_max_width_chars(GTK_LABEL(label), 54);
gtk_label_set_xalign(GTK_LABEL(label), 0.0);
apply_winver_margin_style(label);
return label;
}
//
// CALLBACKS
//
static void on_ok_button_clicked(
WINTC_UNUSED(GtkButton* button),
gpointer user_data
)
{
gtk_window_close(
GTK_WINDOW(user_data)
);
}
static void on_window_destroyed(
WINTC_UNUSED(GtkWidget* widget),
WINTC_UNUSED(gpointer user_data)
)
{
gtk_main_quit();
}