mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-05-03 20:51:15 +00:00
Enhancement: Fixes #291, Implement desktop wallpaper support
This commit is contained in:
82
base/regsvc/CMakeLists.txt
Normal file
82
base/regsvc/CMakeLists.txt
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(
|
||||||
|
wintc-regsvc
|
||||||
|
VERSION 1.0
|
||||||
|
DESCRIPTION "Windows Total Conversion registry service."
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_ANYARCH false)
|
||||||
|
set(PROJECT_FREESTATUS true)
|
||||||
|
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
|
||||||
|
|
||||||
|
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
include(../../packaging/cmake-inc/common/CMakeLists.txt)
|
||||||
|
include(../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||||
|
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||||
|
|
||||||
|
wintc_resolve_library(glib-2.0 GLIB)
|
||||||
|
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||||
|
wintc_resolve_library(sqlite3 SQLITE3)
|
||||||
|
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||||
|
wintc_resolve_library(wintc-registry WINTC_REGISTRY)
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
wintc-regsvc
|
||||||
|
src/backend.c
|
||||||
|
src/backend.h
|
||||||
|
src/main.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
wintc-regsvc
|
||||||
|
PROPERTIES
|
||||||
|
OUTPUT_NAME regsvc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
wintc-regsvc
|
||||||
|
PRIVATE ${WINTC_COMPILE_OPTIONS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
wintc-regsvc
|
||||||
|
SYSTEM
|
||||||
|
BEFORE
|
||||||
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${SQLITE3_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_directories(
|
||||||
|
wintc-regsvc
|
||||||
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${SQLITE3_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
wintc-regsvc
|
||||||
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
|
PRIVATE ${SQLITE3_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
#
|
||||||
|
wintc_configure_and_install_packaging()
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS wintc-regsvc
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
8
base/regsvc/README.MD
Normal file
8
base/regsvc/README.MD
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# regsvc
|
||||||
|
This directory contains the source-code for the registry service/daemon.
|
||||||
|
|
||||||
|
## Details
|
||||||
|
Essentially `regsvc` is a very billy-basic daemon that provides the backend for the simplified 'registry' interface defined by `libwintc-registry`.
|
||||||
|
- The registry is implemented as a daemon for DBus-based IPC, so things like Control Panel applets can configure settings and the recipient programs (like the desktop) can be notified
|
||||||
|
- It's not a full clone of the Windows Registry, just a very simple form
|
||||||
|
- The backend uses SQLite3 for storage in the user profile
|
||||||
5
base/regsvc/deps
Normal file
5
base/regsvc/deps
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
bt,rt:glib2
|
||||||
|
bt,rt:gtk3
|
||||||
|
bt,rt:sqlite3
|
||||||
|
bt,rt:wintc-comgtk
|
||||||
|
bt,rt:wintc-registry
|
||||||
713
base/regsvc/src/backend.c
Normal file
713
base/regsvc/src/backend.c
Normal file
@@ -0,0 +1,713 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "backend.h"
|
||||||
|
|
||||||
|
#define WINTC_COMPONENT_REGISTRY "registry"
|
||||||
|
|
||||||
|
#define BAIL_ON_FAIL(query) \
|
||||||
|
rc = (query); \
|
||||||
|
if (rc == SQLITE_ERROR || rc == SQLITE_MISUSE) \
|
||||||
|
{ \
|
||||||
|
handle_sqlite_problem(rc); \
|
||||||
|
sqlite3_finalize(stmt); \
|
||||||
|
return FALSE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE CONSTANTS
|
||||||
|
//
|
||||||
|
static const gchar* S_SQL_INIT =
|
||||||
|
"CREATE TABLE IF NOT EXISTS RegKey ("
|
||||||
|
" Id INTEGER PRIMARY KEY,"
|
||||||
|
" ParentId INTEGER,"
|
||||||
|
" Name VARCHAR(255) NOT NULL,"
|
||||||
|
" FOREIGN KEY(ParentId) REFERENCES RegKey(Id),"
|
||||||
|
" UNIQUE(ParentId, Name)"
|
||||||
|
");"
|
||||||
|
"CREATE TABLE IF NOT EXISTS RegKeyValue ("
|
||||||
|
" Id INTEGER PRIMARY KEY,"
|
||||||
|
" OwnerKey INTEGER,"
|
||||||
|
" Name VARCHAR(255),"
|
||||||
|
" ItemType INTEGER,"
|
||||||
|
" ItemValue BLOB,"
|
||||||
|
" FOREIGN KEY(OwnerKey) REFERENCES RegKey(Id),"
|
||||||
|
" UNIQUE(OwnerKey, Name)"
|
||||||
|
");"
|
||||||
|
"INSERT OR REPLACE INTO RegKey VALUES (1, NULL, 'HKEY_CURRENT_USER');";
|
||||||
|
|
||||||
|
//
|
||||||
|
// STATIC DATA
|
||||||
|
//
|
||||||
|
static sqlite3* s_db = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static gboolean db_create_regkey(
|
||||||
|
const gchar* key_name,
|
||||||
|
gint parent_id,
|
||||||
|
gint* out_id
|
||||||
|
);
|
||||||
|
static gboolean db_get_regkey_id(
|
||||||
|
const gchar* key_name,
|
||||||
|
gint parent_id,
|
||||||
|
gint* out_id
|
||||||
|
);
|
||||||
|
static gboolean db_traverse_to_key(
|
||||||
|
const gchar* key_path,
|
||||||
|
gint* out_id
|
||||||
|
);
|
||||||
|
|
||||||
|
static void handle_sqlite_problem(
|
||||||
|
gint rc
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean is_valid_key_path(
|
||||||
|
GSList* components
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean is_valid_value_name(
|
||||||
|
const gchar* value_name
|
||||||
|
);
|
||||||
|
|
||||||
|
static GSList* path_to_components(
|
||||||
|
const gchar* key_path
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// INTERNAL FUNCTIONS
|
||||||
|
//
|
||||||
|
void backend_close(void)
|
||||||
|
{
|
||||||
|
if (!s_db)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("%s", "regsvc: sqlite closing profile");
|
||||||
|
|
||||||
|
sqlite3_close(s_db);
|
||||||
|
s_db = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean backend_init(void)
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
gchar* path;
|
||||||
|
gint rc;
|
||||||
|
|
||||||
|
if (s_db)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open DB handle
|
||||||
|
//
|
||||||
|
if (!wintc_profile_ensure_exists(WINTC_COMPONENT_REGISTRY, &error))
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = wintc_profile_get_path(WINTC_COMPONENT_REGISTRY, "ntuser.db");
|
||||||
|
rc = sqlite3_open(path, &s_db);
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("regsvc: sqlite opening %s", path);
|
||||||
|
|
||||||
|
g_free(path);
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
g_critical(
|
||||||
|
"regsvc: failed to open profile sqlite %s",
|
||||||
|
sqlite3_errmsg(s_db)
|
||||||
|
);
|
||||||
|
sqlite3_close(s_db);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure tables initialised
|
||||||
|
//
|
||||||
|
char* error_sql = NULL;
|
||||||
|
|
||||||
|
rc =
|
||||||
|
sqlite3_exec(
|
||||||
|
s_db,
|
||||||
|
S_SQL_INIT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error_sql
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
g_critical(
|
||||||
|
"regsvc: failed to init tables %s",
|
||||||
|
error_sql
|
||||||
|
);
|
||||||
|
|
||||||
|
sqlite3_free(error_sql);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean backend_create_key(
|
||||||
|
const gchar* key_path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GSList* components = path_to_components(key_path);
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("regsvc: backend create key %s", key_path);
|
||||||
|
|
||||||
|
if (!is_valid_key_path(components))
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG(
|
||||||
|
"regsvc: backend create key: key/value not valid '%s'",
|
||||||
|
key_path
|
||||||
|
);
|
||||||
|
|
||||||
|
g_slist_free_full(components, g_free);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over to create the key
|
||||||
|
//
|
||||||
|
gint last_id = 0;
|
||||||
|
gboolean success = TRUE;
|
||||||
|
|
||||||
|
for (GSList* iter = components; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
const gchar* key_name = (gchar*) iter->data;
|
||||||
|
gint this_id = 0;
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("regsvc: create key checking for part '%s'", key_name);
|
||||||
|
|
||||||
|
// Check if key exists first
|
||||||
|
//
|
||||||
|
if (!db_get_regkey_id(key_name, last_id, &this_id))
|
||||||
|
{
|
||||||
|
success = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If needed, create the key
|
||||||
|
//
|
||||||
|
if (!this_id)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("%s", "regsvc: need to create that key");
|
||||||
|
|
||||||
|
if (!db_create_regkey(key_name, last_id, &this_id))
|
||||||
|
{
|
||||||
|
success = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last_id = this_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free_full(components, g_free);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean backend_get_key_value(
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
void* value_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gint key_id = 0;
|
||||||
|
gint rc;
|
||||||
|
|
||||||
|
if (value_data == NULL)
|
||||||
|
{
|
||||||
|
g_critical("%s", "regsvc: backend nowhere to store kv");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!is_valid_value_name(value_name) ||
|
||||||
|
!db_traverse_to_key(key_path, &key_id)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG(
|
||||||
|
"regsvc: backend get kv: key/value not valid '%s->%s'",
|
||||||
|
key_path,
|
||||||
|
value_name
|
||||||
|
);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve key stuff
|
||||||
|
//
|
||||||
|
sqlite3_stmt* stmt = NULL;
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_prepare(
|
||||||
|
s_db,
|
||||||
|
"SELECT ItemType, ItemValue FROM RegKeyValue WHERE OwnerKey = ? AND Name = ?;",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 1, key_id));
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_text(stmt, 2, value_name, -1, SQLITE_STATIC));
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_step(stmt));
|
||||||
|
|
||||||
|
// Analyze result
|
||||||
|
//
|
||||||
|
WinTCRegistryValueType found_type = WINTC_REG_INVALID;
|
||||||
|
gboolean success = FALSE;
|
||||||
|
|
||||||
|
if (rc == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
found_type = (WinTCRegistryValueType) sqlite3_column_int(stmt, 0);
|
||||||
|
|
||||||
|
if (found_type == value_type)
|
||||||
|
{
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD:
|
||||||
|
*((gint*) value_data) =
|
||||||
|
sqlite3_column_int(stmt, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_QWORD:
|
||||||
|
*((gint64*) value_data) =
|
||||||
|
sqlite3_column_int64(stmt, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_SZ:
|
||||||
|
*((gchar**) value_data) =
|
||||||
|
g_strdup((const gchar*) sqlite3_column_text(stmt, 1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical(
|
||||||
|
"regsvc: backend unknown key type %d",
|
||||||
|
value_type
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean backend_set_key_value(
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
void* value_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gint key_id = 0;
|
||||||
|
gint rc;
|
||||||
|
|
||||||
|
if (value_data == NULL)
|
||||||
|
{
|
||||||
|
g_critical("%s", "regsvc: backend no data provided to set kv");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!is_valid_value_name(value_name) ||
|
||||||
|
!db_traverse_to_key(key_path, &key_id)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG(
|
||||||
|
"regsvc: backend set kv: key/value not valid '%s->%s'",
|
||||||
|
key_path,
|
||||||
|
value_name
|
||||||
|
);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("regsvc: traversed to key id %d", key_id);
|
||||||
|
|
||||||
|
// Check if we already have a key value
|
||||||
|
//
|
||||||
|
gint value_id = 0;
|
||||||
|
sqlite3_stmt* stmt = NULL;
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_prepare(
|
||||||
|
s_db,
|
||||||
|
"SELECT Id FROM RegKeyValue WHERE OwnerKey = ? AND Name = ?;",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 1, key_id));
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_text(stmt, 2, value_name, -1, SQLITE_STATIC));
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_step(stmt));
|
||||||
|
|
||||||
|
if (rc == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
value_id = sqlite3_column_int(stmt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
// Set new value
|
||||||
|
//
|
||||||
|
gint blob_bind_pos;
|
||||||
|
|
||||||
|
if (value_id)
|
||||||
|
{
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_prepare(
|
||||||
|
s_db,
|
||||||
|
"UPDATE RegKeyValue SET ItemType = ?, ItemValue = ? WHERE Id = ?;",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 1, value_type));
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 3, value_id));
|
||||||
|
|
||||||
|
blob_bind_pos = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_prepare(
|
||||||
|
s_db,
|
||||||
|
"INSERT INTO RegKeyValue VALUES (NULL, ?, ?, ?, ?);",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 1, key_id));
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_bind_text(
|
||||||
|
stmt,
|
||||||
|
2,
|
||||||
|
value_name,
|
||||||
|
-1,
|
||||||
|
SQLITE_STATIC
|
||||||
|
)
|
||||||
|
);
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 3, value_type));
|
||||||
|
|
||||||
|
blob_bind_pos = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD:
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_bind_int(
|
||||||
|
stmt,
|
||||||
|
blob_bind_pos,
|
||||||
|
*((gint*) value_data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_QWORD:
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_bind_int64(
|
||||||
|
stmt,
|
||||||
|
blob_bind_pos,
|
||||||
|
*((gint64*) value_data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_SZ:
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_bind_text(
|
||||||
|
stmt,
|
||||||
|
blob_bind_pos,
|
||||||
|
*((gchar**) value_data),
|
||||||
|
-1,
|
||||||
|
SQLITE_STATIC
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("regsvc: sqlite no binding for %d", value_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_step(stmt));
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static gboolean db_create_regkey(
|
||||||
|
const gchar* key_name,
|
||||||
|
gint parent_id,
|
||||||
|
gint* out_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gint rc;
|
||||||
|
sqlite3_stmt* stmt = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_SET(out_id, 0);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_prepare(
|
||||||
|
s_db,
|
||||||
|
"INSERT INTO RegKey VALUES (NULL, ?, ?);",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!parent_id)
|
||||||
|
{
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_null(stmt, 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 1, parent_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_bind_text(
|
||||||
|
stmt,
|
||||||
|
2,
|
||||||
|
key_name,
|
||||||
|
-1,
|
||||||
|
SQLITE_STATIC
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_step(stmt));
|
||||||
|
|
||||||
|
return db_get_regkey_id(
|
||||||
|
key_name,
|
||||||
|
parent_id,
|
||||||
|
out_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean db_get_regkey_id(
|
||||||
|
const gchar* key_name,
|
||||||
|
gint parent_id,
|
||||||
|
gint* out_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gint rc;
|
||||||
|
sqlite3_stmt* stmt = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_SET(out_id, 0);
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(
|
||||||
|
sqlite3_prepare(
|
||||||
|
s_db,
|
||||||
|
"SELECT Id FROM RegKey WHERE ParentId IS ? AND Name = ?;",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!parent_id)
|
||||||
|
{
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_null(stmt, 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_int(stmt, 1, parent_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_bind_text(stmt, 2, key_name, -1, SQLITE_STATIC));
|
||||||
|
|
||||||
|
BAIL_ON_FAIL(sqlite3_step(stmt));
|
||||||
|
|
||||||
|
if (rc == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
WINTC_SAFE_REF_SET(out_id, sqlite3_column_int(stmt, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean db_traverse_to_key(
|
||||||
|
const gchar* key_path,
|
||||||
|
gint* out_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GSList* components = path_to_components(key_path);
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_SET(out_id, 0);
|
||||||
|
|
||||||
|
if (!is_valid_key_path(components))
|
||||||
|
{
|
||||||
|
// FIXME: Respond invalid path
|
||||||
|
g_slist_free_full(components, g_free);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to traverse to the key
|
||||||
|
//
|
||||||
|
gint last_id = 0;
|
||||||
|
gboolean success = TRUE;
|
||||||
|
|
||||||
|
for (GSList* iter = components; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
const gchar* key_name = (gchar*) iter->data;
|
||||||
|
gint this_id = 0;
|
||||||
|
|
||||||
|
if (!db_get_regkey_id(key_name, last_id, &this_id))
|
||||||
|
{
|
||||||
|
success = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_id = this_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
WINTC_SAFE_REF_SET(out_id, last_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free_full(components, g_free);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_sqlite_problem(
|
||||||
|
gint rc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (rc)
|
||||||
|
{
|
||||||
|
case SQLITE_ERROR:
|
||||||
|
WINTC_LOG_DEBUG("regsvc: sqlite error: %s", sqlite3_errmsg(s_db));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQLITE_MISUSE:
|
||||||
|
g_critical("%s", "regsvc: sqlite misuse detected");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("regsvc: unknown sqlite problem %d", rc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean is_valid_key_path(
|
||||||
|
GSList* components
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (g_slist_length(components) == 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root must be HKCU
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
g_strcmp0(
|
||||||
|
(gchar*) g_slist_nth_data(components, 0),
|
||||||
|
"HKEY_CURRENT_USER"
|
||||||
|
) != 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max length of individual components is 255
|
||||||
|
//
|
||||||
|
for (GSList* iter = components; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
if (strlen((gchar*) iter->data) > 255)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean is_valid_value_name(
|
||||||
|
const gchar* value_name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Can't contain backslashes
|
||||||
|
//
|
||||||
|
if (strchr(value_name, '\\'))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max length of string is 255
|
||||||
|
//
|
||||||
|
if (strlen(value_name) > 255)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSList* path_to_components(
|
||||||
|
const gchar* key_path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GSList* components = NULL;
|
||||||
|
gchar** split = g_strsplit(key_path, "\\", -1);
|
||||||
|
|
||||||
|
// Move strings into list
|
||||||
|
//
|
||||||
|
for (gint i = 0; split[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
components = g_slist_append(components, split[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(split); // The list now owns the strings
|
||||||
|
|
||||||
|
// Naughty hack... if the first component is HKCU, expand it to
|
||||||
|
// HKEY_CURRENT_USER
|
||||||
|
//
|
||||||
|
GSList* first = g_slist_nth(components, 0);
|
||||||
|
|
||||||
|
if (
|
||||||
|
g_strcmp0(
|
||||||
|
(gchar*) first->data,
|
||||||
|
"HKCU"
|
||||||
|
) == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_free(first->data);
|
||||||
|
first->data = g_strdup("HKEY_CURRENT_USER");
|
||||||
|
}
|
||||||
|
|
||||||
|
return components;
|
||||||
|
}
|
||||||
29
base/regsvc/src/backend.h
Normal file
29
base/regsvc/src/backend.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __BACKEND_H__
|
||||||
|
#define __BACKEND_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/registry.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// INTERNAL FUNCTIONS
|
||||||
|
//
|
||||||
|
void backend_close(void);
|
||||||
|
gboolean backend_init(void);
|
||||||
|
|
||||||
|
gboolean backend_create_key(
|
||||||
|
const gchar* key_path
|
||||||
|
);
|
||||||
|
gboolean backend_get_key_value(
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
void* value_data
|
||||||
|
);
|
||||||
|
gboolean backend_set_key_value(
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
void* value_data
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
376
base/regsvc/src/main.c
Normal file
376
base/regsvc/src/main.c
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <glib-unix.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
#include <wintc/registry.h>
|
||||||
|
|
||||||
|
#include "backend.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// STATIC DATA
|
||||||
|
//
|
||||||
|
static GMainLoop* s_main_loop = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void on_name_acquired(
|
||||||
|
GDBusConnection* connection,
|
||||||
|
const gchar* name,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean on_handle_create_key(
|
||||||
|
ZWinRegistryGDBUS* reg_dbus,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* key_path,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
static gboolean on_handle_get_key_value(
|
||||||
|
ZWinRegistryGDBUS* reg_dbus,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
static gboolean on_handle_set_key_value(
|
||||||
|
ZWinRegistryGDBUS* reg_dbus,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_data,
|
||||||
|
gboolean silent,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean on_sigterm(
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ENTRY POINT
|
||||||
|
//
|
||||||
|
int main(
|
||||||
|
WINTC_UNUSED(int argc),
|
||||||
|
WINTC_UNUSED(char* argv[])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
s_main_loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
|
||||||
|
if (!backend_init())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("regsvc: hosting name %s", "uk.oddmatics.wintc.registry");
|
||||||
|
|
||||||
|
g_bus_own_name(
|
||||||
|
G_BUS_TYPE_SESSION,
|
||||||
|
"uk.oddmatics.wintc.registry",
|
||||||
|
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
on_name_acquired,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
g_unix_signal_add(
|
||||||
|
SIGTERM,
|
||||||
|
on_sigterm,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
g_main_loop_run(s_main_loop);
|
||||||
|
|
||||||
|
g_main_loop_unref(s_main_loop);
|
||||||
|
|
||||||
|
backend_close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLBACKS
|
||||||
|
//
|
||||||
|
static void on_name_acquired(
|
||||||
|
GDBusConnection* connection,
|
||||||
|
WINTC_UNUSED(const gchar* name),
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
ZWinRegistryGDBUS* reg_dbus = zwin_registry_gdbus_skeleton_new();
|
||||||
|
|
||||||
|
g_signal_connect(
|
||||||
|
reg_dbus,
|
||||||
|
"handle-create-key",
|
||||||
|
G_CALLBACK(on_handle_create_key),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
g_signal_connect(
|
||||||
|
reg_dbus,
|
||||||
|
"handle-get-key-value",
|
||||||
|
G_CALLBACK(on_handle_get_key_value),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
g_signal_connect(
|
||||||
|
reg_dbus,
|
||||||
|
"handle-set-key-value",
|
||||||
|
G_CALLBACK(on_handle_set_key_value),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!g_dbus_interface_skeleton_export(
|
||||||
|
G_DBUS_INTERFACE_SKELETON(reg_dbus),
|
||||||
|
connection,
|
||||||
|
"/uk/oddmatics/wintc/registry/GDBUS",
|
||||||
|
&error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_handle_create_key(
|
||||||
|
ZWinRegistryGDBUS* reg_dbus,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* key_path,
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("regsvc: received create key request for %s", key_path);
|
||||||
|
|
||||||
|
// Very simply just try creating the key
|
||||||
|
//
|
||||||
|
gboolean success = backend_create_key(key_path);
|
||||||
|
|
||||||
|
zwin_registry_gdbus_complete_create_key(
|
||||||
|
reg_dbus,
|
||||||
|
invocation,
|
||||||
|
success ? 1 : 0
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_handle_get_key_value(
|
||||||
|
ZWinRegistryGDBUS* reg_dbus,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG(
|
||||||
|
"regsvc: received get key value for %s->%s",
|
||||||
|
key_path,
|
||||||
|
value_name
|
||||||
|
);
|
||||||
|
|
||||||
|
// Wrap up in a variant
|
||||||
|
//
|
||||||
|
gboolean success = FALSE;
|
||||||
|
gint value_data_int = 0;
|
||||||
|
gint64 value_data_int64 = 0;
|
||||||
|
gchar* value_data_str = NULL;
|
||||||
|
GVariant* variant_ret = NULL;
|
||||||
|
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD:
|
||||||
|
success =
|
||||||
|
backend_get_key_value(
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
WINTC_REG_DWORD,
|
||||||
|
&value_data_int
|
||||||
|
);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
variant_ret =
|
||||||
|
g_variant_new(
|
||||||
|
"v",
|
||||||
|
g_variant_new_int32(value_data_int)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_QWORD:
|
||||||
|
success =
|
||||||
|
backend_get_key_value(
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
WINTC_REG_QWORD,
|
||||||
|
&value_data_int64
|
||||||
|
);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
variant_ret =
|
||||||
|
g_variant_new(
|
||||||
|
"v",
|
||||||
|
g_variant_new_int64(value_data_int64)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_SZ:
|
||||||
|
success =
|
||||||
|
backend_get_key_value(
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
WINTC_REG_SZ,
|
||||||
|
&value_data_str
|
||||||
|
);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
variant_ret =
|
||||||
|
g_variant_new(
|
||||||
|
"v",
|
||||||
|
g_variant_new_string(value_data_str)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(value_data_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("regsvc: unknown type %d", value_type);
|
||||||
|
success = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// Cannot use maybe-type variants because they're not supported by
|
||||||
|
// DBus/GDBus, so just respond with 0 - libwintc-registry will discard
|
||||||
|
// the variant regardless if the result code is 0 so we could respond
|
||||||
|
// with any variant here and be fine
|
||||||
|
//
|
||||||
|
variant_ret = g_variant_new("v", g_variant_new_int32(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
zwin_registry_gdbus_complete_get_key_value(
|
||||||
|
reg_dbus,
|
||||||
|
invocation,
|
||||||
|
variant_ret,
|
||||||
|
success ? 1 : 0
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_handle_set_key_value(
|
||||||
|
ZWinRegistryGDBUS* reg_dbus,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_data,
|
||||||
|
gboolean silent,
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG(
|
||||||
|
"regsvc: received set key value for %s->%s",
|
||||||
|
key_path,
|
||||||
|
value_name
|
||||||
|
);
|
||||||
|
|
||||||
|
// The variant incoming determines the type etc.
|
||||||
|
//
|
||||||
|
GVariant* inner = g_variant_get_variant(value_data);
|
||||||
|
gboolean success = FALSE;
|
||||||
|
WinTCRegistryValueType value_type = wintc_registry_get_type_for_variant(
|
||||||
|
inner
|
||||||
|
);
|
||||||
|
|
||||||
|
gint value_data_int = 0;
|
||||||
|
gint64 value_data_int64 = 0;
|
||||||
|
gchar* value_data_str = NULL;
|
||||||
|
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD:
|
||||||
|
value_data_int = g_variant_get_int32(inner);
|
||||||
|
|
||||||
|
success =
|
||||||
|
backend_set_key_value(
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
WINTC_REG_DWORD,
|
||||||
|
&value_data_int
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_QWORD:
|
||||||
|
value_data_int64 = g_variant_get_int64(inner);
|
||||||
|
|
||||||
|
success =
|
||||||
|
backend_set_key_value(
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
WINTC_REG_QWORD,
|
||||||
|
&value_data_int64
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_SZ:
|
||||||
|
value_data_str = g_variant_dup_string(inner, NULL);
|
||||||
|
|
||||||
|
success =
|
||||||
|
backend_set_key_value(
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
WINTC_REG_SZ,
|
||||||
|
&value_data_str
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(value_data_str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("%s", "regsvc: set key unknown variant type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
zwin_registry_gdbus_complete_set_key_value(
|
||||||
|
reg_dbus,
|
||||||
|
invocation,
|
||||||
|
success ? 1 : 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (success && !silent)
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name(
|
||||||
|
reg_dbus,
|
||||||
|
"key-value-changed",
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
value_data,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_sigterm(
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("%s", "regsvc: sigterm, exiting...");
|
||||||
|
|
||||||
|
g_main_loop_quit(s_main_loop);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ do_packaging()
|
|||||||
|
|
||||||
# Build package now
|
# Build package now
|
||||||
#
|
#
|
||||||
(cd "${pkg_dir}/usr/local" && find . -type f,l) | sed 's/\.\///' > plist
|
(cd "${pkg_dir}/usr/local" && find -L . -type f) | sed 's/\.\///' > plist
|
||||||
pkg create -M manifest -r "${pkg_dir}" -p plist
|
pkg create -M manifest -r "${pkg_dir}" -p plist
|
||||||
|
|
||||||
cd "${CURDIR}"
|
cd "${CURDIR}"
|
||||||
|
|||||||
55
packaging/cmake-inc/codegen/CMakeLists.txt
Normal file
55
packaging/cmake-inc/codegen/CMakeLists.txt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
# Define function for gdbus-codegen
|
||||||
|
#
|
||||||
|
function(wintc_gdbus_codegen XML_FILE OUT_FILE_NOEXT CP_PUBLIC)
|
||||||
|
find_program(GDBUS_CODEGEN gdbus-codegen REQUIRED)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/${OUT_FILE_NOEXT}.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/${OUT_FILE_NOEXT}.h
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
COMMAND ${GDBUS_CODEGEN}
|
||||||
|
ARGS
|
||||||
|
--interface-prefix uk.oddmatics.wintc.
|
||||||
|
--generate-c-code ${OUT_FILE_NOEXT}
|
||||||
|
--c-namespace ZWin
|
||||||
|
--c-generate-object-manager
|
||||||
|
${XML_FILE}
|
||||||
|
VERBATIM
|
||||||
|
DEPENDS
|
||||||
|
src/${XML_FILE}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
dbus-codegen
|
||||||
|
DEPENDS
|
||||||
|
src/${OUT_FILE_NOEXT}.c
|
||||||
|
src/${OUT_FILE_NOEXT}.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# If the header is needed in public/ for libraries then copy it
|
||||||
|
#
|
||||||
|
if (CP_PUBLIC)
|
||||||
|
find_program(CP cp REQUIRED)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/public/${OUT_FILE_NOEXT}.h
|
||||||
|
COMMAND ${CP}
|
||||||
|
ARGS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/${OUT_FILE_NOEXT}.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/public/${OUT_FILE_NOEXT}.h
|
||||||
|
VERBATIM
|
||||||
|
DEPENDS
|
||||||
|
src/${OUT_FILE_NOEXT}.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
dbus-codegen-header
|
||||||
|
DEPENDS
|
||||||
|
public/${OUT_FILE_NOEXT}.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
set(REPO_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../..)
|
set(REPO_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../..)
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ if (NOT CMAKE_BUILD_TYPE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (${CMAKE_BUILD_TYPE} STREQUAL Debug)
|
if (${CMAKE_BUILD_TYPE} STREQUAL Debug)
|
||||||
add_definitions(-DWINTC_CHECKED)
|
add_compile_definitions(WINTC_CHECKED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Handle SKU stuff
|
# Handle SKU stuff
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ if (NOT DEFINED WINTC_PKGMGR OR "${WINTC_PKGMGR}" STREQUAL "")
|
|||||||
set(WINTC_PKGMGR raw)
|
set(WINTC_PKGMGR raw)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Export install prefix (useful for retrieving data at runtime)
|
||||||
|
#
|
||||||
|
add_compile_definitions(WINTC_RT_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||||
|
|
||||||
# Set up library directory
|
# Set up library directory
|
||||||
#
|
#
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
base/bootvid
|
base/bootvid
|
||||||
base/bldtag
|
base/bldtag
|
||||||
base/logonui
|
base/logonui
|
||||||
|
base/regsvc
|
||||||
cursors/no-shadow/standard
|
cursors/no-shadow/standard
|
||||||
cursors/with-shadow/standard
|
cursors/with-shadow/standard
|
||||||
fonts
|
fonts
|
||||||
@@ -9,6 +10,7 @@ sounds
|
|||||||
themes/native
|
themes/native
|
||||||
themes/professional
|
themes/professional
|
||||||
themes/luna/blue
|
themes/luna/blue
|
||||||
|
shell/cpl/desk
|
||||||
shell/cpl/printers
|
shell/cpl/printers
|
||||||
shell/cpl/sysdm
|
shell/cpl/sysdm
|
||||||
shell/desktop
|
shell/desktop
|
||||||
|
|||||||
2
private/play/dbus/.gitignore
vendored
Normal file
2
private/play/dbus/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Ignore generated output
|
||||||
|
testreg-skel.*
|
||||||
74
private/play/dbus/clt/CMakeLists.txt
Normal file
74
private/play/dbus/clt/CMakeLists.txt
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(
|
||||||
|
wintc-dbus-test-clt
|
||||||
|
VERSION 1.0
|
||||||
|
DESCRIPTION "Windows Total Conversion DBus test client."
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_ANYARCH false)
|
||||||
|
set(PROJECT_FREESTATUS true)
|
||||||
|
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
|
||||||
|
|
||||||
|
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
include(../../../../packaging/cmake-inc/common/CMakeLists.txt)
|
||||||
|
include(../../../../packaging/cmake-inc/codegen/CMakeLists.txt)
|
||||||
|
include(../../../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||||
|
include(../../../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||||
|
|
||||||
|
wintc_resolve_library(glib-2.0 GLIB)
|
||||||
|
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||||
|
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||||
|
|
||||||
|
wintc_gdbus_codegen(
|
||||||
|
testreg.xml
|
||||||
|
testreg-skel
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
wintc-dbus-test-clt
|
||||||
|
src/main.c
|
||||||
|
src/testreg-skel.c
|
||||||
|
src/testreg-skel.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
wintc-dbus-test-clt
|
||||||
|
PRIVATE ${WINTC_COMPILE_OPTIONS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
wintc-dbus-test-clt
|
||||||
|
SYSTEM
|
||||||
|
BEFORE
|
||||||
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_directories(
|
||||||
|
wintc-dbus-test-clt
|
||||||
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
wintc-dbus-test-clt
|
||||||
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
#
|
||||||
|
wintc_configure_and_install_packaging()
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS wintc-dbus-test-clt
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
49
private/play/dbus/clt/src/main.c
Normal file
49
private/play/dbus/clt/src/main.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "testreg-skel.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// ENTRY POINT
|
||||||
|
//
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
WinTCTestregGDBUS* proxy;
|
||||||
|
gchar* szoutput;
|
||||||
|
|
||||||
|
proxy =
|
||||||
|
win_tc_testreg_gdbus_proxy_new_for_bus_sync(
|
||||||
|
G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
"uk.oddmatics.wintc.testreg",
|
||||||
|
"/uk/oddmatics/wintc/testreg/GDBUS",
|
||||||
|
NULL,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!proxy)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
win_tc_testreg_gdbus_call_testing_sync(
|
||||||
|
proxy,
|
||||||
|
"hello!",
|
||||||
|
&szoutput,
|
||||||
|
NULL,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_message("Client got: %s", szoutput);
|
||||||
|
|
||||||
|
g_object_unref(proxy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
8
private/play/dbus/clt/src/testreg.xml
Normal file
8
private/play/dbus/clt/src/testreg.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<node>
|
||||||
|
<interface name="uk.oddmatics.wintc.testreg.GDBUS">
|
||||||
|
<method name="Testing">
|
||||||
|
<arg name="szinput" direction="in" type="s" />
|
||||||
|
<arg name="szoutput" direction="out" type="s" />
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
||||||
75
private/play/dbus/srv/CMakeLists.txt
Normal file
75
private/play/dbus/srv/CMakeLists.txt
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(
|
||||||
|
wintc-dbus-test-srv
|
||||||
|
VERSION 1.0
|
||||||
|
DESCRIPTION "Windows Total Conversion DBus test server."
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_ANYARCH false)
|
||||||
|
set(PROJECT_FREESTATUS true)
|
||||||
|
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
|
||||||
|
|
||||||
|
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
include(../../../../packaging/cmake-inc/common/CMakeLists.txt)
|
||||||
|
include(../../../../packaging/cmake-inc/codegen/CMakeLists.txt)
|
||||||
|
include(../../../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||||
|
include(../../../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||||
|
|
||||||
|
wintc_resolve_library(glib-2.0 GLIB)
|
||||||
|
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||||
|
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||||
|
|
||||||
|
wintc_gdbus_codegen(
|
||||||
|
testreg.xml
|
||||||
|
testreg-skel
|
||||||
|
FALSE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
wintc-dbus-test-srv
|
||||||
|
src/main.c
|
||||||
|
src/testreg-skel.c
|
||||||
|
src/testreg-skel.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
wintc-dbus-test-srv
|
||||||
|
PRIVATE ${WINTC_COMPILE_OPTIONS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
wintc-dbus-test-srv
|
||||||
|
SYSTEM
|
||||||
|
BEFORE
|
||||||
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_directories(
|
||||||
|
wintc-dbus-test-srv
|
||||||
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
wintc-dbus-test-srv
|
||||||
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
#
|
||||||
|
wintc_configure_and_install_packaging()
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS wintc-dbus-test-srv
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
3
private/play/dbus/srv/deps
Normal file
3
private/play/dbus/srv/deps
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
bt,rt:glib2
|
||||||
|
bt,rt:gtk3
|
||||||
|
bt,rt:wintc-comgtk
|
||||||
98
private/play/dbus/srv/src/main.c
Normal file
98
private/play/dbus/srv/src/main.c
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "testreg-skel.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void on_name_acquired(
|
||||||
|
GDBusConnection* connection,
|
||||||
|
const gchar* name,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean on_handle_testing(
|
||||||
|
WinTCTestregGDBUS* iface,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* szinput,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ENTRY POINT
|
||||||
|
//
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
GMainLoop* loop;
|
||||||
|
|
||||||
|
loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
|
||||||
|
g_bus_own_name(
|
||||||
|
G_BUS_TYPE_SESSION,
|
||||||
|
"uk.oddmatics.wintc.testreg",
|
||||||
|
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
on_name_acquired,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
g_main_loop_run(loop);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static void on_name_acquired(
|
||||||
|
GDBusConnection* connection,
|
||||||
|
WINTC_UNUSED(const gchar* name),
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
WinTCTestregGDBUS* iface = win_tc_testreg_gdbus_skeleton_new();
|
||||||
|
|
||||||
|
g_signal_connect(
|
||||||
|
iface,
|
||||||
|
"handle-testing",
|
||||||
|
G_CALLBACK(on_handle_testing),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!g_dbus_interface_skeleton_export(
|
||||||
|
G_DBUS_INTERFACE_SKELETON(iface),
|
||||||
|
connection,
|
||||||
|
"/uk/oddmatics/wintc/testreg/GDBUS",
|
||||||
|
&error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_handle_testing(
|
||||||
|
WinTCTestregGDBUS* iface,
|
||||||
|
GDBusMethodInvocation* invocation,
|
||||||
|
const gchar* szinput,
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gchar* szoutput = g_strdup_printf("GDBUS IN: %s", szinput);
|
||||||
|
|
||||||
|
win_tc_testreg_gdbus_complete_testing(
|
||||||
|
iface,
|
||||||
|
invocation,
|
||||||
|
szoutput
|
||||||
|
);
|
||||||
|
|
||||||
|
g_message("%s", szoutput);
|
||||||
|
g_free(szoutput);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
8
private/play/dbus/srv/src/testreg.xml
Normal file
8
private/play/dbus/srv/src/testreg.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<node>
|
||||||
|
<interface name="uk.oddmatics.wintc.testreg.GDBUS">
|
||||||
|
<method name="Testing">
|
||||||
|
<arg name="szinput" direction="in" type="s" />
|
||||||
|
<arg name="szoutput" direction="out" type="s" />
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
||||||
@@ -25,6 +25,8 @@ wintc_resolve_library(gdk-pixbuf-2.0 GDK_PIXBUF)
|
|||||||
wintc_resolve_library(glib-2.0 GLIB)
|
wintc_resolve_library(glib-2.0 GLIB)
|
||||||
wintc_resolve_library(gtk+-3.0 GTK3)
|
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||||
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||||
|
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
|
||||||
|
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
|
||||||
|
|
||||||
wintc_compile_resources()
|
wintc_compile_resources()
|
||||||
|
|
||||||
@@ -33,6 +35,8 @@ add_library(
|
|||||||
src/resources.c
|
src/resources.c
|
||||||
src/animctl.c
|
src/animctl.c
|
||||||
public/animctl.h
|
public/animctl.h
|
||||||
|
src/cpl.c
|
||||||
|
public/cpl.h
|
||||||
src/style.c
|
src/style.c
|
||||||
public/style.h
|
public/style.h
|
||||||
)
|
)
|
||||||
@@ -57,6 +61,8 @@ target_include_directories(
|
|||||||
PRIVATE ${GLIB_INCLUDE_DIRS}
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
PRIVATE ${GTK3_INCLUDE_DIRS}
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHCOMMON_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHLANG_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_directories(
|
target_link_directories(
|
||||||
@@ -65,6 +71,8 @@ target_link_directories(
|
|||||||
PRIVATE ${GLIB_LIBRARY_DIRS}
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
PRIVATE ${GTK3_LIBRARY_DIRS}
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHCOMMON_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHLANG_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
@@ -73,6 +81,8 @@ target_link_libraries(
|
|||||||
PRIVATE ${GLIB_LIBRARIES}
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
PRIVATE ${GTK3_LIBRARIES}
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_SHCOMMON_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_SHLANG_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ bt,rt:gdk-pixbuf2
|
|||||||
bt,rt:glib2
|
bt,rt:glib2
|
||||||
bt,rt:gtk3
|
bt,rt:gtk3
|
||||||
bt,rt:wintc-comgtk
|
bt,rt:wintc-comgtk
|
||||||
|
bt,rt:wintc-shlang
|
||||||
|
|||||||
13
shared/comctl/public/cpl.h
Normal file
13
shared/comctl/public/cpl.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef __COMCTL_CPL_H__
|
||||||
|
#define __COMCTL_CPL_H__
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
void wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GtkNotebook* notebook,
|
||||||
|
const gchar* resource_path,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define __WINTC_COMCTL_H__
|
#define __WINTC_COMCTL_H__
|
||||||
|
|
||||||
#include "@LIB_HEADER_DIR@/animctl.h"
|
#include "@LIB_HEADER_DIR@/animctl.h"
|
||||||
|
#include "@LIB_HEADER_DIR@/cpl.h"
|
||||||
#include "@LIB_HEADER_DIR@/style.h"
|
#include "@LIB_HEADER_DIR@/style.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
60
shared/comctl/src/cpl.c
Normal file
60
shared/comctl/src/cpl.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
#include <wintc/shlang.h>
|
||||||
|
|
||||||
|
#include "../public/cpl.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
void wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GtkNotebook* notebook,
|
||||||
|
const gchar* resource_path,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GtkBuilder* builder;
|
||||||
|
GtkWidget* box_page;
|
||||||
|
GtkWidget* label_title;
|
||||||
|
|
||||||
|
builder = gtk_builder_new_from_resource(resource_path);
|
||||||
|
|
||||||
|
// Handle construction into UI
|
||||||
|
//
|
||||||
|
wintc_lc_builder_preprocess_widget_text(builder);
|
||||||
|
|
||||||
|
box_page = GTK_WIDGET(gtk_builder_get_object(builder, "page-box"));
|
||||||
|
label_title = GTK_WIDGET(gtk_builder_get_object(builder, "label-title"));
|
||||||
|
|
||||||
|
gtk_notebook_append_page(
|
||||||
|
notebook,
|
||||||
|
box_page,
|
||||||
|
label_title
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pull out objects as requested, args are provided as pairs (name, dstptr)
|
||||||
|
//
|
||||||
|
va_list ap;
|
||||||
|
GtkWidget** next_dst;
|
||||||
|
gchar* next_name;
|
||||||
|
|
||||||
|
va_start(ap, resource_path);
|
||||||
|
|
||||||
|
next_name = va_arg(ap, gchar*);
|
||||||
|
|
||||||
|
while (next_name)
|
||||||
|
{
|
||||||
|
next_dst = va_arg(ap, GtkWidget**);
|
||||||
|
*next_dst = GTK_WIDGET(gtk_builder_get_object(builder, next_name));
|
||||||
|
|
||||||
|
// Iter
|
||||||
|
//
|
||||||
|
next_name = va_arg(ap, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
g_object_unref(G_OBJECT(builder));
|
||||||
|
}
|
||||||
2
shared/registry/.gitignore
vendored
Normal file
2
shared/registry/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Ignore generated output
|
||||||
|
reg-dbus.*
|
||||||
91
shared/registry/CMakeLists.txt
Normal file
91
shared/registry/CMakeLists.txt
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(
|
||||||
|
libwintc-registry
|
||||||
|
VERSION 1.0
|
||||||
|
DESCRIPTION "Windows Total Conversion registry library."
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_ANYARCH false)
|
||||||
|
set(PROJECT_FREESTATUS true)
|
||||||
|
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
|
||||||
|
|
||||||
|
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
set(WINTC_NO_PEDANTIC_COMPILE true) # Necessary for gdbus-codegen
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
include(../../packaging/cmake-inc/common/CMakeLists.txt)
|
||||||
|
include(../../packaging/cmake-inc/codegen/CMakeLists.txt)
|
||||||
|
include(../../packaging/cmake-inc/libraries/CMakeLists.txt)
|
||||||
|
include(../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||||
|
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||||
|
|
||||||
|
wintc_resolve_library(glib-2.0 GLIB)
|
||||||
|
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||||
|
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||||
|
|
||||||
|
wintc_gdbus_codegen(
|
||||||
|
dbus-if.xml
|
||||||
|
reg-dbus
|
||||||
|
TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
libwintc-registry
|
||||||
|
public/reg-dbus.h
|
||||||
|
src/reg-dbus.c
|
||||||
|
src/reg-dbus.h
|
||||||
|
src/regwrap.c
|
||||||
|
public/regwrap.h
|
||||||
|
src/variant.c
|
||||||
|
public/variant.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
libwintc-registry
|
||||||
|
PROPERTIES
|
||||||
|
SOVERSION 1
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
libwintc-registry
|
||||||
|
PRIVATE ${WINTC_COMPILE_OPTIONS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
libwintc-registry
|
||||||
|
SYSTEM
|
||||||
|
BEFORE
|
||||||
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_directories(
|
||||||
|
libwintc-registry
|
||||||
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
libwintc-registry
|
||||||
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
#
|
||||||
|
wintc_configure_and_install_packaging()
|
||||||
|
wintc_add_pkgconfig_install()
|
||||||
|
wintc_install_public_headers()
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS libwintc-registry
|
||||||
|
LIBRARY DESTINATION ${LIB_DIR}
|
||||||
|
)
|
||||||
5
shared/registry/README.MD
Normal file
5
shared/registry/README.MD
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# libwintc-registry
|
||||||
|
This directory contains the source code for the registry library.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
This library provides the GDBus interface and a simple client-side wrapper for interacting with the registry.
|
||||||
4
shared/registry/deps
Normal file
4
shared/registry/deps
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
bt,rt:glib2
|
||||||
|
bt,rt:gtk3
|
||||||
|
bt,rt:python3-packaging
|
||||||
|
bt,rt:wintc-comgtk
|
||||||
8
shared/registry/public/libapi.h.in
Normal file
8
shared/registry/public/libapi.h.in
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef __WINTC_REGISTRY_H__
|
||||||
|
#define __WINTC_REGISTRY_H__
|
||||||
|
|
||||||
|
#include "@LIB_HEADER_DIR@/reg-dbus.h"
|
||||||
|
#include "@LIB_HEADER_DIR@/regwrap.h"
|
||||||
|
#include "@LIB_HEADER_DIR@/variant.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
80
shared/registry/public/regwrap.h
Normal file
80
shared/registry/public/regwrap.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#ifndef __REGISTRY_REGWRAP_H__
|
||||||
|
#define __REGISTRY_REGWRAP_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC ENUMS
|
||||||
|
//
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WINTC_REG_INVALID,
|
||||||
|
WINTC_REG_DWORD,
|
||||||
|
WINTC_REG_QWORD,
|
||||||
|
WINTC_REG_SZ
|
||||||
|
} WinTCRegistryValueType;
|
||||||
|
|
||||||
|
//
|
||||||
|
// GLIB OOP BOILERPLATE
|
||||||
|
//
|
||||||
|
typedef struct _WinTCRegistryClass WinTCRegistryClass;
|
||||||
|
typedef struct _WinTCRegistry WinTCRegistry;
|
||||||
|
|
||||||
|
#define WINTC_TYPE_REGISTRY (wintc_registry_get_type())
|
||||||
|
#define WINTC_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_REGISTRY, WinTCRegistry))
|
||||||
|
#define WINTC_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_REGISTRY, WinTCRegistryClass))
|
||||||
|
#define IS_WINTC_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_REGISTRY))
|
||||||
|
#define IS_WINTC_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_REGISTRY))
|
||||||
|
#define WINTC_REGISTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_REGISTRY, WinTCRegistry))
|
||||||
|
|
||||||
|
GType wintc_registry_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLBACK PROTOTYPES
|
||||||
|
//
|
||||||
|
typedef void (*WinTCRegistryKeyCallback) (
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_variant,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCRegistry* wintc_registry_new(void);
|
||||||
|
|
||||||
|
gboolean wintc_registry_create_key(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
|
||||||
|
gboolean wintc_registry_get_key_value(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
void* value_data,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
|
||||||
|
gboolean wintc_registry_set_key_value(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
const void* value_data,
|
||||||
|
gboolean silent,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
|
||||||
|
void wintc_registry_watch_key(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
WinTCRegistryKeyCallback callback,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
15
shared/registry/public/variant.h
Normal file
15
shared/registry/public/variant.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef __REGISTRY_VARIANT_H__
|
||||||
|
#define __REGISTRY_VARIANT_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "regwrap.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCRegistryValueType wintc_registry_get_type_for_variant(
|
||||||
|
GVariant* variant
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
30
shared/registry/src/dbus-if.xml
Normal file
30
shared/registry/src/dbus-if.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<node>
|
||||||
|
<interface name="uk.oddmatics.wintc.registry.GDBUS">
|
||||||
|
<method name="CreateKey">
|
||||||
|
<arg name="key_path" direction="in" type="s" />
|
||||||
|
<arg name="result" direction="out" type="i" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="GetKeyValue">
|
||||||
|
<arg name="key_path" direction="in" type="s" />
|
||||||
|
<arg name="value_name" direction="in" type="s" />
|
||||||
|
<arg name="value_type" direction="in" type="i" />
|
||||||
|
<arg name="value_data" direction="out" type="v" />
|
||||||
|
<arg name="result" direction="out" type="i" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="SetKeyValue">
|
||||||
|
<arg name="key_path" direction="in" type="s" />
|
||||||
|
<arg name="value_name" direction="in" type="s" />
|
||||||
|
<arg name="value_data" direction="in" type="v" />
|
||||||
|
<arg name="silent" direction="in" type="b" />
|
||||||
|
<arg name="result" direction="out" type="i" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<signal name="KeyValueChanged">
|
||||||
|
<arg name="key_path" type="s" />
|
||||||
|
<arg name="value_name" type="s" />
|
||||||
|
<arg name="value_data" type="v" />
|
||||||
|
</signal>
|
||||||
|
</interface>
|
||||||
|
</node>
|
||||||
433
shared/registry/src/regwrap.c
Normal file
433
shared/registry/src/regwrap.c
Normal file
@@ -0,0 +1,433 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "../public/reg-dbus.h"
|
||||||
|
#include "../public/regwrap.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE STRUCTS
|
||||||
|
//
|
||||||
|
typedef struct _RegistryCBData
|
||||||
|
{
|
||||||
|
WinTCRegistryKeyCallback callback;
|
||||||
|
gpointer user_data;
|
||||||
|
} RegistryCBData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void wintc_registry_dispose(
|
||||||
|
GObject* object
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean wintc_registry_ensure_proxy(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
|
||||||
|
static void on_reg_key_value_changed(
|
||||||
|
ZWinRegistryGDBUS* proxy,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_data,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// GLIB OOP CLASS/INSTANCE DEFINITIONS
|
||||||
|
//
|
||||||
|
struct _WinTCRegistryClass
|
||||||
|
{
|
||||||
|
GObjectClass __parent__;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WinTCRegistry
|
||||||
|
{
|
||||||
|
GObject __parent__;
|
||||||
|
|
||||||
|
gboolean connected_signal;
|
||||||
|
GHashTable* map_key_to_cb;
|
||||||
|
ZWinRegistryGDBUS* proxy;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GLIB TYPE DEFINITIONS & CTORS
|
||||||
|
//
|
||||||
|
G_DEFINE_TYPE(
|
||||||
|
WinTCRegistry,
|
||||||
|
wintc_registry,
|
||||||
|
G_TYPE_OBJECT
|
||||||
|
)
|
||||||
|
|
||||||
|
static void wintc_registry_class_init(
|
||||||
|
WinTCRegistryClass* klass
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->dispose = wintc_registry_dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_registry_init(
|
||||||
|
WinTCRegistry* self
|
||||||
|
)
|
||||||
|
{
|
||||||
|
self->map_key_to_cb =
|
||||||
|
g_hash_table_new_full(
|
||||||
|
g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
g_free
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLASS VIRTUAL METHODS
|
||||||
|
//
|
||||||
|
static void wintc_registry_dispose(
|
||||||
|
GObject* object
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCRegistry* registry = WINTC_REGISTRY(object);
|
||||||
|
|
||||||
|
g_hash_table_destroy(
|
||||||
|
registry->map_key_to_cb
|
||||||
|
);
|
||||||
|
|
||||||
|
(G_OBJECT_CLASS(wintc_registry_parent_class))->dispose(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCRegistry* wintc_registry_new(void)
|
||||||
|
{
|
||||||
|
return WINTC_REGISTRY(
|
||||||
|
g_object_new(
|
||||||
|
WINTC_TYPE_REGISTRY,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean wintc_registry_create_key(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* local_error = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_CLEAR(error);
|
||||||
|
|
||||||
|
if (!wintc_registry_ensure_proxy(registry, &local_error))
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform dbus call
|
||||||
|
//
|
||||||
|
gint result = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!zwin_registry_gdbus_call_create_key_sync(
|
||||||
|
registry->proxy,
|
||||||
|
key_path,
|
||||||
|
&result,
|
||||||
|
NULL,
|
||||||
|
&local_error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean wintc_registry_get_key_value(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
void* value_data,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* local_error = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_CLEAR(error);
|
||||||
|
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD: *((gint*) value_data) = 0; break;
|
||||||
|
case WINTC_REG_QWORD: *((gint64*) value_data) = 0; break;
|
||||||
|
case WINTC_REG_SZ: *((gchar**) value_data) = NULL; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("registry: unknown type %d", value_type);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wintc_registry_ensure_proxy(registry, &local_error))
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform dbus call
|
||||||
|
//
|
||||||
|
gint result = 0;
|
||||||
|
GVariant* value_variant = NULL;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!zwin_registry_gdbus_call_get_key_value_sync(
|
||||||
|
registry->proxy,
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
value_type,
|
||||||
|
&value_variant,
|
||||||
|
&result,
|
||||||
|
NULL,
|
||||||
|
&local_error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
GVariant* inner = g_variant_get_variant(value_variant);
|
||||||
|
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD:
|
||||||
|
*((gint*) value_data) =
|
||||||
|
g_variant_get_int32(inner);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_QWORD:
|
||||||
|
*((gint64*) value_data) =
|
||||||
|
g_variant_get_int64(inner);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_SZ:
|
||||||
|
*((gchar**) value_data) =
|
||||||
|
g_variant_dup_string(inner, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("registry: unknown type %d", value_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_unref(value_variant);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean wintc_registry_set_key_value(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
WinTCRegistryValueType value_type,
|
||||||
|
const void* value_data,
|
||||||
|
gboolean silent,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* local_error = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_CLEAR(error);
|
||||||
|
|
||||||
|
if (!wintc_registry_ensure_proxy(registry, &local_error))
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up variant
|
||||||
|
//
|
||||||
|
GVariant* value_variant = NULL;
|
||||||
|
|
||||||
|
switch (value_type)
|
||||||
|
{
|
||||||
|
case WINTC_REG_DWORD:
|
||||||
|
value_variant =
|
||||||
|
g_variant_new(
|
||||||
|
"v",
|
||||||
|
g_variant_new_int32(
|
||||||
|
*((const gint*) value_data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_QWORD:
|
||||||
|
value_variant =
|
||||||
|
g_variant_new(
|
||||||
|
"v",
|
||||||
|
g_variant_new_int64(
|
||||||
|
*((const gint64*) value_data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINTC_REG_SZ:
|
||||||
|
value_variant =
|
||||||
|
g_variant_new(
|
||||||
|
"v",
|
||||||
|
g_variant_new_string(
|
||||||
|
*((const gchar**) value_data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_critical("registry: unknown type %d", value_type);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform dbus call
|
||||||
|
//
|
||||||
|
gint result = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!zwin_registry_gdbus_call_set_key_value_sync(
|
||||||
|
registry->proxy,
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
value_variant,
|
||||||
|
silent,
|
||||||
|
&result,
|
||||||
|
NULL,
|
||||||
|
&local_error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wintc_registry_watch_key(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
WinTCRegistryKeyCallback callback,
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
|
||||||
|
if (!wintc_registry_ensure_proxy(registry, &error))
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add watcher
|
||||||
|
//
|
||||||
|
RegistryCBData* cb_data = g_new(RegistryCBData, 1);
|
||||||
|
|
||||||
|
cb_data->callback = callback;
|
||||||
|
cb_data->user_data = user_data;
|
||||||
|
|
||||||
|
if (!registry->connected_signal)
|
||||||
|
{
|
||||||
|
g_signal_connect(
|
||||||
|
registry->proxy,
|
||||||
|
"key-value-changed",
|
||||||
|
G_CALLBACK(on_reg_key_value_changed),
|
||||||
|
registry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!g_hash_table_replace(
|
||||||
|
registry->map_key_to_cb,
|
||||||
|
g_strdup(key_path),
|
||||||
|
cb_data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_warning("registry: overwritten key watcher for %s", key_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static gboolean wintc_registry_ensure_proxy(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* local_error = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_CLEAR(error);
|
||||||
|
|
||||||
|
if (registry->proxy)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
registry->proxy =
|
||||||
|
zwin_registry_gdbus_proxy_new_for_bus_sync(
|
||||||
|
G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
"uk.oddmatics.wintc.registry",
|
||||||
|
"/uk/oddmatics/wintc/registry/GDBUS",
|
||||||
|
NULL,
|
||||||
|
&local_error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!registry->proxy)
|
||||||
|
{
|
||||||
|
g_propagate_error(error, local_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLBACKS
|
||||||
|
//
|
||||||
|
static void on_reg_key_value_changed(
|
||||||
|
WINTC_UNUSED(ZWinRegistryGDBUS* proxy),
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_data,
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCRegistry* registry = WINTC_REGISTRY(user_data);
|
||||||
|
|
||||||
|
// Look up if there's a handler for this key
|
||||||
|
//
|
||||||
|
RegistryCBData* cb_data =
|
||||||
|
g_hash_table_lookup(registry->map_key_to_cb, key_path);
|
||||||
|
|
||||||
|
if (!cb_data)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue the callback
|
||||||
|
//
|
||||||
|
GVariant* inner = g_variant_get_variant(value_data);
|
||||||
|
|
||||||
|
cb_data->callback(
|
||||||
|
registry,
|
||||||
|
key_path,
|
||||||
|
value_name,
|
||||||
|
inner,
|
||||||
|
cb_data->user_data
|
||||||
|
);
|
||||||
|
}
|
||||||
28
shared/registry/src/variant.c
Normal file
28
shared/registry/src/variant.c
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "../public/regwrap.h"
|
||||||
|
#include "../public/variant.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCRegistryValueType wintc_registry_get_type_for_variant(
|
||||||
|
GVariant* variant
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (g_variant_is_of_type(variant, G_VARIANT_TYPE_INT32))
|
||||||
|
{
|
||||||
|
return WINTC_REG_DWORD;
|
||||||
|
}
|
||||||
|
else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_INT64))
|
||||||
|
{
|
||||||
|
return WINTC_REG_QWORD;
|
||||||
|
}
|
||||||
|
else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING))
|
||||||
|
{
|
||||||
|
return WINTC_REG_SZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WINTC_REG_INVALID;
|
||||||
|
}
|
||||||
@@ -26,6 +26,8 @@ wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
|||||||
|
|
||||||
add_library(
|
add_library(
|
||||||
libwintc-shcommon
|
libwintc-shcommon
|
||||||
|
src/fs.c
|
||||||
|
public/fs.h
|
||||||
src/path.c
|
src/path.c
|
||||||
public/path.h
|
public/path.h
|
||||||
src/places.c
|
src/places.c
|
||||||
|
|||||||
15
shared/shcommon/public/fs.h
Normal file
15
shared/shcommon/public/fs.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef __SHCOMMON_FS_H__
|
||||||
|
#define __SHCOMMON_FS_H__
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
GSList* wintc_sh_fs_get_names_as_list(
|
||||||
|
const gchar* path,
|
||||||
|
gboolean full_names,
|
||||||
|
GFileTest test,
|
||||||
|
gboolean recursive,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef __WINTC_SHCOMMON_H__
|
#ifndef __WINTC_SHCOMMON_H__
|
||||||
#define __WINTC_SHCOMMON_H__
|
#define __WINTC_SHCOMMON_H__
|
||||||
|
|
||||||
|
#include "@LIB_HEADER_DIR@/fs.h"
|
||||||
#include "@LIB_HEADER_DIR@/path.h"
|
#include "@LIB_HEADER_DIR@/path.h"
|
||||||
#include "@LIB_HEADER_DIR@/places.h"
|
#include "@LIB_HEADER_DIR@/places.h"
|
||||||
|
|
||||||
|
|||||||
93
shared/shcommon/src/fs.c
Normal file
93
shared/shcommon/src/fs.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "../public/fs.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
GSList* wintc_sh_fs_get_names_as_list(
|
||||||
|
const gchar* path,
|
||||||
|
gboolean full_names,
|
||||||
|
GFileTest test,
|
||||||
|
gboolean recursive,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GDir* dir;
|
||||||
|
const gchar* dir_entry = NULL;
|
||||||
|
GSList* dirs_to_enum = NULL;
|
||||||
|
GSList* entries = NULL;
|
||||||
|
GSList* iter = NULL;
|
||||||
|
|
||||||
|
WINTC_SAFE_REF_CLEAR(error);
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG(
|
||||||
|
"shcommon: enum dir %s%s",
|
||||||
|
path,
|
||||||
|
recursive ? " (recursive)" : ""
|
||||||
|
);
|
||||||
|
|
||||||
|
// Push requested path as the first item
|
||||||
|
//
|
||||||
|
dirs_to_enum = g_slist_append(dirs_to_enum, g_strdup(path));
|
||||||
|
iter = dirs_to_enum;
|
||||||
|
|
||||||
|
while (iter)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("shcommon: enum iter dir %s", (gchar*) iter->data);
|
||||||
|
|
||||||
|
dir = g_dir_open((gchar*) iter->data, 0, error);
|
||||||
|
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
g_slist_free_full(dirs_to_enum, g_free);
|
||||||
|
g_slist_free_full(entries, g_free);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((dir_entry = g_dir_read_name(dir)))
|
||||||
|
{
|
||||||
|
gchar* full_path =
|
||||||
|
g_build_path(
|
||||||
|
G_DIR_SEPARATOR_S,
|
||||||
|
(gchar*) iter->data,
|
||||||
|
dir_entry,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
// Take a copy into dirs to enum if needed
|
||||||
|
//
|
||||||
|
if (recursive && g_file_test(full_path, G_FILE_TEST_IS_DIR))
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("shcommon: enum iter, add dir %s", dir_entry);
|
||||||
|
|
||||||
|
dirs_to_enum =
|
||||||
|
g_slist_append(dirs_to_enum, g_strdup(full_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move into entries list if it's one we're interested in
|
||||||
|
//
|
||||||
|
if (!test || g_file_test(full_path, test))
|
||||||
|
{
|
||||||
|
entries =
|
||||||
|
g_slist_append(
|
||||||
|
entries,
|
||||||
|
g_strdup(full_names ? full_path : dir_entry)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(full_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dir_close(dir);
|
||||||
|
|
||||||
|
// Iter to next dir
|
||||||
|
//
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free_full(dirs_to_enum, g_free);
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
@@ -37,8 +37,6 @@ add_library(
|
|||||||
public/cpl.h
|
public/cpl.h
|
||||||
src/error.c
|
src/error.c
|
||||||
public/error.h
|
public/error.h
|
||||||
src/fs.c
|
|
||||||
src/fs.h
|
|
||||||
src/icnvwbeh.c
|
src/icnvwbeh.c
|
||||||
public/icnvwbeh.h
|
public/icnvwbeh.h
|
||||||
public/trevwbeh.h
|
public/trevwbeh.h
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <wintc/comgtk.h>
|
#include <wintc/comgtk.h>
|
||||||
|
#include <wintc/shcommon.h>
|
||||||
|
|
||||||
#include "../public/cpl.h"
|
#include "../public/cpl.h"
|
||||||
#include "fs.h"
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// PRIVATE CONSTANTS
|
// PRIVATE CONSTANTS
|
||||||
@@ -20,7 +20,14 @@ static const gchar* S_CPL_KEY_ICON_NAME = "Icon";
|
|||||||
//
|
//
|
||||||
GSList* wintc_sh_cpl_applet_get_all(void)
|
GSList* wintc_sh_cpl_applet_get_all(void)
|
||||||
{
|
{
|
||||||
GSList* entries = wintc_sh_fs_get_names_as_list(S_CPL_ENTRIES_DIR, TRUE, NULL);
|
GSList* entries =
|
||||||
|
wintc_sh_fs_get_names_as_list(
|
||||||
|
S_CPL_ENTRIES_DIR,
|
||||||
|
TRUE,
|
||||||
|
G_FILE_TEST_IS_REGULAR,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
if (!entries)
|
if (!entries)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
#include <glib.h>
|
|
||||||
#include <wintc/comgtk.h>
|
|
||||||
|
|
||||||
#include "fs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// PUBLIC FUNCTIONS
|
|
||||||
//
|
|
||||||
GSList* wintc_sh_fs_get_names_as_list(
|
|
||||||
const gchar* path,
|
|
||||||
gboolean full_names,
|
|
||||||
GError** error
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GDir* dir;
|
|
||||||
const gchar* dir_entry = NULL;
|
|
||||||
GSList* entries = NULL;
|
|
||||||
|
|
||||||
WINTC_SAFE_REF_CLEAR(error);
|
|
||||||
|
|
||||||
WINTC_LOG_DEBUG("fs: enum dir %s", path);
|
|
||||||
|
|
||||||
dir = g_dir_open(path, 0, error);
|
|
||||||
|
|
||||||
if (!dir)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((dir_entry = g_dir_read_name(dir)))
|
|
||||||
{
|
|
||||||
gchar* next_name = full_names ?
|
|
||||||
g_build_path(
|
|
||||||
G_DIR_SEPARATOR_S,
|
|
||||||
path,
|
|
||||||
dir_entry,
|
|
||||||
NULL
|
|
||||||
) :
|
|
||||||
g_strdup(dir_entry);
|
|
||||||
|
|
||||||
entries = g_slist_append(entries, next_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_dir_close(dir);
|
|
||||||
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#ifndef __FS_H__
|
|
||||||
#define __FS_H__
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// FIXME: Temp! fs.c/h should be moved to another lib!
|
|
||||||
//
|
|
||||||
// For now we just have sync I/O here, we need:
|
|
||||||
// - Should move to async I/O
|
|
||||||
// - Move FS stuff to a separate lib
|
|
||||||
// - MIME type detection
|
|
||||||
// - Symlink/shortcut handling
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// PUBLIC FUNCTIONS
|
|
||||||
//
|
|
||||||
GSList* wintc_sh_fs_get_names_as_list(
|
|
||||||
const gchar* path,
|
|
||||||
gboolean full_names,
|
|
||||||
GError** error
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <wintc/shcommon.h>
|
#include <wintc/shcommon.h>
|
||||||
|
|
||||||
#include "../public/vwfs.h"
|
#include "../public/vwfs.h"
|
||||||
#include "fs.h"
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// PRIVATE ENUMS
|
// PRIVATE ENUMS
|
||||||
@@ -262,7 +261,14 @@ void wintc_sh_view_fs_refresh_items(
|
|||||||
|
|
||||||
// FIXME: Error handling (no way of passing to caller)
|
// FIXME: Error handling (no way of passing to caller)
|
||||||
//
|
//
|
||||||
GSList* entries = wintc_sh_fs_get_names_as_list(view_fs->path, FALSE, NULL);
|
GSList* entries =
|
||||||
|
wintc_sh_fs_get_names_as_list(
|
||||||
|
view_fs->path,
|
||||||
|
FALSE,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
// Create actual array
|
// Create actual array
|
||||||
// FIXME: list->array should probs be in comgtk
|
// FIXME: list->array should probs be in comgtk
|
||||||
|
|||||||
116
shell/cpl/desk/CMakeLists.txt
Normal file
116
shell/cpl/desk/CMakeLists.txt
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(
|
||||||
|
wintc-cpl-desk
|
||||||
|
VERSION 1.0
|
||||||
|
DESCRIPTION "Windows Total Conversion Display Control Panel applet."
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_ANYARCH false)
|
||||||
|
set(PROJECT_FREESTATUS true)
|
||||||
|
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
|
||||||
|
|
||||||
|
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
include(../../../packaging/cmake-inc/common/CMakeLists.txt)
|
||||||
|
include(../../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||||
|
include(../../../packaging/cmake-inc/locale/CMakeLists.txt)
|
||||||
|
include(../../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||||
|
include(../../../packaging/cmake-inc/resources/CMakeLists.txt)
|
||||||
|
|
||||||
|
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-registry WINTC_REGISTRY)
|
||||||
|
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
|
||||||
|
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
|
||||||
|
|
||||||
|
wintc_compile_resources()
|
||||||
|
wintc_create_meta_h()
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
wintc-cpl-desk
|
||||||
|
src/application.c
|
||||||
|
src/application.h
|
||||||
|
src/main.c
|
||||||
|
src/meta.h
|
||||||
|
src/monitor.c
|
||||||
|
src/monitor.h
|
||||||
|
src/resources.c
|
||||||
|
src/settings.c
|
||||||
|
src/settings.h
|
||||||
|
src/window.c
|
||||||
|
src/window.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
wintc-cpl-desk
|
||||||
|
PROPERTIES
|
||||||
|
OUTPUT_NAME desk.cpl
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(
|
||||||
|
wintc-cpl-desk
|
||||||
|
PRIVATE ${WINTC_COMPILE_OPTIONS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
wintc-cpl-desk
|
||||||
|
SYSTEM
|
||||||
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMCTL_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHCOMMON_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHLANG_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_directories(
|
||||||
|
wintc-cpl-desk
|
||||||
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMCTL_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHCOMMON_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_SHLANG_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
wintc-cpl-desk
|
||||||
|
PRIVATE m
|
||||||
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_COMCTL_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_SHCOMMON_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_SHLANG_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(
|
||||||
|
wintc-cpl-desk
|
||||||
|
build-gresources
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
#
|
||||||
|
wintc_configure_and_install_packaging()
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES desk.desktop
|
||||||
|
DESTINATION share/wintc/cpl
|
||||||
|
)
|
||||||
|
install(
|
||||||
|
FILES uk.co.oddmatics.wintc.cpl-desk.desktop
|
||||||
|
DESTINATION share/applications
|
||||||
|
)
|
||||||
|
install(
|
||||||
|
TARGETS wintc-cpl-desk
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
7
shell/cpl/desk/deps
Normal file
7
shell/cpl/desk/deps
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
bt,rt:glib2
|
||||||
|
bt,rt:gtk3
|
||||||
|
bt,rt:wintc-comctl
|
||||||
|
bt,rt:wintc-comgtk
|
||||||
|
bt,rt:wintc-registry
|
||||||
|
bt,rt:wintc-shcommon
|
||||||
|
bt,rt:wintc-shlang
|
||||||
5
shell/cpl/desk/desk.desktop
Normal file
5
shell/cpl/desk/desk.desktop
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[CplApplet]
|
||||||
|
Name=Display
|
||||||
|
Comment=Change the appearance of your desktop, such as the background, screen saver, colors, font sizes, and screen resolution.
|
||||||
|
Exec=desk.cpl
|
||||||
|
Icon=preferences-desktop-display
|
||||||
97
shell/cpl/desk/src/application.c
Normal file
97
shell/cpl/desk/src/application.c
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <wintc/comctl.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// CONSTANTS
|
||||||
|
//
|
||||||
|
static const gchar* S_APP_ID = "uk.co.oddmatics.wintc.cpl-desk";
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||||
|
//
|
||||||
|
struct _WinTCCplDeskApplicationClass
|
||||||
|
{
|
||||||
|
GtkApplicationClass __parent__;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WinTCCplDeskApplication
|
||||||
|
{
|
||||||
|
GtkApplication __parent__;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_application_activate(
|
||||||
|
GApplication* application
|
||||||
|
);
|
||||||
|
static void wintc_cpl_desk_application_startup(
|
||||||
|
GApplication* application
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK TYPE DEFINITIONS & CTORS
|
||||||
|
//
|
||||||
|
G_DEFINE_TYPE(
|
||||||
|
WinTCCplDeskApplication,
|
||||||
|
wintc_cpl_desk_application,
|
||||||
|
GTK_TYPE_APPLICATION
|
||||||
|
)
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_application_class_init(
|
||||||
|
WinTCCplDeskApplicationClass* klass
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GApplicationClass* application_class = G_APPLICATION_CLASS(klass);
|
||||||
|
|
||||||
|
application_class->activate = wintc_cpl_desk_application_activate;
|
||||||
|
application_class->startup = wintc_cpl_desk_application_startup;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_application_init(
|
||||||
|
WINTC_UNUSED(WinTCCplDeskApplication* self)
|
||||||
|
) { }
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLASS VIRTUAL METHODS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_application_activate(
|
||||||
|
GApplication* application
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GtkWidget* new_window =
|
||||||
|
wintc_cpl_desk_window_new(WINTC_CPL_DESK_APPLICATION(application));
|
||||||
|
|
||||||
|
gtk_widget_show_all(new_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_application_startup(
|
||||||
|
GApplication* application
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(G_APPLICATION_CLASS(wintc_cpl_desk_application_parent_class))
|
||||||
|
->startup(application);
|
||||||
|
|
||||||
|
g_set_prgname(S_APP_ID);
|
||||||
|
|
||||||
|
wintc_ctl_install_default_styles();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCCplDeskApplication* wintc_cpl_desk_application_new(void)
|
||||||
|
{
|
||||||
|
return WINTC_CPL_DESK_APPLICATION(
|
||||||
|
g_object_new(
|
||||||
|
wintc_cpl_desk_application_get_type(),
|
||||||
|
"application-id", S_APP_ID,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
27
shell/cpl/desk/src/application.h
Normal file
27
shell/cpl/desk/src/application.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef __APPLICATION_H__
|
||||||
|
#define __APPLICATION_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP BOILERPLATE
|
||||||
|
//
|
||||||
|
typedef struct _WinTCCplDeskApplicationClass WinTCCplDeskApplicationClass;
|
||||||
|
typedef struct _WinTCCplDeskApplication WinTCCplDeskApplication;
|
||||||
|
|
||||||
|
#define WINTC_TYPE_CPL_DESK_APPLICATION (wintc_cpl_desk_application_get_type())
|
||||||
|
#define WINTC_CPL_DESK_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_CPL_DESK_APPLICATION, WinTCCplDeskApplication))
|
||||||
|
#define WINTC_CPL_DESK_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_CPL_DESK_APPLICATION, WinTCCplDeskApplicationClass))
|
||||||
|
#define IS_WINTC_CPL_DESK_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_CPL_DESK_APPLICATION))
|
||||||
|
#define IS_WINTC_CPL_DESK_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_CPL_DESK_APPLICATION))
|
||||||
|
#define WINTC_CPL_DESK_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_CPL_DESK_APPLICATION, WinTCCplDeskApplicationClass))
|
||||||
|
|
||||||
|
GType wintc_cpl_desk_application_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCCplDeskApplication* wintc_cpl_desk_application_new(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
32
shell/cpl/desk/src/main.c
Normal file
32
shell/cpl/desk/src/main.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <wintc/shlang.h>
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
int main(
|
||||||
|
int argc,
|
||||||
|
char* argv[]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Set up locales
|
||||||
|
//
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
bindtextdomain(PKG_NAME, WINTC_LOCALE_DIR);
|
||||||
|
textdomain(PKG_NAME);
|
||||||
|
|
||||||
|
// Launch application
|
||||||
|
//
|
||||||
|
WinTCCplDeskApplication* app = wintc_cpl_desk_application_new();
|
||||||
|
int status;
|
||||||
|
|
||||||
|
g_set_application_name("Display");
|
||||||
|
|
||||||
|
status = g_application_run(G_APPLICATION(app), argc, argv);
|
||||||
|
|
||||||
|
g_object_unref(app);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
303
shell/cpl/desk/src/monitor.c
Normal file
303
shell/cpl/desk/src/monitor.c
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// STATIC CONSTANTS
|
||||||
|
//
|
||||||
|
static const gint S_PREVIEW_IMAGE_OFFSET_X = 16;
|
||||||
|
static const gint S_PREVIEW_IMAGE_OFFSET_Y = 17;
|
||||||
|
|
||||||
|
static const gint S_PREVIEW_IMAGE_WIDTH = 152;
|
||||||
|
static const gint S_PREVIEW_IMAGE_HEIGHT = 112;
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||||
|
//
|
||||||
|
struct _WinTCDeskMonitorClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass __parent__;
|
||||||
|
|
||||||
|
GdkPixbuf* pixbuf_monitor;
|
||||||
|
cairo_surface_t* surface_monitor;
|
||||||
|
|
||||||
|
gint pixbuf_monitor_height;
|
||||||
|
gint pixbuf_monitor_width;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WinTCDeskMonitor
|
||||||
|
{
|
||||||
|
GtkWidget __parent__;
|
||||||
|
|
||||||
|
// UI
|
||||||
|
//
|
||||||
|
GdkPixbuf* pixbuf_preview;
|
||||||
|
cairo_surface_t* surface_preview;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void wintc_desk_monitor_dispose(
|
||||||
|
GObject* object
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean wintc_desk_monitor_draw(
|
||||||
|
GtkWidget* widget,
|
||||||
|
cairo_t* cr
|
||||||
|
);
|
||||||
|
static void wintc_desk_monitor_get_preferred_height(
|
||||||
|
GtkWidget* widget,
|
||||||
|
gint* minimum_height,
|
||||||
|
gint* natural_height
|
||||||
|
);
|
||||||
|
static void wintc_desk_monitor_get_preferred_height_for_width(
|
||||||
|
GtkWidget* widget,
|
||||||
|
gint width,
|
||||||
|
gint* minimum_height,
|
||||||
|
gint* natural_height
|
||||||
|
);
|
||||||
|
static void wintc_desk_monitor_get_preferred_width(
|
||||||
|
GtkWidget* widget,
|
||||||
|
gint* minimum_width,
|
||||||
|
gint* natural_width
|
||||||
|
);
|
||||||
|
static void wintc_desk_monitor_get_preferred_width_for_height(
|
||||||
|
GtkWidget* widget,
|
||||||
|
gint height,
|
||||||
|
gint* minimum_width,
|
||||||
|
gint* natural_width
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK TYPE DEFINITIONS & CTORS
|
||||||
|
//
|
||||||
|
G_DEFINE_TYPE(
|
||||||
|
WinTCDeskMonitor,
|
||||||
|
wintc_desk_monitor,
|
||||||
|
GTK_TYPE_WIDGET
|
||||||
|
)
|
||||||
|
|
||||||
|
static void wintc_desk_monitor_class_init(
|
||||||
|
WinTCDeskMonitorClass* klass
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
|
||||||
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->dispose = wintc_desk_monitor_dispose;
|
||||||
|
|
||||||
|
widget_class->draw =
|
||||||
|
wintc_desk_monitor_draw;
|
||||||
|
widget_class->get_preferred_height =
|
||||||
|
wintc_desk_monitor_get_preferred_height;
|
||||||
|
widget_class->get_preferred_height_for_width =
|
||||||
|
wintc_desk_monitor_get_preferred_height_for_width;
|
||||||
|
widget_class->get_preferred_width =
|
||||||
|
wintc_desk_monitor_get_preferred_width;
|
||||||
|
widget_class->get_preferred_width_for_height =
|
||||||
|
wintc_desk_monitor_get_preferred_width_for_height;
|
||||||
|
|
||||||
|
// Load shared monitor graphic resource
|
||||||
|
//
|
||||||
|
GError* error = NULL;
|
||||||
|
|
||||||
|
klass->pixbuf_monitor =
|
||||||
|
gdk_pixbuf_new_from_resource(
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/monitor.png",
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
|
||||||
|
if (klass->pixbuf_monitor)
|
||||||
|
{
|
||||||
|
klass->surface_monitor =
|
||||||
|
gdk_cairo_surface_create_from_pixbuf(
|
||||||
|
klass->pixbuf_monitor,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
klass->pixbuf_monitor_height =
|
||||||
|
gdk_pixbuf_get_height(
|
||||||
|
klass->pixbuf_monitor
|
||||||
|
);
|
||||||
|
klass->pixbuf_monitor_width =
|
||||||
|
gdk_pixbuf_get_width(
|
||||||
|
klass->pixbuf_monitor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desk_monitor_init(
|
||||||
|
WinTCDeskMonitor* self
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gtk_widget_set_has_window(GTK_WIDGET(self), FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLASS VIRTUAL METHODS
|
||||||
|
//
|
||||||
|
static void wintc_desk_monitor_dispose(
|
||||||
|
GObject* object
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDeskMonitor* monitor = WINTC_DESK_MONITOR(object);
|
||||||
|
|
||||||
|
g_clear_object(&(monitor->pixbuf_preview));
|
||||||
|
cairo_surface_destroy(g_steal_pointer(&monitor->surface_preview));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean wintc_desk_monitor_draw(
|
||||||
|
GtkWidget* widget,
|
||||||
|
cairo_t* cr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDeskMonitorClass* klass = WINTC_DESK_MONITOR_GET_CLASS(widget);
|
||||||
|
WinTCDeskMonitor* monitor = WINTC_DESK_MONITOR(widget);
|
||||||
|
|
||||||
|
// monitor size
|
||||||
|
gint monitor_height = klass->pixbuf_monitor_height;
|
||||||
|
gint monitor_width = klass->pixbuf_monitor_width;
|
||||||
|
|
||||||
|
// my size
|
||||||
|
gint my_height = gtk_widget_get_allocated_height(widget);
|
||||||
|
gint my_width = gtk_widget_get_allocated_width(widget);
|
||||||
|
|
||||||
|
// drawing origin
|
||||||
|
gdouble target_x = floor((my_width / 2.0f) - (monitor_width / 2.0f));
|
||||||
|
gdouble target_y = floor((my_height / 2.0f) - (monitor_height / 2.0f));
|
||||||
|
|
||||||
|
cairo_translate(
|
||||||
|
cr,
|
||||||
|
target_x,
|
||||||
|
target_y
|
||||||
|
);
|
||||||
|
cairo_set_source_surface(
|
||||||
|
cr,
|
||||||
|
klass->surface_monitor,
|
||||||
|
0.0f,
|
||||||
|
0.0f
|
||||||
|
);
|
||||||
|
cairo_pattern_set_extend(
|
||||||
|
cairo_get_source(cr),
|
||||||
|
CAIRO_EXTEND_NONE
|
||||||
|
);
|
||||||
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
if (monitor->surface_preview)
|
||||||
|
{
|
||||||
|
cairo_translate(
|
||||||
|
cr,
|
||||||
|
S_PREVIEW_IMAGE_OFFSET_X,
|
||||||
|
S_PREVIEW_IMAGE_OFFSET_Y
|
||||||
|
);
|
||||||
|
cairo_set_source_surface(
|
||||||
|
cr,
|
||||||
|
monitor->surface_preview,
|
||||||
|
0.0f,
|
||||||
|
0.0f
|
||||||
|
);
|
||||||
|
cairo_pattern_set_extend(
|
||||||
|
cairo_get_source(cr),
|
||||||
|
CAIRO_EXTEND_NONE
|
||||||
|
);
|
||||||
|
cairo_paint(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desk_monitor_get_preferred_height(
|
||||||
|
GtkWidget* widget,
|
||||||
|
gint* minimum_height,
|
||||||
|
gint* natural_height
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDeskMonitorClass* klass = WINTC_DESK_MONITOR_GET_CLASS(widget);
|
||||||
|
|
||||||
|
*minimum_height = klass->pixbuf_monitor_height;
|
||||||
|
*natural_height = klass->pixbuf_monitor_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desk_monitor_get_preferred_height_for_width(
|
||||||
|
GtkWidget* widget,
|
||||||
|
WINTC_UNUSED(gint width),
|
||||||
|
gint* minimum_height,
|
||||||
|
gint* natural_height
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_desk_monitor_get_preferred_height(
|
||||||
|
widget,
|
||||||
|
minimum_height,
|
||||||
|
natural_height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desk_monitor_get_preferred_width(
|
||||||
|
GtkWidget* widget,
|
||||||
|
gint* minimum_width,
|
||||||
|
gint* natural_width
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDeskMonitorClass* klass = WINTC_DESK_MONITOR_GET_CLASS(widget);
|
||||||
|
|
||||||
|
*minimum_width = klass->pixbuf_monitor_width;
|
||||||
|
*natural_width = klass->pixbuf_monitor_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desk_monitor_get_preferred_width_for_height(
|
||||||
|
GtkWidget* widget,
|
||||||
|
WINTC_UNUSED(gint height),
|
||||||
|
gint* minimum_width,
|
||||||
|
gint* natural_width
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_desk_monitor_get_preferred_width(
|
||||||
|
widget,
|
||||||
|
minimum_width,
|
||||||
|
natural_width
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
GtkWidget* wintc_desk_monitor_new(void)
|
||||||
|
{
|
||||||
|
return GTK_WIDGET(
|
||||||
|
g_object_new(
|
||||||
|
WINTC_TYPE_DESK_MONITOR,
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wintc_desk_monitor_set_pixbuf(
|
||||||
|
WinTCDeskMonitor* monitor,
|
||||||
|
const GdkPixbuf* pixbuf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_clear_object(&(monitor->pixbuf_preview));
|
||||||
|
cairo_surface_destroy(g_steal_pointer(&monitor->surface_preview));
|
||||||
|
|
||||||
|
monitor->pixbuf_preview =
|
||||||
|
gdk_pixbuf_scale_simple(
|
||||||
|
pixbuf,
|
||||||
|
S_PREVIEW_IMAGE_WIDTH,
|
||||||
|
S_PREVIEW_IMAGE_HEIGHT,
|
||||||
|
GDK_INTERP_NEAREST
|
||||||
|
);
|
||||||
|
monitor->surface_preview =
|
||||||
|
gdk_cairo_surface_create_from_pixbuf(
|
||||||
|
monitor->pixbuf_preview,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
33
shell/cpl/desk/src/monitor.h
Normal file
33
shell/cpl/desk/src/monitor.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __MONITOR_H__
|
||||||
|
#define __MONITOR_H__
|
||||||
|
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP BOILERPLATE
|
||||||
|
//
|
||||||
|
typedef struct _WinTCDeskMonitorClass WinTCDeskMonitorClass;
|
||||||
|
typedef struct _WinTCDeskMonitor WinTCDeskMonitor;
|
||||||
|
|
||||||
|
#define WINTC_TYPE_DESK_MONITOR (wintc_desk_monitor_get_type())
|
||||||
|
#define WINTC_DESK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_DESK_MONITOR, WinTCDeskMonitor))
|
||||||
|
#define WINTC_DESK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_DESK_MONITOR, WinTCDeskMonitorClass))
|
||||||
|
#define IS_WINTC_DESK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_DESK_MONITOR))
|
||||||
|
#define IS_WINTC_DESK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_DESK_MONITOR))
|
||||||
|
#define WINTC_DESK_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_DESK_MONITOR, WinTCDeskMonitorClass))
|
||||||
|
|
||||||
|
GType wintc_desk_monitor_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
GtkWidget* wintc_desk_monitor_new(void);
|
||||||
|
|
||||||
|
void wintc_desk_monitor_set_pixbuf(
|
||||||
|
WinTCDeskMonitor* monitor,
|
||||||
|
const GdkPixbuf* pixbuf
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
80
shell/cpl/desk/src/res/desk.ui
Normal file
80
shell/cpl/desk/src/res/desk.ui
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.40.0 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkBox" id="main-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkNotebook" id="main-notebook">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button-apply">
|
||||||
|
<property name="label" translatable="no">Apply</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="action-name">win.apply</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button-cancel">
|
||||||
|
<property name="label" translatable="no">%CTL_CANCEL%</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="action-name">win.cancel</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button-ok">
|
||||||
|
<property name="label" translatable="no">%CTL_OK%</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="action-name">win.ok</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="wintc-button-box"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
BIN
shell/cpl/desk/src/res/monitor.png
Normal file
BIN
shell/cpl/desk/src/res/monitor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
164
shell/cpl/desk/src/res/page-appearance.ui
Normal file
164
shell/cpl/desk/src/res/page-appearance.ui
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkLabel" id="label-title">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Appearance</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="page-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<!-- TODO: Need theme preview thing - uxtheme -->
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<!-- Drop downs column -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Windows and buttons:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Color scheme:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Font size:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">5</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- Side buttons column -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="valign">2</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="halign">2</property>
|
||||||
|
<property name="label" translatable="yes">Effects...</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="halign">2</property>
|
||||||
|
<property name="label" translatable="yes">Advanced</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
183
shell/cpl/desk/src/res/page-desktop.ui
Normal file
183
shell/cpl/desk/src/res/page-desktop.ui
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkLabel" id="label-title">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Desktop</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="page-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="WinTCDeskMonitor" id="monitor">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Background:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- Form stuff - one horizontal outer box with two inner vert boxes -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<!-- Wallpaper selection -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="overlay-scrolling">False</property>
|
||||||
|
<property name="vscrollbar-policy">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="listbox-wallpapers">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="label" translatable="yes">Customize Desktop...</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- Additional wallpaper settings -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="label" translatable="yes">%PUNC_MOREINPUT%%CTL_BROWSE%</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Position:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Color:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkColorButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
219
shell/cpl/desk/src/res/page-scrnsave.ui
Normal file
219
shell/cpl/desk/src/res/page-scrnsave.ui
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkLabel" id="label-title">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Screen Saver</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="page-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="WinTCDeskMonitor" id="monitor">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- Screen saver options -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Screen saver</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="label" translatable="yes">Settings</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="label" translatable="yes">Preview</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Wait:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">minutes</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">On resume, display Welcome screen</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Monitor power</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">To adjust monitor power settings and save energy, click Power.</property>
|
||||||
|
<property name="max-width-chars">49</property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
<property name="xalign">1.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="halign">2</property>
|
||||||
|
<property name="label" translatable="yes">Power</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
187
shell/cpl/desk/src/res/page-settings.ui
Normal file
187
shell/cpl/desk/src/res/page-settings.ui
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkLabel" id="label-title">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Settings</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="page-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<!-- TODO: Need monitor preview widget -->
|
||||||
|
<child>
|
||||||
|
<object class="WinTCDeskMonitor" id="monitor">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Display:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">(not implemented)</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<!-- Screen resolution frame -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Screen resolution</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Less</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScale">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">More</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">blam! pixels</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Color quality</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- TODO: Color graphic thing here -->
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
113
shell/cpl/desk/src/res/page-themes.ui
Normal file
113
shell/cpl/desk/src/res/page-themes.ui
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkLabel" id="label-title">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Themes</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="page-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">A theme is a background plus a set of sounds, icons, and other elements to help you personalize your computer with one click.</property>
|
||||||
|
<property name="max-width-chars">71</property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- Theme selection -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Theme:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox">
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="label" translatable="yes">%CTL_SAVEAS%</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="label" translatable="yes">%CTL_DELETE%</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<!-- Theme preview -->
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Sample:</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
13
shell/cpl/desk/src/res/resources.xml
Normal file
13
shell/cpl/desk/src/res/resources.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/uk/oddmatics/wintc/cpl-desk">
|
||||||
|
<file>desk.ui</file>
|
||||||
|
<file>page-appearance.ui</file>
|
||||||
|
<file>page-desktop.ui</file>
|
||||||
|
<file>page-scrnsave.ui</file>
|
||||||
|
<file>page-settings.ui</file>
|
||||||
|
<file>page-themes.ui</file>
|
||||||
|
<file>monitor.png</file>
|
||||||
|
<file>sample.png</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
||||||
BIN
shell/cpl/desk/src/res/sample.png
Normal file
BIN
shell/cpl/desk/src/res/sample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
246
shell/cpl/desk/src/settings.c
Normal file
246
shell/cpl/desk/src/settings.c
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
#include <wintc/registry.h>
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE ENUMS
|
||||||
|
//
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_SETTINGS_CHANGED = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||||
|
//
|
||||||
|
struct _WinTCCplDeskSettingsClass
|
||||||
|
{
|
||||||
|
GObjectClass __parent__;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WinTCCplDeskSettings
|
||||||
|
{
|
||||||
|
GObject __parent__;
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
//
|
||||||
|
gchar* wallpaper_path;
|
||||||
|
|
||||||
|
// State
|
||||||
|
//
|
||||||
|
gboolean changed;
|
||||||
|
WinTCRegistry* registry;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DELCARATIONS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_settings_get_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
);
|
||||||
|
static void wintc_cpl_desk_settings_set_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
);
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_settings_bump_changed(
|
||||||
|
WinTCCplDeskSettings* settings
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK TYPE DEFINITIONS & CTORS
|
||||||
|
//
|
||||||
|
G_DEFINE_TYPE(
|
||||||
|
WinTCCplDeskSettings,
|
||||||
|
wintc_cpl_desk_settings,
|
||||||
|
G_TYPE_OBJECT
|
||||||
|
)
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_settings_class_init(
|
||||||
|
WinTCCplDeskSettingsClass* klass
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->get_property = wintc_cpl_desk_settings_get_property;
|
||||||
|
object_class->set_property = wintc_cpl_desk_settings_set_property;
|
||||||
|
|
||||||
|
g_object_class_install_property(
|
||||||
|
object_class,
|
||||||
|
PROP_SETTINGS_CHANGED,
|
||||||
|
g_param_spec_boolean(
|
||||||
|
"settings-changed",
|
||||||
|
"SettingsChanged",
|
||||||
|
"The state of whether there are unsaved changes to settings.",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_settings_init(
|
||||||
|
WinTCCplDeskSettings* self
|
||||||
|
)
|
||||||
|
{
|
||||||
|
self->registry = wintc_registry_new();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLASS VIRTUAL METHODS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_settings_get_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCCplDeskSettings* settings = WINTC_CPL_DESK_SETTINGS(object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SETTINGS_CHANGED:
|
||||||
|
g_value_set_boolean(value, settings->changed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_settings_set_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCCplDeskSettings* settings = WINTC_CPL_DESK_SETTINGS(object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SETTINGS_CHANGED:
|
||||||
|
settings->changed = g_value_get_boolean(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCCplDeskSettings* wintc_cpl_desk_settings_new(void)
|
||||||
|
{
|
||||||
|
return g_object_new(WINTC_TYPE_CPL_DESK_SETTINGS, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean wintc_cpl_desk_settings_apply(
|
||||||
|
WinTCCplDeskSettings* settings,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!wintc_registry_set_key_value(
|
||||||
|
settings->registry,
|
||||||
|
"HKCU\\Control Panel\\Desktop",
|
||||||
|
"Wallpaper",
|
||||||
|
WINTC_REG_SZ,
|
||||||
|
&(settings->wallpaper_path),
|
||||||
|
FALSE,
|
||||||
|
error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set(
|
||||||
|
settings,
|
||||||
|
"settings-changed", FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean wintc_cpl_desk_settings_load(
|
||||||
|
WinTCCplDeskSettings* settings,
|
||||||
|
GError** error
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gchar* sz_wallpaper = NULL;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!wintc_registry_get_key_value(
|
||||||
|
settings->registry,
|
||||||
|
"HKCU\\Control Panel\\Desktop",
|
||||||
|
"Wallpaper",
|
||||||
|
WINTC_REG_SZ,
|
||||||
|
&sz_wallpaper,
|
||||||
|
error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bin old settings
|
||||||
|
//
|
||||||
|
g_free(g_steal_pointer(&(settings->wallpaper_path)));
|
||||||
|
|
||||||
|
// Load in new settings
|
||||||
|
//
|
||||||
|
settings->wallpaper_path = sz_wallpaper;
|
||||||
|
|
||||||
|
g_object_set(
|
||||||
|
settings,
|
||||||
|
"settings-changed", FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar* wintc_cpl_desk_settings_get_wallpaper(
|
||||||
|
WinTCCplDeskSettings* settings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return settings->wallpaper_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wintc_cpl_desk_settings_set_wallpaper(
|
||||||
|
WinTCCplDeskSettings* settings,
|
||||||
|
const gchar* path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_free(g_steal_pointer(&(settings->wallpaper_path)));
|
||||||
|
|
||||||
|
settings->wallpaper_path = g_strdup(path);
|
||||||
|
|
||||||
|
wintc_cpl_desk_settings_bump_changed(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_settings_bump_changed(
|
||||||
|
WinTCCplDeskSettings* settings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_object_set(
|
||||||
|
settings,
|
||||||
|
"settings-changed", TRUE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
43
shell/cpl/desk/src/settings.h
Normal file
43
shell/cpl/desk/src/settings.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef __SETTINGS_H__
|
||||||
|
#define __SETTINGS_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP BOILERPLATE
|
||||||
|
//
|
||||||
|
typedef struct _WinTCCplDeskSettingsClass WinTCCplDeskSettingsClass;
|
||||||
|
typedef struct _WinTCCplDeskSettings WinTCCplDeskSettings;
|
||||||
|
|
||||||
|
#define WINTC_TYPE_CPL_DESK_SETTINGS (wintc_cpl_desk_settings_get_type())
|
||||||
|
#define WINTC_CPL_DESK_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_CPL_DESK_SETTINGS, WinTCCplDeskSettings))
|
||||||
|
#define WINTC_CPL_DESK_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_CPL_DESK_SETTINGS, WinTCCplDeskSettingsClass))
|
||||||
|
#define IS_WINTC_CPL_DESK_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_CPL_DESK_SETTINGS))
|
||||||
|
#define IS_WINTC_CPL_DESK_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_CPL_DESK_SETTINGS))
|
||||||
|
#define WINTC_CPL_DESK_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_CPL_DESK_SETTINGS, WinTCCplDeskSettingsClass))
|
||||||
|
|
||||||
|
GType wintc_cpl_desk_settings_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCCplDeskSettings* wintc_cpl_desk_settings_new(void);
|
||||||
|
|
||||||
|
gboolean wintc_cpl_desk_settings_apply(
|
||||||
|
WinTCCplDeskSettings* settings,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
gboolean wintc_cpl_desk_settings_load(
|
||||||
|
WinTCCplDeskSettings* settings,
|
||||||
|
GError** error
|
||||||
|
);
|
||||||
|
|
||||||
|
const gchar* wintc_cpl_desk_settings_get_wallpaper(
|
||||||
|
WinTCCplDeskSettings* settings
|
||||||
|
);
|
||||||
|
void wintc_cpl_desk_settings_set_wallpaper(
|
||||||
|
WinTCCplDeskSettings* settings,
|
||||||
|
const gchar* path
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
520
shell/cpl/desk/src/window.c
Normal file
520
shell/cpl/desk/src/window.c
Normal file
@@ -0,0 +1,520 @@
|
|||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <wintc/comctl.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
#include <wintc/shcommon.h>
|
||||||
|
#include <wintc/shlang.h>
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_window_finalize(
|
||||||
|
GObject* object
|
||||||
|
);
|
||||||
|
|
||||||
|
static void add_wallpaper_to_list(
|
||||||
|
WinTCCplDeskWindow* wnd,
|
||||||
|
const gchar* path
|
||||||
|
);
|
||||||
|
static void refresh_wallpaper_list(
|
||||||
|
WinTCCplDeskWindow* wnd
|
||||||
|
);
|
||||||
|
static void select_wallpaper_from_list(
|
||||||
|
WinTCCplDeskWindow* wnd,
|
||||||
|
const gchar* path
|
||||||
|
);
|
||||||
|
|
||||||
|
static void action_apply(
|
||||||
|
GSimpleAction* action,
|
||||||
|
GVariant* parameter,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
static void action_cancel(
|
||||||
|
GSimpleAction* action,
|
||||||
|
GVariant* parameter,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
static void action_ok(
|
||||||
|
GSimpleAction* action,
|
||||||
|
GVariant* parameter,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
static void on_listbox_wallpapers_row_selected(
|
||||||
|
GtkListBox* self,
|
||||||
|
GtkListBoxRow* row,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
static gboolean on_window_map_event(
|
||||||
|
GtkWidget* self,
|
||||||
|
GdkEventAny* event,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// STATIC DATA
|
||||||
|
//
|
||||||
|
static GActionEntry s_window_actions[] = {
|
||||||
|
{
|
||||||
|
.name = "apply",
|
||||||
|
.activate = action_apply,
|
||||||
|
.parameter_type = NULL,
|
||||||
|
.state = NULL,
|
||||||
|
.change_state = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "cancel",
|
||||||
|
.activate = action_cancel,
|
||||||
|
.parameter_type = NULL,
|
||||||
|
.state = NULL,
|
||||||
|
.change_state = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "ok",
|
||||||
|
.activate = action_ok,
|
||||||
|
.parameter_type = NULL,
|
||||||
|
.state = NULL,
|
||||||
|
.change_state = NULL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||||
|
//
|
||||||
|
struct _WinTCCplDeskWindowClass
|
||||||
|
{
|
||||||
|
GtkApplicationWindowClass __parent__;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WinTCCplDeskWindow
|
||||||
|
{
|
||||||
|
GtkApplicationWindow __parent__;
|
||||||
|
|
||||||
|
// State
|
||||||
|
//
|
||||||
|
GSList* list_wallpapers;
|
||||||
|
WinTCCplDeskSettings* settings;
|
||||||
|
|
||||||
|
// UI
|
||||||
|
//
|
||||||
|
GtkWidget* monitor_desktop;
|
||||||
|
GtkWidget* listbox_wallpapers;
|
||||||
|
GtkWidget* notebook_main;
|
||||||
|
|
||||||
|
gboolean sync_settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK TYPE DEFINITION & CTORS
|
||||||
|
//
|
||||||
|
G_DEFINE_TYPE(
|
||||||
|
WinTCCplDeskWindow,
|
||||||
|
wintc_cpl_desk_window,
|
||||||
|
GTK_TYPE_APPLICATION_WINDOW
|
||||||
|
)
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_window_class_init(
|
||||||
|
WinTCCplDeskWindowClass* klass
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->finalize = wintc_cpl_desk_window_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_cpl_desk_window_init(
|
||||||
|
WinTCCplDeskWindow* self
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GtkBuilder* builder;
|
||||||
|
GtkWidget* main_box;
|
||||||
|
|
||||||
|
gtk_widget_set_size_request(
|
||||||
|
GTK_WIDGET(self),
|
||||||
|
414, // Approx.
|
||||||
|
454
|
||||||
|
);
|
||||||
|
gtk_window_set_default_size(
|
||||||
|
GTK_WINDOW(self),
|
||||||
|
414, // Approx.
|
||||||
|
454
|
||||||
|
);
|
||||||
|
gtk_window_set_icon_name(
|
||||||
|
GTK_WINDOW(self),
|
||||||
|
"preferences-desktop-display"
|
||||||
|
);
|
||||||
|
gtk_window_set_resizable(
|
||||||
|
GTK_WINDOW(self),
|
||||||
|
FALSE
|
||||||
|
);
|
||||||
|
gtk_window_set_skip_taskbar_hint(
|
||||||
|
GTK_WINDOW(self),
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
// Init settings
|
||||||
|
//
|
||||||
|
self->settings = wintc_cpl_desk_settings_new();
|
||||||
|
|
||||||
|
// Define GActions
|
||||||
|
//
|
||||||
|
g_action_map_add_action_entries(
|
||||||
|
G_ACTION_MAP(self),
|
||||||
|
s_window_actions,
|
||||||
|
G_N_ELEMENTS(s_window_actions),
|
||||||
|
self
|
||||||
|
);
|
||||||
|
|
||||||
|
g_object_bind_property(
|
||||||
|
self->settings,
|
||||||
|
"settings-changed",
|
||||||
|
g_action_map_lookup_action(
|
||||||
|
G_ACTION_MAP(self),
|
||||||
|
"apply"
|
||||||
|
),
|
||||||
|
"enabled",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize UI
|
||||||
|
//
|
||||||
|
g_type_ensure(WINTC_TYPE_DESK_MONITOR);
|
||||||
|
|
||||||
|
builder =
|
||||||
|
gtk_builder_new_from_resource(
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/desk.ui"
|
||||||
|
);
|
||||||
|
|
||||||
|
wintc_lc_builder_preprocess_widget_text(builder);
|
||||||
|
|
||||||
|
main_box = GTK_WIDGET(gtk_builder_get_object(builder, "main-box"));
|
||||||
|
|
||||||
|
gtk_container_add(GTK_CONTAINER(self), main_box);
|
||||||
|
|
||||||
|
// Pull out widgets
|
||||||
|
//
|
||||||
|
self->notebook_main = GTK_WIDGET(
|
||||||
|
gtk_builder_get_object(
|
||||||
|
builder,
|
||||||
|
"main-notebook"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_object_unref(G_OBJECT(builder));
|
||||||
|
|
||||||
|
// Init pages
|
||||||
|
//
|
||||||
|
wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GTK_NOTEBOOK(self->notebook_main),
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/page-themes.ui",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GTK_NOTEBOOK(self->notebook_main),
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/page-desktop.ui",
|
||||||
|
"listbox-wallpapers", &(self->listbox_wallpapers),
|
||||||
|
"monitor", &(self->monitor_desktop),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GTK_NOTEBOOK(self->notebook_main),
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/page-scrnsave.ui",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GTK_NOTEBOOK(self->notebook_main),
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/page-appearance.ui",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
|
GTK_NOTEBOOK(self->notebook_main),
|
||||||
|
"/uk/oddmatics/wintc/cpl-desk/page-settings.ui",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
// Attach signals
|
||||||
|
//
|
||||||
|
g_signal_connect(
|
||||||
|
self,
|
||||||
|
"map-event",
|
||||||
|
G_CALLBACK(on_window_map_event),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
g_signal_connect(
|
||||||
|
self->listbox_wallpapers,
|
||||||
|
"row-selected",
|
||||||
|
G_CALLBACK(on_listbox_wallpapers_row_selected),
|
||||||
|
self
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initial load stuff
|
||||||
|
//
|
||||||
|
refresh_wallpaper_list(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLASS VIRTUAL METHODS
|
||||||
|
//
|
||||||
|
static void wintc_cpl_desk_window_finalize(
|
||||||
|
GObject* object
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCCplDeskWindow* wnd = WINTC_CPL_DESK_WINDOW(object);
|
||||||
|
|
||||||
|
g_slist_free_full(wnd->list_wallpapers, g_free);
|
||||||
|
|
||||||
|
(G_OBJECT_CLASS(wintc_cpl_desk_window_parent_class))->finalize(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
GtkWidget* wintc_cpl_desk_window_new(
|
||||||
|
WinTCCplDeskApplication* app
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return GTK_WIDGET(
|
||||||
|
g_object_new(
|
||||||
|
WINTC_TYPE_CPL_DESK_WINDOW,
|
||||||
|
"application", GTK_APPLICATION(app),
|
||||||
|
"title", _("Display Properties"),
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static void add_wallpaper_to_list(
|
||||||
|
WinTCCplDeskWindow* wnd,
|
||||||
|
const gchar* path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gchar* filename = g_path_get_basename(path);
|
||||||
|
GtkWidget* label = gtk_label_new(filename);
|
||||||
|
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
|
||||||
|
|
||||||
|
gtk_list_box_insert(
|
||||||
|
GTK_LIST_BOX(wnd->listbox_wallpapers),
|
||||||
|
label,
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void refresh_wallpaper_list(
|
||||||
|
WinTCCplDeskWindow* wnd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
g_slist_free_full(wnd->list_wallpapers, g_free);
|
||||||
|
wintc_container_clear(GTK_CONTAINER(wnd->listbox_wallpapers));
|
||||||
|
|
||||||
|
// Load up wallpapers
|
||||||
|
//
|
||||||
|
GError* error = NULL;
|
||||||
|
GSList* iter = NULL;
|
||||||
|
|
||||||
|
wnd->list_wallpapers =
|
||||||
|
wintc_sh_fs_get_names_as_list(
|
||||||
|
WINTC_RT_PREFIX "/share/backgrounds",
|
||||||
|
TRUE,
|
||||||
|
G_FILE_TEST_IS_REGULAR,
|
||||||
|
TRUE,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!wnd->list_wallpapers)
|
||||||
|
{
|
||||||
|
wintc_nice_error_and_clear(&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = wnd->list_wallpapers;
|
||||||
|
|
||||||
|
while (iter)
|
||||||
|
{
|
||||||
|
add_wallpaper_to_list(wnd, (gchar*) iter->data);
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void select_wallpaper_from_list(
|
||||||
|
WinTCCplDeskWindow* wnd,
|
||||||
|
const gchar* path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gint i = 0;
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GSList* iter = wnd->list_wallpapers; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
if (g_strcmp0((gchar*) iter->data, path) == 0)
|
||||||
|
{
|
||||||
|
gtk_list_box_select_row(
|
||||||
|
GTK_LIST_BOX(wnd->listbox_wallpapers),
|
||||||
|
gtk_list_box_get_row_at_index(
|
||||||
|
GTK_LIST_BOX(wnd->listbox_wallpapers),
|
||||||
|
i
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The path isnt in the listbox, so add it and select last item
|
||||||
|
//
|
||||||
|
add_wallpaper_to_list(wnd, path);
|
||||||
|
|
||||||
|
gtk_list_box_select_row(
|
||||||
|
GTK_LIST_BOX(wnd->listbox_wallpapers),
|
||||||
|
gtk_list_box_get_row_at_index(
|
||||||
|
GTK_LIST_BOX(wnd->listbox_wallpapers),
|
||||||
|
g_slist_length(wnd->list_wallpapers) - 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLBACKS
|
||||||
|
//
|
||||||
|
static void action_apply(
|
||||||
|
WINTC_UNUSED(GSimpleAction* action),
|
||||||
|
WINTC_UNUSED(GVariant* parameter),
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCCplDeskWindow* wnd = WINTC_CPL_DESK_WINDOW(user_data);
|
||||||
|
|
||||||
|
GError* error = NULL;
|
||||||
|
|
||||||
|
if (!wintc_cpl_desk_settings_apply(wnd->settings, &error))
|
||||||
|
{
|
||||||
|
wintc_nice_error_and_clear(&error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void action_cancel(
|
||||||
|
WINTC_UNUSED(GSimpleAction* action),
|
||||||
|
WINTC_UNUSED(GVariant* parameter),
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gtk_window_close(GTK_WINDOW(user_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void action_ok(
|
||||||
|
WINTC_UNUSED(GSimpleAction* action),
|
||||||
|
WINTC_UNUSED(GVariant* parameter),
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GAction* action_apply =
|
||||||
|
g_action_map_lookup_action(
|
||||||
|
G_ACTION_MAP(user_data),
|
||||||
|
"apply"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Try applying settings...
|
||||||
|
//
|
||||||
|
g_action_activate(
|
||||||
|
action_apply,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
// ...we can assume it worked if the apply action is disabled
|
||||||
|
//
|
||||||
|
if (!g_action_get_enabled(action_apply))
|
||||||
|
{
|
||||||
|
gtk_window_close(GTK_WINDOW(user_data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_listbox_wallpapers_row_selected(
|
||||||
|
WINTC_UNUSED(GtkListBox* self),
|
||||||
|
GtkListBoxRow* row,
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCCplDeskWindow* wnd = WINTC_CPL_DESK_WINDOW(user_data);
|
||||||
|
|
||||||
|
GError* error = NULL;
|
||||||
|
GdkPixbuf* pixbuf_wallpaper;
|
||||||
|
const gchar* wallpaper_path;
|
||||||
|
|
||||||
|
wallpaper_path =
|
||||||
|
g_slist_nth_data(
|
||||||
|
wnd->list_wallpapers,
|
||||||
|
gtk_list_box_row_get_index(row)
|
||||||
|
);
|
||||||
|
|
||||||
|
pixbuf_wallpaper =
|
||||||
|
gdk_pixbuf_new_from_file(
|
||||||
|
wallpaper_path,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!pixbuf_wallpaper)
|
||||||
|
{
|
||||||
|
wintc_nice_error_and_clear(&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wintc_desk_monitor_set_pixbuf(
|
||||||
|
WINTC_DESK_MONITOR(wnd->monitor_desktop),
|
||||||
|
pixbuf_wallpaper
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!wnd->sync_settings)
|
||||||
|
{
|
||||||
|
wintc_cpl_desk_settings_set_wallpaper(
|
||||||
|
wnd->settings,
|
||||||
|
wallpaper_path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(pixbuf_wallpaper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_window_map_event(
|
||||||
|
GtkWidget* self,
|
||||||
|
WINTC_UNUSED(GdkEventAny* event),
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCCplDeskWindow* wnd = WINTC_CPL_DESK_WINDOW(self);
|
||||||
|
|
||||||
|
GError* error = NULL;
|
||||||
|
|
||||||
|
if (!wintc_cpl_desk_settings_load(wnd->settings, &error))
|
||||||
|
{
|
||||||
|
wintc_nice_error_and_clear(&error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wnd->sync_settings = TRUE;
|
||||||
|
|
||||||
|
select_wallpaper_from_list(
|
||||||
|
wnd,
|
||||||
|
wintc_cpl_desk_settings_get_wallpaper(wnd->settings)
|
||||||
|
);
|
||||||
|
|
||||||
|
wnd->sync_settings = FALSE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
31
shell/cpl/desk/src/window.h
Normal file
31
shell/cpl/desk/src/window.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef __WINDOW_H__
|
||||||
|
#define __WINDOW_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP BOILERPLATE
|
||||||
|
//
|
||||||
|
typedef struct _WinTCCplDeskWindowClass WinTCCplDeskWindowClass;
|
||||||
|
typedef struct _WinTCCplDeskWindow WinTCCplDeskWindow;
|
||||||
|
|
||||||
|
#define WINTC_TYPE_CPL_DESK_WINDOW (wintc_cpl_desk_window_get_type())
|
||||||
|
#define WINTC_CPL_DESK_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_CPL_DESK_WINDOW, WinTCCplDeskWindow))
|
||||||
|
#define WINTC_CPL_DESK_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_CPL_DESK_WINDOW, WinTCCplDeskWindowClass))
|
||||||
|
#define IS_WINTC_CPL_DESK_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_CPL_DESK_WINDOW))
|
||||||
|
#define IS_WINTC_CPL_DESK_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_CPL_DESK_WINDOW))
|
||||||
|
#define WINTC_CPL_DESK_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_CPL_DESK_WINDOW, WinTCCplDeskWindowClass))
|
||||||
|
|
||||||
|
GType wintc_cpl_desk_window_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
GtkWidget* wintc_cpl_desk_window_new(
|
||||||
|
WinTCCplDeskApplication* app
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
10
shell/cpl/desk/uk.co.oddmatics.wintc.cpl-desk.desktop
Normal file
10
shell/cpl/desk/uk.co.oddmatics.wintc.cpl-desk.desktop
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=Display
|
||||||
|
Comment=Change the appearance of your desktop, such as the background, screen saver, colors, font sizes, and screen resolution.
|
||||||
|
Exec=desk.cpl
|
||||||
|
Icon=preferences-desktop-display
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Settings;GTK;
|
||||||
|
OnlyShowIn=WINTC;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <wintc/comctl.h>
|
||||||
#include <wintc/comgtk.h>
|
#include <wintc/comgtk.h>
|
||||||
#include <wintc/shlang.h>
|
#include <wintc/shlang.h>
|
||||||
|
|
||||||
@@ -10,11 +11,6 @@
|
|||||||
//
|
//
|
||||||
// FORWARD DECLARATIONS
|
// FORWARD DECLARATIONS
|
||||||
//
|
//
|
||||||
static void add_sysdm_page(
|
|
||||||
GtkNotebook* notebook_main,
|
|
||||||
gchar* resource_path
|
|
||||||
);
|
|
||||||
|
|
||||||
static void action_close(
|
static void action_close(
|
||||||
GSimpleAction* action,
|
GSimpleAction* action,
|
||||||
GVariant* parameter,
|
GVariant* parameter,
|
||||||
@@ -117,9 +113,10 @@ static void wintc_cpl_sysdm_window_init(
|
|||||||
|
|
||||||
// Init pages
|
// Init pages
|
||||||
//
|
//
|
||||||
add_sysdm_page(
|
wintc_ctl_cpl_notebook_append_page_from_resource(
|
||||||
GTK_NOTEBOOK(self->notebook_main),
|
GTK_NOTEBOOK(self->notebook_main),
|
||||||
"/uk/oddmatics/wintc/cpl-sysdm/page-gen.ui"
|
"/uk/oddmatics/wintc/cpl-sysdm/page-gen.ui",
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,34 +137,6 @@ GtkWidget* wintc_cpl_sysdm_window_new(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// PRIVATE FUNCTIONS
|
|
||||||
//
|
|
||||||
static void add_sysdm_page(
|
|
||||||
GtkNotebook* notebook_main,
|
|
||||||
gchar* resource_path
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GtkBuilder* builder;
|
|
||||||
GtkWidget* box_page;
|
|
||||||
GtkWidget* label_title;
|
|
||||||
|
|
||||||
builder = gtk_builder_new_from_resource(resource_path);
|
|
||||||
|
|
||||||
wintc_lc_builder_preprocess_widget_text(builder);
|
|
||||||
|
|
||||||
box_page = GTK_WIDGET(gtk_builder_get_object(builder, "page-box"));
|
|
||||||
label_title = GTK_WIDGET(gtk_builder_get_object(builder, "label-title"));
|
|
||||||
|
|
||||||
gtk_notebook_append_page(
|
|
||||||
notebook_main,
|
|
||||||
box_page,
|
|
||||||
label_title
|
|
||||||
);
|
|
||||||
|
|
||||||
g_object_unref(G_OBJECT(builder));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// CALLBACKS
|
// CALLBACKS
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
|||||||
wintc_resolve_library(glib-2.0 GLIB)
|
wintc_resolve_library(glib-2.0 GLIB)
|
||||||
wintc_resolve_library(gtk+-3.0 GTK3)
|
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||||
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||||
|
wintc_resolve_library(wintc-registry WINTC_REGISTRY)
|
||||||
wintc_resolve_library(wintc-shelldpa WINTC_SHELLDPA)
|
wintc_resolve_library(wintc-shelldpa WINTC_SHELLDPA)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
@@ -29,6 +30,8 @@ add_executable(
|
|||||||
src/application.c
|
src/application.c
|
||||||
src/application.h
|
src/application.h
|
||||||
src/main.c
|
src/main.c
|
||||||
|
src/settings.c
|
||||||
|
src/settings.h
|
||||||
src/window.c
|
src/window.c
|
||||||
src/window.h
|
src/window.h
|
||||||
)
|
)
|
||||||
@@ -45,6 +48,7 @@ target_include_directories(
|
|||||||
PRIVATE ${GLIB_INCLUDE_DIRS}
|
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||||
PRIVATE ${GTK3_INCLUDE_DIRS}
|
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||||
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_INCLUDE_DIRS}
|
||||||
PRIVATE ${WINTC_SHELLDPA_INCLUDE_DIRS}
|
PRIVATE ${WINTC_SHELLDPA_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,6 +57,7 @@ target_link_directories(
|
|||||||
PRIVATE ${GLIB_LIBRARY_DIRS}
|
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||||
PRIVATE ${GTK3_LIBRARY_DIRS}
|
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||||
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_LIBRARY_DIRS}
|
||||||
PRIVATE ${WINTC_SHELLDPA_LIBRARY_DIRS}
|
PRIVATE ${WINTC_SHELLDPA_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,6 +66,7 @@ target_link_libraries(
|
|||||||
PRIVATE ${GLIB_LIBRARIES}
|
PRIVATE ${GLIB_LIBRARIES}
|
||||||
PRIVATE ${GTK3_LIBRARIES}
|
PRIVATE ${GTK3_LIBRARIES}
|
||||||
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||||
|
PRIVATE ${WINTC_REGISTRY_LIBRARIES}
|
||||||
PRIVATE ${WINTC_SHELLDPA_LIBRARIES}
|
PRIVATE ${WINTC_SHELLDPA_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
bt,rt:glib2
|
bt,rt:glib2
|
||||||
bt,rt:gtk3
|
bt,rt:gtk3
|
||||||
bt,rt:wintc-comgtk
|
bt,rt:wintc-comgtk
|
||||||
|
bt,rt:wintc-registry
|
||||||
bt,rt:wintc-shelldpa
|
bt,rt:wintc-shelldpa
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <wintc/shelldpa.h>
|
#include <wintc/shelldpa.h>
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -17,6 +18,8 @@ struct _WinTCDesktopApplicationClass
|
|||||||
struct _WinTCDesktopApplication
|
struct _WinTCDesktopApplication
|
||||||
{
|
{
|
||||||
GtkApplication __parent__;
|
GtkApplication __parent__;
|
||||||
|
|
||||||
|
WinTCDesktopSettings* settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -49,8 +52,11 @@ static void wintc_desktop_application_class_init(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void wintc_desktop_application_init(
|
static void wintc_desktop_application_init(
|
||||||
WINTC_UNUSED(WinTCDesktopApplication* self)
|
WinTCDesktopApplication* self
|
||||||
) {}
|
)
|
||||||
|
{
|
||||||
|
self->settings = wintc_desktop_settings_new();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// PUBLIC FUNCTIONS
|
// PUBLIC FUNCTIONS
|
||||||
@@ -97,7 +103,11 @@ static void wintc_desktop_application_activate(
|
|||||||
for (int i = 0; i < n_monitors; i++)
|
for (int i = 0; i < n_monitors; i++)
|
||||||
{
|
{
|
||||||
GdkMonitor* monitor = gdk_display_get_monitor(display, i);
|
GdkMonitor* monitor = gdk_display_get_monitor(display, i);
|
||||||
GtkWidget* wnd = wintc_desktop_window_new(desktop_app, monitor);
|
GtkWidget* wnd = wintc_desktop_window_new(
|
||||||
|
desktop_app,
|
||||||
|
monitor,
|
||||||
|
desktop_app->settings
|
||||||
|
);
|
||||||
|
|
||||||
gtk_widget_show_all(wnd);
|
gtk_widget_show_all(wnd);
|
||||||
}
|
}
|
||||||
|
|||||||
283
shell/desktop/src/settings.c
Normal file
283
shell/desktop/src/settings.c
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <wintc/comgtk.h>
|
||||||
|
#include <wintc/registry.h>
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE ENUMS
|
||||||
|
//
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_PIXBUF_WALLPAPER = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||||
|
//
|
||||||
|
struct _WinTCDesktopSettingsClass
|
||||||
|
{
|
||||||
|
GObjectClass __parent__;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WinTCDesktopSettings
|
||||||
|
{
|
||||||
|
GObject __parent__;
|
||||||
|
|
||||||
|
// State
|
||||||
|
//
|
||||||
|
WinTCRegistry* registry;
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
//
|
||||||
|
GdkPixbuf* pixbuf_wallpaper;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// FORWARD DECLARATIONS
|
||||||
|
//
|
||||||
|
static void wintc_desktop_settings_dispose(
|
||||||
|
GObject* object
|
||||||
|
);
|
||||||
|
static void wintc_desktop_settings_get_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
);
|
||||||
|
static void wintc_desktop_settings_set_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
);
|
||||||
|
|
||||||
|
static void wintc_desktop_settings_set_wallpaper_path(
|
||||||
|
WinTCDesktopSettings* settings,
|
||||||
|
const gchar* wallpaper_path
|
||||||
|
);
|
||||||
|
|
||||||
|
static void regkey_changed_desktop_cb(
|
||||||
|
WinTCRegistry* registry,
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_variant,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK TYPE DEFINITIONS & CTORS
|
||||||
|
//
|
||||||
|
G_DEFINE_TYPE(
|
||||||
|
WinTCDesktopSettings,
|
||||||
|
wintc_desktop_settings,
|
||||||
|
G_TYPE_OBJECT
|
||||||
|
)
|
||||||
|
|
||||||
|
static void wintc_desktop_settings_class_init(
|
||||||
|
WinTCDesktopSettingsClass* klass
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->dispose = wintc_desktop_settings_dispose;
|
||||||
|
object_class->get_property = wintc_desktop_settings_get_property;
|
||||||
|
object_class->set_property = wintc_desktop_settings_set_property;
|
||||||
|
|
||||||
|
g_object_class_install_property(
|
||||||
|
object_class,
|
||||||
|
PROP_PIXBUF_WALLPAPER,
|
||||||
|
g_param_spec_object(
|
||||||
|
"pixbuf-wallpaper",
|
||||||
|
"PixbufWallpaper",
|
||||||
|
"The pixbuf that should be used as the desktop wallpaper.",
|
||||||
|
GDK_TYPE_PIXBUF,
|
||||||
|
G_PARAM_READWRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desktop_settings_init(
|
||||||
|
WinTCDesktopSettings* self
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
|
||||||
|
// Initial registry set up
|
||||||
|
//
|
||||||
|
self->registry = wintc_registry_new();
|
||||||
|
|
||||||
|
if (
|
||||||
|
!wintc_registry_create_key(
|
||||||
|
self->registry,
|
||||||
|
"HKCU\\Control Panel\\Desktop",
|
||||||
|
&error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get some stuff from registry for startup
|
||||||
|
//
|
||||||
|
gchar* sz_wallpaper = NULL;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!wintc_registry_get_key_value(
|
||||||
|
self->registry,
|
||||||
|
"HKCU\\Control Panel\\Desktop",
|
||||||
|
"Wallpaper",
|
||||||
|
WINTC_REG_SZ,
|
||||||
|
&sz_wallpaper,
|
||||||
|
&error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sz_wallpaper)
|
||||||
|
{
|
||||||
|
wintc_desktop_settings_set_wallpaper_path(self, sz_wallpaper);
|
||||||
|
g_free(sz_wallpaper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up watcher
|
||||||
|
//
|
||||||
|
wintc_registry_watch_key(
|
||||||
|
self->registry,
|
||||||
|
"HKCU\\Control Panel\\Desktop",
|
||||||
|
regkey_changed_desktop_cb,
|
||||||
|
self
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLASS VIRTUAL METHODS
|
||||||
|
//
|
||||||
|
static void wintc_desktop_settings_dispose(
|
||||||
|
GObject* object
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDesktopSettings* settings = WINTC_DESKTOP_SETTINGS(object);
|
||||||
|
|
||||||
|
g_clear_object(&(settings->pixbuf_wallpaper));
|
||||||
|
|
||||||
|
(G_OBJECT_CLASS(wintc_desktop_settings_parent_class))->dispose(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desktop_settings_get_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDesktopSettings* settings = WINTC_DESKTOP_SETTINGS(object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_PIXBUF_WALLPAPER:
|
||||||
|
g_value_set_object(value, settings->pixbuf_wallpaper);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desktop_settings_set_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDesktopSettings* settings = WINTC_DESKTOP_SETTINGS(object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_PIXBUF_WALLPAPER:
|
||||||
|
g_clear_object(&(settings->pixbuf_wallpaper));
|
||||||
|
settings->pixbuf_wallpaper = g_value_dup_object(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCDesktopSettings* wintc_desktop_settings_new(void)
|
||||||
|
{
|
||||||
|
return g_object_new(WINTC_TYPE_DESKTOP_SETTINGS, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static void wintc_desktop_settings_set_wallpaper_path(
|
||||||
|
WinTCDesktopSettings* settings,
|
||||||
|
const gchar* wallpaper_path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GError* error = NULL;
|
||||||
|
GdkPixbuf* pixbuf_wallpaper;
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("desktop: setting wallpaper to %s", wallpaper_path);
|
||||||
|
|
||||||
|
pixbuf_wallpaper =
|
||||||
|
gdk_pixbuf_new_from_file(
|
||||||
|
wallpaper_path,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!pixbuf_wallpaper)
|
||||||
|
{
|
||||||
|
wintc_log_error_and_clear(&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set(
|
||||||
|
settings,
|
||||||
|
"pixbuf-wallpaper", pixbuf_wallpaper,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
g_object_unref(pixbuf_wallpaper);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLBACK
|
||||||
|
//
|
||||||
|
static void regkey_changed_desktop_cb(
|
||||||
|
WINTC_UNUSED(WinTCRegistry* registry),
|
||||||
|
const gchar* key_path,
|
||||||
|
const gchar* value_name,
|
||||||
|
GVariant* value_variant,
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDesktopSettings* settings = WINTC_DESKTOP_SETTINGS(user_data);
|
||||||
|
|
||||||
|
WINTC_LOG_DEBUG("desktop: saw key changed %s->%s", key_path, value_name);
|
||||||
|
|
||||||
|
if (g_strcmp0(value_name, "Wallpaper") == 0)
|
||||||
|
{
|
||||||
|
if (wintc_registry_get_type_for_variant(value_variant) != WINTC_REG_SZ)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("%s", "desktop: wallpaper setting is not REG_SZ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wintc_desktop_settings_set_wallpaper_path(
|
||||||
|
settings,
|
||||||
|
g_variant_get_string(value_variant, NULL)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
shell/desktop/src/settings.h
Normal file
26
shell/desktop/src/settings.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef __SETTINGS_H__
|
||||||
|
#define __SETTINGS_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// GTK OOP BOILERPLATE
|
||||||
|
//
|
||||||
|
typedef struct _WinTCDesktopSettingsClass WinTCDesktopSettingsClass;
|
||||||
|
typedef struct _WinTCDesktopSettings WinTCDesktopSettings;
|
||||||
|
|
||||||
|
#define WINTC_TYPE_DESKTOP_SETTINGS (wintc_desktop_settings_get_type())
|
||||||
|
#define WINTC_DESKTOP_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_DESKTOP_SETTINGS, WinTCDesktopSettings))
|
||||||
|
#define WINTC_DESKTOP_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_DESKTOP_SETTINGS, WinTCDesktopSettingsClass))
|
||||||
|
#define IS_WINTC_DESKTOP_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_DESKTOP_SETTINGS))
|
||||||
|
#define IS_WINTC_DESKTOP_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_DESKTOP_SETTINGS))
|
||||||
|
#define WINTC_DESKTOP_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_DESKTOP_SETTINGS, WinTCDesktopSettingsClass))
|
||||||
|
|
||||||
|
GType wintc_desktop_settings_get_type(void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC FUNCTIONS
|
||||||
|
//
|
||||||
|
WinTCDesktopSettings* wintc_desktop_settings_new(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,12 +1,22 @@
|
|||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <wintc/comgtk.h>
|
#include <wintc/comgtk.h>
|
||||||
#include <wintc/shelldpa.h>
|
#include <wintc/shelldpa.h>
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE ENUMS
|
||||||
|
//
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_SETTINGS = 1
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||||
//
|
//
|
||||||
@@ -18,16 +28,51 @@ struct _WinTCDesktopWindowClass
|
|||||||
struct _WinTCDesktopWindow
|
struct _WinTCDesktopWindow
|
||||||
{
|
{
|
||||||
WinTCDpaDesktopWindow __parent__;
|
WinTCDpaDesktopWindow __parent__;
|
||||||
|
|
||||||
|
// Drawing-related
|
||||||
|
//
|
||||||
|
GdkPixbuf* pixbuf_wallpaper;
|
||||||
|
cairo_surface_t* surface_wallpaper;
|
||||||
|
|
||||||
|
// State
|
||||||
|
//
|
||||||
|
WinTCDesktopSettings* settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// FORWARD DECLARATION
|
// FORWARD DECLARATIONS
|
||||||
//
|
//
|
||||||
|
static void wintc_desktop_window_dispose(
|
||||||
|
GObject* object
|
||||||
|
);
|
||||||
|
static void wintc_desktop_window_set_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
);
|
||||||
|
|
||||||
static gboolean wintc_desktop_window_draw(
|
static gboolean wintc_desktop_window_draw(
|
||||||
GtkWidget* widget,
|
GtkWidget* widget,
|
||||||
cairo_t* cr
|
cairo_t* cr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static void wintc_desktop_window_update_wallpaper(
|
||||||
|
WinTCDesktopWindow* wnd
|
||||||
|
);
|
||||||
|
|
||||||
|
static gboolean on_window_map_event(
|
||||||
|
GtkWidget* self,
|
||||||
|
GdkEventAny* event,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
static void on_settings_notify_pixbuf_wallpaper(
|
||||||
|
GObject* self,
|
||||||
|
GParamSpec* pspec,
|
||||||
|
gpointer user_data
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// GTK TYPE DEFINITION & CTORS
|
// GTK TYPE DEFINITION & CTORS
|
||||||
//
|
//
|
||||||
@@ -41,28 +86,175 @@ static void wintc_desktop_window_class_init(
|
|||||||
WinTCDesktopWindowClass* klass
|
WinTCDesktopWindowClass* klass
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
|
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->dispose = wintc_desktop_window_dispose;
|
||||||
|
object_class->set_property = wintc_desktop_window_set_property;
|
||||||
|
|
||||||
widget_class->draw = wintc_desktop_window_draw;
|
widget_class->draw = wintc_desktop_window_draw;
|
||||||
|
|
||||||
|
g_object_class_install_property(
|
||||||
|
object_class,
|
||||||
|
PROP_SETTINGS,
|
||||||
|
g_param_spec_object(
|
||||||
|
"settings",
|
||||||
|
"Settings",
|
||||||
|
"The shared desktop settings",
|
||||||
|
WINTC_TYPE_DESKTOP_SETTINGS,
|
||||||
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wintc_desktop_window_init(
|
static void wintc_desktop_window_init(
|
||||||
WINTC_UNUSED(WinTCDesktopWindow* self)
|
WinTCDesktopWindow* self
|
||||||
) {}
|
)
|
||||||
|
{
|
||||||
|
g_signal_connect(
|
||||||
|
self,
|
||||||
|
"map-event",
|
||||||
|
G_CALLBACK(on_window_map_event),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// CLASS VIRTUAL METHODS
|
// CLASS VIRTUAL METHODS
|
||||||
//
|
//
|
||||||
static gboolean wintc_desktop_window_draw(
|
static void wintc_desktop_window_dispose(
|
||||||
WINTC_UNUSED(GtkWidget* widget),
|
GObject* object
|
||||||
cairo_t* cr
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(object);
|
||||||
|
|
||||||
|
if (wnd->surface_wallpaper)
|
||||||
|
{
|
||||||
|
cairo_surface_destroy(g_steal_pointer(&(wnd->surface_wallpaper)));
|
||||||
|
g_clear_object(&(wnd->pixbuf_wallpaper));
|
||||||
|
}
|
||||||
|
|
||||||
|
(G_OBJECT_CLASS(wintc_desktop_window_parent_class))->dispose(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wintc_desktop_window_set_property(
|
||||||
|
GObject* object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue* value,
|
||||||
|
GParamSpec* pspec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SETTINGS:
|
||||||
|
wnd->settings = g_value_get_object(value);
|
||||||
|
|
||||||
|
g_signal_connect(
|
||||||
|
wnd->settings,
|
||||||
|
"notify::pixbuf-wallpaper",
|
||||||
|
G_CALLBACK(on_settings_notify_pixbuf_wallpaper),
|
||||||
|
wnd
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean wintc_desktop_window_draw(
|
||||||
|
GtkWidget* widget,
|
||||||
|
cairo_t* cr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WinTCDpaDesktopWindow* dpa_wnd = WINTC_DPA_DESKTOP_WINDOW(widget);
|
||||||
|
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(widget);
|
||||||
|
|
||||||
// FIXME: Just drawing default desktop background colour atm
|
// FIXME: Just drawing default desktop background colour atm
|
||||||
//
|
//
|
||||||
cairo_set_source_rgb(cr, 0.0f, 0.298f, 0.596f);
|
cairo_set_source_rgb(cr, 0.0f, 0.298f, 0.596f);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
// FIXME: Billy basic drawing of the wallpaper, if present
|
||||||
|
//
|
||||||
|
if (wnd->surface_wallpaper)
|
||||||
|
{
|
||||||
|
cairo_set_source_surface(cr, wnd->surface_wallpaper, 0.0f, 0.0f);
|
||||||
|
cairo_paint(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rough watermark drawing
|
||||||
|
//
|
||||||
|
if (gdk_monitor_is_primary(dpa_wnd->monitor))
|
||||||
|
{
|
||||||
|
static gchar* s_tag = NULL;
|
||||||
|
|
||||||
|
cairo_text_extents_t extents;
|
||||||
|
gdouble y;
|
||||||
|
|
||||||
|
gint height = gtk_widget_get_allocated_height(widget);
|
||||||
|
gint width = gtk_widget_get_allocated_width(widget);
|
||||||
|
|
||||||
|
if (!s_tag)
|
||||||
|
{
|
||||||
|
gchar* tag = wintc_build_get_tag();
|
||||||
|
|
||||||
|
s_tag =
|
||||||
|
g_strdup_printf("For testing purposes only. Build %s", tag);
|
||||||
|
|
||||||
|
g_free(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to white, IDK if Windows changes this...
|
||||||
|
//
|
||||||
|
cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
// Handle build string first...
|
||||||
|
//
|
||||||
|
cairo_select_font_face(
|
||||||
|
cr,
|
||||||
|
"sans-serif",
|
||||||
|
CAIRO_FONT_SLANT_NORMAL,
|
||||||
|
CAIRO_FONT_WEIGHT_NORMAL
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_text_extents(cr, s_tag, &extents);
|
||||||
|
|
||||||
|
cairo_move_to(
|
||||||
|
cr,
|
||||||
|
width - extents.width - 10,
|
||||||
|
height - extents.height - 34 // FIXME: Hardcoded taskband height
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_show_text(cr, s_tag);
|
||||||
|
|
||||||
|
// ...and the product name
|
||||||
|
// FIXME: Hard coded temp name in here until we have a name
|
||||||
|
//
|
||||||
|
cairo_select_font_face(
|
||||||
|
cr,
|
||||||
|
"sans-serif",
|
||||||
|
CAIRO_FONT_SLANT_NORMAL,
|
||||||
|
CAIRO_FONT_WEIGHT_BOLD
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_text_extents(cr, "Windows 'Total Conversion'", &extents);
|
||||||
|
|
||||||
|
cairo_get_current_point(cr, NULL, &y);
|
||||||
|
|
||||||
|
cairo_move_to(
|
||||||
|
cr,
|
||||||
|
width - extents.width - 10,
|
||||||
|
y - extents.height - 4
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_show_text(cr, "Windows 'Total Conversion'");
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +263,8 @@ static gboolean wintc_desktop_window_draw(
|
|||||||
//
|
//
|
||||||
GtkWidget* wintc_desktop_window_new(
|
GtkWidget* wintc_desktop_window_new(
|
||||||
WinTCDesktopApplication* app,
|
WinTCDesktopApplication* app,
|
||||||
GdkMonitor* monitor
|
GdkMonitor* monitor,
|
||||||
|
WinTCDesktopSettings* settings
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return GTK_WIDGET(
|
return GTK_WIDGET(
|
||||||
@@ -82,7 +275,69 @@ GtkWidget* wintc_desktop_window_new(
|
|||||||
"decorated", TRUE,
|
"decorated", TRUE,
|
||||||
"monitor", monitor,
|
"monitor", monitor,
|
||||||
"resizable", FALSE,
|
"resizable", FALSE,
|
||||||
|
"settings", settings,
|
||||||
NULL
|
NULL
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
//
|
||||||
|
static void wintc_desktop_window_update_wallpaper(
|
||||||
|
WinTCDesktopWindow* wnd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WINTC_LOG_DEBUG("%s", "desktop: window updating wallpaper");
|
||||||
|
|
||||||
|
if (wnd->surface_wallpaper)
|
||||||
|
{
|
||||||
|
cairo_surface_destroy(g_steal_pointer(&(wnd->surface_wallpaper)));
|
||||||
|
g_clear_object(&(wnd->pixbuf_wallpaper));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get(
|
||||||
|
wnd->settings,
|
||||||
|
"pixbuf-wallpaper", &(wnd->pixbuf_wallpaper),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (wnd->pixbuf_wallpaper)
|
||||||
|
{
|
||||||
|
wnd->surface_wallpaper =
|
||||||
|
gdk_cairo_surface_create_from_pixbuf(
|
||||||
|
wnd->pixbuf_wallpaper,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_widget_queue_draw(GTK_WIDGET(wnd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLBACKS
|
||||||
|
//
|
||||||
|
static gboolean on_window_map_event(
|
||||||
|
GtkWidget* self,
|
||||||
|
WINTC_UNUSED(GdkEventAny* event),
|
||||||
|
WINTC_UNUSED(gpointer user_data)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_desktop_window_update_wallpaper(
|
||||||
|
WINTC_DESKTOP_WINDOW(self)
|
||||||
|
);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_settings_notify_pixbuf_wallpaper(
|
||||||
|
WINTC_UNUSED(GObject* self),
|
||||||
|
WINTC_UNUSED(GParamSpec* pspec),
|
||||||
|
gpointer user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wintc_desktop_window_update_wallpaper(
|
||||||
|
WINTC_DESKTOP_WINDOW(user_data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// GTK OOP BOILERPLATE
|
// GTK OOP BOILERPLATE
|
||||||
@@ -26,7 +27,8 @@ GType wintc_desktop_window_get_type(void) G_GNUC_CONST;
|
|||||||
//
|
//
|
||||||
GtkWidget* wintc_desktop_window_new(
|
GtkWidget* wintc_desktop_window_new(
|
||||||
WinTCDesktopApplication* app,
|
WinTCDesktopApplication* app,
|
||||||
GdkMonitor* monitor
|
GdkMonitor* monitor,
|
||||||
|
WinTCDesktopSettings* settings
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,13 +14,17 @@ msgfmt-->bt,rt-->gettext
|
|||||||
plymouth-->bt,rt-->plymouth
|
plymouth-->bt,rt-->plymouth
|
||||||
pulseaudio-->bt-->pulseaudio-dev
|
pulseaudio-->bt-->pulseaudio-dev
|
||||||
pulseaudio-->rt-->libpulse
|
pulseaudio-->rt-->libpulse
|
||||||
|
python3-packaging-->bt,rt-->py3-packaging
|
||||||
python3-venv-->bt,rt-->py3-virtualenv
|
python3-venv-->bt,rt-->py3-virtualenv
|
||||||
sass-->bt,rt-->sassc
|
sass-->bt,rt-->sassc
|
||||||
|
sqlite3-->bt-->sqlite-dev
|
||||||
|
sqlite3-->rt-->sqlite
|
||||||
sysinfo-->bt,rt-->NULL
|
sysinfo-->bt,rt-->NULL
|
||||||
wintc-comctl-->bt,rt-->libwintc-comctl
|
wintc-comctl-->bt,rt-->libwintc-comctl
|
||||||
wintc-comgtk-->bt,rt-->libwintc-comgtk
|
wintc-comgtk-->bt,rt-->libwintc-comgtk
|
||||||
wintc-exec-->bt,rt-->libwintc-exec
|
wintc-exec-->bt,rt-->libwintc-exec
|
||||||
wintc-msgina-->bt,rt-->libwintc-msgina
|
wintc-msgina-->bt,rt-->libwintc-msgina
|
||||||
|
wintc-registry-->bt,rt-->libwintc-registry
|
||||||
wintc-shcommon-->bt,rt-->libwintc-shcommon
|
wintc-shcommon-->bt,rt-->libwintc-shcommon
|
||||||
wintc-shell-->bt,rt-->libwintc-shell
|
wintc-shell-->bt,rt-->libwintc-shell
|
||||||
wintc-shelldpa-->bt,rt-->libwintc-shelldpa
|
wintc-shelldpa-->bt,rt-->libwintc-shelldpa
|
||||||
|
|||||||
@@ -7,13 +7,16 @@ lightdm-->bt,rt-->lightdm
|
|||||||
msgfmt-->bt,rt-->gettext
|
msgfmt-->bt,rt-->gettext
|
||||||
plymouth-->bt,rt-->plymouth
|
plymouth-->bt,rt-->plymouth
|
||||||
pulseaudio-->bt,rt-->libpulse
|
pulseaudio-->bt,rt-->libpulse
|
||||||
|
python3-packaging-->bt,rt-->python-packaging
|
||||||
python3-venv-->bt,rt-->python3
|
python3-venv-->bt,rt-->python3
|
||||||
sass-->bt,rt-->ruby-sass
|
sass-->bt,rt-->ruby-sass
|
||||||
|
sqlite3-->bt,rt-->sqlite
|
||||||
sysinfo-->bt,rt-->NULL
|
sysinfo-->bt,rt-->NULL
|
||||||
wintc-comctl-->bt,rt-->wintc-comctl
|
wintc-comctl-->bt,rt-->wintc-comctl
|
||||||
wintc-comgtk-->bt,rt-->wintc-comgtk
|
wintc-comgtk-->bt,rt-->wintc-comgtk
|
||||||
wintc-exec-->bt,rt-->wintc-exec
|
wintc-exec-->bt,rt-->wintc-exec
|
||||||
wintc-msgina-->bt,rt-->wintc-msgina
|
wintc-msgina-->bt,rt-->wintc-msgina
|
||||||
|
wintc-registry-->bt,rt-->wintc-registry
|
||||||
wintc-shcommon-->bt,rt-->wintc-shcommon
|
wintc-shcommon-->bt,rt-->wintc-shcommon
|
||||||
wintc-shell-->bt,rt-->wintc-shell
|
wintc-shell-->bt,rt-->wintc-shell
|
||||||
wintc-shelldpa-->bt,rt-->wintc-shelldpa
|
wintc-shelldpa-->bt,rt-->wintc-shelldpa
|
||||||
|
|||||||
@@ -7,13 +7,16 @@ lightdm-->bt,rt-->lightdm
|
|||||||
msgfmt-->bt,rt-->gettext
|
msgfmt-->bt,rt-->gettext
|
||||||
plymouth-->bt,rt-->splash
|
plymouth-->bt,rt-->splash
|
||||||
pulseaudio-->bt,rt-->pulseaudio
|
pulseaudio-->bt,rt-->pulseaudio
|
||||||
|
python3-packaging-->bt,rt-->py39-packaging
|
||||||
python3-venv-->bt,rt-->py39-virtualenv
|
python3-venv-->bt,rt-->py39-virtualenv
|
||||||
sass-->bt,rt-->rubygem-sass
|
sass-->bt,rt-->rubygem-sass
|
||||||
|
sqlite3-->bt,rt-->sqlite3
|
||||||
sysinfo-->bt,rt-->libsysinfo
|
sysinfo-->bt,rt-->libsysinfo
|
||||||
wintc-comctl-->bt,rt-->wintc-comctl
|
wintc-comctl-->bt,rt-->wintc-comctl
|
||||||
wintc-comgtk-->bt,rt-->wintc-comgtk
|
wintc-comgtk-->bt,rt-->wintc-comgtk
|
||||||
wintc-exec-->bt,rt-->wintc-exec
|
wintc-exec-->bt,rt-->wintc-exec
|
||||||
wintc-msgina-->bt,rt-->wintc-msgina
|
wintc-msgina-->bt,rt-->wintc-msgina
|
||||||
|
wintc-registry-->bt,rt-->wintc-registry
|
||||||
wintc-shcommon-->bt,rt-->wintc-shcommon
|
wintc-shcommon-->bt,rt-->wintc-shcommon
|
||||||
wintc-shell-->bt,rt-->wintc-shell
|
wintc-shell-->bt,rt-->wintc-shell
|
||||||
wintc-shelldpa-->bt,rt-->wintc-shelldpa
|
wintc-shelldpa-->bt,rt-->wintc-shelldpa
|
||||||
|
|||||||
@@ -14,13 +14,17 @@ msgfmt-->bt,rt-->gettext
|
|||||||
plymouth-->bt,rt-->plymouth
|
plymouth-->bt,rt-->plymouth
|
||||||
pulseaudio-->bt-->libpulse-dev
|
pulseaudio-->bt-->libpulse-dev
|
||||||
pulseaudio-->rt-->libpulse0
|
pulseaudio-->rt-->libpulse0
|
||||||
|
python3-packaging-->bt,rt-->python3-packaging
|
||||||
python3-venv-->bt,rt-->python3-venv
|
python3-venv-->bt,rt-->python3-venv
|
||||||
sass-->bt,rt-->ruby-sass
|
sass-->bt,rt-->ruby-sass
|
||||||
|
sqlite3-->bt-->libsqlite3-dev
|
||||||
|
sqlite3-->rt-->libsqlite3-0
|
||||||
sysinfo-->bt,rt-->NULL
|
sysinfo-->bt,rt-->NULL
|
||||||
wintc-comctl-->bt,rt-->libwintc-comctl
|
wintc-comctl-->bt,rt-->libwintc-comctl
|
||||||
wintc-comgtk-->bt,rt-->libwintc-comgtk
|
wintc-comgtk-->bt,rt-->libwintc-comgtk
|
||||||
wintc-exec-->bt,rt-->libwintc-exec
|
wintc-exec-->bt,rt-->libwintc-exec
|
||||||
wintc-msgina-->bt,rt-->libwintc-msgina
|
wintc-msgina-->bt,rt-->libwintc-msgina
|
||||||
|
wintc-registry-->bt,rt-->libwintc-registry
|
||||||
wintc-shcommon-->bt,rt-->libwintc-shcommon
|
wintc-shcommon-->bt,rt-->libwintc-shcommon
|
||||||
wintc-shell-->bt,rt-->libwintc-shell
|
wintc-shell-->bt,rt-->libwintc-shell
|
||||||
wintc-shelldpa-->bt,rt-->libwintc-shelldpa
|
wintc-shelldpa-->bt,rt-->libwintc-shelldpa
|
||||||
|
|||||||
@@ -14,13 +14,17 @@ msgfmt-->bt,rt-->gettext
|
|||||||
plymouth-->bt,rt-->plymouth
|
plymouth-->bt,rt-->plymouth
|
||||||
pulseaudio-->bt-->pulseaudio-libs-devel
|
pulseaudio-->bt-->pulseaudio-libs-devel
|
||||||
pulseaudio-->rt-->pulseaudio-libs
|
pulseaudio-->rt-->pulseaudio-libs
|
||||||
|
python3-packaging-->bt,rt-->python3-packaging
|
||||||
python3-venv-->bt,rt-->python3-virtualenv
|
python3-venv-->bt,rt-->python3-virtualenv
|
||||||
sass-->bt,rt-->rubygem-sass
|
sass-->bt,rt-->rubygem-sass
|
||||||
|
sqlite3-->bt-->sqlite-devel
|
||||||
|
sqlite3-->rt-->sqlite
|
||||||
sysinfo-->bt,rt-->NULL
|
sysinfo-->bt,rt-->NULL
|
||||||
wintc-comctl-->bt,rt-->wintc-comctl
|
wintc-comctl-->bt,rt-->wintc-comctl
|
||||||
wintc-comgtk-->bt,rt-->wintc-comgtk
|
wintc-comgtk-->bt,rt-->wintc-comgtk
|
||||||
wintc-exec-->bt,rt-->wintc-exec
|
wintc-exec-->bt,rt-->wintc-exec
|
||||||
wintc-msgina-->bt,rt-->wintc-msgina
|
wintc-msgina-->bt,rt-->wintc-msgina
|
||||||
|
wintc-registry-->bt,rt-->wintc-registry
|
||||||
wintc-shcommon-->bt,rt-->wintc-shcommon
|
wintc-shcommon-->bt,rt-->wintc-shcommon
|
||||||
wintc-shell-->bt,rt-->wintc-shell
|
wintc-shell-->bt,rt-->wintc-shell
|
||||||
wintc-shelldpa-->bt,rt-->wintc-shelldpa
|
wintc-shelldpa-->bt,rt-->wintc-shelldpa
|
||||||
|
|||||||
Reference in New Issue
Block a user