Commit dba5944f authored by Giovanni Panozzo's avatar Giovanni Panozzo

Scaler reimplementation

The old scaler popup window has been removed. Now scaling has only one option: on or off. When scaled mode is enabled, the remote desktop is resized to fit in the current viewport, preserving its the aspect ratio.
parent d35067d6
......@@ -221,8 +221,7 @@ static gboolean remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
TRACE_CALL("remmina_rdp_event_update_scale_factor");
GtkAllocation a;
gboolean scale;
gint width, height;
gint hscale, vscale;
gint rdwidth, rdheight;
gint gpwidth, gpheight;
RemminaFile* remminafile;
rfContext* rfi = GET_PLUGIN_DATA(gp);
......@@ -230,26 +229,22 @@ static gboolean remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
gtk_widget_get_allocation(GTK_WIDGET(gp), &a);
width = a.width;
height = a.height;
gpwidth = a.width;
gpheight = a.height;
scale = remmina_plugin_service->protocol_plugin_get_scale(gp);
if (scale)
{
if ((width > 1) && (height > 1))
if ((gpwidth > 1) && (gpheight > 1))
{
gpwidth = remmina_plugin_service->protocol_plugin_get_width(gp);
gpheight = remmina_plugin_service->protocol_plugin_get_height(gp);
hscale = remmina_plugin_service->file_get_int(remminafile, "hscale", 0);
vscale = remmina_plugin_service->file_get_int(remminafile, "vscale", 0);
rfi->scale_width = (hscale > 0 ?
MAX(1, gpwidth * hscale / 100) : width);
rfi->scale_height = (vscale > 0 ?
MAX(1, gpheight * vscale / 100) : height);
rfi->scale_x = (gdouble) rfi->scale_width / (gdouble) gpwidth;
rfi->scale_y = (gdouble) rfi->scale_height / (gdouble) gpheight;
rdwidth = remmina_plugin_service->protocol_plugin_get_width(gp);
rdheight = remmina_plugin_service->protocol_plugin_get_height(gp);
rfi->scale_width = gpwidth;
rfi->scale_height = gpheight;
rfi->scale_x = (gdouble) rfi->scale_width / (gdouble) rdwidth;
rfi->scale_y = (gdouble) rfi->scale_height / (gdouble) rdheight;
}
}
else
......@@ -260,8 +255,10 @@ static gboolean remmina_rdp_event_update_scale_factor(RemminaProtocolWidget* gp)
rfi->scale_y = 0;
}
if ((width > 1) && (height > 1))
gtk_widget_queue_draw_area(GTK_WIDGET(gp), 0, 0, width, height);
/* Now we have scaling vars calculated, resize drawing_area accordingly */
if ((gpwidth > 1) && (gpheight > 1))
gtk_widget_queue_draw_area(GTK_WIDGET(gp), 0, 0, gpwidth, gpheight);
rfi->scale_handler = 0;
......@@ -304,7 +301,7 @@ static gboolean remmina_rdp_event_on_configure(GtkWidget* widget, GdkEventConfig
if (rfi->scale_handler)
g_source_remove(rfi->scale_handler);
rfi->scale_handler = g_timeout_add(1000, (GSourceFunc) remmina_rdp_event_update_scale_factor, gp);
rfi->scale_handler = g_timeout_add(300, (GSourceFunc) remmina_rdp_event_update_scale_factor, gp);
return FALSE;
}
......@@ -438,6 +435,14 @@ static gboolean remmina_rdp_event_on_key(GtkWidget* widget, GdkEventKey* event,
if ( !rfi ) return TRUE;
#ifdef ENABLE_GTK_INSPECTOR_KEY
/* GTK inspector key is propagated up. Disabled by default.
* enable it by defining ENABLE_GTK_INSPECTOR_KEY */
if ( ( event->state & GDK_CONTROL_MASK ) != 0 && ( event->keyval == GDK_KEY_I || event->keyval == GDK_KEY_D ) ) {
return FALSE;
}
#endif
rdp_event.type = REMMINA_RDP_EVENT_TYPE_SCANCODE;
rdp_event.key_event.up = (event->type == GDK_KEY_PRESS ? False : True);
rdp_event.key_event.extended = False;
......@@ -637,7 +642,6 @@ void remmina_rdp_event_update_scale(RemminaProtocolWidget* gp)
{
TRACE_CALL("remmina_rdp_event_update_scale");
gint width, height;
gint hscale, vscale;
RemminaFile* remminafile;
rfContext* rfi = GET_PLUGIN_DATA(gp);
......@@ -645,17 +649,17 @@ void remmina_rdp_event_update_scale(RemminaProtocolWidget* gp)
width = remmina_plugin_service->protocol_plugin_get_width(gp);
height = remmina_plugin_service->protocol_plugin_get_height(gp);
hscale = remmina_plugin_service->file_get_int(remminafile, "hscale", 0);
vscale = remmina_plugin_service->file_get_int(remminafile, "vscale", 0);
remmina_rdp_event_update_scale_factor(gp);
if (rfi->scale)
{
gtk_widget_set_size_request(rfi->drawing_area,
(hscale > 0 ? width * hscale / 100 : -1),
(vscale > 0 ? height * vscale / 100 : -1));
/* In scaled mode, drawing_area will get its dimensions from its parent */
gtk_widget_set_size_request(rfi->drawing_area, -1, -1 );
}
else
{
/* In non scaled mode, the plugins forces dimensions of drawing area */
gtk_widget_set_size_request(rfi->drawing_area, width, height);
}
......
......@@ -318,7 +318,6 @@ static gboolean remmina_plugin_vnc_update_scale_buffer(RemminaProtocolWidget *gp
RemminaFile *remminafile;
gint width, height;
gint gpwidth, gpheight;
gint hscale, vscale;
gboolean scale;
gint x, y, w, h;
GdkPixbuf *pixbuf;
......@@ -344,10 +343,8 @@ static gboolean remmina_plugin_vnc_update_scale_buffer(RemminaProtocolWidget *gp
}
gpwidth = remmina_plugin_service->protocol_plugin_get_width(gp);
gpheight = remmina_plugin_service->protocol_plugin_get_height(gp);
hscale = remmina_plugin_service->file_get_int(remminafile, "hscale", 0);
vscale = remmina_plugin_service->file_get_int(remminafile, "vscale", 0);
gpdata->scale_width = (hscale > 0 ? MAX(1, gpwidth * hscale / 100) : width);
gpdata->scale_height = (vscale > 0 ? MAX(1, gpheight * vscale / 100) : height);
gpdata->scale_width = width;
gpdata->scale_height = height;
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, gpdata->scale_width,
gpdata->scale_height);
......@@ -406,7 +403,6 @@ static void remmina_plugin_vnc_update_scale(RemminaProtocolWidget *gp, gboolean
RemminaPluginVncData *gpdata;
RemminaFile *remminafile;
gint width, height;
gint hscale, vscale;
if ( !remmina_plugin_service->is_main_thread() ) {
struct onMainThread_cb_data *d;
......@@ -426,13 +422,12 @@ static void remmina_plugin_vnc_update_scale(RemminaProtocolWidget *gp, gboolean
height = remmina_plugin_service->protocol_plugin_get_height(gp);
if (scale)
{
hscale = remmina_plugin_service->file_get_int(remminafile, "hscale", 0);
vscale = remmina_plugin_service->file_get_int(remminafile, "vscale", 0);
gtk_widget_set_size_request(GTK_WIDGET(gpdata->drawing_area), (hscale > 0 ? width * hscale / 100 : -1),
(vscale > 0 ? height * vscale / 100 : -1));
/* In scaled mode, drawing_area will get its dimensions from its parent */
gtk_widget_set_size_request(GTK_WIDGET(gpdata->drawing_area), -1, -1 );
}
else
{
/* In non scaled mode, the plugins forces dimensions of drawing area */
gtk_widget_set_size_request (GTK_WIDGET (gpdata->drawing_area), width, height);
}
......@@ -1949,7 +1944,7 @@ static gboolean remmina_plugin_vnc_on_configure(GtkWidget *widget, GdkEventConfi
/* We do a delayed reallocating to improve performance */
if (gpdata->scale_handler)
g_source_remove(gpdata->scale_handler);
gpdata->scale_handler = g_timeout_add(1000, (GSourceFunc) remmina_plugin_vnc_update_scale_buffer_main, gp);
gpdata->scale_handler = g_timeout_add(300, (GSourceFunc) remmina_plugin_vnc_update_scale_buffer_main, gp);
return FALSE;
}
......
......@@ -87,8 +87,6 @@ set(REMMINA_SRCS
src/remmina_protocol_widget.h
src/remmina_public.c
src/remmina_public.h
src/remmina_scaler.c
src/remmina_scaler.h
src/remmina_scrolled_viewport.c
src/remmina_scrolled_viewport.h
src/remmina_sftp_client.c
......
This diff is collapsed.
......@@ -47,7 +47,6 @@
#include "remmina_file.h"
#include "remmina_file_manager.h"
#include "remmina_ssh.h"
#include "remmina_scaler.h"
#include "remmina_widget_pool.h"
#include "remmina_plugin_manager.h"
#include "remmina_icon.h"
......@@ -107,7 +106,6 @@ struct _RemminaFileEditorPriv
GtkWidget* resolution_custom_radio;
GtkWidget* resolution_custom_combo;
GtkWidget* keymap_combo;
GtkWidget* scaler_widget;
GtkWidget* ssh_enabled_check;
GtkWidget* ssh_loopback_check;
......@@ -688,15 +686,6 @@ static void remmina_file_editor_create_settings(RemminaFileEditor* gfe, GtkWidge
#endif
gtk_grid_attach(GTK_GRID(grid), widget, 0, row + 1, 1, row + 2);
widget = remmina_scaler_new();
gtk_widget_show(widget);
gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, row + 2);
remmina_scaler_set(REMMINA_SCALER(widget),
remmina_file_get_int(priv->remmina_file, "hscale", 0),
remmina_file_get_int(priv->remmina_file, "vscale", 0),
remmina_file_get_int(priv->remmina_file, "aspectscale", FALSE));
priv->scaler_widget = widget;
row++;
break;
......@@ -1004,7 +993,6 @@ static void remmina_file_editor_protocol_combo_on_changed(GtkComboBox* combo, Re
priv->resolution_custom_radio = NULL;
priv->resolution_custom_combo = NULL;
priv->keymap_combo = NULL;
priv->scaler_widget = NULL;
priv->ssh_enabled_check = NULL;
priv->ssh_loopback_check = NULL;
......@@ -1162,13 +1150,6 @@ static void remmina_file_editor_update(RemminaFileEditor* gfe)
remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->keymap_combo)));
}
if (priv->scaler_widget)
{
remmina_file_set_int(priv->remmina_file, "hscale", REMMINA_SCALER(priv->scaler_widget)->hscale);
remmina_file_set_int(priv->remmina_file, "vscale", REMMINA_SCALER(priv->scaler_widget)->vscale);
remmina_file_set_int(priv->remmina_file, "aspectscale", REMMINA_SCALER(priv->scaler_widget)->aspectscale);
}
remmina_file_editor_update_ssh(gfe);
remmina_file_editor_update_settings(gfe);
}
......
......@@ -359,3 +359,23 @@ RemminaSecretPlugin* remmina_plugin_manager_get_secret_plugin(void)
return remmina_secret_plugin;
}
gboolean remmina_plugin_manager_query_feature_by_type(RemminaPluginType ptype, const gchar* name, RemminaProtocolFeatureType ftype)
{
const RemminaProtocolFeature *feature;
RemminaProtocolPlugin* plugin;
plugin = (RemminaProtocolPlugin*) remmina_plugin_manager_get_plugin(ptype, name);
if (plugin == NULL)
{
return FALSE;
}
for (feature = plugin->features; feature && feature->type; feature++)
{
if (feature->type == ftype)
return TRUE;
}
return FALSE;
}
......@@ -44,6 +44,7 @@ typedef gboolean (*RemminaPluginFunc)(gchar *name, RemminaPlugin *plugin, gpoint
void remmina_plugin_manager_init(void);
RemminaPlugin* remmina_plugin_manager_get_plugin(RemminaPluginType type, const gchar *name);
gboolean remmina_plugin_manager_query_feature_by_type(RemminaPluginType ptype, const gchar* name, RemminaProtocolFeatureType ftype);
void remmina_plugin_manager_for_each_plugin(RemminaPluginType type, RemminaPluginFunc func, gpointer data);
void remmina_plugin_manager_show(GtkWindow *parent);
RemminaFilePlugin* remmina_plugin_manager_get_import_file_handler(const gchar *file);
......
......@@ -788,13 +788,15 @@ void remmina_protocol_widget_set_scale(RemminaProtocolWidget* gp, gboolean scale
gboolean remmina_protocol_widget_get_expand(RemminaProtocolWidget* gp)
{
TRACE_CALL("remmina_protocol_widget_get_expand");
return gp->priv->expand;
// Deprecated, no longer in use. Kept here to avoid breaking plugin api
return FALSE;
}
void remmina_protocol_widget_set_expand(RemminaProtocolWidget* gp, gboolean expand)
{
TRACE_CALL("remmina_protocol_widget_set_expand");
gp->priv->expand = expand;
// Deprecated, no longer in use. Kept here to avoid breaking plugin api
return;
}
gboolean remmina_protocol_widget_has_error(RemminaProtocolWidget* gp)
......
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009 - Vic Lee
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "config.h"
#include "remmina_chain_button.h"
#include "remmina_scaler.h"
#include "remmina/remmina_trace_calls.h"
G_DEFINE_TYPE( RemminaScaler, remmina_scaler, GTK_TYPE_TABLE)
#define MIN_SCALE_VALUE 0.05
struct _RemminaScalerPriv
{
GtkWidget *hscale_widget;
GtkWidget *vscale_widget;
GtkWidget *aspectscale_button;
};
enum
{
SCALED_SIGNAL, LAST_SIGNAL
};
static guint remmina_scaler_signals[LAST_SIGNAL] =
{ 0 };
static void remmina_scaler_class_init(RemminaScalerClass *klass)
{
TRACE_CALL("remmina_scaler_class_init");
remmina_scaler_signals[SCALED_SIGNAL] = g_signal_new("scaled", G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(RemminaScalerClass, scaled), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
static gchar*
remmina_scaler_format_scale_value(GtkScale *scale, gdouble value, gpointer user_data)
{
TRACE_CALL("remmina_scaler_format_scale_value");
if (value <= MIN_SCALE_VALUE)
{
return g_strdup(_("Fit window size"));
}
else
{
return g_strdup_printf("%.2f", value);
}
}
static void remmina_scaler_on_chain_changed(RemminaChainButton *cb, RemminaScaler *scaler)
{
TRACE_CALL("remmina_scaler_on_chain_changed");
scaler->aspectscale = cb->chained;
if (cb->chained)
{
gtk_range_set_value(GTK_RANGE(scaler->priv->vscale_widget),
gtk_range_get_value(GTK_RANGE(scaler->priv->hscale_widget)));
}
g_signal_emit(G_OBJECT(scaler), remmina_scaler_signals[SCALED_SIGNAL], 0);
}
static void remmina_scaler_on_hscale_value_changed(GtkWidget *widget, RemminaScaler *scaler)
{
TRACE_CALL("remmina_scaler_on_hscale_value_changed");
gdouble value;
value = gtk_range_get_value(GTK_RANGE(scaler->priv->hscale_widget));
scaler->hscale = (value <= MIN_SCALE_VALUE ? 0 : (gint)(value * 100.0));
if (REMMINA_CHAIN_BUTTON(scaler->priv->aspectscale_button)->chained
&& gtk_range_get_value(GTK_RANGE(scaler->priv->hscale_widget))
!= gtk_range_get_value(GTK_RANGE(scaler->priv->vscale_widget)))
{
gtk_range_set_value(GTK_RANGE(scaler->priv->vscale_widget),
gtk_range_get_value(GTK_RANGE(scaler->priv->hscale_widget)));
}
g_signal_emit(G_OBJECT(scaler), remmina_scaler_signals[SCALED_SIGNAL], 0);
}
static void remmina_scaler_on_vscale_value_changed(GtkWidget *widget, RemminaScaler *scaler)
{
TRACE_CALL("remmina_scaler_on_vscale_value_changed");
gdouble value;
value = gtk_range_get_value(GTK_RANGE(scaler->priv->vscale_widget));
scaler->vscale = (value <= MIN_SCALE_VALUE ? 0 : (gint)(value * 100.0));
if (REMMINA_CHAIN_BUTTON(scaler->priv->aspectscale_button)->chained
&& gtk_range_get_value(GTK_RANGE(scaler->priv->hscale_widget))
!= gtk_range_get_value(GTK_RANGE(scaler->priv->vscale_widget)))
{
gtk_range_set_value(GTK_RANGE(scaler->priv->hscale_widget),
gtk_range_get_value(GTK_RANGE(scaler->priv->vscale_widget)));
}
g_signal_emit(G_OBJECT(scaler), remmina_scaler_signals[SCALED_SIGNAL], 0);
}
static void remmina_scaler_destroy(RemminaScaler *scaler, gpointer data)
{
TRACE_CALL("remmina_scaler_destroy");
g_free(scaler->priv);
}
static void remmina_scaler_init(RemminaScaler *scaler)
{
TRACE_CALL("remmina_scaler_init");
RemminaScalerPriv *priv;
GtkWidget *widget = NULL;
priv = g_new(RemminaScalerPriv, 1);
scaler->priv = priv;
scaler->hscale = 0;
scaler->vscale = 0;
scaler->aspectscale = FALSE;
gtk_table_resize(GTK_TABLE(scaler), 2, 2);
#if GTK_VERSION == 3
widget = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, MIN_SCALE_VALUE, 1.0, 0.01);
#elif GTK_VERSION == 2
widget = gtk_hscale_new_with_range(MIN_SCALE_VALUE, 1.0, 0.01);
#endif
gtk_widget_show(widget);
gtk_widget_set_tooltip_text(widget, _("Horizontal scale"));
gtk_table_attach_defaults(GTK_TABLE(scaler), widget, 1, 2, 0, 1);
g_signal_connect(G_OBJECT(widget), "format-value", G_CALLBACK(remmina_scaler_format_scale_value), NULL);
priv->hscale_widget = widget;
#if GTK_VERSION == 3
widget = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, MIN_SCALE_VALUE, 1.0, 0.01);
#elif GTK_VERSION == 2
widget = gtk_hscale_new_with_range(MIN_SCALE_VALUE, 1.0, 0.01);
#endif
gtk_widget_show(widget);
gtk_widget_set_tooltip_text(widget, _("Vertical scale"));
gtk_table_attach_defaults(GTK_TABLE(scaler), widget, 1, 2, 1, 2);
g_signal_connect(G_OBJECT(widget), "format-value", G_CALLBACK(remmina_scaler_format_scale_value), NULL);
priv->vscale_widget = widget;
g_signal_connect(G_OBJECT(priv->hscale_widget), "value-changed", G_CALLBACK(remmina_scaler_on_hscale_value_changed),
scaler);
g_signal_connect(G_OBJECT(priv->vscale_widget), "value-changed", G_CALLBACK(remmina_scaler_on_vscale_value_changed),
scaler);
widget = remmina_chain_button_new();
gtk_widget_show(widget);
gtk_table_attach(GTK_TABLE(scaler), widget, 2, 3, 0, 2, 0, 0, 0, 0);
g_signal_connect(G_OBJECT(widget), "chain-toggled", G_CALLBACK(remmina_scaler_on_chain_changed), scaler);
priv->aspectscale_button = widget;
g_signal_connect(G_OBJECT(scaler), "destroy", G_CALLBACK(remmina_scaler_destroy), NULL);
}
GtkWidget*
remmina_scaler_new(void)
{
TRACE_CALL("remmina_scaler_new");
return GTK_WIDGET(g_object_new(REMMINA_TYPE_SCALER, NULL));
}
void remmina_scaler_set(RemminaScaler *scaler, gint hscale, gint vscale, gboolean chained)
{
TRACE_CALL("remmina_scaler_set");
gtk_range_set_value(GTK_RANGE(scaler->priv->hscale_widget), ((gdouble) hscale) / 100.0);
gtk_range_set_value(GTK_RANGE(scaler->priv->vscale_widget), ((gdouble) vscale) / 100.0);
remmina_chain_button_set(REMMINA_CHAIN_BUTTON(scaler->priv->aspectscale_button), chained);
}
void remmina_scaler_set_draw_value(RemminaScaler *scaler, gboolean draw_value)
{
TRACE_CALL("remmina_scaler_set_draw_value");
gtk_scale_set_draw_value(GTK_SCALE(scaler->priv->hscale_widget), draw_value);
gtk_scale_set_draw_value(GTK_SCALE(scaler->priv->vscale_widget), draw_value);
}
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009 - Vic Lee
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/
#ifndef __REMMINASCALER_H__
#define __REMMINASCALER_H__
G_BEGIN_DECLS
#define REMMINA_TYPE_SCALER (remmina_scaler_get_type ())
#define REMMINA_SCALER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), REMMINA_TYPE_SCALER, RemminaScaler))
#define REMMINA_SCALER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), REMMINA_TYPE_SCALER, RemminaScalerClass))
#define REMMINA_IS_SCALER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), REMMINA_TYPE_SCALER))
#define REMMINA_IS_SCALER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), REMMINA_TYPE_SCALER))
#define REMMINA_SCALER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), REMMINA_TYPE_SCALER, RemminaScalerClass))
typedef struct _RemminaScalerPriv RemminaScalerPriv;
typedef struct _RemminaScaler
{
GtkTable table;
gint hscale;
gint vscale;
gboolean aspectscale;
RemminaScalerPriv *priv;
} RemminaScaler;
typedef struct _RemminaScalerClass
{
GtkTableClass parent_class;
void (*scaled)(RemminaScaler *scaler);
} RemminaScalerClass;
GType remmina_scaler_get_type(void)
G_GNUC_CONST;
GtkWidget* remmina_scaler_new(void);
void remmina_scaler_set(RemminaScaler *scaler, gint hscale, gint vscale, gboolean chained);
void remmina_scaler_set_draw_value(RemminaScaler *scaler, gboolean draw_value);
G_END_DECLS
#endif /* __REMMINASCALER_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment