mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-05-01 11:41:30 +00:00
Enhancement: Fixes #356, taskmgr - layout and process view
This commit is contained in:
@@ -24,3 +24,4 @@ shell/taskband
|
||||
shell/winver
|
||||
wallpapers
|
||||
windows/notepad
|
||||
windows/taskmgr
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
void wintc_menu_shell_deselect_on_leave(
|
||||
GtkWidget* widget,
|
||||
WINTC_UNUSED(GdkEvent* event),
|
||||
GdkEvent* event,
|
||||
GtkMenuShell* menu_shell
|
||||
);
|
||||
|
||||
@@ -26,8 +26,16 @@ void wintc_menu_shell_deselect_on_leave(
|
||||
*/
|
||||
void wintc_menu_shell_select_on_enter(
|
||||
GtkWidget* widget,
|
||||
WINTC_UNUSED(GdkEvent* event),
|
||||
GdkEvent* event,
|
||||
GtkMenuShell* menu_shell
|
||||
);
|
||||
|
||||
/**
|
||||
* Callback for closing the toplevel window upon a GtkButton clicked event.
|
||||
*/
|
||||
void wintc_button_close_window_on_clicked(
|
||||
GtkButton* self,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,6 +69,16 @@ gchar* wintc_str_set_suffix(
|
||||
const gchar* suffix
|
||||
);
|
||||
|
||||
/**
|
||||
* Duplicates the substring in an array of delimiter separated values by the
|
||||
* specified index.
|
||||
*/
|
||||
gchar* wintc_strdup_delimited(
|
||||
const gchar* str,
|
||||
gchar* delim_str,
|
||||
guint index
|
||||
);
|
||||
|
||||
/**
|
||||
* Duplicates part of a string from the start and ending at the first
|
||||
* occurrence of the specified delimiter (exclusive, so the delimiter will not
|
||||
@@ -152,7 +162,7 @@ guint wintc_strv_length(
|
||||
* Extracts a substring from one string to create a new string.
|
||||
*
|
||||
* @param start A pointer to the start of the substring.
|
||||
* @param end A pointer to the end of the substring.
|
||||
* @param end A pointer to the end of the substring or NULL.
|
||||
* @return A copy of the substring.
|
||||
*/
|
||||
gchar* wintc_substr(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "../public/defprocs.h"
|
||||
#include "../public/shorthand.h"
|
||||
#include "../public/window.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
@@ -32,3 +33,13 @@ void wintc_menu_shell_select_on_enter(
|
||||
widget
|
||||
);
|
||||
}
|
||||
|
||||
void wintc_button_close_window_on_clicked(
|
||||
GtkButton* self,
|
||||
WINTC_UNUSED(gpointer user_data)
|
||||
)
|
||||
{
|
||||
gtk_window_close(
|
||||
wintc_widget_get_toplevel_window(GTK_WIDGET(self))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,35 @@ gchar* wintc_str_set_suffix(
|
||||
}
|
||||
}
|
||||
|
||||
gchar* wintc_strdup_delimited(
|
||||
const gchar* str,
|
||||
gchar* delim_str,
|
||||
guint index
|
||||
)
|
||||
{
|
||||
gint delim_len = strlen(delim_str);
|
||||
const gchar* next = str;
|
||||
|
||||
for (guint i = 0; i < index; i++)
|
||||
{
|
||||
if (next != str)
|
||||
{
|
||||
next += delim_len; // Advance past the delimiter
|
||||
}
|
||||
|
||||
next = strstr(next, delim_str);
|
||||
|
||||
if (!next)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
next += delim_len;
|
||||
|
||||
return wintc_substr(next, strstr(next, delim_str));
|
||||
}
|
||||
|
||||
gchar* wintc_strdup_nextchr(
|
||||
const gchar* str,
|
||||
gssize len,
|
||||
@@ -224,6 +253,11 @@ gchar* wintc_substr(
|
||||
const gchar* end
|
||||
)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
end = start + strlen(start);
|
||||
}
|
||||
|
||||
if (end < start)
|
||||
{
|
||||
g_critical("substr: invalid substring requested");
|
||||
|
||||
@@ -21,16 +21,18 @@ include(../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||
include(../../packaging/cmake-inc/resources/CMakeLists.txt)
|
||||
|
||||
wintc_resolve_library(gdk-pixbuf-2.0 GDK_PIXBUF)
|
||||
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-exec WINTC_EXEC)
|
||||
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
|
||||
wintc_resolve_library(wintc-shellext WINTC_SHELLEXT)
|
||||
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
|
||||
wintc_resolve_library(wintc-winbrand WINTC_WINBRAND)
|
||||
wintc_resolve_library(libcanberra CANBERRA)
|
||||
wintc_resolve_library(libcanberra-gtk3 CANBERRA_GTK3)
|
||||
wintc_resolve_library(gdk-pixbuf-2.0 GDK_PIXBUF)
|
||||
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-exec WINTC_EXEC)
|
||||
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
|
||||
wintc_resolve_library(wintc-shellext WINTC_SHELLEXT)
|
||||
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
|
||||
wintc_resolve_library(wintc-winbrand WINTC_WINBRAND)
|
||||
|
||||
wintc_compile_resources()
|
||||
|
||||
@@ -51,6 +53,8 @@ add_library(
|
||||
src/icnvwbeh.c
|
||||
public/icnvwbeh.h
|
||||
src/resources.c
|
||||
public/sound.h
|
||||
src/sound.c
|
||||
src/trevwbeh.c
|
||||
public/trevwbeh.h
|
||||
src/nmspace.c
|
||||
@@ -81,6 +85,8 @@ target_include_directories(
|
||||
libwintc-shell
|
||||
SYSTEM
|
||||
BEFORE
|
||||
PRIVATE ${CANBERRA_INCLUDE_DIRS}
|
||||
PRIVATE ${CANBERRA_GTK3_INCLUDE_DIRS}
|
||||
PRIVATE ${GDK_PIXBUF_INCLUDE_DIRS}
|
||||
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||
@@ -95,6 +101,8 @@ target_include_directories(
|
||||
|
||||
target_link_directories(
|
||||
libwintc-shell
|
||||
PRIVATE ${CANBERRA_LIBRARY_DIRS}
|
||||
PRIVATE ${CANBERRA_GTK3_LIBRARY_DIRS}
|
||||
PRIVATE ${GDK_PIXBUF_LIBRARY_DIRS}
|
||||
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||
@@ -109,6 +117,8 @@ target_link_directories(
|
||||
|
||||
target_link_libraries(
|
||||
libwintc-shell
|
||||
PRIVATE ${CANBERRA_LIBRARIES}
|
||||
PRIVATE ${CANBERRA_GTK3_LIBRARIES}
|
||||
PRIVATE ${GDK_PIXBUF_LIBRARIES}
|
||||
PRIVATE ${GLIB_LIBRARIES}
|
||||
PRIVATE ${GTK3_LIBRARIES}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
bt,rt:canberra
|
||||
bt,rt:canberra-gtk3
|
||||
bt,rt:gdk-pixbuf2
|
||||
bt,rt:glib2
|
||||
bt,rt:gtk3
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "@LIB_HEADER_DIR@/fsclipbd.h"
|
||||
#include "@LIB_HEADER_DIR@/icnvwbeh.h"
|
||||
#include "@LIB_HEADER_DIR@/nmspace.h"
|
||||
#include "@LIB_HEADER_DIR@/sound.h"
|
||||
#include "@LIB_HEADER_DIR@/trevwbeh.h"
|
||||
#include "@LIB_HEADER_DIR@/vwcpl.h"
|
||||
#include "@LIB_HEADER_DIR@/vwdesk.h"
|
||||
|
||||
52
shared/shell/public/sound.h
Normal file
52
shared/shell/public/sound.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef __SHELL_SOUND_H__
|
||||
#define __SHELL_SOUND_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
//
|
||||
// PUBLIC DEFINES
|
||||
//
|
||||
#define WINTC_SHELL_SND_ASTERISK "dialog-warning"
|
||||
#define WINTC_SHELL_SND_BATTCRIT "battery-low"
|
||||
#define WINTC_SHELL_SND_CRITSTOP "dialog-error"
|
||||
#define WINTC_SHELL_SND_CLOSEPRG "windows-close-program"
|
||||
#define WINTC_SHELL_SND_DEFAULT "bell-window-system"
|
||||
#define WINTC_SHELL_SND_DEVADD "device-added-media"
|
||||
#define WINTC_SHELL_SND_DEVREM "device-removed-media"
|
||||
#define WINTC_SHELL_SND_DEVFAIL "windows-hardfail"
|
||||
#define WINTC_SHELL_SND_EXCLAM "dialog-question"
|
||||
#define WINTC_SHELL_SND_EXITWIN "desktop-logout"
|
||||
#define WINTC_SHELL_SND_BATTLOW "battery-caution"
|
||||
#define WINTC_SHELL_SND_MAXIMIZE "windows-maximize"
|
||||
#define WINTC_SHELL_SND_MENUCMD "windows-menu-command"
|
||||
#define WINTC_SHELL_SND_MENUPOP "windows-menu-popup"
|
||||
#define WINTC_SHELL_SND_MINIMIZE "windows-minimize"
|
||||
#define WINTC_SHELL_SND_NEWMAIL "message-new-email"
|
||||
#define WINTC_SHELL_SND_OPENPRG "windows-open-program"
|
||||
#define WINTC_SHELL_SND_PRINTCMP "windows-print-complete"
|
||||
#define WINTC_SHELL_SND_PROGERR "windows-program-error"
|
||||
#define WINTC_SHELL_SND_QUESTION "windows-question"
|
||||
#define WINTC_SHELL_SND_RESTDOWN "windows-restore-down"
|
||||
#define WINTC_SHELL_SND_RESTUP "windows-restore-up"
|
||||
#define WINTC_SHELL_SND_SELECT "windows-select"
|
||||
#define WINTC_SHELL_SND_SHOWTOOL "windows-show-toolbar-band"
|
||||
#define WINTC_SHELL_SND_STARTWIN "desktop-login"
|
||||
#define WINTC_SHELL_SND_SYSNOTIF "windows-system-notification"
|
||||
#define WINTC_SHELL_SND_LOGOFF "windows-logoff"
|
||||
#define WINTC_SHELL_SND_LOGON "windows-logon"
|
||||
|
||||
#define WINTC_SHELL_SND_BLKPOPUP "windows-blocked-popup"
|
||||
#define WINTC_SHELL_SND_CMPNAV "windows-complete-navigation"
|
||||
#define WINTC_SHELL_SND_EMPTYBIN "trash-empty"
|
||||
#define WINTC_SHELL_SND_INFOBAR "windows-information-bar"
|
||||
#define WINTC_SHELL_SND_MOVEITEM "windows-move-menu-item"
|
||||
#define WINTC_SHELL_SND_STARTNAV "windows-start-navigation"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
void wintc_sh_play_sound(
|
||||
const gchar* name
|
||||
);
|
||||
|
||||
#endif
|
||||
22
shared/shell/src/sound.c
Normal file
22
shared/shell/src/sound.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <canberra.h>
|
||||
#include <canberra-gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "../public/sound.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
void wintc_sh_play_sound(
|
||||
const gchar* name
|
||||
)
|
||||
{
|
||||
ca_context* ctx = ca_gtk_context_get();
|
||||
|
||||
ca_context_play(
|
||||
ctx,
|
||||
0,
|
||||
CA_PROP_EVENT_ID, name,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
@@ -2,5 +2,7 @@ bt,rt:glib2
|
||||
bt,rt:gtk3
|
||||
bt,rt:wintc-comctl
|
||||
bt,rt:wintc-comgtk
|
||||
bt,rt:wintc-exec
|
||||
bt,rt:wintc-shcommon
|
||||
bt,rt:wintc-shellext
|
||||
bt,rt:wintc-shlang
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef __INTAPI_H__
|
||||
#define __INTAPI_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
//
|
||||
// PUBLIC CONSTANTS
|
||||
//
|
||||
|
||||
108
windows/taskmgr/CMakeLists.txt
Normal file
108
windows/taskmgr/CMakeLists.txt
Normal file
@@ -0,0 +1,108 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(
|
||||
wintc-taskmgr
|
||||
VERSION 1.0
|
||||
DESCRIPTION "Windows Total Conversion Task Manager application."
|
||||
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-shcommon WINTC_SHCOMMON)
|
||||
wintc_resolve_library(wintc-shell WINTC_SHELL)
|
||||
wintc_resolve_library(wintc-shellext WINTC_SHELLEXT)
|
||||
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
|
||||
|
||||
wintc_compile_resources()
|
||||
wintc_create_meta_h()
|
||||
|
||||
add_executable(
|
||||
wintc-taskmgr
|
||||
src/application.c
|
||||
src/application.h
|
||||
src/intapi.h
|
||||
src/main.c
|
||||
src/meta.h
|
||||
src/pageproc.c
|
||||
src/pageproc.h
|
||||
src/procmon.c
|
||||
src/procmon.h
|
||||
src/resources.c
|
||||
src/window.c
|
||||
src/window.h
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
wintc-taskmgr
|
||||
PROPERTIES
|
||||
OUTPUT_NAME taskmgr
|
||||
)
|
||||
|
||||
target_compile_options(
|
||||
wintc-taskmgr
|
||||
PRIVATE ${WINTC_COMPILE_OPTIONS}
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
wintc-taskmgr
|
||||
SYSTEM
|
||||
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_COMCTL_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHCOMMON_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHELL_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHELLEXT_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHLANG_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_directories(
|
||||
wintc-taskmgr
|
||||
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_COMCTL_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHCOMMON_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHELL_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHELLEXT_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHLANG_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
wintc-taskmgr
|
||||
PRIVATE ${GLIB_LIBRARIES}
|
||||
PRIVATE ${GTK3_LIBRARIES}
|
||||
PRIVATE ${WINTC_COMCTL_LIBRARIES}
|
||||
PRIVATE ${WINTC_COMGTK_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHCOMMON_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHELL_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHELLEXT_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHLANG_LIBRARIES}
|
||||
)
|
||||
|
||||
# Installation
|
||||
#
|
||||
wintc_configure_and_install_packaging()
|
||||
wintc_install_icons_into_package()
|
||||
|
||||
install(
|
||||
TARGETS wintc-taskmgr
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
4
windows/taskmgr/README.MD
Normal file
4
windows/taskmgr/README.MD
Normal file
@@ -0,0 +1,4 @@
|
||||
# taskmgr
|
||||
This directory contains the source code for the *Task Manager*.
|
||||
|
||||

|
||||
8
windows/taskmgr/deps
Normal file
8
windows/taskmgr/deps
Normal file
@@ -0,0 +1,8 @@
|
||||
bt,rt:glib2
|
||||
bt,rt:gtk3
|
||||
bt,rt:wintc-comctl
|
||||
bt,rt:wintc-comgtk
|
||||
bt,rt:wintc-shcommon
|
||||
bt,rt:wintc-shell
|
||||
bt,rt:wintc-shellext
|
||||
bt,rt:wintc-shlang
|
||||
BIN
windows/taskmgr/icons/16x16/taskmgr.png
Normal file
BIN
windows/taskmgr/icons/16x16/taskmgr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 227 B |
BIN
windows/taskmgr/icons/32x32/taskmgr.png
Normal file
BIN
windows/taskmgr/icons/32x32/taskmgr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 299 B |
90
windows/taskmgr/src/application.c
Normal file
90
windows/taskmgr/src/application.c
Normal file
@@ -0,0 +1,90 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc/comctl.h>
|
||||
#include <wintc/comgtk.h>
|
||||
|
||||
#include "application.h"
|
||||
#include "window.h"
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
struct _WinTCTaskmgrApplicationClass
|
||||
{
|
||||
GtkApplicationClass __parent__;
|
||||
};
|
||||
|
||||
struct _WinTCTaskmgrApplication
|
||||
{
|
||||
GtkApplication __parent__;
|
||||
};
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_taskmgr_application_activate(
|
||||
GApplication* application
|
||||
);
|
||||
static void wintc_taskmgr_application_startup(
|
||||
GApplication* application
|
||||
);
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITIONS & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCTaskmgrApplication,
|
||||
wintc_taskmgr_application,
|
||||
GTK_TYPE_APPLICATION
|
||||
)
|
||||
|
||||
static void wintc_taskmgr_application_class_init(
|
||||
WinTCTaskmgrApplicationClass* klass
|
||||
)
|
||||
{
|
||||
GApplicationClass* application_class = G_APPLICATION_CLASS(klass);
|
||||
|
||||
application_class->activate = wintc_taskmgr_application_activate;
|
||||
application_class->startup = wintc_taskmgr_application_startup;
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_application_init(
|
||||
WINTC_UNUSED(WinTCTaskmgrApplication* self)
|
||||
) { }
|
||||
|
||||
//
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_taskmgr_application_activate(
|
||||
GApplication* application
|
||||
)
|
||||
{
|
||||
GtkWidget* new_window =
|
||||
wintc_taskmgr_window_new(WINTC_TASKMGR_APPLICATION(application));
|
||||
|
||||
gtk_widget_show_all(new_window);
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_application_startup(
|
||||
GApplication* application
|
||||
)
|
||||
{
|
||||
(G_APPLICATION_CLASS(wintc_taskmgr_application_parent_class))
|
||||
->startup(application);
|
||||
|
||||
wintc_ctl_install_default_styles();
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCTaskmgrApplication* wintc_taskmgr_application_new(void)
|
||||
{
|
||||
return WINTC_TASKMGR_APPLICATION(
|
||||
g_object_new(
|
||||
wintc_taskmgr_application_get_type(),
|
||||
"application-id", "uk.co.oddmatics.wintc.samples.taskmgr",
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
27
windows/taskmgr/src/application.h
Normal file
27
windows/taskmgr/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 _WinTCTaskmgrApplicationClass WinTCTaskmgrApplicationClass;
|
||||
typedef struct _WinTCTaskmgrApplication WinTCTaskmgrApplication;
|
||||
|
||||
#define WINTC_TYPE_TASKMGR_APPLICATION (wintc_taskmgr_application_get_type())
|
||||
#define WINTC_TASKMGR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_TASKMGR_APPLICATION, WinTCTaskmgrApplication))
|
||||
#define WINTC_TASKMGR_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_TASKMGR_APPLICATION, WinTCTaskmgrApplicationClass))
|
||||
#define IS_WINTC_TASKMGR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_TASKMGR_APPLICATION))
|
||||
#define IS_WINTC_TASKMGR_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_TASKMGR_APPLICATION))
|
||||
#define WINTC_TASKMGR_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_TASKMGR_APPLICATION, WinTCTaskmgrApplicationClass))
|
||||
|
||||
GType wintc_taskmgr_application_get_type(void) G_GNUC_CONST;
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCTaskmgrApplication* wintc_taskmgr_application_new(void);
|
||||
|
||||
#endif
|
||||
9
windows/taskmgr/src/intapi.h
Normal file
9
windows/taskmgr/src/intapi.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __INTAPI_H__
|
||||
#define __INTAPI_H__
|
||||
|
||||
//
|
||||
// PUBLIC CONSTANTS
|
||||
//
|
||||
#define WINTC_TASKMGR_HOSTEXT_PAGE 1
|
||||
|
||||
#endif
|
||||
32
windows/taskmgr/src/main.c
Normal file
32
windows/taskmgr/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
|
||||
//
|
||||
WinTCTaskmgrApplication* app = wintc_taskmgr_application_new();
|
||||
int status;
|
||||
|
||||
g_set_application_name("Taskmgr");
|
||||
|
||||
status = g_application_run(G_APPLICATION(app), argc, argv);
|
||||
|
||||
g_object_unref(app);
|
||||
|
||||
return status;
|
||||
}
|
||||
295
windows/taskmgr/src/pageproc.c
Normal file
295
windows/taskmgr/src/pageproc.c
Normal file
@@ -0,0 +1,295 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <signal.h>
|
||||
#include <wintc/comgtk.h>
|
||||
#include <wintc/shcommon.h>
|
||||
#include <wintc/shell.h>
|
||||
#include <wintc/shellext.h>
|
||||
#include <wintc/shlang.h>
|
||||
|
||||
#include "intapi.h"
|
||||
#include "pageproc.h"
|
||||
#include "procmon.h"
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_taskmgr_page_processes_constructed(
|
||||
GObject* object
|
||||
);
|
||||
|
||||
static void on_button_endproc_clicked(
|
||||
GtkButton* self,
|
||||
gpointer user_data
|
||||
);
|
||||
static void on_dlgkill_button_yes_clicked(
|
||||
GtkButton* self,
|
||||
gpointer user_data
|
||||
);
|
||||
static void on_treeview_cursor_changed(
|
||||
GtkWidget* self,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
typedef struct _WinTCTaskmgrPageProcesses
|
||||
{
|
||||
WinTCShextUIController __parent__;
|
||||
|
||||
// UI
|
||||
//
|
||||
GtkWidget* button_endproc;
|
||||
GtkWidget* treeview_procs;
|
||||
} WinTCTaskmgrPageProcess;
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITIONS & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCTaskmgrPageProcesses,
|
||||
wintc_taskmgr_page_processes,
|
||||
WINTC_TYPE_SHEXT_UI_CONTROLLER
|
||||
)
|
||||
|
||||
static void wintc_taskmgr_page_processes_class_init(
|
||||
WinTCTaskmgrPageProcessesClass* klass
|
||||
)
|
||||
{
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->constructed = wintc_taskmgr_page_processes_constructed;
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_page_processes_init(
|
||||
WINTC_UNUSED(WinTCTaskmgrPageProcesses* self)
|
||||
) {}
|
||||
|
||||
//
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_taskmgr_page_processes_constructed(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrPageProcesses* page = WINTC_TASKMGR_PAGE_PROCESSES(object);
|
||||
|
||||
GtkBuilder* builder =
|
||||
gtk_builder_new_from_resource(
|
||||
"/uk/oddmatics/wintc/taskmgr/page-processes.ui"
|
||||
);
|
||||
|
||||
wintc_lc_builder_preprocess_widget_text(builder);
|
||||
|
||||
// Insert page into host
|
||||
//
|
||||
WinTCIShextUIHost* ui_host =
|
||||
wintc_shext_ui_controller_get_ui_host(
|
||||
WINTC_SHEXT_UI_CONTROLLER(object)
|
||||
);
|
||||
|
||||
wintc_builder_get_objects(
|
||||
builder,
|
||||
"button-endproc", &(page->button_endproc),
|
||||
"tree-view", &(page->treeview_procs),
|
||||
NULL
|
||||
);
|
||||
|
||||
wintc_ishext_ui_host_get_ext_widget(
|
||||
ui_host,
|
||||
WINTC_TASKMGR_HOSTEXT_PAGE,
|
||||
GTK_TYPE_BOX,
|
||||
builder
|
||||
);
|
||||
|
||||
g_object_unref(builder);
|
||||
|
||||
// Set up treeview
|
||||
//
|
||||
WinTCTaskmgrProcmon* procmon = wintc_taskmgr_procmon_get_instance();
|
||||
|
||||
wintc_taskmgr_procmon_bind_tree_view_model(
|
||||
procmon,
|
||||
GTK_TREE_VIEW(page->treeview_procs)
|
||||
);
|
||||
|
||||
gtk_tree_view_append_column(
|
||||
GTK_TREE_VIEW(page->treeview_procs),
|
||||
gtk_tree_view_column_new_with_attributes(
|
||||
"Image Name",
|
||||
gtk_cell_renderer_text_new(),
|
||||
"text", COLUMN_IMAGE_NAME,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
gtk_tree_view_append_column(
|
||||
GTK_TREE_VIEW(page->treeview_procs),
|
||||
gtk_tree_view_column_new_with_attributes(
|
||||
"User Name",
|
||||
gtk_cell_renderer_text_new(),
|
||||
"text", COLUMN_USER_NAME,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
gtk_tree_view_append_column(
|
||||
GTK_TREE_VIEW(page->treeview_procs),
|
||||
gtk_tree_view_column_new_with_attributes(
|
||||
"CPU",
|
||||
gtk_cell_renderer_text_new(),
|
||||
"text", COLUMN_CPU_USAGE,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
gtk_tree_view_append_column(
|
||||
GTK_TREE_VIEW(page->treeview_procs),
|
||||
gtk_tree_view_column_new_with_attributes(
|
||||
"Mem Usage",
|
||||
gtk_cell_renderer_text_new(),
|
||||
"text", COLUMN_MEM_USAGE,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
|
||||
// Hook up signals
|
||||
//
|
||||
g_signal_connect(
|
||||
page->button_endproc,
|
||||
"clicked",
|
||||
G_CALLBACK(on_button_endproc_clicked),
|
||||
page
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
page->treeview_procs,
|
||||
"cursor-changed",
|
||||
G_CALLBACK(on_treeview_cursor_changed),
|
||||
page
|
||||
);
|
||||
|
||||
// Chain up
|
||||
//
|
||||
(G_OBJECT_CLASS(wintc_taskmgr_page_processes_parent_class))
|
||||
->constructed(object);
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void on_button_endproc_clicked(
|
||||
GtkButton* self,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrPageProcesses* page = WINTC_TASKMGR_PAGE_PROCESSES(user_data);
|
||||
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel* model = NULL;
|
||||
|
||||
if (
|
||||
!gtk_tree_selection_get_selected(
|
||||
gtk_tree_view_get_selection(GTK_TREE_VIEW(page->treeview_procs)),
|
||||
&model,
|
||||
&iter
|
||||
)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the PID and kill
|
||||
//
|
||||
guint pid = 0;
|
||||
|
||||
gtk_tree_model_get(
|
||||
model,
|
||||
&iter,
|
||||
COLUMN_PID, &pid,
|
||||
-1
|
||||
);
|
||||
|
||||
// Spawn the dialog to confirm the action
|
||||
//
|
||||
GtkBuilder* builder;
|
||||
|
||||
GtkWidget* button_no = NULL;
|
||||
GtkWidget* button_yes = NULL;
|
||||
GtkWidget* wnd = NULL;
|
||||
|
||||
builder =
|
||||
gtk_builder_new_from_resource(
|
||||
"/uk/oddmatics/wintc/taskmgr/dlgkill.ui"
|
||||
);
|
||||
|
||||
wintc_lc_builder_preprocess_widget_text(builder);
|
||||
|
||||
wintc_builder_get_objects(
|
||||
builder,
|
||||
"main-wnd", &wnd,
|
||||
"button-no", &button_no,
|
||||
"button-yes", &button_yes,
|
||||
NULL
|
||||
);
|
||||
|
||||
gtk_window_set_modal(
|
||||
GTK_WINDOW(wnd),
|
||||
TRUE
|
||||
);
|
||||
gtk_window_set_transient_for(
|
||||
GTK_WINDOW(wnd),
|
||||
wintc_widget_get_toplevel_window(GTK_WIDGET(self))
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
button_no,
|
||||
"clicked",
|
||||
G_CALLBACK(wintc_button_close_window_on_clicked),
|
||||
NULL
|
||||
);
|
||||
g_signal_connect(
|
||||
button_yes,
|
||||
"clicked",
|
||||
G_CALLBACK(on_dlgkill_button_yes_clicked),
|
||||
GUINT_TO_POINTER(pid)
|
||||
);
|
||||
|
||||
gtk_window_present_with_time(
|
||||
GTK_WINDOW(wnd),
|
||||
0
|
||||
);
|
||||
|
||||
wintc_sh_play_sound(WINTC_SHELL_SND_EXCLAM);
|
||||
|
||||
g_object_unref(builder);
|
||||
}
|
||||
|
||||
static void on_dlgkill_button_yes_clicked(
|
||||
GtkButton* self,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
guint pid = GPOINTER_TO_UINT(user_data);
|
||||
|
||||
gtk_window_close(
|
||||
wintc_widget_get_toplevel_window(GTK_WIDGET(self))
|
||||
);
|
||||
|
||||
kill(pid, SIGKILL);
|
||||
}
|
||||
|
||||
static void on_treeview_cursor_changed(
|
||||
GtkWidget* self,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrPageProcesses* page = WINTC_TASKMGR_PAGE_PROCESSES(user_data);
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
page->button_endproc,
|
||||
gtk_tree_selection_get_selected(
|
||||
gtk_tree_view_get_selection(GTK_TREE_VIEW(self)),
|
||||
NULL,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
20
windows/taskmgr/src/pageproc.h
Normal file
20
windows/taskmgr/src/pageproc.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __PAGEPROC_H__
|
||||
#define __PAGEPROC_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <wintc/shellext.h>
|
||||
|
||||
//
|
||||
// GTK OOP BOILERPLATE
|
||||
//
|
||||
#define WINTC_TYPE_TASKMGR_PAGE_PROCESSES (wintc_taskmgr_page_processes_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE(
|
||||
WinTCTaskmgrPageProcesses,
|
||||
wintc_taskmgr_page_processes,
|
||||
WINTC,
|
||||
TASKMGR_PAGE_PROCESSES,
|
||||
WinTCShextUIController
|
||||
)
|
||||
|
||||
#endif
|
||||
523
windows/taskmgr/src/procmon.c
Normal file
523
windows/taskmgr/src/procmon.c
Normal file
@@ -0,0 +1,523 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <wintc/comgtk.h>
|
||||
#include <wintc/shcommon.h>
|
||||
|
||||
#include "procmon.h"
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void process_get_details(
|
||||
guint pid,
|
||||
gchar** owner,
|
||||
guint* cpu_time,
|
||||
guint* mem_total
|
||||
);
|
||||
|
||||
static void process_get_totals(
|
||||
guint* cpu_time
|
||||
);
|
||||
|
||||
static gboolean timeout_process_monitor(
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// STATIC DATA
|
||||
//
|
||||
static gchar* S_PROC_STAT_PATH = NULL;
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
typedef struct _WinTCTaskmgrProcmon
|
||||
{
|
||||
GObject __parent__;
|
||||
|
||||
// State
|
||||
//
|
||||
guint id_procmon;
|
||||
guint last_cpu_time;
|
||||
GtkListStore* model_procs;
|
||||
} WinTCTaskmgrProcmon;
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITIONS & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCTaskmgrProcmon,
|
||||
wintc_taskmgr_procmon,
|
||||
G_TYPE_OBJECT
|
||||
)
|
||||
|
||||
static void wintc_taskmgr_procmon_class_init(
|
||||
WINTC_UNUSED(WinTCTaskmgrProcmonClass* klass)
|
||||
)
|
||||
{
|
||||
S_PROC_STAT_PATH =
|
||||
g_build_path(
|
||||
G_DIR_SEPARATOR_S,
|
||||
G_DIR_SEPARATOR_S,
|
||||
"proc",
|
||||
"stat",
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_procmon_init(
|
||||
WinTCTaskmgrProcmon* self
|
||||
)
|
||||
{
|
||||
// Set up model
|
||||
//
|
||||
self->model_procs =
|
||||
gtk_list_store_new(
|
||||
N_COLUMNS,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT
|
||||
);
|
||||
|
||||
// Start process monitor
|
||||
//
|
||||
self->id_procmon =
|
||||
g_timeout_add_seconds(
|
||||
1,
|
||||
(GSourceFunc) timeout_process_monitor,
|
||||
self
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCTaskmgrProcmon* wintc_taskmgr_procmon_get_instance(void)
|
||||
{
|
||||
static WinTCTaskmgrProcmon* singleton;
|
||||
|
||||
if (!singleton)
|
||||
{
|
||||
singleton =
|
||||
WINTC_TASKMGR_PROCMON(
|
||||
g_object_new(
|
||||
WINTC_TYPE_TASKMGR_PROCMON,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void wintc_taskmgr_procmon_bind_tree_view_model(
|
||||
WinTCTaskmgrProcmon* procmon,
|
||||
GtkTreeView* tree_view
|
||||
)
|
||||
{
|
||||
gtk_tree_view_set_model(
|
||||
tree_view,
|
||||
GTK_TREE_MODEL(procmon->model_procs)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static void process_get_details(
|
||||
guint pid,
|
||||
gchar** owner,
|
||||
guint* cpu_time,
|
||||
guint* mem_total
|
||||
)
|
||||
{
|
||||
GError* error = NULL;
|
||||
gchar* pid_str = g_strdup_printf("%u", pid);
|
||||
|
||||
// Owner
|
||||
//
|
||||
if (owner)
|
||||
{
|
||||
GFile* file_pid = g_file_new_build_filename(
|
||||
G_DIR_SEPARATOR_S,
|
||||
"proc",
|
||||
pid_str,
|
||||
NULL
|
||||
);
|
||||
GFileInfo* file_info = g_file_query_info(
|
||||
file_pid,
|
||||
G_FILE_ATTRIBUTE_OWNER_USER,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
NULL,
|
||||
&error
|
||||
);
|
||||
|
||||
|
||||
if (file_info)
|
||||
{
|
||||
*owner =
|
||||
g_file_info_get_attribute_as_string(
|
||||
file_info,
|
||||
G_FILE_ATTRIBUTE_OWNER_USER
|
||||
);
|
||||
|
||||
g_object_unref(file_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WINTC_CHECKED
|
||||
g_warning("Problem querying file info for process %s", pid_str);
|
||||
wintc_log_error_and_clear(&error);
|
||||
#else
|
||||
g_clear_error(&error);
|
||||
#endif
|
||||
}
|
||||
|
||||
g_object_unref(file_pid);
|
||||
}
|
||||
|
||||
// Stats
|
||||
//
|
||||
// FIXME: This is pretty rough, we use utime + stime / total CPU time for
|
||||
// usage, and we're just displaying virtual memory usage in KB for
|
||||
// memory total
|
||||
//
|
||||
// This is likely pretty far from how Windows displays these stats,
|
||||
// but it's better than nothing for now
|
||||
//
|
||||
gchar* stat_path = g_build_path(
|
||||
G_DIR_SEPARATOR_S,
|
||||
G_DIR_SEPARATOR_S,
|
||||
"proc",
|
||||
pid_str,
|
||||
"stat",
|
||||
NULL
|
||||
);
|
||||
gchar* stat_str = NULL;
|
||||
|
||||
*cpu_time = 0;
|
||||
*mem_total = 0;
|
||||
|
||||
if (g_file_get_contents(stat_path, &stat_str, NULL, NULL))
|
||||
{
|
||||
gchar* mem_s = wintc_strdup_delimited(stat_str, " ", 22);
|
||||
gchar* utime_s = wintc_strdup_delimited(stat_str, " ", 13);
|
||||
gchar* stime_s = wintc_strdup_delimited(stat_str, " ", 14);
|
||||
|
||||
*cpu_time = strtoul(utime_s, NULL, 0) + strtoul(stime_s, NULL, 0);
|
||||
*mem_total = strtoul(mem_s, NULL, 0) / 1024;
|
||||
|
||||
g_free(stat_str);
|
||||
g_free(mem_s);
|
||||
g_free(utime_s);
|
||||
g_free(stime_s);
|
||||
}
|
||||
|
||||
g_free(stat_path);
|
||||
g_free(pid_str);
|
||||
}
|
||||
|
||||
static void process_get_totals(
|
||||
guint* cpu_time
|
||||
)
|
||||
{
|
||||
gchar* cpu_stats = NULL;
|
||||
|
||||
if (
|
||||
g_file_get_contents(
|
||||
S_PROC_STAT_PATH,
|
||||
&cpu_stats,
|
||||
NULL,
|
||||
NULL
|
||||
)
|
||||
)
|
||||
{
|
||||
gchar* last_stime_s = wintc_strdup_delimited(
|
||||
cpu_stats + 5, // skip 'cpu '
|
||||
" ",
|
||||
0
|
||||
);
|
||||
gchar* last_utime_s = wintc_strdup_delimited(
|
||||
cpu_stats + 5,
|
||||
" ",
|
||||
2
|
||||
);
|
||||
|
||||
*cpu_time =
|
||||
strtoul(last_stime_s, NULL, 0) + strtoul(last_utime_s, NULL, 0);
|
||||
|
||||
g_free(last_stime_s);
|
||||
g_free(last_utime_s);
|
||||
g_free(cpu_stats);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static gboolean timeout_process_monitor(
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrProcmon* procmon = WINTC_TASKMGR_PROCMON(user_data);
|
||||
|
||||
// Acquire the total CPU time stats
|
||||
//
|
||||
guint total_cpu_delta;
|
||||
guint total_cpu_time;
|
||||
|
||||
process_get_totals(
|
||||
&total_cpu_time
|
||||
);
|
||||
|
||||
total_cpu_delta = total_cpu_time - procmon->last_cpu_time;
|
||||
|
||||
// We store a mapping of PIDs that we found to check against later
|
||||
//
|
||||
GHashTable* map_pid_to_exe =
|
||||
g_hash_table_new_full(
|
||||
g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) g_free
|
||||
);
|
||||
|
||||
// Retrieve stuff under /proc
|
||||
//
|
||||
GList* proc_dirs =
|
||||
wintc_sh_fs_get_names_as_list(
|
||||
G_DIR_SEPARATOR_S "proc",
|
||||
TRUE,
|
||||
G_FILE_TEST_IS_DIR,
|
||||
FALSE,
|
||||
NULL
|
||||
);
|
||||
|
||||
for (GList* iter = proc_dirs; iter; iter = iter->next)
|
||||
{
|
||||
const gchar* dir_name = wintc_basename((gchar*) iter->data);
|
||||
|
||||
// Only interested in PIDs
|
||||
//
|
||||
if (!g_ascii_isdigit(*dir_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Retrieve the exe info
|
||||
//
|
||||
GFile* file_exe = g_file_new_build_filename(
|
||||
G_DIR_SEPARATOR_S,
|
||||
(gchar*) iter->data,
|
||||
"exe",
|
||||
NULL
|
||||
);
|
||||
GFileInfo* file_info = g_file_query_info(
|
||||
file_exe,
|
||||
"standard::symlink-target",
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
g_object_unref(file_exe);
|
||||
|
||||
if (!file_info)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pull the info
|
||||
//
|
||||
gchar* exe_target =
|
||||
g_file_info_get_attribute_as_string(
|
||||
file_info,
|
||||
"standard::symlink-target"
|
||||
);
|
||||
|
||||
// Track this process
|
||||
//
|
||||
if (exe_target)
|
||||
{
|
||||
g_hash_table_insert(
|
||||
map_pid_to_exe,
|
||||
GUINT_TO_POINTER(
|
||||
strtoul(dir_name, NULL, 0)
|
||||
),
|
||||
g_strdup(wintc_basename(exe_target))
|
||||
);
|
||||
|
||||
g_free(exe_target);
|
||||
}
|
||||
|
||||
g_object_unref(file_info);
|
||||
}
|
||||
|
||||
g_list_free_full(proc_dirs, (GDestroyNotify) g_free);
|
||||
|
||||
// Iterate over the current list store, update rows where we have a
|
||||
// mapping, remove ones we don't, and then insert the remainder
|
||||
//
|
||||
GtkTreeIter tree_iter;
|
||||
|
||||
if (
|
||||
gtk_tree_model_get_iter_first(
|
||||
GTK_TREE_MODEL(procmon->model_procs),
|
||||
&tree_iter
|
||||
)
|
||||
)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
guint pid = 0;
|
||||
gchar* exe = NULL;
|
||||
|
||||
gtk_tree_model_get(
|
||||
GTK_TREE_MODEL(procmon->model_procs),
|
||||
&tree_iter,
|
||||
COLUMN_PID, &pid,
|
||||
COLUMN_IMAGE_NAME, &exe,
|
||||
-1
|
||||
);
|
||||
|
||||
// If we either don't have a mapping or it doesn't match, delete
|
||||
// the row
|
||||
//
|
||||
const gchar* cmp_exe =
|
||||
g_hash_table_lookup(map_pid_to_exe, GUINT_TO_POINTER(pid));
|
||||
|
||||
if (
|
||||
!cmp_exe ||
|
||||
g_strcmp0(exe, cmp_exe) != 0
|
||||
)
|
||||
{
|
||||
if (
|
||||
!gtk_list_store_remove(
|
||||
procmon->model_procs,
|
||||
&tree_iter
|
||||
)
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
g_free(exe);
|
||||
|
||||
// We DO have a mapping AND it matches, so update the row (and
|
||||
// remove the mapping so we know it has been dealt with)
|
||||
//
|
||||
guint cpu_time;
|
||||
guint last_cpu_time;
|
||||
guint mem_usage;
|
||||
|
||||
process_get_details(
|
||||
pid,
|
||||
NULL,
|
||||
&cpu_time,
|
||||
&mem_usage
|
||||
);
|
||||
|
||||
gtk_tree_model_get(
|
||||
GTK_TREE_MODEL(procmon->model_procs),
|
||||
&tree_iter,
|
||||
COLUMN_CPU_TIME, &last_cpu_time,
|
||||
-1
|
||||
);
|
||||
|
||||
// Update the records
|
||||
//
|
||||
guint cpu_delta = cpu_time - last_cpu_time;
|
||||
gdouble cpu_pct = cpu_delta / (gdouble) total_cpu_delta;
|
||||
|
||||
gtk_list_store_set(
|
||||
procmon->model_procs,
|
||||
&tree_iter,
|
||||
COLUMN_CPU_TIME, cpu_time,
|
||||
COLUMN_CPU_USAGE, (gint) (cpu_pct * 100),
|
||||
COLUMN_MEM_USAGE, mem_usage,
|
||||
-1
|
||||
);
|
||||
|
||||
g_hash_table_remove(
|
||||
map_pid_to_exe,
|
||||
GUINT_TO_POINTER(pid)
|
||||
);
|
||||
|
||||
// Next...
|
||||
//
|
||||
if (
|
||||
!gtk_tree_model_iter_next(
|
||||
GTK_TREE_MODEL(procmon->model_procs),
|
||||
&tree_iter
|
||||
)
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over the remaining items in the map to add them
|
||||
//
|
||||
GHashTableIter map_iter;
|
||||
gpointer map_key_pid;
|
||||
gpointer map_value_exe;
|
||||
|
||||
g_hash_table_iter_init(&map_iter, map_pid_to_exe);
|
||||
|
||||
while (
|
||||
g_hash_table_iter_next(
|
||||
&map_iter,
|
||||
&map_key_pid,
|
||||
&map_value_exe
|
||||
)
|
||||
)
|
||||
{
|
||||
const gchar* exe = (gchar*) map_value_exe;
|
||||
guint pid = GPOINTER_TO_UINT(map_key_pid);
|
||||
|
||||
guint cpu_time;
|
||||
guint mem_total;
|
||||
gchar* owner = NULL;
|
||||
|
||||
process_get_details(
|
||||
pid,
|
||||
&owner,
|
||||
&cpu_time,
|
||||
&mem_total
|
||||
);
|
||||
|
||||
gtk_list_store_append(
|
||||
procmon->model_procs,
|
||||
&tree_iter
|
||||
);
|
||||
gtk_list_store_set(
|
||||
procmon->model_procs,
|
||||
&tree_iter,
|
||||
COLUMN_PID, pid,
|
||||
COLUMN_IMAGE_NAME, exe,
|
||||
COLUMN_USER_NAME, owner,
|
||||
COLUMN_CPU_TIME, cpu_time,
|
||||
COLUMN_CPU_USAGE, 0,
|
||||
COLUMN_MEM_USAGE, mem_total,
|
||||
-1
|
||||
);
|
||||
|
||||
g_free(owner);
|
||||
}
|
||||
|
||||
g_hash_table_destroy(map_pid_to_exe);
|
||||
|
||||
// Update processor stats
|
||||
//
|
||||
procmon->last_cpu_time = total_cpu_time;
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
44
windows/taskmgr/src/procmon.h
Normal file
44
windows/taskmgr/src/procmon.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef __PROCMON_H__
|
||||
#define __PROCMON_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//
|
||||
// PUBLIC ENUMS
|
||||
//
|
||||
enum
|
||||
{
|
||||
COLUMN_PID = 0,
|
||||
COLUMN_IMAGE_NAME,
|
||||
COLUMN_USER_NAME,
|
||||
COLUMN_CPU_TIME, // utime + stime
|
||||
COLUMN_CPU_USAGE,
|
||||
COLUMN_MEM_USAGE,
|
||||
N_COLUMNS
|
||||
};
|
||||
|
||||
//
|
||||
// GTK OOP BOILERPLATE
|
||||
//
|
||||
#define WINTC_TYPE_TASKMGR_PROCMON (wintc_taskmgr_procmon_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE(
|
||||
WinTCTaskmgrProcmon,
|
||||
wintc_taskmgr_procmon,
|
||||
WINTC,
|
||||
TASKMGR_PROCMON,
|
||||
GObject
|
||||
)
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCTaskmgrProcmon* wintc_taskmgr_procmon_get_instance(void);
|
||||
|
||||
void wintc_taskmgr_procmon_bind_tree_view_model(
|
||||
WinTCTaskmgrProcmon* procmon,
|
||||
GtkTreeView* tree_view
|
||||
);
|
||||
|
||||
#endif
|
||||
115
windows/taskmgr/src/res/dlgkill.ui
Normal file
115
windows/taskmgr/src/res/dlgkill.ui
Normal file
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="main-wnd">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="title" translatable="yes">Task Manager Warning</property>
|
||||
<property name="type-hint">GDK_WINDOW_TYPE_HINT_DIALOG</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="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">dialog-warning</property>
|
||||
<property name="pixel-size">32</property>
|
||||
<property name="yalign">0.0</property>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mr-lg" />
|
||||
</style>
|
||||
</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">WARNING: Terminating a process can cause undesired results including loss of data and system instability. The process will not be given the chance to save its state or data before it is terminated. Are you sure you want to terminate the process?</property>
|
||||
<property name="max-width-chars">46</property>
|
||||
<property name="wrap">TRUE</property>
|
||||
<property name="xalign">0.0</property>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mr-sm" />
|
||||
</style>
|
||||
</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>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="halign">GTK_ALIGN_CENTER</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkButton" id="button-yes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="label" translatable="no">%CTL_YES%</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button-no">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="label" translatable="no">%CTL_NO%</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<style>
|
||||
<class name="wintc-button-box" />
|
||||
<class name="wintc-mt-lg" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mb-lg" />
|
||||
<class name="wintc-ml-lg" />
|
||||
<class name="wintc-mr-lg" />
|
||||
<class name="wintc-mt-lg" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
87
windows/taskmgr/src/res/page-processes.ui
Normal file
87
windows/taskmgr/src/res/page-processes.ui
Normal file
@@ -0,0 +1,87 @@
|
||||
<?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">Processes</property>
|
||||
</object>
|
||||
<object class="GtkBox" id="page">
|
||||
<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">True</property>
|
||||
<property name="overlay-scrolling">False</property>
|
||||
<property name="shadow-type">in</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkTreeView" id="tree-view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</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="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check-allusers">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="label" translatable="yes">Show processes from all users</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" id="button-endproc">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="label" translatable="yes">End Process</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>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mt-md" />
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mb-lg" />
|
||||
<class name="wintc-ml-lg" />
|
||||
<class name="wintc-mr-lg" />
|
||||
<class name="wintc-mt-lg" />
|
||||
</style>
|
||||
</object>
|
||||
</interface>
|
||||
8
windows/taskmgr/src/res/resources.xml
Normal file
8
windows/taskmgr/src/res/resources.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/uk/oddmatics/wintc/taskmgr">
|
||||
<file>dlgkill.ui</file>
|
||||
<file>taskmgr.ui</file>
|
||||
<file>page-processes.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
314
windows/taskmgr/src/res/taskmgr.ui
Normal file
314
windows/taskmgr/src/res/taskmgr.ui
Normal file
@@ -0,0 +1,314 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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="GtkMenuBar" id="main-menubar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">%CTL_FILEMENU%</property>
|
||||
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">New Task (Run...)</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.exit</property>
|
||||
<property name="label" translatable="yes">Exit Task Manager</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Options</property>
|
||||
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Always On Top</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Minimize On Use</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Hide When Minimized</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Show 16-bit tasks</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">%CTL_VIEWMENU%</property>
|
||||
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Refresh Now</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Update Speed</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Select Columns</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Shut Down</property>
|
||||
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Stand By</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Hibernate</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Turn Off</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Restart</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Log Off %s</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Switch User</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">%CTL_HELPMENU%</property>
|
||||
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.notimpl</property>
|
||||
<property name="label" translatable="yes">Task Manager Help Topics</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.about</property>
|
||||
<property name="label" translatable="yes">About Task Manager</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkNotebook" id="main-notebook">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mb-md" />
|
||||
<class name="wintc-ml-md" />
|
||||
<class name="wintc-mr-md" />
|
||||
<class name="wintc-mt-md" />
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox" id="box-status">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel" id="label-procs">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Processes: %d</property>
|
||||
|
||||
<style>
|
||||
<class name="wintc-mb-sm" />
|
||||
<class name="wintc-ml-sm" />
|
||||
<class name="wintc-mr-sm" />
|
||||
<class name="wintc-mt-sm" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
334
windows/taskmgr/src/window.c
Normal file
334
windows/taskmgr/src/window.c
Normal file
@@ -0,0 +1,334 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc/comgtk.h>
|
||||
#include <wintc/shell.h>
|
||||
#include <wintc/shellext.h>
|
||||
#include <wintc/shlang.h>
|
||||
|
||||
#include "application.h"
|
||||
#include "intapi.h"
|
||||
#include "pageproc.h"
|
||||
#include "window.h"
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_taskmgr_window_ishext_ui_host_interface_init(
|
||||
WinTCIShextUIHostInterface* iface
|
||||
);
|
||||
|
||||
static void wintc_taskmgr_window_constructed(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_taskmgr_window_dispose(
|
||||
GObject* object
|
||||
);
|
||||
|
||||
static GtkWidget* wintc_taskmgr_window_get_ext_widget(
|
||||
WinTCIShextUIHost* host,
|
||||
guint ext_id,
|
||||
GType expected_type,
|
||||
gpointer ctx
|
||||
);
|
||||
|
||||
static void action_notimpl(
|
||||
GSimpleAction* action,
|
||||
GVariant* parameter,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
static void action_about(
|
||||
GSimpleAction* action,
|
||||
GVariant* parameter,
|
||||
gpointer user_data
|
||||
);
|
||||
static void action_exit(
|
||||
GSimpleAction* action,
|
||||
GVariant* parameter,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// STATIC DATA
|
||||
//
|
||||
static GActionEntry s_window_actions[] = {
|
||||
{
|
||||
.name = "notimpl",
|
||||
.activate = action_notimpl,
|
||||
.parameter_type = NULL,
|
||||
.state = NULL,
|
||||
.change_state = NULL
|
||||
},
|
||||
{
|
||||
.name = "about",
|
||||
.activate = action_about,
|
||||
.parameter_type = NULL,
|
||||
.state = NULL,
|
||||
.change_state = NULL
|
||||
},
|
||||
{
|
||||
.name = "exit",
|
||||
.activate = action_exit,
|
||||
.parameter_type = NULL,
|
||||
.state = NULL,
|
||||
.change_state = NULL
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
struct _WinTCTaskmgrWindowClass
|
||||
{
|
||||
GtkApplicationWindowClass __parent__;
|
||||
};
|
||||
|
||||
struct _WinTCTaskmgrWindow
|
||||
{
|
||||
GtkApplicationWindow __parent__;
|
||||
|
||||
// UI
|
||||
//
|
||||
GtkWidget* notebook_main;
|
||||
GtkWidget* menubar_main;
|
||||
|
||||
WinTCShextUIController* uictl_processes;
|
||||
};
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITION & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE_WITH_CODE(
|
||||
WinTCTaskmgrWindow,
|
||||
wintc_taskmgr_window,
|
||||
GTK_TYPE_APPLICATION_WINDOW,
|
||||
G_IMPLEMENT_INTERFACE(
|
||||
WINTC_TYPE_ISHEXT_UI_HOST,
|
||||
wintc_taskmgr_window_ishext_ui_host_interface_init
|
||||
)
|
||||
)
|
||||
|
||||
static void wintc_taskmgr_window_class_init(
|
||||
WinTCTaskmgrWindowClass* klass
|
||||
)
|
||||
{
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->constructed = wintc_taskmgr_window_constructed;
|
||||
object_class->dispose = wintc_taskmgr_window_dispose;
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_window_init(
|
||||
WinTCTaskmgrWindow* self
|
||||
)
|
||||
{
|
||||
GtkBuilder* builder;
|
||||
GtkWidget* main_box = NULL;
|
||||
|
||||
// Define GActions
|
||||
//
|
||||
g_action_map_add_action_entries(
|
||||
G_ACTION_MAP(self),
|
||||
s_window_actions,
|
||||
G_N_ELEMENTS(s_window_actions),
|
||||
self
|
||||
);
|
||||
|
||||
// Initialize UI
|
||||
//
|
||||
builder =
|
||||
gtk_builder_new_from_resource(
|
||||
"/uk/oddmatics/wintc/taskmgr/taskmgr.ui"
|
||||
);
|
||||
|
||||
wintc_lc_builder_preprocess_widget_text(builder);
|
||||
|
||||
wintc_builder_get_objects(
|
||||
builder,
|
||||
"main-box", &main_box,
|
||||
"main-menubar", &(self->menubar_main),
|
||||
"main-notebook", &(self->notebook_main),
|
||||
NULL
|
||||
);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(self), main_box);
|
||||
|
||||
gtk_widget_set_size_request(
|
||||
GTK_WIDGET(self),
|
||||
396,
|
||||
420
|
||||
);
|
||||
|
||||
g_object_unref(builder);
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_window_ishext_ui_host_interface_init(
|
||||
WinTCIShextUIHostInterface* iface
|
||||
)
|
||||
{
|
||||
iface->get_ext_widget = wintc_taskmgr_window_get_ext_widget;
|
||||
}
|
||||
|
||||
//
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_taskmgr_window_constructed(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrWindow* wnd = WINTC_TASKMGR_WINDOW(object);
|
||||
|
||||
// Init pages
|
||||
//
|
||||
wnd->uictl_processes =
|
||||
wintc_shext_ui_controller_new_from_type(
|
||||
WINTC_TYPE_TASKMGR_PAGE_PROCESSES,
|
||||
WINTC_ISHEXT_UI_HOST(object)
|
||||
);
|
||||
|
||||
(G_OBJECT_CLASS(wintc_taskmgr_window_parent_class))
|
||||
->constructed(object);
|
||||
}
|
||||
|
||||
static void wintc_taskmgr_window_dispose(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrWindow* wnd = WINTC_TASKMGR_WINDOW(object);
|
||||
|
||||
g_clear_object(&(wnd->uictl_processes));
|
||||
|
||||
(G_OBJECT_CLASS(wintc_taskmgr_window_parent_class))
|
||||
->dispose(object);
|
||||
}
|
||||
|
||||
//
|
||||
// INTERFACE METHODS (WinTCIShextUIHost)
|
||||
//
|
||||
static GtkWidget* wintc_taskmgr_window_get_ext_widget(
|
||||
WinTCIShextUIHost* host,
|
||||
guint ext_id,
|
||||
GType expected_type,
|
||||
gpointer ctx
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrWindow* wnd = WINTC_TASKMGR_WINDOW(host);
|
||||
|
||||
switch (ext_id)
|
||||
{
|
||||
case WINTC_TASKMGR_HOSTEXT_PAGE:
|
||||
if (!GTK_IS_BUILDER(ctx))
|
||||
{
|
||||
g_critical(
|
||||
"%s",
|
||||
"ext_widget: Expected a GtkBuilder!"
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Try to pull the necessary widgets
|
||||
//
|
||||
GtkWidget* label_title = NULL;
|
||||
GtkWidget* widget_page = NULL;
|
||||
|
||||
wintc_builder_get_objects(
|
||||
GTK_BUILDER(ctx),
|
||||
"label-title", &label_title,
|
||||
"page", &widget_page,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!label_title || !widget_page)
|
||||
{
|
||||
g_critical("%s", "ext_widget: Missing required page widgets.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (G_OBJECT_TYPE(widget_page) != expected_type)
|
||||
{
|
||||
g_critical("%s", "ext_widget: Expected type mismatch.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_notebook_append_page(
|
||||
GTK_NOTEBOOK(wnd->notebook_main),
|
||||
widget_page,
|
||||
label_title
|
||||
);
|
||||
|
||||
return widget_page;
|
||||
|
||||
default:
|
||||
g_critical("ext_widget: %u", ext_id);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GtkWidget* wintc_taskmgr_window_new(
|
||||
WinTCTaskmgrApplication* app
|
||||
)
|
||||
{
|
||||
return GTK_WIDGET(
|
||||
g_object_new(
|
||||
WINTC_TYPE_TASKMGR_WINDOW,
|
||||
"application", GTK_APPLICATION(app),
|
||||
"title", "Windows Task Manager",
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void action_notimpl(
|
||||
WINTC_UNUSED(GSimpleAction* action),
|
||||
WINTC_UNUSED(GVariant* parameter),
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrWindow* wnd = WINTC_TASKMGR_WINDOW(user_data);
|
||||
|
||||
GError* error = NULL;
|
||||
|
||||
g_set_error(
|
||||
&error,
|
||||
WINTC_GENERAL_ERROR,
|
||||
WINTC_GENERAL_ERROR_NOTIMPL,
|
||||
"%s",
|
||||
"Action not implemented."
|
||||
);
|
||||
|
||||
wintc_nice_error_and_clear(&error, GTK_WINDOW(wnd));
|
||||
}
|
||||
|
||||
static void action_about(
|
||||
WINTC_UNUSED(GSimpleAction* action),
|
||||
WINTC_UNUSED(GVariant* parameter),
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrWindow* wnd = WINTC_TASKMGR_WINDOW(user_data);
|
||||
|
||||
wintc_sh_about(
|
||||
GTK_WINDOW(wnd),
|
||||
"Windows Task Manager",
|
||||
NULL,
|
||||
"taskmgr"
|
||||
);
|
||||
}
|
||||
|
||||
static void action_exit(
|
||||
WINTC_UNUSED(GSimpleAction* action),
|
||||
WINTC_UNUSED(GVariant* parameter),
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCTaskmgrWindow* wnd = WINTC_TASKMGR_WINDOW(user_data);
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(wnd));
|
||||
}
|
||||
31
windows/taskmgr/src/window.h
Normal file
31
windows/taskmgr/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 _WinTCTaskmgrWindowClass WinTCTaskmgrWindowClass;
|
||||
typedef struct _WinTCTaskmgrWindow WinTCTaskmgrWindow;
|
||||
|
||||
#define WINTC_TYPE_TASKMGR_WINDOW (wintc_taskmgr_window_get_type())
|
||||
#define WINTC_TASKMGR_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_TASKMGR_WINDOW, WinTCTaskmgrWindow))
|
||||
#define WINTC_TASKMGR_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_TASKMGR_WINDOW, WinTCTaskmgrWindowClass))
|
||||
#define IS_WINTC_TASKMGR_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_TASKMGR_WINDOW))
|
||||
#define IS_WINTC_TASKMGR_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_TASKMGR_WINDOW))
|
||||
#define WINTC_TASKMGR_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_TASKMGR_WINDOW, WinTCTaskmgrWindowClass))
|
||||
|
||||
GType wintc_taskmgr_window_get_type(void) G_GNUC_CONST;
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GtkWidget* wintc_taskmgr_window_new(
|
||||
WinTCTaskmgrApplication* app
|
||||
);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user