Convert print backends to use a GIOExtensionPoint

Use GIOModule and GIOExtensionPoint. This is the preferred
way to define extensions these days, instead of manually
implementing type modules.
This commit is contained in:
Matthias Clasen 2018-02-18 18:00:42 -05:00
parent 7272610a02
commit de0039546b
7 changed files with 212 additions and 383 deletions

View File

@ -129,6 +129,7 @@
#include "gtkwidgetprivate.h"
#include "gtkwindowprivate.h"
#include "gtkwindowgroup.h"
#include "gtkprintbackend.h"
#include "a11y/gtkaccessibility.h"
@ -655,6 +656,8 @@ do_post_parse_initialization (void)
_gtk_accel_map_init ();
gtk_print_backends_init ();
gtk_initialized = TRUE;
display_manager = gdk_display_manager_get ();

View File

@ -22,6 +22,7 @@
#include <gmodule.h>
#include "gtkintl.h"
#include "gtkdebug.h"
#include "gtkmodulesprivate.h"
#include "gtkmarshalers.h"
#include "gtkprivate.h"
@ -78,223 +79,32 @@ gtk_print_backend_error_quark (void)
return quark;
}
/*****************************************
* GtkPrintBackendModule modules *
*****************************************/
typedef struct _GtkPrintBackendModule GtkPrintBackendModule;
typedef struct _GtkPrintBackendModuleClass GtkPrintBackendModuleClass;
struct _GtkPrintBackendModule
void
gtk_print_backends_init (void)
{
GTypeModule parent_instance;
GModule *library;
GIOExtensionPoint *ep;
GIOModuleScope *scope;
char **paths;
int i;
void (*init) (GTypeModule *module);
void (*exit) (void);
GtkPrintBackend* (*create) (void);
GTK_NOTE (MODULES,
g_print ("Registering extension point %s\n", GTK_PRINT_BACKEND_EXTENSION_POINT_NAME));
gchar *path;
};
ep = g_io_extension_point_register (GTK_PRINT_BACKEND_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, GTK_TYPE_PRINT_BACKEND);
struct _GtkPrintBackendModuleClass
{
GTypeModuleClass parent_class;
};
scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
GType _gtk_print_backend_module_get_type (void);
G_DEFINE_TYPE (GtkPrintBackendModule, _gtk_print_backend_module, G_TYPE_TYPE_MODULE)
#define GTK_TYPE_PRINT_BACKEND_MODULE (_gtk_print_backend_module_get_type ())
#define GTK_PRINT_BACKEND_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_PRINT_BACKEND_MODULE, GtkPrintBackendModule))
static GSList *loaded_backends;
static gboolean
gtk_print_backend_module_load (GTypeModule *module)
{
GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
gpointer initp, exitp, createp;
pb_module->library = g_module_open (pb_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
if (!pb_module->library)
paths = _gtk_get_module_path ("printbackends");
for (i = 0; paths[i]; i++)
{
g_warning ("%s", g_module_error ());
return FALSE;
}
/* extract symbols from the lib */
if (!g_module_symbol (pb_module->library, "pb_module_init",
&initp) ||
!g_module_symbol (pb_module->library, "pb_module_exit",
&exitp) ||
!g_module_symbol (pb_module->library, "pb_module_create",
&createp))
{
g_warning ("%s", g_module_error ());
g_module_close (pb_module->library);
return FALSE;
GTK_NOTE (MODULES,
g_print ("Scanning io modules in %s\n", paths[i]));
g_io_modules_scan_all_in_directory_with_scope (paths[i], scope);
}
g_strfreev (paths);
pb_module->init = initp;
pb_module->exit = exitp;
pb_module->create = createp;
/* call the printbackend's init function to let it */
/* setup anything it needs to set up. */
pb_module->init (module);
return TRUE;
}
static void
gtk_print_backend_module_unload (GTypeModule *module)
{
GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
pb_module->exit();
g_module_close (pb_module->library);
pb_module->library = NULL;
pb_module->init = NULL;
pb_module->exit = NULL;
pb_module->create = NULL;
}
/* This only will ever be called if an error occurs during
* initialization
*/
static void
gtk_print_backend_module_finalize (GObject *object)
{
GtkPrintBackendModule *module = GTK_PRINT_BACKEND_MODULE (object);
g_free (module->path);
G_OBJECT_CLASS (_gtk_print_backend_module_parent_class)->finalize (object);
}
static void
_gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class)
{
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
module_class->load = gtk_print_backend_module_load;
module_class->unload = gtk_print_backend_module_unload;
gobject_class->finalize = gtk_print_backend_module_finalize;
}
static void
gtk_print_backend_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPrintBackend *backend = GTK_PRINT_BACKEND (object);
GtkPrintBackendPrivate *priv = backend->priv;
switch (prop_id)
{
case PROP_STATUS:
priv->status = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_print_backend_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPrintBackend *backend = GTK_PRINT_BACKEND (object);
GtkPrintBackendPrivate *priv = backend->priv;
switch (prop_id)
{
case PROP_STATUS:
g_value_set_int (value, priv->status);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
_gtk_print_backend_module_init (GtkPrintBackendModule *pb_module)
{
}
static GtkPrintBackend *
_gtk_print_backend_module_create (GtkPrintBackendModule *pb_module)
{
GtkPrintBackend *pb;
if (g_type_module_use (G_TYPE_MODULE (pb_module)))
{
pb = pb_module->create ();
g_type_module_unuse (G_TYPE_MODULE (pb_module));
return pb;
}
return NULL;
}
static GtkPrintBackend *
_gtk_print_backend_create (const gchar *backend_name)
{
GSList *l;
gchar *module_path;
gchar *full_name;
GtkPrintBackendModule *pb_module;
GtkPrintBackend *pb;
for (l = loaded_backends; l != NULL; l = l->next)
{
pb_module = l->data;
if (strcmp (G_TYPE_MODULE (pb_module)->name, backend_name) == 0)
return _gtk_print_backend_module_create (pb_module);
}
pb = NULL;
if (g_module_supported ())
{
full_name = g_strconcat ("printbackend-", backend_name, NULL);
module_path = _gtk_find_module (full_name, "printbackends");
g_free (full_name);
if (module_path)
{
pb_module = g_object_new (GTK_TYPE_PRINT_BACKEND_MODULE, NULL);
g_type_module_set_name (G_TYPE_MODULE (pb_module), backend_name);
pb_module->path = g_strdup (module_path);
loaded_backends = g_slist_prepend (loaded_backends,
pb_module);
pb = _gtk_print_backend_module_create (pb_module);
/* Increase use-count so that we don't unload print backends.
* There is a problem with module unloading in the cups module,
* see cups_dispatch_watch_finalize for details.
*/
g_type_module_use (G_TYPE_MODULE (pb_module));
}
g_free (module_path);
}
return pb;
g_io_module_scope_free (scope);
}
/**
@ -311,9 +121,12 @@ gtk_print_backend_load_modules (void)
gchar **backends;
gint i;
GtkSettings *settings;
GIOExtensionPoint *ep;
result = NULL;
ep = g_io_extension_point_lookup (GTK_PRINT_BACKEND_EXTENSION_POINT_NAME);
settings = gtk_settings_get_default ();
if (settings)
g_object_get (settings, "gtk-print-backends", &setting, NULL);
@ -324,9 +137,19 @@ gtk_print_backend_load_modules (void)
for (i = 0; backends[i]; i++)
{
backend = _gtk_print_backend_create (g_strstrip (backends[i]));
if (backend)
result = g_list_append (result, backend);
GIOExtension *ext;
GType type;
ext = g_io_extension_point_get_extension_by_name (ep, backends[i]);
if (!ext)
continue;
GTK_NOTE (PRINTING,
g_print ("Found %s print backend\n", backends[i]));
type = g_io_extension_get_type (ext);
backend = g_object_new (type, NULL);
result = g_list_append (result, backend);
}
g_strfreev (backends);
@ -359,7 +182,47 @@ static void request_password (GtkPrintBack
gpointer auth_info_visible,
const gchar *prompt,
gboolean can_store_auth_info);
static void
gtk_print_backend_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPrintBackend *backend = GTK_PRINT_BACKEND (object);
GtkPrintBackendPrivate *priv = backend->priv;
switch (prop_id)
{
case PROP_STATUS:
priv->status = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_print_backend_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPrintBackend *backend = GTK_PRINT_BACKEND (object);
GtkPrintBackendPrivate *priv = backend->priv;
switch (prop_id)
{
case PROP_STATUS:
g_value_set_int (value, priv->status);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_print_backend_class_init (GtkPrintBackendClass *class)
{

View File

@ -140,6 +140,8 @@ struct _GtkPrintBackendClass
void (*_gtk_reserved4) (void);
};
#define GTK_PRINT_BACKEND_EXTENSION_POINT_NAME "gtk-print-backend"
GDK_AVAILABLE_IN_ALL
GType gtk_print_backend_get_type (void) G_GNUC_CONST;
@ -222,6 +224,8 @@ GDK_AVAILABLE_IN_ALL
gboolean gtk_printer_set_state_message (GtkPrinter *printer,
const gchar *message);
void gtk_print_backends_init (void);
G_END_DECLS

View File

@ -103,48 +103,37 @@ static void cloudprint_printer_request_details (GtkPri
TGOAAccount * t_goa_account_copy (TGOAAccount *account);
void t_goa_account_free (gpointer data);
GG_DEFINE_DYNAMIC_TYPE(GtkPrintBackendCloudprint, gtk_print_backend_cloudprint, GTK_TYPE_PRINT_BACKEND)
static void
gtk_print_backend_cloudprint_register_type (GTypeModule *module)
void
g_io_module_load (GIOModule *module)
{
const GTypeInfo print_backend_cloudprint_info =
{
sizeof (GtkPrintBackendCloudprintClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_print_backend_cloudprint_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkPrintBackendCloudprint),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_print_backend_cloudprint_init,
g_type_module_use (G_TYPE_MODULE (module));
gtk_print_backend_cloudprint_register_type (G_TYPE_MODULE (module));
gtk_cloudprint_account_register_type (G_TYPE_MODULE (module));
gtk_printer_cloudprint_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
GTK_TYPE_PRINT_BACKEND_CLOUDPRINT,
"cloudprint",
10);
}
void
g_io_module_unload (GIOModule *module)
{
}
char **
g_io_module_query (void)
{
char *eps[] = {
GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
NULL
};
print_backend_cloudprint_type = g_type_module_register_type (module,
GTK_TYPE_PRINT_BACKEND,
"GtkPrintBackendCloudprint",
&print_backend_cloudprint_info, 0);
}
G_MODULE_EXPORT void
pb_module_init (GTypeModule *module)
{
gtk_print_backend_cloudprint_register_type (module);
gtk_cloudprint_account_register_type (module);
gtk_printer_cloudprint_register_type (module);
}
G_MODULE_EXPORT void
pb_module_exit (void)
{
}
G_MODULE_EXPORT GtkPrintBackend *
pb_module_create (void)
{
return gtk_print_backend_cloudprint_new ();
return g_strdupv (eps);
}
/*
@ -190,6 +179,11 @@ gtk_print_backend_cloudprint_class_init (GtkPrintBackendCloudprintClass *klass)
backend_class->printer_request_details = cloudprint_printer_request_details;
}
static void
gtk_print_backend_cloudprint_class_finalize (GtkPrintBackendCloudprintClass *class)
{
}
static void
gtk_print_backend_cloudprint_init (GtkPrintBackendCloudprint *backend)
{

View File

@ -236,49 +236,38 @@ static void secrets_service_vanished_cb (GDBusConnec
const gchar *name,
gpointer user_data);
static void
gtk_print_backend_cups_register_type (GTypeModule *module)
G_DEFINE_DYNAMIC_TYPE(GtkPrintBackendCups, gtk_print_backend_cups, GTK_TYPE_PRINT_BACKEND)
void
g_io_module_load (GIOModule *module)
{
const GTypeInfo print_backend_cups_info =
{
sizeof (GtkPrintBackendCupsClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_print_backend_cups_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkPrintBackendCups),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_print_backend_cups_init
g_type_module_use (G_TYPE_MODULE (module));
gtk_print_backend_cups_register_type (G_TYPE_MODULE (module));
gtk_printer_cups_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
GTK_TYPE_PRINT_BACKEND_CUPS,
"cups",
10);
}
void
g_io_module_unload (GIOModule *module)
{
}
char **
g_io_module_query (void)
{
char *eps[] = {
GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
NULL
};
print_backend_cups_type = g_type_module_register_type (module,
GTK_TYPE_PRINT_BACKEND,
"GtkPrintBackendCups",
&print_backend_cups_info, 0);
return g_strdupv (eps);
}
G_MODULE_EXPORT void
pb_module_init (GTypeModule *module)
{
GTK_NOTE (PRINTING,
g_print ("CUPS Backend: Initializing the CUPS print backend module\n"));
gtk_print_backend_cups_register_type (module);
gtk_printer_cups_register_type (module);
}
G_MODULE_EXPORT void
pb_module_exit (void)
{
}
G_MODULE_EXPORT GtkPrintBackend *
pb_module_create (void)
{
return gtk_print_backend_cups_new ();
}
/* CUPS 1.6 Getter/Setter Functions CUPS 1.6 makes private most of the
* IPP structures and enforces access via new getter functions, which
* are unfortunately not available in earlier versions. We define
@ -287,7 +276,7 @@ pb_module_create (void)
*/
#ifndef HAVE_CUPS_API_1_6
#define ippGetOperation(ipp_request) ipp_request->request.op.operation_id
#define ippGetInteger(attr, index) attr->values[index].integer
#define ippGet:Integer(attr, index) attr->values[index].integer
#define ippGetBoolean(attr, index) attr->values[index].boolean
#define ippGetString(attr, index, foo) attr->values[index].string.text
#define ippGetValueTag(attr) attr->value_tag
@ -323,14 +312,10 @@ ippNextAttribute (ipp_t *ipp)
return (ipp->current = ipp->current->next);
}
#endif
/*
* GtkPrintBackendCups
*/
GType
gtk_print_backend_cups_get_type (void)
{
return print_backend_cups_type;
}
/**
* gtk_print_backend_cups_new:
@ -376,6 +361,11 @@ gtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class)
backend_class->set_password = gtk_print_backend_cups_set_password;
}
static void
gtk_print_backend_cups_class_finalize (GtkPrintBackendCupsClass *class)
{
}
static gboolean
option_is_ipp_option (GtkPrinterOption *option)
{

View File

@ -104,53 +104,35 @@ static cairo_surface_t * file_printer_create_cairo_surface (GtkPrinter
static GList * file_printer_list_papers (GtkPrinter *printer);
static GtkPageSetup * file_printer_get_default_page_size (GtkPrinter *printer);
static void
gtk_print_backend_file_register_type (GTypeModule *module)
G_DEFINE_DYNAMIC_TYPE(GtkPrintBackendFile, gtk_print_backend_file, GTK_TYPE_PRINT_BACKEND)
void
g_io_module_load (GIOModule *module)
{
const GTypeInfo print_backend_file_info =
{
sizeof (GtkPrintBackendFileClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_print_backend_file_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkPrintBackendFile),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_print_backend_file_init,
g_type_module_use (G_TYPE_MODULE (module));
gtk_print_backend_file_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
GTK_TYPE_PRINT_BACKEND_FILE,
"file",
10);
}
void
g_io_module_unload (GIOModule *module)
{
}
char **
g_io_module_query (void)
{
char *eps[] = {
GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
NULL
};
print_backend_file_type = g_type_module_register_type (module,
GTK_TYPE_PRINT_BACKEND,
"GtkPrintBackendFile",
&print_backend_file_info, 0);
}
G_MODULE_EXPORT void
pb_module_init (GTypeModule *module)
{
gtk_print_backend_file_register_type (module);
}
G_MODULE_EXPORT void
pb_module_exit (void)
{
}
G_MODULE_EXPORT GtkPrintBackend *
pb_module_create (void)
{
return gtk_print_backend_file_new ();
}
/*
* GtkPrintBackendFile
*/
GType
gtk_print_backend_file_get_type (void)
{
return print_backend_file_type;
return g_strdupv (eps);
}
/**
@ -184,6 +166,11 @@ gtk_print_backend_file_class_init (GtkPrintBackendFileClass *class)
backend_class->printer_get_default_page_size = file_printer_get_default_page_size;
}
static void
gtk_print_backend_file_class_finalize (GtkPrintBackendFileClass *class)
{
}
/* return N_FORMATS if no explicit format in the settings */
static OutputFormat
format_from_settings (GtkPrintSettings *settings)

View File

@ -83,53 +83,36 @@ static void gtk_print_backend_lpr_print_stream (GtkPrintBacke
gpointer user_data,
GDestroyNotify dnotify);
static void
gtk_print_backend_lpr_register_type (GTypeModule *module)
G_DEFINE_DYNAMIC_TYPE(GtkPrintBackendLpr, gtk_print_backend_lpr, GTK_TYPE_PRINT_BACKEND
void
g_io_module_load (GIOModule *module)
{
const GTypeInfo print_backend_lpr_info =
{
sizeof (GtkPrintBackendLprClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_print_backend_lpr_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkPrintBackendLpr),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_print_backend_lpr_init,
g_type_module_use (G_TYPE_MODULE (module));
gtk_print_backend_lpr_register_type (G_TYPE_MODULE (module));
gtk_printer_lpr_register_type (G_TYPE_MODULE (module));
g_io_extension_point_implement (GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
GTK_TYPE_PRINT_BACKEND_CUPS,
"lpr",
10);
}
void
g_io_module_unload (GIOModule *module)
{
}
char **
g_io_module_query (void)
{
char *eps[] = {
GTK_PRINT_BACKEND_EXTENSION_POINT_NAME,
NULL
};
print_backend_lpr_type = g_type_module_register_type (module,
GTK_TYPE_PRINT_BACKEND,
"GtkPrintBackendLpr",
&print_backend_lpr_info, 0);
}
G_MODULE_EXPORT void
pb_module_init (GTypeModule *module)
{
gtk_print_backend_lpr_register_type (module);
}
G_MODULE_EXPORT void
pb_module_exit (void)
{
}
G_MODULE_EXPORT GtkPrintBackend *
pb_module_create (void)
{
return gtk_print_backend_lpr_new ();
}
/*
* GtkPrintBackendLpr
*/
GType
gtk_print_backend_lpr_get_type (void)
{
return print_backend_lpr_type;
return g_strdupv (eps);
}
/**
@ -161,6 +144,11 @@ gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class)
backend_class->printer_prepare_for_print = lpr_printer_prepare_for_print;
}
static void
gtk_print_backend_lpr_class_finalize (GtkPrintBackendLprClass *class)
{
}
static cairo_status_t
_cairo_write (void *closure,
const unsigned char *data,