Commit 35519331 authored by smorlat's avatar smorlat

add new entry and button to trigger buddylookup

Improve buddylookup dialog

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@633 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent c9b82c99
......@@ -40,7 +40,15 @@ void linphone_gtk_buddy_lookup_window_destroyed(GtkWidget *w){
}
}
void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
static void enable_add_buddy_button(GtkWidget *w){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),TRUE);
}
static void disable_add_buddy_button(GtkWidget *w){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),FALSE);
}
GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
......@@ -71,6 +79,7 @@ void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (results));
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)enable_add_buddy_button,w);
#if GTK_CHECK_VERSION(2,12,0)
gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(results),LOOKUP_RESULT_ADDRESS);
#endif
......@@ -81,11 +90,14 @@ void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
gtk_progress_bar_set_text(pb,NULL);
gtk_dialog_add_button(GTK_DIALOG(w),GTK_STOCK_CLOSE,GTK_RESPONSE_CLOSE);
g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(-1));
gtk_widget_show(w);
return w;
}
static void enable_add_buddy_button(GtkWidget *w, gboolean val){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),val);
void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw){
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"keyword")),kw);
}
static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
......@@ -134,7 +146,6 @@ static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
if (results) sip_setup_context_free_results(results);
break;
}
enable_add_buddy_button(w,bls==BuddyLookupDone);
g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(bls));
return TRUE;
}
......@@ -176,6 +187,7 @@ static void linphone_gtk_display_lookup_results(GtkWidget *w, const MSList *resu
const MSList *elem;
store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
gtk_list_store_clear(store);
disable_add_buddy_button(gtk_widget_get_toplevel(w));
for(elem=results;elem!=NULL;elem=elem->next){
BuddyInfo *bi=(BuddyInfo*)elem->data;
gtk_list_store_append(store,&iter);
......@@ -204,11 +216,16 @@ void linphone_gtk_add_buddy_from_database(GtkWidget *button){
gtk_tree_model_get (model, &iter,LOOKUP_RESULT_SIP_URI , &uri,LOOKUP_RESULT_NAME, &name, -1);
addr=g_strdup_printf("%s <%s>",name,uri);
lf=linphone_friend_new_with_addr(addr);
linphone_core_add_friend(linphone_gtk_get_core(),lf);
linphone_gtk_show_friends();
g_free(addr);
g_free(uri);
g_free(name);
linphone_gtk_show_contact(lf);
}
}
/*called when double clicking on a contact */
void linphone_gtk_buddy_lookup_contact_activated(GtkWidget *treeview){
linphone_gtk_add_buddy_from_database(treeview);
gtk_widget_destroy(gtk_widget_get_toplevel(treeview));
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Mon Mar 9 15:48:11 2009 -->
<?xml version="1.0"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy toplevel-contextual -->
<widget class="GtkDialog" id="buddylookup">
<property name="border_width">5</property>
<property name="title" translatable="yes">Search contacts in directory</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="window_position">center-on-parent</property>
<property name="icon">linphone2.png</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<signal name="response" handler="gtk_widget_destroy"/>
<child internal-child="vbox">
......@@ -35,21 +35,23 @@
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property>
<child>
<widget class="GtkTreeView" id="search_results">
<property name="width_request">512</property>
<property name="height_request">140</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="row_activated" handler="linphone_gtk_buddy_lookup_contact_activated"/>
</widget>
</child>
</widget>
......@@ -63,7 +65,6 @@
<property name="visible">True</property>
<property name="activity_mode">True</property>
<property name="show_text">True</property>
<property name="text" translatable="yes"></property>
</widget>
<packing>
<property name="expand">False</property>
......@@ -79,7 +80,6 @@
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="linphone_gtk_add_buddy_from_database"/>
<child>
<widget class="GtkHBox" id="hbox1">
......@@ -92,6 +92,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
......@@ -110,6 +111,7 @@
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">5</property>
<property name="position">0</property>
</packing>
</child>
</widget>
......@@ -139,7 +141,7 @@
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
......@@ -149,7 +151,8 @@
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>
......
......@@ -226,6 +226,58 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist)
gtk_widget_get_toplevel(friendlist),"show_category")),0);
}
void linphone_gtk_show_directory_search(void){
LinphoneProxyConfig *cfg=NULL;
SipSetupContext * ssc=NULL;
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *search_box=linphone_gtk_get_widget(mw,"directory_search_box");
linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
if (cfg){
ssc=linphone_proxy_config_get_sip_setup_context(cfg);
if (ssc!=NULL && sip_setup_context_get_capabilities(ssc) & SIP_SETUP_CAP_BUDDY_LOOKUP){
GtkWidget *entry=linphone_gtk_get_widget(mw,"directory_search_entry");
gchar *tooltip;
GdkColor grey={0,40000,40000,40000};
gtk_widget_show(search_box);
tooltip=g_strdup_printf(_("Search in %s directory"),linphone_proxy_config_get_domain(cfg));
gtk_widget_modify_text(entry,GTK_STATE_NORMAL,&grey);
gtk_entry_set_text(GTK_ENTRY(entry),tooltip);
g_object_set_data(G_OBJECT(entry),"active",GINT_TO_POINTER(0));
g_free(tooltip);
return;
}
}
gtk_widget_hide(search_box);
}
gboolean linphone_gtk_directory_search_focus_out(GtkWidget *entry){
if (gtk_entry_get_text_length(GTK_ENTRY(entry))==0)
linphone_gtk_show_directory_search();
return FALSE;
}
gboolean linphone_gtk_directory_search_focus_in(GtkWidget *entry){
if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry),"active"))==0){
gtk_entry_set_text(GTK_ENTRY(entry),"");
gtk_widget_modify_text(entry,GTK_STATE_NORMAL,NULL);
g_object_set_data(G_OBJECT(entry),"active",GINT_TO_POINTER(1));
}
return FALSE;
}
void linphone_gtk_directory_search_activate(GtkWidget *entry){
LinphoneProxyConfig *cfg;
linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
GtkWidget *w=linphone_gtk_show_buddy_lookup_window(linphone_proxy_config_get_sip_setup_context(cfg));
linphone_gtk_buddy_lookup_set_keyword(w,gtk_entry_get_text(GTK_ENTRY(entry)));
}
void linphone_gtk_directory_search_button_clicked(GtkWidget *button){
linphone_gtk_directory_search_activate(
linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"directory_search_entry"));
}
void linphone_gtk_show_friends(void){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *friendlist=linphone_gtk_get_widget(mw,"contact_list");
......@@ -237,6 +289,8 @@ void linphone_gtk_show_friends(void){
LinphoneCore *core=linphone_gtk_get_core();
const gchar *search=NULL;
gboolean online_only=FALSE,lookup=FALSE;
linphone_gtk_show_directory_search();
if (gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))==NULL){
linphone_gtk_friend_list_init(friendlist);
......
......@@ -69,10 +69,13 @@ void linphone_gtk_check_for_new_version(void);
const char *linphone_gtk_get_lang(const char *config_file);
void linphone_gtk_set_lang(const char *code);
SipSetupContext* linphone_gtk_get_default_sip_setup_context(void);
void linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx);
GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx);
void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw);
void * linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, const char *purpose, float progress);
gchar *linphone_gtk_get_display_name(const char *sip_uri);
void linphone_gtk_show_directory_search(void);
/*functions controlling the in-call view*/
void linphone_gtk_show_in_call_view(void);
void linphone_gtk_show_idle_view(void);
......
......@@ -366,6 +366,7 @@ static void update_video_title(){
}
static gboolean linphone_gtk_iterate(LinphoneCore *lc){
static gboolean first_time=TRUE;
unsigned long id;
static unsigned long previd=0;
static gboolean in_iterate=FALSE;
......@@ -374,6 +375,12 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
if (in_iterate) return TRUE;
in_iterate=TRUE;
linphone_core_iterate(lc);
if (first_time){
/*after the first call to iterate, SipSetupContexts should be ready, so take actions:*/
linphone_gtk_show_directory_search();
first_time=FALSE;
}
id=linphone_core_get_native_video_window_id(lc);
if (id!=previd || video_needs_update){
GdkWindow *w;
......@@ -578,8 +585,10 @@ void linphone_gtk_enable_self_view(GtkWidget *w){
void linphone_gtk_used_identity_changed(GtkWidget *w){
int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
if (sel && strlen(sel)>0) //avoid a dummy "changed" at gui startup
if (sel && strlen(sel)>0){ //avoid a dummy "changed" at gui startup
linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1));
linphone_gtk_show_directory_search();
}
}
static void linphone_gtk_show_main_window(){
......
......@@ -440,6 +440,46 @@ Online users</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="directory_search_box">
<child>
<widget class="GtkEntry" id="directory_search_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="secondary_icon_stock">gtk-find</property>
<property name="secondary_icon_activatable">True</property>
<property name="secondary_icon_sensitive">True</property>
<signal name="focus_in_event" handler="linphone_gtk_directory_search_focus_in"/>
<signal name="activate" handler="linphone_gtk_directory_search_activate"/>
<signal name="icon_press" handler="linphone_gtk_directory_search_activate"/>
<signal name="focus_out_event" handler="linphone_gtk_directory_search_focus_out"/>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="directory_search_button">
<property name="label" translatable="yes">gtk-find</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_directory_search_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
*.lo
.deps
.libs
Makefile
Makefile.in
libmediastreamer.la
libmsspeex.la
mediastream
mstest
ring_test
test_alaw
test_gsm
test_lpc10
test_mulaw
test_rtprecv
test_speex
EXTRA_DIST=Makefile.ms
if BUILD_UGLIB
SUPPORTLIB=$(top_builddir)/support/libuglib.la
endif
#gdk video output
if BUILD_VIDEO
VIDEO_TESTPROGS=test_v4l test_videostream
#videoserver videoclient
endif
if BUILD_TRUESPEECH
TRUESPEECH_SOURCES = mstruespeechencoder.c mstruespeechencoder.h \
mstruespeechdecoder.c mstruespeechdecoder.h
TRUESPEECH_LIBADD = ../win32acm/libwin32acm.a
TRUESPEECH_TEST = test_truespeech
TRUESPEECH_INCLUDES = -I$(top_srcdir)/win32acm
endif
if BUILD_MEDIASTREAMER
noinst_LTLIBRARIES = libmediastreamer.la
endif
useless_files=mstcpserv.c mstcpserv.h mstcpclient.c mstcpclient.h
libmediastreamer_la_SOURCES=msfilter.c msfilter.h msutils.h waveheader.h\
mscodec.c mscodec.h \
mssoundread.c mssoundread.h \
mssoundwrite.c mssoundwrite.h \
msbuffer.c msbuffer.h \
msqueue.c msqueue.h \
msfifo.c msfifo.h \
ms.c ms.h\
mssync.c mssync.h \
msnosync.c msnosync.h \
msread.c msread.h \
mswrite.c mswrite.h \
mscopy.c mscopy.h \
msosswrite.c msosswrite.h \
msossread.c msossread.h \
msringplayer.c msringplayer.h \
msGSMencoder.c msGSMencoder.h \
msGSMdecoder.c msGSMdecoder.h \
msLPC10encoder.c msLPC10encoder.h \
msLPC10decoder.c msLPC10decoder.h \
msrtprecv.c msrtprecv.h \
msrtpsend.c msrtpsend.h \
msAlawenc.c msAlawenc.h g711common.h \
msAlawdec.c msAlawdec.h g711common.h \
msMUlawenc.c msMUlawenc.h g711common.h \
msMUlawdec.c msMUlawdec.h g711common.h \
mstimer.c mstimer.h \
msqdispatcher.c msqdispatcher.h \
msfdispatcher.c msfdispatcher.h \
sndcard.c sndcard.h \
osscard.c osscard.h\
hpuxsndcard.c \
alsacard.c alsacard.h \
jackcard.c jackcard.h \
audiostream.c mediastream.h \
$(TRUESPEECH_SOURCES)\
msspeexenc.c msspeexenc.h msspeexdec.c msspeexdec.h \
$(VIDEO_SOURCES)
if BUILD_VIDEO
libmediastreamer_la_SOURCES+=msv4l.c msv4l.h affine.c affine.h \
msavencoder.c msavencoder.h\
msavdecoder.c msavdecoder.h \
videostream.c \
msvideosource.c msvideosource.h \
mssdlout.c mssdlout.h \
rfc2429.h
endif
libmediastreamer_la_LIBADD= $(GLIB_LIBS) \
../gsmlib/libgsm.la \
../lpc10-1.5/liblpc10.la \
../oRTP/src/libortp.la \
$(JACK_LIBS)\
$(SAMPLERATE_LIBS)\
$(SUPPORTLIB) \
$(ALSA_LIBS) \
$(TRUESPEECH_LIBADD) \
$(SPEEX_LIBS) \
$(VIDEO_LIBS)
if BUILD_MEDIASTREAMER
noinst_PROGRAMS=mstest ring_test test_gsm test_lpc10 test_alaw test_mulaw \
test_speex \
test_rtprecv \
$(VIDEO_TESTPROGS) $(TRUESPEECH_TEST)
libexec_PROGRAMS=mediastream
endif
# test program to test TrueSpeech encoder and decoder objects
test_truespeech_SOURCES=test_truespeech.c
test_truespeech_LDADD=libmediastreamer.la
mstest_SOURCES=test.c
mstest_LDADD=libmediastreamer.la
#test program to test MSRingPlayer object
ring_test_SOURCES=ring_test.c
ring_test_LDADD=libmediastreamer.la
#test program to test GSM dec and enc objects
test_gsm_SOURCES=test_gsm.c
test_gsm_LDADD=libmediastreamer.la
#test program to test speex dec and enc objects
test_speex_SOURCES=test_speex.c
test_speex_LDADD=libmediastreamer.la
#test program to test LPC10-1.5 dec and enc objects
test_lpc10_SOURCES=test_lpc10.c
test_lpc10_LDADD=libmediastreamer.la
#test program to test ALAW dec and enc objects
test_alaw_SOURCES=test_alaw.c
test_alaw_LDADD=libmediastreamer.la
#test program to test MULAW dec and enc objects
test_mulaw_SOURCES=test_mulaw.c
test_mulaw_LDADD=libmediastreamer.la
#test program to test rtprecv object
test_rtprecv_SOURCES=test_rtprecv.c
test_rtprecv_LDADD=libmediastreamer.la
#test program to test full video stream
test_videostream_SOURCES=test_videostream.c
test_videostream_LDADD=libmediastreamer.la
#test program to test video4linux input plugin
test_v4l_SOURCES=test_v4l.c
test_v4l_LDADD=libmediastreamer.la
#videoserver_SOURCES=videoserver.c
#videoserver_LDADD=libmediastreamer.la
#videoclient_SOURCES=videoclient.c
#videoclient_LDADD=libmediastreamer.la
#the mediastream program that runs a processing that will be used in linphone
mediastream_SOURCES=mediastream.c
mediastream_LDADD=libmediastreamer.la
ORTP_CFLAGS=`cat $(top_builddir)/oRTP/ortp.defs`
AM_CFLAGS=$(GLIB_CFLAGS) -DG_LOG_DOMAIN=\"MediaStreamer\" $(TRUESPEECH_CFLAGS) $(IPV6_CFLAGS) $(ORTP_CFLAGS) \
$(VIDEO_CFLAGS)
INCLUDES= -I$(top_srcdir) \
-I$(top_srcdir)/mediastreamer \
-I$(top_srcdir)/oRTP/include \
-I$(top_srcdir)/gsmlib \
-I$(top_srcdir)/lpc10-1.5 \
$(SPEEX_CFLAGS) \
$(TRUESPEECH_INCLUDES)
linphone_includedir=$(includedir)/linphone
linphone_include_HEADERS=sndcard.h
OBJEXT=o
AR = ar
RANLIB = ranlib
DEFS= -DG_LOG_DOMAIN=\"MediaStreamer\"
INCLUDES=-I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include/ \
-I../gsmlib/ -I../lpc10-1.5 -I../oRTP
COMPILE= gcc $(DEFS) $(INCLUDES)
LIBTOOL=libtool
LDFLAGS=-L/usr/local/lib/ -lglib-1.3 -lgthread-1.3 -lpthread
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
libmediastreamer_a_OBJECTS = msfilter.$(OBJEXT) msbuffer.$(OBJEXT) \
msqueue.$(OBJEXT) msfifo.$(OBJEXT) ms.$(OBJEXT) mssync.$(OBJEXT) \
msnosync.$(OBJEXT) msread.$(OBJEXT) mswrite.$(OBJEXT) mscopy.$(OBJEXT) \
msv4lsource.$(OBJEXT) msoss.$(OBJEXT) msosswrite.$(OBJEXT) \
msossread.$(OBJEXT) msringplayer.$(OBJEXT) msGSMencoder.$(OBJEXT) \
msGSMdecoder.$(OBJEXT) msLPC10encoder.$(OBJEXT) \
msLPC10decoder.$(OBJEXT)
all: libmediastreamer.a mstest
.c.o:
$(COMPILE) -c $<
libmediastreamer.a: $(libmediastreamer_a_OBJECTS)
-rm -f libmediastreamer.a
$(AR) cru libmediastreamer.a $(libmediastreamer_a_OBJECTS)
$(RANLIB) libmediastreamer.a
mstest: test.o libmediastreamer.a
gcc -o mstest test.o libmediastreamer.a $(LDFLAGS) -Wl,-rpath /usr/local/lib
Mediastreamer is the library that handle all media operations: rtp streaming
from file, from soundcard, with codec transcoding, and vice-versa;-).
And also video streaming in the future.
/*
* affine.c -- Affine Transforms for 2d objects
* Copyright (C) 2002 Charles Yates <charles.yates@pandora.be>
* Portions Copyright (C) 2003 Dan Dennedy <dan@dennedy.org>
* ported from C++ to C
* wrote affine_scale()
*
* 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.
*/
#include "affine.h"
static inline void Multiply( affine_transform_t *this, affine_transform_t *that )
{
double output[2][2];
register int i, j;
for ( i = 0; i < 2; i ++ )
for ( j = 0; j < 2; j ++ )
output[ i ][ j ] = this->matrix[ i ][ 0 ] * that->matrix[ j ][ 0 ] +
this->matrix[ i ][ 1 ] * that->matrix[ j ][ 1 ];
this->matrix[ 0 ][ 0 ] = output[ 0 ][ 0 ];
this->matrix[ 0 ][ 1 ] = output[ 0 ][ 1 ];
this->matrix[ 1 ][ 0 ] = output[ 1 ][ 0 ];
this->matrix[ 1 ][ 1 ] = output[ 1 ][ 1 ];
}
void affine_transform_init( affine_transform_t *this )
{
this->matrix[ 0 ][ 0 ] = 1;
this->matrix[ 0 ][ 1 ] = 0;
this->matrix[ 1 ][ 0 ] = 0;
this->matrix[ 1 ][ 1 ] = 1;
}
// Rotate by a given angle
void affine_transform_rotate( affine_transform_t *this, double angle )
{
affine_transform_t affine;
affine.matrix[ 0 ][ 0 ] = cos( angle * M_PI / 180 );
affine.matrix[ 0 ][ 1 ] = 0 - sin( angle * M_PI / 180 );
affine.matrix[ 1 ][ 0 ] = sin( angle * M_PI / 180 );
affine.matrix[ 1 ][ 1 ] = cos( angle * M_PI / 180 );
Multiply( this, &affine );
}
// Shear by a given value
void affine_transform_shear( affine_transform_t *this, double shear )
{
affine_transform_t affine;
affine.matrix[ 0 ][ 0 ] = 1;
affine.matrix[ 0 ][ 1 ] = shear;
affine.matrix[ 1 ][ 0 ] = 0;
affine.matrix[ 1 ][ 1 ] = 1;
Multiply( this, &affine );
}
void affine_transform_scale( affine_transform_t *this, double sx, double sy )
{
affine_transform_t affine;
affine.matrix[ 0 ][ 0 ] = sx;
affine.matrix[ 0 ][ 1 ] = 0;
affine.matrix[ 1 ][ 0 ] = 0;