diff --git a/introspection/nm-manager-client.xml b/introspection/nm-manager-client.xml index 9a0d4da214..a3e89f34b7 100644 --- a/introspection/nm-manager-client.xml +++ b/introspection/nm-manager-client.xml @@ -43,6 +43,8 @@ object. dbus-glib generates the same bound function names for D-Bus the methods + + diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 8303f4d469..61d57e0717 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -120,6 +120,18 @@ + + + Indicates if WiMAX devices are currently enabled or not. + + + + + + Indicates if the WiMAX hardware is currently enabled, i.e. the state of the RF kill switch. + + + List of active connection object paths. diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 4b1b09c421..f396e95dfa 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -43,6 +43,9 @@ global: nm_client_wwan_get_enabled; nm_client_wwan_hardware_get_enabled; nm_client_wwan_set_enabled; + nm_client_wimax_get_enabled; + nm_client_wimax_hardware_get_enabled; + nm_client_wimax_set_enabled; nm_dbus_settings_get_connection_by_path; nm_dbus_settings_get_type; nm_dbus_settings_new; diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 05fa4dbf24..8365d0907c 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -63,6 +63,9 @@ typedef struct { gboolean wwan_enabled; gboolean wwan_hw_enabled; + + gboolean wimax_enabled; + gboolean wimax_hw_enabled; } NMClientPrivate; enum { @@ -73,6 +76,8 @@ enum { PROP_WIRELESS_HARDWARE_ENABLED, PROP_WWAN_ENABLED, PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, PROP_ACTIVE_CONNECTIONS, LAST_PROP @@ -188,6 +193,36 @@ update_wwan_status (NMClient *client, gboolean notify) } } +static void +update_wimax_status (NMClient *client, gboolean notify) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + gboolean val; + + val = _nm_object_get_boolean_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WimaxHardwareEnabled"); + if (val != priv->wimax_hw_enabled) { + priv->wimax_hw_enabled = val; + if (notify) + _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_WIMAX_HARDWARE_ENABLED); + } + + if (priv->wimax_hw_enabled == FALSE) + val = FALSE; + else { + val = _nm_object_get_boolean_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WimaxEnabled"); + } + + if (val != priv->wimax_enabled) { + priv->wimax_enabled = val; + if (notify) + _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_WIMAX_ENABLED); + } +} + static GObject * new_active_connection (DBusGConnection *connection, const char *path) { @@ -254,6 +289,8 @@ register_for_property_changed (NMClient *client) { NM_CLIENT_WIRELESS_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wireless_hw_enabled }, { NM_CLIENT_WWAN_ENABLED, _nm_object_demarshal_generic, &priv->wwan_enabled }, { NM_CLIENT_WWAN_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wwan_hw_enabled }, + { NM_CLIENT_WIMAX_ENABLED, _nm_object_demarshal_generic, &priv->wimax_enabled }, + { NM_CLIENT_WIMAX_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wimax_hw_enabled }, { NM_CLIENT_ACTIVE_CONNECTIONS, demarshal_active_connections, &priv->active_connections }, { NULL }, }; @@ -329,6 +366,7 @@ constructor (GType type, if (priv->manager_running) { update_wireless_status (NM_CLIENT (object), FALSE); update_wwan_status (NM_CLIENT (object), FALSE); + update_wimax_status (NM_CLIENT (object), FALSE); nm_client_get_state (NM_CLIENT (object)); } @@ -405,6 +443,20 @@ set_property (GObject *object, guint prop_id, _nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WWAN_HARDWARE_ENABLED); } break; + case PROP_WIMAX_ENABLED: + b = g_value_get_boolean (value); + if (priv->wimax_enabled != b) { + priv->wimax_enabled = b; + _nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WIMAX_ENABLED); + } + break; + case PROP_WIMAX_HARDWARE_ENABLED: + b = g_value_get_boolean (value); + if (priv->wimax_hw_enabled != b) { + priv->wimax_hw_enabled = b; + _nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WIMAX_HARDWARE_ENABLED); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -439,6 +491,12 @@ get_property (GObject *object, case PROP_WWAN_HARDWARE_ENABLED: g_value_set_boolean (value, priv->wwan_hw_enabled); break; + case PROP_WIMAX_ENABLED: + g_value_set_boolean (value, priv->wimax_enabled); + break; + case PROP_WIMAX_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->wimax_hw_enabled); + break; case PROP_ACTIVE_CONNECTIONS: g_value_set_boxed (value, nm_client_get_active_connections (self)); break; @@ -541,6 +599,32 @@ nm_client_class_init (NMClientClass *client_class) TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** + * NMClient::wimax-enabled: + * + * Whether WiMAX functionality is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIMAX_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, + "WimaxEnabled", + "Is WiMAX enabled", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + /** + * NMClient::wimax-hardware-enabled: + * + * Whether the WiMAX hardware is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIMAX_HARDWARE_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, + "WimaxHardwareEnabled", + "Is WiMAX hardware enabled", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** * NMClient::active-connections: * @@ -652,10 +736,13 @@ proxy_name_owner_changed (DBusGProxy *proxy, priv->wireless_hw_enabled = FALSE; priv->wwan_enabled = FALSE; priv->wwan_hw_enabled = FALSE; + priv->wimax_enabled = FALSE; + priv->wimax_hw_enabled = FALSE; } else { _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_MANAGER_RUNNING); update_wireless_status (client, TRUE); update_wwan_status (client, TRUE); + update_wimax_status (client, TRUE); } } @@ -1015,6 +1102,61 @@ nm_client_wwan_hardware_get_enabled (NMClient *client) return NM_CLIENT_GET_PRIVATE (client)->wwan_hw_enabled; } +/** + * nm_client_wimax_get_enabled: + * @client: a #NMClient + * + * Determines whether WiMAX is enabled. + * + * Returns: %TRUE if WiMAX is enabled + **/ +gboolean +nm_client_wimax_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return NM_CLIENT_GET_PRIVATE (client)->wimax_enabled; +} + +/** + * nm_client_wimax_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable WiMAX + * + * Enables or disables WiMAX devices. + **/ +void +nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) +{ + GValue value = {0,}; + + g_return_if_fail (NM_IS_CLIENT (client)); + + g_value_init (&value, G_TYPE_BOOLEAN); + g_value_set_boolean (&value, enabled); + + _nm_object_set_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WimaxEnabled", + &value); +} + +/** + * nm_client_wimax_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the WiMAX hardware is enabled. + * + * Returns: %TRUE if the WiMAX hardware is enabled + **/ +gboolean +nm_client_wimax_hardware_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return NM_CLIENT_GET_PRIVATE (client)->wimax_hw_enabled; +} + /** * nm_client_get_state: * @client: a #NMClient diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 6aafc0872c..b75bf2231a 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -47,6 +47,8 @@ G_BEGIN_DECLS #define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" #define NM_CLIENT_WWAN_ENABLED "wwan-enabled" #define NM_CLIENT_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" +#define NM_CLIENT_WIMAX_ENABLED "wimax-enabled" +#define NM_CLIENT_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" #define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections" typedef struct { @@ -96,6 +98,10 @@ gboolean nm_client_wwan_get_enabled (NMClient *client); void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled); gboolean nm_client_wwan_hardware_get_enabled (NMClient *client); +gboolean nm_client_wimax_get_enabled (NMClient *client); +void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled); +gboolean nm_client_wimax_hardware_get_enabled (NMClient *client); + NMState nm_client_get_state (NMClient *client); gboolean nm_client_get_manager_running (NMClient *client); const GPtrArray *nm_client_get_active_connections (NMClient *client); diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 09a4320c78..e815745ca2 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -330,15 +330,17 @@ parse_state_file (const char *filename, gboolean *net_enabled, gboolean *wifi_enabled, gboolean *wwan_enabled, + gboolean *wimax_enabled, GError **error) { GKeyFile *state_file; GError *tmp_error = NULL; - gboolean wifi, net, wwan; + gboolean wifi, net, wwan, wimax; g_return_val_if_fail (net_enabled != NULL, FALSE); g_return_val_if_fail (wifi_enabled != NULL, FALSE); g_return_val_if_fail (wwan_enabled != NULL, FALSE); + g_return_val_if_fail (wimax_enabled != NULL, FALSE); state_file = g_key_file_new (); if (!state_file) { @@ -377,6 +379,7 @@ parse_state_file (const char *filename, g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled); g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled); g_key_file_set_boolean (state_file, "main", "WWANEnabled", *wwan_enabled); + g_key_file_set_boolean (state_file, "main", "WimaxEnabled", *wimax_enabled); data = g_key_file_to_data (state_file, &len, NULL); if (data) @@ -419,6 +422,14 @@ parse_state_file (const char *filename, *wwan_enabled = wwan; g_clear_error (&tmp_error); + wimax = g_key_file_get_boolean (state_file, "main", "WimaxEnabled", &tmp_error); + if (tmp_error) { + g_clear_error (error); + g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message); + } else + *wimax_enabled = wimax; + g_clear_error (&tmp_error); + g_key_file_free (state_file); return TRUE; @@ -437,7 +448,7 @@ main (int argc, char *argv[]) char *pidfile = NULL, *user_pidfile = NULL; char *config = NULL, *plugins = NULL; char *state_file = NM_DEFAULT_SYSTEM_STATE_FILE; - gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE; + gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; gboolean success; NMPolicy *policy = NULL; NMVPNManager *vpn_manager = NULL; @@ -520,7 +531,7 @@ main (int argc, char *argv[]) g_clear_error (&error); /* Parse the state file */ - if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &error)) { + if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) { g_warning ("State file %s parsing failed: (%d) %s.", state_file, error ? error->code : -1, @@ -600,6 +611,7 @@ main (int argc, char *argv[]) net_enabled, wifi_enabled, wwan_enabled, + wimax_enabled, &error); if (manager == NULL) { nm_error ("Failed to initialize the network manager: %s", diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index ad81a5a78b..b326dfe80a 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -909,7 +909,7 @@ check_companion_cb (gpointer user_data) if (priv->device_added_cb != 0) return FALSE; - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL); priv->device_added_cb = g_signal_connect (manager, "device-added", G_CALLBACK (device_added_cb), self); diff --git a/src/nm-manager.c b/src/nm-manager.c index 7eecbe0ba8..c98254cf12 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -63,6 +63,8 @@ #define NM_MANAGER_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" #define NM_MANAGER_WWAN_ENABLED "wwan-enabled" #define NM_MANAGER_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" +#define NM_MANAGER_WIMAX_ENABLED "wimax-enabled" +#define NM_MANAGER_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" #define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections" static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err); @@ -231,6 +233,8 @@ enum { PROP_WIRELESS_HARDWARE_ENABLED, PROP_WWAN_ENABLED, PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, PROP_ACTIVE_CONNECTIONS, /* Not exported */ @@ -1339,6 +1343,12 @@ rfkill_wwan_filter (GObject *object) return NM_IS_MODEM (object); } +static gboolean +rfkill_wimax_filter (GObject *object) +{ + return NM_IS_WIMAX_DEVICE (object); +} + static void manager_rfkill_update_one_type (NMManager *self, RadioState *rstate, @@ -1484,6 +1494,10 @@ add_device (NMManager *self, NMDevice *device) nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), priv->radio_states[RFKILL_TYPE_WWAN].enabled); */ + } else if (NM_IS_WIMAX_DEVICE (device)) { + nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX); + nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), + priv->radio_states[RFKILL_TYPE_WIMAX].enabled); } type_desc = nm_device_get_type_desc (device); @@ -2872,6 +2886,7 @@ nm_manager_get (const char *config_file, gboolean initial_net_enabled, gboolean initial_wifi_enabled, gboolean initial_wwan_enabled, + gboolean initial_wimax_enabled, GError **error) { static NMManager *singleton = NULL; @@ -2904,6 +2919,7 @@ nm_manager_get (const char *config_file, priv->radio_states[RFKILL_TYPE_WLAN].enabled = initial_wifi_enabled; priv->radio_states[RFKILL_TYPE_WWAN].enabled = initial_wwan_enabled; + priv->radio_states[RFKILL_TYPE_WIMAX].enabled = initial_wimax_enabled; g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); @@ -3034,6 +3050,11 @@ set_property (GObject *object, guint prop_id, &priv->radio_states[RFKILL_TYPE_WWAN], g_value_get_boolean (value)); break; + case PROP_WIMAX_ENABLED: + manager_set_radio_enabled (NM_MANAGER (object), + &priv->radio_states[RFKILL_TYPE_WIMAX], + g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3064,6 +3085,12 @@ get_property (GObject *object, guint prop_id, case PROP_WWAN_HARDWARE_ENABLED: g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled); break; + case PROP_WIMAX_ENABLED: + g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].enabled); + break; + case PROP_WIMAX_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].hw_enabled); + break; case PROP_ACTIVE_CONNECTIONS: g_value_take_boxed (value, get_active_connections (self, NULL)); break; @@ -3105,6 +3132,14 @@ nm_manager_init (NMManager *manager) priv->radio_states[RFKILL_TYPE_WWAN].other_enabled_func = nm_manager_get_modem_enabled_state; priv->radio_states[RFKILL_TYPE_WWAN].object_filter_func = rfkill_wwan_filter; + priv->radio_states[RFKILL_TYPE_WIMAX].enabled = TRUE; + priv->radio_states[RFKILL_TYPE_WIMAX].key = "WimaxEnabled"; + priv->radio_states[RFKILL_TYPE_WIMAX].prop = NM_MANAGER_WIMAX_ENABLED; + priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NM_MANAGER_WIMAX_HARDWARE_ENABLED; + priv->radio_states[RFKILL_TYPE_WIMAX].desc = "WiMAX"; + priv->radio_states[RFKILL_TYPE_WIMAX].other_enabled_func = NULL; + priv->radio_states[RFKILL_TYPE_WIMAX].object_filter_func = rfkill_wimax_filter; + for (i = 0; i < RFKILL_TYPE_MAX; i++) priv->radio_states[i].hw_enabled = TRUE; @@ -3215,6 +3250,22 @@ nm_manager_class_init (NMManagerClass *manager_class) TRUE, G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_WIMAX_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, + "WimaxEnabled", + "Is WiMAX enabled", + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_WIMAX_HARDWARE_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, + "WimaxHardwareEnabled", + "Whether WiMAX is disabled by a hardware switch or not", + TRUE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTIONS, g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, diff --git a/src/nm-manager.h b/src/nm-manager.h index 1090409a9b..bebd9217b7 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -75,6 +75,7 @@ NMManager *nm_manager_get (const char *config_file, gboolean initial_net_enabled, gboolean initial_wifi_enabled, gboolean initial_wwan_enabled, + gboolean initial_wimax_enabled, GError **error); void nm_manager_start (NMManager *manager); diff --git a/src/wimax/nm-wimax-device.c b/src/wimax/nm-wimax-device.c index ffb0ab5fd0..66a7b65c88 100644 --- a/src/wimax/nm-wimax-device.c +++ b/src/wimax/nm-wimax-device.c @@ -38,7 +38,10 @@ static gboolean impl_device_get_nsp_list (NMWimaxDevice *device, GPtrArray **lis #include "nm-wimax-device-glue.h" -G_DEFINE_TYPE (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE) +static void device_interface_init (NMDeviceInterface *iface_class); + +G_DEFINE_TYPE_EXTENDED (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) enum { PROP_0, @@ -225,7 +228,7 @@ schedule_rf_state_update (NMWimaxDevice *self) { NMWimaxDevicePrivate *priv = GET_PRIVATE (self); - /* This is scheduled because on startup we get nm_wimax_device_set_enabled() + /* This is scheduled because on startup we get nm_device_interface_set_enabled() while the device state is still unmanaged. It'll change to unavailable right after it, so it would result in enabling RF kill, followed by disabling it again. Pretty lame. @@ -235,21 +238,6 @@ schedule_rf_state_update (NMWimaxDevice *self) priv->rf_update_id = g_idle_add ((GSourceFunc) rf_state_update, self); } -void -nm_wimax_device_set_enabled (NMWimaxDevice *self, gboolean enabled) -{ - NMWimaxDevicePrivate *priv; - - g_return_if_fail (NM_IS_WIMAX_DEVICE (self)); - - priv = GET_PRIVATE (self); - if (priv->enabled == enabled) - return; - - priv->enabled = enabled; - schedule_rf_state_update (self); -} - GSList * nm_wimax_device_get_nsps (NMWimaxDevice *self) { @@ -612,6 +600,20 @@ device_state_changed (NMDevice *device, } } +/* NMDeviceInterface interface */ + +static void +real_set_enabled (NMDeviceInterface *device, gboolean enabled) +{ + NMWimaxDevicePrivate *priv = GET_PRIVATE (device); + + if (priv->enabled == enabled) + return; + + priv->enabled = enabled; + schedule_rf_state_update (NM_WIMAX_DEVICE (device)); +} + /* NMDevice methods */ static void @@ -862,6 +864,12 @@ real_deactivate_quickly (NMDevice *device) /* GObject methods */ +static void +device_interface_init (NMDeviceInterface *iface_class) +{ + iface_class->set_enabled = real_set_enabled; +} + static void nm_wimax_device_init (NMWimaxDevice *self) { diff --git a/src/wimax/nm-wimax-device.h b/src/wimax/nm-wimax-device.h index e381dddfc2..301ebdd8db 100644 --- a/src/wimax/nm-wimax-device.h +++ b/src/wimax/nm-wimax-device.h @@ -65,9 +65,6 @@ void nm_wimax_device_get_hw_address (NMWimaxDevice *self, struct ether_addr *addr); guint32 nm_wimax_device_get_ifindex (NMWimaxDevice *self); -void nm_wimax_device_set_enabled (NMWimaxDevice *self, - gboolean enabled); - GSList *nm_wimax_device_get_nsps (NMWimaxDevice *self); NMWimaxNsp *nm_wimax_device_get_active_nsp (NMWimaxDevice *self);