aplicando formato allman
parent
def492f92d
commit
f2a13175e5
1797
src/eggdesktopfile.c
1797
src/eggdesktopfile.c
File diff suppressed because it is too large
Load Diff
|
@ -26,25 +26,26 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct EggDesktopFile EggDesktopFile;
|
typedef struct EggDesktopFile EggDesktopFile;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
|
{
|
||||||
|
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
|
||||||
|
|
||||||
EGG_DESKTOP_FILE_TYPE_APPLICATION,
|
EGG_DESKTOP_FILE_TYPE_APPLICATION,
|
||||||
EGG_DESKTOP_FILE_TYPE_LINK,
|
EGG_DESKTOP_FILE_TYPE_LINK,
|
||||||
EGG_DESKTOP_FILE_TYPE_DIRECTORY
|
EGG_DESKTOP_FILE_TYPE_DIRECTORY
|
||||||
} EggDesktopFileType;
|
} EggDesktopFileType;
|
||||||
|
|
||||||
EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path,
|
EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path,
|
EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path,
|
||||||
GError **error);
|
GError **error);
|
||||||
EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path,
|
EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path,
|
||||||
const char **search_dirs,
|
const char **search_dirs,
|
||||||
GError **error);
|
GError **error);
|
||||||
EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
|
EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
|
||||||
const char *source,
|
const char *source,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void egg_desktop_file_free (EggDesktopFile *desktop_file);
|
void egg_desktop_file_free (EggDesktopFile *desktop_file);
|
||||||
|
|
||||||
|
@ -56,35 +57,36 @@ const char *egg_desktop_file_get_name (EggDesktopFile *deskto
|
||||||
const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file);
|
const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file);
|
||||||
|
|
||||||
gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
|
gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
|
||||||
const char *desktop_environment);
|
const char *desktop_environment);
|
||||||
|
|
||||||
gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file);
|
gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file);
|
||||||
gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file);
|
gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file);
|
||||||
gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
|
gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
|
||||||
|
|
||||||
char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
|
char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
|
||||||
GSList *documents,
|
GSList *documents,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
|
gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
|
||||||
GSList *documents,
|
GSList *documents,
|
||||||
GError **error,
|
GError **error,
|
||||||
...) G_GNUC_NULL_TERMINATED;
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
|
{
|
||||||
EGG_DESKTOP_FILE_LAUNCH_PUTENV,
|
EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_SCREEN,
|
EGG_DESKTOP_FILE_LAUNCH_PUTENV,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
|
EGG_DESKTOP_FILE_LAUNCH_SCREEN,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
|
EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_TIME,
|
EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_FLAGS,
|
EGG_DESKTOP_FILE_LAUNCH_TIME,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
|
EGG_DESKTOP_FILE_LAUNCH_FLAGS,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
|
EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
|
EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
|
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
|
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
|
||||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
|
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
|
||||||
|
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
|
||||||
} EggDesktopFileLaunchOption;
|
} EggDesktopFileLaunchOption;
|
||||||
|
|
||||||
/* Standard Keys */
|
/* Standard Keys */
|
||||||
|
@ -112,30 +114,30 @@ typedef enum {
|
||||||
|
|
||||||
/* Accessors */
|
/* Accessors */
|
||||||
gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
|
gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
GError **error);
|
GError **error);
|
||||||
char *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
|
char *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
GError **error) G_GNUC_MALLOC;
|
GError **error) G_GNUC_MALLOC;
|
||||||
char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
|
char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *locale,
|
const char *locale,
|
||||||
GError **error) G_GNUC_MALLOC;
|
GError **error) G_GNUC_MALLOC;
|
||||||
gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
|
gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
GError **error);
|
GError **error);
|
||||||
double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
|
double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
GError **error);
|
GError **error);
|
||||||
char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
|
char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
gsize *length,
|
gsize *length,
|
||||||
GError **error) G_GNUC_MALLOC;
|
GError **error) G_GNUC_MALLOC;
|
||||||
char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
|
char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *locale,
|
const char *locale,
|
||||||
gsize *length,
|
gsize *length,
|
||||||
GError **error) G_GNUC_MALLOC;
|
GError **error) G_GNUC_MALLOC;
|
||||||
|
|
||||||
|
|
||||||
/* Errors */
|
/* Errors */
|
||||||
|
@ -143,10 +145,11 @@ char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file
|
||||||
|
|
||||||
GQuark egg_desktop_file_error_quark (void);
|
GQuark egg_desktop_file_error_quark (void);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
EGG_DESKTOP_FILE_ERROR_INVALID,
|
{
|
||||||
EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
|
EGG_DESKTOP_FILE_ERROR_INVALID,
|
||||||
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
|
EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
|
||||||
|
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
|
||||||
} EggDesktopFileError;
|
} EggDesktopFileError;
|
||||||
|
|
||||||
/* Global application desktop file */
|
/* Global application desktop file */
|
||||||
|
|
|
@ -60,7 +60,8 @@ egg_shell (const char *shell)
|
||||||
#ifndef G_OS_WIN32
|
#ifndef G_OS_WIN32
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
int i;
|
int i;
|
||||||
static const char shells [][14] = {
|
static const char shells [][14] =
|
||||||
|
{
|
||||||
/* Note that on some systems shells can also
|
/* Note that on some systems shells can also
|
||||||
* be installed in /usr/bin */
|
* be installed in /usr/bin */
|
||||||
"/bin/bash", "/usr/bin/bash",
|
"/bin/bash", "/usr/bin/bash",
|
||||||
|
@ -71,23 +72,30 @@ egg_shell (const char *shell)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (geteuid () == getuid () &&
|
if (geteuid () == getuid () &&
|
||||||
getegid () == getgid ()) {
|
getegid () == getgid ())
|
||||||
|
{
|
||||||
/* only in non-setuid */
|
/* only in non-setuid */
|
||||||
if (shell != NULL) {
|
if (shell != NULL)
|
||||||
if (access (shell, X_OK) == 0) {
|
{
|
||||||
|
if (access (shell, X_OK) == 0)
|
||||||
|
{
|
||||||
return g_strdup (shell);
|
return g_strdup (shell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pw = getpwuid(getuid());
|
pw = getpwuid(getuid());
|
||||||
if (pw && pw->pw_shell) {
|
if (pw && pw->pw_shell)
|
||||||
if (access (pw->pw_shell, X_OK) == 0) {
|
{
|
||||||
|
if (access (pw->pw_shell, X_OK) == 0)
|
||||||
|
{
|
||||||
return g_strdup (pw->pw_shell);
|
return g_strdup (pw->pw_shell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i != G_N_ELEMENTS (shells); i++) {
|
for (i = 0; i != G_N_ELEMENTS (shells); i++)
|
||||||
if (access (shells [i], X_OK) == 0) {
|
{
|
||||||
|
if (access (shells [i], X_OK) == 0)
|
||||||
|
{
|
||||||
return g_strdup (shells[i]);
|
return g_strdup (shells[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,26 +51,27 @@
|
||||||
typedef struct _EggSMClientOSX EggSMClientOSX;
|
typedef struct _EggSMClientOSX EggSMClientOSX;
|
||||||
typedef struct _EggSMClientOSXClass EggSMClientOSXClass;
|
typedef struct _EggSMClientOSXClass EggSMClientOSXClass;
|
||||||
|
|
||||||
struct _EggSMClientOSX {
|
struct _EggSMClientOSX
|
||||||
EggSMClient parent;
|
{
|
||||||
|
EggSMClient parent;
|
||||||
|
|
||||||
AppleEvent quit_event, quit_reply;
|
AppleEvent quit_event, quit_reply;
|
||||||
gboolean quit_requested, quitting;
|
gboolean quit_requested, quitting;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EggSMClientOSXClass
|
struct _EggSMClientOSXClass
|
||||||
{
|
{
|
||||||
EggSMClientClass parent_class;
|
EggSMClientClass parent_class;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sm_client_osx_startup (EggSMClient *client,
|
static void sm_client_osx_startup (EggSMClient *client,
|
||||||
const char *client_id);
|
const char *client_id);
|
||||||
static void sm_client_osx_will_quit (EggSMClient *client,
|
static void sm_client_osx_will_quit (EggSMClient *client,
|
||||||
gboolean will_quit);
|
gboolean will_quit);
|
||||||
static gboolean sm_client_osx_end_session (EggSMClient *client,
|
static gboolean sm_client_osx_end_session (EggSMClient *client,
|
||||||
EggSMClientEndStyle style,
|
EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation);
|
gboolean request_confirmation);
|
||||||
|
|
||||||
static pascal OSErr quit_requested (const AppleEvent *, AppleEvent *, long);
|
static pascal OSErr quit_requested (const AppleEvent *, AppleEvent *, long);
|
||||||
|
|
||||||
|
@ -79,157 +80,157 @@ G_DEFINE_TYPE (EggSMClientOSX, egg_sm_client_osx, EGG_TYPE_SM_CLIENT)
|
||||||
static void
|
static void
|
||||||
egg_sm_client_osx_init (EggSMClientOSX *osx)
|
egg_sm_client_osx_init (EggSMClientOSX *osx)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
egg_sm_client_osx_class_init (EggSMClientOSXClass *klass)
|
egg_sm_client_osx_class_init (EggSMClientOSXClass *klass)
|
||||||
{
|
{
|
||||||
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
|
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
|
||||||
|
|
||||||
sm_client_class->startup = sm_client_osx_startup;
|
sm_client_class->startup = sm_client_osx_startup;
|
||||||
sm_client_class->will_quit = sm_client_osx_will_quit;
|
sm_client_class->will_quit = sm_client_osx_will_quit;
|
||||||
sm_client_class->end_session = sm_client_osx_end_session;
|
sm_client_class->end_session = sm_client_osx_end_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
EggSMClient *
|
EggSMClient *
|
||||||
egg_sm_client_osx_new (void)
|
egg_sm_client_osx_new (void)
|
||||||
{
|
{
|
||||||
return g_object_new (EGG_TYPE_SM_CLIENT_OSX, NULL);
|
return g_object_new (EGG_TYPE_SM_CLIENT_OSX, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_client_osx_startup (EggSMClient *client,
|
sm_client_osx_startup (EggSMClient *client,
|
||||||
const char *client_id)
|
const char *client_id)
|
||||||
{
|
{
|
||||||
AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
|
AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
|
||||||
NewAEEventHandlerUPP (quit_requested),
|
NewAEEventHandlerUPP (quit_requested),
|
||||||
(long)GPOINTER_TO_SIZE (client), false);
|
(long)GPOINTER_TO_SIZE (client), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
idle_quit_requested (gpointer client)
|
idle_quit_requested (gpointer client)
|
||||||
{
|
{
|
||||||
egg_sm_client_quit_requested (client);
|
egg_sm_client_quit_requested (client);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pascal OSErr
|
static pascal OSErr
|
||||||
quit_requested (const AppleEvent *aevt, AppleEvent *reply, long refcon)
|
quit_requested (const AppleEvent *aevt, AppleEvent *reply, long refcon)
|
||||||
{
|
{
|
||||||
EggSMClient *client = GSIZE_TO_POINTER ((gsize)refcon);
|
EggSMClient *client = GSIZE_TO_POINTER ((gsize)refcon);
|
||||||
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
|
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
|
||||||
|
|
||||||
g_return_val_if_fail (!osx->quit_requested, userCanceledErr);
|
g_return_val_if_fail (!osx->quit_requested, userCanceledErr);
|
||||||
|
|
||||||
/* FIXME AEInteractWithUser? */
|
|
||||||
|
|
||||||
osx->quit_requested = TRUE;
|
/* FIXME AEInteractWithUser? */
|
||||||
AEDuplicateDesc (aevt, &osx->quit_event);
|
|
||||||
AEDuplicateDesc (reply, &osx->quit_reply);
|
|
||||||
AESuspendTheCurrentEvent (aevt);
|
|
||||||
|
|
||||||
/* Don't emit the "quit_requested" signal immediately, since we're
|
osx->quit_requested = TRUE;
|
||||||
* called from a weird point in the guts of gdkeventloop-quartz.c
|
AEDuplicateDesc (aevt, &osx->quit_event);
|
||||||
*/
|
AEDuplicateDesc (reply, &osx->quit_reply);
|
||||||
g_idle_add (idle_quit_requested, client);
|
AESuspendTheCurrentEvent (aevt);
|
||||||
return noErr;
|
|
||||||
|
/* Don't emit the "quit_requested" signal immediately, since we're
|
||||||
|
* called from a weird point in the guts of gdkeventloop-quartz.c
|
||||||
|
*/
|
||||||
|
g_idle_add (idle_quit_requested, client);
|
||||||
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pascal OSErr
|
static pascal OSErr
|
||||||
quit_requested_resumed (const AppleEvent *aevt, AppleEvent *reply, long refcon)
|
quit_requested_resumed (const AppleEvent *aevt, AppleEvent *reply, long refcon)
|
||||||
{
|
{
|
||||||
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
|
EggSMClientOSX *osx = GSIZE_TO_POINTER ((gsize)refcon);
|
||||||
|
|
||||||
osx->quit_requested = FALSE;
|
osx->quit_requested = FALSE;
|
||||||
return osx->quitting ? noErr : userCanceledErr;
|
return osx->quitting ? noErr : userCanceledErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
idle_will_quit (gpointer client)
|
idle_will_quit (gpointer client)
|
||||||
{
|
{
|
||||||
EggSMClientOSX *osx = (EggSMClientOSX *)client;
|
EggSMClientOSX *osx = (EggSMClientOSX *)client;
|
||||||
|
|
||||||
/* Resume the event with a new handler that will return a value to
|
/* Resume the event with a new handler that will return a value to
|
||||||
* the system.
|
* the system.
|
||||||
*/
|
*/
|
||||||
AEResumeTheCurrentEvent (&osx->quit_event, &osx->quit_reply,
|
AEResumeTheCurrentEvent (&osx->quit_event, &osx->quit_reply,
|
||||||
NewAEEventHandlerUPP (quit_requested_resumed),
|
NewAEEventHandlerUPP (quit_requested_resumed),
|
||||||
(long)GPOINTER_TO_SIZE (client));
|
(long)GPOINTER_TO_SIZE (client));
|
||||||
AEDisposeDesc (&osx->quit_event);
|
AEDisposeDesc (&osx->quit_event);
|
||||||
AEDisposeDesc (&osx->quit_reply);
|
AEDisposeDesc (&osx->quit_reply);
|
||||||
|
|
||||||
if (osx->quitting)
|
if (osx->quitting)
|
||||||
egg_sm_client_quit (client);
|
egg_sm_client_quit (client);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_client_osx_will_quit (EggSMClient *client,
|
sm_client_osx_will_quit (EggSMClient *client,
|
||||||
gboolean will_quit)
|
gboolean will_quit)
|
||||||
{
|
{
|
||||||
EggSMClientOSX *osx = (EggSMClientOSX *)client;
|
EggSMClientOSX *osx = (EggSMClientOSX *)client;
|
||||||
|
|
||||||
g_return_if_fail (osx->quit_requested);
|
g_return_if_fail (osx->quit_requested);
|
||||||
|
|
||||||
osx->quitting = will_quit;
|
osx->quitting = will_quit;
|
||||||
|
|
||||||
/* Finish in an idle handler since the caller might have called
|
/* Finish in an idle handler since the caller might have called
|
||||||
* egg_sm_client_will_quit() from inside the "quit_requested" signal
|
* egg_sm_client_will_quit() from inside the "quit_requested" signal
|
||||||
* handler, but may not expect the "quit" signal to arrive during
|
* handler, but may not expect the "quit" signal to arrive during
|
||||||
* the _will_quit() call.
|
* the _will_quit() call.
|
||||||
*/
|
*/
|
||||||
g_idle_add (idle_will_quit, client);
|
g_idle_add (idle_will_quit, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sm_client_osx_end_session (EggSMClient *client,
|
sm_client_osx_end_session (EggSMClient *client,
|
||||||
EggSMClientEndStyle style,
|
EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation)
|
gboolean request_confirmation)
|
||||||
{
|
{
|
||||||
static const ProcessSerialNumber loginwindow_psn = { 0, kSystemProcess };
|
static const ProcessSerialNumber loginwindow_psn = { 0, kSystemProcess };
|
||||||
AppleEvent event = { typeNull, NULL }, reply = { typeNull, NULL };
|
AppleEvent event = { typeNull, NULL }, reply = { typeNull, NULL };
|
||||||
AEAddressDesc target;
|
AEAddressDesc target;
|
||||||
AEEventID id;
|
AEEventID id;
|
||||||
OSErr err;
|
OSErr err;
|
||||||
|
|
||||||
switch (style)
|
switch (style)
|
||||||
{
|
{
|
||||||
case EGG_SM_CLIENT_END_SESSION_DEFAULT:
|
case EGG_SM_CLIENT_END_SESSION_DEFAULT:
|
||||||
case EGG_SM_CLIENT_LOGOUT:
|
case EGG_SM_CLIENT_LOGOUT:
|
||||||
id = request_confirmation ? kAELogOut : kAEReallyLogOut;
|
id = request_confirmation ? kAELogOut : kAEReallyLogOut;
|
||||||
break;
|
break;
|
||||||
case EGG_SM_CLIENT_REBOOT:
|
case EGG_SM_CLIENT_REBOOT:
|
||||||
id = request_confirmation ? kAEShowRestartDialog : kAERestart;
|
id = request_confirmation ? kAEShowRestartDialog : kAERestart;
|
||||||
break;
|
break;
|
||||||
case EGG_SM_CLIENT_SHUTDOWN:
|
case EGG_SM_CLIENT_SHUTDOWN:
|
||||||
id = request_confirmation ? kAEShowShutdownDialog : kAEShutDown;
|
id = request_confirmation ? kAEShowShutdownDialog : kAEShutDown;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = AECreateDesc (typeProcessSerialNumber, &loginwindow_psn,
|
err = AECreateDesc (typeProcessSerialNumber, &loginwindow_psn,
|
||||||
sizeof (loginwindow_psn), &target);
|
sizeof (loginwindow_psn), &target);
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
g_warning ("Could not create descriptor for loginwindow: %d", err);
|
g_warning ("Could not create descriptor for loginwindow: %d", err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = AECreateAppleEvent (kCoreEventClass, id, &target,
|
err = AECreateAppleEvent (kCoreEventClass, id, &target,
|
||||||
kAutoGenerateReturnID, kAnyTransactionID,
|
kAutoGenerateReturnID, kAnyTransactionID,
|
||||||
&event);
|
&event);
|
||||||
AEDisposeDesc (&target);
|
AEDisposeDesc (&target);
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
g_warning ("Could not create logout AppleEvent: %d", err);
|
g_warning ("Could not create logout AppleEvent: %d", err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = AESend (&event, &reply, kAENoReply, kAENormalPriority,
|
err = AESend (&event, &reply, kAENoReply, kAENormalPriority,
|
||||||
kAEDefaultTimeout, NULL, NULL);
|
kAEDefaultTimeout, NULL, NULL);
|
||||||
AEDisposeDesc (&event);
|
AEDisposeDesc (&event);
|
||||||
if (err == noErr)
|
if (err == noErr)
|
||||||
AEDisposeDesc (&reply);
|
AEDisposeDesc (&reply);
|
||||||
|
|
||||||
return err == noErr;
|
return err == noErr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,31 +66,32 @@
|
||||||
typedef struct _EggSMClientWin32 EggSMClientWin32;
|
typedef struct _EggSMClientWin32 EggSMClientWin32;
|
||||||
typedef struct _EggSMClientWin32Class EggSMClientWin32Class;
|
typedef struct _EggSMClientWin32Class EggSMClientWin32Class;
|
||||||
|
|
||||||
struct _EggSMClientWin32 {
|
struct _EggSMClientWin32
|
||||||
EggSMClient parent;
|
{
|
||||||
|
EggSMClient parent;
|
||||||
|
|
||||||
HANDLE message_event, response_event;
|
HANDLE message_event, response_event;
|
||||||
|
|
||||||
volatile GSourceFunc event;
|
volatile GSourceFunc event;
|
||||||
volatile gboolean will_quit;
|
volatile gboolean will_quit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EggSMClientWin32Class
|
struct _EggSMClientWin32Class
|
||||||
{
|
{
|
||||||
EggSMClientClass parent_class;
|
EggSMClientClass parent_class;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sm_client_win32_startup (EggSMClient *client,
|
static void sm_client_win32_startup (EggSMClient *client,
|
||||||
const char *client_id);
|
const char *client_id);
|
||||||
static void sm_client_win32_will_quit (EggSMClient *client,
|
static void sm_client_win32_will_quit (EggSMClient *client,
|
||||||
gboolean will_quit);
|
gboolean will_quit);
|
||||||
static gboolean sm_client_win32_end_session (EggSMClient *client,
|
static gboolean sm_client_win32_end_session (EggSMClient *client,
|
||||||
EggSMClientEndStyle style,
|
EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation);
|
gboolean request_confirmation);
|
||||||
|
|
||||||
static GSource *g_win32_handle_source_add (HANDLE handle, GSourceFunc callback,
|
static GSource *g_win32_handle_source_add (HANDLE handle, GSourceFunc callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
static gboolean got_message (gpointer user_data);
|
static gboolean got_message (gpointer user_data);
|
||||||
static void sm_client_thread (gpointer data);
|
static void sm_client_thread (gpointer data);
|
||||||
|
|
||||||
|
@ -99,79 +100,79 @@ G_DEFINE_TYPE (EggSMClientWin32, egg_sm_client_win32, EGG_TYPE_SM_CLIENT)
|
||||||
static void
|
static void
|
||||||
egg_sm_client_win32_init (EggSMClientWin32 *win32)
|
egg_sm_client_win32_init (EggSMClientWin32 *win32)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
egg_sm_client_win32_class_init (EggSMClientWin32Class *klass)
|
egg_sm_client_win32_class_init (EggSMClientWin32Class *klass)
|
||||||
{
|
{
|
||||||
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
|
EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
|
||||||
|
|
||||||
sm_client_class->startup = sm_client_win32_startup;
|
sm_client_class->startup = sm_client_win32_startup;
|
||||||
sm_client_class->will_quit = sm_client_win32_will_quit;
|
sm_client_class->will_quit = sm_client_win32_will_quit;
|
||||||
sm_client_class->end_session = sm_client_win32_end_session;
|
sm_client_class->end_session = sm_client_win32_end_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
EggSMClient *
|
EggSMClient *
|
||||||
egg_sm_client_win32_new (void)
|
egg_sm_client_win32_new (void)
|
||||||
{
|
{
|
||||||
return g_object_new (EGG_TYPE_SM_CLIENT_WIN32, NULL);
|
return g_object_new (EGG_TYPE_SM_CLIENT_WIN32, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_client_win32_startup (EggSMClient *client,
|
sm_client_win32_startup (EggSMClient *client,
|
||||||
const char *client_id)
|
const char *client_id)
|
||||||
{
|
{
|
||||||
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
|
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
|
||||||
|
|
||||||
win32->message_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
win32->message_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
win32->response_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
win32->response_event = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
g_win32_handle_source_add (win32->message_event, got_message, win32);
|
g_win32_handle_source_add (win32->message_event, got_message, win32);
|
||||||
_beginthread (sm_client_thread, 0, client);
|
_beginthread (sm_client_thread, 0, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_client_win32_will_quit (EggSMClient *client,
|
sm_client_win32_will_quit (EggSMClient *client,
|
||||||
gboolean will_quit)
|
gboolean will_quit)
|
||||||
{
|
{
|
||||||
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
|
EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
|
||||||
|
|
||||||
win32->will_quit = will_quit;
|
win32->will_quit = will_quit;
|
||||||
SetEvent (win32->response_event);
|
SetEvent (win32->response_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sm_client_win32_end_session (EggSMClient *client,
|
sm_client_win32_end_session (EggSMClient *client,
|
||||||
EggSMClientEndStyle style,
|
EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation)
|
gboolean request_confirmation)
|
||||||
{
|
{
|
||||||
UINT uFlags = EWX_LOGOFF;
|
UINT uFlags = EWX_LOGOFF;
|
||||||
|
|
||||||
switch (style)
|
switch (style)
|
||||||
{
|
{
|
||||||
case EGG_SM_CLIENT_END_SESSION_DEFAULT:
|
case EGG_SM_CLIENT_END_SESSION_DEFAULT:
|
||||||
case EGG_SM_CLIENT_LOGOUT:
|
case EGG_SM_CLIENT_LOGOUT:
|
||||||
uFlags = EWX_LOGOFF;
|
uFlags = EWX_LOGOFF;
|
||||||
break;
|
break;
|
||||||
case EGG_SM_CLIENT_REBOOT:
|
case EGG_SM_CLIENT_REBOOT:
|
||||||
uFlags = EWX_REBOOT;
|
uFlags = EWX_REBOOT;
|
||||||
break;
|
break;
|
||||||
case EGG_SM_CLIENT_SHUTDOWN:
|
case EGG_SM_CLIENT_SHUTDOWN:
|
||||||
uFlags = EWX_POWEROFF;
|
uFlags = EWX_POWEROFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There's no way to make ExitWindowsEx() show a logout dialog, so
|
/* There's no way to make ExitWindowsEx() show a logout dialog, so
|
||||||
* we ignore @request_confirmation.
|
* we ignore @request_confirmation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef SHTDN_REASON_FLAG_PLANNED
|
#ifdef SHTDN_REASON_FLAG_PLANNED
|
||||||
ExitWindowsEx (uFlags, SHTDN_REASON_FLAG_PLANNED);
|
ExitWindowsEx (uFlags, SHTDN_REASON_FLAG_PLANNED);
|
||||||
#else
|
#else
|
||||||
ExitWindowsEx (uFlags, 0);
|
ExitWindowsEx (uFlags, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,174 +181,176 @@ sm_client_win32_end_session (EggSMClient *client,
|
||||||
static gboolean
|
static gboolean
|
||||||
emit_quit_requested (gpointer smclient)
|
emit_quit_requested (gpointer smclient)
|
||||||
{
|
{
|
||||||
gdk_threads_enter ();
|
gdk_threads_enter ();
|
||||||
egg_sm_client_quit_requested (smclient);
|
egg_sm_client_quit_requested (smclient);
|
||||||
gdk_threads_leave ();
|
gdk_threads_leave ();
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
emit_quit (gpointer smclient)
|
emit_quit (gpointer smclient)
|
||||||
{
|
{
|
||||||
EggSMClientWin32 *win32 = smclient;
|
EggSMClientWin32 *win32 = smclient;
|
||||||
|
|
||||||
gdk_threads_enter ();
|
gdk_threads_enter ();
|
||||||
egg_sm_client_quit (smclient);
|
egg_sm_client_quit (smclient);
|
||||||
gdk_threads_leave ();
|
gdk_threads_leave ();
|
||||||
|
|
||||||
SetEvent (win32->response_event);
|
SetEvent (win32->response_event);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
emit_quit_cancelled (gpointer smclient)
|
emit_quit_cancelled (gpointer smclient)
|
||||||
{
|
{
|
||||||
EggSMClientWin32 *win32 = smclient;
|
EggSMClientWin32 *win32 = smclient;
|
||||||
|
|
||||||
gdk_threads_enter ();
|
gdk_threads_enter ();
|
||||||
egg_sm_client_quit_cancelled (smclient);
|
egg_sm_client_quit_cancelled (smclient);
|
||||||
gdk_threads_leave ();
|
gdk_threads_leave ();
|
||||||
|
|
||||||
SetEvent (win32->response_event);
|
SetEvent (win32->response_event);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
got_message (gpointer smclient)
|
got_message (gpointer smclient)
|
||||||
{
|
{
|
||||||
EggSMClientWin32 *win32 = smclient;
|
EggSMClientWin32 *win32 = smclient;
|
||||||
|
|
||||||
win32->event (win32);
|
win32->event (win32);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Windows HANDLE GSource */
|
/* Windows HANDLE GSource */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
GSource source;
|
{
|
||||||
GPollFD pollfd;
|
GSource source;
|
||||||
|
GPollFD pollfd;
|
||||||
} GWin32HandleSource;
|
} GWin32HandleSource;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_win32_handle_source_prepare (GSource *source, gint *timeout)
|
g_win32_handle_source_prepare (GSource *source, gint *timeout)
|
||||||
{
|
{
|
||||||
*timeout = -1;
|
*timeout = -1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_win32_handle_source_check (GSource *source)
|
g_win32_handle_source_check (GSource *source)
|
||||||
{
|
{
|
||||||
GWin32HandleSource *hsource = (GWin32HandleSource *)source;
|
GWin32HandleSource *hsource = (GWin32HandleSource *)source;
|
||||||
|
|
||||||
return hsource->pollfd.revents;
|
return hsource->pollfd.revents;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
g_win32_handle_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
|
g_win32_handle_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
|
||||||
{
|
{
|
||||||
return (*callback) (user_data);
|
return (*callback) (user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_win32_handle_source_finalize (GSource *source)
|
g_win32_handle_source_finalize (GSource *source)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSourceFuncs g_win32_handle_source_funcs = {
|
GSourceFuncs g_win32_handle_source_funcs =
|
||||||
g_win32_handle_source_prepare,
|
{
|
||||||
g_win32_handle_source_check,
|
g_win32_handle_source_prepare,
|
||||||
g_win32_handle_source_dispatch,
|
g_win32_handle_source_check,
|
||||||
g_win32_handle_source_finalize
|
g_win32_handle_source_dispatch,
|
||||||
|
g_win32_handle_source_finalize
|
||||||
};
|
};
|
||||||
|
|
||||||
static GSource *
|
static GSource *
|
||||||
g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, gpointer user_data)
|
g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, gpointer user_data)
|
||||||
{
|
{
|
||||||
GWin32HandleSource *hsource;
|
GWin32HandleSource *hsource;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource));
|
source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource));
|
||||||
hsource = (GWin32HandleSource *)source;
|
hsource = (GWin32HandleSource *)source;
|
||||||
hsource->pollfd.fd = (int)handle;
|
hsource->pollfd.fd = (int)handle;
|
||||||
hsource->pollfd.events = G_IO_IN;
|
hsource->pollfd.events = G_IO_IN;
|
||||||
hsource->pollfd.revents = 0;
|
hsource->pollfd.revents = 0;
|
||||||
g_source_add_poll (source, &hsource->pollfd);
|
g_source_add_poll (source, &hsource->pollfd);
|
||||||
|
|
||||||
g_source_set_callback (source, callback, user_data, NULL);
|
g_source_set_callback (source, callback, user_data, NULL);
|
||||||
g_source_attach (source, NULL);
|
g_source_attach (source, NULL);
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* logout-listener thread */
|
/* logout-listener thread */
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
sm_client_win32_window_procedure (HWND hwnd,
|
sm_client_win32_window_procedure (HWND hwnd,
|
||||||
UINT message,
|
UINT message,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
EggSMClientWin32 *win32 =
|
EggSMClientWin32 *win32 =
|
||||||
(EggSMClientWin32 *)GetWindowLongPtr (hwnd, GWLP_USERDATA);
|
(EggSMClientWin32 *)GetWindowLongPtr (hwnd, GWLP_USERDATA);
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
|
||||||
case WM_QUERYENDSESSION:
|
|
||||||
win32->event = emit_quit_requested;
|
|
||||||
SetEvent (win32->message_event);
|
|
||||||
|
|
||||||
WaitForSingleObject (win32->response_event, INFINITE);
|
|
||||||
return win32->will_quit;
|
|
||||||
|
|
||||||
case WM_ENDSESSION:
|
|
||||||
if (wParam)
|
|
||||||
{
|
{
|
||||||
/* The session is ending */
|
case WM_QUERYENDSESSION:
|
||||||
win32->event = emit_quit;
|
win32->event = emit_quit_requested;
|
||||||
|
SetEvent (win32->message_event);
|
||||||
|
|
||||||
|
WaitForSingleObject (win32->response_event, INFINITE);
|
||||||
|
return win32->will_quit;
|
||||||
|
|
||||||
|
case WM_ENDSESSION:
|
||||||
|
if (wParam)
|
||||||
|
{
|
||||||
|
/* The session is ending */
|
||||||
|
win32->event = emit_quit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Nope, the session *isn't* ending */
|
||||||
|
win32->event = emit_quit_cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEvent (win32->message_event);
|
||||||
|
WaitForSingleObject (win32->response_event, INFINITE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DefWindowProc (hwnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Nope, the session *isn't* ending */
|
|
||||||
win32->event = emit_quit_cancelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEvent (win32->message_event);
|
|
||||||
WaitForSingleObject (win32->response_event, INFINITE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return DefWindowProc (hwnd, message, wParam, lParam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_client_thread (gpointer smclient)
|
sm_client_thread (gpointer smclient)
|
||||||
{
|
{
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
WNDCLASSEXW wcl;
|
WNDCLASSEXW wcl;
|
||||||
ATOM klass;
|
ATOM klass;
|
||||||
HWND window;
|
HWND window;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
instance = GetModuleHandle (NULL);
|
instance = GetModuleHandle (NULL);
|
||||||
|
|
||||||
memset (&wcl, 0, sizeof (WNDCLASSEX));
|
memset (&wcl, 0, sizeof (WNDCLASSEX));
|
||||||
wcl.cbSize = sizeof (WNDCLASSEX);
|
wcl.cbSize = sizeof (WNDCLASSEX);
|
||||||
wcl.lpfnWndProc = sm_client_win32_window_procedure;
|
wcl.lpfnWndProc = sm_client_win32_window_procedure;
|
||||||
wcl.hInstance = instance;
|
wcl.hInstance = instance;
|
||||||
wcl.lpszClassName = L"EggSmClientWindow";
|
wcl.lpszClassName = L"EggSmClientWindow";
|
||||||
klass = RegisterClassEx (&wcl);
|
klass = RegisterClassEx (&wcl);
|
||||||
|
|
||||||
window = CreateWindowEx (0, MAKEINTRESOURCE (klass),
|
window = CreateWindowEx (0, MAKEINTRESOURCE (klass),
|
||||||
L"EggSmClientWindow", 0,
|
L"EggSmClientWindow", 0,
|
||||||
10, 10, 50, 50, GetDesktopWindow (),
|
10, 10, 50, 50, GetDesktopWindow (),
|
||||||
NULL, instance, NULL);
|
NULL, instance, NULL);
|
||||||
SetWindowLongPtr (window, GWLP_USERDATA, (LONG_PTR)smclient);
|
SetWindowLongPtr (window, GWLP_USERDATA, (LONG_PTR)smclient);
|
||||||
|
|
||||||
/* main loop */
|
/* main loop */
|
||||||
while (GetMessage (&msg, NULL, 0, 0))
|
while (GetMessage (&msg, NULL, 0, 0))
|
||||||
DispatchMessage (&msg);
|
DispatchMessage (&msg);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,22 +26,24 @@
|
||||||
#include "eggsmclient-private.h"
|
#include "eggsmclient-private.h"
|
||||||
|
|
||||||
static void egg_sm_client_debug_handler (const char *log_domain,
|
static void egg_sm_client_debug_handler (const char *log_domain,
|
||||||
GLogLevelFlags log_level,
|
GLogLevelFlags log_level,
|
||||||
const char *message,
|
const char *message,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
enum {
|
enum
|
||||||
SAVE_STATE,
|
{
|
||||||
QUIT_REQUESTED,
|
SAVE_STATE,
|
||||||
QUIT_CANCELLED,
|
QUIT_REQUESTED,
|
||||||
QUIT,
|
QUIT_CANCELLED,
|
||||||
LAST_SIGNAL
|
QUIT,
|
||||||
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL];
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
struct _EggSMClientPrivate {
|
struct _EggSMClientPrivate
|
||||||
GKeyFile *state_file;
|
{
|
||||||
|
GKeyFile *state_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
|
#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
|
||||||
|
@ -54,125 +56,125 @@ static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL;
|
||||||
static void
|
static void
|
||||||
egg_sm_client_init (EggSMClient *client)
|
egg_sm_client_init (EggSMClient *client)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
egg_sm_client_class_init (EggSMClientClass *klass)
|
egg_sm_client_class_init (EggSMClientClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
|
g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EggSMClient::save_state:
|
* EggSMClient::save_state:
|
||||||
* @client: the client
|
* @client: the client
|
||||||
* @state_file: a #GKeyFile to save state information into
|
* @state_file: a #GKeyFile to save state information into
|
||||||
*
|
*
|
||||||
* Emitted when the session manager has requested that the
|
* Emitted when the session manager has requested that the
|
||||||
* application save information about its current state. The
|
* application save information about its current state. The
|
||||||
* application should save its state into @state_file, and then the
|
* application should save its state into @state_file, and then the
|
||||||
* session manager may then restart the application in a future
|
* session manager may then restart the application in a future
|
||||||
* session and tell it to initialize itself from that state.
|
* session and tell it to initialize itself from that state.
|
||||||
*
|
*
|
||||||
* You should not save any data into @state_file's "start group"
|
* You should not save any data into @state_file's "start group"
|
||||||
* (ie, the %NULL group). Instead, applications should save their
|
* (ie, the %NULL group). Instead, applications should save their
|
||||||
* data into groups with names that start with the application name,
|
* data into groups with names that start with the application name,
|
||||||
* and libraries that connect to this signal should save their data
|
* and libraries that connect to this signal should save their data
|
||||||
* into groups with names that start with the library name.
|
* into groups with names that start with the library name.
|
||||||
*
|
*
|
||||||
* Alternatively, rather than (or in addition to) using @state_file,
|
* Alternatively, rather than (or in addition to) using @state_file,
|
||||||
* the application can save its state by calling
|
* the application can save its state by calling
|
||||||
* egg_sm_client_set_restart_command() during the processing of this
|
* egg_sm_client_set_restart_command() during the processing of this
|
||||||
* signal (eg, to include a list of files to open).
|
* signal (eg, to include a list of files to open).
|
||||||
**/
|
**/
|
||||||
signals[SAVE_STATE] =
|
signals[SAVE_STATE] =
|
||||||
g_signal_new ("save_state",
|
g_signal_new ("save_state",
|
||||||
G_OBJECT_CLASS_TYPE (object_class),
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (EggSMClientClass, save_state),
|
G_STRUCT_OFFSET (EggSMClientClass, save_state),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__POINTER,
|
g_cclosure_marshal_VOID__POINTER,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
1, G_TYPE_POINTER);
|
1, G_TYPE_POINTER);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EggSMClient::quit_requested:
|
* EggSMClient::quit_requested:
|
||||||
* @client: the client
|
* @client: the client
|
||||||
*
|
*
|
||||||
* Emitted when the session manager requests that the application
|
* Emitted when the session manager requests that the application
|
||||||
* exit (generally because the user is logging out). The application
|
* exit (generally because the user is logging out). The application
|
||||||
* should decide whether or not it is willing to quit (perhaps after
|
* should decide whether or not it is willing to quit (perhaps after
|
||||||
* asking the user what to do with documents that have unsaved
|
* asking the user what to do with documents that have unsaved
|
||||||
* changes) and then call egg_sm_client_will_quit(), passing %TRUE
|
* changes) and then call egg_sm_client_will_quit(), passing %TRUE
|
||||||
* or %FALSE to give its answer to the session manager. (It does not
|
* or %FALSE to give its answer to the session manager. (It does not
|
||||||
* need to give an answer before returning from the signal handler;
|
* need to give an answer before returning from the signal handler;
|
||||||
* it can interact with the user asynchronously and then give its
|
* it can interact with the user asynchronously and then give its
|
||||||
* answer later on.) If the application does not connect to this
|
* answer later on.) If the application does not connect to this
|
||||||
* signal, then #EggSMClient will automatically return %TRUE on its
|
* signal, then #EggSMClient will automatically return %TRUE on its
|
||||||
* behalf.
|
* behalf.
|
||||||
*
|
*
|
||||||
* The application should not save its session state as part of
|
* The application should not save its session state as part of
|
||||||
* handling this signal; if the user has requested that the session
|
* handling this signal; if the user has requested that the session
|
||||||
* be saved when logging out, then ::save_state will be emitted
|
* be saved when logging out, then ::save_state will be emitted
|
||||||
* separately.
|
* separately.
|
||||||
*
|
*
|
||||||
* If the application agrees to quit, it should then wait for either
|
* If the application agrees to quit, it should then wait for either
|
||||||
* the ::quit_cancelled or ::quit signals to be emitted.
|
* the ::quit_cancelled or ::quit signals to be emitted.
|
||||||
**/
|
**/
|
||||||
signals[QUIT_REQUESTED] =
|
signals[QUIT_REQUESTED] =
|
||||||
g_signal_new ("quit_requested",
|
g_signal_new ("quit_requested",
|
||||||
G_OBJECT_CLASS_TYPE (object_class),
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
|
G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EggSMClient::quit_cancelled:
|
* EggSMClient::quit_cancelled:
|
||||||
* @client: the client
|
* @client: the client
|
||||||
*
|
*
|
||||||
* Emitted when the session manager decides to cancel a logout after
|
* Emitted when the session manager decides to cancel a logout after
|
||||||
* the application has already agreed to quit. After receiving this
|
* the application has already agreed to quit. After receiving this
|
||||||
* signal, the application can go back to what it was doing before
|
* signal, the application can go back to what it was doing before
|
||||||
* receiving the ::quit_requested signal.
|
* receiving the ::quit_requested signal.
|
||||||
**/
|
**/
|
||||||
signals[QUIT_CANCELLED] =
|
signals[QUIT_CANCELLED] =
|
||||||
g_signal_new ("quit_cancelled",
|
g_signal_new ("quit_cancelled",
|
||||||
G_OBJECT_CLASS_TYPE (object_class),
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
|
G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EggSMClient::quit:
|
* EggSMClient::quit:
|
||||||
* @client: the client
|
* @client: the client
|
||||||
*
|
*
|
||||||
* Emitted when the session manager wants the application to quit
|
* Emitted when the session manager wants the application to quit
|
||||||
* (generally because the user is logging out). The application
|
* (generally because the user is logging out). The application
|
||||||
* should exit as soon as possible after receiving this signal; if
|
* should exit as soon as possible after receiving this signal; if
|
||||||
* it does not, the session manager may choose to forcibly kill it.
|
* it does not, the session manager may choose to forcibly kill it.
|
||||||
*
|
*
|
||||||
* Normally a GUI application would only be sent a ::quit if it
|
* Normally a GUI application would only be sent a ::quit if it
|
||||||
* agreed to quit in response to a ::quit_requested signal. However,
|
* agreed to quit in response to a ::quit_requested signal. However,
|
||||||
* this is not guaranteed; in some situations the session manager
|
* this is not guaranteed; in some situations the session manager
|
||||||
* may decide to end the session without giving applications a
|
* may decide to end the session without giving applications a
|
||||||
* chance to object.
|
* chance to object.
|
||||||
**/
|
**/
|
||||||
signals[QUIT] =
|
signals[QUIT] =
|
||||||
g_signal_new ("quit",
|
g_signal_new ("quit",
|
||||||
G_OBJECT_CLASS_TYPE (object_class),
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (EggSMClientClass, quit),
|
G_STRUCT_OFFSET (EggSMClientClass, quit),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean sm_client_disable = FALSE;
|
static gboolean sm_client_disable = FALSE;
|
||||||
|
@ -182,29 +184,29 @@ static char *sm_config_prefix = NULL;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sm_client_post_parse_func (GOptionContext *context,
|
sm_client_post_parse_func (GOptionContext *context,
|
||||||
GOptionGroup *group,
|
GOptionGroup *group,
|
||||||
gpointer data,
|
gpointer data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
EggSMClient *client = egg_sm_client_get ();
|
EggSMClient *client = egg_sm_client_get ();
|
||||||
|
|
||||||
if (sm_client_id == NULL)
|
if (sm_client_id == NULL)
|
||||||
{
|
{
|
||||||
const gchar *desktop_autostart_id;
|
const gchar *desktop_autostart_id;
|
||||||
|
|
||||||
desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
|
desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
|
||||||
|
|
||||||
if (desktop_autostart_id != NULL)
|
if (desktop_autostart_id != NULL)
|
||||||
sm_client_id = g_strdup (desktop_autostart_id);
|
sm_client_id = g_strdup (desktop_autostart_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
|
/* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
|
||||||
* use the same client id. */
|
* use the same client id. */
|
||||||
g_unsetenv ("DESKTOP_AUTOSTART_ID");
|
g_unsetenv ("DESKTOP_AUTOSTART_ID");
|
||||||
|
|
||||||
if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
|
if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
|
||||||
EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
|
EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,43 +221,54 @@ sm_client_post_parse_func (GOptionContext *context,
|
||||||
GOptionGroup *
|
GOptionGroup *
|
||||||
egg_sm_client_get_option_group (void)
|
egg_sm_client_get_option_group (void)
|
||||||
{
|
{
|
||||||
const GOptionEntry entries[] = {
|
const GOptionEntry entries[] =
|
||||||
{ "sm-client-disable", 0, 0,
|
{
|
||||||
G_OPTION_ARG_NONE, &sm_client_disable,
|
{
|
||||||
N_("Disable connection to session manager"), NULL },
|
"sm-client-disable", 0, 0,
|
||||||
{ "sm-client-state-file", 0, 0,
|
G_OPTION_ARG_NONE, &sm_client_disable,
|
||||||
G_OPTION_ARG_FILENAME, &sm_client_state_file,
|
N_("Disable connection to session manager"), NULL
|
||||||
N_("Specify file containing saved configuration"), N_("FILE") },
|
},
|
||||||
{ "sm-client-id", 0, 0,
|
{
|
||||||
G_OPTION_ARG_STRING, &sm_client_id,
|
"sm-client-state-file", 0, 0,
|
||||||
N_("Specify session management ID"), N_("ID") },
|
G_OPTION_ARG_FILENAME, &sm_client_state_file,
|
||||||
/* MateClient compatibility option */
|
N_("Specify file containing saved configuration"), N_("FILE")
|
||||||
{ "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
|
},
|
||||||
G_OPTION_ARG_NONE, &sm_client_disable,
|
{
|
||||||
NULL, NULL },
|
"sm-client-id", 0, 0,
|
||||||
/* MateClient compatibility option. This is a dummy option that only
|
G_OPTION_ARG_STRING, &sm_client_id,
|
||||||
* exists so that sessions saved by apps with MateClient can be restored
|
N_("Specify session management ID"), N_("ID")
|
||||||
* later when they've switched to EggSMClient. See bug #575308.
|
},
|
||||||
*/
|
/* MateClient compatibility option */
|
||||||
{ "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
|
{
|
||||||
G_OPTION_ARG_STRING, &sm_config_prefix,
|
"sm-disable", 0, G_OPTION_FLAG_HIDDEN,
|
||||||
NULL, NULL },
|
G_OPTION_ARG_NONE, &sm_client_disable,
|
||||||
{ NULL }
|
NULL, NULL
|
||||||
};
|
},
|
||||||
GOptionGroup *group;
|
/* MateClient compatibility option. This is a dummy option that only
|
||||||
|
* exists so that sessions saved by apps with MateClient can be restored
|
||||||
|
* later when they've switched to EggSMClient. See bug #575308.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
"sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
|
||||||
|
G_OPTION_ARG_STRING, &sm_config_prefix,
|
||||||
|
NULL, NULL
|
||||||
|
},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
GOptionGroup *group;
|
||||||
|
|
||||||
/* Use our own debug handler for the "EggSMClient" domain. */
|
/* Use our own debug handler for the "EggSMClient" domain. */
|
||||||
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
|
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
|
||||||
egg_sm_client_debug_handler, NULL);
|
egg_sm_client_debug_handler, NULL);
|
||||||
|
|
||||||
group = g_option_group_new ("sm-client",
|
group = g_option_group_new ("sm-client",
|
||||||
_("Session management options:"),
|
_("Session management options:"),
|
||||||
_("Show session management options"),
|
_("Show session management options"),
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
g_option_group_add_entries (group, entries);
|
g_option_group_add_entries (group, entries);
|
||||||
g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
|
g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,7 +295,7 @@ egg_sm_client_get_option_group (void)
|
||||||
void
|
void
|
||||||
egg_sm_client_set_mode (EggSMClientMode mode)
|
egg_sm_client_set_mode (EggSMClientMode mode)
|
||||||
{
|
{
|
||||||
global_client_mode = mode;
|
global_client_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -296,7 +309,7 @@ egg_sm_client_set_mode (EggSMClientMode mode)
|
||||||
EggSMClientMode
|
EggSMClientMode
|
||||||
egg_sm_client_get_mode (void)
|
egg_sm_client_get_mode (void)
|
||||||
{
|
{
|
||||||
return global_client_mode;
|
return global_client_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -315,38 +328,38 @@ egg_sm_client_get_mode (void)
|
||||||
EggSMClient *
|
EggSMClient *
|
||||||
egg_sm_client_get (void)
|
egg_sm_client_get (void)
|
||||||
{
|
{
|
||||||
if (!global_client)
|
if (!global_client)
|
||||||
{
|
|
||||||
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
|
|
||||||
!sm_client_disable)
|
|
||||||
{
|
{
|
||||||
|
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
|
||||||
|
!sm_client_disable)
|
||||||
|
{
|
||||||
#if defined (GDK_WINDOWING_WIN32)
|
#if defined (GDK_WINDOWING_WIN32)
|
||||||
global_client = egg_sm_client_win32_new ();
|
global_client = egg_sm_client_win32_new ();
|
||||||
#elif defined (GDK_WINDOWING_QUARTZ)
|
#elif defined (GDK_WINDOWING_QUARTZ)
|
||||||
global_client = egg_sm_client_osx_new ();
|
global_client = egg_sm_client_osx_new ();
|
||||||
#else
|
#else
|
||||||
/* If both D-Bus and XSMP are compiled in, try XSMP first
|
/* If both D-Bus and XSMP are compiled in, try XSMP first
|
||||||
* (since it supports state saving) and fall back to D-Bus
|
* (since it supports state saving) and fall back to D-Bus
|
||||||
* if XSMP isn't available.
|
* if XSMP isn't available.
|
||||||
*/
|
*/
|
||||||
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
||||||
global_client = egg_sm_client_xsmp_new ();
|
global_client = egg_sm_client_xsmp_new ();
|
||||||
# endif
|
# endif
|
||||||
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
||||||
if (!global_client)
|
if (!global_client)
|
||||||
global_client = egg_sm_client_dbus_new ();
|
global_client = egg_sm_client_dbus_new ();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback: create a dummy client, so that callers don't have
|
||||||
|
* to worry about a %NULL return value.
|
||||||
|
*/
|
||||||
|
if (!global_client)
|
||||||
|
global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fallback: create a dummy client, so that callers don't have
|
return global_client;
|
||||||
* to worry about a %NULL return value.
|
|
||||||
*/
|
|
||||||
if (!global_client)
|
|
||||||
global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return global_client;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -363,9 +376,9 @@ egg_sm_client_get (void)
|
||||||
gboolean
|
gboolean
|
||||||
egg_sm_client_is_resumed (EggSMClient *client)
|
egg_sm_client_is_resumed (EggSMClient *client)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (client == global_client, FALSE);
|
g_return_val_if_fail (client == global_client, FALSE);
|
||||||
|
|
||||||
return sm_client_state_file != NULL;
|
return sm_client_state_file != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -390,34 +403,34 @@ egg_sm_client_is_resumed (EggSMClient *client)
|
||||||
GKeyFile *
|
GKeyFile *
|
||||||
egg_sm_client_get_state_file (EggSMClient *client)
|
egg_sm_client_get_state_file (EggSMClient *client)
|
||||||
{
|
{
|
||||||
EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
|
EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
|
||||||
char *state_file_path;
|
char *state_file_path;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (client == global_client, NULL);
|
g_return_val_if_fail (client == global_client, NULL);
|
||||||
|
|
||||||
if (!sm_client_state_file)
|
if (!sm_client_state_file)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (priv->state_file)
|
if (priv->state_file)
|
||||||
return priv->state_file;
|
return priv->state_file;
|
||||||
|
|
||||||
if (!strncmp (sm_client_state_file, "file://", 7))
|
if (!strncmp (sm_client_state_file, "file://", 7))
|
||||||
state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
|
state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
|
||||||
else
|
else
|
||||||
state_file_path = g_strdup (sm_client_state_file);
|
state_file_path = g_strdup (sm_client_state_file);
|
||||||
|
|
||||||
priv->state_file = g_key_file_new ();
|
priv->state_file = g_key_file_new ();
|
||||||
if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
|
if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
|
||||||
{
|
{
|
||||||
g_warning ("Could not load SM state file '%s': %s",
|
g_warning ("Could not load SM state file '%s': %s",
|
||||||
sm_client_state_file, err->message);
|
sm_client_state_file, err->message);
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
g_key_file_free (priv->state_file);
|
g_key_file_free (priv->state_file);
|
||||||
priv->state_file = NULL;
|
priv->state_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (state_file_path);
|
g_free (state_file_path);
|
||||||
return priv->state_file;
|
return priv->state_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -435,13 +448,13 @@ egg_sm_client_get_state_file (EggSMClient *client)
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
egg_sm_client_set_restart_command (EggSMClient *client,
|
egg_sm_client_set_restart_command (EggSMClient *client,
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv)
|
const char **argv)
|
||||||
{
|
{
|
||||||
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
||||||
|
|
||||||
if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
|
if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
|
||||||
EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
|
EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -451,18 +464,18 @@ egg_sm_client_set_restart_command (EggSMClient *client,
|
||||||
* @argv: argument vector
|
* @argv: argument vector
|
||||||
*
|
*
|
||||||
* Sets the command used to discard a custom state file if using
|
* Sets the command used to discard a custom state file if using
|
||||||
* egg_sm_client_set_restart_command(), which must be called before
|
* egg_sm_client_set_restart_command(), which must be called before
|
||||||
* using this function.
|
* using this function.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
egg_sm_client_set_discard_command (EggSMClient *client,
|
egg_sm_client_set_discard_command (EggSMClient *client,
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv)
|
const char **argv)
|
||||||
{
|
{
|
||||||
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
||||||
|
|
||||||
if (EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command)
|
if (EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command)
|
||||||
EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command (client, argc, argv);
|
EGG_SM_CLIENT_GET_CLASS (client)->set_discard_command (client, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -485,12 +498,12 @@ egg_sm_client_set_discard_command (EggSMClient *client,
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
egg_sm_client_will_quit (EggSMClient *client,
|
egg_sm_client_will_quit (EggSMClient *client,
|
||||||
gboolean will_quit)
|
gboolean will_quit)
|
||||||
{
|
{
|
||||||
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
||||||
|
|
||||||
if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
|
if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
|
||||||
EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
|
EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -511,19 +524,19 @@ egg_sm_client_will_quit (EggSMClient *client,
|
||||||
**/
|
**/
|
||||||
gboolean
|
gboolean
|
||||||
egg_sm_client_end_session (EggSMClientEndStyle style,
|
egg_sm_client_end_session (EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation)
|
gboolean request_confirmation)
|
||||||
{
|
{
|
||||||
EggSMClient *client = egg_sm_client_get ();
|
EggSMClient *client = egg_sm_client_get ();
|
||||||
|
|
||||||
g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
|
g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
|
||||||
|
|
||||||
if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
|
if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
|
||||||
{
|
{
|
||||||
return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
|
return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
|
||||||
request_confirmation);
|
request_confirmation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Signal-emitting callbacks from platform-specific code */
|
/* Signal-emitting callbacks from platform-specific code */
|
||||||
|
@ -531,80 +544,80 @@ egg_sm_client_end_session (EggSMClientEndStyle style,
|
||||||
GKeyFile *
|
GKeyFile *
|
||||||
egg_sm_client_save_state (EggSMClient *client)
|
egg_sm_client_save_state (EggSMClient *client)
|
||||||
{
|
{
|
||||||
GKeyFile *state_file;
|
GKeyFile *state_file;
|
||||||
char *group;
|
char *group;
|
||||||
|
|
||||||
g_return_val_if_fail (client == global_client, NULL);
|
g_return_val_if_fail (client == global_client, NULL);
|
||||||
|
|
||||||
state_file = g_key_file_new ();
|
state_file = g_key_file_new ();
|
||||||
|
|
||||||
g_debug ("Emitting save_state");
|
g_debug ("Emitting save_state");
|
||||||
g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
|
g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
|
||||||
g_debug ("Done emitting save_state");
|
g_debug ("Done emitting save_state");
|
||||||
|
|
||||||
group = g_key_file_get_start_group (state_file);
|
group = g_key_file_get_start_group (state_file);
|
||||||
if (group)
|
if (group)
|
||||||
{
|
{
|
||||||
g_free (group);
|
g_free (group);
|
||||||
return state_file;
|
return state_file;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_key_file_free (state_file);
|
g_key_file_free (state_file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_sm_client_quit_requested (EggSMClient *client)
|
egg_sm_client_quit_requested (EggSMClient *client)
|
||||||
{
|
{
|
||||||
g_return_if_fail (client == global_client);
|
g_return_if_fail (client == global_client);
|
||||||
|
|
||||||
if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
|
if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
|
||||||
{
|
{
|
||||||
g_debug ("Not emitting quit_requested because no one is listening");
|
g_debug ("Not emitting quit_requested because no one is listening");
|
||||||
egg_sm_client_will_quit (client, TRUE);
|
egg_sm_client_will_quit (client, TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_debug ("Emitting quit_requested");
|
g_debug ("Emitting quit_requested");
|
||||||
g_signal_emit (client, signals[QUIT_REQUESTED], 0);
|
g_signal_emit (client, signals[QUIT_REQUESTED], 0);
|
||||||
g_debug ("Done emitting quit_requested");
|
g_debug ("Done emitting quit_requested");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_sm_client_quit_cancelled (EggSMClient *client)
|
egg_sm_client_quit_cancelled (EggSMClient *client)
|
||||||
{
|
{
|
||||||
g_return_if_fail (client == global_client);
|
g_return_if_fail (client == global_client);
|
||||||
|
|
||||||
g_debug ("Emitting quit_cancelled");
|
g_debug ("Emitting quit_cancelled");
|
||||||
g_signal_emit (client, signals[QUIT_CANCELLED], 0);
|
g_signal_emit (client, signals[QUIT_CANCELLED], 0);
|
||||||
g_debug ("Done emitting quit_cancelled");
|
g_debug ("Done emitting quit_cancelled");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_sm_client_quit (EggSMClient *client)
|
egg_sm_client_quit (EggSMClient *client)
|
||||||
{
|
{
|
||||||
g_return_if_fail (client == global_client);
|
g_return_if_fail (client == global_client);
|
||||||
|
|
||||||
g_debug ("Emitting quit");
|
g_debug ("Emitting quit");
|
||||||
g_signal_emit (client, signals[QUIT], 0);
|
g_signal_emit (client, signals[QUIT], 0);
|
||||||
g_debug ("Done emitting quit");
|
g_debug ("Done emitting quit");
|
||||||
|
|
||||||
/* FIXME: should we just call gtk_main_quit() here? */
|
/* FIXME: should we just call gtk_main_quit() here? */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
egg_sm_client_debug_handler (const char *log_domain,
|
egg_sm_client_debug_handler (const char *log_domain,
|
||||||
GLogLevelFlags log_level,
|
GLogLevelFlags log_level,
|
||||||
const char *message,
|
const char *message,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
static int debug = -1;
|
static int debug = -1;
|
||||||
|
|
||||||
if (debug < 0)
|
if (debug < 0)
|
||||||
debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
|
debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
g_log_default_handler (log_domain, log_level, message, NULL);
|
g_log_default_handler (log_domain, log_level, message, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,57 +35,59 @@ typedef struct _EggSMClient EggSMClient;
|
||||||
typedef struct _EggSMClientClass EggSMClientClass;
|
typedef struct _EggSMClientClass EggSMClientClass;
|
||||||
typedef struct _EggSMClientPrivate EggSMClientPrivate;
|
typedef struct _EggSMClientPrivate EggSMClientPrivate;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
EGG_SM_CLIENT_END_SESSION_DEFAULT,
|
{
|
||||||
EGG_SM_CLIENT_LOGOUT,
|
EGG_SM_CLIENT_END_SESSION_DEFAULT,
|
||||||
EGG_SM_CLIENT_REBOOT,
|
EGG_SM_CLIENT_LOGOUT,
|
||||||
EGG_SM_CLIENT_SHUTDOWN
|
EGG_SM_CLIENT_REBOOT,
|
||||||
|
EGG_SM_CLIENT_SHUTDOWN
|
||||||
} EggSMClientEndStyle;
|
} EggSMClientEndStyle;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
EGG_SM_CLIENT_MODE_DISABLED,
|
{
|
||||||
EGG_SM_CLIENT_MODE_NO_RESTART,
|
EGG_SM_CLIENT_MODE_DISABLED,
|
||||||
EGG_SM_CLIENT_MODE_NORMAL
|
EGG_SM_CLIENT_MODE_NO_RESTART,
|
||||||
|
EGG_SM_CLIENT_MODE_NORMAL
|
||||||
} EggSMClientMode;
|
} EggSMClientMode;
|
||||||
|
|
||||||
struct _EggSMClient
|
struct _EggSMClient
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EggSMClientClass
|
struct _EggSMClientClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (*save_state) (EggSMClient *client,
|
void (*save_state) (EggSMClient *client,
|
||||||
GKeyFile *state_file);
|
GKeyFile *state_file);
|
||||||
|
|
||||||
void (*quit_requested) (EggSMClient *client);
|
void (*quit_requested) (EggSMClient *client);
|
||||||
void (*quit_cancelled) (EggSMClient *client);
|
void (*quit_cancelled) (EggSMClient *client);
|
||||||
void (*quit) (EggSMClient *client);
|
void (*quit) (EggSMClient *client);
|
||||||
|
|
||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
void (*startup) (EggSMClient *client,
|
void (*startup) (EggSMClient *client,
|
||||||
const char *client_id);
|
const char *client_id);
|
||||||
void (*set_restart_command) (EggSMClient *client,
|
void (*set_restart_command) (EggSMClient *client,
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv);
|
const char **argv);
|
||||||
void (*set_discard_command) (EggSMClient *client,
|
void (*set_discard_command) (EggSMClient *client,
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv);
|
const char **argv);
|
||||||
void (*will_quit) (EggSMClient *client,
|
void (*will_quit) (EggSMClient *client,
|
||||||
gboolean will_quit);
|
gboolean will_quit);
|
||||||
gboolean (*end_session) (EggSMClient *client,
|
gboolean (*end_session) (EggSMClient *client,
|
||||||
EggSMClientEndStyle style,
|
EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation);
|
gboolean request_confirmation);
|
||||||
|
|
||||||
/* Padding for future expansion */
|
/* Padding for future expansion */
|
||||||
void (*_egg_reserved1) (void);
|
void (*_egg_reserved1) (void);
|
||||||
void (*_egg_reserved2) (void);
|
void (*_egg_reserved2) (void);
|
||||||
void (*_egg_reserved3) (void);
|
void (*_egg_reserved3) (void);
|
||||||
void (*_egg_reserved4) (void);
|
void (*_egg_reserved4) (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType egg_sm_client_get_type (void) G_GNUC_CONST;
|
GType egg_sm_client_get_type (void) G_GNUC_CONST;
|
||||||
|
@ -103,19 +105,19 @@ GKeyFile *egg_sm_client_get_state_file (EggSMClient *client);
|
||||||
|
|
||||||
/* Alternate means of saving state */
|
/* Alternate means of saving state */
|
||||||
void egg_sm_client_set_restart_command (EggSMClient *client,
|
void egg_sm_client_set_restart_command (EggSMClient *client,
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv);
|
const char **argv);
|
||||||
void egg_sm_client_set_discard_command (EggSMClient *client,
|
void egg_sm_client_set_discard_command (EggSMClient *client,
|
||||||
int argc,
|
int argc,
|
||||||
const char **argv);
|
const char **argv);
|
||||||
|
|
||||||
/* Handling "quit_requested" signal */
|
/* Handling "quit_requested" signal */
|
||||||
void egg_sm_client_will_quit (EggSMClient *client,
|
void egg_sm_client_will_quit (EggSMClient *client,
|
||||||
gboolean will_quit);
|
gboolean will_quit);
|
||||||
|
|
||||||
/* Initiate a logout/reboot/shutdown */
|
/* Initiate a logout/reboot/shutdown */
|
||||||
gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
|
gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
|
||||||
gboolean request_confirmation);
|
gboolean request_confirmation);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
1204
src/profile-editor.c
1204
src/profile-editor.c
File diff suppressed because it is too large
Load Diff
273
src/skey-popup.c
273
src/skey-popup.c
|
@ -30,199 +30,200 @@
|
||||||
#define SKEY_PREFIX "s/key "
|
#define SKEY_PREFIX "s/key "
|
||||||
#define OTP_PREFIX "otp-"
|
#define OTP_PREFIX "otp-"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
TerminalScreen *screen;
|
{
|
||||||
char *seed;
|
TerminalScreen *screen;
|
||||||
int seq;
|
char *seed;
|
||||||
int hash;
|
int seq;
|
||||||
|
int hash;
|
||||||
} SkeyData;
|
} SkeyData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
skey_data_free (SkeyData *data)
|
skey_data_free (SkeyData *data)
|
||||||
{
|
{
|
||||||
g_free (data->seed);
|
g_free (data->seed);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
extract_seq_and_seed (const gchar *skey_match,
|
extract_seq_and_seed (const gchar *skey_match,
|
||||||
gint *seq,
|
gint *seq,
|
||||||
gchar **seed)
|
gchar **seed)
|
||||||
{
|
{
|
||||||
gchar *end_ptr = NULL;
|
gchar *end_ptr = NULL;
|
||||||
|
|
||||||
/* FIXME: use g_ascii_strtoll */
|
/* FIXME: use g_ascii_strtoll */
|
||||||
*seq = strtol (skey_match + strlen (SKEY_PREFIX), &end_ptr, 0);
|
*seq = strtol (skey_match + strlen (SKEY_PREFIX), &end_ptr, 0);
|
||||||
|
|
||||||
if (end_ptr == NULL || *end_ptr == '\000')
|
if (end_ptr == NULL || *end_ptr == '\000')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
*seed = g_strdup (end_ptr + 1);
|
*seed = g_strdup (end_ptr + 1);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
extract_hash_seq_and_seed (const gchar *otp_match,
|
extract_hash_seq_and_seed (const gchar *otp_match,
|
||||||
gint *hash,
|
gint *hash,
|
||||||
gint *seq,
|
gint *seq,
|
||||||
gchar **seed)
|
gchar **seed)
|
||||||
{
|
{
|
||||||
gchar *end_ptr = NULL;
|
gchar *end_ptr = NULL;
|
||||||
const gchar *p = otp_match + strlen (OTP_PREFIX);
|
const gchar *p = otp_match + strlen (OTP_PREFIX);
|
||||||
gint len = 3;
|
gint len = 3;
|
||||||
|
|
||||||
if (strncmp (p, "md4", 3) == 0)
|
if (strncmp (p, "md4", 3) == 0)
|
||||||
*hash = MD4;
|
*hash = MD4;
|
||||||
else if (strncmp (p, "md5", 3) == 0)
|
else if (strncmp (p, "md5", 3) == 0)
|
||||||
*hash = MD5;
|
*hash = MD5;
|
||||||
else if (strncmp (p, "sha1", 4) == 0)
|
else if (strncmp (p, "sha1", 4) == 0)
|
||||||
{
|
{
|
||||||
*hash = SHA1;
|
*hash = SHA1;
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
p += len;
|
p += len;
|
||||||
|
|
||||||
/* RFC mandates the following skipping */
|
/* RFC mandates the following skipping */
|
||||||
while (*p == ' ' || *p == '\t')
|
while (*p == ' ' || *p == '\t')
|
||||||
{
|
{
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: use g_ascii_strtoll */
|
/* FIXME: use g_ascii_strtoll */
|
||||||
*seq = strtol (p, &end_ptr, 0);
|
*seq = strtol (p, &end_ptr, 0);
|
||||||
|
|
||||||
if (end_ptr == NULL || *end_ptr == '\000')
|
if (end_ptr == NULL || *end_ptr == '\000')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
p = end_ptr;
|
p = end_ptr;
|
||||||
|
|
||||||
while (*p == ' ' || *p == '\t')
|
while (*p == ' ' || *p == '\t')
|
||||||
{
|
{
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*seed = g_strdup (p);
|
*seed = g_strdup (p);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
skey_challenge_response_cb (GtkWidget *dialog,
|
skey_challenge_response_cb (GtkWidget *dialog,
|
||||||
int response_id,
|
int response_id,
|
||||||
SkeyData *data)
|
SkeyData *data)
|
||||||
{
|
{
|
||||||
if (response_id == GTK_RESPONSE_OK)
|
if (response_id == GTK_RESPONSE_OK)
|
||||||
{
|
|
||||||
GtkWidget *entry;
|
|
||||||
const char *password;
|
|
||||||
char *response;
|
|
||||||
|
|
||||||
entry = g_object_get_data (G_OBJECT (dialog), "skey-entry");
|
|
||||||
password = gtk_entry_get_text (GTK_ENTRY (entry));
|
|
||||||
|
|
||||||
/* FIXME: fix skey to use g_malloc */
|
|
||||||
response = skey (data->hash, data->seq, data->seed, password);
|
|
||||||
if (response)
|
|
||||||
{
|
{
|
||||||
VteTerminal *vte_terminal = VTE_TERMINAL (data->screen);
|
GtkWidget *entry;
|
||||||
static const char newline[2] = "\n";
|
const char *password;
|
||||||
|
char *response;
|
||||||
|
|
||||||
vte_terminal_feed_child (vte_terminal, response, strlen (response));
|
entry = g_object_get_data (G_OBJECT (dialog), "skey-entry");
|
||||||
vte_terminal_feed_child (vte_terminal, newline, strlen (newline));
|
password = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||||
free (response);
|
|
||||||
|
/* FIXME: fix skey to use g_malloc */
|
||||||
|
response = skey (data->hash, data->seq, data->seed, password);
|
||||||
|
if (response)
|
||||||
|
{
|
||||||
|
VteTerminal *vte_terminal = VTE_TERMINAL (data->screen);
|
||||||
|
static const char newline[2] = "\n";
|
||||||
|
|
||||||
|
vte_terminal_feed_child (vte_terminal, response, strlen (response));
|
||||||
|
vte_terminal_feed_child (vte_terminal, newline, strlen (newline));
|
||||||
|
free (response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
terminal_skey_do_popup (GtkWindow *window,
|
terminal_skey_do_popup (GtkWindow *window,
|
||||||
TerminalScreen *screen,
|
TerminalScreen *screen,
|
||||||
const gchar *skey_match)
|
const gchar *skey_match)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog, *label, *entry, *ok_button;
|
GtkWidget *dialog, *label, *entry, *ok_button;
|
||||||
char *title_text;
|
char *title_text;
|
||||||
char *seed;
|
char *seed;
|
||||||
int seq;
|
int seq;
|
||||||
int hash = MD5;
|
int hash = MD5;
|
||||||
SkeyData *data;
|
SkeyData *data;
|
||||||
|
|
||||||
if (strncmp (SKEY_PREFIX, skey_match, strlen (SKEY_PREFIX)) == 0)
|
if (strncmp (SKEY_PREFIX, skey_match, strlen (SKEY_PREFIX)) == 0)
|
||||||
{
|
|
||||||
if (!extract_seq_and_seed (skey_match, &seq, &seed))
|
|
||||||
{
|
{
|
||||||
terminal_util_show_error_dialog (window, NULL, NULL,
|
if (!extract_seq_and_seed (skey_match, &seq, &seed))
|
||||||
_("The text you clicked on doesn't "
|
{
|
||||||
"seem to be a valid S/Key "
|
terminal_util_show_error_dialog (window, NULL, NULL,
|
||||||
"challenge."));
|
_("The text you clicked on doesn't "
|
||||||
return;
|
"seem to be a valid S/Key "
|
||||||
|
"challenge."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!extract_hash_seq_and_seed (skey_match, &hash, &seq, &seed))
|
|
||||||
{
|
{
|
||||||
terminal_util_show_error_dialog (window, NULL, NULL,
|
if (!extract_hash_seq_and_seed (skey_match, &hash, &seq, &seed))
|
||||||
_("The text you clicked on doesn't "
|
{
|
||||||
"seem to be a valid OTP "
|
terminal_util_show_error_dialog (window, NULL, NULL,
|
||||||
"challenge."));
|
_("The text you clicked on doesn't "
|
||||||
return;
|
"seem to be a valid OTP "
|
||||||
|
"challenge."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!terminal_util_load_builder_file ("skey-challenge.ui",
|
if (!terminal_util_load_builder_file ("skey-challenge.ui",
|
||||||
"skey-dialog", &dialog,
|
"skey-dialog", &dialog,
|
||||||
"skey-entry", &entry,
|
"skey-entry", &entry,
|
||||||
"text-label", &label,
|
"text-label", &label,
|
||||||
"skey-ok-button", &ok_button,
|
"skey-ok-button", &ok_button,
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
g_free (seed);
|
g_free (seed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
title_text = g_strdup_printf ("<big><b>%s</b></big>",
|
title_text = g_strdup_printf ("<big><b>%s</b></big>",
|
||||||
gtk_label_get_text (GTK_LABEL (label)));
|
gtk_label_get_text (GTK_LABEL (label)));
|
||||||
gtk_label_set_label (GTK_LABEL (label), title_text);
|
gtk_label_set_label (GTK_LABEL (label), title_text);
|
||||||
g_free (title_text);
|
g_free (title_text);
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (dialog), "skey-entry", entry);
|
g_object_set_data (G_OBJECT (dialog), "skey-entry", entry);
|
||||||
|
|
||||||
gtk_widget_grab_focus (entry);
|
gtk_widget_grab_focus (entry);
|
||||||
gtk_widget_grab_default (ok_button);
|
gtk_widget_grab_default (ok_button);
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry), "");
|
gtk_entry_set_text (GTK_ENTRY (entry), "");
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), window);
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), window);
|
||||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||||
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
|
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
|
||||||
|
|
||||||
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
||||||
GTK_RESPONSE_OK,
|
GTK_RESPONSE_OK,
|
||||||
GTK_RESPONSE_CANCEL,
|
GTK_RESPONSE_CANCEL,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
/* FIXME: make this dialogue close if the screen closes! */
|
/* FIXME: make this dialogue close if the screen closes! */
|
||||||
|
|
||||||
data = g_new (SkeyData, 1);
|
data = g_new (SkeyData, 1);
|
||||||
data->hash = hash;
|
data->hash = hash;
|
||||||
data->seq = seq;
|
data->seq = seq;
|
||||||
data->seed = seed;
|
data->seed = seed;
|
||||||
data->screen = screen;
|
data->screen = screen;
|
||||||
|
|
||||||
g_signal_connect_data (dialog, "response",
|
g_signal_connect_data (dialog, "response",
|
||||||
G_CALLBACK (skey_challenge_response_cb),
|
G_CALLBACK (skey_challenge_response_cb),
|
||||||
data, (GClosureNotify) skey_data_free, 0);
|
data, (GClosureNotify) skey_data_free, 0);
|
||||||
g_signal_connect (dialog, "delete-event",
|
g_signal_connect (dialog, "delete-event",
|
||||||
G_CALLBACK (terminal_util_dialog_response_on_delete), NULL);
|
G_CALLBACK (terminal_util_dialog_response_on_delete), NULL);
|
||||||
|
|
||||||
gtk_window_present (GTK_WINDOW (dialog));
|
gtk_window_present (GTK_WINDOW (dialog));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
void terminal_skey_do_popup (GtkWindow *window,
|
void terminal_skey_do_popup (GtkWindow *window,
|
||||||
TerminalScreen *screen,
|
TerminalScreen *screen,
|
||||||
const gchar *skey_match);
|
const gchar *skey_match);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
516
src/skey/btoe.c
516
src/skey/btoe.c
|
@ -16,228 +16,228 @@ static guint32 extract (char *s, int start, int length);
|
||||||
|
|
||||||
/* Dictionary for integer-word translations */
|
/* Dictionary for integer-word translations */
|
||||||
static const char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
static const char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||||
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
|
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
|
||||||
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
|
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
|
||||||
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
|
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
|
||||||
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
||||||
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
|
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
|
||||||
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
|
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
|
||||||
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
|
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
|
||||||
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
||||||
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
|
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
|
||||||
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
|
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
|
||||||
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
|
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
|
||||||
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
||||||
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
|
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
|
||||||
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
|
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
|
||||||
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
|
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
|
||||||
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
||||||
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
|
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
|
||||||
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
|
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
|
||||||
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
|
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
|
||||||
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
||||||
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
|
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
|
||||||
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
|
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
|
||||||
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
|
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
|
||||||
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS",
|
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS",
|
||||||
"IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG",
|
"IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG",
|
||||||
"JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY",
|
"JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY",
|
||||||
"KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC",
|
"KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC",
|
||||||
"LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG",
|
"LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG",
|
||||||
"LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO",
|
"LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO",
|
||||||
"LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE",
|
"LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE",
|
||||||
"MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY",
|
"MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY",
|
||||||
"ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB",
|
"ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB",
|
||||||
"MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM",
|
"MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM",
|
||||||
"MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE",
|
"MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE",
|
||||||
"NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON",
|
"NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON",
|
||||||
"NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK",
|
"NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK",
|
||||||
"OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK",
|
"OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK",
|
||||||
"OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR",
|
"OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR",
|
||||||
"OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL",
|
"OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL",
|
||||||
"PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN",
|
"PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN",
|
||||||
"PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY",
|
"PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY",
|
||||||
"PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG",
|
"PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG",
|
||||||
"PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW",
|
"PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW",
|
||||||
"RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO",
|
"RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO",
|
||||||
"RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE",
|
"RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE",
|
||||||
"RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN",
|
"RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN",
|
||||||
"SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW",
|
"SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW",
|
||||||
"SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY",
|
"SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY",
|
||||||
"SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB",
|
"SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB",
|
||||||
"SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP",
|
"SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP",
|
||||||
"TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM",
|
"TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM",
|
||||||
"TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW",
|
"TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW",
|
||||||
"TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US",
|
"TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US",
|
||||||
"USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY",
|
"USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY",
|
||||||
"WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK",
|
"WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK",
|
||||||
"WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA",
|
"WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA",
|
||||||
"YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE",
|
"YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE",
|
||||||
"ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR",
|
"ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR",
|
||||||
"AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR",
|
"AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR",
|
||||||
"AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO",
|
"AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO",
|
||||||
"ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS",
|
"ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS",
|
||||||
"AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB",
|
"AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB",
|
||||||
"ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
|
"ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
|
||||||
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
|
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
|
||||||
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT",
|
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT",
|
||||||
"BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE",
|
"BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE",
|
||||||
"BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE",
|
"BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE",
|
||||||
"BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK",
|
"BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK",
|
||||||
"BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER",
|
"BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER",
|
||||||
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT",
|
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT",
|
||||||
"BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
|
"BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
|
||||||
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT",
|
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT",
|
||||||
"BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR",
|
"BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR",
|
||||||
"BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL",
|
"BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL",
|
||||||
"BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN",
|
"BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN",
|
||||||
"BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE",
|
"BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE",
|
||||||
"BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
|
"BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
|
||||||
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF",
|
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF",
|
||||||
"BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
|
"BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
|
||||||
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY",
|
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY",
|
||||||
"CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE",
|
"CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE",
|
||||||
"CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK",
|
"CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK",
|
||||||
"CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT",
|
"CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT",
|
||||||
"CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB",
|
"CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB",
|
||||||
"CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
|
"CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
|
||||||
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK",
|
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK",
|
||||||
"COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
|
"COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
|
||||||
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT",
|
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT",
|
||||||
"CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG",
|
"CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG",
|
||||||
"CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF",
|
"CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF",
|
||||||
"CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS",
|
"CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS",
|
||||||
"DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK",
|
"DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK",
|
||||||
"DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
|
"DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
|
||||||
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM",
|
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM",
|
||||||
"DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
|
"DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
|
||||||
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC",
|
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC",
|
||||||
"DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME",
|
"DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME",
|
||||||
"DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE",
|
"DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE",
|
||||||
"DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM",
|
"DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM",
|
||||||
"DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE",
|
"DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE",
|
||||||
"DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
|
"DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
|
||||||
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA",
|
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA",
|
||||||
"EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
|
"EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
|
||||||
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE",
|
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE",
|
||||||
"FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST",
|
"FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST",
|
||||||
"FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT",
|
"FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT",
|
||||||
"FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM",
|
"FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM",
|
||||||
"FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS",
|
"FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS",
|
||||||
"FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
|
"FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
|
||||||
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY",
|
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY",
|
||||||
"FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
|
"FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
|
||||||
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU",
|
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU",
|
||||||
"FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL",
|
"FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL",
|
||||||
"FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL",
|
"FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL",
|
||||||
"GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB",
|
"GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB",
|
||||||
"GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD",
|
"GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD",
|
||||||
"GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
|
"GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
|
||||||
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB",
|
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB",
|
||||||
"GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
|
"GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
|
||||||
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE",
|
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE",
|
||||||
"GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW",
|
"GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW",
|
||||||
"GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL",
|
"GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL",
|
||||||
"GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK",
|
"GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK",
|
||||||
"HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG",
|
"HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG",
|
||||||
"HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
|
"HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
|
||||||
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT",
|
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT",
|
||||||
"HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
|
"HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
|
||||||
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH",
|
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH",
|
||||||
"HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO",
|
"HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO",
|
||||||
"HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK",
|
"HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK",
|
||||||
"HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE",
|
"HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE",
|
||||||
"HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO",
|
"HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO",
|
||||||
"HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
|
"HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
|
||||||
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO",
|
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO",
|
||||||
"IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
|
"IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
|
||||||
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF",
|
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF",
|
||||||
"JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS",
|
"JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS",
|
||||||
"JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD",
|
"JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD",
|
||||||
"JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO",
|
"JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO",
|
||||||
"JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE",
|
"JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE",
|
||||||
"KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
|
"KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
|
||||||
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT",
|
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT",
|
||||||
"KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
|
"KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
|
||||||
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB",
|
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB",
|
||||||
"LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE",
|
"LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE",
|
||||||
"LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN",
|
"LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN",
|
||||||
"LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK",
|
"LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK",
|
||||||
"LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES",
|
"LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES",
|
||||||
"LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
|
"LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
|
||||||
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE",
|
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE",
|
||||||
"LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
|
"LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
|
||||||
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS",
|
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS",
|
||||||
"LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU",
|
"LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU",
|
||||||
"LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN",
|
"LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN",
|
||||||
"LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE",
|
"LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE",
|
||||||
"MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE",
|
"MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE",
|
||||||
"MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
|
"MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
|
||||||
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET",
|
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET",
|
||||||
"MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
|
"MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
|
||||||
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE",
|
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE",
|
||||||
"MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN",
|
"MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN",
|
||||||
"MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK",
|
"MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK",
|
||||||
"MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS",
|
"MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS",
|
||||||
"MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL",
|
"MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL",
|
||||||
"MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
|
"MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
|
||||||
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT",
|
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT",
|
||||||
"NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
|
"NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
|
||||||
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE",
|
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE",
|
||||||
"NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN",
|
"NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN",
|
||||||
"NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO",
|
"NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO",
|
||||||
"OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN",
|
"OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN",
|
||||||
"OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO",
|
"OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO",
|
||||||
"OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
|
"OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
|
||||||
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE",
|
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE",
|
||||||
"RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
|
"RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
|
||||||
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF",
|
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF",
|
||||||
"REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE",
|
"REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE",
|
||||||
"RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE",
|
"RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE",
|
||||||
"RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL",
|
"RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL",
|
||||||
"ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE",
|
"ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE",
|
||||||
"ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
|
"ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
|
||||||
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH",
|
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH",
|
||||||
"RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
|
"RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
|
||||||
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA",
|
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA",
|
||||||
"SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM",
|
"SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM",
|
||||||
"SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL",
|
"SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL",
|
||||||
"SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED",
|
"SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED",
|
||||||
"SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK",
|
"SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK",
|
||||||
"SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
|
"SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
|
||||||
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID",
|
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID",
|
||||||
"SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
|
"SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
|
||||||
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM",
|
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM",
|
||||||
"SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK",
|
"SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK",
|
||||||
"SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG",
|
"SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG",
|
||||||
"SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG",
|
"SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG",
|
||||||
"STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN",
|
"STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN",
|
||||||
"SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
|
"SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
|
||||||
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK",
|
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK",
|
||||||
"TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
|
"TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
|
||||||
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL",
|
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL",
|
||||||
"TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE",
|
"TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE",
|
||||||
"THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE",
|
"THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE",
|
||||||
"TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE",
|
"TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE",
|
||||||
"TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE",
|
"TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE",
|
||||||
"TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
|
"TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
|
||||||
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM",
|
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM",
|
||||||
"TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
|
"TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
|
||||||
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT",
|
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT",
|
||||||
"ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN",
|
"ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN",
|
||||||
"VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND",
|
"VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND",
|
||||||
"VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID",
|
"VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID",
|
||||||
"VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE",
|
"VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE",
|
||||||
"WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
|
"WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
|
||||||
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS",
|
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS",
|
||||||
"WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
|
"WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
|
||||||
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN",
|
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN",
|
||||||
"WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE",
|
"WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE",
|
||||||
"WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT",
|
"WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT",
|
||||||
"WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT",
|
"WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT",
|
||||||
"WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH",
|
"WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH",
|
||||||
"YEAR", "YELL", "YOGA", "YOKE"
|
"YEAR", "YELL", "YOGA", "YOKE"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encode 8 bytes in 'c' as a string of English words.
|
* Encode 8 bytes in 'c' as a string of English words.
|
||||||
|
@ -246,31 +246,31 @@ static const char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||||
|
|
||||||
char *btoe(unsigned char *md)
|
char *btoe(unsigned char *md)
|
||||||
{
|
{
|
||||||
char cp[9]; /* 64 + 2 = 66 bits */
|
char cp[9]; /* 64 + 2 = 66 bits */
|
||||||
int p, i;
|
int p, i;
|
||||||
static int buf[BUFSIZ];
|
static int buf[BUFSIZ];
|
||||||
char *engout = (char *)buf;
|
char *engout = (char *)buf;
|
||||||
|
|
||||||
memcpy(cp, md, SKEY_SIZE);
|
memcpy(cp, md, SKEY_SIZE);
|
||||||
/* compute parity */
|
/* compute parity */
|
||||||
for(p = 0, i = 0; i < 64; i += 2)
|
for(p = 0, i = 0; i < 64; i += 2)
|
||||||
p += extract(cp, i, 2);
|
p += extract(cp, i, 2);
|
||||||
cp[8] = (char)p << 6;
|
cp[8] = (char)p << 6;
|
||||||
/* now 66 bits */
|
/* now 66 bits */
|
||||||
|
|
||||||
engout[0] = '\0';
|
engout[0] = '\0';
|
||||||
strncat(engout, &Wp[extract(cp, 0, 11)][0], 4);
|
strncat(engout, &Wp[extract(cp, 0, 11)][0], 4);
|
||||||
strcat (engout," ");
|
strcat (engout," ");
|
||||||
strncat(engout, &Wp[extract(cp, 11, 11)][0], 4);
|
strncat(engout, &Wp[extract(cp, 11, 11)][0], 4);
|
||||||
strcat (engout," ");
|
strcat (engout," ");
|
||||||
strncat(engout, &Wp[extract(cp, 22, 11)][0], 4);
|
strncat(engout, &Wp[extract(cp, 22, 11)][0], 4);
|
||||||
strcat (engout," ");
|
strcat (engout," ");
|
||||||
strncat(engout, &Wp[extract(cp, 33, 11)][0], 4);
|
strncat(engout, &Wp[extract(cp, 33, 11)][0], 4);
|
||||||
strcat (engout," ");
|
strcat (engout," ");
|
||||||
strncat(engout, &Wp[extract(cp, 44, 11)][0], 4);
|
strncat(engout, &Wp[extract(cp, 44, 11)][0], 4);
|
||||||
strcat (engout," ");
|
strcat (engout," ");
|
||||||
strncat(engout, &Wp[extract(cp, 55, 11)][0], 4);
|
strncat(engout, &Wp[extract(cp, 55, 11)][0], 4);
|
||||||
return (engout);
|
return (engout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,23 +282,23 @@ char *btoe(unsigned char *md)
|
||||||
|
|
||||||
static guint32 extract(char *s, int start, int length)
|
static guint32 extract(char *s, int start, int length)
|
||||||
{
|
{
|
||||||
guint8 cl;
|
guint8 cl;
|
||||||
guint8 cc;
|
guint8 cc;
|
||||||
guint8 cr;
|
guint8 cr;
|
||||||
guint32 x;
|
guint32 x;
|
||||||
|
|
||||||
/* 66 = 11 x 6 */
|
/* 66 = 11 x 6 */
|
||||||
|
|
||||||
g_assert(length >= 0);
|
|
||||||
g_assert(length <= 11);
|
|
||||||
g_assert(start >= 0);
|
|
||||||
g_assert(start + length <= 66);
|
|
||||||
|
|
||||||
cl = s[start/8];
|
g_assert(length >= 0);
|
||||||
cc = s[start/8 + 1];
|
g_assert(length <= 11);
|
||||||
cr = s[start/8 + 2];
|
g_assert(start >= 0);
|
||||||
x = (guint32) ((((cl << 8) | cc) << 8) | cr); /* 24 bits */
|
g_assert(start + length <= 66);
|
||||||
x = x >> (24 - (length + (start % 8))); /* cut tail */
|
|
||||||
x = (x & (0xffff >> (16 - length))); /* cut head */
|
cl = s[start/8];
|
||||||
return(x); /* length */
|
cc = s[start/8 + 1];
|
||||||
|
cr = s[start/8 + 2];
|
||||||
|
x = (guint32) ((((cl << 8) | cc) << 8) | cr); /* 24 bits */
|
||||||
|
x = x >> (24 - (length + (start % 8))); /* cut tail */
|
||||||
|
x = (x & (0xffff >> (16 - length))); /* cut head */
|
||||||
|
return(x); /* length */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Nikos Mavroyanopoulos
|
* Copyright (C) 2001 Nikos Mavroyanopoulos
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Library General Public License as published
|
* under the terms of the GNU Library General Public License as published
|
||||||
* by the Free Software Foundation; either version 3 of the License, or
|
* by the Free Software Foundation; either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful,
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The algorithm is due to Ron Rivest. This code is based on code
|
* The algorithm is due to Ron Rivest. This code is based on code
|
||||||
* written by Colin Plumb in 1993.
|
* written by Colin Plumb in 1993.
|
||||||
*/
|
*/
|
||||||
|
@ -42,12 +42,14 @@ static void byteReverse(unsigned char *buf, unsigned longs);
|
||||||
static void byteReverse(unsigned char *buf, unsigned longs)
|
static void byteReverse(unsigned char *buf, unsigned longs)
|
||||||
{
|
{
|
||||||
guint32 t;
|
guint32 t;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||||
((unsigned) buf[1] << 8 | buf[0]);
|
((unsigned) buf[1] << 8 | buf[0]);
|
||||||
*(guint32 *) buf = t;
|
*(guint32 *) buf = t;
|
||||||
buf += 4;
|
buf += 4;
|
||||||
} while (--longs);
|
}
|
||||||
|
while (--longs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -73,7 +75,7 @@ void MD4Init(MD4_CTX *ctx)
|
||||||
* of bytes.
|
* of bytes.
|
||||||
*/
|
*/
|
||||||
void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
|
void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
|
||||||
unsigned len)
|
unsigned len)
|
||||||
{
|
{
|
||||||
register guint32 t;
|
register guint32 t;
|
||||||
|
|
||||||
|
@ -88,11 +90,13 @@ void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
|
||||||
|
|
||||||
/* Handle any leading odd-sized chunks */
|
/* Handle any leading odd-sized chunks */
|
||||||
|
|
||||||
if (t) {
|
if (t)
|
||||||
|
{
|
||||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||||
|
|
||||||
t = 64 - t;
|
t = 64 - t;
|
||||||
if (len < t) {
|
if (len < t)
|
||||||
|
{
|
||||||
memcpy(p, buf, len);
|
memcpy(p, buf, len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +108,8 @@ void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
|
||||||
}
|
}
|
||||||
/* Process data in 64-byte chunks */
|
/* Process data in 64-byte chunks */
|
||||||
|
|
||||||
while (len >= 64) {
|
while (len >= 64)
|
||||||
|
{
|
||||||
memcpy(ctx->in, buf, 64);
|
memcpy(ctx->in, buf, 64);
|
||||||
byteReverse(ctx->in, 16);
|
byteReverse(ctx->in, 16);
|
||||||
MD4Transform(ctx->buf, (guint32 *) ctx->in);
|
MD4Transform(ctx->buf, (guint32 *) ctx->in);
|
||||||
|
@ -118,7 +123,7 @@ void MD4Update(MD4_CTX *ctx, unsigned char const *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||||
*/
|
*/
|
||||||
void MD4Final(unsigned char* digest, MD4_CTX *ctx)
|
void MD4Final(unsigned char* digest, MD4_CTX *ctx)
|
||||||
|
@ -138,7 +143,8 @@ void MD4Final(unsigned char* digest, MD4_CTX *ctx)
|
||||||
count = 64 - 1 - count;
|
count = 64 - 1 - count;
|
||||||
|
|
||||||
/* Pad out to 56 mod 64 */
|
/* Pad out to 56 mod 64 */
|
||||||
if (count < 8) {
|
if (count < 8)
|
||||||
|
{
|
||||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
memset(p, 0, count);
|
memset(p, 0, count);
|
||||||
byteReverse(ctx->in, 16);
|
byteReverse(ctx->in, 16);
|
||||||
|
@ -146,7 +152,9 @@ void MD4Final(unsigned char* digest, MD4_CTX *ctx)
|
||||||
|
|
||||||
/* Now fill the next block with 56 bytes */
|
/* Now fill the next block with 56 bytes */
|
||||||
memset(ctx->in, 0, 56);
|
memset(ctx->in, 0, 56);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Pad block to 56 bytes */
|
/* Pad block to 56 bytes */
|
||||||
memset(p, 0, count - 8);
|
memset(p, 0, count - 8);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +166,7 @@ void MD4Final(unsigned char* digest, MD4_CTX *ctx)
|
||||||
|
|
||||||
MD4Transform(ctx->buf, (guint32 *) ctx->in);
|
MD4Transform(ctx->buf, (guint32 *) ctx->in);
|
||||||
byteReverse((unsigned char *) ctx->buf, 4);
|
byteReverse((unsigned char *) ctx->buf, 4);
|
||||||
|
|
||||||
if (digest!=NULL)
|
if (digest!=NULL)
|
||||||
memcpy(digest, ctx->buf, 16);
|
memcpy(digest, ctx->buf, 16);
|
||||||
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||||
|
@ -317,10 +325,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
md4 = (MD4_CTX *)malloc(sizeof(MD4_CTX));
|
md4 = (MD4_CTX *)malloc(sizeof(MD4_CTX));
|
||||||
MD4Init(md4);
|
MD4Init(md4);
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
r = read(0, data, sizeof data);
|
r = read(0, data, sizeof data);
|
||||||
MD4Update(md4, data, r);
|
MD4Update(md4, data, r);
|
||||||
} while (r);
|
}
|
||||||
|
while (r);
|
||||||
|
|
||||||
MD4Final(digest, md4);
|
MD4Final(digest, md4);
|
||||||
printf("MD4 Digest is: ");
|
printf("MD4 Digest is: ");
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
#define MD4_H
|
#define MD4_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
guint32 buf[4];
|
guint32 buf[4];
|
||||||
guint32 bits[2];
|
guint32 bits[2];
|
||||||
unsigned char in[64];
|
unsigned char in[64];
|
||||||
|
|
|
@ -12,9 +12,9 @@ int MD5Keycrunch(char *result, const char *seed, const char *passhrase)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
gsize len;
|
gsize len;
|
||||||
GChecksum *checksum;
|
GChecksum *checksum;
|
||||||
guint8 digest[16];
|
guint8 digest[16];
|
||||||
gsize digest_len = sizeof (digest);
|
gsize digest_len = sizeof (digest);
|
||||||
guint32 *results;
|
guint32 *results;
|
||||||
|
|
||||||
len = strlen(seed) + strlen(passhrase);
|
len = strlen(seed) + strlen(passhrase);
|
||||||
|
@ -27,41 +27,41 @@ int MD5Keycrunch(char *result, const char *seed, const char *passhrase)
|
||||||
strcat(buf, passhrase);
|
strcat(buf, passhrase);
|
||||||
skey_sevenbit(buf);
|
skey_sevenbit(buf);
|
||||||
|
|
||||||
checksum = g_checksum_new (G_CHECKSUM_MD5);
|
checksum = g_checksum_new (G_CHECKSUM_MD5);
|
||||||
g_checksum_update (checksum, (const guchar *) buf, len);
|
g_checksum_update (checksum, (const guchar *) buf, len);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
|
|
||||||
g_checksum_get_digest (checksum, digest, &digest_len);
|
g_checksum_get_digest (checksum, digest, &digest_len);
|
||||||
g_assert (digest_len == 16);
|
g_assert (digest_len == 16);
|
||||||
|
|
||||||
results = (guint32 *) digest;
|
results = (guint32 *) digest;
|
||||||
results[0] ^= results[2];
|
results[0] ^= results[2];
|
||||||
results[1] ^= results[3];
|
results[1] ^= results[3];
|
||||||
|
|
||||||
memcpy((void *)result, (void *)results, SKEY_SIZE);
|
memcpy((void *)result, (void *)results, SKEY_SIZE);
|
||||||
|
|
||||||
g_checksum_free (checksum);
|
g_checksum_free (checksum);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MD5SKey(char *x)
|
void MD5SKey(char *x)
|
||||||
{
|
{
|
||||||
GChecksum *checksum;
|
GChecksum *checksum;
|
||||||
guint8 digest[16];
|
guint8 digest[16];
|
||||||
gsize digest_len = sizeof (digest);
|
gsize digest_len = sizeof (digest);
|
||||||
guint32 *results;
|
guint32 *results;
|
||||||
|
|
||||||
checksum = g_checksum_new (G_CHECKSUM_MD5);
|
checksum = g_checksum_new (G_CHECKSUM_MD5);
|
||||||
g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE);
|
g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE);
|
||||||
g_checksum_get_digest (checksum, digest, &digest_len);
|
g_checksum_get_digest (checksum, digest, &digest_len);
|
||||||
g_assert (digest_len == 16);
|
g_assert (digest_len == 16);
|
||||||
|
|
||||||
results = (guint32 *) digest;
|
results = (guint32 *) digest;
|
||||||
results[0] ^= results[2];
|
results[0] ^= results[2];
|
||||||
results[1] ^= results[3];
|
results[1] ^= results[3];
|
||||||
|
|
||||||
memcpy((void *)x, (void *)results, SKEY_SIZE);
|
memcpy((void *)x, (void *)results, SKEY_SIZE);
|
||||||
|
|
||||||
g_checksum_free (checksum);
|
g_checksum_free (checksum);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,15 @@
|
||||||
*/
|
*/
|
||||||
static void byteReverse(unsigned char *buf, unsigned longs)
|
static void byteReverse(unsigned char *buf, unsigned longs)
|
||||||
{
|
{
|
||||||
guint32 t;
|
guint32 t;
|
||||||
do {
|
do
|
||||||
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
{
|
||||||
((unsigned) buf[1] << 8 | buf[0]);
|
t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||||
*(guint32 *) buf = t;
|
((unsigned) buf[1] << 8 | buf[0]);
|
||||||
buf += 4;
|
*(guint32 *) buf = t;
|
||||||
} while (--longs);
|
buf += 4;
|
||||||
|
}
|
||||||
|
while (--longs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -41,10 +43,10 @@ static void byteReverse(unsigned char *buf, unsigned longs)
|
||||||
int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
|
int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
gsize len;
|
gsize len;
|
||||||
GChecksum *checksum;
|
GChecksum *checksum;
|
||||||
guint8 digest[20];
|
guint8 digest[20];
|
||||||
gsize digest_len = sizeof (digest);
|
gsize digest_len = sizeof (digest);
|
||||||
guint32 *results;
|
guint32 *results;
|
||||||
|
|
||||||
len = strlen(seed) + strlen(passphrase);
|
len = strlen(seed) + strlen(passphrase);
|
||||||
|
@ -56,14 +58,14 @@ int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
|
||||||
strcat(buf, passphrase);
|
strcat(buf, passphrase);
|
||||||
skey_sevenbit(buf);
|
skey_sevenbit(buf);
|
||||||
|
|
||||||
checksum = g_checksum_new (G_CHECKSUM_SHA1);
|
checksum = g_checksum_new (G_CHECKSUM_SHA1);
|
||||||
g_checksum_update (checksum, (const guchar *) buf, len);
|
g_checksum_update (checksum, (const guchar *) buf, len);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
|
|
||||||
g_checksum_get_digest (checksum, digest, &digest_len);
|
g_checksum_get_digest (checksum, digest, &digest_len);
|
||||||
g_assert (digest_len == 20);
|
g_assert (digest_len == 20);
|
||||||
|
|
||||||
results = (guint32 *) digest;
|
results = (guint32 *) digest;
|
||||||
|
|
||||||
#ifndef WORDS_BIGENDIAN
|
#ifndef WORDS_BIGENDIAN
|
||||||
HTONDIGEST(results);
|
HTONDIGEST(results);
|
||||||
|
@ -71,31 +73,31 @@ int SHA1Keycrunch(char *result, const char *seed, const char *passphrase)
|
||||||
byteReverse((unsigned char *)digest, 5);
|
byteReverse((unsigned char *)digest, 5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
results = (guint32 *) digest;
|
results = (guint32 *) digest;
|
||||||
results[0] ^= results[2];
|
results[0] ^= results[2];
|
||||||
results[1] ^= results[3];
|
results[1] ^= results[3];
|
||||||
results[0] ^= results[4];
|
results[0] ^= results[4];
|
||||||
|
|
||||||
memcpy((void *)result, (void *)results, SKEY_SIZE);
|
memcpy((void *)result, (void *)results, SKEY_SIZE);
|
||||||
|
|
||||||
g_checksum_free (checksum);
|
g_checksum_free (checksum);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHA1SKey(char *x)
|
void SHA1SKey(char *x)
|
||||||
{
|
{
|
||||||
GChecksum *checksum;
|
GChecksum *checksum;
|
||||||
guint8 digest[20];
|
guint8 digest[20];
|
||||||
gsize digest_len = sizeof (digest);
|
gsize digest_len = sizeof (digest);
|
||||||
guint32 *results;
|
guint32 *results;
|
||||||
|
|
||||||
checksum = g_checksum_new (G_CHECKSUM_SHA1);
|
checksum = g_checksum_new (G_CHECKSUM_SHA1);
|
||||||
g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE);
|
g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE);
|
||||||
g_checksum_get_digest (checksum, digest, &digest_len);
|
g_checksum_get_digest (checksum, digest, &digest_len);
|
||||||
g_assert (digest_len == 20);
|
g_assert (digest_len == 20);
|
||||||
|
|
||||||
results = (guint32 *) digest;
|
results = (guint32 *) digest;
|
||||||
#ifndef WORDS_BIGENDIAN
|
#ifndef WORDS_BIGENDIAN
|
||||||
HTONDIGEST(results);
|
HTONDIGEST(results);
|
||||||
#else
|
#else
|
||||||
|
@ -108,5 +110,5 @@ void SHA1SKey(char *x)
|
||||||
|
|
||||||
memcpy((void *)x, (void *)results, SKEY_SIZE);
|
memcpy((void *)x, (void *)results, SKEY_SIZE);
|
||||||
|
|
||||||
g_checksum_free (checksum);
|
g_checksum_free (checksum);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define _SHA1_H
|
#define _SHA1_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
int SHA1Keycrunch(char *result, const char *seed, const char *passphrase);
|
int SHA1Keycrunch(char *result, const char *seed, const char *passphrase);
|
||||||
void SHA1SKey(char *x);
|
void SHA1SKey(char *x);
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,13 @@
|
||||||
#include "skey.h"
|
#include "skey.h"
|
||||||
#include "btoe.h"
|
#include "btoe.h"
|
||||||
|
|
||||||
struct skey_hash {
|
struct skey_hash
|
||||||
|
{
|
||||||
int (*Keycrunch) (char *, const char *, const char *);
|
int (*Keycrunch) (char *, const char *, const char *);
|
||||||
void (*Skey) (char *);
|
void (*Skey) (char *);
|
||||||
};
|
};
|
||||||
static struct skey_hash hash_table[] = {
|
static struct skey_hash hash_table[] =
|
||||||
|
{
|
||||||
{ MD4Keycrunch, MD4SKey },
|
{ MD4Keycrunch, MD4SKey },
|
||||||
{ MD5Keycrunch, MD5SKey },
|
{ MD5Keycrunch, MD5SKey },
|
||||||
{ SHA1Keycrunch, SHA1SKey }
|
{ SHA1Keycrunch, SHA1SKey }
|
||||||
|
@ -26,7 +28,7 @@ char *skey(SKeyAlgorithm algorithm, int seq, const char *seed, const char *passp
|
||||||
{
|
{
|
||||||
char key[SKEY_SIZE];
|
char key[SKEY_SIZE];
|
||||||
int i;
|
int i;
|
||||||
g_assert (algorithm < G_N_ELEMENTS (hash_table));
|
g_assert (algorithm < G_N_ELEMENTS (hash_table));
|
||||||
if (hash_table[algorithm].Keycrunch(key, seed, passphrase) == -1)
|
if (hash_table[algorithm].Keycrunch(key, seed, passphrase) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
typedef enum {
|
typedef enum
|
||||||
MD4,
|
{
|
||||||
MD5,
|
MD4,
|
||||||
SHA1
|
MD5,
|
||||||
|
SHA1
|
||||||
} SKeyAlgorithm;
|
} SKeyAlgorithm;
|
||||||
|
|
||||||
#define SKEY_SIZE 8
|
#define SKEY_SIZE 8
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
#include "skey.h"
|
#include "skey.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
SKeyAlgorithm algorithm;
|
{
|
||||||
|
SKeyAlgorithm algorithm;
|
||||||
const char *passphrase;
|
const char *passphrase;
|
||||||
const char *seed;
|
const char *seed;
|
||||||
int count;
|
int count;
|
||||||
|
@ -17,7 +18,8 @@ typedef struct {
|
||||||
const char *btoe;
|
const char *btoe;
|
||||||
} TestEntry;
|
} TestEntry;
|
||||||
|
|
||||||
static const TestEntry tests[] = {
|
static const TestEntry tests[] =
|
||||||
|
{
|
||||||
{ MD4, "This is a test.", "TeSt", 0, "D185 4218 EBBB 0B51", "ROME MUG FRED SCAN LIVE LACE" },
|
{ MD4, "This is a test.", "TeSt", 0, "D185 4218 EBBB 0B51", "ROME MUG FRED SCAN LIVE LACE" },
|
||||||
{ MD4, "This is a test.", "TeSt", 1, "6347 3EF0 1CD0 B444", "CARD SAD MINI RYE COL KIN" },
|
{ MD4, "This is a test.", "TeSt", 1, "6347 3EF0 1CD0 B444", "CARD SAD MINI RYE COL KIN" },
|
||||||
{ MD4, "This is a test.", "TeSt", 99, "C5E6 1277 6E6C 237A", "NOTE OUT IBIS SINK NAVE MODE" },
|
{ MD4, "This is a test.", "TeSt", 99, "C5E6 1277 6E6C 237A", "NOTE OUT IBIS SINK NAVE MODE" },
|
||||||
|
@ -46,54 +48,56 @@ static const TestEntry tests[] = {
|
||||||
{ SHA1, "OTP's are good", "correct", 1, "82AE B52D 9437 74E4", "FLIT DOSE ALSO MEW DRUM DEFY" },
|
{ SHA1, "OTP's are good", "correct", 1, "82AE B52D 9437 74E4", "FLIT DOSE ALSO MEW DRUM DEFY" },
|
||||||
{ SHA1, "OTP's are good", "correct", 99, "4F29 6A74 FE15 67EC", "AURA ALOE HURL WING BERG WAIT" },
|
{ SHA1, "OTP's are good", "correct", 99, "4F29 6A74 FE15 67EC", "AURA ALOE HURL WING BERG WAIT" },
|
||||||
|
|
||||||
{ SHA1, "Passphrase", "IiIi", 100, "27F4 01CC 0AC8 5112", "MEG JACK DIET GAD FORK GARY" }
|
{ SHA1, "Passphrase", "IiIi", 100, "27F4 01CC 0AC8 5112", "MEG JACK DIET GAD FORK GARY" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *algos[] = {
|
static const char *algos[] =
|
||||||
"MD4",
|
{
|
||||||
"MD5",
|
"MD4",
|
||||||
"SHA1"
|
"MD5",
|
||||||
|
"SHA1"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
skey_test (gconstpointer data)
|
skey_test (gconstpointer data)
|
||||||
{
|
{
|
||||||
const TestEntry *test = (const TestEntry *) data;
|
const TestEntry *test = (const TestEntry *) data;
|
||||||
char *key;
|
char *key;
|
||||||
|
|
||||||
key = skey (test->algorithm,
|
key = skey (test->algorithm,
|
||||||
test->count,
|
test->count,
|
||||||
test->seed,
|
test->seed,
|
||||||
test->passphrase);
|
test->passphrase);
|
||||||
g_assert (key != NULL);
|
g_assert (key != NULL);
|
||||||
g_assert (strcmp (key, test->btoe) == 0);
|
g_assert (strcmp (key, test->btoe) == 0);
|
||||||
free (key);
|
free (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!setlocale (LC_ALL, ""))
|
if (!setlocale (LC_ALL, ""))
|
||||||
g_error ("Locale not supported by C library!\n");
|
g_error ("Locale not supported by C library!\n");
|
||||||
|
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
g_test_bug_base ("http://bugzilla.mate.org/enter_bug.cgi?product=mate-terminal");
|
g_test_bug_base ("http://bugzilla.mate.org/enter_bug.cgi?product=mate-terminal");
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (tests); ++i) {
|
for (i = 0; i < G_N_ELEMENTS (tests); ++i)
|
||||||
const TestEntry *test = &tests[i];
|
{
|
||||||
char *name;
|
const TestEntry *test = &tests[i];
|
||||||
|
char *name;
|
||||||
|
|
||||||
name = g_strdup_printf ("/%s/%s/%s/%d/%s/%s",
|
name = g_strdup_printf ("/%s/%s/%s/%d/%s/%s",
|
||||||
algos[test->algorithm],
|
algos[test->algorithm],
|
||||||
test->passphrase,
|
test->passphrase,
|
||||||
test->seed,
|
test->seed,
|
||||||
test->count,
|
test->count,
|
||||||
test->hex,
|
test->hex,
|
||||||
test->btoe);
|
test->btoe);
|
||||||
g_test_add_data_func (name, test, skey_test);
|
g_test_add_data_func (name, test, skey_test);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,7 +25,7 @@
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
void terminal_accels_init (void);
|
void terminal_accels_init (void);
|
||||||
|
|
||||||
void terminal_accels_shutdown (void);
|
void terminal_accels_shutdown (void);
|
||||||
|
|
||||||
void terminal_edit_keys_dialog_show (GtkWindow *transient_parent);
|
void terminal_edit_keys_dialog_show (GtkWindow *transient_parent);
|
||||||
|
|
2476
src/terminal-app.c
2476
src/terminal-app.c
File diff suppressed because it is too large
Load Diff
|
@ -102,16 +102,16 @@ void terminal_app_new_profile (TerminalApp *app,
|
||||||
GtkWindow *transient_parent);
|
GtkWindow *transient_parent);
|
||||||
|
|
||||||
TerminalWindow * terminal_app_new_window (TerminalApp *app,
|
TerminalWindow * terminal_app_new_window (TerminalApp *app,
|
||||||
GdkScreen *screen);
|
GdkScreen *screen);
|
||||||
|
|
||||||
TerminalScreen *terminal_app_new_terminal (TerminalApp *app,
|
TerminalScreen *terminal_app_new_terminal (TerminalApp *app,
|
||||||
TerminalWindow *window,
|
TerminalWindow *window,
|
||||||
TerminalProfile *profile,
|
TerminalProfile *profile,
|
||||||
char **override_command,
|
char **override_command,
|
||||||
const char *title,
|
const char *title,
|
||||||
const char *working_dir,
|
const char *working_dir,
|
||||||
char **child_env,
|
char **child_env,
|
||||||
double zoom);
|
double zoom);
|
||||||
|
|
||||||
TerminalWindow *terminal_app_get_current_window (TerminalApp *app);
|
TerminalWindow *terminal_app_get_current_window (TerminalApp *app);
|
||||||
|
|
||||||
|
@ -129,10 +129,10 @@ GList* terminal_app_get_profile_list (TerminalApp *app);
|
||||||
TerminalProfile* terminal_app_ensure_profile_fallback (TerminalApp *app);
|
TerminalProfile* terminal_app_ensure_profile_fallback (TerminalApp *app);
|
||||||
|
|
||||||
TerminalProfile* terminal_app_get_profile_by_name (TerminalApp *app,
|
TerminalProfile* terminal_app_get_profile_by_name (TerminalApp *app,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
TerminalProfile* terminal_app_get_profile_by_visible_name (TerminalApp *app,
|
TerminalProfile* terminal_app_get_profile_by_visible_name (TerminalApp *app,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
/* may return NULL */
|
/* may return NULL */
|
||||||
TerminalProfile* terminal_app_get_default_profile (TerminalApp *app);
|
TerminalProfile* terminal_app_get_default_profile (TerminalApp *app);
|
||||||
|
@ -141,7 +141,7 @@ TerminalProfile* terminal_app_get_default_profile (TerminalApp *app);
|
||||||
TerminalProfile* terminal_app_get_profile_for_new_term (TerminalApp *app);
|
TerminalProfile* terminal_app_get_profile_for_new_term (TerminalApp *app);
|
||||||
|
|
||||||
TerminalEncoding *terminal_app_ensure_encoding (TerminalApp *app,
|
TerminalEncoding *terminal_app_ensure_encoding (TerminalApp *app,
|
||||||
const char *charset);
|
const char *charset);
|
||||||
|
|
||||||
GHashTable *terminal_app_get_encodings (TerminalApp *app);
|
GHashTable *terminal_app_get_encodings (TerminalApp *app);
|
||||||
|
|
||||||
|
|
|
@ -28,18 +28,19 @@ void
|
||||||
_terminal_debug_init(void)
|
_terminal_debug_init(void)
|
||||||
{
|
{
|
||||||
#ifdef MATE_ENABLE_DEBUG
|
#ifdef MATE_ENABLE_DEBUG
|
||||||
const GDebugKey keys[] = {
|
const GDebugKey keys[] =
|
||||||
{ "accels", TERMINAL_DEBUG_ACCELS },
|
{
|
||||||
{ "encodings", TERMINAL_DEBUG_ENCODINGS },
|
{ "accels", TERMINAL_DEBUG_ACCELS },
|
||||||
{ "factory", TERMINAL_DEBUG_FACTORY },
|
{ "encodings", TERMINAL_DEBUG_ENCODINGS },
|
||||||
{ "geometry", TERMINAL_DEBUG_GEOMETRY },
|
{ "factory", TERMINAL_DEBUG_FACTORY },
|
||||||
{ "mdi", TERMINAL_DEBUG_MDI },
|
{ "geometry", TERMINAL_DEBUG_GEOMETRY },
|
||||||
{ "processes", TERMINAL_DEBUG_PROCESSES },
|
{ "mdi", TERMINAL_DEBUG_MDI },
|
||||||
{ "profile", TERMINAL_DEBUG_PROFILE }
|
{ "processes", TERMINAL_DEBUG_PROCESSES },
|
||||||
};
|
{ "profile", TERMINAL_DEBUG_PROFILE }
|
||||||
|
};
|
||||||
|
|
||||||
_terminal_debug_flags = g_parse_debug_string (g_getenv ("MATE_TERMINAL_DEBUG"),
|
_terminal_debug_flags = g_parse_debug_string (g_getenv ("MATE_TERMINAL_DEBUG"),
|
||||||
keys, G_N_ELEMENTS (keys));
|
keys, G_N_ELEMENTS (keys));
|
||||||
#endif /* MATE_ENABLE_DEBUG */
|
#endif /* MATE_ENABLE_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,15 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
TERMINAL_DEBUG_ACCELS = 1 << 0,
|
{
|
||||||
TERMINAL_DEBUG_ENCODINGS = 1 << 1,
|
TERMINAL_DEBUG_ACCELS = 1 << 0,
|
||||||
TERMINAL_DEBUG_FACTORY = 1 << 2,
|
TERMINAL_DEBUG_ENCODINGS = 1 << 1,
|
||||||
TERMINAL_DEBUG_GEOMETRY = 1 << 3,
|
TERMINAL_DEBUG_FACTORY = 1 << 2,
|
||||||
TERMINAL_DEBUG_MDI = 1 << 4,
|
TERMINAL_DEBUG_GEOMETRY = 1 << 3,
|
||||||
TERMINAL_DEBUG_PROCESSES = 1 << 5,
|
TERMINAL_DEBUG_MDI = 1 << 4,
|
||||||
TERMINAL_DEBUG_PROFILE = 1 << 6
|
TERMINAL_DEBUG_PROCESSES = 1 << 5,
|
||||||
|
TERMINAL_DEBUG_PROFILE = 1 << 6
|
||||||
} TerminalDebugFlags;
|
} TerminalDebugFlags;
|
||||||
|
|
||||||
void _terminal_debug_init(void);
|
void _terminal_debug_init(void);
|
||||||
|
@ -43,7 +44,7 @@ static inline gboolean _terminal_debug_on (TerminalDebugFlags flags) G_GNUC_CONS
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
_terminal_debug_on (TerminalDebugFlags flags)
|
_terminal_debug_on (TerminalDebugFlags flags)
|
||||||
{
|
{
|
||||||
return (_terminal_debug_flags & flags) == flags;
|
return (_terminal_debug_flags & flags) == flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MATE_ENABLE_DEBUG
|
#ifdef MATE_ENABLE_DEBUG
|
||||||
|
@ -60,12 +61,13 @@ _terminal_debug_on (TerminalDebugFlags flags)
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
static void _terminal_debug_print (guint flags, const char *fmt, ...)
|
static void _terminal_debug_print (guint flags, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
if (_terminal_debug_on (flags)) {
|
if (_terminal_debug_on (flags))
|
||||||
va_list ap;
|
{
|
||||||
va_start (ap, fmt);
|
va_list ap;
|
||||||
g_vfprintf (stderr, fmt, ap);
|
va_start (ap, fmt);
|
||||||
va_end (ap);
|
g_vfprintf (stderr, fmt, ap);
|
||||||
}
|
va_end (ap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
*
|
*
|
||||||
* There's a list of character sets stored in mateconf, indicating
|
* There's a list of character sets stored in mateconf, indicating
|
||||||
* which encodings to display in the encoding menu.
|
* which encodings to display in the encoding menu.
|
||||||
*
|
*
|
||||||
* We have a pre-canned list of available encodings
|
* We have a pre-canned list of available encodings
|
||||||
* (hardcoded in the table below) that can be added to
|
* (hardcoded in the table below) that can be added to
|
||||||
* the encoding menu, and to give a human-readable name
|
* the encoding menu, and to give a human-readable name
|
||||||
|
@ -44,101 +44,104 @@
|
||||||
* labeled "user defined" but still appears in the menu.
|
* labeled "user defined" but still appears in the menu.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const struct {
|
static const struct
|
||||||
const char *charset;
|
{
|
||||||
const char *name;
|
const char *charset;
|
||||||
} encodings[] = {
|
const char *name;
|
||||||
{ "ISO-8859-1", N_("Western") },
|
} encodings[] =
|
||||||
{ "ISO-8859-2", N_("Central European") },
|
{
|
||||||
{ "ISO-8859-3", N_("South European") },
|
{ "ISO-8859-1", N_("Western") },
|
||||||
{ "ISO-8859-4", N_("Baltic") },
|
{ "ISO-8859-2", N_("Central European") },
|
||||||
{ "ISO-8859-5", N_("Cyrillic") },
|
{ "ISO-8859-3", N_("South European") },
|
||||||
{ "ISO-8859-6", N_("Arabic") },
|
{ "ISO-8859-4", N_("Baltic") },
|
||||||
{ "ISO-8859-7", N_("Greek") },
|
{ "ISO-8859-5", N_("Cyrillic") },
|
||||||
{ "ISO-8859-8", N_("Hebrew Visual") },
|
{ "ISO-8859-6", N_("Arabic") },
|
||||||
{ "ISO-8859-8-I", N_("Hebrew") },
|
{ "ISO-8859-7", N_("Greek") },
|
||||||
{ "ISO-8859-9", N_("Turkish") },
|
{ "ISO-8859-8", N_("Hebrew Visual") },
|
||||||
{ "ISO-8859-10", N_("Nordic") },
|
{ "ISO-8859-8-I", N_("Hebrew") },
|
||||||
{ "ISO-8859-13", N_("Baltic") },
|
{ "ISO-8859-9", N_("Turkish") },
|
||||||
{ "ISO-8859-14", N_("Celtic") },
|
{ "ISO-8859-10", N_("Nordic") },
|
||||||
{ "ISO-8859-15", N_("Western") },
|
{ "ISO-8859-13", N_("Baltic") },
|
||||||
{ "ISO-8859-16", N_("Romanian") },
|
{ "ISO-8859-14", N_("Celtic") },
|
||||||
{ "UTF-8", N_("Unicode") },
|
{ "ISO-8859-15", N_("Western") },
|
||||||
{ "ARMSCII-8", N_("Armenian") },
|
{ "ISO-8859-16", N_("Romanian") },
|
||||||
{ "BIG5", N_("Chinese Traditional") },
|
{ "UTF-8", N_("Unicode") },
|
||||||
{ "BIG5-HKSCS", N_("Chinese Traditional") },
|
{ "ARMSCII-8", N_("Armenian") },
|
||||||
{ "CP866", N_("Cyrillic/Russian") },
|
{ "BIG5", N_("Chinese Traditional") },
|
||||||
{ "EUC-JP", N_("Japanese") },
|
{ "BIG5-HKSCS", N_("Chinese Traditional") },
|
||||||
{ "EUC-KR", N_("Korean") },
|
{ "CP866", N_("Cyrillic/Russian") },
|
||||||
{ "EUC-TW", N_("Chinese Traditional") },
|
{ "EUC-JP", N_("Japanese") },
|
||||||
{ "GB18030", N_("Chinese Simplified") },
|
{ "EUC-KR", N_("Korean") },
|
||||||
{ "GB2312", N_("Chinese Simplified") },
|
{ "EUC-TW", N_("Chinese Traditional") },
|
||||||
{ "GBK", N_("Chinese Simplified") },
|
{ "GB18030", N_("Chinese Simplified") },
|
||||||
{ "GEORGIAN-PS", N_("Georgian") },
|
{ "GB2312", N_("Chinese Simplified") },
|
||||||
{ "IBM850", N_("Western") },
|
{ "GBK", N_("Chinese Simplified") },
|
||||||
{ "IBM852", N_("Central European") },
|
{ "GEORGIAN-PS", N_("Georgian") },
|
||||||
{ "IBM855", N_("Cyrillic") },
|
{ "IBM850", N_("Western") },
|
||||||
{ "IBM857", N_("Turkish") },
|
{ "IBM852", N_("Central European") },
|
||||||
{ "IBM862", N_("Hebrew") },
|
{ "IBM855", N_("Cyrillic") },
|
||||||
{ "IBM864", N_("Arabic") },
|
{ "IBM857", N_("Turkish") },
|
||||||
{ "ISO-2022-JP", N_("Japanese") },
|
{ "IBM862", N_("Hebrew") },
|
||||||
{ "ISO-2022-KR", N_("Korean") },
|
{ "IBM864", N_("Arabic") },
|
||||||
{ "ISO-IR-111", N_("Cyrillic") },
|
{ "ISO-2022-JP", N_("Japanese") },
|
||||||
{ "KOI8-R", N_("Cyrillic") },
|
{ "ISO-2022-KR", N_("Korean") },
|
||||||
{ "KOI8-U", N_("Cyrillic/Ukrainian") },
|
{ "ISO-IR-111", N_("Cyrillic") },
|
||||||
{ "MAC_ARABIC", N_("Arabic") },
|
{ "KOI8-R", N_("Cyrillic") },
|
||||||
{ "MAC_CE", N_("Central European") },
|
{ "KOI8-U", N_("Cyrillic/Ukrainian") },
|
||||||
{ "MAC_CROATIAN", N_("Croatian") },
|
{ "MAC_ARABIC", N_("Arabic") },
|
||||||
{ "MAC-CYRILLIC", N_("Cyrillic") },
|
{ "MAC_CE", N_("Central European") },
|
||||||
{ "MAC_DEVANAGARI", N_("Hindi") },
|
{ "MAC_CROATIAN", N_("Croatian") },
|
||||||
{ "MAC_FARSI", N_("Persian") },
|
{ "MAC-CYRILLIC", N_("Cyrillic") },
|
||||||
{ "MAC_GREEK", N_("Greek") },
|
{ "MAC_DEVANAGARI", N_("Hindi") },
|
||||||
{ "MAC_GUJARATI", N_("Gujarati") },
|
{ "MAC_FARSI", N_("Persian") },
|
||||||
{ "MAC_GURMUKHI", N_("Gurmukhi") },
|
{ "MAC_GREEK", N_("Greek") },
|
||||||
{ "MAC_HEBREW", N_("Hebrew") },
|
{ "MAC_GUJARATI", N_("Gujarati") },
|
||||||
{ "MAC_ICELANDIC", N_("Icelandic") },
|
{ "MAC_GURMUKHI", N_("Gurmukhi") },
|
||||||
{ "MAC_ROMAN", N_("Western") },
|
{ "MAC_HEBREW", N_("Hebrew") },
|
||||||
{ "MAC_ROMANIAN", N_("Romanian") },
|
{ "MAC_ICELANDIC", N_("Icelandic") },
|
||||||
{ "MAC_TURKISH", N_("Turkish") },
|
{ "MAC_ROMAN", N_("Western") },
|
||||||
{ "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian") },
|
{ "MAC_ROMANIAN", N_("Romanian") },
|
||||||
{ "SHIFT_JIS", N_("Japanese") },
|
{ "MAC_TURKISH", N_("Turkish") },
|
||||||
{ "TCVN", N_("Vietnamese") },
|
{ "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian") },
|
||||||
{ "TIS-620", N_("Thai") },
|
{ "SHIFT_JIS", N_("Japanese") },
|
||||||
{ "UHC", N_("Korean") },
|
{ "TCVN", N_("Vietnamese") },
|
||||||
{ "VISCII", N_("Vietnamese") },
|
{ "TIS-620", N_("Thai") },
|
||||||
{ "WINDOWS-1250", N_("Central European") },
|
{ "UHC", N_("Korean") },
|
||||||
{ "WINDOWS-1251", N_("Cyrillic") },
|
{ "VISCII", N_("Vietnamese") },
|
||||||
{ "WINDOWS-1252", N_("Western") },
|
{ "WINDOWS-1250", N_("Central European") },
|
||||||
{ "WINDOWS-1253", N_("Greek") },
|
{ "WINDOWS-1251", N_("Cyrillic") },
|
||||||
{ "WINDOWS-1254", N_("Turkish") },
|
{ "WINDOWS-1252", N_("Western") },
|
||||||
{ "WINDOWS-1255", N_("Hebrew") },
|
{ "WINDOWS-1253", N_("Greek") },
|
||||||
{ "WINDOWS-1256", N_("Arabic") },
|
{ "WINDOWS-1254", N_("Turkish") },
|
||||||
{ "WINDOWS-1257", N_("Baltic") },
|
{ "WINDOWS-1255", N_("Hebrew") },
|
||||||
{ "WINDOWS-1258", N_("Vietnamese") },
|
{ "WINDOWS-1256", N_("Arabic") },
|
||||||
|
{ "WINDOWS-1257", N_("Baltic") },
|
||||||
|
{ "WINDOWS-1258", N_("Vietnamese") },
|
||||||
#if 0
|
#if 0
|
||||||
/* These encodings do NOT pass-through ASCII, so are always rejected.
|
/* These encodings do NOT pass-through ASCII, so are always rejected.
|
||||||
* FIXME: why are they in this table; or rather why do we need
|
* FIXME: why are they in this table; or rather why do we need
|
||||||
* the ASCII pass-through requirement?
|
* the ASCII pass-through requirement?
|
||||||
*/
|
*/
|
||||||
{ "UTF-7", N_("Unicode") },
|
{ "UTF-7", N_("Unicode") },
|
||||||
{ "UTF-16", N_("Unicode") },
|
{ "UTF-16", N_("Unicode") },
|
||||||
{ "UCS-2", N_("Unicode") },
|
{ "UCS-2", N_("Unicode") },
|
||||||
{ "UCS-4", N_("Unicode") },
|
{ "UCS-4", N_("Unicode") },
|
||||||
{ "JOHAB", N_("Korean") },
|
{ "JOHAB", N_("Korean") },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
GtkWidget *dialog;
|
{
|
||||||
GtkListStore *base_store;
|
GtkWidget *dialog;
|
||||||
GtkTreeView *available_tree_view;
|
GtkListStore *base_store;
|
||||||
GtkTreeSelection *available_selection;
|
GtkTreeView *available_tree_view;
|
||||||
GtkTreeModel *available_model;
|
GtkTreeSelection *available_selection;
|
||||||
GtkTreeView *active_tree_view;
|
GtkTreeModel *available_model;
|
||||||
GtkTreeSelection *active_selection;
|
GtkTreeView *active_tree_view;
|
||||||
GtkTreeModel *active_model;
|
GtkTreeSelection *active_selection;
|
||||||
GtkWidget *add_button;
|
GtkTreeModel *active_model;
|
||||||
GtkWidget *remove_button;
|
GtkWidget *add_button;
|
||||||
|
GtkWidget *remove_button;
|
||||||
} EncodingDialogData;
|
} EncodingDialogData;
|
||||||
|
|
||||||
static GtkWidget *encoding_dialog = NULL;
|
static GtkWidget *encoding_dialog = NULL;
|
||||||
|
@ -149,163 +152,164 @@ terminal_encoding_new (const char *charset,
|
||||||
gboolean is_custom,
|
gboolean is_custom,
|
||||||
gboolean force_valid)
|
gboolean force_valid)
|
||||||
{
|
{
|
||||||
TerminalEncoding *encoding;
|
TerminalEncoding *encoding;
|
||||||
|
|
||||||
encoding = g_slice_new (TerminalEncoding);
|
encoding = g_slice_new (TerminalEncoding);
|
||||||
encoding->refcount = 1;
|
encoding->refcount = 1;
|
||||||
encoding->id = g_strdup (charset);
|
encoding->id = g_strdup (charset);
|
||||||
encoding->name = g_strdup (display_name);
|
encoding->name = g_strdup (display_name);
|
||||||
encoding->valid = encoding->validity_checked = force_valid;
|
encoding->valid = encoding->validity_checked = force_valid;
|
||||||
encoding->is_custom = is_custom;
|
encoding->is_custom = is_custom;
|
||||||
encoding->is_active = FALSE;
|
encoding->is_active = FALSE;
|
||||||
|
|
||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalEncoding*
|
TerminalEncoding*
|
||||||
terminal_encoding_ref (TerminalEncoding *encoding)
|
terminal_encoding_ref (TerminalEncoding *encoding)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (encoding != NULL, NULL);
|
g_return_val_if_fail (encoding != NULL, NULL);
|
||||||
|
|
||||||
encoding->refcount++;
|
encoding->refcount++;
|
||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
terminal_encoding_unref (TerminalEncoding *encoding)
|
terminal_encoding_unref (TerminalEncoding *encoding)
|
||||||
{
|
{
|
||||||
if (--encoding->refcount > 0)
|
if (--encoding->refcount > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_free (encoding->name);
|
g_free (encoding->name);
|
||||||
g_free (encoding->id);
|
g_free (encoding->id);
|
||||||
g_slice_free (TerminalEncoding, encoding);
|
g_slice_free (TerminalEncoding, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
terminal_encoding_get_id (TerminalEncoding *encoding)
|
terminal_encoding_get_id (TerminalEncoding *encoding)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (encoding != NULL, NULL);
|
g_return_val_if_fail (encoding != NULL, NULL);
|
||||||
|
|
||||||
return encoding->id;
|
return encoding->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
terminal_encoding_get_charset (TerminalEncoding *encoding)
|
terminal_encoding_get_charset (TerminalEncoding *encoding)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (encoding != NULL, NULL);
|
g_return_val_if_fail (encoding != NULL, NULL);
|
||||||
|
|
||||||
if (strcmp (encoding->id, "current") == 0)
|
if (strcmp (encoding->id, "current") == 0)
|
||||||
{
|
{
|
||||||
const char *charset;
|
const char *charset;
|
||||||
|
|
||||||
g_get_charset (&charset);
|
g_get_charset (&charset);
|
||||||
return charset;
|
return charset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoding->id;
|
return encoding->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
terminal_encoding_is_valid (TerminalEncoding *encoding)
|
terminal_encoding_is_valid (TerminalEncoding *encoding)
|
||||||
{
|
{
|
||||||
/* All of the printing ASCII characters from space (32) to the tilde (126) */
|
/* All of the printing ASCII characters from space (32) to the tilde (126) */
|
||||||
static const char ascii_sample[] =
|
static const char ascii_sample[] =
|
||||||
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||||
char *converted;
|
char *converted;
|
||||||
gsize bytes_read = 0, bytes_written = 0;
|
gsize bytes_read = 0, bytes_written = 0;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (encoding->validity_checked)
|
if (encoding->validity_checked)
|
||||||
return encoding->valid;
|
return encoding->valid;
|
||||||
|
|
||||||
/* Test that the encoding is a proper superset of ASCII (which naive
|
/* Test that the encoding is a proper superset of ASCII (which naive
|
||||||
* apps are going to use anyway) by attempting to validate the text
|
* apps are going to use anyway) by attempting to validate the text
|
||||||
* using the current encoding. This also flushes out any encodings
|
* using the current encoding. This also flushes out any encodings
|
||||||
* which the underlying GIConv implementation can't support.
|
* which the underlying GIConv implementation can't support.
|
||||||
*/
|
*/
|
||||||
converted = g_convert (ascii_sample, sizeof (ascii_sample) - 1,
|
converted = g_convert (ascii_sample, sizeof (ascii_sample) - 1,
|
||||||
terminal_encoding_get_charset (encoding), "UTF-8",
|
terminal_encoding_get_charset (encoding), "UTF-8",
|
||||||
&bytes_read, &bytes_written, &error);
|
&bytes_read, &bytes_written, &error);
|
||||||
|
|
||||||
/* The encoding is only valid if ASCII passes through cleanly. */
|
/* The encoding is only valid if ASCII passes through cleanly. */
|
||||||
encoding->valid = (bytes_read == (sizeof (ascii_sample) - 1)) &&
|
encoding->valid = (bytes_read == (sizeof (ascii_sample) - 1)) &&
|
||||||
(converted != NULL) &&
|
(converted != NULL) &&
|
||||||
(strcmp (converted, ascii_sample) == 0);
|
(strcmp (converted, ascii_sample) == 0);
|
||||||
|
|
||||||
#ifdef MATE_ENABLE_DEBUG
|
#ifdef MATE_ENABLE_DEBUG
|
||||||
_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ENCODINGS)
|
_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ENCODINGS)
|
||||||
{
|
{
|
||||||
if (!encoding->valid)
|
if (!encoding->valid)
|
||||||
{
|
{
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
||||||
"Rejecting encoding %s as invalid:\n",
|
"Rejecting encoding %s as invalid:\n",
|
||||||
terminal_encoding_get_charset (encoding));
|
terminal_encoding_get_charset (encoding));
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
||||||
" input \"%s\"\n",
|
" input \"%s\"\n",
|
||||||
ascii_sample);
|
ascii_sample);
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
||||||
" output \"%s\" bytes read %u written %u\n",
|
" output \"%s\" bytes read %u written %u\n",
|
||||||
converted ? converted : "(null)", bytes_read, bytes_written);
|
converted ? converted : "(null)", bytes_read, bytes_written);
|
||||||
if (error)
|
if (error)
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
||||||
" Error: %s\n",
|
" Error: %s\n",
|
||||||
error->message);
|
error->message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
_terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
|
||||||
"Encoding %s is valid\n\n",
|
"Encoding %s is valid\n\n",
|
||||||
terminal_encoding_get_charset (encoding));
|
terminal_encoding_get_charset (encoding));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
g_free (converted);
|
g_free (converted);
|
||||||
|
|
||||||
encoding->validity_checked = TRUE;
|
encoding->validity_checked = TRUE;
|
||||||
return encoding->valid;
|
return encoding->valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
terminal_encoding_get_type (void)
|
terminal_encoding_get_type (void)
|
||||||
{
|
{
|
||||||
static GType type = 0;
|
static GType type = 0;
|
||||||
|
|
||||||
if (G_UNLIKELY (type == 0)) {
|
if (G_UNLIKELY (type == 0))
|
||||||
type = g_boxed_type_register_static (I_("TerminalEncoding"),
|
{
|
||||||
(GBoxedCopyFunc) terminal_encoding_ref,
|
type = g_boxed_type_register_static (I_("TerminalEncoding"),
|
||||||
(GBoxedFreeFunc) terminal_encoding_unref);
|
(GBoxedCopyFunc) terminal_encoding_ref,
|
||||||
}
|
(GBoxedFreeFunc) terminal_encoding_unref);
|
||||||
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_active_encodings_mateconf (void)
|
update_active_encodings_mateconf (void)
|
||||||
{
|
{
|
||||||
GSList *list, *l;
|
GSList *list, *l;
|
||||||
GSList *strings = NULL;
|
GSList *strings = NULL;
|
||||||
MateConfClient *conf;
|
MateConfClient *conf;
|
||||||
|
|
||||||
list = terminal_app_get_active_encodings (terminal_app_get ());
|
list = terminal_app_get_active_encodings (terminal_app_get ());
|
||||||
for (l = list; l != NULL; l = l->next)
|
for (l = list; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
TerminalEncoding *encoding = (TerminalEncoding *) l->data;
|
TerminalEncoding *encoding = (TerminalEncoding *) l->data;
|
||||||
|
|
||||||
strings = g_slist_prepend (strings, (gpointer) terminal_encoding_get_id (encoding));
|
strings = g_slist_prepend (strings, (gpointer) terminal_encoding_get_id (encoding));
|
||||||
}
|
}
|
||||||
|
|
||||||
conf = mateconf_client_get_default ();
|
conf = mateconf_client_get_default ();
|
||||||
mateconf_client_set_list (conf,
|
mateconf_client_set_list (conf,
|
||||||
CONF_GLOBAL_PREFIX"/active_encodings",
|
CONF_GLOBAL_PREFIX"/active_encodings",
|
||||||
MATECONF_VALUE_STRING,
|
MATECONF_VALUE_STRING,
|
||||||
strings,
|
strings,
|
||||||
NULL);
|
NULL);
|
||||||
g_object_unref (conf);
|
g_object_unref (conf);
|
||||||
|
|
||||||
g_slist_free (strings);
|
g_slist_free (strings);
|
||||||
g_slist_foreach (list, (GFunc) terminal_encoding_unref, NULL);
|
g_slist_foreach (list, (GFunc) terminal_encoding_unref, NULL);
|
||||||
g_slist_free (list);
|
g_slist_free (list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -313,78 +317,78 @@ response_callback (GtkWidget *window,
|
||||||
int id,
|
int id,
|
||||||
EncodingDialogData *data)
|
EncodingDialogData *data)
|
||||||
{
|
{
|
||||||
if (id == GTK_RESPONSE_HELP)
|
if (id == GTK_RESPONSE_HELP)
|
||||||
terminal_util_show_help ("mate-terminal-encoding-add", GTK_WINDOW (window));
|
terminal_util_show_help ("mate-terminal-encoding-add", GTK_WINDOW (window));
|
||||||
else
|
else
|
||||||
gtk_widget_destroy (GTK_WIDGET (window));
|
gtk_widget_destroy (GTK_WIDGET (window));
|
||||||
}
|
}
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
COLUMN_NAME,
|
COLUMN_NAME,
|
||||||
COLUMN_CHARSET,
|
COLUMN_CHARSET,
|
||||||
COLUMN_DATA,
|
COLUMN_DATA,
|
||||||
N_COLUMNS
|
N_COLUMNS
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
selection_changed_cb (GtkTreeSelection *selection,
|
selection_changed_cb (GtkTreeSelection *selection,
|
||||||
EncodingDialogData *data)
|
EncodingDialogData *data)
|
||||||
{
|
{
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
gboolean have_selection;
|
gboolean have_selection;
|
||||||
|
|
||||||
if (selection == data->available_selection)
|
if (selection == data->available_selection)
|
||||||
button = data->add_button;
|
button = data->add_button;
|
||||||
else if (selection == data->active_selection)
|
else if (selection == data->active_selection)
|
||||||
button = data->remove_button;
|
button = data->remove_button;
|
||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
|
||||||
have_selection = gtk_tree_selection_get_selected (selection, NULL, NULL);
|
have_selection = gtk_tree_selection_get_selected (selection, NULL, NULL);
|
||||||
gtk_widget_set_sensitive (button, have_selection);
|
gtk_widget_set_sensitive (button, have_selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
button_clicked_cb (GtkWidget *button,
|
button_clicked_cb (GtkWidget *button,
|
||||||
EncodingDialogData *data)
|
EncodingDialogData *data)
|
||||||
{
|
{
|
||||||
GtkTreeSelection *selection;
|
GtkTreeSelection *selection;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
GtkTreeIter filter_iter, iter;
|
GtkTreeIter filter_iter, iter;
|
||||||
TerminalEncoding *encoding;
|
TerminalEncoding *encoding;
|
||||||
|
|
||||||
if (button == data->add_button)
|
if (button == data->add_button)
|
||||||
selection = data->available_selection;
|
selection = data->available_selection;
|
||||||
else if (button == data->remove_button)
|
else if (button == data->remove_button)
|
||||||
selection = data->active_selection;
|
selection = data->active_selection;
|
||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
|
||||||
if (!gtk_tree_selection_get_selected (selection, &model, &filter_iter))
|
if (!gtk_tree_selection_get_selected (selection, &model, &filter_iter))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
|
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
|
||||||
&iter,
|
&iter,
|
||||||
&filter_iter);
|
&filter_iter);
|
||||||
|
|
||||||
model = GTK_TREE_MODEL (data->base_store);
|
model = GTK_TREE_MODEL (data->base_store);
|
||||||
gtk_tree_model_get (model, &iter, COLUMN_DATA, &encoding, -1);
|
gtk_tree_model_get (model, &iter, COLUMN_DATA, &encoding, -1);
|
||||||
g_assert (encoding != NULL);
|
g_assert (encoding != NULL);
|
||||||
|
|
||||||
if (button == data->add_button)
|
if (button == data->add_button)
|
||||||
encoding->is_active = TRUE;
|
encoding->is_active = TRUE;
|
||||||
else if (button == data->remove_button)
|
else if (button == data->remove_button)
|
||||||
encoding->is_active = FALSE;
|
encoding->is_active = FALSE;
|
||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
|
||||||
terminal_encoding_unref (encoding);
|
terminal_encoding_unref (encoding);
|
||||||
|
|
||||||
/* We don't need to emit row-changed here, since updating the mateconf pref
|
/* We don't need to emit row-changed here, since updating the mateconf pref
|
||||||
* will update the models.
|
* will update the models.
|
||||||
*/
|
*/
|
||||||
update_active_encodings_mateconf ();
|
update_active_encodings_mateconf ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -392,16 +396,16 @@ liststore_insert_encoding (gpointer key,
|
||||||
TerminalEncoding *encoding,
|
TerminalEncoding *encoding,
|
||||||
GtkListStore *store)
|
GtkListStore *store)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
if (!terminal_encoding_is_valid (encoding))
|
if (!terminal_encoding_is_valid (encoding))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gtk_list_store_insert_with_values (store, &iter, -1,
|
gtk_list_store_insert_with_values (store, &iter, -1,
|
||||||
COLUMN_CHARSET, terminal_encoding_get_charset (encoding),
|
COLUMN_CHARSET, terminal_encoding_get_charset (encoding),
|
||||||
COLUMN_NAME, encoding->name,
|
COLUMN_NAME, encoding->name,
|
||||||
COLUMN_DATA, encoding,
|
COLUMN_DATA, encoding,
|
||||||
-1);
|
-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -409,206 +413,206 @@ filter_active_encodings (GtkTreeModel *child_model,
|
||||||
GtkTreeIter *child_iter,
|
GtkTreeIter *child_iter,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
TerminalEncoding *encoding;
|
TerminalEncoding *encoding;
|
||||||
gboolean active = GPOINTER_TO_UINT (data);
|
gboolean active = GPOINTER_TO_UINT (data);
|
||||||
gboolean visible;
|
gboolean visible;
|
||||||
|
|
||||||
gtk_tree_model_get (child_model, child_iter, COLUMN_DATA, &encoding, -1);
|
gtk_tree_model_get (child_model, child_iter, COLUMN_DATA, &encoding, -1);
|
||||||
visible = active ? encoding->is_active : !encoding->is_active;
|
visible = active ? encoding->is_active : !encoding->is_active;
|
||||||
terminal_encoding_unref (encoding);
|
terminal_encoding_unref (encoding);
|
||||||
|
|
||||||
return visible;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkTreeModel *
|
static GtkTreeModel *
|
||||||
encodings_create_treemodel (GtkListStore *base_store,
|
encodings_create_treemodel (GtkListStore *base_store,
|
||||||
gboolean active)
|
gboolean active)
|
||||||
{
|
{
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
|
|
||||||
model = gtk_tree_model_filter_new (GTK_TREE_MODEL (base_store), NULL);
|
model = gtk_tree_model_filter_new (GTK_TREE_MODEL (base_store), NULL);
|
||||||
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
|
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
|
||||||
filter_active_encodings,
|
filter_active_encodings,
|
||||||
GUINT_TO_POINTER (active), NULL);
|
GUINT_TO_POINTER (active), NULL);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encodings_list_changed_cb (TerminalApp *app,
|
encodings_list_changed_cb (TerminalApp *app,
|
||||||
EncodingDialogData *data)
|
EncodingDialogData *data)
|
||||||
{
|
{
|
||||||
gtk_list_store_clear (data->base_store);
|
gtk_list_store_clear (data->base_store);
|
||||||
|
|
||||||
g_hash_table_foreach (terminal_app_get_encodings (app), (GHFunc) liststore_insert_encoding, data->base_store);
|
g_hash_table_foreach (terminal_app_get_encodings (app), (GHFunc) liststore_insert_encoding, data->base_store);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encoding_dialog_data_free (EncodingDialogData *data)
|
encoding_dialog_data_free (EncodingDialogData *data)
|
||||||
{
|
{
|
||||||
g_signal_handlers_disconnect_by_func (terminal_app_get (),
|
g_signal_handlers_disconnect_by_func (terminal_app_get (),
|
||||||
G_CALLBACK (encodings_list_changed_cb),
|
G_CALLBACK (encodings_list_changed_cb),
|
||||||
data);
|
data);
|
||||||
|
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
terminal_encoding_dialog_show (GtkWindow *transient_parent)
|
terminal_encoding_dialog_show (GtkWindow *transient_parent)
|
||||||
{
|
{
|
||||||
TerminalApp *app;
|
TerminalApp *app;
|
||||||
GtkCellRenderer *cell_renderer;
|
GtkCellRenderer *cell_renderer;
|
||||||
GtkTreeViewColumn *column;
|
GtkTreeViewColumn *column;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
EncodingDialogData *data;
|
EncodingDialogData *data;
|
||||||
|
|
||||||
if (encoding_dialog)
|
if (encoding_dialog)
|
||||||
{
|
{
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (encoding_dialog), transient_parent);
|
gtk_window_set_transient_for (GTK_WINDOW (encoding_dialog), transient_parent);
|
||||||
gtk_window_present (GTK_WINDOW (encoding_dialog));
|
gtk_window_present (GTK_WINDOW (encoding_dialog));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = g_new (EncodingDialogData, 1);
|
data = g_new (EncodingDialogData, 1);
|
||||||
|
|
||||||
if (!terminal_util_load_builder_file ("encodings-dialog.ui",
|
if (!terminal_util_load_builder_file ("encodings-dialog.ui",
|
||||||
"encodings-dialog", &data->dialog,
|
"encodings-dialog", &data->dialog,
|
||||||
"add-button", &data->add_button,
|
"add-button", &data->add_button,
|
||||||
"remove-button", &data->remove_button,
|
"remove-button", &data->remove_button,
|
||||||
"available-treeview", &data->available_tree_view,
|
"available-treeview", &data->available_tree_view,
|
||||||
"displayed-treeview", &data->active_tree_view,
|
"displayed-treeview", &data->active_tree_view,
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
g_free (data);
|
g_free (data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (data->dialog), "GT::Data", data, (GDestroyNotify) encoding_dialog_data_free);
|
g_object_set_data_full (G_OBJECT (data->dialog), "GT::Data", data, (GDestroyNotify) encoding_dialog_data_free);
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (data->dialog), transient_parent);
|
gtk_window_set_transient_for (GTK_WINDOW (data->dialog), transient_parent);
|
||||||
gtk_window_set_role (GTK_WINDOW (data->dialog), "mate-terminal-encodings");
|
gtk_window_set_role (GTK_WINDOW (data->dialog), "mate-terminal-encodings");
|
||||||
g_signal_connect (data->dialog, "response",
|
g_signal_connect (data->dialog, "response",
|
||||||
G_CALLBACK (response_callback), data);
|
G_CALLBACK (response_callback), data);
|
||||||
|
|
||||||
/* buttons */
|
/* buttons */
|
||||||
g_signal_connect (data->add_button, "clicked",
|
g_signal_connect (data->add_button, "clicked",
|
||||||
G_CALLBACK (button_clicked_cb), data);
|
G_CALLBACK (button_clicked_cb), data);
|
||||||
|
|
||||||
g_signal_connect (data->remove_button, "clicked",
|
g_signal_connect (data->remove_button, "clicked",
|
||||||
G_CALLBACK (button_clicked_cb), data);
|
G_CALLBACK (button_clicked_cb), data);
|
||||||
|
|
||||||
/* Tree view of available encodings */
|
|
||||||
/* Column 1 */
|
|
||||||
cell_renderer = gtk_cell_renderer_text_new ();
|
|
||||||
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
|
|
||||||
cell_renderer,
|
|
||||||
"text", COLUMN_NAME,
|
|
||||||
NULL);
|
|
||||||
gtk_tree_view_append_column (data->available_tree_view, column);
|
|
||||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
|
|
||||||
|
|
||||||
/* Column 2 */
|
|
||||||
cell_renderer = gtk_cell_renderer_text_new ();
|
|
||||||
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
|
|
||||||
cell_renderer,
|
|
||||||
"text", COLUMN_CHARSET,
|
|
||||||
NULL);
|
|
||||||
gtk_tree_view_append_column (data->available_tree_view, column);
|
|
||||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
|
|
||||||
|
|
||||||
data->available_selection = gtk_tree_view_get_selection (data->available_tree_view);
|
/* Tree view of available encodings */
|
||||||
gtk_tree_selection_set_mode (data->available_selection, GTK_SELECTION_BROWSE);
|
/* Column 1 */
|
||||||
|
cell_renderer = gtk_cell_renderer_text_new ();
|
||||||
|
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
|
||||||
|
cell_renderer,
|
||||||
|
"text", COLUMN_NAME,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (data->available_tree_view, column);
|
||||||
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
|
||||||
|
|
||||||
g_signal_connect (data->available_selection, "changed",
|
/* Column 2 */
|
||||||
G_CALLBACK (selection_changed_cb), data);
|
cell_renderer = gtk_cell_renderer_text_new ();
|
||||||
|
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
|
||||||
|
cell_renderer,
|
||||||
|
"text", COLUMN_CHARSET,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (data->available_tree_view, column);
|
||||||
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
|
||||||
|
|
||||||
/* Tree view of selected encodings */
|
data->available_selection = gtk_tree_view_get_selection (data->available_tree_view);
|
||||||
/* Column 1 */
|
gtk_tree_selection_set_mode (data->available_selection, GTK_SELECTION_BROWSE);
|
||||||
cell_renderer = gtk_cell_renderer_text_new ();
|
|
||||||
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
|
|
||||||
cell_renderer,
|
|
||||||
"text", COLUMN_NAME,
|
|
||||||
NULL);
|
|
||||||
gtk_tree_view_append_column (data->active_tree_view, column);
|
|
||||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
|
|
||||||
|
|
||||||
/* Column 2 */
|
|
||||||
cell_renderer = gtk_cell_renderer_text_new ();
|
|
||||||
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
|
|
||||||
cell_renderer,
|
|
||||||
"text", COLUMN_CHARSET,
|
|
||||||
NULL);
|
|
||||||
gtk_tree_view_append_column (data->active_tree_view, column);
|
|
||||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
|
|
||||||
|
|
||||||
/* Add the data */
|
g_signal_connect (data->available_selection, "changed",
|
||||||
|
G_CALLBACK (selection_changed_cb), data);
|
||||||
|
|
||||||
data->active_selection = gtk_tree_view_get_selection (data->active_tree_view);
|
/* Tree view of selected encodings */
|
||||||
gtk_tree_selection_set_mode (data->active_selection, GTK_SELECTION_BROWSE);
|
/* Column 1 */
|
||||||
|
cell_renderer = gtk_cell_renderer_text_new ();
|
||||||
|
column = gtk_tree_view_column_new_with_attributes (_("_Description"),
|
||||||
|
cell_renderer,
|
||||||
|
"text", COLUMN_NAME,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (data->active_tree_view, column);
|
||||||
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
|
||||||
|
|
||||||
g_signal_connect (data->active_selection, "changed",
|
/* Column 2 */
|
||||||
G_CALLBACK (selection_changed_cb), data);
|
cell_renderer = gtk_cell_renderer_text_new ();
|
||||||
|
column = gtk_tree_view_column_new_with_attributes (_("_Encoding"),
|
||||||
|
cell_renderer,
|
||||||
|
"text", COLUMN_CHARSET,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (data->active_tree_view, column);
|
||||||
|
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CHARSET);
|
||||||
|
|
||||||
data->base_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, TERMINAL_TYPE_ENCODING);
|
/* Add the data */
|
||||||
|
|
||||||
app = terminal_app_get ();
|
data->active_selection = gtk_tree_view_get_selection (data->active_tree_view);
|
||||||
encodings_list_changed_cb (app, data);
|
gtk_tree_selection_set_mode (data->active_selection, GTK_SELECTION_BROWSE);
|
||||||
g_signal_connect (app, "encoding-list-changed",
|
|
||||||
G_CALLBACK (encodings_list_changed_cb), data);
|
|
||||||
|
|
||||||
/* Now turn on sorting */
|
g_signal_connect (data->active_selection, "changed",
|
||||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->base_store),
|
G_CALLBACK (selection_changed_cb), data);
|
||||||
COLUMN_NAME,
|
|
||||||
GTK_SORT_ASCENDING);
|
|
||||||
|
|
||||||
model = encodings_create_treemodel (data->base_store, FALSE);
|
|
||||||
gtk_tree_view_set_model (data->available_tree_view, model);
|
|
||||||
g_object_unref (model);
|
|
||||||
|
|
||||||
model = encodings_create_treemodel (data->base_store, TRUE);
|
data->base_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, TERMINAL_TYPE_ENCODING);
|
||||||
gtk_tree_view_set_model (data->active_tree_view, model);
|
|
||||||
g_object_unref (model);
|
|
||||||
|
|
||||||
g_object_unref (data->base_store);
|
app = terminal_app_get ();
|
||||||
|
encodings_list_changed_cb (app, data);
|
||||||
|
g_signal_connect (app, "encoding-list-changed",
|
||||||
|
G_CALLBACK (encodings_list_changed_cb), data);
|
||||||
|
|
||||||
gtk_window_present (GTK_WINDOW (data->dialog));
|
/* Now turn on sorting */
|
||||||
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->base_store),
|
||||||
|
COLUMN_NAME,
|
||||||
|
GTK_SORT_ASCENDING);
|
||||||
|
|
||||||
encoding_dialog = data->dialog;
|
model = encodings_create_treemodel (data->base_store, FALSE);
|
||||||
g_signal_connect (data->dialog, "destroy",
|
gtk_tree_view_set_model (data->available_tree_view, model);
|
||||||
G_CALLBACK (gtk_widget_destroyed), &encoding_dialog);
|
g_object_unref (model);
|
||||||
|
|
||||||
|
model = encodings_create_treemodel (data->base_store, TRUE);
|
||||||
|
gtk_tree_view_set_model (data->active_tree_view, model);
|
||||||
|
g_object_unref (model);
|
||||||
|
|
||||||
|
g_object_unref (data->base_store);
|
||||||
|
|
||||||
|
gtk_window_present (GTK_WINDOW (data->dialog));
|
||||||
|
|
||||||
|
encoding_dialog = data->dialog;
|
||||||
|
g_signal_connect (data->dialog, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &encoding_dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
GHashTable *
|
GHashTable *
|
||||||
terminal_encodings_get_builtins (void)
|
terminal_encodings_get_builtins (void)
|
||||||
{
|
{
|
||||||
GHashTable *encodings_hashtable;
|
GHashTable *encodings_hashtable;
|
||||||
guint i;
|
guint i;
|
||||||
TerminalEncoding *encoding;
|
TerminalEncoding *encoding;
|
||||||
|
|
||||||
encodings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal,
|
encodings_hashtable = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL,
|
NULL,
|
||||||
(GDestroyNotify) terminal_encoding_unref);
|
(GDestroyNotify) terminal_encoding_unref);
|
||||||
|
|
||||||
|
|
||||||
/* Placeholder entry for the current locale's charset */
|
/* Placeholder entry for the current locale's charset */
|
||||||
encoding = terminal_encoding_new ("current",
|
encoding = terminal_encoding_new ("current",
|
||||||
_("Current Locale"),
|
_("Current Locale"),
|
||||||
FALSE,
|
FALSE,
|
||||||
TRUE);
|
TRUE);
|
||||||
g_hash_table_insert (encodings_hashtable,
|
g_hash_table_insert (encodings_hashtable,
|
||||||
(gpointer) terminal_encoding_get_id (encoding),
|
(gpointer) terminal_encoding_get_id (encoding),
|
||||||
encoding);
|
encoding);
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (encodings); ++i)
|
for (i = 0; i < G_N_ELEMENTS (encodings); ++i)
|
||||||
{
|
{
|
||||||
encoding = terminal_encoding_new (encodings[i].charset,
|
encoding = terminal_encoding_new (encodings[i].charset,
|
||||||
_(encodings[i].name),
|
_(encodings[i].name),
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE);
|
FALSE);
|
||||||
g_hash_table_insert (encodings_hashtable,
|
g_hash_table_insert (encodings_hashtable,
|
||||||
(gpointer) terminal_encoding_get_id (encoding),
|
(gpointer) terminal_encoding_get_id (encoding),
|
||||||
encoding);
|
encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
return encodings_hashtable;
|
return encodings_hashtable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,21 +28,21 @@
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int refcount;
|
int refcount;
|
||||||
char *id;
|
char *id;
|
||||||
char *name;
|
char *name;
|
||||||
guint valid : 1;
|
guint valid : 1;
|
||||||
guint validity_checked : 1;
|
guint validity_checked : 1;
|
||||||
guint is_custom : 1;
|
guint is_custom : 1;
|
||||||
guint is_active : 1;
|
guint is_active : 1;
|
||||||
} TerminalEncoding;
|
} TerminalEncoding;
|
||||||
|
|
||||||
GType terminal_encoding_get_type (void);
|
GType terminal_encoding_get_type (void);
|
||||||
|
|
||||||
TerminalEncoding *terminal_encoding_new (const char *charset,
|
TerminalEncoding *terminal_encoding_new (const char *charset,
|
||||||
const char *display_name,
|
const char *display_name,
|
||||||
gboolean is_custom,
|
gboolean is_custom,
|
||||||
gboolean force_valid);
|
gboolean force_valid);
|
||||||
|
|
||||||
TerminalEncoding *terminal_encoding_ref (TerminalEncoding *encoding);
|
TerminalEncoding *terminal_encoding_ref (TerminalEncoding *encoding);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
struct _TerminalInfoBarPrivate
|
struct _TerminalInfoBarPrivate
|
||||||
{
|
{
|
||||||
GtkWidget *content_box;
|
GtkWidget *content_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (TerminalInfoBar, terminal_info_bar, GTK_TYPE_INFO_BAR)
|
G_DEFINE_TYPE (TerminalInfoBar, terminal_info_bar, GTK_TYPE_INFO_BAR)
|
||||||
|
@ -36,22 +36,22 @@ G_DEFINE_TYPE (TerminalInfoBar, terminal_info_bar, GTK_TYPE_INFO_BAR)
|
||||||
static void
|
static void
|
||||||
terminal_info_bar_init (TerminalInfoBar *bar)
|
terminal_info_bar_init (TerminalInfoBar *bar)
|
||||||
{
|
{
|
||||||
GtkInfoBar *info_bar = GTK_INFO_BAR (bar);
|
GtkInfoBar *info_bar = GTK_INFO_BAR (bar);
|
||||||
TerminalInfoBarPrivate *priv;
|
TerminalInfoBarPrivate *priv;
|
||||||
|
|
||||||
priv = bar->priv = TERMINAL_INFO_BAR_GET_PRIVATE (bar);
|
priv = bar->priv = TERMINAL_INFO_BAR_GET_PRIVATE (bar);
|
||||||
|
|
||||||
priv->content_box = gtk_vbox_new (FALSE, 6);
|
priv->content_box = gtk_vbox_new (FALSE, 6);
|
||||||
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (info_bar)),
|
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (info_bar)),
|
||||||
priv->content_box, TRUE, TRUE, 0);
|
priv->content_box, TRUE, TRUE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_info_bar_class_init (TerminalInfoBarClass *klass)
|
terminal_info_bar_class_init (TerminalInfoBarClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (TerminalInfoBarPrivate));
|
g_type_class_add_private (gobject_class, sizeof (TerminalInfoBarPrivate));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public API */
|
/* public API */
|
||||||
|
@ -67,26 +67,27 @@ terminal_info_bar_new (GtkMessageType type,
|
||||||
const char *first_button_text,
|
const char *first_button_text,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
GtkWidget *info_bar;
|
GtkWidget *info_bar;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
info_bar = g_object_new (TERMINAL_TYPE_INFO_BAR,
|
info_bar = g_object_new (TERMINAL_TYPE_INFO_BAR,
|
||||||
"message-type", type,
|
"message-type", type,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
va_start (args, first_button_text);
|
va_start (args, first_button_text);
|
||||||
while (first_button_text != NULL) {
|
while (first_button_text != NULL)
|
||||||
int response_id;
|
{
|
||||||
|
int response_id;
|
||||||
|
|
||||||
response_id = va_arg (args, int);
|
response_id = va_arg (args, int);
|
||||||
gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
|
gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
|
||||||
first_button_text, response_id);
|
first_button_text, response_id);
|
||||||
|
|
||||||
first_button_text = va_arg (args, const char *);
|
first_button_text = va_arg (args, const char *);
|
||||||
}
|
}
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
return info_bar;
|
return info_bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -94,26 +95,26 @@ terminal_info_bar_format_text (TerminalInfoBar *bar,
|
||||||
const char *format,
|
const char *format,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
TerminalInfoBarPrivate *priv;
|
TerminalInfoBarPrivate *priv;
|
||||||
char *text;
|
char *text;
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
g_return_if_fail (TERMINAL_IS_INFO_BAR (bar));
|
g_return_if_fail (TERMINAL_IS_INFO_BAR (bar));
|
||||||
|
|
||||||
priv = bar->priv;
|
priv = bar->priv;
|
||||||
|
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
text = g_strdup_vprintf (format, args);
|
text = g_strdup_vprintf (format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
label = gtk_label_new (text);
|
label = gtk_label_new (text);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
|
|
||||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
|
||||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
|
|
||||||
|
|
||||||
gtk_box_pack_start (GTK_BOX (priv->content_box), label, FALSE, FALSE, 0);
|
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||||
gtk_widget_show_all (priv->content_box);
|
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||||||
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (priv->content_box), label, FALSE, FALSE, 0);
|
||||||
|
gtk_widget_show_all (priv->content_box);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,15 +36,15 @@ typedef struct _TerminalInfoBarPrivate TerminalInfoBarPrivate;
|
||||||
|
|
||||||
struct _TerminalInfoBar
|
struct _TerminalInfoBar
|
||||||
{
|
{
|
||||||
GtkInfoBar parent_instance;
|
GtkInfoBar parent_instance;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
TerminalInfoBarPrivate *priv;
|
TerminalInfoBarPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _TerminalInfoBarClass
|
struct _TerminalInfoBarClass
|
||||||
{
|
{
|
||||||
GtkInfoBarClass parent_class;
|
GtkInfoBarClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType terminal_info_bar_get_type (void);
|
GType terminal_info_bar_get_type (void);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,81 +28,82 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
gboolean remote_arguments;
|
gboolean remote_arguments;
|
||||||
char **env;
|
char **env;
|
||||||
char *startup_id;
|
char *startup_id;
|
||||||
char *display_name;
|
char *display_name;
|
||||||
int screen_number;
|
int screen_number;
|
||||||
GList *initial_windows;
|
GList *initial_windows;
|
||||||
gboolean default_window_menubar_forced;
|
gboolean default_window_menubar_forced;
|
||||||
gboolean default_window_menubar_state;
|
gboolean default_window_menubar_state;
|
||||||
gboolean default_fullscreen;
|
gboolean default_fullscreen;
|
||||||
gboolean default_maximize;
|
gboolean default_maximize;
|
||||||
char *default_role;
|
char *default_role;
|
||||||
char *default_geometry;
|
char *default_geometry;
|
||||||
char *default_working_dir;
|
char *default_working_dir;
|
||||||
char *default_title;
|
char *default_title;
|
||||||
char **exec_argv;
|
char **exec_argv;
|
||||||
char *default_profile;
|
char *default_profile;
|
||||||
gboolean default_profile_is_id;
|
gboolean default_profile_is_id;
|
||||||
|
|
||||||
gboolean execute;
|
gboolean execute;
|
||||||
gboolean use_factory;
|
gboolean use_factory;
|
||||||
double zoom;
|
double zoom;
|
||||||
|
|
||||||
char *config_file;
|
char *config_file;
|
||||||
gboolean load_config;
|
gboolean load_config;
|
||||||
gboolean save_config;
|
gboolean save_config;
|
||||||
} TerminalOptions;
|
} TerminalOptions;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *profile;
|
char *profile;
|
||||||
gboolean profile_is_id;
|
gboolean profile_is_id;
|
||||||
char **exec_argv;
|
char **exec_argv;
|
||||||
char *title;
|
char *title;
|
||||||
char *working_dir;
|
char *working_dir;
|
||||||
double zoom;
|
double zoom;
|
||||||
guint zoom_set : 1;
|
guint zoom_set : 1;
|
||||||
guint active : 1;
|
guint active : 1;
|
||||||
} InitialTab;
|
} InitialTab;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
guint source_tag;
|
guint source_tag;
|
||||||
|
|
||||||
GList *tabs; /* list of InitialTab */
|
GList *tabs; /* list of InitialTab */
|
||||||
|
|
||||||
gboolean force_menubar_state;
|
gboolean force_menubar_state;
|
||||||
gboolean menubar_state;
|
gboolean menubar_state;
|
||||||
|
|
||||||
gboolean start_fullscreen;
|
gboolean start_fullscreen;
|
||||||
gboolean start_maximized;
|
gboolean start_maximized;
|
||||||
|
|
||||||
char *geometry;
|
char *geometry;
|
||||||
char *role;
|
char *role;
|
||||||
|
|
||||||
} InitialWindow;
|
} InitialWindow;
|
||||||
|
|
||||||
#define TERMINAL_OPTION_ERROR (g_quark_from_static_string ("terminal-option-error"))
|
#define TERMINAL_OPTION_ERROR (g_quark_from_static_string ("terminal-option-error"))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
TERMINAL_OPTION_ERROR_NOT_IN_FACTORY,
|
{
|
||||||
TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS,
|
TERMINAL_OPTION_ERROR_NOT_IN_FACTORY,
|
||||||
TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE,
|
TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS,
|
||||||
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE
|
TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE,
|
||||||
|
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE
|
||||||
} TerminalOptionError;
|
} TerminalOptionError;
|
||||||
|
|
||||||
TerminalOptions *terminal_options_parse (const char *working_directory,
|
TerminalOptions *terminal_options_parse (const char *working_directory,
|
||||||
const char *display_name,
|
const char *display_name,
|
||||||
const char *startup_id,
|
const char *startup_id,
|
||||||
char **env,
|
char **env,
|
||||||
gboolean remote_arguments,
|
gboolean remote_arguments,
|
||||||
gboolean ignore_unknown_options,
|
gboolean ignore_unknown_options,
|
||||||
int *argcp,
|
int *argcp,
|
||||||
char ***argvp,
|
char ***argvp,
|
||||||
GError **error,
|
GError **error,
|
||||||
...) G_GNUC_NULL_TERMINATED;
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
|
||||||
gboolean terminal_options_merge_config (TerminalOptions *options,
|
gboolean terminal_options_merge_config (TerminalOptions *options,
|
||||||
GKeyFile *key_file,
|
GKeyFile *key_file,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,32 +28,32 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
/* this has to be kept in sync with the option menu in the profile editor UI file */
|
/* this has to be kept in sync with the option menu in the profile editor UI file */
|
||||||
TERMINAL_TITLE_REPLACE,
|
TERMINAL_TITLE_REPLACE,
|
||||||
TERMINAL_TITLE_BEFORE,
|
TERMINAL_TITLE_BEFORE,
|
||||||
TERMINAL_TITLE_AFTER,
|
TERMINAL_TITLE_AFTER,
|
||||||
TERMINAL_TITLE_IGNORE
|
TERMINAL_TITLE_IGNORE
|
||||||
} TerminalTitleMode;
|
} TerminalTitleMode;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TERMINAL_SCROLLBAR_LEFT,
|
TERMINAL_SCROLLBAR_LEFT,
|
||||||
TERMINAL_SCROLLBAR_RIGHT,
|
TERMINAL_SCROLLBAR_RIGHT,
|
||||||
TERMINAL_SCROLLBAR_HIDDEN
|
TERMINAL_SCROLLBAR_HIDDEN
|
||||||
} TerminalScrollbarPosition;
|
} TerminalScrollbarPosition;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TERMINAL_EXIT_CLOSE,
|
TERMINAL_EXIT_CLOSE,
|
||||||
TERMINAL_EXIT_RESTART,
|
TERMINAL_EXIT_RESTART,
|
||||||
TERMINAL_EXIT_HOLD
|
TERMINAL_EXIT_HOLD
|
||||||
} TerminalExitAction;
|
} TerminalExitAction;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TERMINAL_BACKGROUND_SOLID,
|
TERMINAL_BACKGROUND_SOLID,
|
||||||
TERMINAL_BACKGROUND_IMAGE,
|
TERMINAL_BACKGROUND_IMAGE,
|
||||||
TERMINAL_BACKGROUND_TRANSPARENT
|
TERMINAL_BACKGROUND_TRANSPARENT
|
||||||
} TerminalBackgroundType;
|
} TerminalBackgroundType;
|
||||||
|
|
||||||
#define TERMINAL_PALETTE_SIZE 16
|
#define TERMINAL_PALETTE_SIZE 16
|
||||||
|
@ -120,18 +120,18 @@ typedef struct _TerminalProfilePrivate TerminalProfilePrivate;
|
||||||
|
|
||||||
struct _TerminalProfile
|
struct _TerminalProfile
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
TerminalProfilePrivate *priv;
|
TerminalProfilePrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _TerminalProfileClass
|
struct _TerminalProfileClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (* forgotten) (TerminalProfile *profile);
|
void (* forgotten) (TerminalProfile *profile);
|
||||||
|
|
||||||
GHashTable *mateconf_keys;
|
GHashTable *mateconf_keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType terminal_profile_get_type (void);
|
GType terminal_profile_get_type (void);
|
||||||
|
@ -143,48 +143,48 @@ void _terminal_profile_forget (TerminalProfile *prof
|
||||||
gboolean _terminal_profile_get_forgotten (TerminalProfile *profile);
|
gboolean _terminal_profile_get_forgotten (TerminalProfile *profile);
|
||||||
|
|
||||||
TerminalProfile* _terminal_profile_clone (TerminalProfile *base_profile,
|
TerminalProfile* _terminal_profile_clone (TerminalProfile *base_profile,
|
||||||
const char *visible_name);
|
const char *visible_name);
|
||||||
|
|
||||||
gboolean terminal_profile_property_locked (TerminalProfile *profile,
|
gboolean terminal_profile_property_locked (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
void terminal_profile_reset_property (TerminalProfile *profile,
|
void terminal_profile_reset_property (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
gboolean terminal_profile_get_property_boolean (TerminalProfile *profile,
|
gboolean terminal_profile_get_property_boolean (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
gconstpointer terminal_profile_get_property_boxed (TerminalProfile *profile,
|
gconstpointer terminal_profile_get_property_boxed (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
double terminal_profile_get_property_double (TerminalProfile *profile,
|
double terminal_profile_get_property_double (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
int terminal_profile_get_property_enum (TerminalProfile *profile,
|
int terminal_profile_get_property_enum (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
int terminal_profile_get_property_int (TerminalProfile *profile,
|
int terminal_profile_get_property_int (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
gpointer terminal_profile_get_property_object (TerminalProfile *profile,
|
gpointer terminal_profile_get_property_object (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
const char* terminal_profile_get_property_string (TerminalProfile *profile,
|
const char* terminal_profile_get_property_string (TerminalProfile *profile,
|
||||||
const char *prop_name);
|
const char *prop_name);
|
||||||
|
|
||||||
gboolean terminal_profile_get_palette (TerminalProfile *profile,
|
gboolean terminal_profile_get_palette (TerminalProfile *profile,
|
||||||
GdkColor *colors,
|
GdkColor *colors,
|
||||||
guint *n_colors);
|
guint *n_colors);
|
||||||
|
|
||||||
gboolean terminal_profile_get_palette_is_builtin (TerminalProfile *profile,
|
gboolean terminal_profile_get_palette_is_builtin (TerminalProfile *profile,
|
||||||
guint *n);
|
guint *n);
|
||||||
|
|
||||||
void terminal_profile_set_palette_builtin (TerminalProfile *profile,
|
void terminal_profile_set_palette_builtin (TerminalProfile *profile,
|
||||||
guint n);
|
guint n);
|
||||||
|
|
||||||
gboolean terminal_profile_modify_palette_entry (TerminalProfile *profile,
|
gboolean terminal_profile_modify_palette_entry (TerminalProfile *profile,
|
||||||
guint i,
|
guint i,
|
||||||
const GdkColor *color);
|
const GdkColor *color);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -29,27 +29,27 @@
|
||||||
|
|
||||||
struct _TerminalScreenContainerPrivate
|
struct _TerminalScreenContainerPrivate
|
||||||
{
|
{
|
||||||
TerminalScreen *screen;
|
TerminalScreen *screen;
|
||||||
#ifdef USE_SCROLLED_WINDOW
|
#ifdef USE_SCROLLED_WINDOW
|
||||||
GtkWidget *scrolled_window;
|
GtkWidget *scrolled_window;
|
||||||
#else
|
#else
|
||||||
GtkWidget *hbox;
|
GtkWidget *hbox;
|
||||||
GtkWidget *vscrollbar;
|
GtkWidget *vscrollbar;
|
||||||
#endif
|
#endif
|
||||||
GtkPolicyType hscrollbar_policy;
|
GtkPolicyType hscrollbar_policy;
|
||||||
GtkPolicyType vscrollbar_policy;
|
GtkPolicyType vscrollbar_policy;
|
||||||
GtkCornerType window_placement;
|
GtkCornerType window_placement;
|
||||||
guint window_placement_set : 1;
|
guint window_placement_set : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_SCREEN,
|
PROP_SCREEN,
|
||||||
PROP_HSCROLLBAR_POLICY,
|
PROP_HSCROLLBAR_POLICY,
|
||||||
PROP_VSCROLLBAR_POLICY,
|
PROP_VSCROLLBAR_POLICY,
|
||||||
PROP_WINDOW_PLACEMENT,
|
PROP_WINDOW_PLACEMENT,
|
||||||
PROP_WINDOW_PLACEMENT_SET
|
PROP_WINDOW_PLACEMENT_SET
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (TerminalScreenContainer, terminal_screen_container, GTK_TYPE_VBOX)
|
G_DEFINE_TYPE (TerminalScreenContainer, terminal_screen_container, GTK_TYPE_VBOX)
|
||||||
|
@ -58,43 +58,44 @@ G_DEFINE_TYPE (TerminalScreenContainer, terminal_screen_container, GTK_TYPE_VBOX
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_screen_container_set_placement_internal (TerminalScreenContainer *container,
|
terminal_screen_container_set_placement_internal (TerminalScreenContainer *container,
|
||||||
GtkCornerType corner)
|
GtkCornerType corner)
|
||||||
{
|
{
|
||||||
TerminalScreenContainerPrivate *priv = container->priv;
|
TerminalScreenContainerPrivate *priv = container->priv;
|
||||||
|
|
||||||
#ifdef USE_SCROLLED_WINDOW
|
#ifdef USE_SCROLLED_WINDOW
|
||||||
gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (priv->scrolled_window), corner);
|
gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (priv->scrolled_window), corner);
|
||||||
#else
|
#else
|
||||||
switch (corner) {
|
switch (corner)
|
||||||
case GTK_CORNER_TOP_LEFT:
|
{
|
||||||
case GTK_CORNER_BOTTOM_LEFT:
|
case GTK_CORNER_TOP_LEFT:
|
||||||
gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 1);
|
case GTK_CORNER_BOTTOM_LEFT:
|
||||||
break;
|
gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 1);
|
||||||
case GTK_CORNER_TOP_RIGHT:
|
break;
|
||||||
case GTK_CORNER_BOTTOM_RIGHT:
|
case GTK_CORNER_TOP_RIGHT:
|
||||||
gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 0);
|
case GTK_CORNER_BOTTOM_RIGHT:
|
||||||
break;
|
gtk_box_reorder_child (GTK_BOX (priv->hbox), priv->vscrollbar, 0);
|
||||||
default:
|
break;
|
||||||
g_assert_not_reached ();
|
default:
|
||||||
}
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
priv->window_placement = corner;
|
priv->window_placement = corner;
|
||||||
g_object_notify (G_OBJECT (container), "window-placement");
|
g_object_notify (G_OBJECT (container), "window-placement");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_screen_container_set_placement_set (TerminalScreenContainer *container,
|
terminal_screen_container_set_placement_set (TerminalScreenContainer *container,
|
||||||
gboolean set)
|
gboolean set)
|
||||||
{
|
{
|
||||||
TerminalScreenContainerPrivate *priv = container->priv;
|
TerminalScreenContainerPrivate *priv = container->priv;
|
||||||
|
|
||||||
#ifdef USE_SCROLLED_WINDOW
|
#ifdef USE_SCROLLED_WINDOW
|
||||||
g_object_set (priv->scrolled_window, "window-placement-set", set, NULL);
|
g_object_set (priv->scrolled_window, "window-placement-set", set, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
priv->window_placement_set = set != FALSE;
|
priv->window_placement_set = set != FALSE;
|
||||||
g_object_notify (G_OBJECT (container), "window-placement-set");
|
g_object_notify (G_OBJECT (container), "window-placement-set");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_SCROLLED_WINDOW) && defined(MATE_ENABLE_DEBUG)
|
#if defined(USE_SCROLLED_WINDOW) && defined(MATE_ENABLE_DEBUG)
|
||||||
|
@ -103,9 +104,9 @@ size_request_cb (GtkWidget *widget,
|
||||||
GtkRequisition *req,
|
GtkRequisition *req,
|
||||||
TerminalScreenContainer *container)
|
TerminalScreenContainer *container)
|
||||||
{
|
{
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
|
_terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
|
||||||
"[screen %p] scrolled-window size req %d : %d\n",
|
"[screen %p] scrolled-window size req %d : %d\n",
|
||||||
container->priv->screen, req->width, req->height);
|
container->priv->screen, req->width, req->height);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -114,66 +115,66 @@ size_request_cb (GtkWidget *widget,
|
||||||
static void
|
static void
|
||||||
terminal_screen_container_init (TerminalScreenContainer *container)
|
terminal_screen_container_init (TerminalScreenContainer *container)
|
||||||
{
|
{
|
||||||
TerminalScreenContainerPrivate *priv;
|
TerminalScreenContainerPrivate *priv;
|
||||||
|
|
||||||
priv = container->priv = TERMINAL_SCREEN_CONTAINER_GET_PRIVATE (container);
|
priv = container->priv = TERMINAL_SCREEN_CONTAINER_GET_PRIVATE (container);
|
||||||
|
|
||||||
priv->hscrollbar_policy = GTK_POLICY_AUTOMATIC;
|
priv->hscrollbar_policy = GTK_POLICY_AUTOMATIC;
|
||||||
priv->vscrollbar_policy = GTK_POLICY_AUTOMATIC;
|
priv->vscrollbar_policy = GTK_POLICY_AUTOMATIC;
|
||||||
priv->window_placement = GTK_CORNER_BOTTOM_RIGHT;
|
priv->window_placement = GTK_CORNER_BOTTOM_RIGHT;
|
||||||
priv->window_placement_set = FALSE;
|
priv->window_placement_set = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
terminal_screen_container_constructor (GType type,
|
terminal_screen_container_constructor (GType type,
|
||||||
guint n_construct_properties,
|
guint n_construct_properties,
|
||||||
GObjectConstructParam *construct_params)
|
GObjectConstructParam *construct_params)
|
||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
TerminalScreenContainer *container;
|
TerminalScreenContainer *container;
|
||||||
TerminalScreenContainerPrivate *priv;
|
TerminalScreenContainerPrivate *priv;
|
||||||
|
|
||||||
object = G_OBJECT_CLASS (terminal_screen_container_parent_class)->constructor
|
object = G_OBJECT_CLASS (terminal_screen_container_parent_class)->constructor
|
||||||
(type, n_construct_properties, construct_params);
|
(type, n_construct_properties, construct_params);
|
||||||
|
|
||||||
container = TERMINAL_SCREEN_CONTAINER (object);
|
container = TERMINAL_SCREEN_CONTAINER (object);
|
||||||
priv = container->priv;
|
priv = container->priv;
|
||||||
|
|
||||||
g_assert (priv->screen != NULL);
|
g_assert (priv->screen != NULL);
|
||||||
|
|
||||||
#ifdef USE_SCROLLED_WINDOW
|
#ifdef USE_SCROLLED_WINDOW
|
||||||
priv->scrolled_window = gtk_scrolled_window_new (NULL, vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen)));
|
priv->scrolled_window = gtk_scrolled_window_new (NULL, vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen)));
|
||||||
|
|
||||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window),
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window),
|
||||||
priv->hscrollbar_policy,
|
priv->hscrollbar_policy,
|
||||||
priv->vscrollbar_policy);
|
priv->vscrollbar_policy);
|
||||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scrolled_window),
|
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scrolled_window),
|
||||||
GTK_SHADOW_NONE);
|
GTK_SHADOW_NONE);
|
||||||
gtk_container_add (GTK_CONTAINER (priv->scrolled_window), GTK_WIDGET (priv->screen));
|
gtk_container_add (GTK_CONTAINER (priv->scrolled_window), GTK_WIDGET (priv->screen));
|
||||||
gtk_widget_show (GTK_WIDGET (priv->screen));
|
gtk_widget_show (GTK_WIDGET (priv->screen));
|
||||||
gtk_box_pack_end (GTK_BOX (container), priv->scrolled_window, TRUE, TRUE, 0);
|
gtk_box_pack_end (GTK_BOX (container), priv->scrolled_window, TRUE, TRUE, 0);
|
||||||
gtk_widget_show (priv->scrolled_window);
|
gtk_widget_show (priv->scrolled_window);
|
||||||
|
|
||||||
#ifdef MATE_ENABLE_DEBUG
|
#ifdef MATE_ENABLE_DEBUG
|
||||||
g_signal_connect (priv->scrolled_window, "size-request", G_CALLBACK (size_request_cb), container);
|
g_signal_connect (priv->scrolled_window, "size-request", G_CALLBACK (size_request_cb), container);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
priv->hbox = gtk_hbox_new (FALSE, 0);
|
priv->hbox = gtk_hbox_new (FALSE, 0);
|
||||||
|
|
||||||
priv->vscrollbar = gtk_vscrollbar_new (vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen)));
|
priv->vscrollbar = gtk_vscrollbar_new (vte_terminal_get_adjustment (VTE_TERMINAL (priv->screen)));
|
||||||
|
|
||||||
gtk_box_pack_start (GTK_BOX (priv->hbox), GTK_WIDGET (priv->screen), TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (priv->hbox), GTK_WIDGET (priv->screen), TRUE, TRUE, 0);
|
||||||
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->vscrollbar, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->vscrollbar, FALSE, FALSE, 0);
|
||||||
|
|
||||||
gtk_box_pack_end (GTK_BOX (container), priv->hbox, TRUE, TRUE, 0);
|
gtk_box_pack_end (GTK_BOX (container), priv->hbox, TRUE, TRUE, 0);
|
||||||
gtk_widget_show_all (priv->hbox);
|
gtk_widget_show_all (priv->hbox);
|
||||||
#endif /* USE_SCROLLED_WINDOW */
|
#endif /* USE_SCROLLED_WINDOW */
|
||||||
|
|
||||||
_terminal_screen_update_scrollbar (priv->screen);
|
_terminal_screen_update_scrollbar (priv->screen);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -182,28 +183,29 @@ terminal_screen_container_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object);
|
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object);
|
||||||
TerminalScreenContainerPrivate *priv = container->priv;
|
TerminalScreenContainerPrivate *priv = container->priv;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id)
|
||||||
case PROP_SCREEN:
|
{
|
||||||
break;
|
case PROP_SCREEN:
|
||||||
case PROP_HSCROLLBAR_POLICY:
|
break;
|
||||||
g_value_set_enum (value, priv->hscrollbar_policy);
|
case PROP_HSCROLLBAR_POLICY:
|
||||||
break;
|
g_value_set_enum (value, priv->hscrollbar_policy);
|
||||||
case PROP_VSCROLLBAR_POLICY:
|
break;
|
||||||
g_value_set_enum (value, priv->vscrollbar_policy);
|
case PROP_VSCROLLBAR_POLICY:
|
||||||
break;
|
g_value_set_enum (value, priv->vscrollbar_policy);
|
||||||
case PROP_WINDOW_PLACEMENT:
|
break;
|
||||||
g_value_set_enum (value, priv->window_placement);
|
case PROP_WINDOW_PLACEMENT:
|
||||||
break;
|
g_value_set_enum (value, priv->window_placement);
|
||||||
case PROP_WINDOW_PLACEMENT_SET:
|
break;
|
||||||
g_value_set_boolean (value, priv->window_placement_set);
|
case PROP_WINDOW_PLACEMENT_SET:
|
||||||
break;
|
g_value_set_boolean (value, priv->window_placement_set);
|
||||||
default:
|
break;
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
default:
|
||||||
break;
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -212,88 +214,89 @@ terminal_screen_container_set_property (GObject *object,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object);
|
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (object);
|
||||||
TerminalScreenContainerPrivate *priv = container->priv;
|
TerminalScreenContainerPrivate *priv = container->priv;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id)
|
||||||
case PROP_SCREEN:
|
{
|
||||||
priv->screen = g_value_get_object (value);
|
case PROP_SCREEN:
|
||||||
break;
|
priv->screen = g_value_get_object (value);
|
||||||
case PROP_HSCROLLBAR_POLICY:
|
break;
|
||||||
terminal_screen_container_set_policy (container,
|
case PROP_HSCROLLBAR_POLICY:
|
||||||
g_value_get_enum (value),
|
terminal_screen_container_set_policy (container,
|
||||||
priv->vscrollbar_policy);
|
g_value_get_enum (value),
|
||||||
break;
|
priv->vscrollbar_policy);
|
||||||
case PROP_VSCROLLBAR_POLICY:
|
break;
|
||||||
terminal_screen_container_set_policy (container,
|
case PROP_VSCROLLBAR_POLICY:
|
||||||
priv->hscrollbar_policy,
|
terminal_screen_container_set_policy (container,
|
||||||
g_value_get_enum (value));
|
priv->hscrollbar_policy,
|
||||||
break;
|
g_value_get_enum (value));
|
||||||
case PROP_WINDOW_PLACEMENT:
|
break;
|
||||||
terminal_screen_container_set_placement_internal (container, g_value_get_enum (value));
|
case PROP_WINDOW_PLACEMENT:
|
||||||
break;
|
terminal_screen_container_set_placement_internal (container, g_value_get_enum (value));
|
||||||
case PROP_WINDOW_PLACEMENT_SET:
|
break;
|
||||||
terminal_screen_container_set_placement_set (container, g_value_get_boolean (value));
|
case PROP_WINDOW_PLACEMENT_SET:
|
||||||
break;
|
terminal_screen_container_set_placement_set (container, g_value_get_boolean (value));
|
||||||
default:
|
break;
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
default:
|
||||||
break;
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_screen_container_class_init (TerminalScreenContainerClass *klass)
|
terminal_screen_container_class_init (TerminalScreenContainerClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (TerminalScreenContainerPrivate));
|
g_type_class_add_private (gobject_class, sizeof (TerminalScreenContainerPrivate));
|
||||||
|
|
||||||
gobject_class->constructor = terminal_screen_container_constructor;
|
gobject_class->constructor = terminal_screen_container_constructor;
|
||||||
gobject_class->get_property = terminal_screen_container_get_property;
|
gobject_class->get_property = terminal_screen_container_get_property;
|
||||||
gobject_class->set_property = terminal_screen_container_set_property;
|
gobject_class->set_property = terminal_screen_container_set_property;
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class,
|
(gobject_class,
|
||||||
PROP_SCREEN,
|
PROP_SCREEN,
|
||||||
g_param_spec_object ("screen", NULL, NULL,
|
g_param_spec_object ("screen", NULL, NULL,
|
||||||
TERMINAL_TYPE_SCREEN,
|
TERMINAL_TYPE_SCREEN,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class,
|
(gobject_class,
|
||||||
PROP_HSCROLLBAR_POLICY,
|
PROP_HSCROLLBAR_POLICY,
|
||||||
g_param_spec_enum ("hscrollbar-policy", NULL, NULL,
|
g_param_spec_enum ("hscrollbar-policy", NULL, NULL,
|
||||||
GTK_TYPE_POLICY_TYPE,
|
GTK_TYPE_POLICY_TYPE,
|
||||||
GTK_POLICY_AUTOMATIC,
|
GTK_POLICY_AUTOMATIC,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class,
|
(gobject_class,
|
||||||
PROP_VSCROLLBAR_POLICY,
|
PROP_VSCROLLBAR_POLICY,
|
||||||
g_param_spec_enum ("vscrollbar-policy", NULL, NULL,
|
g_param_spec_enum ("vscrollbar-policy", NULL, NULL,
|
||||||
GTK_TYPE_POLICY_TYPE,
|
GTK_TYPE_POLICY_TYPE,
|
||||||
GTK_POLICY_AUTOMATIC,
|
GTK_POLICY_AUTOMATIC,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class,
|
(gobject_class,
|
||||||
PROP_WINDOW_PLACEMENT,
|
PROP_WINDOW_PLACEMENT,
|
||||||
g_param_spec_enum ("window-placement", NULL, NULL,
|
g_param_spec_enum ("window-placement", NULL, NULL,
|
||||||
GTK_TYPE_CORNER_TYPE,
|
GTK_TYPE_CORNER_TYPE,
|
||||||
GTK_CORNER_TOP_LEFT,
|
GTK_CORNER_TOP_LEFT,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class,
|
(gobject_class,
|
||||||
PROP_WINDOW_PLACEMENT_SET,
|
PROP_WINDOW_PLACEMENT_SET,
|
||||||
g_param_spec_boolean ("window-placement-set", NULL, NULL,
|
g_param_spec_boolean ("window-placement-set", NULL, NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public API */
|
/* public API */
|
||||||
|
@ -307,9 +310,9 @@ terminal_screen_container_class_init (TerminalScreenContainerClass *klass)
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
terminal_screen_container_new (TerminalScreen *screen)
|
terminal_screen_container_new (TerminalScreen *screen)
|
||||||
{
|
{
|
||||||
return g_object_new (TERMINAL_TYPE_SCREEN_CONTAINER,
|
return g_object_new (TERMINAL_TYPE_SCREEN_CONTAINER,
|
||||||
"screen", screen,
|
"screen", screen,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -321,9 +324,9 @@ terminal_screen_container_new (TerminalScreen *screen)
|
||||||
TerminalScreen *
|
TerminalScreen *
|
||||||
terminal_screen_container_get_screen (TerminalScreenContainer *container)
|
terminal_screen_container_get_screen (TerminalScreenContainer *container)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container), NULL);
|
g_return_val_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container), NULL);
|
||||||
|
|
||||||
return container->priv->screen;
|
return container->priv->screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -335,9 +338,9 @@ terminal_screen_container_get_screen (TerminalScreenContainer *container)
|
||||||
TerminalScreenContainer *
|
TerminalScreenContainer *
|
||||||
terminal_screen_container_get_from_screen (TerminalScreen *screen)
|
terminal_screen_container_get_from_screen (TerminalScreen *screen)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
|
g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
|
||||||
|
|
||||||
return TERMINAL_SCREEN_CONTAINER (gtk_widget_get_ancestor (GTK_WIDGET (screen), TERMINAL_TYPE_SCREEN_CONTAINER));
|
return TERMINAL_SCREEN_CONTAINER (gtk_widget_get_ancestor (GTK_WIDGET (screen), TERMINAL_TYPE_SCREEN_CONTAINER));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -353,42 +356,45 @@ terminal_screen_container_set_policy (TerminalScreenContainer *container,
|
||||||
GtkPolicyType hpolicy G_GNUC_UNUSED,
|
GtkPolicyType hpolicy G_GNUC_UNUSED,
|
||||||
GtkPolicyType vpolicy)
|
GtkPolicyType vpolicy)
|
||||||
{
|
{
|
||||||
TerminalScreenContainerPrivate *priv;
|
TerminalScreenContainerPrivate *priv;
|
||||||
GObject *object;
|
GObject *object;
|
||||||
|
|
||||||
g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container));
|
g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container));
|
||||||
|
|
||||||
object = G_OBJECT (container);
|
object = G_OBJECT (container);
|
||||||
priv = container->priv;
|
priv = container->priv;
|
||||||
|
|
||||||
g_object_freeze_notify (object);
|
g_object_freeze_notify (object);
|
||||||
|
|
||||||
if (priv->hscrollbar_policy != hpolicy) {
|
if (priv->hscrollbar_policy != hpolicy)
|
||||||
priv->hscrollbar_policy = hpolicy;
|
{
|
||||||
g_object_notify (object, "hscrollbar-policy");
|
priv->hscrollbar_policy = hpolicy;
|
||||||
}
|
g_object_notify (object, "hscrollbar-policy");
|
||||||
if (priv->vscrollbar_policy != vpolicy) {
|
}
|
||||||
priv->vscrollbar_policy = vpolicy;
|
if (priv->vscrollbar_policy != vpolicy)
|
||||||
g_object_notify (object, "vscrollbar-policy");
|
{
|
||||||
}
|
priv->vscrollbar_policy = vpolicy;
|
||||||
|
g_object_notify (object, "vscrollbar-policy");
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_SCROLLED_WINDOW
|
#ifdef USE_SCROLLED_WINDOW
|
||||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), hpolicy, vpolicy);
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), hpolicy, vpolicy);
|
||||||
#else
|
#else
|
||||||
switch (vpolicy) {
|
switch (vpolicy)
|
||||||
case GTK_POLICY_NEVER:
|
{
|
||||||
gtk_widget_hide (priv->vscrollbar);
|
case GTK_POLICY_NEVER:
|
||||||
break;
|
gtk_widget_hide (priv->vscrollbar);
|
||||||
case GTK_POLICY_AUTOMATIC:
|
break;
|
||||||
case GTK_POLICY_ALWAYS:
|
case GTK_POLICY_AUTOMATIC:
|
||||||
gtk_widget_show (priv->vscrollbar);
|
case GTK_POLICY_ALWAYS:
|
||||||
break;
|
gtk_widget_show (priv->vscrollbar);
|
||||||
default:
|
break;
|
||||||
g_assert_not_reached ();
|
default:
|
||||||
}
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_object_thaw_notify (object);
|
g_object_thaw_notify (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -400,10 +406,10 @@ terminal_screen_container_set_policy (TerminalScreenContainer *container,
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
terminal_screen_container_set_placement (TerminalScreenContainer *container,
|
terminal_screen_container_set_placement (TerminalScreenContainer *container,
|
||||||
GtkCornerType corner)
|
GtkCornerType corner)
|
||||||
{
|
{
|
||||||
g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container));
|
g_return_if_fail (TERMINAL_IS_SCREEN_CONTAINER (container));
|
||||||
|
|
||||||
terminal_screen_container_set_placement_internal (container, corner);
|
terminal_screen_container_set_placement_internal (container, corner);
|
||||||
terminal_screen_container_set_placement_set (container, TRUE);
|
terminal_screen_container_set_placement_set (container, TRUE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,15 +38,15 @@ typedef struct _TerminalScreenContainerPrivate TerminalScreenContainerPrivate;
|
||||||
|
|
||||||
struct _TerminalScreenContainer
|
struct _TerminalScreenContainer
|
||||||
{
|
{
|
||||||
GtkVBox parent_instance;
|
GtkVBox parent_instance;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
TerminalScreenContainerPrivate *priv;
|
TerminalScreenContainerPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _TerminalScreenContainerClass
|
struct _TerminalScreenContainerClass
|
||||||
{
|
{
|
||||||
GtkVBoxClass parent_class;
|
GtkVBoxClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType terminal_screen_container_get_type (void);
|
GType terminal_screen_container_get_type (void);
|
||||||
|
@ -58,11 +58,11 @@ TerminalScreen *terminal_screen_container_get_screen (TerminalScreenContainer *c
|
||||||
TerminalScreenContainer *terminal_screen_container_get_from_screen (TerminalScreen *screen);
|
TerminalScreenContainer *terminal_screen_container_get_from_screen (TerminalScreen *screen);
|
||||||
|
|
||||||
void terminal_screen_container_set_policy (TerminalScreenContainer *container,
|
void terminal_screen_container_set_policy (TerminalScreenContainer *container,
|
||||||
GtkPolicyType hpolicy,
|
GtkPolicyType hpolicy,
|
||||||
GtkPolicyType vpolicy);
|
GtkPolicyType vpolicy);
|
||||||
|
|
||||||
void terminal_screen_container_set_placement (TerminalScreenContainer *container,
|
void terminal_screen_container_set_placement (TerminalScreenContainer *container,
|
||||||
GtkCornerType corner);
|
GtkCornerType corner);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,12 +27,13 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
FLAVOR_AS_IS,
|
{
|
||||||
FLAVOR_DEFAULT_TO_HTTP,
|
FLAVOR_AS_IS,
|
||||||
FLAVOR_VOIP_CALL,
|
FLAVOR_DEFAULT_TO_HTTP,
|
||||||
FLAVOR_EMAIL,
|
FLAVOR_VOIP_CALL,
|
||||||
FLAVOR_SKEY
|
FLAVOR_EMAIL,
|
||||||
|
FLAVOR_SKEY
|
||||||
} TerminalURLFlavour;
|
} TerminalURLFlavour;
|
||||||
|
|
||||||
/* Forward decls */
|
/* Forward decls */
|
||||||
|
@ -52,24 +53,24 @@ typedef struct _TerminalScreenPrivate TerminalScreenPrivate;
|
||||||
|
|
||||||
struct _TerminalScreen
|
struct _TerminalScreen
|
||||||
{
|
{
|
||||||
VteTerminal parent_instance;
|
VteTerminal parent_instance;
|
||||||
|
|
||||||
TerminalScreenPrivate *priv;
|
TerminalScreenPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _TerminalScreenClass
|
struct _TerminalScreenClass
|
||||||
{
|
{
|
||||||
VteTerminalClass parent_class;
|
VteTerminalClass parent_class;
|
||||||
|
|
||||||
void (* profile_set) (TerminalScreen *screen,
|
void (* profile_set) (TerminalScreen *screen,
|
||||||
TerminalProfile *old_profile);
|
TerminalProfile *old_profile);
|
||||||
void (* show_popup_menu) (TerminalScreen *screen,
|
void (* show_popup_menu) (TerminalScreen *screen,
|
||||||
TerminalScreenPopupInfo *info);
|
TerminalScreenPopupInfo *info);
|
||||||
gboolean (* match_clicked) (TerminalScreen *screen,
|
gboolean (* match_clicked) (TerminalScreen *screen,
|
||||||
const char *url,
|
const char *url,
|
||||||
int flavour,
|
int flavour,
|
||||||
guint state);
|
guint state);
|
||||||
void (* close_screen) (TerminalScreen *screen);
|
void (* close_screen) (TerminalScreen *screen);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType terminal_screen_get_type (void) G_GNUC_CONST;
|
GType terminal_screen_get_type (void) G_GNUC_CONST;
|
||||||
|
@ -86,11 +87,11 @@ void terminal_screen_set_profile (TerminalScreen *screen,
|
||||||
TerminalProfile* terminal_screen_get_profile (TerminalScreen *screen);
|
TerminalProfile* terminal_screen_get_profile (TerminalScreen *screen);
|
||||||
|
|
||||||
void terminal_screen_set_override_command (TerminalScreen *screen,
|
void terminal_screen_set_override_command (TerminalScreen *screen,
|
||||||
char **argv);
|
char **argv);
|
||||||
const char** terminal_screen_get_override_command (TerminalScreen *screen);
|
const char** terminal_screen_get_override_command (TerminalScreen *screen);
|
||||||
|
|
||||||
void terminal_screen_set_initial_environment (TerminalScreen *screen,
|
void terminal_screen_set_initial_environment (TerminalScreen *screen,
|
||||||
char **argv);
|
char **argv);
|
||||||
char ** terminal_screen_get_initial_environment (TerminalScreen *screen);
|
char ** terminal_screen_get_initial_environment (TerminalScreen *screen);
|
||||||
|
|
||||||
const char* terminal_screen_get_raw_title (TerminalScreen *screen);
|
const char* terminal_screen_get_raw_title (TerminalScreen *screen);
|
||||||
|
@ -102,7 +103,7 @@ void terminal_screen_set_user_title (TerminalScreen *screen,
|
||||||
const char *text);
|
const char *text);
|
||||||
|
|
||||||
void terminal_screen_set_override_title (TerminalScreen *screen,
|
void terminal_screen_set_override_title (TerminalScreen *screen,
|
||||||
const char *title);
|
const char *title);
|
||||||
|
|
||||||
const char *terminal_screen_get_dynamic_title (TerminalScreen *screen);
|
const char *terminal_screen_get_dynamic_title (TerminalScreen *screen);
|
||||||
const char *terminal_screen_get_dynamic_icon_title (TerminalScreen *screen);
|
const char *terminal_screen_get_dynamic_icon_title (TerminalScreen *screen);
|
||||||
|
@ -112,15 +113,15 @@ char *terminal_screen_get_current_dir_with_fallback (TerminalScreen *screen);
|
||||||
|
|
||||||
void terminal_screen_set_font (TerminalScreen *screen);
|
void terminal_screen_set_font (TerminalScreen *screen);
|
||||||
void terminal_screen_set_font_scale (TerminalScreen *screen,
|
void terminal_screen_set_font_scale (TerminalScreen *screen,
|
||||||
double factor);
|
double factor);
|
||||||
double terminal_screen_get_font_scale (TerminalScreen *screen);
|
double terminal_screen_get_font_scale (TerminalScreen *screen);
|
||||||
|
|
||||||
void terminal_screen_get_size (TerminalScreen *screen,
|
void terminal_screen_get_size (TerminalScreen *screen,
|
||||||
int *width_chars,
|
int *width_chars,
|
||||||
int *height_chars);
|
int *height_chars);
|
||||||
void terminal_screen_get_cell_size (TerminalScreen *screen,
|
void terminal_screen_get_cell_size (TerminalScreen *screen,
|
||||||
int *width_chars,
|
int *width_chars,
|
||||||
int *height_chars);
|
int *height_chars);
|
||||||
|
|
||||||
void _terminal_screen_update_scrollbar (TerminalScreen *screen);
|
void _terminal_screen_update_scrollbar (TerminalScreen *screen);
|
||||||
|
|
||||||
|
@ -140,15 +141,16 @@ gboolean terminal_screen_has_foreground_process (TerminalScreen *screen);
|
||||||
#define TERMINAL_SCALE_MINIMUM (TERMINAL_SCALE_XXXXX_SMALL/1.2)
|
#define TERMINAL_SCALE_MINIMUM (TERMINAL_SCALE_XXXXX_SMALL/1.2)
|
||||||
#define TERMINAL_SCALE_MAXIMUM (TERMINAL_SCALE_XXXXX_LARGE*1.2)
|
#define TERMINAL_SCALE_MAXIMUM (TERMINAL_SCALE_XXXXX_LARGE*1.2)
|
||||||
|
|
||||||
struct _TerminalScreenPopupInfo {
|
struct _TerminalScreenPopupInfo
|
||||||
int ref_count;
|
{
|
||||||
TerminalWindow *window;
|
int ref_count;
|
||||||
TerminalScreen *screen;
|
TerminalWindow *window;
|
||||||
char *string;
|
TerminalScreen *screen;
|
||||||
TerminalURLFlavour flavour;
|
char *string;
|
||||||
guint button;
|
TerminalURLFlavour flavour;
|
||||||
guint state;
|
guint button;
|
||||||
guint32 timestamp;
|
guint state;
|
||||||
|
guint32 timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info);
|
TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info);
|
||||||
|
|
|
@ -31,12 +31,12 @@
|
||||||
static GQuark
|
static GQuark
|
||||||
get_quark (void)
|
get_quark (void)
|
||||||
{
|
{
|
||||||
static GQuark quark = 0;
|
static GQuark quark = 0;
|
||||||
|
|
||||||
if (G_UNLIKELY (!quark))
|
if (G_UNLIKELY (!quark))
|
||||||
quark = g_quark_from_static_string ("GT:data");
|
quark = g_quark_from_static_string ("GT:data");
|
||||||
|
|
||||||
return quark;
|
return quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,332 +47,340 @@ get_quark (void)
|
||||||
|
|
||||||
typedef struct _TerminalSearchDialogPrivate
|
typedef struct _TerminalSearchDialogPrivate
|
||||||
{
|
{
|
||||||
GtkWidget *search_label;
|
GtkWidget *search_label;
|
||||||
GtkWidget *search_entry;
|
GtkWidget *search_entry;
|
||||||
GtkWidget *search_text_entry;
|
GtkWidget *search_text_entry;
|
||||||
GtkWidget *match_case_checkbutton;
|
GtkWidget *match_case_checkbutton;
|
||||||
GtkWidget *entire_word_checkbutton;
|
GtkWidget *entire_word_checkbutton;
|
||||||
GtkWidget *regex_checkbutton;
|
GtkWidget *regex_checkbutton;
|
||||||
GtkWidget *backwards_checkbutton;
|
GtkWidget *backwards_checkbutton;
|
||||||
GtkWidget *wrap_around_checkbutton;
|
GtkWidget *wrap_around_checkbutton;
|
||||||
|
|
||||||
GtkListStore *store;
|
GtkListStore *store;
|
||||||
GtkEntryCompletion *completion;
|
GtkEntryCompletion *completion;
|
||||||
|
|
||||||
/* Cached regex */
|
/* Cached regex */
|
||||||
GRegex *regex;
|
GRegex *regex;
|
||||||
GRegexCompileFlags regex_compile_flags;
|
GRegexCompileFlags regex_compile_flags;
|
||||||
} TerminalSearchDialogPrivate;
|
} TerminalSearchDialogPrivate;
|
||||||
|
|
||||||
|
|
||||||
static void update_sensitivity (void *unused,
|
static void update_sensitivity (void *unused,
|
||||||
GtkWidget *dialog);
|
GtkWidget *dialog);
|
||||||
static void response_handler (GtkWidget *dialog,
|
static void response_handler (GtkWidget *dialog,
|
||||||
gint response_id,
|
gint response_id,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
static void terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv);
|
static void terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv);
|
||||||
|
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
terminal_search_dialog_new (GtkWindow *parent)
|
terminal_search_dialog_new (GtkWindow *parent)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
GtkListStore *store;
|
GtkListStore *store;
|
||||||
GtkEntryCompletion *completion;
|
GtkEntryCompletion *completion;
|
||||||
|
|
||||||
priv = g_new0 (TerminalSearchDialogPrivate, 1);
|
priv = g_new0 (TerminalSearchDialogPrivate, 1);
|
||||||
|
|
||||||
if (!terminal_util_load_builder_file ("find-dialog.ui",
|
if (!terminal_util_load_builder_file ("find-dialog.ui",
|
||||||
"find-dialog", &dialog,
|
"find-dialog", &dialog,
|
||||||
"search-label", &priv->search_label,
|
"search-label", &priv->search_label,
|
||||||
"search-entry", &priv->search_entry,
|
"search-entry", &priv->search_entry,
|
||||||
"match-case-checkbutton", &priv->match_case_checkbutton,
|
"match-case-checkbutton", &priv->match_case_checkbutton,
|
||||||
"entire-word-checkbutton", &priv->entire_word_checkbutton,
|
"entire-word-checkbutton", &priv->entire_word_checkbutton,
|
||||||
"regex-checkbutton", &priv->regex_checkbutton,
|
"regex-checkbutton", &priv->regex_checkbutton,
|
||||||
"search-backwards-checkbutton", &priv->backwards_checkbutton,
|
"search-backwards-checkbutton", &priv->backwards_checkbutton,
|
||||||
"wrap-around-checkbutton", &priv->wrap_around_checkbutton,
|
"wrap-around-checkbutton", &priv->wrap_around_checkbutton,
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
g_free (priv);
|
g_free (priv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_set_qdata_full (G_OBJECT (dialog), get_quark (), priv,
|
g_object_set_qdata_full (G_OBJECT (dialog), get_quark (), priv,
|
||||||
(GDestroyNotify) terminal_search_dialog_private_destroy);
|
(GDestroyNotify) terminal_search_dialog_private_destroy);
|
||||||
|
|
||||||
|
|
||||||
priv->search_text_entry = gtk_bin_get_child (GTK_BIN (priv->search_entry));
|
priv->search_text_entry = gtk_bin_get_child (GTK_BIN (priv->search_entry));
|
||||||
gtk_widget_set_size_request (priv->search_entry, 300, -1);
|
gtk_widget_set_size_request (priv->search_entry, 300, -1);
|
||||||
|
|
||||||
priv->store = store = gtk_list_store_new (1, G_TYPE_STRING);
|
priv->store = store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||||
g_object_set (G_OBJECT (priv->search_entry),
|
g_object_set (G_OBJECT (priv->search_entry),
|
||||||
"model", store,
|
"model", store,
|
||||||
"text-column", 0,
|
"text-column", 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
priv->completion = completion = gtk_entry_completion_new ();
|
priv->completion = completion = gtk_entry_completion_new ();
|
||||||
gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store));
|
gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store));
|
||||||
gtk_entry_completion_set_text_column (completion, 0);
|
gtk_entry_completion_set_text_column (completion, 0);
|
||||||
gtk_entry_completion_set_minimum_key_length (completion, HISTORY_MIN_ITEM_LEN);
|
gtk_entry_completion_set_minimum_key_length (completion, HISTORY_MIN_ITEM_LEN);
|
||||||
gtk_entry_completion_set_popup_completion (completion, FALSE);
|
gtk_entry_completion_set_popup_completion (completion, FALSE);
|
||||||
gtk_entry_completion_set_inline_completion (completion, TRUE);
|
gtk_entry_completion_set_inline_completion (completion, TRUE);
|
||||||
gtk_entry_set_completion (GTK_ENTRY (priv->search_text_entry), completion);
|
gtk_entry_set_completion (GTK_ENTRY (priv->search_text_entry), completion);
|
||||||
|
|
||||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
|
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
|
||||||
|
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (priv->search_text_entry), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (priv->search_text_entry), TRUE);
|
||||||
g_signal_connect (priv->search_text_entry, "changed", G_CALLBACK (update_sensitivity), dialog);
|
g_signal_connect (priv->search_text_entry, "changed", G_CALLBACK (update_sensitivity), dialog);
|
||||||
g_signal_connect (priv->regex_checkbutton, "toggled", G_CALLBACK (update_sensitivity), dialog);
|
g_signal_connect (priv->regex_checkbutton, "toggled", G_CALLBACK (update_sensitivity), dialog);
|
||||||
|
|
||||||
g_signal_connect (dialog, "response", G_CALLBACK (response_handler), NULL);
|
g_signal_connect (dialog, "response", G_CALLBACK (response_handler), NULL);
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
|
||||||
|
|
||||||
return GTK_WIDGET (dialog);
|
return GTK_WIDGET (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
terminal_search_dialog_present (GtkWidget *dialog)
|
terminal_search_dialog_present (GtkWidget *dialog)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_DIALOG (dialog));
|
g_return_if_fail (GTK_IS_DIALOG (dialog));
|
||||||
|
|
||||||
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
g_return_if_fail (priv);
|
g_return_if_fail (priv);
|
||||||
|
|
||||||
gtk_window_present (GTK_WINDOW (dialog));
|
gtk_window_present (GTK_WINDOW (dialog));
|
||||||
gtk_widget_grab_focus (priv->search_text_entry);
|
gtk_widget_grab_focus (priv->search_text_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv)
|
terminal_search_dialog_private_destroy (TerminalSearchDialogPrivate *priv)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (priv->regex)
|
if (priv->regex)
|
||||||
g_regex_unref (priv->regex);
|
g_regex_unref (priv->regex);
|
||||||
|
|
||||||
g_object_unref (priv->store);
|
g_object_unref (priv->store);
|
||||||
g_object_unref (priv->completion);
|
g_object_unref (priv->completion);
|
||||||
|
|
||||||
g_free (priv);
|
g_free (priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_sensitivity (void *unused, GtkWidget *dialog)
|
update_sensitivity (void *unused, GtkWidget *dialog)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
TerminalSearchDialogPrivate *priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
const gchar *search_string;
|
const gchar *search_string;
|
||||||
gboolean valid;
|
gboolean valid;
|
||||||
|
|
||||||
if (priv->regex) {
|
if (priv->regex)
|
||||||
g_regex_unref (priv->regex);
|
{
|
||||||
priv->regex = NULL;
|
g_regex_unref (priv->regex);
|
||||||
}
|
priv->regex = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
search_string = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
|
search_string = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
|
||||||
g_return_if_fail (search_string != NULL);
|
g_return_if_fail (search_string != NULL);
|
||||||
|
|
||||||
valid = *search_string != '\0';
|
valid = *search_string != '\0';
|
||||||
|
|
||||||
if (valid && GET_FLAG (regex_checkbutton)) {
|
if (valid && GET_FLAG (regex_checkbutton))
|
||||||
/* Check that the regex is valid */
|
{
|
||||||
valid = NULL != terminal_search_dialog_get_regex (dialog);
|
/* Check that the regex is valid */
|
||||||
/* TODO show the error message somewhere */
|
valid = NULL != terminal_search_dialog_get_regex (dialog);
|
||||||
}
|
/* TODO show the error message somewhere */
|
||||||
|
}
|
||||||
|
|
||||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, valid);
|
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
remove_item (GtkListStore *store,
|
remove_item (GtkListStore *store,
|
||||||
const gchar *text)
|
const gchar *text)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
g_return_val_if_fail (text != NULL, FALSE);
|
g_return_val_if_fail (text != NULL, FALSE);
|
||||||
|
|
||||||
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
|
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
do {
|
do
|
||||||
gchar *item_text;
|
{
|
||||||
|
gchar *item_text;
|
||||||
|
|
||||||
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &item_text, -1);
|
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &item_text, -1);
|
||||||
|
|
||||||
if (item_text != NULL && strcmp (item_text, text) == 0) {
|
if (item_text != NULL && strcmp (item_text, text) == 0)
|
||||||
gtk_list_store_remove (store, &iter);
|
{
|
||||||
g_free (item_text);
|
gtk_list_store_remove (store, &iter);
|
||||||
return TRUE;
|
g_free (item_text);
|
||||||
}
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
g_free (item_text);
|
g_free (item_text);
|
||||||
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
|
}
|
||||||
|
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clamp_list_store (GtkListStore *store,
|
clamp_list_store (GtkListStore *store,
|
||||||
guint max)
|
guint max)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
/* -1 because TreePath counts from 0 */
|
/* -1 because TreePath counts from 0 */
|
||||||
path = gtk_tree_path_new_from_indices (max - 1, -1);
|
path = gtk_tree_path_new_from_indices (max - 1, -1);
|
||||||
|
|
||||||
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
|
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
|
||||||
while (1)
|
while (1)
|
||||||
if (!gtk_list_store_remove (store, &iter))
|
if (!gtk_list_store_remove (store, &iter))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gtk_tree_path_free (path);
|
gtk_tree_path_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
history_entry_insert (GtkListStore *store,
|
history_entry_insert (GtkListStore *store,
|
||||||
const gchar *text)
|
const gchar *text)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
g_return_if_fail (text != NULL);
|
g_return_if_fail (text != NULL);
|
||||||
|
|
||||||
if (g_utf8_strlen (text, -1) <= HISTORY_MIN_ITEM_LEN)
|
if (g_utf8_strlen (text, -1) <= HISTORY_MIN_ITEM_LEN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* remove the text from the store if it was already
|
/* remove the text from the store if it was already
|
||||||
* present. If it wasn't, clamp to max history - 1
|
* present. If it wasn't, clamp to max history - 1
|
||||||
* before inserting the new row, otherwise appending
|
* before inserting the new row, otherwise appending
|
||||||
* would not work */
|
* would not work */
|
||||||
|
|
||||||
if (!remove_item (store, text))
|
if (!remove_item (store, text))
|
||||||
clamp_list_store (store, HISTORY_LENGTH - 1);
|
clamp_list_store (store, HISTORY_LENGTH - 1);
|
||||||
|
|
||||||
gtk_list_store_insert (store, &iter, 0);
|
gtk_list_store_insert (store, &iter, 0);
|
||||||
gtk_list_store_set (store, &iter, 0, text, -1);
|
gtk_list_store_set (store, &iter, 0, text, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
response_handler (GtkWidget *dialog,
|
response_handler (GtkWidget *dialog,
|
||||||
gint response_id,
|
gint response_id,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
const gchar *str;
|
const gchar *str;
|
||||||
|
|
||||||
if (response_id != GTK_RESPONSE_ACCEPT) {
|
if (response_id != GTK_RESPONSE_ACCEPT)
|
||||||
gtk_widget_hide (dialog);
|
{
|
||||||
return;
|
gtk_widget_hide (dialog);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
|
|
||||||
str = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
|
str = gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
|
||||||
if (*str != '\0')
|
if (*str != '\0')
|
||||||
history_entry_insert (priv->store, str);
|
history_entry_insert (priv->store, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
terminal_search_dialog_set_search_text (GtkWidget *dialog,
|
terminal_search_dialog_set_search_text (GtkWidget *dialog,
|
||||||
const gchar *text)
|
const gchar *text)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_DIALOG (dialog));
|
g_return_if_fail (GTK_IS_DIALOG (dialog));
|
||||||
g_return_if_fail (text != NULL);
|
g_return_if_fail (text != NULL);
|
||||||
|
|
||||||
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
g_return_if_fail (priv);
|
g_return_if_fail (priv);
|
||||||
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (priv->search_text_entry), text);
|
gtk_entry_set_text (GTK_ENTRY (priv->search_text_entry), text);
|
||||||
|
|
||||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
|
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
|
||||||
GTK_RESPONSE_ACCEPT,
|
GTK_RESPONSE_ACCEPT,
|
||||||
(*text != '\0'));
|
(*text != '\0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
const gchar *
|
||||||
terminal_search_dialog_get_search_text (GtkWidget *dialog)
|
terminal_search_dialog_get_search_text (GtkWidget *dialog)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
|
g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
|
||||||
|
|
||||||
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
g_return_val_if_fail (priv, NULL);
|
g_return_val_if_fail (priv, NULL);
|
||||||
|
|
||||||
return gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
|
return gtk_entry_get_text (GTK_ENTRY (priv->search_text_entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalSearchFlags
|
TerminalSearchFlags
|
||||||
terminal_search_dialog_get_search_flags (GtkWidget *dialog)
|
terminal_search_dialog_get_search_flags (GtkWidget *dialog)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
TerminalSearchFlags flags = 0;
|
TerminalSearchFlags flags = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_DIALOG (dialog), flags);
|
g_return_val_if_fail (GTK_IS_DIALOG (dialog), flags);
|
||||||
|
|
||||||
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
g_return_val_if_fail (priv, flags);
|
g_return_val_if_fail (priv, flags);
|
||||||
|
|
||||||
if (GET_FLAG (backwards_checkbutton))
|
if (GET_FLAG (backwards_checkbutton))
|
||||||
flags |= TERMINAL_SEARCH_FLAG_BACKWARDS;
|
flags |= TERMINAL_SEARCH_FLAG_BACKWARDS;
|
||||||
|
|
||||||
if (GET_FLAG (wrap_around_checkbutton))
|
if (GET_FLAG (wrap_around_checkbutton))
|
||||||
flags |= TERMINAL_SEARCH_FLAG_WRAP_AROUND;
|
flags |= TERMINAL_SEARCH_FLAG_WRAP_AROUND;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
GRegex *
|
GRegex *
|
||||||
terminal_search_dialog_get_regex (GtkWidget *dialog)
|
terminal_search_dialog_get_regex (GtkWidget *dialog)
|
||||||
{
|
{
|
||||||
TerminalSearchDialogPrivate *priv;
|
TerminalSearchDialogPrivate *priv;
|
||||||
GRegexCompileFlags compile_flags;
|
GRegexCompileFlags compile_flags;
|
||||||
const char *text, *pattern;
|
const char *text, *pattern;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
|
g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
|
||||||
|
|
||||||
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
priv = TERMINAL_SEARCH_DIALOG_GET_PRIVATE (dialog);
|
||||||
g_return_val_if_fail (priv, NULL);
|
g_return_val_if_fail (priv, NULL);
|
||||||
|
|
||||||
pattern = text = terminal_search_dialog_get_search_text (dialog);
|
pattern = text = terminal_search_dialog_get_search_text (dialog);
|
||||||
|
|
||||||
compile_flags = G_REGEX_OPTIMIZE;
|
compile_flags = G_REGEX_OPTIMIZE;
|
||||||
|
|
||||||
if (!GET_FLAG (match_case_checkbutton))
|
if (!GET_FLAG (match_case_checkbutton))
|
||||||
compile_flags |= G_REGEX_CASELESS;
|
compile_flags |= G_REGEX_CASELESS;
|
||||||
|
|
||||||
if (GET_FLAG (regex_checkbutton))
|
if (GET_FLAG (regex_checkbutton))
|
||||||
compile_flags |= G_REGEX_MULTILINE;
|
compile_flags |= G_REGEX_MULTILINE;
|
||||||
else
|
else
|
||||||
pattern = g_regex_escape_string (text, -1);
|
pattern = g_regex_escape_string (text, -1);
|
||||||
|
|
||||||
if (GET_FLAG (entire_word_checkbutton)) {
|
if (GET_FLAG (entire_word_checkbutton))
|
||||||
const char *old_pattern = pattern;
|
{
|
||||||
pattern = g_strdup_printf ("\\b%s\\b", pattern);
|
const char *old_pattern = pattern;
|
||||||
if (old_pattern != text)
|
pattern = g_strdup_printf ("\\b%s\\b", pattern);
|
||||||
g_free ((char *) old_pattern);
|
if (old_pattern != text)
|
||||||
}
|
g_free ((char *) old_pattern);
|
||||||
|
}
|
||||||
|
|
||||||
if (!priv->regex || priv->regex_compile_flags != compile_flags) {
|
if (!priv->regex || priv->regex_compile_flags != compile_flags)
|
||||||
priv->regex_compile_flags = compile_flags;
|
{
|
||||||
if (priv->regex)
|
priv->regex_compile_flags = compile_flags;
|
||||||
g_regex_unref (priv->regex);
|
if (priv->regex)
|
||||||
|
g_regex_unref (priv->regex);
|
||||||
|
|
||||||
/* TODO Error handling */
|
/* TODO Error handling */
|
||||||
priv->regex = g_regex_new (pattern, compile_flags, 0, NULL);
|
priv->regex = g_regex_new (pattern, compile_flags, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern != text)
|
if (pattern != text)
|
||||||
g_free ((char *) pattern);
|
g_free ((char *) pattern);
|
||||||
|
|
||||||
return priv->regex;
|
return priv->regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef enum _TerminalSearchFlags {
|
typedef enum _TerminalSearchFlags
|
||||||
TERMINAL_SEARCH_FLAG_BACKWARDS = 1 << 0,
|
{
|
||||||
TERMINAL_SEARCH_FLAG_WRAP_AROUND = 1 << 1
|
TERMINAL_SEARCH_FLAG_BACKWARDS = 1 << 0,
|
||||||
|
TERMINAL_SEARCH_FLAG_WRAP_AROUND = 1 << 1
|
||||||
} TerminalSearchFlags;
|
} TerminalSearchFlags;
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,12 +37,12 @@ GtkWidget *terminal_search_dialog_new (GtkWindow *parent);
|
||||||
void terminal_search_dialog_present (GtkWidget *dialog);
|
void terminal_search_dialog_present (GtkWidget *dialog);
|
||||||
|
|
||||||
void terminal_search_dialog_set_search_text (GtkWidget *dialog,
|
void terminal_search_dialog_set_search_text (GtkWidget *dialog,
|
||||||
const gchar *text);
|
const gchar *text);
|
||||||
|
|
||||||
const gchar *terminal_search_dialog_get_search_text (GtkWidget *dialog);
|
const gchar *terminal_search_dialog_get_search_text (GtkWidget *dialog);
|
||||||
|
|
||||||
TerminalSearchFlags
|
TerminalSearchFlags
|
||||||
terminal_search_dialog_get_search_flags(GtkWidget *dialog);
|
terminal_search_dialog_get_search_flags(GtkWidget *dialog);
|
||||||
GRegex *terminal_search_dialog_get_regex (GtkWidget *dialog);
|
GRegex *terminal_search_dialog_get_regex (GtkWidget *dialog);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -30,22 +30,22 @@
|
||||||
|
|
||||||
struct _TerminalTabLabelPrivate
|
struct _TerminalTabLabelPrivate
|
||||||
{
|
{
|
||||||
TerminalScreen *screen;
|
TerminalScreen *screen;
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkWidget *close_button;
|
GtkWidget *close_button;
|
||||||
gboolean bold;
|
gboolean bold;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_SCREEN
|
PROP_SCREEN
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CLOSE_BUTTON_CLICKED,
|
CLOSE_BUTTON_CLICKED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL];
|
static guint signals[LAST_SIGNAL];
|
||||||
|
@ -58,7 +58,7 @@ static void
|
||||||
close_button_clicked_cb (GtkWidget *widget,
|
close_button_clicked_cb (GtkWidget *widget,
|
||||||
TerminalTabLabel *tab_label)
|
TerminalTabLabel *tab_label)
|
||||||
{
|
{
|
||||||
g_signal_emit (tab_label, signals[CLOSE_BUTTON_CLICKED], 0);
|
g_signal_emit (tab_label, signals[CLOSE_BUTTON_CLICKED], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -66,15 +66,15 @@ sync_tab_label (TerminalScreen *screen,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
GtkWidget *label)
|
GtkWidget *label)
|
||||||
{
|
{
|
||||||
GtkWidget *hbox;
|
GtkWidget *hbox;
|
||||||
const char *title;
|
const char *title;
|
||||||
|
|
||||||
title = terminal_screen_get_title (screen);
|
title = terminal_screen_get_title (screen);
|
||||||
hbox = gtk_widget_get_parent (label);
|
hbox = gtk_widget_get_parent (label);
|
||||||
|
|
||||||
gtk_label_set_text (GTK_LABEL (label), title);
|
gtk_label_set_text (GTK_LABEL (label), title);
|
||||||
|
|
||||||
gtk_widget_set_tooltip_text (hbox, title);
|
gtk_widget_set_tooltip_text (hbox, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
|
@ -85,33 +85,33 @@ static void
|
||||||
terminal_tab_label_parent_set (GtkWidget *widget,
|
terminal_tab_label_parent_set (GtkWidget *widget,
|
||||||
GtkWidget *old_parent)
|
GtkWidget *old_parent)
|
||||||
{
|
{
|
||||||
void (* parent_set) (GtkWidget *, GtkWidget *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->parent_set;
|
void (* parent_set) (GtkWidget *, GtkWidget *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->parent_set;
|
||||||
|
|
||||||
if (parent_set)
|
if (parent_set)
|
||||||
parent_set (widget, old_parent);
|
parent_set (widget, old_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_tab_label_style_set (GtkWidget *widget,
|
terminal_tab_label_style_set (GtkWidget *widget,
|
||||||
GtkStyle *previous_style)
|
GtkStyle *previous_style)
|
||||||
{
|
{
|
||||||
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (widget);
|
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (widget);
|
||||||
TerminalTabLabelPrivate *priv = tab_label->priv;
|
TerminalTabLabelPrivate *priv = tab_label->priv;
|
||||||
void (* style_set) (GtkWidget *, GtkStyle *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->style_set;
|
void (* style_set) (GtkWidget *, GtkStyle *) = GTK_WIDGET_CLASS (terminal_tab_label_parent_class)->style_set;
|
||||||
int h, w;
|
int h, w;
|
||||||
|
|
||||||
if (style_set)
|
if (style_set)
|
||||||
style_set (widget, previous_style);
|
style_set (widget, previous_style);
|
||||||
|
|
||||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
|
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
|
||||||
GTK_ICON_SIZE_MENU, &w, &h);
|
GTK_ICON_SIZE_MENU, &w, &h);
|
||||||
gtk_widget_set_size_request (priv->close_button, w + 2, h + 2);
|
gtk_widget_set_size_request (priv->close_button, w + 2, h + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_tab_label_init (TerminalTabLabel *tab_label)
|
terminal_tab_label_init (TerminalTabLabel *tab_label)
|
||||||
{
|
{
|
||||||
tab_label->priv = TERMINAL_TAB_LABEL_GET_PRIVATE (tab_label);
|
tab_label->priv = TERMINAL_TAB_LABEL_GET_PRIVATE (tab_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
|
@ -119,51 +119,51 @@ terminal_tab_label_constructor (GType type,
|
||||||
guint n_construct_properties,
|
guint n_construct_properties,
|
||||||
GObjectConstructParam *construct_params)
|
GObjectConstructParam *construct_params)
|
||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
TerminalTabLabel *tab_label;
|
TerminalTabLabel *tab_label;
|
||||||
TerminalTabLabelPrivate *priv;
|
TerminalTabLabelPrivate *priv;
|
||||||
GtkWidget *hbox, *label, *close_button, *image;
|
GtkWidget *hbox, *label, *close_button, *image;
|
||||||
|
|
||||||
object = G_OBJECT_CLASS (terminal_tab_label_parent_class)->constructor
|
object = G_OBJECT_CLASS (terminal_tab_label_parent_class)->constructor
|
||||||
(type, n_construct_properties, construct_params);
|
(type, n_construct_properties, construct_params);
|
||||||
|
|
||||||
tab_label = TERMINAL_TAB_LABEL (object);
|
tab_label = TERMINAL_TAB_LABEL (object);
|
||||||
hbox = GTK_WIDGET (tab_label);
|
hbox = GTK_WIDGET (tab_label);
|
||||||
priv = tab_label->priv;
|
priv = tab_label->priv;
|
||||||
|
|
||||||
g_assert (priv->screen != NULL);
|
g_assert (priv->screen != NULL);
|
||||||
|
|
||||||
gtk_box_set_spacing (GTK_BOX (hbox), SPACING);
|
|
||||||
|
|
||||||
priv->label = label = gtk_label_new (NULL);
|
gtk_box_set_spacing (GTK_BOX (hbox), SPACING);
|
||||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
||||||
gtk_misc_set_padding (GTK_MISC (label), 0, 0);
|
|
||||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
|
|
||||||
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
|
|
||||||
|
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
|
priv->label = label = gtk_label_new (NULL);
|
||||||
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||||
|
gtk_misc_set_padding (GTK_MISC (label), 0, 0);
|
||||||
|
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
|
||||||
|
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
|
||||||
|
|
||||||
priv->close_button = close_button = gtk_button_new ();
|
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
|
||||||
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
|
|
||||||
gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
|
|
||||||
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
|
|
||||||
gtk_widget_set_name (close_button, "mate-terminal-tab-close-button");
|
|
||||||
gtk_widget_set_tooltip_text (close_button, _("Close tab"));
|
|
||||||
|
|
||||||
image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
|
priv->close_button = close_button = gtk_button_new ();
|
||||||
gtk_container_add (GTK_CONTAINER (close_button), image);
|
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
|
||||||
gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
|
gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
|
||||||
|
gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
|
||||||
|
gtk_widget_set_name (close_button, "mate-terminal-tab-close-button");
|
||||||
|
gtk_widget_set_tooltip_text (close_button, _("Close tab"));
|
||||||
|
|
||||||
sync_tab_label (priv->screen, NULL, label);
|
image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
|
||||||
g_signal_connect (priv->screen, "notify::title",
|
gtk_container_add (GTK_CONTAINER (close_button), image);
|
||||||
G_CALLBACK (sync_tab_label), label);
|
gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
g_signal_connect (close_button, "clicked",
|
sync_tab_label (priv->screen, NULL, label);
|
||||||
G_CALLBACK (close_button_clicked_cb), tab_label);
|
g_signal_connect (priv->screen, "notify::title",
|
||||||
|
G_CALLBACK (sync_tab_label), label);
|
||||||
|
|
||||||
gtk_widget_show_all (hbox);
|
g_signal_connect (close_button, "clicked",
|
||||||
|
G_CALLBACK (close_button_clicked_cb), tab_label);
|
||||||
|
|
||||||
return object;
|
gtk_widget_show_all (hbox);
|
||||||
|
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -171,7 +171,7 @@ terminal_tab_label_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
// TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
|
// TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
|
||||||
|
|
||||||
G_OBJECT_CLASS (terminal_tab_label_parent_class)->finalize (object);
|
G_OBJECT_CLASS (terminal_tab_label_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -180,51 +180,52 @@ terminal_tab_label_set_property (GObject *object,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
|
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
|
||||||
TerminalTabLabelPrivate *priv = tab_label->priv;
|
TerminalTabLabelPrivate *priv = tab_label->priv;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id)
|
||||||
case PROP_SCREEN:
|
{
|
||||||
priv->screen = g_value_get_object (value);
|
case PROP_SCREEN:
|
||||||
break;
|
priv->screen = g_value_get_object (value);
|
||||||
default:
|
break;
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
default:
|
||||||
break;
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_tab_label_class_init (TerminalTabLabelClass *klass)
|
terminal_tab_label_class_init (TerminalTabLabelClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->constructor = terminal_tab_label_constructor;
|
gobject_class->constructor = terminal_tab_label_constructor;
|
||||||
gobject_class->finalize = terminal_tab_label_finalize;
|
gobject_class->finalize = terminal_tab_label_finalize;
|
||||||
gobject_class->set_property = terminal_tab_label_set_property;
|
gobject_class->set_property = terminal_tab_label_set_property;
|
||||||
|
|
||||||
widget_class->parent_set = terminal_tab_label_parent_set;
|
widget_class->parent_set = terminal_tab_label_parent_set;
|
||||||
widget_class->style_set = terminal_tab_label_style_set;
|
widget_class->style_set = terminal_tab_label_style_set;
|
||||||
|
|
||||||
signals[CLOSE_BUTTON_CLICKED] =
|
signals[CLOSE_BUTTON_CLICKED] =
|
||||||
g_signal_new (I_("close-button-clicked"),
|
g_signal_new (I_("close-button-clicked"),
|
||||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (TerminalTabLabelClass, close_button_clicked),
|
G_STRUCT_OFFSET (TerminalTabLabelClass, close_button_clicked),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(gobject_class,
|
(gobject_class,
|
||||||
PROP_SCREEN,
|
PROP_SCREEN,
|
||||||
g_param_spec_object ("screen", NULL, NULL,
|
g_param_spec_object ("screen", NULL, NULL,
|
||||||
TERMINAL_TYPE_SCREEN,
|
TERMINAL_TYPE_SCREEN,
|
||||||
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
|
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (TerminalTabLabelPrivate));
|
g_type_class_add_private (gobject_class, sizeof (TerminalTabLabelPrivate));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public API */
|
/* public API */
|
||||||
|
@ -238,9 +239,9 @@ terminal_tab_label_class_init (TerminalTabLabelClass *klass)
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
terminal_tab_label_new (TerminalScreen *screen)
|
terminal_tab_label_new (TerminalScreen *screen)
|
||||||
{
|
{
|
||||||
return g_object_new (TERMINAL_TYPE_TAB_LABEL,
|
return g_object_new (TERMINAL_TYPE_TAB_LABEL,
|
||||||
"screen", screen,
|
"screen", screen,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,36 +255,37 @@ void
|
||||||
terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
|
terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
|
||||||
gboolean bold)
|
gboolean bold)
|
||||||
{
|
{
|
||||||
TerminalTabLabelPrivate *priv = tab_label->priv;
|
TerminalTabLabelPrivate *priv = tab_label->priv;
|
||||||
PangoAttrList *attr_list;
|
PangoAttrList *attr_list;
|
||||||
PangoAttribute *weight_attr;
|
PangoAttribute *weight_attr;
|
||||||
gboolean free_list = FALSE;
|
gboolean free_list = FALSE;
|
||||||
|
|
||||||
bold = bold != FALSE;
|
bold = bold != FALSE;
|
||||||
if (priv->bold == bold)
|
if (priv->bold == bold)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
priv->bold = bold;
|
priv->bold = bold;
|
||||||
|
|
||||||
attr_list = gtk_label_get_attributes (GTK_LABEL (priv->label));
|
attr_list = gtk_label_get_attributes (GTK_LABEL (priv->label));
|
||||||
if (!attr_list) {
|
if (!attr_list)
|
||||||
attr_list = pango_attr_list_new ();
|
{
|
||||||
free_list = TRUE;
|
attr_list = pango_attr_list_new ();
|
||||||
}
|
free_list = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (bold)
|
if (bold)
|
||||||
weight_attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
weight_attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
|
||||||
else
|
else
|
||||||
weight_attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);
|
weight_attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);
|
||||||
|
|
||||||
/* gtk_label_get_attributes() returns the label's internal list,
|
/* gtk_label_get_attributes() returns the label's internal list,
|
||||||
* which we're probably not supposed to modify directly.
|
* which we're probably not supposed to modify directly.
|
||||||
* It seems to work ok however.
|
* It seems to work ok however.
|
||||||
*/
|
*/
|
||||||
pango_attr_list_change (attr_list, weight_attr);
|
pango_attr_list_change (attr_list, weight_attr);
|
||||||
|
|
||||||
gtk_label_set_attributes (GTK_LABEL (priv->label), attr_list);
|
gtk_label_set_attributes (GTK_LABEL (priv->label), attr_list);
|
||||||
|
|
||||||
if (free_list)
|
if (free_list)
|
||||||
pango_attr_list_unref (attr_list);
|
pango_attr_list_unref (attr_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,18 +38,18 @@ typedef struct _TerminalTabLabelPrivate TerminalTabLabelPrivate;
|
||||||
|
|
||||||
struct _TerminalTabLabel
|
struct _TerminalTabLabel
|
||||||
{
|
{
|
||||||
GtkHBox parent_instance;
|
GtkHBox parent_instance;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
TerminalTabLabelPrivate *priv;
|
TerminalTabLabelPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _TerminalTabLabelClass
|
struct _TerminalTabLabelClass
|
||||||
{
|
{
|
||||||
GtkHBoxClass parent_class;
|
GtkHBoxClass parent_class;
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
void (* close_button_clicked) (TerminalTabLabel *tab_label);
|
void (* close_button_clicked) (TerminalTabLabel *tab_label);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType terminal_tab_label_get_type (void);
|
GType terminal_tab_label_get_type (void);
|
||||||
|
@ -57,7 +57,7 @@ GType terminal_tab_label_get_type (void);
|
||||||
GtkWidget *terminal_tab_label_new (TerminalScreen *screen);
|
GtkWidget *terminal_tab_label_new (TerminalScreen *screen);
|
||||||
|
|
||||||
void terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
|
void terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
|
||||||
gboolean bold);
|
gboolean bold);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ struct _TerminalTabsMenuPrivate
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_WINDOW
|
PROP_WINDOW
|
||||||
};
|
};
|
||||||
|
|
||||||
static void terminal_tabs_menu_update (TerminalTabsMenu *menu);
|
static void terminal_tabs_menu_update (TerminalTabsMenu *menu);
|
||||||
|
@ -76,77 +76,77 @@ G_DEFINE_TYPE (TerminalTabsMenu, terminal_tabs_menu, G_TYPE_OBJECT)
|
||||||
static guint
|
static guint
|
||||||
allocate_tab_id (void)
|
allocate_tab_id (void)
|
||||||
{
|
{
|
||||||
int bit;
|
int bit;
|
||||||
guint b, len;
|
guint b, len;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint8 byte, mask;
|
guint8 byte, mask;
|
||||||
|
|
||||||
if (n_tabs++ == 0)
|
if (n_tabs++ == 0)
|
||||||
{
|
{
|
||||||
g_assert (tabs_id_array == NULL);
|
g_assert (tabs_id_array == NULL);
|
||||||
tabs_id_array = g_byte_array_sized_new (16);
|
tabs_id_array = g_byte_array_sized_new (16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a free ID */
|
/* Find a free ID */
|
||||||
len = tabs_id_array->len;
|
len = tabs_id_array->len;
|
||||||
data = tabs_id_array->data;
|
data = tabs_id_array->data;
|
||||||
for (b = 0; b < len; ++b)
|
for (b = 0; b < len; ++b)
|
||||||
{
|
{
|
||||||
if (data[b] != 0xff)
|
if (data[b] != 0xff)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to append a new byte */
|
/* Need to append a new byte */
|
||||||
if (b == len)
|
if (b == len)
|
||||||
{
|
{
|
||||||
guint8 bytes[] = { 0 };
|
guint8 bytes[] = { 0 };
|
||||||
g_byte_array_append (tabs_id_array, bytes, G_N_ELEMENTS (bytes));
|
g_byte_array_append (tabs_id_array, bytes, G_N_ELEMENTS (bytes));
|
||||||
g_assert (tabs_id_array->len > b);
|
g_assert (tabs_id_array->len > b);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = tabs_id_array->data + b;
|
data = tabs_id_array->data + b;
|
||||||
byte = 0xff ^ *data;
|
byte = 0xff ^ *data;
|
||||||
/* Now find the first free bit */
|
/* Now find the first free bit */
|
||||||
bit = g_bit_nth_lsf (byte, -1);
|
bit = g_bit_nth_lsf (byte, -1);
|
||||||
mask = 1 << bit;
|
mask = 1 << bit;
|
||||||
g_assert (bit >= 0 && bit <= 7);
|
g_assert (bit >= 0 && bit <= 7);
|
||||||
g_assert ((*data & mask) == 0);
|
g_assert ((*data & mask) == 0);
|
||||||
/* And mark it as allocated */
|
/* And mark it as allocated */
|
||||||
*data |= mask;
|
*data |= mask;
|
||||||
|
|
||||||
return b * 8 + bit;
|
return b * 8 + bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_tab_id (GtkAction *action)
|
free_tab_id (GtkAction *action)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
guint id;
|
guint id;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint b, bit;
|
guint b, bit;
|
||||||
|
|
||||||
name = gtk_action_get_name (action);
|
name = gtk_action_get_name (action);
|
||||||
id = g_ascii_strtoull (name + ACTION_VERB_FORMAT_PREFIX_LEN, NULL,
|
id = g_ascii_strtoull (name + ACTION_VERB_FORMAT_PREFIX_LEN, NULL,
|
||||||
ACTION_VERB_FORMAT_BASE);
|
ACTION_VERB_FORMAT_BASE);
|
||||||
g_assert (id < tabs_id_array->len * 8);
|
g_assert (id < tabs_id_array->len * 8);
|
||||||
|
|
||||||
b = id >> 3;
|
b = id >> 3;
|
||||||
bit = id & 0x7;
|
bit = id & 0x7;
|
||||||
data = tabs_id_array->data + b;
|
data = tabs_id_array->data + b;
|
||||||
*data &= ~(1 << bit);
|
*data &= ~(1 << bit);
|
||||||
|
|
||||||
g_assert (n_tabs > 0);
|
g_assert (n_tabs > 0);
|
||||||
if (--n_tabs == 0)
|
if (--n_tabs == 0)
|
||||||
{
|
{
|
||||||
g_assert (tabs_id_array != NULL);
|
g_assert (tabs_id_array != NULL);
|
||||||
g_byte_array_free (tabs_id_array, TRUE);
|
g_byte_array_free (tabs_id_array, TRUE);
|
||||||
tabs_id_array = NULL;
|
tabs_id_array = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tab_action_activate_cb (GtkToggleAction *action,
|
tab_action_activate_cb (GtkToggleAction *action,
|
||||||
TerminalTabsMenu *menu)
|
TerminalTabsMenu *menu)
|
||||||
{
|
{
|
||||||
TerminalTabsMenuPrivate *priv = menu->priv;
|
TerminalTabsMenuPrivate *priv = menu->priv;
|
||||||
TerminalScreen *screen;
|
TerminalScreen *screen;
|
||||||
|
@ -161,14 +161,14 @@ tab_action_activate_cb (GtkToggleAction *action,
|
||||||
|
|
||||||
if (terminal_window_get_active (priv->window) != screen)
|
if (terminal_window_get_active (priv->window) != screen)
|
||||||
{
|
{
|
||||||
terminal_window_switch_screen (priv->window, screen);
|
terminal_window_switch_screen (priv->window, screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sync_tab_title (TerminalScreen *screen,
|
sync_tab_title (TerminalScreen *screen,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
GtkAction *action)
|
GtkAction *action)
|
||||||
{
|
{
|
||||||
const char *title;
|
const char *title;
|
||||||
|
|
||||||
|
@ -180,28 +180,28 @@ sync_tab_title (TerminalScreen *screen,
|
||||||
static void
|
static void
|
||||||
notebook_page_added_cb (GtkNotebook *notebook,
|
notebook_page_added_cb (GtkNotebook *notebook,
|
||||||
TerminalScreenContainer *container,
|
TerminalScreenContainer *container,
|
||||||
guint position,
|
guint position,
|
||||||
TerminalTabsMenu *menu)
|
TerminalTabsMenu *menu)
|
||||||
{
|
{
|
||||||
TerminalTabsMenuPrivate *priv = menu->priv;
|
TerminalTabsMenuPrivate *priv = menu->priv;
|
||||||
GtkAction *action;
|
GtkAction *action;
|
||||||
char verb[ACTION_VERB_FORMAT_LENGTH];
|
char verb[ACTION_VERB_FORMAT_LENGTH];
|
||||||
GSList *group;
|
GSList *group;
|
||||||
TerminalScreen *screen;
|
TerminalScreen *screen;
|
||||||
|
|
||||||
screen = terminal_screen_container_get_screen (container);
|
screen = terminal_screen_container_get_screen (container);
|
||||||
|
|
||||||
g_snprintf (verb, sizeof (verb), ACTION_VERB_FORMAT, allocate_tab_id ());
|
g_snprintf (verb, sizeof (verb), ACTION_VERB_FORMAT, allocate_tab_id ());
|
||||||
|
|
||||||
action = g_object_new (GTK_TYPE_RADIO_ACTION,
|
action = g_object_new (GTK_TYPE_RADIO_ACTION,
|
||||||
"name", verb,
|
"name", verb,
|
||||||
"tooltip", _("Switch to this tab"),
|
"tooltip", _("Switch to this tab"),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
sync_tab_title (screen, NULL, action);
|
sync_tab_title (screen, NULL, action);
|
||||||
/* make sure the action is alive when handling the signal, see bug #169833 */
|
/* make sure the action is alive when handling the signal, see bug #169833 */
|
||||||
g_signal_connect_object (screen, "notify::title",
|
g_signal_connect_object (screen, "notify::title",
|
||||||
G_CALLBACK (sync_tab_title), action, 0);
|
G_CALLBACK (sync_tab_title), action, 0);
|
||||||
|
|
||||||
gtk_action_group_add_action_with_accel (priv->action_group, action, NULL);
|
gtk_action_group_add_action_with_accel (priv->action_group, action, NULL);
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ notebook_page_added_cb (GtkNotebook *notebook,
|
||||||
g_object_set_data (G_OBJECT (action), DATA_KEY, screen);
|
g_object_set_data (G_OBJECT (action), DATA_KEY, screen);
|
||||||
|
|
||||||
g_signal_connect (action, "activate",
|
g_signal_connect (action, "activate",
|
||||||
G_CALLBACK (tab_action_activate_cb), menu);
|
G_CALLBACK (tab_action_activate_cb), menu);
|
||||||
|
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
|
|
||||||
|
@ -228,37 +228,37 @@ notebook_page_added_cb (GtkNotebook *notebook,
|
||||||
static void
|
static void
|
||||||
notebook_page_removed_cb (GtkNotebook *notebook,
|
notebook_page_removed_cb (GtkNotebook *notebook,
|
||||||
TerminalScreenContainer *container,
|
TerminalScreenContainer *container,
|
||||||
guint position,
|
guint position,
|
||||||
TerminalTabsMenu *menu)
|
TerminalTabsMenu *menu)
|
||||||
{
|
{
|
||||||
TerminalTabsMenuPrivate *priv = menu->priv;
|
TerminalTabsMenuPrivate *priv = menu->priv;
|
||||||
GtkAction *action;
|
GtkAction *action;
|
||||||
TerminalScreen *screen;
|
TerminalScreen *screen;
|
||||||
|
|
||||||
screen = terminal_screen_container_get_screen (container);
|
screen = terminal_screen_container_get_screen (container);
|
||||||
|
|
||||||
action = g_object_get_data (G_OBJECT (screen), DATA_KEY);
|
action = g_object_get_data (G_OBJECT (screen), DATA_KEY);
|
||||||
g_return_if_fail (action != NULL);
|
g_return_if_fail (action != NULL);
|
||||||
|
|
||||||
free_tab_id (action);
|
free_tab_id (action);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func
|
g_signal_handlers_disconnect_by_func
|
||||||
(screen, G_CALLBACK (sync_tab_title), action);
|
(screen, G_CALLBACK (sync_tab_title), action);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func
|
g_signal_handlers_disconnect_by_func
|
||||||
(action, G_CALLBACK (tab_action_activate_cb), menu);
|
(action, G_CALLBACK (tab_action_activate_cb), menu);
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (screen), DATA_KEY, NULL);
|
g_object_set_data (G_OBJECT (screen), DATA_KEY, NULL);
|
||||||
gtk_action_group_remove_action (priv->action_group, action);
|
gtk_action_group_remove_action (priv->action_group, action);
|
||||||
|
|
||||||
terminal_tabs_menu_update (menu);
|
terminal_tabs_menu_update (menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notebook_page_reordered_cb (GtkNotebook *notebook,
|
notebook_page_reordered_cb (GtkNotebook *notebook,
|
||||||
GtkBin *bin,
|
GtkBin *bin,
|
||||||
guint position,
|
guint position,
|
||||||
TerminalTabsMenu *menu)
|
TerminalTabsMenu *menu)
|
||||||
{
|
{
|
||||||
terminal_tabs_menu_update (menu);
|
terminal_tabs_menu_update (menu);
|
||||||
}
|
}
|
||||||
|
@ -273,28 +273,28 @@ notebook_page_switch_cb (GtkNotebook *notebook,
|
||||||
guint position,
|
guint position,
|
||||||
TerminalTabsMenu *menu)
|
TerminalTabsMenu *menu)
|
||||||
{
|
{
|
||||||
TerminalScreenContainer *container;
|
TerminalScreenContainer *container;
|
||||||
TerminalScreen *screen;
|
TerminalScreen *screen;
|
||||||
GtkAction *action;
|
GtkAction *action;
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION (2, 90, 6)
|
#if GTK_CHECK_VERSION (2, 90, 6)
|
||||||
container = TERMINAL_SCREEN_CONTAINER (page);
|
container = TERMINAL_SCREEN_CONTAINER (page);
|
||||||
#else
|
#else
|
||||||
container = TERMINAL_SCREEN_CONTAINER (gtk_notebook_get_nth_page (notebook, position));
|
container = TERMINAL_SCREEN_CONTAINER (gtk_notebook_get_nth_page (notebook, position));
|
||||||
#endif
|
#endif
|
||||||
screen = terminal_screen_container_get_screen (container);
|
screen = terminal_screen_container_get_screen (container);
|
||||||
|
|
||||||
action = g_object_get_data (G_OBJECT (screen), DATA_KEY);
|
action = g_object_get_data (G_OBJECT (screen), DATA_KEY);
|
||||||
g_signal_handlers_block_by_func (action, G_CALLBACK (tab_action_activate_cb), menu);
|
g_signal_handlers_block_by_func (action, G_CALLBACK (tab_action_activate_cb), menu);
|
||||||
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
|
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
|
||||||
g_signal_handlers_unblock_by_func (action, G_CALLBACK (tab_action_activate_cb), menu);
|
g_signal_handlers_unblock_by_func (action, G_CALLBACK (tab_action_activate_cb), menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
connect_proxy_cb (GtkActionGroup *action_group,
|
connect_proxy_cb (GtkActionGroup *action_group,
|
||||||
GtkAction *action,
|
GtkAction *action,
|
||||||
GtkWidget *proxy,
|
GtkWidget *proxy,
|
||||||
gpointer dummy)
|
gpointer dummy)
|
||||||
{
|
{
|
||||||
if (GTK_IS_MENU_ITEM (proxy))
|
if (GTK_IS_MENU_ITEM (proxy))
|
||||||
{
|
{
|
||||||
|
@ -310,7 +310,7 @@ connect_proxy_cb (GtkActionGroup *action_group,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
|
terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
|
||||||
TerminalWindow *window)
|
TerminalWindow *window)
|
||||||
{
|
{
|
||||||
TerminalTabsMenuPrivate *priv = menu->priv;
|
TerminalTabsMenuPrivate *priv = menu->priv;
|
||||||
GtkWidget *notebook;
|
GtkWidget *notebook;
|
||||||
|
@ -324,49 +324,49 @@ terminal_tabs_menu_set_window (TerminalTabsMenu *menu,
|
||||||
g_object_unref (priv->action_group);
|
g_object_unref (priv->action_group);
|
||||||
|
|
||||||
priv->anchor_action = g_object_new (GTK_TYPE_RADIO_ACTION,
|
priv->anchor_action = g_object_new (GTK_TYPE_RADIO_ACTION,
|
||||||
"name", "TabsMenuAnchorAction",
|
"name", "TabsMenuAnchorAction",
|
||||||
NULL);
|
NULL);
|
||||||
gtk_action_group_add_action (priv->action_group, priv->anchor_action);
|
gtk_action_group_add_action (priv->action_group, priv->anchor_action);
|
||||||
g_object_unref (priv->anchor_action);
|
g_object_unref (priv->anchor_action);
|
||||||
|
|
||||||
g_signal_connect (priv->action_group, "connect-proxy",
|
g_signal_connect (priv->action_group, "connect-proxy",
|
||||||
G_CALLBACK (connect_proxy_cb), NULL);
|
G_CALLBACK (connect_proxy_cb), NULL);
|
||||||
|
|
||||||
notebook = terminal_window_get_notebook (window);
|
notebook = terminal_window_get_notebook (window);
|
||||||
g_signal_connect_object (notebook, "page-added",
|
g_signal_connect_object (notebook, "page-added",
|
||||||
G_CALLBACK (notebook_page_added_cb), menu, 0);
|
G_CALLBACK (notebook_page_added_cb), menu, 0);
|
||||||
g_signal_connect_object (notebook, "page-removed",
|
g_signal_connect_object (notebook, "page-removed",
|
||||||
G_CALLBACK (notebook_page_removed_cb), menu, 0);
|
G_CALLBACK (notebook_page_removed_cb), menu, 0);
|
||||||
g_signal_connect_object (notebook, "page-reordered",
|
g_signal_connect_object (notebook, "page-reordered",
|
||||||
G_CALLBACK (notebook_page_reordered_cb), menu, 0);
|
G_CALLBACK (notebook_page_reordered_cb), menu, 0);
|
||||||
g_signal_connect_object (notebook, "switch-page",
|
g_signal_connect_object (notebook, "switch-page",
|
||||||
G_CALLBACK (notebook_page_switch_cb), menu, 0);
|
G_CALLBACK (notebook_page_switch_cb), menu, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_tabs_menu_set_property (GObject *object,
|
terminal_tabs_menu_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
TerminalTabsMenu *menu = TERMINAL_TABS_MENU (object);
|
TerminalTabsMenu *menu = TERMINAL_TABS_MENU (object);
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_WINDOW:
|
case PROP_WINDOW:
|
||||||
terminal_tabs_menu_set_window (menu, g_value_get_object (value));
|
terminal_tabs_menu_set_window (menu, g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_tabs_menu_get_property (GObject *object,
|
terminal_tabs_menu_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
/* no readable properties */
|
/* no readable properties */
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
|
@ -381,16 +381,16 @@ terminal_tabs_menu_class_init (TerminalTabsMenuClass *klass)
|
||||||
object_class->get_property = terminal_tabs_menu_get_property;
|
object_class->get_property = terminal_tabs_menu_get_property;
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_WINDOW,
|
PROP_WINDOW,
|
||||||
g_param_spec_object ("window", NULL, NULL,
|
g_param_spec_object ("window", NULL, NULL,
|
||||||
TERMINAL_TYPE_WINDOW,
|
TERMINAL_TYPE_WINDOW,
|
||||||
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
|
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
|
||||||
g_type_class_add_private (object_class, sizeof (TerminalTabsMenuPrivate));
|
g_type_class_add_private (object_class, sizeof (TerminalTabsMenuPrivate));
|
||||||
|
|
||||||
/* We don't want to save accels, so skip them */
|
/* We don't want to save accels, so skip them */
|
||||||
gtk_accel_map_add_filter ("<Actions>/Main/TabsSwitch*");
|
gtk_accel_map_add_filter ("<Actions>/Main/TabsSwitch*");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -417,29 +417,29 @@ TerminalTabsMenu *
|
||||||
terminal_tabs_menu_new (TerminalWindow *window)
|
terminal_tabs_menu_new (TerminalWindow *window)
|
||||||
{
|
{
|
||||||
return TERMINAL_TABS_MENU (g_object_new (TERMINAL_TYPE_TABS_MENU,
|
return TERMINAL_TABS_MENU (g_object_new (TERMINAL_TYPE_TABS_MENU,
|
||||||
"window", window,
|
"window", window,
|
||||||
NULL));
|
NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tab_set_action_accelerator (GtkActionGroup *action_group,
|
tab_set_action_accelerator (GtkActionGroup *action_group,
|
||||||
GtkAction *action,
|
GtkAction *action,
|
||||||
guint tab_number,
|
guint tab_number,
|
||||||
gboolean is_single_tab)
|
gboolean is_single_tab)
|
||||||
{
|
{
|
||||||
if (!is_single_tab &&
|
if (!is_single_tab &&
|
||||||
tab_number < TERMINAL_ACCELS_N_TABS_SWITCH)
|
tab_number < TERMINAL_ACCELS_N_TABS_SWITCH)
|
||||||
{
|
{
|
||||||
char accel_path[ACCEL_PATH_FORMAT_LENGTH];
|
char accel_path[ACCEL_PATH_FORMAT_LENGTH];
|
||||||
|
|
||||||
g_snprintf (accel_path, sizeof (accel_path), ACCEL_PATH_FORMAT, tab_number + 1);
|
g_snprintf (accel_path, sizeof (accel_path), ACCEL_PATH_FORMAT, tab_number + 1);
|
||||||
gtk_action_set_accel_path (action, accel_path);
|
gtk_action_set_accel_path (action, accel_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gtk_action_set_accel_path (action, NULL);
|
gtk_action_set_accel_path (action, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -467,20 +467,20 @@ terminal_tabs_menu_update (TerminalTabsMenu *menu)
|
||||||
|
|
||||||
for (l = tabs; l != NULL; l = l->next)
|
for (l = tabs; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (l->data);
|
TerminalScreenContainer *container = TERMINAL_SCREEN_CONTAINER (l->data);
|
||||||
GObject *screen = G_OBJECT (terminal_screen_container_get_screen (container));
|
GObject *screen = G_OBJECT (terminal_screen_container_get_screen (container));
|
||||||
|
|
||||||
action = g_object_get_data (screen, DATA_KEY);
|
action = g_object_get_data (screen, DATA_KEY);
|
||||||
g_return_if_fail (action != NULL);
|
g_return_if_fail (action != NULL);
|
||||||
|
|
||||||
verb = gtk_action_get_name (action);
|
verb = gtk_action_get_name (action);
|
||||||
|
|
||||||
tab_set_action_accelerator (p->action_group, action, i++, is_single_tab);
|
tab_set_action_accelerator (p->action_group, action, i++, is_single_tab);
|
||||||
|
|
||||||
gtk_ui_manager_add_ui (manager, p->ui_id,
|
gtk_ui_manager_add_ui (manager, p->ui_id,
|
||||||
UI_PATH,
|
UI_PATH,
|
||||||
verb, verb,
|
verb, verb,
|
||||||
GTK_UI_MANAGER_MENUITEM, FALSE);
|
GTK_UI_MANAGER_MENUITEM, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (tabs);
|
g_list_free (tabs);
|
||||||
|
|
1511
src/terminal-util.c
1511
src/terminal-util.c
File diff suppressed because it is too large
Load Diff
|
@ -33,18 +33,18 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
void terminal_util_set_unique_role (GtkWindow *window, const char *prefix);
|
void terminal_util_set_unique_role (GtkWindow *window, const char *prefix);
|
||||||
|
|
||||||
void terminal_util_show_error_dialog (GtkWindow *transient_parent,
|
void terminal_util_show_error_dialog (GtkWindow *transient_parent,
|
||||||
GtkWidget **weap_ptr,
|
GtkWidget **weap_ptr,
|
||||||
GError *error,
|
GError *error,
|
||||||
const char *message_format, ...) G_GNUC_PRINTF(4, 5);
|
const char *message_format, ...) G_GNUC_PRINTF(4, 5);
|
||||||
|
|
||||||
void terminal_util_show_help (const char *topic, GtkWindow *transient_parent);
|
void terminal_util_show_help (const char *topic, GtkWindow *transient_parent);
|
||||||
|
|
||||||
void terminal_util_set_labelled_by (GtkWidget *widget,
|
void terminal_util_set_labelled_by (GtkWidget *widget,
|
||||||
GtkLabel *label);
|
GtkLabel *label);
|
||||||
void terminal_util_set_atk_name_description (GtkWidget *widget,
|
void terminal_util_set_atk_name_description (GtkWidget *widget,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *desc);
|
const char *desc);
|
||||||
|
|
||||||
void terminal_util_open_url (GtkWidget *parent,
|
void terminal_util_open_url (GtkWidget *parent,
|
||||||
const char *orig_url,
|
const char *orig_url,
|
||||||
|
@ -52,7 +52,7 @@ void terminal_util_open_url (GtkWidget *parent,
|
||||||
guint32 user_time);
|
guint32 user_time);
|
||||||
|
|
||||||
char *terminal_util_resolve_relative_path (const char *path,
|
char *terminal_util_resolve_relative_path (const char *path,
|
||||||
const char *relative_path);
|
const char *relative_path);
|
||||||
|
|
||||||
void terminal_util_transform_uris_to_quoted_fuse_paths (char **uris);
|
void terminal_util_transform_uris_to_quoted_fuse_paths (char **uris);
|
||||||
|
|
||||||
|
@ -62,46 +62,47 @@ char *terminal_util_concat_uris (char **uris,
|
||||||
char *terminal_util_get_licence_text (void);
|
char *terminal_util_get_licence_text (void);
|
||||||
|
|
||||||
gboolean terminal_util_load_builder_file (const char *filename,
|
gboolean terminal_util_load_builder_file (const char *filename,
|
||||||
const char *object_name,
|
const char *object_name,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
gboolean terminal_util_dialog_response_on_delete (GtkWindow *widget);
|
gboolean terminal_util_dialog_response_on_delete (GtkWindow *widget);
|
||||||
|
|
||||||
void terminal_util_key_file_set_string_escape (GKeyFile *key_file,
|
void terminal_util_key_file_set_string_escape (GKeyFile *key_file,
|
||||||
const char *group,
|
const char *group,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *string);
|
const char *string);
|
||||||
char *terminal_util_key_file_get_string_unescape (GKeyFile *key_file,
|
char *terminal_util_key_file_get_string_unescape (GKeyFile *key_file,
|
||||||
const char *group,
|
const char *group,
|
||||||
const char *key,
|
const char *key,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void terminal_util_key_file_set_argv (GKeyFile *key_file,
|
void terminal_util_key_file_set_argv (GKeyFile *key_file,
|
||||||
const char *group,
|
const char *group,
|
||||||
const char *key,
|
const char *key,
|
||||||
int argc,
|
int argc,
|
||||||
char **argv);
|
char **argv);
|
||||||
char **terminal_util_key_file_get_argv (GKeyFile *key_file,
|
char **terminal_util_key_file_get_argv (GKeyFile *key_file,
|
||||||
const char *group,
|
const char *group,
|
||||||
const char *key,
|
const char *key,
|
||||||
int *argc,
|
int *argc,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void terminal_util_add_proxy_env (GHashTable *env_table);
|
void terminal_util_add_proxy_env (GHashTable *env_table);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
FLAG_INVERT_BOOL = 1 << 0,
|
{
|
||||||
|
FLAG_INVERT_BOOL = 1 << 0,
|
||||||
} PropertyChangeFlags;
|
} PropertyChangeFlags;
|
||||||
|
|
||||||
void terminal_util_bind_object_property_to_widget (GObject *object,
|
void terminal_util_bind_object_property_to_widget (GObject *object,
|
||||||
const char *object_prop,
|
const char *object_prop,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
PropertyChangeFlags flags);
|
PropertyChangeFlags flags);
|
||||||
|
|
||||||
gboolean terminal_util_x11_get_net_wm_desktop (GdkWindow *window,
|
gboolean terminal_util_x11_get_net_wm_desktop (GdkWindow *window,
|
||||||
guint32 *desktop);
|
guint32 *desktop);
|
||||||
void terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
|
void terminal_util_x11_set_net_wm_desktop (GdkWindow *window,
|
||||||
guint32 desktop);
|
guint32 desktop);
|
||||||
|
|
||||||
void terminal_util_x11_clear_demands_attention (GdkWindow *window);
|
void terminal_util_x11_clear_demands_attention (GdkWindow *window);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,14 +38,14 @@ typedef struct _TerminalWindowPrivate TerminalWindowPrivate;
|
||||||
|
|
||||||
struct _TerminalWindow
|
struct _TerminalWindow
|
||||||
{
|
{
|
||||||
GtkWindow parent_instance;
|
GtkWindow parent_instance;
|
||||||
|
|
||||||
TerminalWindowPrivate *priv;
|
TerminalWindowPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _TerminalWindowClass
|
struct _TerminalWindowClass
|
||||||
{
|
{
|
||||||
GtkWindowClass parent_class;
|
GtkWindowClass parent_class;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,11 +74,11 @@ void terminal_window_move_screen (TerminalWindow *source_window,
|
||||||
* from the profile of the first screen added to the window
|
* from the profile of the first screen added to the window
|
||||||
*/
|
*/
|
||||||
void terminal_window_set_menubar_visible (TerminalWindow *window,
|
void terminal_window_set_menubar_visible (TerminalWindow *window,
|
||||||
gboolean setting);
|
gboolean setting);
|
||||||
gboolean terminal_window_get_menubar_visible (TerminalWindow *window);
|
gboolean terminal_window_get_menubar_visible (TerminalWindow *window);
|
||||||
|
|
||||||
void terminal_window_switch_screen (TerminalWindow *window,
|
void terminal_window_switch_screen (TerminalWindow *window,
|
||||||
TerminalScreen *screen);
|
TerminalScreen *screen);
|
||||||
TerminalScreen* terminal_window_get_active (TerminalWindow *window);
|
TerminalScreen* terminal_window_get_active (TerminalWindow *window);
|
||||||
|
|
||||||
GList* terminal_window_list_screen_containers (TerminalWindow *window);
|
GList* terminal_window_list_screen_containers (TerminalWindow *window);
|
||||||
|
@ -88,10 +88,10 @@ void terminal_window_set_size (TerminalWindow *window,
|
||||||
TerminalScreen *screen,
|
TerminalScreen *screen,
|
||||||
gboolean even_if_mapped);
|
gboolean even_if_mapped);
|
||||||
void terminal_window_set_size_force_grid (TerminalWindow *window,
|
void terminal_window_set_size_force_grid (TerminalWindow *window,
|
||||||
TerminalScreen *screen,
|
TerminalScreen *screen,
|
||||||
gboolean even_if_mapped,
|
gboolean even_if_mapped,
|
||||||
int force_grid_width,
|
int force_grid_width,
|
||||||
int force_grid_height);
|
int force_grid_height);
|
||||||
|
|
||||||
GtkWidget* terminal_window_get_notebook (TerminalWindow *window);
|
GtkWidget* terminal_window_get_notebook (TerminalWindow *window);
|
||||||
|
|
||||||
|
|
806
src/terminal.c
806
src/terminal.c
|
@ -52,79 +52,84 @@ static char *
|
||||||
ay_to_string (GVariant *variant,
|
ay_to_string (GVariant *variant,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gsize len;
|
gsize len;
|
||||||
const char *data;
|
const char *data;
|
||||||
|
|
||||||
data = g_variant_get_fixed_array (variant, &len, sizeof (char));
|
data = g_variant_get_fixed_array (variant, &len, sizeof (char));
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Make sure there are no embedded NULs */
|
/* Make sure there are no embedded NULs */
|
||||||
if (memchr (data, '\0', len) != NULL) {
|
if (memchr (data, '\0', len) != NULL)
|
||||||
g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
|
{
|
||||||
"String is shorter than claimed");
|
g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
|
||||||
return NULL;
|
"String is shorter than claimed");
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return g_strndup (data, len);
|
return g_strndup (data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
ay_to_strv (GVariant *variant,
|
ay_to_strv (GVariant *variant,
|
||||||
int *argc)
|
int *argc)
|
||||||
{
|
{
|
||||||
GPtrArray *argv;
|
GPtrArray *argv;
|
||||||
const char *data, *nullbyte;
|
const char *data, *nullbyte;
|
||||||
gsize data_len;
|
gsize data_len;
|
||||||
gssize len;
|
gssize len;
|
||||||
|
|
||||||
data = g_variant_get_fixed_array (variant, &data_len, sizeof (char));
|
data = g_variant_get_fixed_array (variant, &data_len, sizeof (char));
|
||||||
if (data_len == 0 || data_len > G_MAXSSIZE) {
|
if (data_len == 0 || data_len > G_MAXSSIZE)
|
||||||
*argc = 0;
|
{
|
||||||
return NULL;
|
*argc = 0;
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
argv = g_ptr_array_new ();
|
argv = g_ptr_array_new ();
|
||||||
|
|
||||||
len = data_len;
|
len = data_len;
|
||||||
do {
|
do
|
||||||
gssize string_len;
|
{
|
||||||
|
gssize string_len;
|
||||||
|
|
||||||
nullbyte = memchr (data, '\0', len);
|
nullbyte = memchr (data, '\0', len);
|
||||||
|
|
||||||
string_len = nullbyte ? (gssize) (nullbyte - data) : len;
|
string_len = nullbyte ? (gssize) (nullbyte - data) : len;
|
||||||
g_ptr_array_add (argv, g_strndup (data, string_len));
|
g_ptr_array_add (argv, g_strndup (data, string_len));
|
||||||
|
|
||||||
len -= string_len + 1;
|
len -= string_len + 1;
|
||||||
data += string_len + 1;
|
data += string_len + 1;
|
||||||
} while (len > 0);
|
}
|
||||||
|
while (len > 0);
|
||||||
|
|
||||||
if (argc)
|
if (argc)
|
||||||
*argc = argv->len;
|
*argc = argv->len;
|
||||||
|
|
||||||
/* NULL terminate */
|
/* NULL terminate */
|
||||||
g_ptr_array_add (argv, NULL);
|
g_ptr_array_add (argv, NULL);
|
||||||
return (char **) g_ptr_array_free (argv, FALSE);
|
return (char **) g_ptr_array_free (argv, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GVariant *
|
static GVariant *
|
||||||
string_to_ay (const char *string)
|
string_to_ay (const char *string)
|
||||||
{
|
{
|
||||||
gsize len;
|
gsize len;
|
||||||
char *data;
|
char *data;
|
||||||
|
|
||||||
len = strlen (string);
|
len = strlen (string);
|
||||||
data = g_strndup (string, len);
|
data = g_strndup (string, len);
|
||||||
|
|
||||||
return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data);
|
return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
char *factory_name;
|
{
|
||||||
TerminalOptions *options;
|
char *factory_name;
|
||||||
int exit_code;
|
TerminalOptions *options;
|
||||||
char **argv;
|
int exit_code;
|
||||||
int argc;
|
char **argv;
|
||||||
|
int argc;
|
||||||
} OwnData;
|
} OwnData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -137,69 +142,74 @@ method_call_cb (GDBusConnection *connection,
|
||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
if (g_strcmp0 (method_name, "HandleArguments") == 0) {
|
if (g_strcmp0 (method_name, "HandleArguments") == 0)
|
||||||
TerminalOptions *options = NULL;
|
{
|
||||||
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
|
TerminalOptions *options = NULL;
|
||||||
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
|
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
|
||||||
char **envv = NULL, **argv = NULL;
|
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
|
||||||
int argc;
|
char **envv = NULL, **argv = NULL;
|
||||||
GError *error = NULL;
|
int argc;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
g_variant_get (parameters, "(@ay@ay@ay@ay@ay)",
|
g_variant_get (parameters, "(@ay@ay@ay@ay@ay)",
|
||||||
&v_wd, &v_display, &v_sid, &v_envv, &v_argv);
|
&v_wd, &v_display, &v_sid, &v_envv, &v_argv);
|
||||||
|
|
||||||
working_directory = ay_to_string (v_wd, &error);
|
working_directory = ay_to_string (v_wd, &error);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
display_name = ay_to_string (v_display, &error);
|
display_name = ay_to_string (v_display, &error);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
startup_id = ay_to_string (v_sid, &error);
|
startup_id = ay_to_string (v_sid, &error);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
envv = ay_to_strv (v_envv, NULL);
|
envv = ay_to_strv (v_envv, NULL);
|
||||||
argv = ay_to_strv (v_argv, &argc);
|
argv = ay_to_strv (v_argv, &argc);
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n",
|
"Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n",
|
||||||
working_directory ? working_directory : "(null)",
|
working_directory ? working_directory : "(null)",
|
||||||
display_name ? display_name : "(null)",
|
display_name ? display_name : "(null)",
|
||||||
startup_id ? startup_id : "(null)");
|
startup_id ? startup_id : "(null)");
|
||||||
|
|
||||||
options = terminal_options_parse (working_directory,
|
options = terminal_options_parse (working_directory,
|
||||||
display_name,
|
display_name,
|
||||||
startup_id,
|
startup_id,
|
||||||
envv,
|
envv,
|
||||||
TRUE,
|
TRUE,
|
||||||
TRUE,
|
TRUE,
|
||||||
&argc, &argv,
|
&argc, &argv,
|
||||||
&error,
|
&error,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (options != NULL) {
|
if (options != NULL)
|
||||||
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
|
{
|
||||||
terminal_options_free (options);
|
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
|
||||||
}
|
terminal_options_free (options);
|
||||||
|
}
|
||||||
out:
|
|
||||||
g_variant_unref (v_wd);
|
|
||||||
g_free (working_directory);
|
|
||||||
g_variant_unref (v_display);
|
|
||||||
g_free (display_name);
|
|
||||||
g_variant_unref (v_sid);
|
|
||||||
g_free (startup_id);
|
|
||||||
g_variant_unref (v_envv);
|
|
||||||
g_strfreev (envv);
|
|
||||||
g_variant_unref (v_argv);
|
|
||||||
g_strfreev (argv);
|
|
||||||
|
|
||||||
if (error == NULL) {
|
out:
|
||||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
|
g_variant_unref (v_wd);
|
||||||
} else {
|
g_free (working_directory);
|
||||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
g_variant_unref (v_display);
|
||||||
g_error_free (error);
|
g_free (display_name);
|
||||||
}
|
g_variant_unref (v_sid);
|
||||||
}
|
g_free (startup_id);
|
||||||
|
g_variant_unref (v_envv);
|
||||||
|
g_strfreev (envv);
|
||||||
|
g_variant_unref (v_argv);
|
||||||
|
g_strfreev (argv);
|
||||||
|
|
||||||
|
if (error == NULL)
|
||||||
|
{
|
||||||
|
g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -207,50 +217,52 @@ bus_acquired_cb (GDBusConnection *connection,
|
||||||
const char *name,
|
const char *name,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
static const char dbus_introspection_xml[] =
|
static const char dbus_introspection_xml[] =
|
||||||
"<node name='/org/mate/Terminal'>"
|
"<node name='/org/mate/Terminal'>"
|
||||||
"<interface name='org.mate.Terminal.Factory'>"
|
"<interface name='org.mate.Terminal.Factory'>"
|
||||||
"<method name='HandleArguments'>"
|
"<method name='HandleArguments'>"
|
||||||
"<arg type='ay' name='working_directory' direction='in' />"
|
"<arg type='ay' name='working_directory' direction='in' />"
|
||||||
"<arg type='ay' name='display_name' direction='in' />"
|
"<arg type='ay' name='display_name' direction='in' />"
|
||||||
"<arg type='ay' name='startup_id' direction='in' />"
|
"<arg type='ay' name='startup_id' direction='in' />"
|
||||||
"<arg type='ay' name='environment' direction='in' />"
|
"<arg type='ay' name='environment' direction='in' />"
|
||||||
"<arg type='ay' name='arguments' direction='in' />"
|
"<arg type='ay' name='arguments' direction='in' />"
|
||||||
"</method>"
|
"</method>"
|
||||||
"</interface>"
|
"</interface>"
|
||||||
"</node>";
|
"</node>";
|
||||||
|
|
||||||
static const GDBusInterfaceVTable interface_vtable = {
|
static const GDBusInterfaceVTable interface_vtable =
|
||||||
method_call_cb,
|
{
|
||||||
NULL,
|
method_call_cb,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
OwnData *data = (OwnData *) user_data;
|
OwnData *data = (OwnData *) user_data;
|
||||||
GDBusNodeInfo *introspection_data;
|
GDBusNodeInfo *introspection_data;
|
||||||
guint registration_id;
|
guint registration_id;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Bus %s acquired\n", name);
|
"Bus %s acquired\n", name);
|
||||||
|
|
||||||
introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
|
introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
|
||||||
g_assert (introspection_data != NULL);
|
g_assert (introspection_data != NULL);
|
||||||
|
|
||||||
registration_id = g_dbus_connection_register_object (connection,
|
registration_id = g_dbus_connection_register_object (connection,
|
||||||
TERMINAL_FACTORY_SERVICE_PATH,
|
TERMINAL_FACTORY_SERVICE_PATH,
|
||||||
introspection_data->interfaces[0],
|
introspection_data->interfaces[0],
|
||||||
&interface_vtable,
|
&interface_vtable,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
&error);
|
&error);
|
||||||
g_dbus_node_info_unref (introspection_data);
|
g_dbus_node_info_unref (introspection_data);
|
||||||
|
|
||||||
if (registration_id == 0) {
|
if (registration_id == 0)
|
||||||
g_printerr ("Failed to register object: %s\n", error->message);
|
{
|
||||||
g_error_free (error);
|
g_printerr ("Failed to register object: %s\n", error->message);
|
||||||
data->exit_code = EXIT_FAILURE;
|
g_error_free (error);
|
||||||
gtk_main_quit ();
|
data->exit_code = EXIT_FAILURE;
|
||||||
}
|
gtk_main_quit ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -258,27 +270,29 @@ name_acquired_cb (GDBusConnection *connection,
|
||||||
const char *name,
|
const char *name,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
OwnData *data = (OwnData *) user_data;
|
OwnData *data = (OwnData *) user_data;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Acquired the name %s on the session bus\n", name);
|
"Acquired the name %s on the session bus\n", name);
|
||||||
|
|
||||||
if (data->options == NULL) {
|
if (data->options == NULL)
|
||||||
/* Name re-acquired!? */
|
{
|
||||||
g_assert_not_reached ();
|
/* Name re-acquired!? */
|
||||||
}
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error)) {
|
if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error))
|
||||||
g_printerr ("Failed to handle options: %s\n", error->message);
|
{
|
||||||
g_error_free (error);
|
g_printerr ("Failed to handle options: %s\n", error->message);
|
||||||
data->exit_code = EXIT_FAILURE;
|
g_error_free (error);
|
||||||
gtk_main_quit ();
|
data->exit_code = EXIT_FAILURE;
|
||||||
}
|
gtk_main_quit ();
|
||||||
|
}
|
||||||
|
|
||||||
terminal_options_free (data->options);
|
terminal_options_free (data->options);
|
||||||
data->options = NULL;
|
data->options = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -286,103 +300,108 @@ name_lost_cb (GDBusConnection *connection,
|
||||||
const char *name,
|
const char *name,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
OwnData *data = (OwnData *) user_data;
|
OwnData *data = (OwnData *) user_data;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char **envv;
|
char **envv;
|
||||||
int envc, i;
|
int envc, i;
|
||||||
GVariantBuilder builder;
|
GVariantBuilder builder;
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
GString *string;
|
GString *string;
|
||||||
char *s;
|
char *s;
|
||||||
gsize len;
|
gsize len;
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Lost the name %s on the session bus\n", name);
|
"Lost the name %s on the session bus\n", name);
|
||||||
|
|
||||||
/* Couldn't get the connection? No way to continue! */
|
/* Couldn't get the connection? No way to continue! */
|
||||||
if (connection == NULL) {
|
if (connection == NULL)
|
||||||
data->exit_code = EXIT_FAILURE;
|
{
|
||||||
gtk_main_quit ();
|
data->exit_code = EXIT_FAILURE;
|
||||||
return;
|
gtk_main_quit ();
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (data->options == NULL) {
|
if (data->options == NULL)
|
||||||
/* Already handled */
|
{
|
||||||
data->exit_code = EXIT_SUCCESS;
|
/* Already handled */
|
||||||
gtk_main_quit ();
|
data->exit_code = EXIT_SUCCESS;
|
||||||
return;
|
gtk_main_quit ();
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Forwarding arguments to existing instance\n");
|
"Forwarding arguments to existing instance\n");
|
||||||
|
|
||||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)"));
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)"));
|
||||||
|
|
||||||
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir));
|
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir));
|
||||||
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name));
|
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name));
|
||||||
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id));
|
g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id));
|
||||||
|
|
||||||
string = g_string_new (NULL);
|
string = g_string_new (NULL);
|
||||||
envv = g_listenv ();
|
envv = g_listenv ();
|
||||||
envc = g_strv_length (envv);
|
envc = g_strv_length (envv);
|
||||||
for (i = 0; i < envc; ++i)
|
for (i = 0; i < envc; ++i)
|
||||||
{
|
{
|
||||||
const char *value;
|
const char *value;
|
||||||
|
|
||||||
value = g_getenv (envv[i]);
|
value = g_getenv (envv[i]);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
g_string_append_c (string, '\0');
|
g_string_append_c (string, '\0');
|
||||||
|
|
||||||
g_string_append_printf (string, "%s=%s", envv[i], value);
|
g_string_append_printf (string, "%s=%s", envv[i], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = string->len;
|
len = string->len;
|
||||||
s = g_string_free (string, FALSE);
|
s = g_string_free (string, FALSE);
|
||||||
g_variant_builder_add (&builder, "@ay",
|
g_variant_builder_add (&builder, "@ay",
|
||||||
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
|
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
|
||||||
|
|
||||||
string = g_string_new (NULL);
|
string = g_string_new (NULL);
|
||||||
|
|
||||||
for (i = 0; i < data->argc; ++i)
|
for (i = 0; i < data->argc; ++i)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
g_string_append_c (string, '\0');
|
g_string_append_c (string, '\0');
|
||||||
g_string_append (string, data->argv[i]);
|
g_string_append (string, data->argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = string->len;
|
len = string->len;
|
||||||
s = g_string_free (string, FALSE);
|
s = g_string_free (string, FALSE);
|
||||||
g_variant_builder_add (&builder, "@ay",
|
g_variant_builder_add (&builder, "@ay",
|
||||||
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
|
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
|
||||||
|
|
||||||
value = g_dbus_connection_call_sync (connection,
|
value = g_dbus_connection_call_sync (connection,
|
||||||
data->factory_name,
|
data->factory_name,
|
||||||
TERMINAL_FACTORY_SERVICE_PATH,
|
TERMINAL_FACTORY_SERVICE_PATH,
|
||||||
TERMINAL_FACTORY_INTERFACE_NAME,
|
TERMINAL_FACTORY_INTERFACE_NAME,
|
||||||
"HandleArguments",
|
"HandleArguments",
|
||||||
g_variant_builder_end (&builder),
|
g_variant_builder_end (&builder),
|
||||||
G_VARIANT_TYPE ("()"),
|
G_VARIANT_TYPE ("()"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
&error);
|
&error);
|
||||||
if (value == NULL) {
|
if (value == NULL)
|
||||||
g_printerr ("Failed to forward arguments: %s\n", error->message);
|
{
|
||||||
g_error_free (error);
|
g_printerr ("Failed to forward arguments: %s\n", error->message);
|
||||||
data->exit_code = EXIT_FAILURE;
|
g_error_free (error);
|
||||||
gtk_main_quit ();
|
data->exit_code = EXIT_FAILURE;
|
||||||
} else {
|
gtk_main_quit ();
|
||||||
g_variant_unref (value);
|
}
|
||||||
data->exit_code = EXIT_SUCCESS;
|
else
|
||||||
}
|
{
|
||||||
|
g_variant_unref (value);
|
||||||
|
data->exit_code = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
terminal_options_free (data->options);
|
terminal_options_free (data->options);
|
||||||
data->options = NULL;
|
data->options = NULL;
|
||||||
|
|
||||||
gtk_main_quit ();
|
gtk_main_quit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Settings storage works as follows:
|
/* Settings storage works as follows:
|
||||||
|
@ -413,207 +432,214 @@ name_lost_cb (GDBusConnection *connection,
|
||||||
static Time
|
static Time
|
||||||
slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
|
slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
|
||||||
{
|
{
|
||||||
Window xwindow;
|
Window xwindow;
|
||||||
XEvent event;
|
XEvent event;
|
||||||
|
|
||||||
{
|
{
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
Atom atom_name;
|
Atom atom_name;
|
||||||
Atom atom_type;
|
Atom atom_type;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
attrs.override_redirect = True;
|
attrs.override_redirect = True;
|
||||||
attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
|
attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
|
||||||
|
|
||||||
xwindow =
|
xwindow =
|
||||||
XCreateWindow (xdisplay,
|
XCreateWindow (xdisplay,
|
||||||
RootWindow (xdisplay, 0),
|
RootWindow (xdisplay, 0),
|
||||||
-100, -100, 1, 1,
|
-100, -100, 1, 1,
|
||||||
0,
|
0,
|
||||||
CopyFromParent,
|
CopyFromParent,
|
||||||
CopyFromParent,
|
CopyFromParent,
|
||||||
(Visual *)CopyFromParent,
|
(Visual *)CopyFromParent,
|
||||||
CWOverrideRedirect | CWEventMask,
|
CWOverrideRedirect | CWEventMask,
|
||||||
&attrs);
|
&attrs);
|
||||||
|
|
||||||
atom_name = XInternAtom (xdisplay, "WM_NAME", TRUE);
|
atom_name = XInternAtom (xdisplay, "WM_NAME", TRUE);
|
||||||
g_assert (atom_name != None);
|
g_assert (atom_name != None);
|
||||||
atom_type = XInternAtom (xdisplay, "STRING", TRUE);
|
atom_type = XInternAtom (xdisplay, "STRING", TRUE);
|
||||||
g_assert (atom_type != None);
|
g_assert (atom_type != None);
|
||||||
|
|
||||||
name = "Fake Window";
|
name = "Fake Window";
|
||||||
XChangeProperty (xdisplay,
|
XChangeProperty (xdisplay,
|
||||||
xwindow, atom_name,
|
xwindow, atom_name,
|
||||||
atom_type,
|
atom_type,
|
||||||
8, PropModeReplace, (unsigned char *)name, strlen (name));
|
8, PropModeReplace, (unsigned char *)name, strlen (name));
|
||||||
}
|
}
|
||||||
|
|
||||||
XWindowEvent (xdisplay,
|
XWindowEvent (xdisplay,
|
||||||
xwindow,
|
xwindow,
|
||||||
PropertyChangeMask,
|
PropertyChangeMask,
|
||||||
&event);
|
&event);
|
||||||
|
|
||||||
XDestroyWindow(xdisplay, xwindow);
|
XDestroyWindow(xdisplay, xwindow);
|
||||||
|
|
||||||
return event.xproperty.time;
|
return event.xproperty.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_factory_name_for_display (const char *display_name)
|
get_factory_name_for_display (const char *display_name)
|
||||||
{
|
{
|
||||||
GString *name;
|
GString *name;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */);
|
name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */);
|
||||||
g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX);
|
g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX);
|
||||||
|
|
||||||
for (p = display_name; *p; ++p)
|
for (p = display_name; *p; ++p)
|
||||||
{
|
{
|
||||||
if (g_ascii_isalnum (*p))
|
if (g_ascii_isalnum (*p))
|
||||||
g_string_append_c (name, *p);
|
g_string_append_c (name, *p);
|
||||||
else
|
else
|
||||||
g_string_append_c (name, '_');
|
g_string_append_c (name, '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Factory name is \"%s\"\n", name->str);
|
"Factory name is \"%s\"\n", name->str);
|
||||||
|
|
||||||
return g_string_free (name, FALSE);
|
return g_string_free (name, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char **argv_copy;
|
char **argv_copy;
|
||||||
int argc_copy;
|
int argc_copy;
|
||||||
const char *startup_id, *display_name, *home_dir;
|
const char *startup_id, *display_name, *home_dir;
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
TerminalOptions *options;
|
TerminalOptions *options;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *working_directory;
|
char *working_directory;
|
||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
|
|
||||||
bindtextdomain (GETTEXT_PACKAGE, TERM_LOCALEDIR);
|
bindtextdomain (GETTEXT_PACKAGE, TERM_LOCALEDIR);
|
||||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
textdomain (GETTEXT_PACKAGE);
|
textdomain (GETTEXT_PACKAGE);
|
||||||
|
|
||||||
/* MateConf uses MateCORBA2 which need GThread. See bug #565516 */
|
/* MateConf uses MateCORBA2 which need GThread. See bug #565516 */
|
||||||
g_thread_init (NULL);
|
g_thread_init (NULL);
|
||||||
|
|
||||||
_terminal_debug_init ();
|
_terminal_debug_init ();
|
||||||
|
|
||||||
/* Make a NULL-terminated copy since we may need it later */
|
/* Make a NULL-terminated copy since we may need it later */
|
||||||
argv_copy = g_new (char *, argc + 1);
|
argv_copy = g_new (char *, argc + 1);
|
||||||
for (i = 0; i < argc; ++i)
|
for (i = 0; i < argc; ++i)
|
||||||
argv_copy [i] = argv [i];
|
argv_copy [i] = argv [i];
|
||||||
argv_copy [i] = NULL;
|
argv_copy [i] = NULL;
|
||||||
argc_copy = argc;
|
argc_copy = argc;
|
||||||
|
|
||||||
startup_id = g_getenv ("DESKTOP_STARTUP_ID");
|
startup_id = g_getenv ("DESKTOP_STARTUP_ID");
|
||||||
|
|
||||||
working_directory = g_get_current_dir ();
|
working_directory = g_get_current_dir ();
|
||||||
|
|
||||||
/* Now change directory to $HOME so we don't prevent unmounting, e.g. if the
|
/* Now change directory to $HOME so we don't prevent unmounting, e.g. if the
|
||||||
* factory is started by caja-open-terminal. See bug #565328.
|
* factory is started by caja-open-terminal. See bug #565328.
|
||||||
* On failure back to /.
|
* On failure back to /.
|
||||||
*/
|
*/
|
||||||
home_dir = g_get_home_dir ();
|
home_dir = g_get_home_dir ();
|
||||||
if (home_dir == NULL || chdir (home_dir) < 0)
|
if (home_dir == NULL || chdir (home_dir) < 0)
|
||||||
(void) chdir ("/");
|
(void) chdir ("/");
|
||||||
|
|
||||||
options = terminal_options_parse (working_directory,
|
options = terminal_options_parse (working_directory,
|
||||||
NULL,
|
NULL,
|
||||||
startup_id,
|
startup_id,
|
||||||
NULL,
|
NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
&argc, &argv,
|
&argc, &argv,
|
||||||
&error,
|
&error,
|
||||||
gtk_get_option_group (TRUE),
|
gtk_get_option_group (TRUE),
|
||||||
#ifdef WITH_SMCLIENT
|
#ifdef WITH_SMCLIENT
|
||||||
egg_sm_client_get_option_group (),
|
egg_sm_client_get_option_group (),
|
||||||
#endif
|
#endif
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_free (working_directory);
|
g_free (working_directory);
|
||||||
|
|
||||||
if (options == NULL) {
|
if (options == NULL)
|
||||||
g_printerr (_("Failed to parse arguments: %s\n"), error->message);
|
{
|
||||||
g_error_free (error);
|
g_printerr (_("Failed to parse arguments: %s\n"), error->message);
|
||||||
exit (EXIT_FAILURE);
|
g_error_free (error);
|
||||||
}
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
g_set_application_name (_("Terminal"));
|
g_set_application_name (_("Terminal"));
|
||||||
|
|
||||||
/* Unset the these env variables, so they doesn't end up
|
|
||||||
* in the factory's env and thus in the terminals' envs.
|
|
||||||
*/
|
|
||||||
g_unsetenv ("DESKTOP_STARTUP_ID");
|
|
||||||
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
|
|
||||||
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE");
|
|
||||||
|
|
||||||
/* Do this here so that gdk_display is initialized */
|
/* Unset the these env variables, so they doesn't end up
|
||||||
if (options->startup_id == NULL)
|
* in the factory's env and thus in the terminals' envs.
|
||||||
{
|
*/
|
||||||
/* Create a fake one containing a timestamp that we can use */
|
g_unsetenv ("DESKTOP_STARTUP_ID");
|
||||||
Time timestamp;
|
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
|
||||||
|
g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE");
|
||||||
|
|
||||||
timestamp = slowly_and_stupidly_obtain_timestamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
/* Do this here so that gdk_display is initialized */
|
||||||
|
if (options->startup_id == NULL)
|
||||||
|
{
|
||||||
|
/* Create a fake one containing a timestamp that we can use */
|
||||||
|
Time timestamp;
|
||||||
|
|
||||||
options->startup_id = g_strdup_printf ("_TIME%lu", timestamp);
|
timestamp = slowly_and_stupidly_obtain_timestamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
||||||
}
|
|
||||||
|
|
||||||
display = gdk_display_get_default ();
|
options->startup_id = g_strdup_printf ("_TIME%lu", timestamp);
|
||||||
display_name = gdk_display_get_name (display);
|
}
|
||||||
options->display_name = g_strdup (display_name);
|
|
||||||
|
|
||||||
if (options->use_factory) {
|
|
||||||
OwnData *data;
|
|
||||||
guint owner_id;
|
|
||||||
|
|
||||||
data = g_new (OwnData, 1);
|
display = gdk_display_get_default ();
|
||||||
data->factory_name = get_factory_name_for_display (display_name);
|
display_name = gdk_display_get_name (display);
|
||||||
data->options = options;
|
options->display_name = g_strdup (display_name);
|
||||||
data->exit_code = -1;
|
|
||||||
data->argv = argv_copy;
|
|
||||||
data->argc = argc_copy;
|
|
||||||
|
|
||||||
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
if (options->use_factory)
|
||||||
data->factory_name,
|
{
|
||||||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
OwnData *data;
|
||||||
bus_acquired_cb,
|
guint owner_id;
|
||||||
name_acquired_cb,
|
|
||||||
name_lost_cb,
|
|
||||||
data, NULL);
|
|
||||||
|
|
||||||
gtk_main ();
|
data = g_new (OwnData, 1);
|
||||||
|
data->factory_name = get_factory_name_for_display (display_name);
|
||||||
|
data->options = options;
|
||||||
|
data->exit_code = -1;
|
||||||
|
data->argv = argv_copy;
|
||||||
|
data->argc = argc_copy;
|
||||||
|
|
||||||
ret = data->exit_code;
|
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
||||||
g_bus_unown_name (owner_id);
|
data->factory_name,
|
||||||
|
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||||
|
bus_acquired_cb,
|
||||||
|
name_acquired_cb,
|
||||||
|
name_lost_cb,
|
||||||
|
data, NULL);
|
||||||
|
|
||||||
g_free (data->factory_name);
|
gtk_main ();
|
||||||
g_free (data);
|
|
||||||
|
|
||||||
} else {
|
ret = data->exit_code;
|
||||||
|
g_bus_unown_name (owner_id);
|
||||||
|
|
||||||
terminal_app_handle_options (terminal_app_get (), options, TRUE /* allow resume */, &error);
|
g_free (data->factory_name);
|
||||||
terminal_options_free (options);
|
g_free (data);
|
||||||
|
|
||||||
if (error == NULL) {
|
}
|
||||||
gtk_main ();
|
else
|
||||||
} else {
|
{
|
||||||
g_printerr ("Error handling options: %s\n", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
ret = EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal_app_shutdown ();
|
terminal_app_handle_options (terminal_app_get (), options, TRUE /* allow resume */, &error);
|
||||||
|
terminal_options_free (options);
|
||||||
|
|
||||||
g_free (argv_copy);
|
if (error == NULL)
|
||||||
|
{
|
||||||
|
gtk_main ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_printerr ("Error handling options: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
terminal_app_shutdown ();
|
||||||
|
|
||||||
|
g_free (argv_copy);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue