merge of 'b98e72d4089afb8a1879e5fe9627cfb132ee88de' gaim

Sun, 20 May 2007 06:19:49 +0000

author
William Ehlhardt <williamehlhardt@gmail.com>
date
Sun, 20 May 2007 06:19:49 +0000
branch
gaim
changeset 20470
77693555855f
parent 13071
b98e72d4089a (current diff)
parent 20469
b2836a24d81e (diff)
child 20471
1966704b3e42

merge of 'b98e72d4089afb8a1879e5fe9627cfb132ee88de'
and 'b2836a24d81e7a1bd1d21b3aea8794b094391344'

.cvsignore file | annotate | diff | comparison | revisions
ChangeLog.API file | annotate | diff | comparison | revisions
PLUGIN_HOWTO file | annotate | diff | comparison | revisions
README.CVS file | annotate | diff | comparison | revisions
README.SVN file | annotate | diff | comparison | revisions
VERSION file | annotate | diff | comparison | revisions
VERSION.in file | annotate | diff | comparison | revisions
doc/.cvsignore file | annotate | diff | comparison | revisions
doc/CREDITS file | annotate | diff | comparison | revisions
gaim.desktop file | annotate | diff | comparison | revisions
gtk/eggtrayicon.c file | annotate | diff | comparison | revisions
gtk/eggtrayicon.h file | annotate | diff | comparison | revisions
gtk/gaimcombobox.c file | annotate | diff | comparison | revisions
gtk/gaimcombobox.h file | annotate | diff | comparison | revisions
gtk/gaimstock.c file | annotate | diff | comparison | revisions
gtk/gaimstock.h file | annotate | diff | comparison | revisions
gtk/gtkaccount.c file | annotate | diff | comparison | revisions
gtk/gtkaccount.h file | annotate | diff | comparison | revisions
gtk/gtkblist.c file | annotate | diff | comparison | revisions
gtk/gtkblist.h file | annotate | diff | comparison | revisions
gtk/gtkcelllayout.c file | annotate | diff | comparison | revisions
gtk/gtkcelllayout.h file | annotate | diff | comparison | revisions
gtk/gtkcellrendererprogress.c file | annotate | diff | comparison | revisions
gtk/gtkcellrendererprogress.h file | annotate | diff | comparison | revisions
gtk/gtkcellview.c file | annotate | diff | comparison | revisions
gtk/gtkcellview.h file | annotate | diff | comparison | revisions
gtk/gtkcellviewmenuitem.c file | annotate | diff | comparison | revisions
gtk/gtkcellviewmenuitem.h file | annotate | diff | comparison | revisions
gtk/gtkconn.c file | annotate | diff | comparison | revisions
gtk/gtkconn.h file | annotate | diff | comparison | revisions
gtk/gtkconv.c file | annotate | diff | comparison | revisions
gtk/gtkconv.h file | annotate | diff | comparison | revisions
gtk/gtkconvwin.h file | annotate | diff | comparison | revisions
gtk/gtkdebug.c file | annotate | diff | comparison | revisions
gtk/gtkdebug.h file | annotate | diff | comparison | revisions
gtk/gtkdialogs.c file | annotate | diff | comparison | revisions
gtk/gtkdialogs.h file | annotate | diff | comparison | revisions
gtk/gtkdnd-hints.c file | annotate | diff | comparison | revisions
gtk/gtkdnd-hints.h file | annotate | diff | comparison | revisions
gtk/gtkdocklet-x11.c file | annotate | diff | comparison | revisions
gtk/gtkdocklet.h file | annotate | diff | comparison | revisions
gtk/gtkeventloop.c file | annotate | diff | comparison | revisions
gtk/gtkeventloop.h file | annotate | diff | comparison | revisions
gtk/gtkexpander.c file | annotate | diff | comparison | revisions
gtk/gtkexpander.h file | annotate | diff | comparison | revisions
gtk/gtkft.c file | annotate | diff | comparison | revisions
gtk/gtkft.h file | annotate | diff | comparison | revisions
gtk/gtkgaim.h file | annotate | diff | comparison | revisions
gtk/gtkidle.c file | annotate | diff | comparison | revisions
gtk/gtkidle.h file | annotate | diff | comparison | revisions
gtk/gtkimhtml.c file | annotate | diff | comparison | revisions
gtk/gtkimhtml.h file | annotate | diff | comparison | revisions
gtk/gtkimhtmltoolbar.c file | annotate | diff | comparison | revisions
gtk/gtkimhtmltoolbar.h file | annotate | diff | comparison | revisions
gtk/gtklog.c file | annotate | diff | comparison | revisions
gtk/gtklog.h file | annotate | diff | comparison | revisions
gtk/gtkmain.c file | annotate | diff | comparison | revisions
gtk/gtkmenutray.c file | annotate | diff | comparison | revisions
gtk/gtkmenutray.h file | annotate | diff | comparison | revisions
gtk/gtknickcolors.h file | annotate | diff | comparison | revisions
gtk/gtknotify.c file | annotate | diff | comparison | revisions
gtk/gtknotify.h file | annotate | diff | comparison | revisions
gtk/gtkplugin.c file | annotate | diff | comparison | revisions
gtk/gtkplugin.h file | annotate | diff | comparison | revisions
gtk/gtkpluginpref.c file | annotate | diff | comparison | revisions
gtk/gtkpluginpref.h file | annotate | diff | comparison | revisions
gtk/gtkpounce.c file | annotate | diff | comparison | revisions
gtk/gtkpounce.h file | annotate | diff | comparison | revisions
gtk/gtkprefs.c file | annotate | diff | comparison | revisions
gtk/gtkprefs.h file | annotate | diff | comparison | revisions
gtk/gtkprivacy.c file | annotate | diff | comparison | revisions
gtk/gtkprivacy.h file | annotate | diff | comparison | revisions
gtk/gtkrequest.c file | annotate | diff | comparison | revisions
gtk/gtkrequest.h file | annotate | diff | comparison | revisions
gtk/gtkroomlist.c file | annotate | diff | comparison | revisions
gtk/gtkroomlist.h file | annotate | diff | comparison | revisions
gtk/gtksavedstatuses.c file | annotate | diff | comparison | revisions
gtk/gtksavedstatuses.h file | annotate | diff | comparison | revisions
gtk/gtksession.c file | annotate | diff | comparison | revisions
gtk/gtksession.h file | annotate | diff | comparison | revisions
gtk/gtksound.c file | annotate | diff | comparison | revisions
gtk/gtksound.h file | annotate | diff | comparison | revisions
gtk/gtksourceiter.c file | annotate | diff | comparison | revisions
gtk/gtksourceiter.h file | annotate | diff | comparison | revisions
gtk/gtkstatusbox.c file | annotate | diff | comparison | revisions
gtk/gtkstatusbox.h file | annotate | diff | comparison | revisions
gtk/gtkthemes.c file | annotate | diff | comparison | revisions
gtk/gtkthemes.h file | annotate | diff | comparison | revisions
gtk/gtkutils.c file | annotate | diff | comparison | revisions
gtk/gtkutils.h file | annotate | diff | comparison | revisions
gtk/gtkwhiteboard.c file | annotate | diff | comparison | revisions
gtk/gtkwhiteboard.h file | annotate | diff | comparison | revisions
gtk/pixmaps/Makefile.am file | annotate | diff | comparison | revisions
gtk/pixmaps/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/pixmaps/about_menu.png file | annotate | diff | comparison | revisions
gtk/pixmaps/accounts.png file | annotate | diff | comparison | revisions
gtk/pixmaps/away.png file | annotate | diff | comparison | revisions
gtk/pixmaps/change-bgcolor-small.png file | annotate | diff | comparison | revisions
gtk/pixmaps/change-fgcolor-small.png file | annotate | diff | comparison | revisions
gtk/pixmaps/connect.png file | annotate | diff | comparison | revisions
gtk/pixmaps/edit.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim-install.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_4bit_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_auth.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_away.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_away_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_away_4bit_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_blank_4bit_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_cool.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_error.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_info.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_msgpend_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_msgpend_4bit_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_msgunread_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_msgunread_4bit_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_offline.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_offline_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_offline_4bit_16.ico file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_question.png file | annotate | diff | comparison | revisions
gtk/pixmaps/gaim_warning.png file | annotate | diff | comparison | revisions
gtk/pixmaps/info.png file | annotate | diff | comparison | revisions
gtk/pixmaps/insert-image-small.png file | annotate | diff | comparison | revisions
gtk/pixmaps/insert-link-small.png file | annotate | diff | comparison | revisions
gtk/pixmaps/insert-smiley-small.png file | annotate | diff | comparison | revisions
gtk/pixmaps/logo.png file | annotate | diff | comparison | revisions
gtk/pixmaps/msgpend.png file | annotate | diff | comparison | revisions
gtk/pixmaps/msgunread.png file | annotate | diff | comparison | revisions
gtk/pixmaps/offline.png file | annotate | diff | comparison | revisions
gtk/pixmaps/online.png file | annotate | diff | comparison | revisions
gtk/pixmaps/pause.png file | annotate | diff | comparison | revisions
gtk/pixmaps/phone.png file | annotate | diff | comparison | revisions
gtk/pixmaps/send-im.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/Makefile.am file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/THEMES-HOWTO file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/Makefile.am file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/angel.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/bigsmile.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/burp.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/cool.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/crazy.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/crossedlips.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/cry.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/download.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/embarrassed.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/farted.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/kiss.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/luke.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/moneymouth.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/mrt.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_angel.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_angry.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_away.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_bat.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_beer.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_bowl.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_boy.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_brb.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_brheart.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_cake.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_car.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_cat.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_cellphone.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_cigarette.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_clock.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_coffee.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_coins.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_computer.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_cry.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_deadflower.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_devil.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_dog.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_dontknow.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_donttell.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_drink.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_email.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_embarrassed.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_eyeroll.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_film.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_fingerscrossed.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_flower.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_gift.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_girl.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_handcuffs.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_heart.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_highfive.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_hot.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_icon.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_idea.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_island.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_kiss.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_laugh.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_lightning.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_nerd.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_neutral.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_note.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_occ.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_online.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_ooooh.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_party.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_phone.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_photo.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_pizza.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_plane.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_plate.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_question.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_rainbow.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_run.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_runback.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sad.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sarcastic.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_secret.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sheep.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sick.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sleep.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sleepy.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_smiley.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_snail.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_soccer.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_star.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_stormy.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sun.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_sunglasses.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_teeth.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_think.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_thumbdown.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_thumbup.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_tongue.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_turtle.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_umbrella.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_weird.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_wink.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/msn_xbox.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/oneeye.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/sad.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/scream.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/smile.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/theme file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/think.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/tongue.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/wink.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_alien.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_alien2.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_angel.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_angry.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_batting.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_beatup.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_bigsmile.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_blush.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_brokenheart.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_bye.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_chicken.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_clap.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_clown.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_coffee.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_cow.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_cowboy.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_cry.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_dance.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_devil.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_doh.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_drool.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_eyebrow.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_eyeroll.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_femalefighter.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_flag.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_flower.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_frustrated.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_ghost.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_giggle.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_glasses.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_huggs.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_hypnotized.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_idea.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_kiss.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_laughloud.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_liar.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_loser.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_love.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_madtongue.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_malefighter1.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_malefighter2.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_mean.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_moneyeyes.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_monkey.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_nailbiting.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_neutral.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_ooooh.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_party.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_peace.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_pig.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_pray.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_pumpkin.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_question.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_rotfl.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_sad.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_shame.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_shamrock.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_shhhh.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_sick.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_sighing.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_silent.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_silly.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_sleep.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_smiley.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_star.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_sunglas.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_sweating.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_talktohand.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_think.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_tired.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_tongue.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_waiting.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_waving.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_whistling.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_wink.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_worried.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_worship.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_yingyang.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yahoo_youkiddingme.gif file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/default/yell.png file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/none/Makefile.am file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/none/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/pixmaps/smileys/none/theme file | annotate | diff | comparison | revisions
gtk/pixmaps/status-away.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-connect0.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-connect1.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-connect2.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-connect3.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-invisible.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-offline.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-online.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-typing0.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-typing1.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-typing2.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status-typing3.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/Makefile.am file | annotate | diff | comparison | revisions
gtk/pixmaps/status/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/Makefile.am file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/activebuddy.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/admin.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/aim.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/aol.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/away.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/blocked.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/bonjour.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/dnd.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/extended_away.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/external.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/female.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/founder.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/founder.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/freeforchat.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/gadu-gadu.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/game.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/halfop.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/halfop.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/hiptop.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/icq.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/ignored.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/ignored.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/invisible.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/irc.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/jabber.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/login.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/logout.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/male.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/meanwhile.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/msn.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/msn.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/notauthorized.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/novell.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/occupied.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/offline.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/op.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/op.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/pending.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/secure.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/silc.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/simple.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/unavailable.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/voice.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/voice.svg file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/wireless.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/yahoo.png file | annotate | diff | comparison | revisions
gtk/pixmaps/status/default/zephyr.png file | annotate | diff | comparison | revisions
gtk/pixmaps/stock_connect_16.png file | annotate | diff | comparison | revisions
gtk/pixmaps/stock_disconnect_16.png file | annotate | diff | comparison | revisions
gtk/pixmaps/tb_drag_arrow_down.xpm file | annotate | diff | comparison | revisions
gtk/pixmaps/tb_drag_arrow_left.xpm file | annotate | diff | comparison | revisions
gtk/pixmaps/tb_drag_arrow_right.xpm file | annotate | diff | comparison | revisions
gtk/pixmaps/tb_drag_arrow_up.xpm file | annotate | diff | comparison | revisions
gtk/pixmaps/text_bigger.png file | annotate | diff | comparison | revisions
gtk/pixmaps/text_normal.png file | annotate | diff | comparison | revisions
gtk/pixmaps/text_smaller.png file | annotate | diff | comparison | revisions
gtk/pixmaps/typed.png file | annotate | diff | comparison | revisions
gtk/pixmaps/typing.png file | annotate | diff | comparison | revisions
gtk/plugins/contact_priority.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/Makefile.am file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/QTUtilities.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/QTUtilities.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/Utilities.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/Utilities.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/camdata.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/camdata.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/camproc.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/camproc.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_features.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_gaim_plugin.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_gtk_gl.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_gtk_gl.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_interface.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_network.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_network.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/cc_output.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/configure.ac file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/crazychat.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/crazychat.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/dog_lids.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/dog_lids.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/doggy.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/doggy.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/draw.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/eye.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/eye.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/eyes.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/eyes.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/face.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/face.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/filter.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/filter.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/glm.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/glm.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/lids.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/lids.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/main.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/mat_struct.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/models.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/models.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/sharky.c file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/sharky.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/test.h file | annotate | diff | comparison | revisions
gtk/plugins/crazychat/util.h file | annotate | diff | comparison | revisions
gtk/plugins/extplacement.c file | annotate | diff | comparison | revisions
gtk/plugins/gaiminc.c file | annotate | diff | comparison | revisions
gtk/plugins/gaimrc.c file | annotate | diff | comparison | revisions
gtk/plugins/gestures/Makefile.am file | annotate | diff | comparison | revisions
gtk/plugins/gestures/gestures.c file | annotate | diff | comparison | revisions
gtk/plugins/gestures/gstroke-internal.h file | annotate | diff | comparison | revisions
gtk/plugins/gestures/gstroke.h file | annotate | diff | comparison | revisions
gtk/plugins/gestures/stroke-draw.c file | annotate | diff | comparison | revisions
gtk/plugins/gestures/stroke.c file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/Makefile.am file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/add_buddy_dialog.c file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/assoc-buddy.c file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/eds-utils.c file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/gevo-util.c file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/gevolution.c file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/gevolution.h file | annotate | diff | comparison | revisions
gtk/plugins/gevolution/new_person_dialog.c file | annotate | diff | comparison | revisions
gtk/plugins/gtk-signals-test.c file | annotate | diff | comparison | revisions
gtk/plugins/history.c file | annotate | diff | comparison | revisions
gtk/plugins/iconaway.c file | annotate | diff | comparison | revisions
gtk/plugins/mailchk.c file | annotate | diff | comparison | revisions
gtk/plugins/musicmessaging/Makefile.am file | annotate | diff | comparison | revisions
gtk/plugins/musicmessaging/music.png file | annotate | diff | comparison | revisions
gtk/plugins/musicmessaging/musicmessaging.c file | annotate | diff | comparison | revisions
gtk/plugins/notify.c file | annotate | diff | comparison | revisions
gtk/plugins/raw.c file | annotate | diff | comparison | revisions
gtk/plugins/relnot.c file | annotate | diff | comparison | revisions
gtk/plugins/spellchk.c file | annotate | diff | comparison | revisions
gtk/plugins/ticker/Makefile.am file | annotate | diff | comparison | revisions
gtk/plugins/ticker/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/plugins/ticker/gtkticker.c file | annotate | diff | comparison | revisions
gtk/plugins/ticker/gtkticker.h file | annotate | diff | comparison | revisions
gtk/plugins/ticker/ticker.c file | annotate | diff | comparison | revisions
gtk/plugins/timestamp.c file | annotate | diff | comparison | revisions
gtk/plugins/timestamp_format.c file | annotate | diff | comparison | revisions
gtk/sounds/Makefile.am file | annotate | diff | comparison | revisions
gtk/sounds/alert.wav file | annotate | diff | comparison | revisions
gtk/sounds/login.wav file | annotate | diff | comparison | revisions
gtk/sounds/logout.wav file | annotate | diff | comparison | revisions
gtk/sounds/receive.wav file | annotate | diff | comparison | revisions
gtk/sounds/send.wav file | annotate | diff | comparison | revisions
gtk/win32/IdleTracker/Makefile.mingw file | annotate | diff | comparison | revisions
gtk/win32/IdleTracker/idletrack.c file | annotate | diff | comparison | revisions
gtk/win32/IdleTracker/idletrack.h file | annotate | diff | comparison | revisions
gtk/win32/gaimrc.rc.in file | annotate | diff | comparison | revisions
gtk/win32/gtkdocklet-win32.c file | annotate | diff | comparison | revisions
gtk/win32/nsis/gaim-header.bmp file | annotate | diff | comparison | revisions
gtk/win32/nsis/gaim-intro.bmp file | annotate | diff | comparison | revisions
gtk/win32/nsis/gaim-plugin.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/langmacros.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/albanian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/bulgarian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/catalan.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/czech.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/danish.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/dutch.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/english.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/finnish.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/french.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/galician.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/german.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/hebrew.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/hungarian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/italian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/japanese.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/korean.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/norwegian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/polish.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/portuguese-br.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/portuguese.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/romanian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/russian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/serbian-latin.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/simp-chinese.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/slovak.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/slovenian.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/spanish.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/swedish.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/trad-chinese.nsh file | annotate | diff | comparison | revisions
gtk/win32/nsis/translations/vietnamese.nsh file | annotate | diff | comparison | revisions
gtk/win32/resource.h file | annotate | diff | comparison | revisions
gtk/win32/untar.c file | annotate | diff | comparison | revisions
gtk/win32/untar.h file | annotate | diff | comparison | revisions
gtk/win32/wspell.c file | annotate | diff | comparison | revisions
gtk/win32/wspell.h file | annotate | diff | comparison | revisions
intl/.cvsignore file | annotate | diff | comparison | revisions
libgaim/account.c file | annotate | diff | comparison | revisions
libgaim/account.h file | annotate | diff | comparison | revisions
libgaim/accountopt.c file | annotate | diff | comparison | revisions
libgaim/accountopt.h file | annotate | diff | comparison | revisions
libgaim/blist.c file | annotate | diff | comparison | revisions
libgaim/blist.h file | annotate | diff | comparison | revisions
libgaim/buddyicon.c file | annotate | diff | comparison | revisions
libgaim/buddyicon.h file | annotate | diff | comparison | revisions
libgaim/cipher.c file | annotate | diff | comparison | revisions
libgaim/cipher.h file | annotate | diff | comparison | revisions
libgaim/cmds.c file | annotate | diff | comparison | revisions
libgaim/cmds.h file | annotate | diff | comparison | revisions
libgaim/connection.c file | annotate | diff | comparison | revisions
libgaim/connection.h file | annotate | diff | comparison | revisions
libgaim/conversation.c file | annotate | diff | comparison | revisions
libgaim/conversation.h file | annotate | diff | comparison | revisions
libgaim/core.c file | annotate | diff | comparison | revisions
libgaim/core.h file | annotate | diff | comparison | revisions
libgaim/dbus-analyze-functions.py file | annotate | diff | comparison | revisions
libgaim/dbus-analyze-types.py file | annotate | diff | comparison | revisions
libgaim/dbus-bindings.h file | annotate | diff | comparison | revisions
libgaim/dbus-define-api.h file | annotate | diff | comparison | revisions
libgaim/dbus-gaim.h file | annotate | diff | comparison | revisions
libgaim/dbus-gaim.service file | annotate | diff | comparison | revisions
libgaim/dbus-maybe.h file | annotate | diff | comparison | revisions
libgaim/dbus-server.c file | annotate | diff | comparison | revisions
libgaim/dbus-server.h file | annotate | diff | comparison | revisions
libgaim/dbus-useful.c file | annotate | diff | comparison | revisions
libgaim/dbus-useful.h file | annotate | diff | comparison | revisions
libgaim/debug.c file | annotate | diff | comparison | revisions
libgaim/debug.h file | annotate | diff | comparison | revisions
libgaim/desktopitem.c file | annotate | diff | comparison | revisions
libgaim/desktopitem.h file | annotate | diff | comparison | revisions
libgaim/dnssrv.c file | annotate | diff | comparison | revisions
libgaim/dnssrv.h file | annotate | diff | comparison | revisions
libgaim/eventloop.c file | annotate | diff | comparison | revisions
libgaim/eventloop.h file | annotate | diff | comparison | revisions
libgaim/ft.c file | annotate | diff | comparison | revisions
libgaim/ft.h file | annotate | diff | comparison | revisions
libgaim/gaim-client-example.c file | annotate | diff | comparison | revisions
libgaim/gaim-client.c file | annotate | diff | comparison | revisions
libgaim/gaim-client.h file | annotate | diff | comparison | revisions
libgaim/gaim-notifications-example file | annotate | diff | comparison | revisions
libgaim/gaim-remote file | annotate | diff | comparison | revisions
libgaim/gaim-send file | annotate | diff | comparison | revisions
libgaim/gaim-send-async file | annotate | diff | comparison | revisions
libgaim/gaim.h file | annotate | diff | comparison | revisions
libgaim/idle.c file | annotate | diff | comparison | revisions
libgaim/idle.h file | annotate | diff | comparison | revisions
libgaim/imgstore.c file | annotate | diff | comparison | revisions
libgaim/imgstore.h file | annotate | diff | comparison | revisions
libgaim/internal.h file | annotate | diff | comparison | revisions
libgaim/log.c file | annotate | diff | comparison | revisions
libgaim/log.h file | annotate | diff | comparison | revisions
libgaim/mime.c file | annotate | diff | comparison | revisions
libgaim/mime.h file | annotate | diff | comparison | revisions
libgaim/network.c file | annotate | diff | comparison | revisions
libgaim/network.h file | annotate | diff | comparison | revisions
libgaim/notify.c file | annotate | diff | comparison | revisions
libgaim/notify.h file | annotate | diff | comparison | revisions
libgaim/ntlm.c file | annotate | diff | comparison | revisions
libgaim/ntlm.h file | annotate | diff | comparison | revisions
libgaim/plugin.c file | annotate | diff | comparison | revisions
libgaim/plugin.h file | annotate | diff | comparison | revisions
libgaim/pluginpref.c file | annotate | diff | comparison | revisions
libgaim/pluginpref.h file | annotate | diff | comparison | revisions
libgaim/plugins/ciphertest.c file | annotate | diff | comparison | revisions
libgaim/plugins/codeinline.c file | annotate | diff | comparison | revisions
libgaim/plugins/dbus-example.c file | annotate | diff | comparison | revisions
libgaim/plugins/filectl.c file | annotate | diff | comparison | revisions
libgaim/plugins/fortuneprofile.pl file | annotate | diff | comparison | revisions
libgaim/plugins/gaim.pl file | annotate | diff | comparison | revisions
libgaim/plugins/idle.c file | annotate | diff | comparison | revisions
libgaim/plugins/ipc-test-client.c file | annotate | diff | comparison | revisions
libgaim/plugins/ipc-test-server.c file | annotate | diff | comparison | revisions
libgaim/plugins/log_reader.c file | annotate | diff | comparison | revisions
libgaim/plugins/mono/BooPlugin.boo file | annotate | diff | comparison | revisions
libgaim/plugins/mono/GetBuddyBack.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/MPlugin.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/Makefile.am file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/Buddy.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/BuddyList.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/Debug.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/Event.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/GaimPlugin.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/Makefile.am file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/Signal.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/api/Status.cs file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/Makefile.am file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/blist-glue.c file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/debug-glue.c file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/mono-glue.h file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/mono-helper.c file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/mono-helper.h file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/mono.c file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/signal-glue.c file | annotate | diff | comparison | revisions
libgaim/plugins/mono/loader/status-glue.c file | annotate | diff | comparison | revisions
libgaim/plugins/perl/Makefile.am file | annotate | diff | comparison | revisions
libgaim/plugins/perl/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Account.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/AccountOpts.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/BuddyIcon.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/BuddyList.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Cipher.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Cmds.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Connection.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Conversation.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/FT.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Gaim.pm file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Gaim.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/ImgStore.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Log.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/MANIFEST file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Makefile.PL.in file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Network.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Notify.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Plugin.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/PluginPref.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Pounce.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Prefs.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Privacy.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Proxy.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Prpl.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Request.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Roomlist.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/SSLConn.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/SavedStatuses.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Server.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Sound.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Status.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Stringref.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/Util.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/XMLNode.xs file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/fallback/const-c.inc file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/fallback/const-xs.inc file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/module.h file | annotate | diff | comparison | revisions
libgaim/plugins/perl/common/typemap file | annotate | diff | comparison | revisions
libgaim/plugins/perl/libgaimperl.c file | annotate | diff | comparison | revisions
libgaim/plugins/perl/perl-common.c file | annotate | diff | comparison | revisions
libgaim/plugins/perl/perl-common.h file | annotate | diff | comparison | revisions
libgaim/plugins/perl/perl-handlers.c file | annotate | diff | comparison | revisions
libgaim/plugins/perl/perl-handlers.h file | annotate | diff | comparison | revisions
libgaim/plugins/perl/perl.c file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/account.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/buddy_list.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/conversation.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/count_down.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/gtk_frame_test.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/plugin_action.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/plugin_pref.pl file | annotate | diff | comparison | revisions
libgaim/plugins/perl/scripts/request.pl file | annotate | diff | comparison | revisions
libgaim/plugins/pluginpref_example.c file | annotate | diff | comparison | revisions
libgaim/plugins/psychic.c file | annotate | diff | comparison | revisions
libgaim/plugins/signals-test.c file | annotate | diff | comparison | revisions
libgaim/plugins/simple.c file | annotate | diff | comparison | revisions
libgaim/plugins/ssl/Makefile.am file | annotate | diff | comparison | revisions
libgaim/plugins/ssl/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/plugins/ssl/ssl-gnutls.c file | annotate | diff | comparison | revisions
libgaim/plugins/ssl/ssl-nss.c file | annotate | diff | comparison | revisions
libgaim/plugins/ssl/ssl.c file | annotate | diff | comparison | revisions
libgaim/plugins/statenotify.c file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/Makefile.am file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/signal-test.tcl file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/tcl.c file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/tcl_cmds.c file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/tcl_gaim.h file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/tcl_glib.c file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/tcl_glib.h file | annotate | diff | comparison | revisions
libgaim/plugins/tcl/tcl_signals.c file | annotate | diff | comparison | revisions
libgaim/plugins/test.pl file | annotate | diff | comparison | revisions
libgaim/pounce.c file | annotate | diff | comparison | revisions
libgaim/pounce.h file | annotate | diff | comparison | revisions
libgaim/prefix.c file | annotate | diff | comparison | revisions
libgaim/prefix.h file | annotate | diff | comparison | revisions
libgaim/prefs.c file | annotate | diff | comparison | revisions
libgaim/prefs.h file | annotate | diff | comparison | revisions
libgaim/privacy.c file | annotate | diff | comparison | revisions
libgaim/privacy.h file | annotate | diff | comparison | revisions
libgaim/protocols/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/bonjour.c file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/bonjour.h file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/buddy.c file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/buddy.h file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/dns_sd.c file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/dns_sd.h file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/issues.txt file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/jabber.c file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/jabber.h file | annotate | diff | comparison | revisions
libgaim/protocols/bonjour/messages.txt file | annotate | diff | comparison | revisions
libgaim/protocols/gg/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/gg/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/gg/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/gg/buddylist.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/buddylist.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/confer.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/confer.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/gg-utils.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/gg-utils.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/gg.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/gg.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/COPYING file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/common.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/compat.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/dcc.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/events.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/http.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/libgadu-config.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/libgadu.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/libgadu.h file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/obsolete.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/pubdir.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/lib/pubdir50.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/search.c file | annotate | diff | comparison | revisions
libgaim/protocols/gg/search.h file | annotate | diff | comparison | revisions
libgaim/protocols/irc/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/irc/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/irc/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/irc/PROTOCOL file | annotate | diff | comparison | revisions
libgaim/protocols/irc/cmds.c file | annotate | diff | comparison | revisions
libgaim/protocols/irc/dcc_send.c file | annotate | diff | comparison | revisions
libgaim/protocols/irc/irc.c file | annotate | diff | comparison | revisions
libgaim/protocols/irc/irc.h file | annotate | diff | comparison | revisions
libgaim/protocols/irc/msgs.c file | annotate | diff | comparison | revisions
libgaim/protocols/irc/parse.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/JEPS file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/auth.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/auth.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/buddy.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/buddy.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/chat.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/chat.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/disco.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/disco.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/iq.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/iq.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/jabber.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/jabber.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/jutil.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/jutil.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/message.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/message.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/oob.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/oob.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/parser.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/parser.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/presence.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/presence.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/roster.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/roster.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/si.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/si.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/win32/posix.uname.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/win32/utsname.h file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/xdata.c file | annotate | diff | comparison | revisions
libgaim/protocols/jabber/xdata.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/msn/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/msn/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/msn/cmdproc.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/cmdproc.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/command.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/command.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/dialog.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/dialog.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/directconn.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/directconn.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/error.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/error.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/group.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/group.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/history.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/history.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/httpconn.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/httpconn.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/msg.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/msg.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/msn-utils.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/msn-utils.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/msn.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/msn.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/nexus.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/nexus.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/notification.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/notification.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/object.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/object.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/page.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/page.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/servconn.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/servconn.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/session.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/session.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slp.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slp.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slpcall.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slpcall.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slplink.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slplink.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slpmsg.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slpmsg.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slpsession.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/slpsession.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/state.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/state.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/switchboard.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/switchboard.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/sync.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/sync.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/table.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/table.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/transaction.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/transaction.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/user.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/user.h file | annotate | diff | comparison | revisions
libgaim/protocols/msn/userlist.c file | annotate | diff | comparison | revisions
libgaim/protocols/msn/userlist.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/novell/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmconference.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmconference.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmconn.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmconn.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmcontact.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmcontact.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmevent.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmevent.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmfield.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmfield.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmmessage.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmmessage.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmrequest.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmrequest.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmrtf.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmrtf.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmuser.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmuser.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmuserrecord.c file | annotate | diff | comparison | revisions
libgaim/protocols/novell/nmuserrecord.h file | annotate | diff | comparison | revisions
libgaim/protocols/novell/novell.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/AUTHORS file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/COPYING file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/bstream.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/misc.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/msgcookie.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/oscar.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/rxhandlers.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/snac.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/tlv.c file | annotate | diff | comparison | revisions
libgaim/protocols/oscar/util.c file | annotate | diff | comparison | revisions
libgaim/protocols/sametime/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/sametime/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/sametime/sametime.c file | annotate | diff | comparison | revisions
libgaim/protocols/sametime/sametime.h file | annotate | diff | comparison | revisions
libgaim/protocols/silc/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/silc/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/silc/README file | annotate | diff | comparison | revisions
libgaim/protocols/silc/TODO file | annotate | diff | comparison | revisions
libgaim/protocols/silc/buddy.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/chat.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/ft.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/ops.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/pk.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/silc.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/silcgaim.h file | annotate | diff | comparison | revisions
libgaim/protocols/silc/util.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/wb.c file | annotate | diff | comparison | revisions
libgaim/protocols/silc/wb.h file | annotate | diff | comparison | revisions
libgaim/protocols/simple/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/simple/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/simple/simple.c file | annotate | diff | comparison | revisions
libgaim/protocols/simple/simple.h file | annotate | diff | comparison | revisions
libgaim/protocols/simple/sipmsg.c file | annotate | diff | comparison | revisions
libgaim/protocols/simple/sipmsg.h file | annotate | diff | comparison | revisions
libgaim/protocols/toc/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/toc/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/toc/PROTOCOL file | annotate | diff | comparison | revisions
libgaim/protocols/toc/toc.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/util.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_auth.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_auth.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_crypt.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_crypt.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_doodle.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_doodle.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_filexfer.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_filexfer.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_friend.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_friend.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_packet.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_packet.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_picture.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_picture.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoo_profile.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoochat.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/yahoochat.h file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/ycht.c file | annotate | diff | comparison | revisions
libgaim/protocols/yahoo/ycht.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/.todo file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/Makefile.am file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/Makefile.mingw file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZAsyncLocate.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZCkAuth.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZCkIfNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZClosePort.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZCmpUID.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZCmpUIDP.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFlsLocs.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFlsSubs.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtAuth.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtList.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtNotice.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtRaw.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtRawLst.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtSmRLst.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFmtSmRaw.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZFreeNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZGetLocs.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZGetSender.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZGetSubs.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZGetWGPort.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZIfNotice.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZInit.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZLocations.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZMakeAscii.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZMkAuth.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZNewLocU.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZOpenPort.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZParseNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZPeekIfNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZPeekNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZPeekPkt.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZPending.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZReadAscii.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZRecvNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZRecvPkt.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZRetSubs.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSendList.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSendNot.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSendPkt.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSendRLst.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSendRaw.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSetDest.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSetFD.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSetSrv.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZSubs.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZVariables.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZWait4Not.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/ZhmStat.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/Zinternal.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/com_err.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/error_message.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/error_table.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/et_name.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/init_et.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/internal.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/mit-copyright.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/mit-sipb-copyright.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/sysdep.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/zephyr.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/zephyr.h file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/zephyr_err.c file | annotate | diff | comparison | revisions
libgaim/protocols/zephyr/zephyr_err.h file | annotate | diff | comparison | revisions
libgaim/proxy.c file | annotate | diff | comparison | revisions
libgaim/proxy.h file | annotate | diff | comparison | revisions
libgaim/prpl.c file | annotate | diff | comparison | revisions
libgaim/prpl.h file | annotate | diff | comparison | revisions
libgaim/request.c file | annotate | diff | comparison | revisions
libgaim/request.h file | annotate | diff | comparison | revisions
libgaim/roomlist.c file | annotate | diff | comparison | revisions
libgaim/roomlist.h file | annotate | diff | comparison | revisions
libgaim/savedstatuses.c file | annotate | diff | comparison | revisions
libgaim/savedstatuses.h file | annotate | diff | comparison | revisions
libgaim/server.c file | annotate | diff | comparison | revisions
libgaim/server.h file | annotate | diff | comparison | revisions
libgaim/signals.c file | annotate | diff | comparison | revisions
libgaim/signals.h file | annotate | diff | comparison | revisions
libgaim/sound.c file | annotate | diff | comparison | revisions
libgaim/sound.h file | annotate | diff | comparison | revisions
libgaim/sslconn.c file | annotate | diff | comparison | revisions
libgaim/sslconn.h file | annotate | diff | comparison | revisions
libgaim/status.c file | annotate | diff | comparison | revisions
libgaim/status.h file | annotate | diff | comparison | revisions
libgaim/stringref.c file | annotate | diff | comparison | revisions
libgaim/stringref.h file | annotate | diff | comparison | revisions
libgaim/stun.c file | annotate | diff | comparison | revisions
libgaim/stun.h file | annotate | diff | comparison | revisions
libgaim/upnp.c file | annotate | diff | comparison | revisions
libgaim/upnp.h file | annotate | diff | comparison | revisions
libgaim/util.c file | annotate | diff | comparison | revisions
libgaim/util.h file | annotate | diff | comparison | revisions
libgaim/value.c file | annotate | diff | comparison | revisions
libgaim/value.h file | annotate | diff | comparison | revisions
libgaim/version.h file | annotate | diff | comparison | revisions
libgaim/whiteboard.c file | annotate | diff | comparison | revisions
libgaim/whiteboard.h file | annotate | diff | comparison | revisions
libgaim/win32/global.mak file | annotate | diff | comparison | revisions
libgaim/win32/libc_interface.c file | annotate | diff | comparison | revisions
libgaim/win32/libc_interface.h file | annotate | diff | comparison | revisions
libgaim/win32/libc_internal.h file | annotate | diff | comparison | revisions
libgaim/win32/wgaimerror.h file | annotate | diff | comparison | revisions
libgaim/win32/win32dep.c file | annotate | diff | comparison | revisions
libgaim/win32/win32dep.h file | annotate | diff | comparison | revisions
libgaim/xmlnode.c file | annotate | diff | comparison | revisions
libgaim/xmlnode.h file | annotate | diff | comparison | revisions
m4/.cvsignore file | annotate | diff | comparison | revisions
m4/Makefile.am file | annotate | diff | comparison | revisions
m4/ac_var_timezone_externals.m4 file | annotate | diff | comparison | revisions
m4/artsc.m4 file | annotate | diff | comparison | revisions
m4/esd.m4 file | annotate | diff | comparison | revisions
m4/exosip.m4 file | annotate | diff | comparison | revisions
m4/gnome-gnorba-check.m4 file | annotate | diff | comparison | revisions
m4/gnome-orbit-check.m4 file | annotate | diff | comparison | revisions
m4/gnome-pthread-check.m4 file | annotate | diff | comparison | revisions
m4/gnome-x-checks.m4 file | annotate | diff | comparison | revisions
m4/gnome.m4 file | annotate | diff | comparison | revisions
m4/osip.m4 file | annotate | diff | comparison | revisions
m4/speex.m4 file | annotate | diff | comparison | revisions
m4macros/.cvsignore file | annotate | diff | comparison | revisions
mkinstalldirs file | annotate | diff | comparison | revisions
pixmaps/.cvsignore file | annotate | diff | comparison | revisions
pixmaps/Makefile.am file | annotate | diff | comparison | revisions
pixmaps/Makefile.mingw file | annotate | diff | comparison | revisions
pixmaps/about_menu.png file | annotate | diff | comparison | revisions
pixmaps/accounts.png file | annotate | diff | comparison | revisions
pixmaps/away.png file | annotate | diff | comparison | revisions
pixmaps/change-bgcolor-small.png file | annotate | diff | comparison | revisions
pixmaps/change-fgcolor-small.png file | annotate | diff | comparison | revisions
pixmaps/connect.png file | annotate | diff | comparison | revisions
pixmaps/edit.png file | annotate | diff | comparison | revisions
pixmaps/gaim-install.ico file | annotate | diff | comparison | revisions
pixmaps/gaim.ico file | annotate | diff | comparison | revisions
pixmaps/gaim.png file | annotate | diff | comparison | revisions
pixmaps/gaim.svg file | annotate | diff | comparison | revisions
pixmaps/gaim_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_4bit_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_auth.png file | annotate | diff | comparison | revisions
pixmaps/gaim_away.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_away_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_away_4bit_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_blank_4bit_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_cool.png file | annotate | diff | comparison | revisions
pixmaps/gaim_error.png file | annotate | diff | comparison | revisions
pixmaps/gaim_info.png file | annotate | diff | comparison | revisions
pixmaps/gaim_msgpend_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_msgpend_4bit_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_msgunread_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_msgunread_4bit_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_offline.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_offline_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_offline_4bit_16.ico file | annotate | diff | comparison | revisions
pixmaps/gaim_question.png file | annotate | diff | comparison | revisions
pixmaps/gaim_warning.png file | annotate | diff | comparison | revisions
pixmaps/info.png file | annotate | diff | comparison | revisions
pixmaps/insert-image-small.png file | annotate | diff | comparison | revisions
pixmaps/insert-link-small.png file | annotate | diff | comparison | revisions
pixmaps/insert-smiley-small.png file | annotate | diff | comparison | revisions
pixmaps/logo.png file | annotate | diff | comparison | revisions
pixmaps/msgpend.png file | annotate | diff | comparison | revisions
pixmaps/msgunread.png file | annotate | diff | comparison | revisions
pixmaps/offline.png file | annotate | diff | comparison | revisions
pixmaps/online.png file | annotate | diff | comparison | revisions
pixmaps/pause.png file | annotate | diff | comparison | revisions
pixmaps/phone.png file | annotate | diff | comparison | revisions
pixmaps/send-im.png file | annotate | diff | comparison | revisions
pixmaps/smileys/.cvsignore file | annotate | diff | comparison | revisions
pixmaps/smileys/Makefile.am file | annotate | diff | comparison | revisions
pixmaps/smileys/Makefile.mingw file | annotate | diff | comparison | revisions
pixmaps/smileys/THEMES-HOWTO file | annotate | diff | comparison | revisions
pixmaps/smileys/default/.cvsignore file | annotate | diff | comparison | revisions
pixmaps/smileys/default/Makefile.am file | annotate | diff | comparison | revisions
pixmaps/smileys/default/Makefile.mingw file | annotate | diff | comparison | revisions
pixmaps/smileys/default/angel.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/bigsmile.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/burp.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/cool.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/crazy.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/crossedlips.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/cry.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/download.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/embarrassed.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/farted.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/kiss.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/luke.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/moneymouth.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/mrt.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_angel.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_angry.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_away.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_bat.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_beer.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_bowl.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_boy.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_brb.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_brheart.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_cake.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_car.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_cat.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_cellphone.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_cigarette.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_clock.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_coffee.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_coins.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_computer.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_cry.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_deadflower.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_devil.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_dog.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_dontknow.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_donttell.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_drink.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_email.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_embarrassed.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_eyeroll.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_film.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_fingerscrossed.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_flower.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_gift.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_girl.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_handcuffs.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_heart.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_highfive.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_hot.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_icon.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_idea.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_island.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_kiss.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_laugh.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_lightning.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_nerd.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_neutral.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_note.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_occ.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_online.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_ooooh.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_party.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_phone.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_photo.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_pizza.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_plane.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_plate.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_question.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_rainbow.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_run.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_runback.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sad.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sarcastic.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_secret.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sheep.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sick.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sleep.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sleepy.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_smiley.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_snail.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_soccer.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_star.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_stormy.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sun.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_sunglasses.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_teeth.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_think.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_thumbdown.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_thumbup.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_tongue.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_turtle.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_umbrella.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_weird.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_wink.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/msn_xbox.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/oneeye.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/sad.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/scream.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/smile.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/theme file | annotate | diff | comparison | revisions
pixmaps/smileys/default/think.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/tongue.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/wink.png file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_alien.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_alien2.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_angel.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_angry.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_batting.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_beatup.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_bigsmile.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_blush.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_brokenheart.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_bye.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_chicken.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_clap.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_clown.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_coffee.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_cow.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_cowboy.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_cry.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_dance.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_devil.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_doh.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_drool.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_eyebrow.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_eyeroll.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_femalefighter.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_flag.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_flower.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_frustrated.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_ghost.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_giggle.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_glasses.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_huggs.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_hypnotized.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_idea.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_kiss.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_laughloud.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_liar.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_loser.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_love.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_madtongue.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_malefighter1.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_malefighter2.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_mean.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_moneyeyes.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_monkey.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_nailbiting.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_neutral.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_ooooh.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_party.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_peace.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_pig.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_pray.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_pumpkin.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_question.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_rotfl.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_sad.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_shame.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_shamrock.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_shhhh.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_sick.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_sighing.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_silent.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_silly.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_sleep.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_smiley.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_star.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_sunglas.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_sweating.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_talktohand.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_think.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_tired.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_tongue.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_waiting.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_waving.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_whistling.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_wink.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_worried.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_worship.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_yingyang.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yahoo_youkiddingme.gif file | annotate | diff | comparison | revisions
pixmaps/smileys/default/yell.png file | annotate | diff | comparison | revisions
pixmaps/smileys/none/.cvsignore file | annotate | diff | comparison | revisions
pixmaps/smileys/none/Makefile.am file | annotate | diff | comparison | revisions
pixmaps/smileys/none/Makefile.mingw file | annotate | diff | comparison | revisions
pixmaps/smileys/none/theme file | annotate | diff | comparison | revisions
pixmaps/status-away.png file | annotate | diff | comparison | revisions
pixmaps/status-connect0.png file | annotate | diff | comparison | revisions
pixmaps/status-connect1.png file | annotate | diff | comparison | revisions
pixmaps/status-connect2.png file | annotate | diff | comparison | revisions
pixmaps/status-connect3.png file | annotate | diff | comparison | revisions
pixmaps/status-invisible.png file | annotate | diff | comparison | revisions
pixmaps/status-offline.png file | annotate | diff | comparison | revisions
pixmaps/status-online.png file | annotate | diff | comparison | revisions
pixmaps/status-typing0.png file | annotate | diff | comparison | revisions
pixmaps/status-typing1.png file | annotate | diff | comparison | revisions
pixmaps/status-typing2.png file | annotate | diff | comparison | revisions
pixmaps/status-typing3.png file | annotate | diff | comparison | revisions
pixmaps/status/.cvsignore file | annotate | diff | comparison | revisions
pixmaps/status/Makefile.am file | annotate | diff | comparison | revisions
pixmaps/status/Makefile.mingw file | annotate | diff | comparison | revisions
pixmaps/status/default/.cvsignore file | annotate | diff | comparison | revisions
pixmaps/status/default/Makefile.am file | annotate | diff | comparison | revisions
pixmaps/status/default/Makefile.mingw file | annotate | diff | comparison | revisions
pixmaps/status/default/activebuddy.png file | annotate | diff | comparison | revisions
pixmaps/status/default/admin.png file | annotate | diff | comparison | revisions
pixmaps/status/default/aim.png file | annotate | diff | comparison | revisions
pixmaps/status/default/aol.png file | annotate | diff | comparison | revisions
pixmaps/status/default/away.png file | annotate | diff | comparison | revisions
pixmaps/status/default/blocked.png file | annotate | diff | comparison | revisions
pixmaps/status/default/bonjour.png file | annotate | diff | comparison | revisions
pixmaps/status/default/dnd.png file | annotate | diff | comparison | revisions
pixmaps/status/default/extended_away.png file | annotate | diff | comparison | revisions
pixmaps/status/default/external.png file | annotate | diff | comparison | revisions
pixmaps/status/default/female.png file | annotate | diff | comparison | revisions
pixmaps/status/default/founder.png file | annotate | diff | comparison | revisions
pixmaps/status/default/founder.svg file | annotate | diff | comparison | revisions
pixmaps/status/default/freeforchat.png file | annotate | diff | comparison | revisions
pixmaps/status/default/gadu-gadu.png file | annotate | diff | comparison | revisions
pixmaps/status/default/game.png file | annotate | diff | comparison | revisions
pixmaps/status/default/halfop.png file | annotate | diff | comparison | revisions
pixmaps/status/default/halfop.svg file | annotate | diff | comparison | revisions
pixmaps/status/default/hiptop.png file | annotate | diff | comparison | revisions
pixmaps/status/default/icq.png file | annotate | diff | comparison | revisions
pixmaps/status/default/ignored.png file | annotate | diff | comparison | revisions
pixmaps/status/default/ignored.svg file | annotate | diff | comparison | revisions
pixmaps/status/default/invisible.png file | annotate | diff | comparison | revisions
pixmaps/status/default/irc.png file | annotate | diff | comparison | revisions
pixmaps/status/default/jabber.png file | annotate | diff | comparison | revisions
pixmaps/status/default/login.png file | annotate | diff | comparison | revisions
pixmaps/status/default/logout.png file | annotate | diff | comparison | revisions
pixmaps/status/default/male.png file | annotate | diff | comparison | revisions
pixmaps/status/default/meanwhile.png file | annotate | diff | comparison | revisions
pixmaps/status/default/msn.png file | annotate | diff | comparison | revisions
pixmaps/status/default/msn.svg file | annotate | diff | comparison | revisions
pixmaps/status/default/napster.png file | annotate | diff | comparison | revisions
pixmaps/status/default/notauthorized.png file | annotate | diff | comparison | revisions
pixmaps/status/default/novell.png file | annotate | diff | comparison | revisions
pixmaps/status/default/nr.png file | annotate | diff | comparison | revisions
pixmaps/status/default/occupied.png file | annotate | diff | comparison | revisions
pixmaps/status/default/offline.png file | annotate | diff | comparison | revisions
pixmaps/status/default/op.png file | annotate | diff | comparison | revisions
pixmaps/status/default/op.svg file | annotate | diff | comparison | revisions
pixmaps/status/default/pending.png file | annotate | diff | comparison | revisions
pixmaps/status/default/secure.png file | annotate | diff | comparison | revisions
pixmaps/status/default/silc.png file | annotate | diff | comparison | revisions
pixmaps/status/default/simple.png file | annotate | diff | comparison | revisions
pixmaps/status/default/unavailable.png file | annotate | diff | comparison | revisions
pixmaps/status/default/voice.png file | annotate | diff | comparison | revisions
pixmaps/status/default/voice.svg file | annotate | diff | comparison | revisions
pixmaps/status/default/wireless.png file | annotate | diff | comparison | revisions
pixmaps/status/default/yahoo.png file | annotate | diff | comparison | revisions
pixmaps/status/default/zephyr.png file | annotate | diff | comparison | revisions
pixmaps/stock_connect_16.png file | annotate | diff | comparison | revisions
pixmaps/stock_disconnect_16.png file | annotate | diff | comparison | revisions
pixmaps/tb_drag_arrow_down.xpm file | annotate | diff | comparison | revisions
pixmaps/tb_drag_arrow_left.xpm file | annotate | diff | comparison | revisions
pixmaps/tb_drag_arrow_right.xpm file | annotate | diff | comparison | revisions
pixmaps/tb_drag_arrow_up.xpm file | annotate | diff | comparison | revisions
pixmaps/text_bigger.png file | annotate | diff | comparison | revisions
pixmaps/text_normal.png file | annotate | diff | comparison | revisions
pixmaps/text_smaller.png file | annotate | diff | comparison | revisions
pixmaps/typed.png file | annotate | diff | comparison | revisions
pixmaps/typing.png file | annotate | diff | comparison | revisions
plugins/.cvsignore file | annotate | diff | comparison | revisions
plugins/ChangeLog file | annotate | diff | comparison | revisions
plugins/ChangeLog.API file | annotate | diff | comparison | revisions
plugins/HOWTO file | annotate | diff | comparison | revisions
plugins/Makefile.am file | annotate | diff | comparison | revisions
plugins/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/ciphertest.c file | annotate | diff | comparison | revisions
plugins/codeinline.c file | annotate | diff | comparison | revisions
plugins/contact_priority.c file | annotate | diff | comparison | revisions
plugins/crazychat/Makefile.am file | annotate | diff | comparison | revisions
plugins/crazychat/QTUtilities.c file | annotate | diff | comparison | revisions
plugins/crazychat/QTUtilities.h file | annotate | diff | comparison | revisions
plugins/crazychat/Utilities.c file | annotate | diff | comparison | revisions
plugins/crazychat/Utilities.h file | annotate | diff | comparison | revisions
plugins/crazychat/camdata.c file | annotate | diff | comparison | revisions
plugins/crazychat/camdata.h file | annotate | diff | comparison | revisions
plugins/crazychat/camproc.c file | annotate | diff | comparison | revisions
plugins/crazychat/camproc.h file | annotate | diff | comparison | revisions
plugins/crazychat/cc_features.c file | annotate | diff | comparison | revisions
plugins/crazychat/cc_gaim_plugin.c file | annotate | diff | comparison | revisions
plugins/crazychat/cc_gtk_gl.c file | annotate | diff | comparison | revisions
plugins/crazychat/cc_gtk_gl.h file | annotate | diff | comparison | revisions
plugins/crazychat/cc_interface.h file | annotate | diff | comparison | revisions
plugins/crazychat/cc_network.c file | annotate | diff | comparison | revisions
plugins/crazychat/cc_network.h file | annotate | diff | comparison | revisions
plugins/crazychat/cc_output.c file | annotate | diff | comparison | revisions
plugins/crazychat/configure.ac file | annotate | diff | comparison | revisions
plugins/crazychat/crazychat.c file | annotate | diff | comparison | revisions
plugins/crazychat/crazychat.h file | annotate | diff | comparison | revisions
plugins/crazychat/dog_lids.c file | annotate | diff | comparison | revisions
plugins/crazychat/dog_lids.h file | annotate | diff | comparison | revisions
plugins/crazychat/doggy.c file | annotate | diff | comparison | revisions
plugins/crazychat/doggy.h file | annotate | diff | comparison | revisions
plugins/crazychat/draw.c file | annotate | diff | comparison | revisions
plugins/crazychat/eye.c file | annotate | diff | comparison | revisions
plugins/crazychat/eye.h file | annotate | diff | comparison | revisions
plugins/crazychat/eyes.c file | annotate | diff | comparison | revisions
plugins/crazychat/eyes.h file | annotate | diff | comparison | revisions
plugins/crazychat/face.c file | annotate | diff | comparison | revisions
plugins/crazychat/face.h file | annotate | diff | comparison | revisions
plugins/crazychat/filter.c file | annotate | diff | comparison | revisions
plugins/crazychat/filter.h file | annotate | diff | comparison | revisions
plugins/crazychat/glm.c file | annotate | diff | comparison | revisions
plugins/crazychat/glm.h file | annotate | diff | comparison | revisions
plugins/crazychat/lids.c file | annotate | diff | comparison | revisions
plugins/crazychat/lids.h file | annotate | diff | comparison | revisions
plugins/crazychat/main.c file | annotate | diff | comparison | revisions
plugins/crazychat/mat_struct.h file | annotate | diff | comparison | revisions
plugins/crazychat/models.c file | annotate | diff | comparison | revisions
plugins/crazychat/models.h file | annotate | diff | comparison | revisions
plugins/crazychat/sharky.c file | annotate | diff | comparison | revisions
plugins/crazychat/sharky.h file | annotate | diff | comparison | revisions
plugins/crazychat/test.h file | annotate | diff | comparison | revisions
plugins/crazychat/util.h file | annotate | diff | comparison | revisions
plugins/dbus-example.c file | annotate | diff | comparison | revisions
plugins/docklet/.cvsignore file | annotate | diff | comparison | revisions
plugins/docklet/Makefile.am file | annotate | diff | comparison | revisions
plugins/docklet/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/docklet/MinimizeToTray.c file | annotate | diff | comparison | revisions
plugins/docklet/MinimizeToTray.h file | annotate | diff | comparison | revisions
plugins/docklet/docklet-win32.c file | annotate | diff | comparison | revisions
plugins/docklet/docklet-x11.c file | annotate | diff | comparison | revisions
plugins/docklet/docklet.c file | annotate | diff | comparison | revisions
plugins/docklet/docklet.h file | annotate | diff | comparison | revisions
plugins/docklet/eggtrayicon.c file | annotate | diff | comparison | revisions
plugins/docklet/eggtrayicon.h file | annotate | diff | comparison | revisions
plugins/extplacement.c file | annotate | diff | comparison | revisions
plugins/filectl.c file | annotate | diff | comparison | revisions
plugins/fortuneprofile.pl file | annotate | diff | comparison | revisions
plugins/gaim.pl file | annotate | diff | comparison | revisions
plugins/gaiminc.c file | annotate | diff | comparison | revisions
plugins/gaimrc.c file | annotate | diff | comparison | revisions
plugins/gestures/.cvsignore file | annotate | diff | comparison | revisions
plugins/gestures/Makefile.am file | annotate | diff | comparison | revisions
plugins/gestures/gestures.c file | annotate | diff | comparison | revisions
plugins/gestures/gstroke-internal.h file | annotate | diff | comparison | revisions
plugins/gestures/gstroke.h file | annotate | diff | comparison | revisions
plugins/gestures/stroke-draw.c file | annotate | diff | comparison | revisions
plugins/gestures/stroke.c file | annotate | diff | comparison | revisions
plugins/gevolution/.cvsignore file | annotate | diff | comparison | revisions
plugins/gevolution/Makefile.am file | annotate | diff | comparison | revisions
plugins/gevolution/add_buddy_dialog.c file | annotate | diff | comparison | revisions
plugins/gevolution/assoc-buddy.c file | annotate | diff | comparison | revisions
plugins/gevolution/eds-utils.c file | annotate | diff | comparison | revisions
plugins/gevolution/gevo-util.c file | annotate | diff | comparison | revisions
plugins/gevolution/gevolution.c file | annotate | diff | comparison | revisions
plugins/gevolution/gevolution.h file | annotate | diff | comparison | revisions
plugins/gevolution/new_person_dialog.c file | annotate | diff | comparison | revisions
plugins/gtk-signals-test.c file | annotate | diff | comparison | revisions
plugins/history.c file | annotate | diff | comparison | revisions
plugins/iconaway.c file | annotate | diff | comparison | revisions
plugins/idle.c file | annotate | diff | comparison | revisions
plugins/ipc-test-client.c file | annotate | diff | comparison | revisions
plugins/ipc-test-server.c file | annotate | diff | comparison | revisions
plugins/log_reader.c file | annotate | diff | comparison | revisions
plugins/mailchk.c file | annotate | diff | comparison | revisions
plugins/mono/.cvsignore file | annotate | diff | comparison | revisions
plugins/mono/BooPlugin.boo file | annotate | diff | comparison | revisions
plugins/mono/GetBuddyBack.cs file | annotate | diff | comparison | revisions
plugins/mono/MPlugin.cs file | annotate | diff | comparison | revisions
plugins/mono/Makefile.am file | annotate | diff | comparison | revisions
plugins/mono/api/.cvsignore file | annotate | diff | comparison | revisions
plugins/mono/api/Buddy.cs file | annotate | diff | comparison | revisions
plugins/mono/api/BuddyList.cs file | annotate | diff | comparison | revisions
plugins/mono/api/Debug.cs file | annotate | diff | comparison | revisions
plugins/mono/api/Event.cs file | annotate | diff | comparison | revisions
plugins/mono/api/GaimPlugin.cs file | annotate | diff | comparison | revisions
plugins/mono/api/Makefile.am file | annotate | diff | comparison | revisions
plugins/mono/api/Signal.cs file | annotate | diff | comparison | revisions
plugins/mono/api/Status.cs file | annotate | diff | comparison | revisions
plugins/mono/loader/.cvsignore file | annotate | diff | comparison | revisions
plugins/mono/loader/Makefile.am file | annotate | diff | comparison | revisions
plugins/mono/loader/blist-glue.c file | annotate | diff | comparison | revisions
plugins/mono/loader/debug-glue.c file | annotate | diff | comparison | revisions
plugins/mono/loader/mono-glue.h file | annotate | diff | comparison | revisions
plugins/mono/loader/mono-helper.c file | annotate | diff | comparison | revisions
plugins/mono/loader/mono-helper.h file | annotate | diff | comparison | revisions
plugins/mono/loader/mono.c file | annotate | diff | comparison | revisions
plugins/mono/loader/signal-glue.c file | annotate | diff | comparison | revisions
plugins/mono/loader/status-glue.c file | annotate | diff | comparison | revisions
plugins/musicmessaging/.cvsignore file | annotate | diff | comparison | revisions
plugins/musicmessaging/Makefile.am file | annotate | diff | comparison | revisions
plugins/musicmessaging/music.png file | annotate | diff | comparison | revisions
plugins/musicmessaging/musicmessaging.c file | annotate | diff | comparison | revisions
plugins/notify.c file | annotate | diff | comparison | revisions
plugins/perl/.cvsignore file | annotate | diff | comparison | revisions
plugins/perl/Makefile.am file | annotate | diff | comparison | revisions
plugins/perl/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/perl/common/.cvsignore file | annotate | diff | comparison | revisions
plugins/perl/common/Account.xs file | annotate | diff | comparison | revisions
plugins/perl/common/AccountOpts.xs file | annotate | diff | comparison | revisions
plugins/perl/common/BuddyIcon.xs file | annotate | diff | comparison | revisions
plugins/perl/common/BuddyList.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Cipher.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Cmds.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Connection.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Conversation.xs file | annotate | diff | comparison | revisions
plugins/perl/common/FT.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Gaim.pm file | annotate | diff | comparison | revisions
plugins/perl/common/Gaim.xs file | annotate | diff | comparison | revisions
plugins/perl/common/ImgStore.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Log.xs file | annotate | diff | comparison | revisions
plugins/perl/common/MANIFEST file | annotate | diff | comparison | revisions
plugins/perl/common/Makefile.PL.in file | annotate | diff | comparison | revisions
plugins/perl/common/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/perl/common/Network.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Notify.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Plugin.xs file | annotate | diff | comparison | revisions
plugins/perl/common/PluginPref.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Pounce.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Prefs.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Privacy.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Proxy.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Prpl.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Request.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Roomlist.xs file | annotate | diff | comparison | revisions
plugins/perl/common/SSLConn.xs file | annotate | diff | comparison | revisions
plugins/perl/common/SavedStatuses.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Server.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Sound.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Status.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Stringref.xs file | annotate | diff | comparison | revisions
plugins/perl/common/Util.xs file | annotate | diff | comparison | revisions
plugins/perl/common/XMLNode.xs file | annotate | diff | comparison | revisions
plugins/perl/common/fallback/const-c.inc file | annotate | diff | comparison | revisions
plugins/perl/common/fallback/const-xs.inc file | annotate | diff | comparison | revisions
plugins/perl/common/module.h file | annotate | diff | comparison | revisions
plugins/perl/common/typemap file | annotate | diff | comparison | revisions
plugins/perl/libgaimperl.c file | annotate | diff | comparison | revisions
plugins/perl/perl-common.c file | annotate | diff | comparison | revisions
plugins/perl/perl-common.h file | annotate | diff | comparison | revisions
plugins/perl/perl-handlers.c file | annotate | diff | comparison | revisions
plugins/perl/perl-handlers.h file | annotate | diff | comparison | revisions
plugins/perl/perl.c file | annotate | diff | comparison | revisions
plugins/perl/scripts/account.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/buddy_list.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/conversation.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/count_down.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/gtk_frame_test.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/plugin_action.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/plugin_pref.pl file | annotate | diff | comparison | revisions
plugins/perl/scripts/request.pl file | annotate | diff | comparison | revisions
plugins/pluginpref_example.c file | annotate | diff | comparison | revisions
plugins/psychic.c file | annotate | diff | comparison | revisions
plugins/raw.c file | annotate | diff | comparison | revisions
plugins/relnot.c file | annotate | diff | comparison | revisions
plugins/signals-test.c file | annotate | diff | comparison | revisions
plugins/simple.c file | annotate | diff | comparison | revisions
plugins/spellchk.c file | annotate | diff | comparison | revisions
plugins/ssl/.cvsignore file | annotate | diff | comparison | revisions
plugins/ssl/Makefile.am file | annotate | diff | comparison | revisions
plugins/ssl/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/ssl/ssl-gnutls.c file | annotate | diff | comparison | revisions
plugins/ssl/ssl-nss.c file | annotate | diff | comparison | revisions
plugins/ssl/ssl.c file | annotate | diff | comparison | revisions
plugins/statenotify.c file | annotate | diff | comparison | revisions
plugins/tcl/.cvsignore file | annotate | diff | comparison | revisions
plugins/tcl/Makefile.am file | annotate | diff | comparison | revisions
plugins/tcl/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/tcl/signal-test.tcl file | annotate | diff | comparison | revisions
plugins/tcl/tcl.c file | annotate | diff | comparison | revisions
plugins/tcl/tcl_cmds.c file | annotate | diff | comparison | revisions
plugins/tcl/tcl_gaim.h file | annotate | diff | comparison | revisions
plugins/tcl/tcl_glib.c file | annotate | diff | comparison | revisions
plugins/tcl/tcl_glib.h file | annotate | diff | comparison | revisions
plugins/tcl/tcl_signals.c file | annotate | diff | comparison | revisions
plugins/tcl/tcl_win32.c file | annotate | diff | comparison | revisions
plugins/test.pl file | annotate | diff | comparison | revisions
plugins/ticker/.cvsignore file | annotate | diff | comparison | revisions
plugins/ticker/Makefile.am file | annotate | diff | comparison | revisions
plugins/ticker/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/ticker/gtkticker.c file | annotate | diff | comparison | revisions
plugins/ticker/gtkticker.h file | annotate | diff | comparison | revisions
plugins/ticker/ticker.c file | annotate | diff | comparison | revisions
plugins/timestamp.c file | annotate | diff | comparison | revisions
plugins/timestamp_format.c file | annotate | diff | comparison | revisions
plugins/win32/transparency/.cvsignore file | annotate | diff | comparison | revisions
plugins/win32/transparency/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/win32/transparency/win2ktrans.c file | annotate | diff | comparison | revisions
plugins/win32/winprefs/.cvsignore file | annotate | diff | comparison | revisions
plugins/win32/winprefs/Makefile.mingw file | annotate | diff | comparison | revisions
plugins/win32/winprefs/gtkappbar.c file | annotate | diff | comparison | revisions
plugins/win32/winprefs/gtkappbar.h file | annotate | diff | comparison | revisions
plugins/win32/winprefs/winprefs.c file | annotate | diff | comparison | revisions
po/.cvsignore file | annotate | diff | comparison | revisions
po/update.pl file | annotate | diff | comparison | revisions
setup-gettext file | annotate | diff | comparison | revisions
sounds/.cvsignore file | annotate | diff | comparison | revisions
sounds/Makefile.am file | annotate | diff | comparison | revisions
sounds/alert.wav file | annotate | diff | comparison | revisions
sounds/login.wav file | annotate | diff | comparison | revisions
sounds/logout.wav file | annotate | diff | comparison | revisions
sounds/receive.wav file | annotate | diff | comparison | revisions
sounds/send.wav file | annotate | diff | comparison | revisions
src/.cvsignore file | annotate | diff | comparison | revisions
src/Makefile.am file | annotate | diff | comparison | revisions
src/Makefile.mingw file | annotate | diff | comparison | revisions
src/account.c file | annotate | diff | comparison | revisions
src/account.h file | annotate | diff | comparison | revisions
src/accountopt.c file | annotate | diff | comparison | revisions
src/accountopt.h file | annotate | diff | comparison | revisions
src/blist.c file | annotate | diff | comparison | revisions
src/blist.h file | annotate | diff | comparison | revisions
src/buddyicon.c file | annotate | diff | comparison | revisions
src/buddyicon.h file | annotate | diff | comparison | revisions
src/cipher.c file | annotate | diff | comparison | revisions
src/cipher.h file | annotate | diff | comparison | revisions
src/cmds.c file | annotate | diff | comparison | revisions
src/cmds.h file | annotate | diff | comparison | revisions
src/connection.c file | annotate | diff | comparison | revisions
src/connection.h file | annotate | diff | comparison | revisions
src/conversation.c file | annotate | diff | comparison | revisions
src/conversation.h file | annotate | diff | comparison | revisions
src/core.c file | annotate | diff | comparison | revisions
src/core.h file | annotate | diff | comparison | revisions
src/dbus-analyze-functions.py file | annotate | diff | comparison | revisions
src/dbus-analyze-types.py file | annotate | diff | comparison | revisions
src/dbus-bindings.h file | annotate | diff | comparison | revisions
src/dbus-define-api.h file | annotate | diff | comparison | revisions
src/dbus-gaim.h file | annotate | diff | comparison | revisions
src/dbus-gaim.service file | annotate | diff | comparison | revisions
src/dbus-maybe.h file | annotate | diff | comparison | revisions
src/dbus-server.c file | annotate | diff | comparison | revisions
src/dbus-server.h file | annotate | diff | comparison | revisions
src/dbus-useful.c file | annotate | diff | comparison | revisions
src/dbus-useful.h file | annotate | diff | comparison | revisions
src/debug.c file | annotate | diff | comparison | revisions
src/debug.h file | annotate | diff | comparison | revisions
src/desktopitem.c file | annotate | diff | comparison | revisions
src/desktopitem.h file | annotate | diff | comparison | revisions
src/dnssrv.c file | annotate | diff | comparison | revisions
src/dnssrv.h file | annotate | diff | comparison | revisions
src/eventloop.c file | annotate | diff | comparison | revisions
src/eventloop.h file | annotate | diff | comparison | revisions
src/ft.c file | annotate | diff | comparison | revisions
src/ft.h file | annotate | diff | comparison | revisions
src/gaim-client-example.c file | annotate | diff | comparison | revisions
src/gaim-client.c file | annotate | diff | comparison | revisions
src/gaim-client.h file | annotate | diff | comparison | revisions
src/gaim-notifications-example.py file | annotate | diff | comparison | revisions
src/gaim-remote.py file | annotate | diff | comparison | revisions
src/gaim-send file | annotate | diff | comparison | revisions
src/gaim-send-async file | annotate | diff | comparison | revisions
src/gaim-socket.h file | annotate | diff | comparison | revisions
src/gaim.h file | annotate | diff | comparison | revisions
src/getopt.c file | annotate | diff | comparison | revisions
src/getopt.h file | annotate | diff | comparison | revisions
src/getopt1.c file | annotate | diff | comparison | revisions
src/gtkaccount.c file | annotate | diff | comparison | revisions
src/gtkaccount.h file | annotate | diff | comparison | revisions
src/gtkblist.c file | annotate | diff | comparison | revisions
src/gtkblist.h file | annotate | diff | comparison | revisions
src/gtkcelllayout.c file | annotate | diff | comparison | revisions
src/gtkcelllayout.h file | annotate | diff | comparison | revisions
src/gtkcellrendererprogress.c file | annotate | diff | comparison | revisions
src/gtkcellrendererprogress.h file | annotate | diff | comparison | revisions
src/gtkcellview.c file | annotate | diff | comparison | revisions
src/gtkcellview.h file | annotate | diff | comparison | revisions
src/gtkcellviewmenuitem.c file | annotate | diff | comparison | revisions
src/gtkcellviewmenuitem.h file | annotate | diff | comparison | revisions
src/gtkcombobox.c file | annotate | diff | comparison | revisions
src/gtkcombobox.h file | annotate | diff | comparison | revisions
src/gtkconn.c file | annotate | diff | comparison | revisions
src/gtkconn.h file | annotate | diff | comparison | revisions
src/gtkconv.c file | annotate | diff | comparison | revisions
src/gtkconv.h file | annotate | diff | comparison | revisions
src/gtkconvwin.h file | annotate | diff | comparison | revisions
src/gtkdebug.c file | annotate | diff | comparison | revisions
src/gtkdebug.h file | annotate | diff | comparison | revisions
src/gtkdialogs.c file | annotate | diff | comparison | revisions
src/gtkdialogs.h file | annotate | diff | comparison | revisions
src/gtkdnd-hints.c file | annotate | diff | comparison | revisions
src/gtkdnd-hints.h file | annotate | diff | comparison | revisions
src/gtkeventloop.c file | annotate | diff | comparison | revisions
src/gtkeventloop.h file | annotate | diff | comparison | revisions
src/gtkexpander.c file | annotate | diff | comparison | revisions
src/gtkexpander.h file | annotate | diff | comparison | revisions
src/gtkft.c file | annotate | diff | comparison | revisions
src/gtkft.h file | annotate | diff | comparison | revisions
src/gtkgaim.h file | annotate | diff | comparison | revisions
src/gtkidle.c file | annotate | diff | comparison | revisions
src/gtkidle.h file | annotate | diff | comparison | revisions
src/gtkimhtml.c file | annotate | diff | comparison | revisions
src/gtkimhtml.h file | annotate | diff | comparison | revisions
src/gtkimhtmltoolbar.c file | annotate | diff | comparison | revisions
src/gtkimhtmltoolbar.h file | annotate | diff | comparison | revisions
src/gtklog.c file | annotate | diff | comparison | revisions
src/gtklog.h file | annotate | diff | comparison | revisions
src/gtkmain.c file | annotate | diff | comparison | revisions
src/gtkmedia.c file | annotate | diff | comparison | revisions
src/gtkmedia.h file | annotate | diff | comparison | revisions
src/gtkmenutray.c file | annotate | diff | comparison | revisions
src/gtkmenutray.h file | annotate | diff | comparison | revisions
src/gtknickcolors.h file | annotate | diff | comparison | revisions
src/gtknotify.c file | annotate | diff | comparison | revisions
src/gtknotify.h file | annotate | diff | comparison | revisions
src/gtkplugin.c file | annotate | diff | comparison | revisions
src/gtkplugin.h file | annotate | diff | comparison | revisions
src/gtkpluginpref.c file | annotate | diff | comparison | revisions
src/gtkpluginpref.h file | annotate | diff | comparison | revisions
src/gtkpounce.c file | annotate | diff | comparison | revisions
src/gtkpounce.h file | annotate | diff | comparison | revisions
src/gtkprefs.c file | annotate | diff | comparison | revisions
src/gtkprefs.h file | annotate | diff | comparison | revisions
src/gtkprivacy.c file | annotate | diff | comparison | revisions
src/gtkprivacy.h file | annotate | diff | comparison | revisions
src/gtkrequest.c file | annotate | diff | comparison | revisions
src/gtkrequest.h file | annotate | diff | comparison | revisions
src/gtkroomlist.c file | annotate | diff | comparison | revisions
src/gtkroomlist.h file | annotate | diff | comparison | revisions
src/gtksavedstatuses.c file | annotate | diff | comparison | revisions
src/gtksavedstatuses.h file | annotate | diff | comparison | revisions
src/gtksession.c file | annotate | diff | comparison | revisions
src/gtksession.h file | annotate | diff | comparison | revisions
src/gtksound.c file | annotate | diff | comparison | revisions
src/gtksound.h file | annotate | diff | comparison | revisions
src/gtksourceiter.c file | annotate | diff | comparison | revisions
src/gtksourceiter.h file | annotate | diff | comparison | revisions
src/gtkstatusbox.c file | annotate | diff | comparison | revisions
src/gtkstatusbox.h file | annotate | diff | comparison | revisions
src/gtkstock.c file | annotate | diff | comparison | revisions
src/gtkstock.h file | annotate | diff | comparison | revisions
src/gtkthemes.c file | annotate | diff | comparison | revisions
src/gtkthemes.h file | annotate | diff | comparison | revisions
src/gtkutils.c file | annotate | diff | comparison | revisions
src/gtkutils.h file | annotate | diff | comparison | revisions
src/gtkwhiteboard.c file | annotate | diff | comparison | revisions
src/gtkwhiteboard.h file | annotate | diff | comparison | revisions
src/idle.c file | annotate | diff | comparison | revisions
src/idle.h file | annotate | diff | comparison | revisions
src/imgstore.c file | annotate | diff | comparison | revisions
src/imgstore.h file | annotate | diff | comparison | revisions
src/internal.h file | annotate | diff | comparison | revisions
src/log.c file | annotate | diff | comparison | revisions
src/log.h file | annotate | diff | comparison | revisions
src/media.c file | annotate | diff | comparison | revisions
src/media.h file | annotate | diff | comparison | revisions
src/mediastreamer/.cvsignore file | annotate | diff | comparison | revisions
src/mediastreamer/Makefile.am file | annotate | diff | comparison | revisions
src/mediastreamer/affine.c file | annotate | diff | comparison | revisions
src/mediastreamer/affine.h file | annotate | diff | comparison | revisions
src/mediastreamer/alsacard.c file | annotate | diff | comparison | revisions
src/mediastreamer/alsacard.h file | annotate | diff | comparison | revisions
src/mediastreamer/audiostream.c file | annotate | diff | comparison | revisions
src/mediastreamer/g711common.h file | annotate | diff | comparison | revisions
src/mediastreamer/hpuxsndcard.c file | annotate | diff | comparison | revisions
src/mediastreamer/jackcard.c file | annotate | diff | comparison | revisions
src/mediastreamer/jackcard.h file | annotate | diff | comparison | revisions
src/mediastreamer/mediastream.c file | annotate | diff | comparison | revisions
src/mediastreamer/mediastream.h file | annotate | diff | comparison | revisions
src/mediastreamer/ms.c file | annotate | diff | comparison | revisions
src/mediastreamer/ms.h file | annotate | diff | comparison | revisions
src/mediastreamer/msAlawdec.c file | annotate | diff | comparison | revisions
src/mediastreamer/msAlawdec.h file | annotate | diff | comparison | revisions
src/mediastreamer/msAlawenc.c file | annotate | diff | comparison | revisions
src/mediastreamer/msAlawenc.h file | annotate | diff | comparison | revisions
src/mediastreamer/msGSMdecoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/msGSMdecoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msGSMencoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/msGSMencoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msLPC10decoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/msLPC10decoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msLPC10encoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/msLPC10encoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msMUlawdec.c file | annotate | diff | comparison | revisions
src/mediastreamer/msMUlawdec.h file | annotate | diff | comparison | revisions
src/mediastreamer/msMUlawenc.c file | annotate | diff | comparison | revisions
src/mediastreamer/msMUlawenc.h file | annotate | diff | comparison | revisions
src/mediastreamer/msavdecoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/msavdecoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msavencoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/msavencoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msbuffer.c file | annotate | diff | comparison | revisions
src/mediastreamer/msbuffer.h file | annotate | diff | comparison | revisions
src/mediastreamer/mscodec.c file | annotate | diff | comparison | revisions
src/mediastreamer/mscodec.h file | annotate | diff | comparison | revisions
src/mediastreamer/mscopy.c file | annotate | diff | comparison | revisions
src/mediastreamer/mscopy.h file | annotate | diff | comparison | revisions
src/mediastreamer/msfdispatcher.c file | annotate | diff | comparison | revisions
src/mediastreamer/msfdispatcher.h file | annotate | diff | comparison | revisions
src/mediastreamer/msfifo.c file | annotate | diff | comparison | revisions
src/mediastreamer/msfifo.h file | annotate | diff | comparison | revisions
src/mediastreamer/msfilter.c file | annotate | diff | comparison | revisions
src/mediastreamer/msfilter.h file | annotate | diff | comparison | revisions
src/mediastreamer/msilbcdec.c file | annotate | diff | comparison | revisions
src/mediastreamer/msilbcdec.h file | annotate | diff | comparison | revisions
src/mediastreamer/msilbcenc.c file | annotate | diff | comparison | revisions
src/mediastreamer/msilbcenc.h file | annotate | diff | comparison | revisions
src/mediastreamer/msnosync.c file | annotate | diff | comparison | revisions
src/mediastreamer/msnosync.h file | annotate | diff | comparison | revisions
src/mediastreamer/msossread.c file | annotate | diff | comparison | revisions
src/mediastreamer/msossread.h file | annotate | diff | comparison | revisions
src/mediastreamer/msosswrite.c file | annotate | diff | comparison | revisions
src/mediastreamer/msosswrite.h file | annotate | diff | comparison | revisions
src/mediastreamer/msqdispatcher.c file | annotate | diff | comparison | revisions
src/mediastreamer/msqdispatcher.h file | annotate | diff | comparison | revisions
src/mediastreamer/msqueue.c file | annotate | diff | comparison | revisions
src/mediastreamer/msqueue.h file | annotate | diff | comparison | revisions
src/mediastreamer/msread.c file | annotate | diff | comparison | revisions
src/mediastreamer/msread.h file | annotate | diff | comparison | revisions
src/mediastreamer/msringplayer.c file | annotate | diff | comparison | revisions
src/mediastreamer/msringplayer.h file | annotate | diff | comparison | revisions
src/mediastreamer/msrtprecv.c file | annotate | diff | comparison | revisions
src/mediastreamer/msrtprecv.h file | annotate | diff | comparison | revisions
src/mediastreamer/msrtpsend.c file | annotate | diff | comparison | revisions
src/mediastreamer/msrtpsend.h file | annotate | diff | comparison | revisions
src/mediastreamer/mssdlout.c file | annotate | diff | comparison | revisions
src/mediastreamer/mssdlout.h file | annotate | diff | comparison | revisions
src/mediastreamer/mssoundread.c file | annotate | diff | comparison | revisions
src/mediastreamer/mssoundread.h file | annotate | diff | comparison | revisions
src/mediastreamer/mssoundwrite.c file | annotate | diff | comparison | revisions
src/mediastreamer/mssoundwrite.h file | annotate | diff | comparison | revisions
src/mediastreamer/msspeexdec.c file | annotate | diff | comparison | revisions
src/mediastreamer/msspeexdec.h file | annotate | diff | comparison | revisions
src/mediastreamer/msspeexenc.c file | annotate | diff | comparison | revisions
src/mediastreamer/msspeexenc.h file | annotate | diff | comparison | revisions
src/mediastreamer/mssync.c file | annotate | diff | comparison | revisions
src/mediastreamer/mssync.h file | annotate | diff | comparison | revisions
src/mediastreamer/mstimer.c file | annotate | diff | comparison | revisions
src/mediastreamer/mstimer.h file | annotate | diff | comparison | revisions
src/mediastreamer/mstruespeechdecoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/mstruespeechdecoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/mstruespeechencoder.c file | annotate | diff | comparison | revisions
src/mediastreamer/mstruespeechencoder.h file | annotate | diff | comparison | revisions
src/mediastreamer/msutils.h file | annotate | diff | comparison | revisions
src/mediastreamer/msv4l.c file | annotate | diff | comparison | revisions
src/mediastreamer/msv4l.h file | annotate | diff | comparison | revisions
src/mediastreamer/msvideosource.c file | annotate | diff | comparison | revisions
src/mediastreamer/msvideosource.h file | annotate | diff | comparison | revisions
src/mediastreamer/mswrite.c file | annotate | diff | comparison | revisions
src/mediastreamer/mswrite.h file | annotate | diff | comparison | revisions
src/mediastreamer/osscard.c file | annotate | diff | comparison | revisions
src/mediastreamer/osscard.h file | annotate | diff | comparison | revisions
src/mediastreamer/ring_test.c file | annotate | diff | comparison | revisions
src/mediastreamer/sndcard.c file | annotate | diff | comparison | revisions
src/mediastreamer/sndcard.h file | annotate | diff | comparison | revisions
src/mediastreamer/test.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_alaw.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_gsm.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_lpc10.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_mulaw.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_rtprecv.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_speex.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_truespeech.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_v4l.c file | annotate | diff | comparison | revisions
src/mediastreamer/test_videostream.c file | annotate | diff | comparison | revisions
src/mediastreamer/videostream.c file | annotate | diff | comparison | revisions
src/mediastreamer/waveheader.h file | annotate | diff | comparison | revisions
src/mime.c file | annotate | diff | comparison | revisions
src/mime.h file | annotate | diff | comparison | revisions
src/network.c file | annotate | diff | comparison | revisions
src/network.h file | annotate | diff | comparison | revisions
src/notify.c file | annotate | diff | comparison | revisions
src/notify.h file | annotate | diff | comparison | revisions
src/ntlm.c file | annotate | diff | comparison | revisions
src/ntlm.h file | annotate | diff | comparison | revisions
src/plugin.c file | annotate | diff | comparison | revisions
src/plugin.h file | annotate | diff | comparison | revisions
src/pluginpref.c file | annotate | diff | comparison | revisions
src/pluginpref.h file | annotate | diff | comparison | revisions
src/pounce.c file | annotate | diff | comparison | revisions
src/pounce.h file | annotate | diff | comparison | revisions
src/prefix.c file | annotate | diff | comparison | revisions
src/prefix.h file | annotate | diff | comparison | revisions
src/prefs.c file | annotate | diff | comparison | revisions
src/prefs.h file | annotate | diff | comparison | revisions
src/privacy.c file | annotate | diff | comparison | revisions
src/privacy.h file | annotate | diff | comparison | revisions
src/protocols/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/bonjour/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/bonjour/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/bonjour/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/bonjour/bonjour.c file | annotate | diff | comparison | revisions
src/protocols/bonjour/bonjour.h file | annotate | diff | comparison | revisions
src/protocols/bonjour/buddy.c file | annotate | diff | comparison | revisions
src/protocols/bonjour/buddy.h file | annotate | diff | comparison | revisions
src/protocols/bonjour/dns_sd.c file | annotate | diff | comparison | revisions
src/protocols/bonjour/dns_sd.h file | annotate | diff | comparison | revisions
src/protocols/bonjour/issues.txt file | annotate | diff | comparison | revisions
src/protocols/bonjour/jabber.c file | annotate | diff | comparison | revisions
src/protocols/bonjour/jabber.h file | annotate | diff | comparison | revisions
src/protocols/bonjour/messages.txt file | annotate | diff | comparison | revisions
src/protocols/gg/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/gg/.todo file | annotate | diff | comparison | revisions
src/protocols/gg/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/gg/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/gg/buddylist.c file | annotate | diff | comparison | revisions
src/protocols/gg/buddylist.h file | annotate | diff | comparison | revisions
src/protocols/gg/confer.c file | annotate | diff | comparison | revisions
src/protocols/gg/confer.h file | annotate | diff | comparison | revisions
src/protocols/gg/gg.c file | annotate | diff | comparison | revisions
src/protocols/gg/gg.h file | annotate | diff | comparison | revisions
src/protocols/gg/lib/COPYING file | annotate | diff | comparison | revisions
src/protocols/gg/lib/common.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/compat.h file | annotate | diff | comparison | revisions
src/protocols/gg/lib/dcc.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/events.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/http.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/libgadu-config.h file | annotate | diff | comparison | revisions
src/protocols/gg/lib/libgadu.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/libgadu.h file | annotate | diff | comparison | revisions
src/protocols/gg/lib/obsolete.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/pubdir.c file | annotate | diff | comparison | revisions
src/protocols/gg/lib/pubdir50.c file | annotate | diff | comparison | revisions
src/protocols/gg/search.c file | annotate | diff | comparison | revisions
src/protocols/gg/search.h file | annotate | diff | comparison | revisions
src/protocols/gg/utils.c file | annotate | diff | comparison | revisions
src/protocols/gg/utils.h file | annotate | diff | comparison | revisions
src/protocols/irc/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/irc/.todo file | annotate | diff | comparison | revisions
src/protocols/irc/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/irc/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/irc/PROTOCOL file | annotate | diff | comparison | revisions
src/protocols/irc/cmds.c file | annotate | diff | comparison | revisions
src/protocols/irc/dcc_send.c file | annotate | diff | comparison | revisions
src/protocols/irc/irc.c file | annotate | diff | comparison | revisions
src/protocols/irc/irc.h file | annotate | diff | comparison | revisions
src/protocols/irc/msgs.c file | annotate | diff | comparison | revisions
src/protocols/irc/parse.c file | annotate | diff | comparison | revisions
src/protocols/jabber/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/jabber/.todo file | annotate | diff | comparison | revisions
src/protocols/jabber/JEPS file | annotate | diff | comparison | revisions
src/protocols/jabber/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/jabber/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/jabber/auth.c file | annotate | diff | comparison | revisions
src/protocols/jabber/auth.h file | annotate | diff | comparison | revisions
src/protocols/jabber/buddy.c file | annotate | diff | comparison | revisions
src/protocols/jabber/buddy.h file | annotate | diff | comparison | revisions
src/protocols/jabber/chat.c file | annotate | diff | comparison | revisions
src/protocols/jabber/chat.h file | annotate | diff | comparison | revisions
src/protocols/jabber/disco.c file | annotate | diff | comparison | revisions
src/protocols/jabber/disco.h file | annotate | diff | comparison | revisions
src/protocols/jabber/iq.c file | annotate | diff | comparison | revisions
src/protocols/jabber/iq.h file | annotate | diff | comparison | revisions
src/protocols/jabber/jabber.c file | annotate | diff | comparison | revisions
src/protocols/jabber/jabber.h file | annotate | diff | comparison | revisions
src/protocols/jabber/jutil.c file | annotate | diff | comparison | revisions
src/protocols/jabber/jutil.h file | annotate | diff | comparison | revisions
src/protocols/jabber/message.c file | annotate | diff | comparison | revisions
src/protocols/jabber/message.h file | annotate | diff | comparison | revisions
src/protocols/jabber/oob.c file | annotate | diff | comparison | revisions
src/protocols/jabber/oob.h file | annotate | diff | comparison | revisions
src/protocols/jabber/parser.c file | annotate | diff | comparison | revisions
src/protocols/jabber/parser.h file | annotate | diff | comparison | revisions
src/protocols/jabber/presence.c file | annotate | diff | comparison | revisions
src/protocols/jabber/presence.h file | annotate | diff | comparison | revisions
src/protocols/jabber/roster.c file | annotate | diff | comparison | revisions
src/protocols/jabber/roster.h file | annotate | diff | comparison | revisions
src/protocols/jabber/si.c file | annotate | diff | comparison | revisions
src/protocols/jabber/si.h file | annotate | diff | comparison | revisions
src/protocols/jabber/win32/posix.uname.c file | annotate | diff | comparison | revisions
src/protocols/jabber/win32/utsname.h file | annotate | diff | comparison | revisions
src/protocols/jabber/xdata.c file | annotate | diff | comparison | revisions
src/protocols/jabber/xdata.h file | annotate | diff | comparison | revisions
src/protocols/msn/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/msn/.todo file | annotate | diff | comparison | revisions
src/protocols/msn/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/msn/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/msn/cmdproc.c file | annotate | diff | comparison | revisions
src/protocols/msn/cmdproc.h file | annotate | diff | comparison | revisions
src/protocols/msn/command.c file | annotate | diff | comparison | revisions
src/protocols/msn/command.h file | annotate | diff | comparison | revisions
src/protocols/msn/dialog.c file | annotate | diff | comparison | revisions
src/protocols/msn/dialog.h file | annotate | diff | comparison | revisions
src/protocols/msn/directconn.c file | annotate | diff | comparison | revisions
src/protocols/msn/directconn.h file | annotate | diff | comparison | revisions
src/protocols/msn/error.c file | annotate | diff | comparison | revisions
src/protocols/msn/error.h file | annotate | diff | comparison | revisions
src/protocols/msn/group.c file | annotate | diff | comparison | revisions
src/protocols/msn/group.h file | annotate | diff | comparison | revisions
src/protocols/msn/history.c file | annotate | diff | comparison | revisions
src/protocols/msn/history.h file | annotate | diff | comparison | revisions
src/protocols/msn/httpconn.c file | annotate | diff | comparison | revisions
src/protocols/msn/httpconn.h file | annotate | diff | comparison | revisions
src/protocols/msn/msg.c file | annotate | diff | comparison | revisions
src/protocols/msn/msg.h file | annotate | diff | comparison | revisions
src/protocols/msn/msn.c file | annotate | diff | comparison | revisions
src/protocols/msn/msn.h file | annotate | diff | comparison | revisions
src/protocols/msn/nexus.c file | annotate | diff | comparison | revisions
src/protocols/msn/nexus.h file | annotate | diff | comparison | revisions
src/protocols/msn/notification.c file | annotate | diff | comparison | revisions
src/protocols/msn/notification.h file | annotate | diff | comparison | revisions
src/protocols/msn/object.c file | annotate | diff | comparison | revisions
src/protocols/msn/object.h file | annotate | diff | comparison | revisions
src/protocols/msn/page.c file | annotate | diff | comparison | revisions
src/protocols/msn/page.h file | annotate | diff | comparison | revisions
src/protocols/msn/servconn.c file | annotate | diff | comparison | revisions
src/protocols/msn/servconn.h file | annotate | diff | comparison | revisions
src/protocols/msn/session.c file | annotate | diff | comparison | revisions
src/protocols/msn/session.h file | annotate | diff | comparison | revisions
src/protocols/msn/slp.c file | annotate | diff | comparison | revisions
src/protocols/msn/slp.h file | annotate | diff | comparison | revisions
src/protocols/msn/slpcall.c file | annotate | diff | comparison | revisions
src/protocols/msn/slpcall.h file | annotate | diff | comparison | revisions
src/protocols/msn/slplink.c file | annotate | diff | comparison | revisions
src/protocols/msn/slplink.h file | annotate | diff | comparison | revisions
src/protocols/msn/slpmsg.c file | annotate | diff | comparison | revisions
src/protocols/msn/slpmsg.h file | annotate | diff | comparison | revisions
src/protocols/msn/slpsession.c file | annotate | diff | comparison | revisions
src/protocols/msn/slpsession.h file | annotate | diff | comparison | revisions
src/protocols/msn/state.c file | annotate | diff | comparison | revisions
src/protocols/msn/state.h file | annotate | diff | comparison | revisions
src/protocols/msn/switchboard.c file | annotate | diff | comparison | revisions
src/protocols/msn/switchboard.h file | annotate | diff | comparison | revisions
src/protocols/msn/sync.c file | annotate | diff | comparison | revisions
src/protocols/msn/sync.h file | annotate | diff | comparison | revisions
src/protocols/msn/table.c file | annotate | diff | comparison | revisions
src/protocols/msn/table.h file | annotate | diff | comparison | revisions
src/protocols/msn/transaction.c file | annotate | diff | comparison | revisions
src/protocols/msn/transaction.h file | annotate | diff | comparison | revisions
src/protocols/msn/user.c file | annotate | diff | comparison | revisions
src/protocols/msn/user.h file | annotate | diff | comparison | revisions
src/protocols/msn/userlist.c file | annotate | diff | comparison | revisions
src/protocols/msn/userlist.h file | annotate | diff | comparison | revisions
src/protocols/msn/utils.c file | annotate | diff | comparison | revisions
src/protocols/msn/utils.h file | annotate | diff | comparison | revisions
src/protocols/napster/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/napster/.todo file | annotate | diff | comparison | revisions
src/protocols/napster/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/napster/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/napster/napster.c file | annotate | diff | comparison | revisions
src/protocols/novell/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/novell/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/novell/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/novell/nmconference.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmconference.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmconn.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmconn.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmcontact.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmcontact.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmevent.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmevent.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmfield.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmfield.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmmessage.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmmessage.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmrequest.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmrequest.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmrtf.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmrtf.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmuser.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmuser.h file | annotate | diff | comparison | revisions
src/protocols/novell/nmuserrecord.c file | annotate | diff | comparison | revisions
src/protocols/novell/nmuserrecord.h file | annotate | diff | comparison | revisions
src/protocols/novell/novell.c file | annotate | diff | comparison | revisions
src/protocols/oscar/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/oscar/.todo file | annotate | diff | comparison | revisions
src/protocols/oscar/AUTHORS file | annotate | diff | comparison | revisions
src/protocols/oscar/COPYING file | annotate | diff | comparison | revisions
src/protocols/oscar/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/oscar/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/oscar/admin.c file | annotate | diff | comparison | revisions
src/protocols/oscar/adverts.c file | annotate | diff | comparison | revisions
src/protocols/oscar/aim.h file | annotate | diff | comparison | revisions
src/protocols/oscar/aim_cbtypes.h file | annotate | diff | comparison | revisions
src/protocols/oscar/aim_internal.h file | annotate | diff | comparison | revisions
src/protocols/oscar/auth.c file | annotate | diff | comparison | revisions
src/protocols/oscar/bart.c file | annotate | diff | comparison | revisions
src/protocols/oscar/bos.c file | annotate | diff | comparison | revisions
src/protocols/oscar/bstream.c file | annotate | diff | comparison | revisions
src/protocols/oscar/buddylist.c file | annotate | diff | comparison | revisions
src/protocols/oscar/chat.c file | annotate | diff | comparison | revisions
src/protocols/oscar/chatnav.c file | annotate | diff | comparison | revisions
src/protocols/oscar/conn.c file | annotate | diff | comparison | revisions
src/protocols/oscar/email.c file | annotate | diff | comparison | revisions
src/protocols/oscar/ft.c file | annotate | diff | comparison | revisions
src/protocols/oscar/icq.c file | annotate | diff | comparison | revisions
src/protocols/oscar/im.c file | annotate | diff | comparison | revisions
src/protocols/oscar/invite.c file | annotate | diff | comparison | revisions
src/protocols/oscar/locate.c file | annotate | diff | comparison | revisions
src/protocols/oscar/misc.c file | annotate | diff | comparison | revisions
src/protocols/oscar/msgcookie.c file | annotate | diff | comparison | revisions
src/protocols/oscar/odir.c file | annotate | diff | comparison | revisions
src/protocols/oscar/oscar.c file | annotate | diff | comparison | revisions
src/protocols/oscar/popups.c file | annotate | diff | comparison | revisions
src/protocols/oscar/rxhandlers.c file | annotate | diff | comparison | revisions
src/protocols/oscar/rxqueue.c file | annotate | diff | comparison | revisions
src/protocols/oscar/search.c file | annotate | diff | comparison | revisions
src/protocols/oscar/service.c file | annotate | diff | comparison | revisions
src/protocols/oscar/snac.c file | annotate | diff | comparison | revisions
src/protocols/oscar/ssi.c file | annotate | diff | comparison | revisions
src/protocols/oscar/stats.c file | annotate | diff | comparison | revisions
src/protocols/oscar/tlv.c file | annotate | diff | comparison | revisions
src/protocols/oscar/translate.c file | annotate | diff | comparison | revisions
src/protocols/oscar/txqueue.c file | annotate | diff | comparison | revisions
src/protocols/oscar/util.c file | annotate | diff | comparison | revisions
src/protocols/sametime/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/sametime/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/sametime/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/sametime/sametime.c file | annotate | diff | comparison | revisions
src/protocols/sametime/sametime.h file | annotate | diff | comparison | revisions
src/protocols/silc/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/silc/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/silc/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/silc/README file | annotate | diff | comparison | revisions
src/protocols/silc/TODO file | annotate | diff | comparison | revisions
src/protocols/silc/buddy.c file | annotate | diff | comparison | revisions
src/protocols/silc/chat.c file | annotate | diff | comparison | revisions
src/protocols/silc/ft.c file | annotate | diff | comparison | revisions
src/protocols/silc/ops.c file | annotate | diff | comparison | revisions
src/protocols/silc/pk.c file | annotate | diff | comparison | revisions
src/protocols/silc/silc.c file | annotate | diff | comparison | revisions
src/protocols/silc/silcgaim.h file | annotate | diff | comparison | revisions
src/protocols/silc/util.c file | annotate | diff | comparison | revisions
src/protocols/silc/wb.c file | annotate | diff | comparison | revisions
src/protocols/silc/wb.h file | annotate | diff | comparison | revisions
src/protocols/simple/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/simple/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/simple/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/simple/simple.c file | annotate | diff | comparison | revisions
src/protocols/simple/simple.h file | annotate | diff | comparison | revisions
src/protocols/simple/sipmsg.c file | annotate | diff | comparison | revisions
src/protocols/simple/sipmsg.h file | annotate | diff | comparison | revisions
src/protocols/toc/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/toc/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/toc/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/toc/PROTOCOL file | annotate | diff | comparison | revisions
src/protocols/toc/toc.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/yahoo/.todo file | annotate | diff | comparison | revisions
src/protocols/yahoo/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/yahoo/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/yahoo/util.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_auth.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_auth.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_crypt.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_crypt.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_doodle.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_doodle.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_filexfer.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_filexfer.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_friend.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_friend.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_packet.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_packet.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_picture.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_picture.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoo_profile.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoochat.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/yahoochat.h file | annotate | diff | comparison | revisions
src/protocols/yahoo/ycht.c file | annotate | diff | comparison | revisions
src/protocols/yahoo/ycht.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/.cvsignore file | annotate | diff | comparison | revisions
src/protocols/zephyr/.todo file | annotate | diff | comparison | revisions
src/protocols/zephyr/Makefile.am file | annotate | diff | comparison | revisions
src/protocols/zephyr/Makefile.mingw file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZAsyncLocate.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZCkAuth.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZCkIfNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZClosePort.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZCmpUID.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZCmpUIDP.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFlsLocs.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFlsSubs.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtAuth.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtList.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtNotice.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtRaw.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtRawLst.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtSmRLst.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFmtSmRaw.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZFreeNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZGetLocs.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZGetSender.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZGetSubs.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZGetWGPort.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZIfNotice.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZInit.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZLocations.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZMakeAscii.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZMkAuth.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZNewLocU.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZOpenPort.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZParseNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZPeekIfNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZPeekNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZPeekPkt.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZPending.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZReadAscii.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZRecvNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZRecvPkt.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZRetSubs.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSendList.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSendNot.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSendPkt.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSendRLst.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSendRaw.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSetDest.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSetFD.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSetSrv.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZSubs.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZVariables.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZWait4Not.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/ZhmStat.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/Zinternal.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/com_err.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/error_message.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/error_table.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/et_name.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/init_et.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/internal.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/mit-copyright.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/mit-sipb-copyright.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/sysdep.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/zephyr.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/zephyr.h file | annotate | diff | comparison | revisions
src/protocols/zephyr/zephyr_err.c file | annotate | diff | comparison | revisions
src/protocols/zephyr/zephyr_err.h file | annotate | diff | comparison | revisions
src/proxy.c file | annotate | diff | comparison | revisions
src/proxy.h file | annotate | diff | comparison | revisions
src/prpl.c file | annotate | diff | comparison | revisions
src/prpl.h file | annotate | diff | comparison | revisions
src/request.c file | annotate | diff | comparison | revisions
src/request.h file | annotate | diff | comparison | revisions
src/roomlist.c file | annotate | diff | comparison | revisions
src/roomlist.h file | annotate | diff | comparison | revisions
src/savedstatuses.c file | annotate | diff | comparison | revisions
src/savedstatuses.h file | annotate | diff | comparison | revisions
src/server.c file | annotate | diff | comparison | revisions
src/server.h file | annotate | diff | comparison | revisions
src/signals.c file | annotate | diff | comparison | revisions
src/signals.h file | annotate | diff | comparison | revisions
src/socket.c file | annotate | diff | comparison | revisions
src/sound.c file | annotate | diff | comparison | revisions
src/sound.h file | annotate | diff | comparison | revisions
src/sslconn.c file | annotate | diff | comparison | revisions
src/sslconn.h file | annotate | diff | comparison | revisions
src/status.c file | annotate | diff | comparison | revisions
src/status.h file | annotate | diff | comparison | revisions
src/stringref.c file | annotate | diff | comparison | revisions
src/stringref.h file | annotate | diff | comparison | revisions
src/stun.c file | annotate | diff | comparison | revisions
src/stun.h file | annotate | diff | comparison | revisions
src/upnp.c file | annotate | diff | comparison | revisions
src/upnp.h file | annotate | diff | comparison | revisions
src/util.c file | annotate | diff | comparison | revisions
src/util.h file | annotate | diff | comparison | revisions
src/value.c file | annotate | diff | comparison | revisions
src/value.h file | annotate | diff | comparison | revisions
src/version.h file | annotate | diff | comparison | revisions
src/whiteboard.c file | annotate | diff | comparison | revisions
src/whiteboard.h file | annotate | diff | comparison | revisions
src/win32/IdleTracker/.cvsignore file | annotate | diff | comparison | revisions
src/win32/IdleTracker/Makefile.mingw file | annotate | diff | comparison | revisions
src/win32/IdleTracker/idletrack.c file | annotate | diff | comparison | revisions
src/win32/IdleTracker/idletrack.h file | annotate | diff | comparison | revisions
src/win32/gaimrc.rc file | annotate | diff | comparison | revisions
src/win32/global.mak file | annotate | diff | comparison | revisions
src/win32/libc_interface.c file | annotate | diff | comparison | revisions
src/win32/libc_interface.h file | annotate | diff | comparison | revisions
src/win32/libc_internal.h file | annotate | diff | comparison | revisions
src/win32/nsis/gaim-header.bmp file | annotate | diff | comparison | revisions
src/win32/nsis/gaim-intro.bmp file | annotate | diff | comparison | revisions
src/win32/nsis/gaim-plugin.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/langmacros.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/albanian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/bulgarian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/catalan.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/czech.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/danish.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/dutch.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/english.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/finnish.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/french.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/galician.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/german.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/hebrew.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/hungarian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/italian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/japanese.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/korean.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/norwegian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/polish.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/portuguese-br.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/portuguese.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/romanian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/russian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/serbian-latin.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/simp-chinese.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/slovak.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/slovenian.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/spanish.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/swedish.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/trad-chinese.nsh file | annotate | diff | comparison | revisions
src/win32/nsis/translations/vietnamese.nsh file | annotate | diff | comparison | revisions
src/win32/resource.h file | annotate | diff | comparison | revisions
src/win32/untar.c file | annotate | diff | comparison | revisions
src/win32/untar.h file | annotate | diff | comparison | revisions
src/win32/wgaimerror.h file | annotate | diff | comparison | revisions
src/win32/win32dep.c file | annotate | diff | comparison | revisions
src/win32/win32dep.h file | annotate | diff | comparison | revisions
src/win32/wspell.c file | annotate | diff | comparison | revisions
src/win32/wspell.h file | annotate | diff | comparison | revisions
src/win_gaim.c file | annotate | diff | comparison | revisions
src/xmlnode.c file | annotate | diff | comparison | revisions
src/xmlnode.h file | annotate | diff | comparison | revisions
--- a/.cvsignore	Mon Apr 16 00:43:53 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-config.h
-libtool
-config.status
-intl
-ABOUT-NLS
-compile
-config.guess
-config.sub
-Doxyfile
-ltconfig
-ltmain.sh
-install-sh
-missing
-aclocal.m4
-configure
-config.h.in
-stamp-h.in
-Makefile.in
-config.log
-config.cache
-Makefile
-stamp-h
-gaim.spec
-depcomp
-stamp-h1
-autom4te*.cache
-configure.2.1x
-confdefs.h
-*.swp
-win32-install-dir
-.temp-gettextize
-gaim.pc
-*.apspec
--- a/.todo	Mon Apr 16 00:43:53 2007 +0000
+++ b/.todo	Sun May 20 06:19:49 2007 +0000
@@ -2,24 +2,6 @@
     <title>
         Gaim TODO List
     </title>
-    <note priority="low" time="1036030063" done="1092939968">
-        i18n/portability stuff
-        <comment>
-            makes more sense to put this in with specific items at this point
-        </comment>
-        <note priority="medium" time="1036028041" done="0">
-            sounds/Makefile needs to use host CC, not target (that's the only part that seems broken for cross-compiling --Disconnect)
-        </note>
-        <note priority="low" time="1035996506" done="1057532505">
-            i18n: icq i18n
-            <comment>
-                I consider this as good as it will get.  utf8 works well.
-            </comment>
-        </note>
-        <note priority="low" time="1035996519" done="0">
-            i18n: info dialog
-        </note>
-    </note>
     <note priority="high" time="1036029816">
         UI stuff
         <note priority="high" time="1053306672" done="1089237474">
@@ -118,12 +100,6 @@
     </note>
     <note priority="high" time="1036029923">
         Prefs stuff
-        <note priority="high" time="1036027042" done="1063207482">
-            check to make sure gaimrc properly unescapes things like a " in a password as the .gaimrc file is read in. (reports indicate this may be a problem, esp. for \ and / )
-            <comment>
-                i think this is fixed by the new prefs
-            </comment>
-        </note>
         <note priority="veryhigh" time="1129562765">
             make sure prefs save
         </note>
@@ -142,12 +118,6 @@
     </note>
     <note priority="high" time="1036030165">
         Core stuff
-        <note priority="medium" time="1036038372" done="1129562842">
-            remember previous state better. both away, and allow start to invisible.
-            <comment>
-                status rewrite
-            </comment>
-        </note>
         <note priority="low" time="1036038499" done="1129562864">
             encryption and hash stuff currently in gaim consolidated to an api
             <comment>
@@ -228,12 +198,6 @@
     </note>
     <note priority="medium" time="1036030336">
         In General (i don't know where this should be)
-        <note priority="veryhigh" time="1037658028" done="1092939805">
-            internal sounds not working now (is this fixed?)
-            <comment>
-                libao fixed this, there is no "internal" option
-            </comment>
-        </note>
         <note priority="medium" time="1036039588" done="1063208189">
             person support
             <comment>
@@ -303,24 +267,12 @@
     </note>
     <note priority="verylow" time="1036026433">
         DISCUSSION: entries here are things i'm not sure are desirable or doable.
-        <note priority="medium" time="1043803233" done="1089237940">
-            make blist.xml and/or .gaim as configureable as .gaimrc
-            <comment>
-                .gaim is now configurable at run time
-            </comment>
-        </note>
         <note priority="low" time="1036026529" done="1089237962">
             do we really need some of the preferences? (Ignore TIK messages. Does anyone use that method of retrieving Away messages anymore? no, but it is small and it would be a piece of history lost ;-))
             <comment>
                 prefsslash04
             </comment>
         </note>
-        <note priority="verylow" time="1036026575" done="1063208296">
-            timestamp on debug messages?
-            <comment>
-                done some time ago
-            </comment>
-        </note>
         <note priority="low" time="1036026508">
             "console beep" sound option should use different frequency beeps for different events, or at least give some way to allow this behavior.
         </note>
--- a/AUTHORS	Mon Apr 16 00:43:53 2007 +0000
+++ b/AUTHORS	Sun May 20 06:19:49 2007 +0000
@@ -1,8 +1,10 @@
 gaim - the Pimpin' Penguin IM Clone that's Good for the Soul
 ============================================================
 
-We've got an IRC room now too, #gaim on irc.freenode.net (#wingaim for Windows
-users). Come check us out.
+For a complete list of all contributors, see the COPYRIGHT file.
+
+We've got an IRC room now too, #gaim on irc.freenode.net (#wingaim for
+Windows users). Come check us out.
 
 Current Developers:
 ------------------
@@ -17,23 +19,24 @@
 
 Daniel 'datallah' Atallah
 Ethan 'Paco-Paco' Blanton - Developer
-Herman Bloggs - Win32 Port
+Thomas Butter - Developer
+Sadrul Habib Chowdhury - Developer
 Mark 'KingAnt' Doliner - Developer
 Christian 'ChipX86' Hammond - Developer & Webmaster
 Gary 'grim' Kramlich - Developer
 Richard 'rlaager' Laager
 Christopher 'siege' O'Brien - Developer
+Bartosz Oler - Developer
 Etan 'deryni' Reisner - Developer
 Tim 'marv' Ringenbach - Developer
 Luke 'LSchiere' Schierer - Support
+Evan Schoenberg - Developer
 Stu 'nosnilmot' Tomlinson - Developer
 Nathan 'faceprint' Walp - Developer
 
 Crazy Patch Writers:
---------------------
-
+-------------------
 Ka-Hing 'javabsp' Cheung
-Sadrul Habib Chowdhury
 Felipe 'shx' Contreras
 Decklin Foster
 Peter 'Bleeter' Lawler
@@ -42,7 +45,8 @@
 Kevin 'SimGuy' Stange
 
 Retired Developers:
---------
+------------------
+Herman Bloggs - Win32 Port
 Jim Duchek <jim@linuxpimps.com> - maintainer
 Rob Flynn <gaim@robflynn.com> - maintainer
 Adam Fritzler - libfaim maintainer
@@ -50,3 +54,74 @@
 Jim Seymour - Jabber developer
 Mark Spencer <markster@marko.net> - original author
 Eric Warmenhoven <eric@warmenhoven.org> - lead developer
+
+Other Contributions:
+-------------------
+Much thanks to Evan Martin <martine@cs.washington.edu> for writing 
+GtkSpell <http://gtkspell.sourceforge.net> responsible for the 
+"Highlight misspelled words" feature and for gtk-nativewin
+<http://bunny.darktech.org/cvs/gtk-nativewin/> the default GTK+-2.0
+engine used in our win32 port.
+
+** LOGO DESIGNED BY: Naru Sundar **
+
+Peter Teichiman <peter@helixcode.com>
+Larry Ewing 
+Jeramey A. Crawford
+	Thanks to these boys.  Peter and Larry managed to stomp
+	out a large list of Mem Leaks.  Jeramey found the remaining
+	onees and pointed me to those.  Props to the boys at 
+	Helix Code.  Thanks guys.
+
+Nathan Walp
+	A healthy amount of patches for the Jabber plugin
+
+Neil Sanchala
+	Wrote most of the Zephyr plugin
+
+Arkadiusz Miskiewicz
+	Wrote the Gadu-Gadu plugin
+	
+David Prater    <IM: dRaven43>          draven@tcsx.net   
+	Log and Colour Button Images
+
+Sébastien Carpe <IM: Seb Carpe>
+	Base HTTP Proxy Support
+
+Ari Pollak      <IM: Ari Pollak>	compwiz.dhs.org
+	Resize conversation window patch   
+
+Decklin Foster
+	Many GUI improvements, other nifty additions and fixes
+
+David <IM: CrazyDavy>
+	The neato-bigger text box
+
+S D Erle
+	Writing a cool perl script to translate WinAIM lists to gaim
+
+BMiller
+	A good collection of stuff. %n for away messages, import winaim
+	lists, pic/text/pic+text for buttons, among others
+
+Lance Rocker
+	Improved HTML formatting in logs, plus lots of debugging on *BSD.
+
+ergofobe:
+	GNOME Url handler patch
+
+Justin M. Ward <justin@yossman.net>:
+	Alphabetical Away Messages patch
+
+G. Sumner Hayes <IM: SumnerFool> Security Patches
+
+Brian Ryner for a little make file patch :)
+
+Ryan C. Gordon - I still think you look like Silent Bob.
+
+Elliot Tobin <elliot@bha.udel.edu>
+
+Thanks to Jeroen van der Vegt for the initial smiley plugin and images.
+
+The OpenQ Team
+	Wrote the QQ plugin (see AUTHORS in the qq directory)
--- a/COPYRIGHT	Mon Apr 16 00:43:53 2007 +0000
+++ b/COPYRIGHT	Sun May 20 06:19:49 2007 +0000
@@ -1,27 +1,36 @@
 Gaim
-Copyright (C) 1998-2005 by the following:
+Copyright (C) 1998-2006 by the following:
 
 If you have contributed to Gaim, you deserve to be on this list.
 Contact us (see: AUTHORS) and we'll add you.
 
+Saleem Abdulrasool
 Dave Ahlswede
 Manuel Amador
 Matt Amato
+Geoffrey Antos
 Daniel Atallah
 Paul Aurich
 Patrick Aussems
+Anibal Avelar
+Ali Albazaz
 Alex Badea
 John Bailey
+Chris Banal
 Luca Barbato
 Levi Bard
+Ryan Barrett
 Kevin Barry
+Lukas Barth
 Derek Battams
 Martin Bayard
 Curtis Beattie
 Dave Bell
 Igor Belyi
 Brian Bernas
+Paul Betts
 Jonas Birmé
+George-Cristian Bîrzan
 Eric Blade
 Ethan Blanton
 Joshua Blanton
@@ -31,22 +40,30 @@
 Jason Boerner
 Graham Booker
 Paolo Borelli
+Julien Bossart
 Craig Boston
 Chris Boyle
 Derrick J Brashear
 Matt Brenneke
 Jeremy Brooks
+Jonathan Brossard
 Philip Brown
 Sean Burke
 Thomas Butter
+Trevor Caira
 Andrea Canciani
+Damien Carbery
 Michael Carlson
+Keegan Carruthers-Smith
 Steve Cavilia
 Julien Cegarra
 Cerulean Studios, LLC
 Jonathan Champ
+Christophe Chapuis
+Patrick Cheung
 Ka-Hing Cheung
 Sadrul Habib Chowdhury
+Brian Chu
 Arturo Cisneros, Jr.
 Vincas Ciziunas
 Jonathan Clark
@@ -54,6 +71,8 @@
 Eoin Coffey
 Jason Cohen
 Todd Cohen
+Jono Cole
+Lorenzo Colitti
 Nathan Conrad
 Felipe Contreras
 Alex Converse
@@ -62,7 +81,10 @@
 Adam Cowell
 Palmer Cox
 Jeramey Crawford
+Michael Culbertson
 Martijn Dekker
+Philip Derrin
+Taso N. Devetzis
 Balwinder Singh Dheeman
 Andrew Dieffenbach
 Finlay Dobbie
@@ -78,6 +100,7 @@
 Nelson Elhage
 Ignacio J. Elia
 Brian Enigma
+Mattias Eriksson
 Stefan Esser
 Steffen Eschenbacher
 Marc Etcheverry
@@ -85,6 +108,7 @@
 Gábor Farkas
 Jesse Farmer
 Gavan Fantom (gavan)
+Leonardo Fernandes
 David Fiander
 Rob Flynn <gaim@robflynn.com>
 Rob Foehl (rwf)
@@ -97,10 +121,14 @@
 Adam Fritzler
 Max G.
 François Gagné
+Andrew Gaul
 Evgueni V. Gavrilov
 Ignacy Gawedzki
+Georgi Georgiev
+Ike Gingerich
 Gustavo Giráldez
 Richard Gobeille
+Ian Goldberg
 Michael Golden
 Charlie Gordon
 Ryan C. Gordon
@@ -117,22 +145,35 @@
 Mike Heffner
 Benjamin Herrenschmidt
 Fernando Herrera
+hjheins
+Hil
 Casey Ho
 Iain Holmes
 Joshua Honeycutt
 Nigel Horne
 Juanjo Molinero Horno
+Nathanael Hoyle
+Greg Hudson
 Magnus Hult
 Karsten Huneycutt
+Kevin Hunter
 Rian Hunter
 Thomas Huriaux
+Vitaliy Ischenko
+Scott Jackson
+Hans Petter Jansson
 Henry Jen
 Benjamin Kahn
+Anders Kaseorg
 Praveen Karadakal
 John Kelm
+Jochen Kemnade
 Akuke Kok
+Konstantin Korikov
 Cole Kowalski
 Gary Kramlich
+Jan Kratochvil
+Andrej Krivulčík
 Patrik Kullman
 Tuomas Kuosmanen
 Tero Kuusela
@@ -156,6 +197,7 @@
 Uli Luckas
 Matthew Luckie
 Mike Lundy
+Jason Lynch
 Lucio Maciel
 Brian Macke
 Paolo Maggi
@@ -170,16 +212,20 @@
 Torrey McMahon
 Robert McQueen
 Robert Mibus
+Lars T. Mikkelsen
 Benjamin Miller
 Kevin Miller
 Paul Miller
 Arkadiusz Miskiewicz
 Andrew Molloy
+Benjamin Moody
 Tim Mooney
 Sergio Moretto
 Christian Muise
 Richard Nelson
+Dennis Nezic
 Matthew A. Nicholson
+Henning Norén
 Szilard Novaki
 Novell
 Padraig O'Briain
@@ -188,6 +234,7 @@
 Ruediger Oertel
 Gudmundur Bjarni Olafsson
 Bartosz Oler
+Shawn Outman
 Nathan Owens (pianocomp81)
 John Oyler
 Matt Pandina
@@ -196,24 +243,31 @@
 Havoc Pennington
 Ted Percival
 Eduardo Pérez
+Celso Pinto
 Joao Luís Marques Pinto
 Aleksander Piotrowski
 Julien Pivotto
 Ari Pollak
 Robey Pointer
+Stephen Pope
 Nathan Poznick
+Jory A. Pratt
 Brent Priddy
 Federicco Mena Quintero
 Yosef Radchenko
 David Raeman
+R. Ramkumar
+Mart Raudsepp
 Etan Reisner
 Kristian Rietveld
 Pekka Riikonen
 Tim Ringenbach
 Dennis Ristuccia
+Lee Roach
 Rhett Robinson
 Luciano Miguel Ferreira Rocha
 Andrew Rodland
+Miguel Rodríguez (migrax)
 Jason Roth
 Jean-Francois Roy
 Sam S.
@@ -222,12 +276,15 @@
 Tom Samstag
 Neil Sanchala
 Laurent Sansonetti
+Andrew Sayman
 Alceste Scalas
 Carsten Schaar
+Matteo Settenvini
 Colin Seymour
 Luke Schierer
 Ralph Schmieder
 David Schmitt
+Mark Schneider
 Evan Schoenberg
 Federico Schwindt
 Torrey Searle
@@ -241,6 +298,7 @@
 John Silvestri
 Craig Slusher
 Alex Smith
+Brad Smith
 Malcolm Smith
 David Smock
 Phil Snowberger
@@ -248,6 +306,7 @@
 Sony Computer Entertainment America, Inc.
 Mark Spencer
 Lex Spoon
+Chris Stafford
 Kevin Stange
 Richard Stellingwerff
 Charlie Stockman
@@ -274,16 +333,21 @@
 Brad Turcotte
 Junichi Uekawa
 István Váradi
+Martijn van Beers
 Philip Van Hoof
 Kristof Vansant
 James Vega
 David Vermeille
 Sid Vicious
 Bjoern Voigt
+Wan Hing Wah
 Philip Walford
 Nathan Walp
+Jonty Wareing
 Eric Warmenhoven
 Adam J. Warrington
+Denis Washington
+Zsombor Welker
 Andrew Wellington
 Adam Wendt
 Dave West
@@ -293,9 +357,12 @@
 Dan Willemsen
 Jason Willis
 Matt Wilson
+Dan Winship
+Scott Wolchok
 Pui Lam Wong
 Justin Wood
 Ximian
+Ma Xuan
 Jared Yanovich
 Timmy Yee
 Nickolai Zeldovich
--- a/ChangeLog	Mon Apr 16 00:43:53 2007 +0000
+++ b/ChangeLog	Sun May 20 06:19:49 2007 +0000
@@ -1,6 +1,17 @@
 Gaim: The Pimpin' Penguin IM Client that's good for the soul!
 
 version 2.0.0:
+	Build Changes:
+	* With the Core/UI split completed, it is now possible to build Gaim
+	  without any UIs, creating a libgaim library upon which other UIs
+	  may be constructed
+	* A new ncurses-based console UI called gaim-text is now available
+	  (Sadrul Habib Chowdhury, Google Summer of Code)
+	* Reorganized the source tree to split apart the code for the UI
+	  changes and libgaim targets
+	* libxml2 is now required.  We switched from gmarkup to libxml2 for
+	  more correct XML parsing.
+
 	Status System:
 	* The code dealing with buddy and account status, away messages,
 	  away states, online/offline, etc has been completely rewritten.
@@ -12,6 +23,8 @@
 	  becomes idle, load the "Buddy State Notification" plugin
 
 	Buddy List:
+	* Performance when manipulating and displaying the buddy list has
+	  been significantly improved (Aaron Sheldon, Google Summer of Code)
 	* Buddy icons are now shown in tooltips (Felipe Contreras)
 	* Tooltips now contain additional information about a "Person" that
 	  contains multiple online buddies
@@ -20,6 +33,15 @@
 	* If Gaim is exited with the buddy list hidden in the docklet, it
 	  will remain hidden when Gaim is started again (Scott Shedden)
 	* Improved buddy list searching with CTRL+F
+	* Ability to set a buddy icon for all of your accounts at once via
+	  the buddy list (You can still set per-account icons via the
+	  account editor)
+	* The space wasted by the group expanders has been eliminated and
+	  the expander setting in .gtkrc-2.0 is no longer needed
+	* Authorization requests don't popup new dialogs any more. They are
+	  displayed at the bottom of the buddy list instead.
+	* New mail notifications don't popup new dialogs any more. The are
+	  displayed at the top of the buddylist instead.
 
 	Conversations and Chats:
 	* Timestamps honor the locale.  To use the traditional style,
@@ -44,19 +66,33 @@
 	  IM/Send File/Get info/ignore the user
 	* Added tab management options to the tab right-click menu (Sadrul Habib
 	  Chowdhury)
-	* Brand new message queueing system (Casey Harkins)
+	* Brand new message queueing system.  Sounds are played when a
+	  message is queued rather than when the message is dequeued
+	  (Casey Harkins)
 	* Ability to find the last message from a user in a chat (Levi Bard
 	  and Sadrul Habib Chowdhury)
+	* Formatting is preserved across messages
+	  (There are known issues with pasting formatted text.  Either use "Paste
+	   as Plain Text", hit Ctrl-R after pasting, or use the Clear Formatting
+	   button on the toolbar.)
+	* Performance while joining large chat rooms has been significantly
+	  improved (Aaron Sheldon, Google Summer of Code)
 
 	Sounds:
 	* Beautiful new default sounds (Brad Turcotte)
-	* Use libao for playing sounds via NAS instead of accessing NAS directly
+	* Use GStreamer for playing sounds, instead of libao
 	* A volume control in the preferences (Casey Harkins)
 
 	Log Viewer:
 	* Log viewer aggregates logs from the same "Person"
 	* When opening the log viewer, show the most recent log by default
 	  (Peter McCurdy)
+	* Logs are now saved with the current timezone, which is displayed
+	  in the log viewer
+	* Text logs are linkified, so URLs are clickable
+	* The old logger now caches file offsets, so opening the log viewer
+	  for buddies with old logs should be much faster now if you have large
+	  log files (except the first time for a log, when the cache is built)
 
 	Plugins:
 	* Plugins are now accessed through a separate dialog from the Tools
@@ -85,6 +121,17 @@
 	* The functionality of the auto-reconnect plugin has been
 	  moved into the Gaim core, and the plugin itself has been
 	  removed.
+	* 'Highlight when nick said' option added to Message Notification
+	  plugin.
+	* The system tray icon is now transparent (Dan Winship)
+	* New Log Reader plugin that can read and display logs from Adium,
+	  MSN Messenger, and Trillian in the log viewer
+	* New Contact Availability plugin that attempts to predict the
+	  times when people in your buddylist will most likely respond
+	  to you, based on times in the past when they have responded
+	  (Geoffrey Foster, Google Summer of Code)
+	* A few new plugins: Autoaccept, Autoreply, Buddy Notes, New Line, Offline
+	  Message Emulation, Conversation Colors and Markerline
 
 	MSN Features:
 	* Custom smiley receiving support (Irving Cordova & Francesco Fracassi)
@@ -104,8 +151,10 @@
 	AIM/ICQ Features:
 	* ICQ file transfer support with newer ICQ clients (Jonathan Clark,
 	  Google Summer of Code)
-	* Many overall improvements to OSCAR file transfers (Jonathan Clark,
-	  Google Summer of Code)
+	* Many overall improvements to AIM and ICQ file transfers (Jonathan
+	  Clark, Google Summer of Code)
+	* Support for pausing and resuming AIM and ICQ file transfers
+	  (Graham Booker)
 	* Ability to set ICQ "require authorization" and "web aware"
 	  setting (Ettore Simone)
 	* ICQ encoding fix for offline buddies (Ilya Konstantinov)
@@ -116,6 +165,7 @@
 	  channel or change your nick
 	* Added /nickserv, /memoserv, /chanserv and /operserv
 	  commands (Joao Luís Marques Pinto)
+	* Added CTCP VERSION via /version (Andrej Krivulčík)
 
 	Jabber Features:
 	* Support for SRV lookups
@@ -132,9 +182,13 @@
 	* Bonjour (Rendezvous) protocol support (Juanjo Molinero Horno, Google
 	  Summer of Code)
 	* Updated Gadu-Gadu protocol support (Bartosz Oler, Google Summer of
-	  Code)
+	  Code).  This requires the libgadu library.  See
+	  http://gaim.sourceforge.net/faq2.php#libgadu for more information.
 	* SIP/SIMPLE support (Thomas Butter, Google Summer of Code)
 	* Sametime protocol support
+	  Requires the meanwhile library: http://meanwhile.sourceforge.net
+	* QQ protocol support (Mark Huetsch, Google Summer of Code)
+	* Removed support for the Napster and TOC protocols
 
 	Other Noteworthy Changes:
 	* UPnP and NAT traversal support (Adam J. Warrington, Google Summer of
@@ -143,8 +197,6 @@
 	  better at lower resolutions (Sadrul Habib Chowdhury)
 	* New "find buddy" results dialog (Alex Converse)
 	* People using input methods can now use Enter again
-	* GNOME users can open received files by clicking on "Open" in the
-	  file transfer window
 	* Mouse-over hyperlink coloring is now themeable
 	* Buddy Pounces now have a proper management window. (Kevin Stange)
 	* Buddy icons maintain aspect ratio when resized
@@ -157,7 +209,13 @@
 	  The spaces (and now backslashes) must be backslash-escaped.
 	  (Sadrul Habib Chowdhury)
 	* New e-mail notices are now grouped into one dialog.
-	  (Sadrul Habib Chowdhury)
+	  (Sadrul Habib Chowdhury, Chris Stafford)
+	* "Open" in the File Transfer window integrates with GNOME, KDE, and
+	  Windows and falls back to the browser in other environments.
+	* On Mac OS X, the keyboard/mouse idle time pref now uses system idle
+	  time instead of X11 idle time (Michael Culbertson)
+	* Autocomplete in the buddy pounce dialog (Sadrul Habib Chowdhury)
+	* Non-blocking socket I/O is used in most protocol plugins
 
 	Preference Changes:
 	* Preferences have been substantially reorganized and cleaned up
@@ -652,7 +710,7 @@
 	* Removed "Icons on tabs", default to yes
 	* Removed "Sounds when you log in", default to no
 	* Removed "Seconds before resending autoresponse", default to 600
-          seconds
+	  seconds
 	* Removed "Send autoresponse in active conversations", default to no
 	* Removed "Show people joining in window", default to yes
 	* Removed "Show people leaving in window", default to yes
@@ -920,7 +978,7 @@
 	  list as well.
 	* Events in a conversation (user logged in, logged out, window closed,
 	  etc.) now grey the tab.
-	* Various bug fixes (larne from irc, Tim Ringenbach, Bjoern 
+	* Various bug fixes (larne from irc, Tim Ringenbach, Bjoern
 	  Voigt, Paul A (darkrain))
 
 version 0.66 (07/18/2003):
@@ -982,10 +1040,10 @@
 	* Napster protocol updates (Thanks Auke Kok).
 
 version 0.62 (04/23/2003):
-	* Keyboard shortcuts in the buddy list work again (Thanks Joe 
+	* Keyboard shortcuts in the buddy list work again (Thanks Joe
 	  Clarke).
 	* Support for Jabber XHTML messages
-	* Ability to re-request authorization from ICQ and Jabber users by right 
+	* Ability to re-request authorization from ICQ and Jabber users by right
 	  clicking on them in your buddy list.
 	* Improved Zephyr internationalization.
 	* Bug causing 'Hide on Send' windows to be lost forever fixed.
@@ -1001,7 +1059,7 @@
 	* Re-implemented the logout icons.
 	* New icons for "away" and "aol" (Thanks, Moses Lei)
 
-version 0.60 (04/04/2003): 
+version 0.60 (04/04/2003):
 	Core:
 	* Auto-loading protocol plugins.
 	* Plugins dialog and perl script menu merged into preferences.
@@ -1013,7 +1071,7 @@
 	* Added support for automake 1.6.
 	* aim:// URI's supported with gaim-remote command.
 	* Quit Gaim remotely with gaim-remote. (Thanks, John Silvestri)
-	* Added rudimentary support for X11R6 session management. (Thanks, 
+	* Added rudimentary support for X11R6 session management. (Thanks,
 	  Robert McQueen)
 	* Conversation backend and UI are now separated. (Thanks,
 	  Christian Hammond)
@@ -1021,11 +1079,11 @@
 	  Lichtmaier)
 	* As a side effect of the above: IPv6 support. Tested only with IRC
 	  (you can receive ipv6 chat requests from irssi!).
-	
+
 	Plugins:
-	* Tray icon plugin--replaces the old GNOME applet. You'll need 
-	  the panel Notification Area applet (aka system-tray-applet) 
-	  for GNOME 2, or the Kicker for KDE 3.1. (Thanks, Robert 
+	* Tray icon plugin--replaces the old GNOME applet. You'll need
+	  the panel Notification Area applet (aka system-tray-applet)
+	  for GNOME 2, or the Kicker for KDE 3.1. (Thanks, Robert
 	  McQueen, Nicolás Lichtmaier, Kristian Rietveld, Ari Pollak &
 	  Patrick Aussems)
 	* Added GAIM::remove_event_handler and made set_info short
@@ -1040,9 +1098,9 @@
 	AIM/ICQ:
 	* TOC no longer compiles statically by default--use OSCAR.
 	* ICQ plugin no longer gets built--use OSCAR.
-	* Server-stored buddy lists for ICQ with full support for 
+	* Server-stored buddy lists for ICQ with full support for
 	  authorization (Thanks, Mark Doliner)
-	* File send/receive support for Aim over Oscar (Thanks, William T. 
+	* File send/receive support for Aim over Oscar (Thanks, William T.
 	  Mahan and Mark Doliner)
 	* Non-direct connect typing notification for AIM over OSCAR.
 	  (Thanks, Mark Doliner)
@@ -1055,19 +1113,19 @@
 	* Ability to add screenname@mac.com people to AIM buddy lists.
 	  (Thanks, Graham Booker)
 	* Ability to change ICQ password. (Thanks, Mark Doliner)
-	* Option to have AIM notify you if you have 
+	* Option to have AIM notify you if you have
 	  unread mail. (Thanks, Mark Doliner)
 	* Parse URL messages, Contact Sending and Pager Messages
 	  in ICQ. (Thanks, Mark Doliner)
 	* use snprintf instead of sprintf. (Thanks, William T. Mahan)
-	* Fixed crashbug on empty rvous requests. (Thanks Brandon Scott 
+	* Fixed crashbug on empty rvous requests. (Thanks Brandon Scott
 	  (Xeon) for pointing this out, and Matt Pandina for the patch)
 	* Nice Oscar changes--mostly internal. (Thanks, Mark Doliner)
 
 	IRC:
 	* Added more IRC slash commands -- /W, /VERSION, /MODE, /CTCP stuff,
 	  -- and other cool IRC enhancments. (Thanks, Jonas Birmé)
-	* IRC's /topic with no argument displays the current topic (Thanks, 
+	* IRC's /topic with no argument displays the current topic (Thanks,
 	  Mark Doliner)
 	* DCC File Receive support for IRC.
 	* Optional password on IRC accounts. (Thanks, Christian Hammond)
@@ -1079,21 +1137,21 @@
 	* Jabber roster updated on group renames.
 	* Fixed a possible segfault when signing off Jabber. (Thanks,
 	  Craig Boston)
-	* Improved typing notification support for Jabber and 
+	* Improved typing notification support for Jabber and
 	  Yahoo! (Thanks, Nathan Walp)
 	* File receive support for Jabber. (Thanks, Nathan Walp)
 
 	MSN:
 	* MSN users are notified when the other party closes the conversation
 	  window. (Thanks, Christian Hammond)
- 	* File receive support for MSN. (Thanks, Christian Hammond)
+	* File receive support for MSN. (Thanks, Christian Hammond)
 
 	Internationalization:
-	* Now using libiconv for better i18n support (Thanks, Junichi 
+	* Now using libiconv for better i18n support (Thanks, Junichi
 	  Uekawa)
 	* Lots of i18n fixes (Thanks Matt Wilson, Ethan Blanton, A Lee)
 	* Correct i18n handling for many parts of AIM/ICQ, including
-	  instant messages, away messages, and profiles (Thanks, 
+	  instant messages, away messages, and profiles (Thanks,
 	  Ethan Blanton)
 	* Improved MSN internationalization (Thanks, A Lee)
 
@@ -1108,7 +1166,7 @@
 	* Fix first message in tab not displaying bug (Thanks, Etan Reisner)
 	* Changed some default options
 	* Updated desktop and window icons (Thanks, Robert McQueen)
-	* Switch the .desktop file to the new KDE/GNOME common vfolder 
+	* Switch the .desktop file to the new KDE/GNOME common vfolder
 	  format (Thanks, Robert McQueen)
 	* Removed all deprecated GTK calls.  Now 100% GTK 2. (Thanks Nathan
 	  Walp, Christian Hammond, Ari Pollak, Ethan Blanton, Robert McQueen)
@@ -1117,7 +1175,7 @@
 	  Robert McQueen)
 	* Can get info for ICQ and Jabber users from the "Edit
 	  Buddies" tab (Thanks, Brian Bernas)
-	* Code cleanups and fixes (Thanks, Federico Mena Quintero and 
+	* Code cleanups and fixes (Thanks, Federico Mena Quintero and
 	  Ka-Hing Cheung)
 	* Word-wrapping on mail notification text (Thanks, Andrew Molloy)
 	* Generic File Transfer PRPL interface (Thanks, Christian Hammond)
@@ -1127,10 +1185,10 @@
 
 version 0.59.9 (03/01/2003):
 	* Updated zh_TW.po file (Thanks breeze833)
-	* Fix an oscar bug that caused some messages from 
+	* Fix an oscar bug that caused some messages from
 	  AOL 8.0 to be dropped (Thanks Mark Doliner)
 	* Changed "openprojects" to "freenode" in irc.c
-	* Fixed charset conversion on systems which use a BOM for UCS-4 
+	* Fixed charset conversion on systems which use a BOM for UCS-4
 	  (Thanks, Alfredo Pen~a, Ethan Blanton)
 	* Fixed a typo in the man page (Thanks Eric S. Raymond)
 
@@ -1175,7 +1233,7 @@
 	* Changed "color" binding to Ctrl-K.
 	* Unaliaising a person in the "Online" tab will show up
 	  in the "Edit" tab as well (Thanks, Jason Willis)
-	* Internationalization fixes, esp. with UTF-8 locales 
+	* Internationalization fixes, esp. with UTF-8 locales
 	  (Thanks Matt Wilson and Ethan Blanton)
 
 version 0.59.2 (09/09/2002):
@@ -1212,9 +1270,9 @@
 	  Robert McQueen)
 	* Now using libiconv for better i18n support (Thanks Junichi
 	  Uekawa)
-	* Will work with Perl 5.8 (thanks, Timothy Lee and Dan 
+	* Will work with Perl 5.8 (thanks, Timothy Lee and Dan
 	  Colascione)
-	* Fix for HTTP proxies (thanks, Ethan Blanton)	
+	* Fix for HTTP proxies (thanks, Ethan Blanton)
 	* Read proxy environment variables. (thanks, Christian Hammond)
 	* Use the pretty gaim.png for our menu entry.
 	* Added support for gettext 0.11.x.
@@ -1238,7 +1296,7 @@
 	* Perl scripts can play Gaim sounds (thanks Andrew Rodland)
 	* Internal sounds can be played by commands (thanks Lex Spoon)
 	* Auto-login item in applet menu (thanks Chris Boyle)
-	* Fixed MSN "Unkown Error Code", "Already there", and 
+	* Fixed MSN "Unkown Error Code", "Already there", and
 	  "Already in opposite list" errors
 	* Changed "Play sound" button to "Mute" button
 	* You can now have "reserved" chars in IM and proxy passwords
@@ -1255,7 +1313,7 @@
 	  entirely
 	* Gaim can now handle messages from Mac ICQ and Miranda ICQ
 	  (Thanks, Mark Doliner)
-	* Added Mozilla to browser options and changed KFM to 
+	* Added Mozilla to browser options and changed KFM to
 	  Konqueror.
 	* Can now set the server and port for MSN and Napster
 	* MSN Internationalization (Thanks Felipe Contreras and
@@ -1266,7 +1324,7 @@
 version 0.58 (05/13/2002):
 	* Better applet transparency
 	* Option to raise buddy list on signons/signoffs
-	* Formatting of incoming MSN messages	
+	* Formatting of incoming MSN messages
 	* Get Info from menu multiple-account-aware (thanks
 	  Brian Bernas)
 	* Hide and unhide functions for the filectl plugin.
@@ -1316,7 +1374,7 @@
 	* Fixed MSN privacy settings
 	* Group deletion fix (Thanks Mark Doliner)
 	* Alias/Group syncronization for Jabber (Thanks JSeymour)
- 	* Fixed broken signal handling in gdm-started GNOME sessions 
+	* Fixed broken signal handling in gdm-started GNOME sessions
 	  (Thanks Jim Seymour, Vann, Robert McQueen)
 	* Oscar group syncronization (Thanks, Mark Doliner)
 	* ICQ Authorization via Oscar (Thanks, Mark Doliner)
@@ -1324,18 +1382,18 @@
 version 0.55 (03/29/2002):
 	* Jabber improvements (Thanks Jim Seymour)
 	* Various sound cleanups (Thanks Robert McQueen)
-	* Login process shown in single window (Thanks Michael 
+	* Login process shown in single window (Thanks Michael
 	  Golden)
 	* Can reorder your accounts in the account editor (Thanks
 	  Luke Schierer)
 	* Shows "mobile" icon for Oscar buddies using mobile
 	  devices (Thanks Mark Doliner)
 	* Fixed bug in MSN smilies that crashed PPC (and other?) platforms
-	* HTTP Proxy settings now HTTP compliant (Thanks Robert McQueen)	
+	* HTTP Proxy settings now HTTP compliant (Thanks Robert McQueen)
 	* Speling corections (Thanks Tero Kuusela)
 	* Oscar list icon fixes (Thanks Mark Doliner)
 	* Oscar idle times work again (Thanks Mark Doliner)
-	* Protocol icons on Edit Buddies tab (Thanks Christian Hammond)	
+	* Protocol icons on Edit Buddies tab (Thanks Christian Hammond)
 
 version 0.54 (03/14/2002):
 	* Compiles without GdkPixbuf again
@@ -1346,8 +1404,8 @@
 	* Option to globally disable Buddy Icon animation (Thanks
 	  Luke Schierer)
 	* Numerous bugfixes
-	* Yahoo! will tell you when your buddies are playing Yahoo! 
- 	  games and give you the ability to join them
+	* Yahoo! will tell you when your buddies are playing Yahoo!
+	  games and give you the ability to join them
 	* Yahoo! can receive offline messages
 	* IRC can do DCC chat.
 	* IRC will convert HTML formatting to mIRC formatting.
@@ -1450,7 +1508,7 @@
 	* Better applet icon drawing (thanks to Ari Pollak)
 	* An extraordinary number of bug fixes
 	* Ability to stop animation on buddy icons, restart animation,
-	  hide certain buddy icons, and save people's buddy icons, all 
+	  hide certain buddy icons, and save people's buddy icons, all
 	  through a right-click menu
 	* Event handlers in perl passed arguments as elements of
 	  an array rather than all concatenated as a string, making
@@ -1461,7 +1519,7 @@
 	* Add buddy dialog now lets you select which protocol
 	  to add the buddy to
 	* Pressing 'signon' on the first screen for accounts that
-	  do not require passwords no longer incorrectly displays 
+	  do not require passwords no longer incorrectly displays
 	  an error message.
 
 version 0.45 (10/04/2001):
@@ -1690,7 +1748,7 @@
 		MSN (plugins/msn)
 
 version 0.11.0-pre2 (12/04/2000):
-	* Fixed a segfault with a bad util.c 
+	* Fixed a segfault with a bad util.c
 
 version 0.11.0-pre1 (12/03/2000):
 	* Multiple connections
@@ -1732,7 +1790,7 @@
 	* A third conversation window display preference.
 	* Better support for things like Sawfish
 
-version 0.10.0 (09/11/2000): 
+version 0.10.0 (09/11/2000):
 	* New Smiley Faces and Pixmaps added.
 	* Smiley faces now properly wrap in the conversation windows.
 	* Smiley dialog
@@ -1746,7 +1804,7 @@
 	* Redesigned preferences dialog
 	* Redesigned conversation dialog
 	* Removed the Lag-O-Meter (Lag-O-Meter is now a plugin)
-	* Socks 4/5 Proxy works
+	* SOCKS 4a/5 proxy works
 	* Buddy Pounces are now saved in .gaimrc
 	* Buddy Chats are now saved in .gaimrc
 	* Ability to merge gaim, aim2, aim4 buddylists. Thanks again bmiller!
@@ -1754,8 +1812,8 @@
 	  as. For example, if your buddy's SN is 'CouldntGetMyName', you can
 	  alias him as 'Loser'.
 	* Compile with GNOME bits if available
-	* Added GNOME Url Handler as an available web-browser 
-	* Added the S html tag. 		
+	* Added GNOME Url Handler as an available web-browser
+	* Added the S html tag.
 	* Optionally Ignore TiK's Automated Messages
 	* Option to beep instead of play sound
 	* New icons for panel (depends on some GNOME pixmaps)
@@ -1767,11 +1825,11 @@
 	* More plugin events, more plugin features
 	* Run-time OSCAR support
 	* Added buddy list ticker (See prefs/Appearance). Clicking on a
-	  name will cause a new or previous IM window to display for 
-	  that screenname 
+	  name will cause a new or previous IM window to display for
+	  that screenname
 	* "You are sending messages too quickly" error is now fixed
 	   when you have a large buddylist.
-	* Fixed the LC_ALL compile problem on Solaris boxes 
+	* Fixed the LC_ALL compile problem on Solaris boxes
 	* Fixed PPC and ARM compile problem with oscar.c
 	* Smileys work better, and don't cause font attributes to drop
 	* Dialog windows are now prettier
@@ -1794,7 +1852,7 @@
 	* Double error bug when sending message to an offline user is
 	  fixed.
 	* Pressing enter once again sends a message in buddy chatrooms (oops)
-	* More fixes for the change on the AOL sign-on process. 
+	* More fixes for the change on the AOL sign-on process.
 	* Fixed bug where Gaim sometimes doesn't find a font to use.
 	* Per-conversation font and color dialogs (thanks fflewddur)
 	* Chat in oscar works (somewhat)
@@ -1809,14 +1867,14 @@
 	* Paned buddy chat window (Thanks Syd)
 	* Buddy lists (and changes) are cached to ~/.gaim/<sn>.blist
 	  where <sn> is your screen name. If for some reason, you log
-          into the AOL server and the buddy list comes back empty, we
+	  into the AOL server and the buddy list comes back empty, we
 	  check for a cache file, and, if we find one, read it in. This
-          essentially implements recovery from a server crash at AOL
+	  essentially implements recovery from a server crash at AOL
 	  (AOL does not back up machines that contain TOC-based buddy
 	  lists, unfortunately).  (Thanks Syd)
-	* Font selection dialog 
+	* Font selection dialog
 	* Small changes to the Oscar/libfaim stuff (see libfaim/README.gaim)
-	* SOCKS v4 Proxy support
+	* SOCKS 4a proxy support
 	* Better proxy support overall (you can get people's info now! :) )
 	* Two-way file transfer (you can get and send files, but you still
 	  can't initiate either)
@@ -1860,13 +1918,13 @@
 	* GNOME Applet support works better
 	  (thanks to Eric Warmenhoven for the patch)
 	* Support for displaying true type fonts
-	* Lag-O-Meter does not send lag-test if not selected 
+	* Lag-O-Meter does not send lag-test if not selected
 	* Fixed problem with saving away messages which contain spaces
 	  and numbers.
-	* Various GNOME Applet Enhancements (thanks AGAIN to 
-	  Eric.  Someone needs to stop this boy :-) ) 
+	* Various GNOME Applet Enhancements (thanks AGAIN to
+	  Eric.  Someone needs to stop this boy :-) )
 	* A lot of random, obscure bugs fixed
-	* All of the major and I believe all of the minor memory leaks are 
+	* All of the major and I believe all of the minor memory leaks are
 	  now fixed
 	  (Thanks to Peter Teichman, Larry Ewing, Jeramey Crawford, and me)
 
@@ -1876,9 +1934,9 @@
 	* New .gaimrc format
 	* Better support for multiple screen names
 	* Font Properties
-	* Saving of buddylist window position 
+	* Saving of buddylist window position
 	* Fixed a problem with Gaim and the Netscape-branded version
-	  of Mozilla 
+	  of Mozilla
 	* New Sound Properties
 	* More General Properties
 	* Bigger Text-Entry field (Thanks to CrazyDavy for this one)
@@ -1908,8 +1966,8 @@
 	* Some logging fixes and improvements
 	* configurable host/port selection
 	* Clickable Links in buddy chat
-	* New Gaim Logo 
-	* Display Signon/Signoff messages in conversation windows 
+	* New Gaim Logo
+	* Display Signon/Signoff messages in conversation windows
 	* Option to strip HTML from logged messages
 	* GNOME cleanups (It might work now haha)
 	* When viewing user info, URLS are converted to clickable links
@@ -1983,7 +2041,7 @@
 	* `Blocking' on conversation window
 	* Add/Remove buddy from conversation window
 	* Scroll-Wheel Mice work in Conversation Window
-	* Fixed WindowMaker Appicon 
+	* Fixed WindowMaker Appicon
 	* Version Number in About Box
 	* Gaim Slogan in about box :)
-	* Created Changelog File :) 
+	* Created Changelog File :)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ChangeLog.API	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,678 @@
+Gaim: The Pimpin' Penguin IM Client that's good for the soul!
+
+version 2.0.0:
+	Changed:
+	* All the status stuff.  Yay!
+	* gaim_prefs_connect_callback(), added handle parameter
+	* gtk_imhtml_toolbar now descends from GtkHBox making it easier to add your
+	  own widgets to it
+	* gaim_find_conversation_with_account, added a "type" parameter
+	* gaim_gtk_prefs_labeled_spin_button, the "key" parameter is now a
+	  const char* instead of just a char*
+	* gaim_gtk_prefs_labeled_entry, the "key" parameter is now a const char*
+	  instead of just a char*
+	* the add_buddy perl sub.  The sub now takes the account as the first
+	  argument, and buddy and group as the second and third.  It also adds
+	  the buddy to the server-side buddy list of the given account.
+	* gaim_connection_new, gaim_account_connect and gaim_account_register no
+	  longer return a GaimConnection
+	* keep_alive in GaimConnection is renamed to keepalive
+	* gaim_mkstemp, added a second argument, a boolean, of whether or not the
+	  file is binary
+	* gaim_log_logger_new, rewritten
+	* gaim_conv_window_remove_conversation()'s last argument to be a
+	  GaimConversation.
+	* A new blocked icon: pixmaps/status/default/blocked.png
+	* In pixmaps/status/default: extendedaway.png renamed to extended_away.png
+	* In pixmaps/status/default: na.png renamed to unavailable.png
+	* gtk_imhtml_toggle_bold(): No longer returns a value
+	* gtk_imhtml_toggle_italic(): No longer returns a value
+	* gtk_imhtml_toggle_underline(): No longer returns a value
+	* gtk_imhtml_toggle_strike(): No longer returns a value
+	* gtk_imhtml_scroll_to_end(): Added the smooth paramter
+	* gaim_log_new(), added conv parameter
+	* gaim_buddy_icon_new(), leaves a reference which the caller owns.  Use
+	  gaim_buddy_icon_unref() immediately if you don't want a reference (the
+	  old behavior).
+	* GAIM_CONV_UNKNOWN to GAIM_CONV_TYPE_UNKNOWN.
+	* GAIM_CONV_IM to GAIM_CONV_TYPE_IM.
+	* GAIM_CONV_CHAT to GAIM_CONV_TYPE_CHAT.
+	* GAIM_CONV_MISC to GAIM_CONV_TYPE_MISC.
+	* GAIM_CONV_ANY to GAIM_CONV_TYPE_ANY.
+	* GaimConversationUiOps.write_conv, Replaced const char *who with
+	  const char *name, const char *alias
+	* gaim_conv_chat_add_users(), added extra_msgs and new_arrivals (pass NULL
+	  and FALSE respectively, to get the same behavior as before)
+	* chat_add_users in GaimConversationUiOps, added cbuddies and 
+	  new_arrivals and removed buddies.
+	* chat_rename_user in GaimConversationUiOps, added new_alias
+	* gaim_conv_chat_cb_new(), added alias. (pass NULL to get the same
+	  behavior as before).
+	* GaimConversation.log became GList * GaimConversation.logs, so that a
+	  conversation can have multiple logs at once
+	* gaim_conv_chat_add_user, added extra_msgs
+	* gaim_notify_userinfo, removed primary and secondary parameters
+	* GaimNotifyUiOps.notify_userinfo: removed title, primary, and
+	  secondary parameters
+	* Idle timers are now added and removed in gtkidle.c in response
+	  to the signed-on and signed-off signals
+	* GaimXfer->ops.read, GaimXfer->ops.write, gaim_xfer_set_read_fnc(),
+	  gaim_xfer_set_write_fnc(), gaim_xfer_read(), gaim_xfer_write():
+	  Changed ssize_t to gssize
+	* serv_got_im, serv_got_chat_in, serv_send_im and serv_chat_send all use
+	  GaimMessageFlags instead of GaimConvImFlags / GaimConvChatFlags
+	* All core<->prpl message passing now uses html.  This was previously true
+	  for receiving messages, it's now also true for sending them.  prpls that
+	  don't support html need to gaim_unescape_html() the message.
+	* Notify API: GCallback -> GaimNotifyCloseCallback,
+	              void *user_data -> gpointer user_data
+	* gaim_notify_searchresults_get_rows_count,
+	  gaim_notify_searchresults_get_columns_count: return type now guint
+	* gaim_account_notify_added: No longer checks if there is a
+	  GaimBuddy for the added user, that's left up to the prpls.  See the
+	  documentation for this function and gaim_account_request_add.
+	* gaim_accounts_reorder: new_index is now a gint instead of a size_t
+	* displaying-message signals: displaying-[im|chat]-msg and
+	  displayed-[im|chat]-msg signals are emitted for all messages
+	  (ie, for received messages, sent messages, system messages, error
+	  messages etc.), and the signals now have
+	  gaim_gtk_conversations_get_handle() for their handle.
+	* GAIM_NOTIFY_BUTTON_ADD_BUDDY to GAIM_NOTIFY_BUTTON_ADD
+	* conversation-switched: This signal has been moved from conversation to
+	                         the UI and the signal-handlers only receive the
+	                         conversation that has been switched to.
+	* GaimPluginProtocolInfo: Added offline_message
+	* GaimPluginProtocolInfo: Added whiteboard_prpl_ops
+	* GaimPluginProtocolInfo: Added media_prpl_ops
+	* GaimPluginProtocolInfo: Added "user_info" argument to tooltip_text,
+	                          changed the return type to void
+	* GaimPluginProtocolInfo: Added "full" argument to tooltip_text
+	* gaim_pounce_new(): Added option argument for pounce options
+	* gaim_network_listen() and gaim_network_listen_range(): Added
+	  socket_type parameter to allow creation of UDP listening. Modified
+	  to be asynchronous with a callback to allow for UPnP operation.
+	  Returns a data structure that can be used to cancel the listen
+	  attempt using gaim_network_listen_cancel()
+	* GaimPrefCallback: val is now a gconstpointer instead of a gpointer
+	* gtk_imhtml_get_current_format(): the arguments are now set to TRUE or
+	  FALSE.  Previously they were set to TRUE or left alone.  Also, you
+	  may now pass NULL if you're not interested in a specific formatting.
+	* Smiley Themes: Backslashes must be backslash-escaped.
+	* Plugins: Depedencies are now honored when unloading plugins.
+	* gaim_markup_extract_info_field(): Added format_cb parameter.
+	* gaim_markup_extract_info_field(): Changed GString parameter to a GaimNotifyUserInfo paramter.
+	* gaim_str_to_time(): Added support for parsing the MM/DD/YYYY format.
+	* gaim_plugin_action_new(): label is now const char *
+	* gaim_plugin_pref_new_with_name(): name is now const char *
+	* gaim_plugin_pref_new_with_label(): label is now const char *
+	* gaim_plugin_pref_new_with_name_and_label(): name and label are
+	  now const char *
+	* gaim_plugin_pref_set_name(): name is now const char *
+	* gaim_plugin_pref_get_name(): return type is now const char *
+	* gaim_plugin_pref_set_label(): label is now const char *
+	* gaim_plugin_pref_get_label(): return type is now const char *
+	* gaim_plugin_pref_add_choice(): label is now const char *
+	* struct proto_chat_entry: label is now const char *
+	* struct proto_chat_entry: identifier is now const char *
+	* All network activity has been updated to use non-blocking sockets.
+	  This means that plugins must be updated to expect such a socket from
+	  gaim_proxy_connect() and gaim_network_listen*().
+	* gaim_proxy_connect(): changed to return NULL on error and a pointer
+	  to a GaimProxyConnectInfo object which can be used to cancel
+	  connection attempts using gaim_proxy_connect_cancel().  Also added
+	  a 'handle' parameter that can be used to cancel the connection
+	  attempt using gaim_proxy_connect_cancel_with_handle().
+	* gaim_gethostbyname_async(): Renamed to gaim_dnsquery_a() and
+	  changed to return a pointer to a data structure that can be
+	  used to cancel the pending DNS query using gaim_dnsquery_destroy()
+	* gaim_url_fetch(): Renamed to gaim_util_fetch_url() and changed
+	  to return a pointer to a data structure that can be used to cancel
+	  the pending HTTP request using gaim_util_fetch_url_cancel().
+	  Corresponding callback has changed to accept this data structure
+	  as its first argument, and to accept an error message as an
+	  additional final argument.
+	* gaim_gtk_create_imhtml(): Added sw_ret() parameter
+	* gaim_account_get_log(): Added create parameter
+	* GAIM_CMD_P_VERYHIGH is now GAIM_CMD_P_VERY_HIGH
+	* gtk_imhtml_search_find(): Now wraps around to the top instead of
+	  clearing the search at the end.
+	* gaim_gtkxfer_dialog_show: Can now take NULL to show (and possibly
+	  create) a default gtkxfer dialog.
+	* CHAT_USERS_BUDDY_COLUMN became CHAT_USERS_WEIGHT_COLUMN, along with
+	  a change in the values stored in the column.
+	* gaim_find_buddies() returns a list of all buddies in the account if name
+	  is NULL.
+	* gaim_gtk_set_custom_buddy_icon() sets custom icon for a user.
+	* Hid the definition of _GaimStringref, which already had a warning to
+	  avoid accessing it directly.
+	* notify_userinfo() UI op is passed a GaimNotifyUserInfo instead of a char*
+	  for the user information
+	* gaim_buddy_icon_get_scale_size() and was changed to ALWAYS scale
+	  the icon instead of only when icon_spec->scale_rules contains
+	  GAIM_ICON_SCALE_DISPLAY.  Callers should be changed to check the
+	  scale_rules before calling this function.
+	* gaim_gtk_buddy_icon_get_scale_size() was changed to accept an
+	  additional parameter which is used to determine what kind of
+	  scaling should be done, if any.
+
+	Removed:
+	* gaim_gtk_sound_{get,set}_mute() (replaced by the /gaim/gtk/sound/mute
+	  preference)
+	* gaim_escape_html(const char *html) (use g_markup_escape_text(html, -1)
+	  instead)
+	* gaim_accounts_sync, account changes are now scheduled to be saved
+	  automatically
+	* gaim_connection_connect
+	* gaim_connection_disconnect
+	* gaim_connection_register
+	* gaim_accounts_auto_login
+	* gaim_find_conversation, use gaim_find_conversation_with_account instead
+	* gaim_chat_get_display_name
+	* gaim_conversation_set_history, gaim_conversation_get_history, and
+	  GaimConversation->history.  Use gtk_imhtml_get_markup instead.
+	* set_gaim_user_dir to gaim_util_set_user_dir
+	* create_prpl_icon to gaim_gtk_create_prpl_icon
+	* Window flashing support in the core: gaim_conv_window_flash, and flash UI
+	  operation for conversations.  Use signal "received-im-msg" or similar.
+	* All warning stuff from the core.
+	* gaim_gtkconv_get_dest_tab_at_xy(), instead use gaim_gtkconv_get_tab_at_xy()
+	* chat_add_user from GaimConversationUiOps: only chat_add_users is used
+	* chat_remove_user from GaimConversationUiOps: only chat_remove_users is used
+	* uc from the GaimBuddy struct
+	* gaim_sound_get_handle()
+	* gaim_debug_vargs()
+	* serv_add_buddy(); use gaim_account_add_buddy() instead
+	* serv_add_buddies(); use gaim_account_add_buddies() instead
+	* serv_change_passwd(); use gaim_account_change_password() instead
+	* serv_close()
+	* serv_finish_login()
+	* serv_login()
+	* serv_remove_buddy(); use gaim_account_remove_buddy() instead
+	* serv_remove_buddies(); use gaim_account_remove_buddies() instead
+	* serv_rename_group()
+	* serv_set_buddyicon(): use gaim_account_set_buddy_icon() instead
+	* serv_touch_idle(): use gaim_gtk_check_idle() instead
+	* GaimGtkImPane->a_virgin
+	* gaim_str_strip_cr(); use gaim_str_strip_char(str, '\r') instead
+	* gaim_find_buddys_group renamed to gaim_buddy_get_group
+	* gaim_gtkpounce_menu_build()
+	* gaim_gtkpounce_dialog_show()
+	* GaimGtkBuddyList->bpmenu
+	* GaimConvImFlags and GaimConvChatFlags; use GaimMessageFlags instead
+	* cb and user_data from the ops in GaimNotifyUiOps: This is now handled
+	  by the notify API in the core.
+	* GaimConversationUiOps.updated: use the conversation-updated signal
+	* GAIM_SUBTYPE_CONV_WINDOW: windows are now only represented in the UI,
+	  so GAIM_TYPE_BOXED is used for the signal types
+	* gaim_gtk_privacy_is_showable(): We do fallback privacy in the core
+	  now, so this would always be TRUE now.
+	* GaimBlistNodeAction: See GaimMenuAction
+	* gaim_blist_node_action_new(); use gaim_menu_action_new() instead
+	* gaim_date()
+	* gaim_date_full(): See gaim_date_format_full()
+	* gaim_strftime(): See gaim_utf8_strftime()
+	* GAIM_MESSAGE_COLORIZE
+	* user_data from gaim_notify_searchresults_new_rows and from 
+	  notify_searchresults in GaimNotifyUiOps.
+	* gaim_conversation_get_send_history(), and send_history from
+	  GaimConversation
+	* Removed ui_ops from GaimBuddyList. Use gaim_blist_get_ui_ops() instead
+	* GaimGtkConversation: dialogs (dialogs.search moved to GaimGtkWindow)
+	* gaim_show_xfer_dialog: Use gaim_gtk_xfer_dialog_show(NULL) instead.
+	* GaimGtkRoomlistDialog: Nothing used it outside of the file it was in.
+	* gaim_gtk_roomlist_dialog_new: use gaim_gtk_roomlist_show
+	* gaim_gtk_roomlist_dialog_new_with_account: use gaim_gtk_roomlist_show_with_account
+
+	Added:
+	* gaim_prefs_disconnect_by_handle()
+	* a password field to GaimConnection, which only persists for the
+	  session (when "remember password" is false, account->password is
+	  NEVER set) Use gaim_connection_get_password(GaimConnection *gc)
+	* gaim_log_common_writer, gaim_log_common_lister, gaim_log_common_sizer,
+	  and gaim_log_get_log_dir to allow log formats that use standard Gaim
+	  log directory to use Gaim's built-in code for these purposes.
+	* GaimLogCommonLoggerData struct for a basic logger_data struct to be
+	  used with "common" logger functions.
+	* gaim_gtk_blist_node_is_contact_expanded, returns TRUE if the given
+	  blist node is a buddy inside an expanded contact, or is itself an
+	  expanded contact
+	* GaimLogSet struct, get_log_sets function to GaimLogLogger,
+	  gaim_log_get_log_sets, gaim_log_set_compare
+	* gaim_privacy_check(), to check if a given user is allowed to send
+	  messages to the specified account
+	* gtk_imhtml_clear_formatting()
+	* gtk_imhtml_delete to clear out part of a imhtml buffer
+	* gtk_imhtml_get_protocol_name()
+	* gaim_buddy_icons_get_full_path(), to get the full path of a buddy
+	  icon setting
+	* CHAT_USERS_ALIAS_COLUMN, CHAT_USERS_COLOR_COLUMN,
+	  CHAT_USERS_BUDDY_COLUMN to the list of columns for the chat
+	  user list
+	* gaim_account_add_buddy()
+	* gaim_account_add_buddies()
+	* gaim_account_remove_buddy()
+	* gaim_account_remove_buddies()
+	* gaim_account_change_password()
+	* gaim_account_supports_offline_message()
+	* gaim_conversation_close_logs(), to force a conversation's log(s) to
+	  be closed.  New logs will be opened as necessary.
+	* gaim_plugin_get_id()
+	* gaim_plugin_get_name()
+	* gaim_plugin_get_version()
+	* gaim_plugin_get_summary()
+	* gaim_plugin_get_description()
+	* gaim_plugin_get_author()
+	* gaim_plugin_get_homepage()
+	* gaim_gtkconv_switch_active_conversation(GaimConversation *)
+	* gaim_str_strip_char() to strip a given character from
+	  a given string
+	* gaim_util_chrreplace() to replace a given character with a
+	  different character
+	* gaim_gtk_blist_toggle_visibility() to intelligently toggle the
+	  visiblity of the buddy list
+	* gaim_gtk_blist_visibility_manager_add() to indicate the addition of a
+	  visibility manager - see the docs for more information
+	* gaim_gtk_blist_visibility_manager_remove() to indicate the removal of
+	  a visibility manager - see the docs for more information
+	* gaim_gtk_conversations_find_unseen_list() to get a list of conversations
+	  with an "unseen" state >= to the specified state and other criteria
+	* gaim_gtk_conversations_fill_menu() fill a menu from list of conversations
+	* gaim_gtk_create_prpl_icon()
+	* gaim_gtk_create_prpl_icon_with_status()
+	* gaim_gtk_pounces_manager_show()
+	* gaim_gtk_pounces_manager_hide()
+	* gaim_gtk_pounce_editor_show()
+	* GAIM_POUNCE_MESSAGE_RECEIVED
+	* GaimPounceOption
+	* gaim_pounce_set_options()
+	* gaim_pounce_set_options()
+	* GAIM_STOCK_CONNECT, GAIM_STOCK_DISCONNECT
+	* GAIM_STOCK_PLUGIN
+	* gaim_account_request_add: Notifies the user that they were added to
+	                            someone's buddy list, and offers them the choice
+	                            of adding that person to their buddy list.
+	* gaim_blist_alias_contact()
+	* gaim_cipher_http_digest_calculate_session_key()
+	* gaim_cipher_http_digest_calculate_response()
+	* gaim_notify_searchresults_labeled()
+	* GAIM_NOTIFY_BUTTON_LABELED, GAIM_NOTIFY_BUTTON_INFO,
+	  GAIM_NOTIFY_BUTTON_IM, GAIM_NOTIFY_BUTTON_JOIN,
+	  GAIM_NOTIFY_BUTTON_INVITE
+	* stock buttons GAIM_STOCK_IM, GAIM_STOCK_INFO
+	* gaim_conversation_present()
+	* GaimConversationUiOps->present(GaimConversation *)
+	* GaimPlugin.unloadable
+	* gaim_plugin_is_unloadable()
+	* GAIM_PLUGIN_PREF_STRING_FORMAT
+	* gaim_plugin_pref_get_format_type()
+	* gaim_plugin_pref_set_format_type()
+	* GaimStringFormatType
+	* gaim_log_get_handle()
+	* gaim_log_uninit()
+	* GAIM_SUBTYPE_LOG
+	* gaim_marshal_POINTER__POINTER_POINTER
+	* gaim_utf8_ncr_encode()
+	* gaim_gtk_log_init()
+	* gaim_gtk_log_get_handle()
+	* gaim_gtk_log_uninit()
+	* gaim_util_fetch_url_request()
+	* GaimMenuAction
+	* gaim_menu_action_new()
+	* gaim_menu_action_free()
+	* GaimInfoFieldFormatCallback
+	* gaim_utf8_strftime()
+	* gaim_date_format_short()
+	* gaim_date_format_long()
+	* gaim_date_format_full()
+	* gaim_time_format()
+	* gaim_plugin_action_free()
+	* GaimRequestType: Added GAIM_REQUEST_FOLDER
+	* GaimRequestUiOps: Added request_folder
+	* gaim_request_folder()
+	* gaim_gtk_setup_screenname_autocomplete()
+	* gaim_gtk_set_cursor()
+	* gaim_gtk_clear_cursor()
+	* GAIM_MESSAGE_ACTIVE_ONLY
+	* gaim_proxy_get_setup()
+	* GaimNotifySearchResultsCallback: Added user_data.
+	* gaim_notify_searchresults: Added user_data.
+	* gaim_network_listen_cancel(): Can be used to cancel a previous
+	  call to gaim_network_listen() or gaim_network_listen_range()
+	* gaim_proxy_connect_cancel(): Can be used to cancel a pending
+	  gaim_proxy_connect() request
+	* gaim_proxy_connect_cancel_with_handle(): Can be used to cancel
+	  a previous gaim_proxy_connect() request using a specified handle
+	* gaim_dnsquery_destroy(): Can be used to cancel a pending DNS
+	  query.
+	* gaim_util_fetch_url_cancel(): Can be used to cancel a pending
+	  call to gaim_util_fetch_url() or gaim_util_fetch_url_request().
+	* GaimGtkWindow: dialogs.search (previously in GaimGtkConversation)
+	* gaim_buddy_get_server_alias()
+	* gaim_conv_send_confirm()
+	* GaimConversationUiOps.send_confirm
+	* gaim_gtk_roomlist_dialog_show_with_account
+	* gaim_gtk_tree_view_search_equal_func to be used with
+	  gtk_tree_view_set_search_equal_func
+	* gaim_xfer_set_bytes_sent().  Sets the offset in the file to
+	  read from or write to.
+	* gaim_privacy_deny and gaim_privacy_allow
+	* gaim_gtk_blist_set_headline
+	* gaim_gtk_set_urgent
+	* GtkGaimScrollBook and its functions.
+
+	Signals - Changed:  (See the Doxygen docs for details on all signals.)
+	* Signal propagation now stops after a handler returns a non-NULL value.
+	  This value is now returned.  Previously, all registered handlers were
+	  called and the value from the last handler was used.
+	* "buddy-typing" and "buddy-typing-stopped": replaced the GaimConversation*
+	  with GaimAccount*, const char *name.  Also, the signal is now emitted
+	  regardless of whether a conversation exists and regardless of whether
+	  the user is on the buddy list.
+	* "chat-buddy-joined": added the new_arrival argument
+	* "chat-invited" handlers can now return a value to control what happens
+	  to the invite (accept, reject, prompt the user).
+	* "chat-left": Emitted *after* setting chat->left to TRUE.
+	* "drawing-tooltip": the second argument is now a GString* instead of
+	  a char**
+	* "drawing-tooltip": added the "full" argument
+	* "received-im-msg" and "received-chat-msg" to match, both now pass a
+	  conversation pointer and flags
+	* "receiving-im-msg" and "receving-chat-msg" to match, both now pass a
+	  conversation pointer and a pointer to the flags.
+	* "writing-im-msg", "wrote-im-msg", "writing-chat-msg", "wrote-chat-msg":
+	  Now emitted from a difference place in the message handling code.
+	  The arguments also changed.
+	* "displaying-im-msg", "displayed-im-msg", "displaying-chat-msg",
+	  "displayed-chat-msg": Added "who" argument, which changes the order
+	  of the existing arguments.
+
+	Signals - Added:  (See the Doxygen docs for details on all signals.)
+	* "account-disabled"
+	* "account-status-changed"
+	* "account-alias-changed"
+	* "cipher-added"
+	* "cipher-removed"
+	* "conversation-dragging"
+	* "dbus-method-called"
+	* "dbus-introspect"
+	* "file-recv-accept"
+	* "file-recv-start"
+	* "file-recv-cancel"
+	* "file-recv-complete"
+	* "file-recv-request"
+	* "file-send-accept"
+	* "file-send-start"
+	* "file-send-cancel"
+	* "file-send-complete"
+	* "buddy-added"
+	* "buddy-removed"
+	* "blist-node-aliased"
+	* "buddy-status-changed"
+	* "buddy-idle-changed": A buddy's idle status changed.
+	* "buddy-icon-changed"
+	* "buddy-got-login-time": The login time for a buddy is now known
+	* "displaying-userinfo"
+	* "gtkblist-hiding"
+	* "gtkblist-unhiding"
+	* "log-displaying"
+	* "savedstatus-changed"
+	* "sendto-extended-menu"
+
+	Signals - Removed:
+	* "account-away": replaced by account-status-changed
+	* "account-warned"
+	* "buddy-away": replaced by buddy-status-changed
+	* "buddy-back": replaced by buddy-status-changed
+	* "buddy-idle": replaced by buddy-idle-changed
+	* "buddy-unidle": replaced by buddy-idle-changed
+	* "buddy-icon-cached": replaced by buddy-icon-changed
+	* "conversation-drag-end": replaced by conversation-dragging
+	* "conversation-switching"
+
+version 1.5.0 (8/11/2005):
+	* Added: gaim_xfer_conversation_write
+	  Writes a messages to a conversation window with the use
+	  of the associated file transfer.
+
+version 1.4.0 (7/7/2005):
+	* Added: gaim_buddy_icon_uncache()
+	  Deletes a cached buddy icon for a specified buddy
+	* Added: gaim_buddy_icon_get_type
+	  Attempts to determine the type of a given buddy icon.
+	* Added: buddy-icon-cached signal
+	  Emitted when a new buddy icon is cached.
+
+version 1.3.1 (6/9/2005):
+	* No changes
+
+version 1.3.0 (5/10/2005):
+	* Added: gaim_blist_schedule_save()
+	  This should be used instead of gaim_blist_sync when you
+	  want the blist.xml file to be written to disk.  There
+	  should not be many occasions when you want to do this,
+	  as the functions in the blist API that modify the buddy
+	  list will normally call it for you.
+	* Added: OPT_PROTO_NO_NORMALIZE_CONV
+	  Tells the conversation API to not normalize screen names
+	  in conversations.  This is used by the Jabber PRPL.
+
+version 1.2.1 (4/3/2005):
+	* No changes
+
+version 1.2.0 (3/17/2005):
+	* You can use gaim_signal_connect_priority() and
+	  gaim_signal_connect_priority_vargs() to connect to
+	  Gaim signals with a given priority (Will Gorman)
+	* Added: gaim_conversation_set_features
+		 gaim_conversation_get_features
+	  These allow plugins (notable prpls) to change the
+	  formatting capabilities of an existing conversation.
+	  This comes with a new "features" field in
+	  GaimConversation (Christopher O'Brien)
+	* Added: GAIM_CONNECTION_NO_IMAGES to GaimConectionFlags
+	   (Christopher O'Brien)
+	* Added: GAIM_CBFLAGS_TYPING to GaimConvChatBuddyFlags
+	   (Christopher O'Brien)
+	* Added: gaim_account_request_add which takes the same arguments as
+	*  gaim_account_notify_added but always asks the user if they want to add
+	*  the buddy to the buddy list
+	* Added: An accompanying request_add GaimAccountUiOp
+
+version 1.1.4 (2/24/2005):
+	* No changes
+
+version 1.1.3 (2/17/2005):
+	* No changes
+
+version 1.1.2 (1/20/2005):
+	* No changes
+
+version 1.1.1 (12/28/2004):
+	* No changes
+
+version 1.1.0 (12/02/2004):
+	* Added: gaim_utf8_salvage
+	* Added: binary relocation support in prefix.h
+	         WARNING: If your plugin uses anything inside the
+		 #ifdef ENABLE_BINRELOC from prefix.h, it won't be
+		 loadable on a copy of Gaim compiled without binreloc
+		 support. In particular, watch out for the autoconf-like
+		 macros, and accidently including them through internal.h,
+		 which you probably shouldn't be including anyway.
+
+version 1.0.0 (09/17/2004):
+	* Added: get_chat_name to the GaimPluginProtocolInfo struct
+	* Changed: gaim_blist_update_buddy_presence(), presence changed to
+	           type gboolean
+	* Changed: the versioning scheme, and all the plugin structs
+
+version 0.82 (08/26/2004):
+	Gaim API:
+	* Removed: gaim_gtk_get_dispstyle(), gaim_gtk_change_text()
+	* Removed: multi.h
+	* Renamed: ui.h to gtkdialogs.h
+	* Renamed: gtkinternal.h to gtkgaim.h
+	* Renamed: show_info_dialog to gaim_gtkdialogs_info
+	* Renamed: show_log_dialog to gaim_gtkdialogs_log
+	* Renamed: show_warn_dialog to gaim_gtkdialogs_warn
+	* Renamed: show_im_dialog to gaim_gtkdialogs_im
+	* Renamed: gaim_gtkdialogs_new_im to gaim_gtkdialogs_im_with_user
+	* Renamed: destroy_all_dialogs to gaim_gtkdialogs_destroy_all
+	* Renamed: alias_dialog_bud to gaim_gtkdialogs_alias_buddy
+	* Renamed: alias_dialog_contact to gaim_gtkdialogs_alias_contact
+	* Renamed: alias_dialog_blist_chat to gaim_gtkdialogs_alias_chat
+	* Renamed: show_confirm_del to gaim_gtkdialogs_remove_buddy
+	* Renamed: show_confirm_del_group to gaim_gtkdialogs_remove_group
+	* Renamed: show_confirm_del_blist_chat to gaim_gtkdialogs_remove_chat
+	* Renamed: show_confirm_del_contact to gaim_gtkdialogs_remove_contact
+	* Renamed: show_about to gaim_gtkdialogs_about
+	* Added: gaim_notify_userinfo() and the associated notify_userinfo() UI op
+	         which pass account and contact information associated with the
+	         userinfo
+
+	Buddy List API:
+	* Changed: gaim_blist_request_add_chat(), added name parameter
+	* Added: gaim_contact_on_account()
+	* Added: flags parameter to the GaimBlistNode struct
+
+	Conversation API:
+	* Added: gaim_gtkconv_button_new()
+
+	Protocol Plugin API: v7
+	* Added: chat_info_defaults to the GaimPluginProtocolInfo struct
+
+	Signals:
+	* Added: conversation-updated for any update to the data associated
+	  with the conversation (topic, icon, adding to buddy list, etc.)
+
+	Conversation API:
+	* Changed: gaim_conv_chat_add_user() (added new_arrival parameter)
+
+version 0.81 (08/05/2004):
+	Commands API:
+	* Most functions now have a void *data argument.
+
+	Blist API:
+	* Added: gaim_buddy_get_contact_alias
+	* Renamed: gaim_get_buddy_alias to gaim_buddy_get_alias
+	* Renamed: gaim_get_buddy_alias_only to gaim_buddy_get_alias_only
+
+	Conversation API:
+	* Changed: gaim_conv_chat_add_user(), added flags parameter
+	* Changed: gaim_conv_chat_add_users(), added GList of flags parameter
+	* Changed: gaim_conv_chat_get_users(), now returns a GList of
+	  GaimConvChatBuddy's
+	* Changed: gaim_conv_chat_set_users() now expects a GList of
+	  GaimConvChatBuddy's
+	* Added: gaim_conv_chat_set_user_flags()
+	* Added: gaim_conv_chat_get_user_flags()
+	* Added: gaim_conv_chat_find_user()
+	* Added: gaim_conv_chat_cb_new()
+	* Added: gaim_conv_chat_cb_find()
+	* Added: gaim_conv_chat_cb_destroy()
+	* Added: gaim_conv_chat_cb_get_name()
+
+	Conversation UI ops:
+	* Added: chat_update_user()
+
+	Signals:
+	* Changed: chat-buddy-joining & chat-buddy-joined now include the user's flags
+	* Changed: chat-buddy-joining & chat-buddy-leaving are now booleans, return
+	  TRUE if you don't want the join/leave to be displayed in the UI.
+	* Added: chat-buddy-flags for when user's flags change
+	  gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT (required for the new
+	  chat-buddy-flags signal)
+	* Added: account-modified for when account settings have been changed.
+
+version 0.80 (07/15/2004):
+	Gaim API:
+	* Removed: PRPL numbers : gaim_account_set_protocol(),
+	  gaim_account_get_protocol(), gaim_accounts_find_with_prpl_num,
+	  gaim_prpl_num_to_id(), gaim_prpl_id_to_num(), GaimProtocol
+
+	Protocol Plugin API: v6
+	* Added: can_receive_file & send_file to the GaimPluginProtocolInfo struct
+
+	Signals:
+	* Changed "chat-invited" to also include the components hash table so
+	  plugins can use serv_join_chat when the signal is emitted.
+	* Added "chat-topic-changed" signal plugins know when a topic is changed.
+
+version 0.79 (06/24/2004):
+	Gaim API:
+	* gaim_url_parse() now takes two additional parameters, which are used
+	  for returning the username and password from the URL, if they exist.
+	* Added: has_focus UI op to GaimConversationUiOps and
+	  GaimConvWindowUiOps.
+	* Added: gaim_conversation_has_focus() and gaim_conv_window_has_focus().
+	* Removed: gaim_blist_save()
+
+	Protocol Plugin API: v5
+	* Changed: add_buddy, add_buddies, remove_buddy, remove_buddies,
+	  rename_group and remove_group to take GaimBuddy's and
+	  GaimGroup's consistently.
+	* Removed: OPT_PROTO_BUDDY_ICON (replaced by icon_spec)
+	* Added: icon_spec to the GaimPluginProtocolInfo struct
+
+version 0.78 (05/30/2004):
+	Plugin API: v4
+	* Added: actions - for plugins to add to the new Plugin Actions menu
+
+	Loader Plugin API: v2 (no changes)
+
+	Protocol Plugin API: v4
+	* Removed: set_dir, get_dir and dir_search (not used, AIM-centric)
+	* Removed: actions (replaced by generic plugin actions)
+
+	Perl Plugin API: v2 (no changes)
+	TCL Plugin API: (no changes)
+
+	Signals:
+	* Added: "blist-node-extended-menu" for extending Buddy, Chat and
+			 Group right-click menus
+	* Added: "drawing-tooltip" for plugins to allow plugins to change text
+			 appearing in tooltips
+	* Added: "gtkblist-created"
+	* Added: "receiving-im-msg" and "receiving-chat-msg" (these behave
+			  exactly like received-*-msg used to)
+	* Added: "buddy-idle-updated" signal, for when the idle time changes.
+	* Changed: "received-im-msg" and "received-chat-msg" no longer pass
+			   pointers to who, message and flags, and are now void.
+	* Removed: "drawing-menu" - it was UI sepecific and
+			   "blist-node-extended-menu" is superior
+
+version 0.77 (04/22/2004):
+	Loader & Protocol Plugins independantly versioned
+	Plugin loading now checks versioning on plugins (Standard, Loader &
+	Protocol)
+	new GAIM_{PLUGIN,PRPL,LOADER}_API_VERSION constants
+
+	Plugin API: v3
+	* Added: prefs_info for UI independant plugin prefs
+
+	Loader Plugin API: v2
+	* Added: api_version at top of GaimPluginLoaderInfo struct
+
+	Protocol Plugin API: v2
+	* Added: api_version at top of GaimPluginProtocolInfo struct
+	* Added: chat_menu for protocol specific extensions to the chat menu
+	* Removed: get_away "Nada used it. Pink elephants on parade."
+	* Removed: protocol_prefs (replaced by generic plugin prefs_info)
+
+	Perl Plugin API: v2 (no changes)
+	TCL API: (no changes)
+
+	Signals:
+	* Added: "conversation-drag-ended"
+
+version 0.76 (04/01/2004):
+	Plugin API: v2
+	Perl Plugin API: v2
+	Loader Plugin API: (not versioned)
+	Protocol Plugin API: (not versioned)
+	* Added: protocol_prefs for protocol specific preferences
+	* Added: reject_chat so protocols can act on chat invite rejection
+
+	TCL Plugin API: (not versioned)
+	* Changes to plugin registration to show descriptions
+
--- a/Doxyfile.in	Mon Apr 16 00:43:53 2007 +0000
+++ b/Doxyfile.in	Sun May 20 06:19:49 2007 +0000
@@ -431,7 +431,9 @@
 # directories like "/usr/src/myproject". Separate the files or directories 
 # with spaces.
 
-INPUT                  = src \
+INPUT                  = libgaim \
+						 gtk \
+						 console \
                          doc
 
 # If the value of the INPUT tag contains directories, you can use the 
--- a/HACKING	Mon Apr 16 00:43:53 2007 +0000
+++ b/HACKING	Sun May 20 06:19:49 2007 +0000
@@ -28,26 +28,24 @@
 you don't know GTK+ you should go learn that first.
 
 If you're going to hack gaim, PLEASE, PLEASE PLEASE PLEASE send patches
-against the absolute latest CVS. I get really annoyed when I get patches
+against the absolute latest SVN. I get really annoyed when I get patches
 against the last released version, especially since I don't usually have
 a copy of it on my computer, and gaim tends to change a lot between
-versions. (I sometimes get annoyed when they're against CVS from 3 days
+versions. (I sometimes get annoyed when they're against SVN from 3 days
 ago, but can't complain because it's usually my fault that I haven't
-looked at the patch yet.) To get gaim from CVS (if you haven't already),
+looked at the patch yet.) To get gaim from SVN (if you haven't already),
 run the following commands:
 
-$ export CVSROOT=:pserver:anonymous@cvs.sourceforge.net:/cvsroot/gaim
-$ cvs login (hit enter as the password)
-$ cvs co gaim (you'll see it getting all of the files)
+$ svn co https://svn.sourceforge.net/svnroot/gaim/trunk gaim
 $ cd gaim
 $ ./autogen.sh
 
 You'll now have your normal gaim tree with ./configure and all (which
 ./autogen.sh takes the liberty of running for you). (If you want to make
-your life really simple, learn how CVS works. CVS is your friend.) To make
+your life really simple, learn how SVN works. SVN is your friend.) To make
 a patch, just edit the files right there in that tree (don't bother with
 two trees, or even two copies of the same file). Then when you're ready to
-make your patch, simply run 'cvs diff -u >my.patch' and post it on 
+make your patch, simply run 'svn diff > my.patch' and post it on
 sf.net/projects/gaim in the patches section.
 
 Some Documentation is available on the Gaim api if you run the command 
--- a/Makefile.am	Mon Apr 16 00:43:53 2007 +0000
+++ b/Makefile.am	Sun May 20 06:19:49 2007 +0000
@@ -1,44 +1,58 @@
 EXTRA_DIST = \
 		COPYRIGHT \
+		ChangeLog.API \
+		ChangeLog.win32 \
 		Doxyfile.in \
+		HACKING \
+		Makefile.mingw \
+		PLUGIN_HOWTO \
+		PROGRAMMING_NOTES \
+		README.SVN \
+		README.dbus \
+		README.mingw \
 		gaim.pc.in \
 		gaim.spec.in \
 		gaim.apspec.in \
-		gaim.desktop \
+		gaim.desktop.in \
+		gaim.service.in \
 		gaim-installer.nsi \
-		HACKING \
-		PROGRAMMING_NOTES \
-		setup-gettext \
-		ChangeLog.win32 \
+		intltool-extract.in \
+		intltool-merge.in \
+		intltool-update.in \
 		config.h.mingw \
-		Makefile.mingw \
-		README.mingw \
-		VERSION \
-		VERSION.in \
-		plugins/win32/transparency/Makefile.mingw \
-		plugins/win32/transparency/win2ktrans.c \
-		plugins/win32/winprefs/gtkappbar.c \
-		plugins/win32/winprefs/gtkappbar.h \
-		plugins/win32/winprefs/Makefile.mingw \
-		plugins/win32/winprefs/winprefs.c \
 		po/Makefile.mingw
 
-gaimincludedir=$(includedir)/gaim
-gaiminclude_HEADERS = config.h
+noinst_HEADERS = config.h
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = gaim.pc
 
+if ENABLE_DBUS
+dbus_servicedir=$(DBUS_SERVICES_DIR)
+dbus_service_DATA=gaim.service
+endif
+
 dist-hook: gaim.spec
 	cp gaim.spec $(distdir)
+	rm $(distdir)/config.h
 
-distcheck-hook: plugins/perl/common/Gaim.pm
-#	cp plugins/perl/common/Gaim.pm $(distdir)/plugins/perl/common
+distcheck-hook: libgaim/plugins/perl/common/Gaim.pm gtk/plugins/perl/common/GtkUI.pm
+#	cp libgaim/plugins/perl/common/Gaim.pm $(distdir)/libgaim/plugins/perl/common
 
 appsdir = $(datadir)/applications
-apps_DATA = gaim.desktop
+apps_in_files = gaim.desktop.in
+apps_DATA = $(apps_in_files:.desktop.in=.desktop)
+@INTLTOOL_DESKTOP_RULE@
 
-SUBDIRS = doc intl m4macros pixmaps plugins po sounds src
+if ENABLE_GTK
+GTK_DIR=gtk
+endif
+
+if ENABLE_GNT
+GNT_DIR=console
+endif
+
+SUBDIRS = libgaim doc $(GNT_DIR) $(GTK_DIR) m4macros po
 
 docs: Doxyfile
 if HAVE_DOXYGEN
@@ -55,5 +69,5 @@
 distuninstallcheck_listfiles = \
 	find . -type f -print | grep -v perl | grep -v Gaim.3pm
 
-ACLOCAL_AMFLAGS = -I m4
-
+DISTCLEANFILES= gaim.desktop libgaim/gconf/gaim.schemas intltool-extract \
+			intltool-merge intltool-update
--- a/Makefile.mingw	Mon Apr 16 00:43:53 2007 +0000
+++ b/Makefile.mingw	Sun May 20 06:19:49 2007 +0000
@@ -5,125 +5,93 @@
 # Description: Top Makefile for win32 (mingw) port of Gaim
 #
 
-GAIM_SRC = ./src
-GAIM_PROTOS = $(GAIM_SRC)/protocols
-GAIM_PLUGINS = ./plugins
-GAIM_PIXMAPS = ./pixmaps
-GAIM_SOUNDS = ./sounds
-GAIM_INSTALL_DIR = ./win32-install-dir
-GTKSPELL_TOP = ../win32-dev/gtkspell-2.0.6/gtkspell
-IDLETRACK_TOP = $(GAIM_SRC)/win32/IdleTracker
-GTKRC_TOP = ../win32-dev/gtkrc
-OSCAR = $(GAIM_PROTOS)/oscar
-YAHOO = $(GAIM_PROTOS)/yahoo
-MSN = $(GAIM_PROTOS)/msn
-TOC = $(GAIM_PROTOS)/toc
-IRC = $(GAIM_PROTOS)/irc
-JABBER = $(GAIM_PROTOS)/jabber
-NAPSTER = $(GAIM_PROTOS)/napster
-GG = $(GAIM_PROTOS)/gg
-NOVELL = $(GAIM_PROTOS)/novell
-SILC = $(GAIM_PROTOS)/silc
-SIMPLE = $(GAIM_PROTOS)/simple
-SAMETIME = $(GAIM_PROTOS)/sametime
-PO = ./po
+GAIM_TOP := .
+include $(GAIM_TOP)/libgaim/win32/global.mak
 
-MAKENSIS := makensis.exe
-
-VERSION := $(shell cat ./VERSION)
-
-NEEDED_DLLS =		$(GTKSPELL_TOP)/libgtkspell.dll \
-			$(IDLETRACK_TOP)/idletrack.dll
+# Generate a X.X.X.X version for the installer file versioning header
+# The last digit will be 99 for a final release, 0 for dev or unknown, or the beta number
+GAIM_PRODUCT_VERSION = $(shell \
+awk 'BEGIN {FS="."} { \
+    if (int($$3) == $$3) { \
+        $$4 = "99"; \
+    } else { \
+        $$5 = $$3; \
+        sub(int($$3), "", $$5); \
+        if ($$5 == "dev") { \
+            $$4 = "0"; \
+        } else { \
+            if (sub("beta", "", $$5) > 0) { \
+                $$4 = $$5; \
+            } else { \
+                $$4 = "0"; \
+            } \
+        } \
+    } \
+    printf("%s.%s.%s.%s", $$1, $$2, int($$3), $$4); \
+    exit; \
+}' VERSION)
 
-SOUNDS =		$(GAIM_SOUNDS)/alert.wav \
-			$(GAIM_SOUNDS)/login.wav \
-			$(GAIM_SOUNDS)/logout.wav \
-			$(GAIM_SOUNDS)/receive.wav \
-			$(GAIM_SOUNDS)/send.wav
-
-
-##
-## Don't forget to change STATIC_PROTO_INIT, in config.h.mingw if you
-## change the status of a protocol (static/plugin)
-##
+GTK_INSTALL_VERSION = $(shell \
+  source ../gtk_installer/version.sh; \
+  echo $$gtk_version \
+)
 
-OSCAR_TYPE = PLUGIN
-YAHOO_TYPE = PLUGIN
-MSN_TYPE = PLUGIN
-TOC_TYPE = PLUGIN
-IRC_TYPE = PLUGIN
-JABBER_TYPE = PLUGIN
-NAPSTER_TYPE = PLUGIN
-GG_TYPE = PLUGIN
-NOVELL_TYPE = PLUGIN
-SILC_TYPE = PLUGIN
-SIMPLE_TYPE = PLUGIN
-SAMETIME_TYPE = PLUGIN
+# Any *.dll or *.exe files included in win32-install-dir that we don't compile
+# should be included in this list so they don't get stripped
+NON_GAIM_DLLS = \
+	freebl3.dll \
+	libgtkspell.dll \
+	libmeanwhile-1.dll \
+	libxml2.dll \
+	nspr4.dll \
+	nss3.dll \
+	nssckbi.dll \
+	plc4.dll \
+	plds4.dll \
+	silc.dll \
+	silcclient.dll \
+	softokn3.dll \
+	ssl3.dll
 
-all:
-	cp config.h.mingw config.h
-	$(MAKE) TYPE='$(OSCAR_TYPE)' -C $(OSCAR) -f Makefile.mingw
-	$(MAKE) TYPE='$(YAHOO_TYPE)' -C $(YAHOO) -f Makefile.mingw
-	$(MAKE) TYPE='$(MSN_TYPE)' -C $(MSN) -f Makefile.mingw
-	$(MAKE) TYPE='$(IRC_TYPE)' -C $(IRC) -f Makefile.mingw
-	$(MAKE) TYPE='$(JABBER_TYPE)' -C $(JABBER) -f Makefile.mingw
-	$(MAKE) TYPE='$(NAPSTER_TYPE)' -C $(NAPSTER) -f Makefile.mingw
-	$(MAKE) TYPE='$(GG_TYPE)' -C $(GG) -f Makefile.mingw
-	$(MAKE) TYPE='$(NOVELL_TYPE)' -C $(NOVELL) -f Makefile.mingw
-	$(MAKE) TYPE='$(SILC_TYPE)' -C $(SILC) -f Makefile.mingw
-	$(MAKE) TYPE='$(SIMPLE_TYPE)' -C $(SIMPLE) -f Makefile.mingw
-	$(MAKE) TYPE='$(SAMETIME_TYPE)' -C $(SAMETIME) -f Makefile.mingw
-	$(MAKE) -C $(GAIM_SRC) -f Makefile.mingw
-	$(MAKE) -C $(GAIM_PLUGINS) -f Makefile.mingw
+#build an expression for `find` to use to ignore the above files
+NON_GAIM_DLLS_FIND_EXP = $(patsubst %,-o -name %,$(NON_GAIM_DLLS))
 
+.PHONY: all install installer installer_nogtk installer_debug installers clean uninstall create_release_install_dir
 
-install: all
-	mkdir -p $(GAIM_INSTALL_DIR)/plugins
-	mkdir -p $(GAIM_INSTALL_DIR)/sounds/gaim
-	$(MAKE) -C $(GAIM_PIXMAPS) -f Makefile.mingw install
-	$(MAKE) -C $(PO) -f Makefile.mingw install
-	$(MAKE) -C $(GAIM_SRC) -f Makefile.mingw install
-	$(MAKE) -C $(GAIM_PLUGINS) -f Makefile.mingw install
-	$(MAKE) TYPE='$(OSCAR_TYPE)' -C $(OSCAR) -f Makefile.mingw install
-	$(MAKE) TYPE='$(YAHOO_TYPE)' -C $(YAHOO) -f Makefile.mingw install
-	$(MAKE) TYPE='$(MSN_TYPE)' -C $(MSN) -f Makefile.mingw install
-	$(MAKE) TYPE='$(IRC_TYPE)' -C $(IRC) -f Makefile.mingw install
-	$(MAKE) TYPE='$(JABBER_TYPE)' -C $(JABBER) -f Makefile.mingw install
-	$(MAKE) TYPE='$(NAPSTER_TYPE)' -C $(NAPSTER) -f Makefile.mingw install
-	$(MAKE) TYPE='$(GG_TYPE)' -C $(GG) -f Makefile.mingw install
-	$(MAKE) TYPE='$(NOVELL_TYPE)' -C $(NOVELL) -f Makefile.mingw install
-	$(MAKE) TYPE='$(SILC_TYPE)' -C $(SILC) -f Makefile.mingw install
-	$(MAKE) TYPE='$(SIMPLE_TYPE)' -C $(SIMPLE) -f Makefile.mingw install
-	$(MAKE) TYPE='$(SAMETIME_TYPE)' -C $(SAMETIME) -f Makefile.mingw install
-	cp $(NEEDED_DLLS) $(GAIM_INSTALL_DIR)
-	cp $(SOUNDS) $(GAIM_INSTALL_DIR)/sounds/gaim
+all: $(GAIM_CONFIG_H)
+	$(MAKE) -C $(GAIM_LIB_TOP) -f $(GAIM_WIN32_MAKEFILE)
+	$(MAKE) -C $(GAIM_GTK_TOP) -f $(GAIM_WIN32_MAKEFILE)
+	$(MAKE) -C $(GAIM_PO_TOP) -f $(GAIM_WIN32_MAKEFILE)
+
+install: all $(GAIM_INSTALL_DIR)
+	$(MAKE) -C $(GAIM_LIB_TOP) -f $(GAIM_WIN32_MAKEFILE) install
+	$(MAKE) -C $(GAIM_GTK_TOP) -f $(GAIM_WIN32_MAKEFILE) install
+	$(MAKE) -C $(GAIM_PO_TOP) -f $(GAIM_WIN32_MAKEFILE) install
 
-installer:
-	$(MAKENSIS) /DGAIM_VERSION="$(VERSION)" /DWITH_GTK gaim-installer.nsi
-
-installer_nogtk:
-	$(MAKENSIS) /DGAIM_VERSION="$(VERSION)" gaim-installer.nsi
+create_release_install_dir: install
+	rm -rf $(GAIM_INSTALL_DIR).release
+	cp -R $(GAIM_INSTALL_DIR) $(GAIM_INSTALL_DIR).release
+	find $(GAIM_INSTALL_DIR).release \( -name '*.dll' -o -name '*.exe' \) \
+	 -not \( -false $(NON_GAIM_DLLS_FIND_EXP) \) -exec strip --strip-unneeded {} ';'
 
-installer_debug:
-	$(MAKENSIS) /DGAIM_VERSION="$(VERSION)" /DDEBUG gaim-installer.nsi
+installer: create_release_install_dir
+	$(MAKENSIS) /V3 /DGAIM_VERSION="$(GAIM_VERSION)" /DGAIM_PRODUCT_VERSION="$(GAIM_PRODUCT_VERSION)" /DWITH_GTK /DGAIM_INSTALL_DIR="$(GAIM_INSTALL_DIR).release" /DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" gaim-installer.nsi
 
-installers: installer installer_nogtk
+installer_nogtk: create_release_install_dir
+	$(MAKENSIS) /V3 /DGAIM_VERSION="$(GAIM_VERSION)" /DGAIM_PRODUCT_VERSION="$(GAIM_PRODUCT_VERSION)" /DGAIM_INSTALL_DIR="$(GAIM_INSTALL_DIR).release" /DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" gaim-installer.nsi
 
+installer_debug: install
+	$(MAKENSIS) /V3 /DGAIM_VERSION="$(GAIM_VERSION)" /DGAIM_PRODUCT_VERSION="$(GAIM_PRODUCT_VERSION)" /DGAIM_INSTALL_DIR="$(GAIM_INSTALL_DIR)" /DDEBUG /DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" gaim-installer.nsi
+
+installers: installer installer_nogtk installer_debug
 
 clean:
-	$(MAKE) -C $(PO) -f Makefile.mingw clean
-	$(MAKE) -C $(OSCAR) -f Makefile.mingw clean
-	$(MAKE) -C $(YAHOO) -f Makefile.mingw clean
-	$(MAKE) -C $(MSN) -f Makefile.mingw clean
-	$(MAKE) -C $(IRC) -f Makefile.mingw clean
-	$(MAKE) -C $(JABBER) -f Makefile.mingw clean
-	$(MAKE) -C $(NAPSTER) -f Makefile.mingw clean
-	$(MAKE) -C $(GG) -f Makefile.mingw clean
-	$(MAKE) -C $(NOVELL) -f Makefile.mingw clean
-	$(MAKE) -C $(SILC) -f Makefile.mingw clean
-	$(MAKE) -C $(SIMPLE) -f Makefile.mingw clean
-	$(MAKE) -C $(SAMETIME) -f Makefile.mingw clean
-	$(MAKE) -C $(GAIM_SRC) -f Makefile.mingw clean
-	$(MAKE) -C $(GAIM_PLUGINS) -f Makefile.mingw clean
-	rm -rf config.h $(GAIM_INSTALL_DIR)
-	rm -rf gaim*.exe
+	$(MAKE) -C $(GAIM_PO_TOP) -f $(GAIM_WIN32_MAKEFILE) clean
+	$(MAKE) -C $(GAIM_GTK_TOP) -f $(GAIM_WIN32_MAKEFILE) clean
+	$(MAKE) -C $(GAIM_LIB_TOP) -f $(GAIM_WIN32_MAKEFILE) clean
+	rm -f $(GAIM_CONFIG_H) gaim*.exe
+
+uninstall:
+	rm -rf $(GAIM_INSTALL_PERLMOD_DIR) $(GAIM_INSTALL_PLUGINS_DIR) $(GAIM_INSTALL_PO_DIR) $(GAIM_INSTALL_DIR) $(GAIM_INSTALL_DIR).release
+
+include $(GAIM_COMMON_TARGETS)
--- a/NEWS	Mon Apr 16 00:43:53 2007 +0000
+++ b/NEWS	Sun May 20 06:19:49 2007 +0000
@@ -1,5 +1,44 @@
 -=[ Gaim ]=-  The Pimpin' Penguin IM Client That's Good For The Soul!
 
+2.0.0beta6 (1/17/2006):
+	Sean: Barring any seriously major new issues, we expect this to be
+	the final beta release before 2.0.0. This has a bunch of cool UI
+	changes, some Google Talk features, a bunch new plugins, and other
+	goodness.
+
+	Nathan: Beta6 rocks.  That is all.
+
+	Gary: Long time no news.  My silence will end soon ;)
+
+	Evan: My first news! I knocked out a nice collection of crashes,
+	thanks in part to my ever-patient Adium beta testers. Gaim 2.0.0
+	is going to be delicious. :)
+
+2.0.0beta5 (11/9/2006):
+	Sean: Another release in our endless stream in betas. This one's
+	pretty awesome; and it fixes major bugs introduced in previous
+	ones.
+
+2.0.0beta4 (10/17/2006)
+	Sean: Still beta. Maybe the next one should be a gamma.. :)
+
+	Daniel: I'm super chuffed to announce that this will work with newer
+	(i.e. >= 2.8.0) versions of GTK+ on Windows.
+
+	Luke: Several significant changes in this one, including no longer
+	using libao for sound!  There are no doubt bugs here, but hopefully
+	nothing major.
+
+	Nathan: I don't have much to say, but yay for another beta!
+
+	Etan: I did a bunch of perl work for this beta again, there is now
+	some support for perl scripts to call functions in the gtk ui, it
+	still needs work.
+
+2.0.0beta3 (03/25/2006):
+	Mark: Yeah, I know, another beta.  Don't worry, we'll get this
+	puppy out the door eventually.
+
 2.0.0beta2 (01/24/2006):
 	Mark: So this is the new year, and I don't feel any different, but
 	Gaim is getting better.  We hope this will be our last beta before
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PLUGIN_HOWTO	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,20 @@
+For information on writing a plugin for Gaim, go
+http://gaim.sourceforge.net/api/ and see the HOWTOs in the
+"Related Pages" section.
+
+You can also generate this documentation locally by installing
+doxygen and graphviz dot, then running "make docs" in the Gaim
+source tree.  The documentation will be in the docs/html directory.
+
+This next paragraph is old and possibly out of date:
+Compilation of the plugins is fairly straight-forward; there is a
+Makefile in this directory that has a rule for making the .so file
+from a .c file. No modification of the Makefile should be necessary,
+unless if you simply want to type 'make' to have it made; otherwise,
+'make filename.so' will take filename.c and make the .so plugin from
+it. If you need to link in with extra libraries, you can set the
+environment variable PLUGIN_LIBS to be the libraries you want to link
+with.
+
+It should be possible to compile plugins outside of the Gaim source
+tree, which is a much cleaner solution.
--- a/README	Mon Apr 16 00:43:53 2007 +0000
+++ b/README	Sun May 20 06:19:49 2007 +0000
@@ -24,12 +24,10 @@
 well as the development files!). The configure script will fail if you
 don't. You can get it from http://www.gtk.org/.
 
-For sound support, you also need libao
-(http://freshmeat.net/projects/libao/) and libaudiofile
-(http://www.68k.org/~michael/audiofile/). For spellchecking support, you
-need libgtkspell (http://gtkspell.sf.net/). Your distro of choice
-probably already includes these, just be sure to install the development
-packages.
+For sound support, you also need gstreamer 0.10 or higher. For
+spellchecking support, you need libgtkspell (http://gtkspell.sf.net/).
+Your distro of choice probably already includes these, just be sure to
+install the development packages.
 
 RUN
 ===
@@ -73,7 +71,7 @@
 
 If you come across a bug, please report it to http://gaim.sf.net/bug.php.
 
-See README.CVS for information on the bleeding edge CVS version of Gaim.
+See README.SVN for information on the bleeding edge SVN version of Gaim.
 You probably shouldn't use it, as it may eat your children, as well as
 your settings.
 
--- a/README.CVS	Mon Apr 16 00:43:53 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-If you plan to use gaim CVS, PLEASE read this message in its entirety!
-
-Gaim is a fast-moving project with a somewhat regular release schedule.
-Due to the rate of gaim development, CVS undergoes frequent bursts of
-massive changes, often leaving behind brokenness and partial
-functionality while the responsible developers rewrite some portion of
-code or seek to add new features.
-
-What this all boils down to is that CVS _WILL_ sometimes be broken.
-Because of this, we ask that users who are not interested in
-personally tracking down bugs and fixing them (without a lot of
-assistance from the developers!) avoid CVS and use releases.  Since
-releases will be made often, this should not prevent anyone from using
-the newest, shiniest features -- but it will prevent users from having
-to deal with ugly development bugs that we already know about but
-haven't gotten around to fixing.
-
-If you are interested in hacking on gaim, please read README and
-HACKING, and take note of the issues in PROGRAMMING_NOTES.  (Note that
-they may be somewhat out of date at times.) Win32 developers, please
-read README.mingw.
-
-By far the best documentation, however, is the documented code.  Not
-all parts of gaim have yet been documented, but the major subsystems
-are falling fast.  If you have doxygen, you can use the Doxyfile in
-the toplevel directory to generate pretty documentation.  Otherwise
-(or even if you do!), the header files for each subsystem contain
-documentation for the functions they contain.  For instance,
-conversation.h contains documentation for the entire
-gaim_conversation_* API, and account.h contains documentation for the
-gaim_account_* API.
-
-If you have questions, please feel free to contact the gaim developers
-by email at gaim-devel@lists.sourceforge.net, on IRC at
-irc.freenode.net in #gaim, or via the sourceforge forums at
-http://www.sourceforge.net/projects/gaim.  Please do as much homework
-as you can before contacting us; the more you know about your
-question, the faster and more effectively we can help you!
-
-Send patches to gaim-devel@lists.sourceforge.net or post them in the
-Sourceforge forums at http://www.sourceforge.net/projects/gaim.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.SVN	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,41 @@
+If you plan to use gaim SVN, PLEASE read this message in its entirety!
+
+Gaim is a fast-moving project with a somewhat regular release schedule.
+Due to the rate of gaim development, SVN undergoes frequent bursts of
+massive changes, often leaving behind brokenness and partial
+functionality while the responsible developers rewrite some portion of
+code or seek to add new features.
+
+What this all boils down to is that SVN _WILL_ sometimes be broken.
+Because of this, we ask that users who are not interested in
+personally tracking down bugs and fixing them (without a lot of
+assistance from the developers!) avoid SVN and use releases.  Since
+releases will be made often, this should not prevent anyone from using
+the newest, shiniest features -- but it will prevent users from having
+to deal with ugly development bugs that we already know about but
+haven't gotten around to fixing.
+
+If you are interested in hacking on gaim, please read README and
+HACKING, and take note of the issues in PROGRAMMING_NOTES.  (Note that
+they may be somewhat out of date at times.) Win32 developers, please
+read README.mingw.
+
+By far the best documentation, however, is the documented code.  Not
+all parts of gaim have yet been documented, but the major subsystems
+are falling fast.  If you have doxygen, you can use the Doxyfile in
+the toplevel directory to generate pretty documentation.  Otherwise
+(or even if you do!), the header files for each subsystem contain
+documentation for the functions they contain.  For instance,
+conversation.h contains documentation for the entire
+gaim_conversation_* API, and account.h contains documentation for the
+gaim_account_* API.
+
+If you have questions, please feel free to contact the gaim developers
+by email at gaim-devel@lists.sourceforge.net, on IRC at
+irc.freenode.net in #gaim, or via the sourceforge forums at
+http://www.sourceforge.net/projects/gaim.  Please do as much homework
+as you can before contacting us; the more you know about your
+question, the faster and more effectively we can help you!
+
+Send patches to gaim-devel@lists.sourceforge.net or post them in the
+Sourceforge forums at http://www.sourceforge.net/projects/gaim.
--- a/README.mingw	Mon Apr 16 00:43:53 2007 +0000
+++ b/README.mingw	Sun May 20 06:19:49 2007 +0000
@@ -1,10 +1,6 @@
-How to build Gaim using MinGw
+How to build Gaim using MinGW
 =============================
 
-Since these instructions are constantly changing and in order for me to
-avoid maintaining two versions of these instructions please refer to:
+Since these instructions are constantly changing, please refer to:
 
-http://gaim.sourceforge.net/win32
-
-- Herman
-  
+http://gaim.sourceforge.net/win32/build.php
--- a/VERSION	Mon Apr 16 00:43:53 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-2.0.0cvs
--- a/VERSION.in	Mon Apr 16 00:43:53 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-@VERSION@
--- a/acinclude.m4	Mon Apr 16 00:43:53 2007 +0000
+++ b/acinclude.m4	Sun May 20 06:19:49 2007 +0000
@@ -411,305 +411,6 @@
   rm -f conf.gtktest
 ])
 
-dnl This is XIPH_PATH_AO renamed to GAIM_PATH_AO to prevent conflicts.
-dnl It's a long story.  --elb
-
-# ao.m4
-# Configure paths for libao
-# Jack Moffitt <jack@icecast.org> 10-21-2000
-# Shamelessly stolen from Owen Taylor and Manish Singh
-
-dnl GAIM_PATH_AO([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
-dnl Test for libao, and define AO_CFLAGS and AO_LIBS
-dnl
-AC_DEFUN([GAIM_PATH_AO],
-[dnl 
-dnl Get the cflags and libraries
-dnl
-AC_ARG_WITH(ao,[  --with-ao=PFX   Prefix where libao is installed (optional)], ao_prefix="$withval", ao_prefix="")
-AC_ARG_WITH(ao-libraries,[  --with-ao-libraries=DIR   Directory where libao library is installed (optional)], ao_libraries="$withval", ao_libraries="")
-AC_ARG_WITH(ao-includes,[  --with-ao-includes=DIR   Directory where libao header files are installed (optional)], ao_includes="$withval", ao_includes="")
-AC_ARG_ENABLE(aotest, [  --disable-aotest       Do not try to compile and run a test ao program],, enable_aotest=yes)
-
-
-  if test "x$ao_libraries" != "x" ; then
-    AO_LIBS="-L$ao_libraries"
-  elif test "x$ao_prefix" != "x"; then
-    AO_LIBS="-L$ao_prefix/lib"
-  elif test "x$prefix" != "xNONE"; then
-    AO_LIBS="-L$prefix/lib"
-  fi
-
-  if test "x$ao_includes" != "x" ; then
-    AO_CFLAGS="-I$ao_includes"
-  elif test "x$ao_prefix" != "x"; then
-    AO_CFLAGS="-I$ao_prefix/include"
-  elif test "x$prefix" != "xNONE"; then
-    AO_CFLAGS="-I$prefix/include"
-  fi
-
-  # see where dl* and friends live
-  AC_CHECK_FUNCS(dlopen, [AO_DL_LIBS=""], [
-    AC_CHECK_LIB(dl, dlopen, [AO_DL_LIBS="-ldl"], [
-      AC_MSG_WARN([could not find dlopen() needed by libao sound drivers
-      your system may not be supported.])
-    ])
-  ])
-
-  AO_LIBS="$AO_LIBS -lao $AO_DL_LIBS"
-
-  AC_MSG_CHECKING(for ao)
-  no_ao=""
-
-
-  if test "x$enable_aotest" = "xyes" ; then
-    ac_save_CFLAGS="$CFLAGS"
-    ac_save_LIBS="$LIBS"
-    CFLAGS="$CFLAGS $AO_CFLAGS"
-    LIBS="$LIBS $AO_LIBS"
-dnl
-dnl Now check if the installed ao is sufficiently new.
-dnl
-      rm -f conf.aotest
-      AC_TRY_RUN([
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ao/ao.h>
-
-int main ()
-{
-  system("touch conf.aotest");
-  return 0;
-}
-
-],, no_ao=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
-       CFLAGS="$ac_save_CFLAGS"
-       LIBS="$ac_save_LIBS"
-  fi
-
-  if test "x$no_ao" = "x" ; then
-     AC_MSG_RESULT(yes)
-     ifelse([$1], , :, [$1])     
-  else
-     AC_MSG_RESULT(no)
-     if test -f conf.aotest ; then
-       :
-     else
-       echo "*** Could not run ao test program, checking why..."
-       CFLAGS="$CFLAGS $AO_CFLAGS"
-       LIBS="$LIBS $AO_LIBS"
-       AC_TRY_LINK([
-#include <stdio.h>
-#include <ao/ao.h>
-],     [ return 0; ],
-       [ echo "*** The test program compiled, but did not run. This usually means"
-       echo "*** that the run-time linker is not finding ao or finding the wrong"
-       echo "*** version of ao. If it is not finding ao, you'll need to set your"
-       echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
-       echo "*** to the installed location  Also, make sure you have run ldconfig if that"
-       echo "*** is required on your system"
-       echo "***"
-       echo "*** If you have an old version installed, it is best to remove it, although"
-       echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
-       [ echo "*** The test program failed to compile or link. See the file config.log for the"
-       echo "*** exact error that occurred. This usually means ao was incorrectly installed"
-       echo "*** or that you have moved ao since it was installed." ])
-       CFLAGS="$ac_save_CFLAGS"
-       LIBS="$ac_save_LIBS"
-     fi
-     AO_CFLAGS=""
-     AO_LIBS=""
-     ifelse([$2], , :, [$2])
-  fi
-  AC_SUBST(AO_CFLAGS)
-  AC_SUBST(AO_LIBS)
-  rm -f conf.aotest
-])
-
-dnl audiofile.m4, included here for those people who don't have audiofile
-dnl installed but would like to build CVS.
-
-# Configure paths for the Audio File Library
-# Bertrand Guiheneuf 98-10-21
-# stolen from esd.m4 in esound :
-# Manish Singh    98-9-30
-# stolen back from Frank Belew
-# stolen from Manish Singh
-# Shamelessly stolen from Owen Taylor
-
-dnl AM_PATH_AUDIOFILE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl Test for Audio File Library, and define AUDIOFILE_CFLAGS and AUDIOFILE_LIBS.
-dnl
-AC_DEFUN([AM_PATH_AUDIOFILE],
-[dnl 
-dnl Get compiler flags and libraries from the audiofile-config script.
-dnl
-AC_ARG_WITH(audiofile-prefix,[  --with-audiofile-prefix=PFX   Prefix where Audio File Library is installed (optional)],
-            audiofile_prefix="$withval", audiofile_prefix="")
-AC_ARG_WITH(audiofile-exec-prefix,[  --with-audiofile-exec-prefix=PFX Exec prefix where Audio File Library is installed (optional)],
-            audiofile_exec_prefix="$withval", audiofile_exec_prefix="")
-AC_ARG_ENABLE(audiofiletest, [  --disable-audiofiletest       Do not try to compile and run a test Audio File Library program], , enable_audiofiletest=yes)
-
-  if test x$audiofile_exec_prefix != x ; then
-     audiofile_args="$audiofile_args --exec-prefix=$audiofile_exec_prefix"
-     if test x${AUDIOFILE_CONFIG+set} != xset ; then
-        AUDIOFILE_CONFIG=$audiofile_exec_prefix/bin/audiofile-config
-     fi
-  fi
-  if test x$audiofile_prefix != x ; then
-     audiofile_args="$audiofile_args --prefix=$audiofile_prefix"
-     if test x${AUDIOFILE_CONFIG+set} != xset ; then
-        AUDIOFILE_CONFIG=$audiofile_prefix/bin/audiofile-config
-     fi
-  fi
-
-  AC_PATH_PROG(AUDIOFILE_CONFIG, audiofile-config, no)
-  min_audiofile_version=ifelse([$1], ,0.2.5,$1)
-  AC_MSG_CHECKING(for Audio File Library - version >= $min_audiofile_version)
-  no_audiofile=""
-  if test "$AUDIOFILE_CONFIG" = "no" ; then
-    no_audiofile=yes
-  else
-    AUDIOFILE_LIBS=`$AUDIOFILE_CONFIG $audiofileconf_args --libs`
-    AUDIOFILE_CFLAGS=`$AUDIOFILE_CONFIG $audiofileconf_args --cflags`
-    audiofile_major_version=`$AUDIOFILE_CONFIG $audiofile_args --version | \
-           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
-    audiofile_minor_version=`$AUDIOFILE_CONFIG $audiofile_args --version | \
-           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
-    audiofile_micro_version=`$AUDIOFILE_CONFIG $audiofile_config_args --version | \
-           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
-    if test "x$enable_audiofiletest" = "xyes" ; then
-      AC_LANG_SAVE
-      AC_LANG_C
-      ac_save_CFLAGS="$CFLAGS"
-      ac_save_LIBS="$LIBS"
-      CFLAGS="$CFLAGS $AUDIOFILE_CFLAGS"
-      LIBS="$LIBS $AUDIOFILE_LIBS"
-dnl
-dnl Now check if the installed Audio File Library is sufficiently new. 
-dnl (Also checks the sanity of the results of audiofile-config to some extent.)
-dnl
-      rm -f conf.audiofiletest
-      AC_TRY_RUN([
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <audiofile.h>
-
-char*
-my_strdup (char *str)
-{
-  char *new_str;
-  
-  if (str)
-    {
-      new_str = malloc ((strlen (str) + 1) * sizeof(char));
-      strcpy (new_str, str);
-    }
-  else
-    new_str = NULL;
-  
-  return new_str;
-}
-
-int main ()
-{
-  int major, minor, micro;
-  char *tmp_version;
-
-  system ("touch conf.audiofiletest");
-
-  /* HP/UX 9 (%@#!) writes to sscanf strings */
-  tmp_version = my_strdup("$min_audiofile_version");
-  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
-     printf("%s, bad version string\n", "$min_audiofile_version");
-     exit(1);
-   }
-
-   if (($audiofile_major_version > major) ||
-      (($audiofile_major_version == major) && ($audiofile_minor_version > minor)) ||
-      (($audiofile_major_version == major) && ($audiofile_minor_version == minor) && ($audiofile_micro_version >= micro)))
-    {
-      return 0;
-    }
-  else
-    {
-      printf("\n*** 'audiofile-config --version' returned %d.%d.%d, but the minimum version\n", $audiofile_major_version, $audiofile_minor_version, $audiofile_micro_version);
-      printf("*** of the Audio File Library required is %d.%d.%d. If audiofile-config is correct, then it is\n", major, minor, micro);
-      printf("*** best to upgrade to the required version.\n");
-      printf("*** If audiofile-config was wrong, set the environment variable AUDIOFILE_CONFIG\n");
-      printf("*** to point to the correct copy of audiofile-config, and remove the file\n");
-      printf("*** config.cache before re-running configure\n");
-      return 1;
-    }
-}
-
-],, no_audiofile=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
-       CFLAGS="$ac_save_CFLAGS"
-       LIBS="$ac_save_LIBS"
-       AC_LANG_RESTORE
-     fi
-  fi
-  if test "x$no_audiofile" = x ; then
-     AC_MSG_RESULT(yes)
-     ifelse([$2], , :, [$2])     
-  else
-     AC_MSG_RESULT(no)
-     if test "$AUDIOFILE_CONFIG" = "no" ; then
-       cat <<END
-*** The audiofile-config script installed by the Audio File Library could
-*** not be found.  If the Audio File Library was installed in PREFIX, make
-*** sure PREFIX/bin is in your path, or set the AUDIOFILE_CONFIG
-*** environment variable to the full path to audiofile-config.
-END
-     else
-       if test -f conf.audiofiletest ; then
-        :
-       else
-          echo "*** Could not run Audio File Library test program; checking why..."
-          AC_LANG_SAVE
-          AC_LANG_C
-          CFLAGS="$CFLAGS $AUDIOFILE_CFLAGS"
-          LIBS="$LIBS $AUDIOFILE_LIBS"
-          AC_TRY_LINK([
-#include <stdio.h>
-#include <audiofile.h>
-],      [ return 0; ],
-        [ cat <<END
-*** The test program compiled, but did not run.  This usually means that
-*** the run-time linker is not finding Audio File Library or finding the
-*** wrong version of Audio File Library.
-***
-*** If it is not finding Audio File Library, you'll need to set your
-*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point
-*** to the installed location.  Also, make sure you have run ldconfig if
-*** that is required on your system.
-***
-*** If you have an old version installed, it is best to remove it, although
-*** you may also be able to get things to work by modifying
-*** LD_LIBRARY_PATH.
-END
-        ],
-        [ echo "*** The test program failed to compile or link. See the file config.log"
-          echo "*** for the exact error that occurred. This usually means the Audio File"
-          echo "*** Library was incorrectly installed or that you have moved the Audio"
-          echo "*** File Library since it was installed. In the latter case, you may want"
-          echo "*** to edit the audiofile-config script: $AUDIOFILE_CONFIG" ])
-          CFLAGS="$ac_save_CFLAGS"
-          LIBS="$ac_save_LIBS"
-          AC_LANG_RESTORE
-       fi
-     fi
-     AUDIOFILE_CFLAGS=""
-     AUDIOFILE_LIBS=""
-     ifelse([$3], , :, [$3])
-  fi
-  AC_SUBST(AUDIOFILE_CFLAGS)
-  AC_SUBST(AUDIOFILE_LIBS)
-  rm -f conf.audiofiletest
-])
-
 dnl ac_var_timeszone_externals.m4
 
 # Define 'timezone', 'altzone' and 'daylight'
@@ -836,3 +537,42 @@
 	AC_SUBST(BINRELOC_CFLAGS)
 	AC_SUBST(BINRELOC_LIBS)
 ])
+dnl AM_GCONF_SOURCE_2
+dnl Defines GCONF_SCHEMA_CONFIG_SOURCE which is where you should install schemas
+dnl  (i.e. pass to gconftool-2
+dnl Defines GCONF_SCHEMA_FILE_DIR which is a filesystem directory where
+dnl  you should install foo.schemas files
+dnl
+
+AC_DEFUN([AM_GCONF_SOURCE_2],
+[
+  if test "x$GCONF_SCHEMA_INSTALL_SOURCE" = "x"; then
+    GCONF_SCHEMA_CONFIG_SOURCE=`gconftool-2 --get-default-source`
+  else
+    GCONF_SCHEMA_CONFIG_SOURCE=$GCONF_SCHEMA_INSTALL_SOURCE
+  fi
+
+  AC_ARG_WITH(gconf-source, 
+  [  --with-gconf-source=sourceaddress      Config database for installing schema files.],GCONF_SCHEMA_CONFIG_SOURCE="$withval",)
+
+  AC_SUBST(GCONF_SCHEMA_CONFIG_SOURCE)
+  AC_MSG_RESULT([Using config source $GCONF_SCHEMA_CONFIG_SOURCE for schema installation])
+
+  if test "x$GCONF_SCHEMA_FILE_DIR" = "x"; then
+    GCONF_SCHEMA_FILE_DIR='$(sysconfdir)/gconf/schemas'
+  fi
+
+  AC_ARG_WITH(gconf-schema-file-dir, 
+  [  --with-gconf-schema-file-dir=dir        Directory for installing schema files.],GCONF_SCHEMA_FILE_DIR="$withval",)
+
+  AC_SUBST(GCONF_SCHEMA_FILE_DIR)
+  AC_MSG_RESULT([Using $GCONF_SCHEMA_FILE_DIR as install directory for schema files])
+
+  AC_ARG_ENABLE(schemas-install,
+     [  --disable-schemas-install	Disable the schemas installation],
+     [case ${enableval} in
+       yes|no) ;;
+       *) AC_MSG_ERROR(bad value ${enableval} for --enable-schemas-install) ;;
+      esac])
+  AM_CONDITIONAL([GCONF_SCHEMAS_INSTALL], [test "$enable_schemas_install" != no])
+])
--- a/autogen.sh	Mon Apr 16 00:43:53 2007 +0000
+++ b/autogen.sh	Sun May 20 06:19:49 2007 +0000
@@ -1,31 +1,41 @@
 #!/bin/sh
 
-SETUP_GETTEXT=./setup-gettext
+CONFIGURE_ARGS=""
+if [ -f configure.args ] ; then
+	CONFIGURE_ARGS="${CONFIGURE_ARGS} `cat configure.args`"
+fi
 
-($SETUP_GETTEXT --gettext-tool) < /dev/null > /dev/null 2>&1 || {
+(glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have glib-gettextize installed to compile Gaim.";
 	echo;
-	echo "You must have gettext installed to compile Gaim";
+	exit;
+}
+
+(intltoolize --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have intltool installed to compile Gaim.";
 	echo;
 	exit;
 }
 
 (libtoolize --version) < /dev/null > /dev/null 2>&1 || {
 	echo;
-	echo "You must have libtool installed to compile Gaim";
+	echo "You must have libtool installed to compile Gaim.";
 	echo;
 	exit;
 }
 
 (automake --version) < /dev/null > /dev/null 2>&1 || {
 	echo;
-	echo "You must have automake installed to compile Gaim";
+	echo "You must have automake installed to compile Gaim.";
 	echo;
 	exit;
 }
 
 (autoconf --version) < /dev/null > /dev/null 2>&1 || {
 	echo;
-	echo "You must have autoconf installed to compile Gaim";
+	echo "You must have autoconf installed to compile Gaim.";
 	echo;
 	exit;
 }
@@ -33,17 +43,6 @@
 echo "Generating configuration files for Gaim, please wait...."
 echo;
 
-# Backup the po/ChangeLog. This should prevent the annoying
-# gettext ChangeLog modifications.
-
-cp -p po/ChangeLog po/ChangeLog.save
-
-echo "Running gettextize, please ignore non-fatal messages...."
-$SETUP_GETTEXT
-
-# Restore the po/ChangeLog file.
-mv po/ChangeLog.save po/ChangeLog
-
 echo "Running libtoolize, please ignore non-fatal messages...."
 echo n | libtoolize --copy --force || exit;
 
@@ -58,10 +57,17 @@
 	fi
 done
 
-aclocal $ACLOCAL_FLAGS -I ./m4 || exit;
+libtoolize -c -f --automake
+glib-gettextize --force --copy
+intltoolize --force --copy
+aclocal $ACLOCAL_FLAGS || exit;
 autoheader || exit;
 automake --add-missing --copy;
 autoconf || exit;
 automake || exit;
-./configure $@
 
+echo;
+echo "Running ./configure ${CONFIGURE_ARGS} $@"
+echo;
+./configure ${CONFIGURE_ARGS} $@
+
--- a/config.h.mingw	Mon Apr 16 00:43:53 2007 +0000
+++ b/config.h.mingw	Sun May 20 06:19:49 2007 +0000
@@ -183,6 +183,9 @@
    declares uintmax_t. */
 #define HAVE_INTTYPES_H_WITH_UINTMAX 1
 
+/* Define if we have IOKit */
+/* #undef HAVE_IOKIT */
+
 /* Define to 1 if you have the `krb_get_err_text' function. */
 /* #undef HAVE_KRB_GET_ERR_TEXT */
 
@@ -204,6 +207,9 @@
 /* Define if your <locale.h> file defines LC_MESSAGES. */
 /* #define HAVE_LC_MESSAGES 1 */
 
+/* Define to 1 if you have libgadu. */
+#define HAVE_LIBGADU 1
+
 /* Define to 1 if you have the `nsl' library (-lnsl). */
 /* #define HAVE_LIBNSL 1 */
 
@@ -315,7 +321,7 @@
 /* Define to 1 if you have the <signal.h> header file. */
 /* #define HAVE_SIGNAL_H 1 */
 
-/* define if we have silcmime.h */
+/* Define if we have silcmime.h */
 /* #undef HAVE_SILCMIME_H */
 
 /* Define to 1 if you have the <smime.h> header file. */
@@ -373,6 +379,9 @@
 /* Define to 1 if you have the `strftime' function. */
 #define HAVE_STRFTIME 1
 
+/* Define to 1 if you have a strftime() that supports the %z format string. */
+/* #undef HAVE_STRFTIME_Z_FORMAT */
+
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
@@ -419,7 +428,7 @@
 #define HAVE_SYS_STAT_H 1
 
 /* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
+/* #undef HAVE_SYS_TIME_H */
 
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
@@ -520,13 +529,13 @@
 #define PACKAGE_NAME "gaim"
 
 /* Define to the full name and version of this package. */
-/* #define PACKAGE_STRING "gaim 2.0.0cvs" */
+/* #define PACKAGE_STRING "gaim 2.0.0dev" */
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "gaim"
 
 /* Define to the version of this package. */
-/* #define PACKAGE_VERSION "2.0.0cvs" */
+/* #define PACKAGE_VERSION "2.0.0dev" */
 
 /* Define if <inttypes.h> exists and defines unusable PRI* macros. */
 /* #undef PRI_MACROS_BROKEN */
@@ -541,9 +550,9 @@
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be
    automatically deduced at run-time.
-	STACK_DIRECTION > 0 => grows toward higher addresses
-	STACK_DIRECTION < 0 => grows toward lower addresses
-	STACK_DIRECTION = 0 => direction of growth unknown */
+    STACK_DIRECTION > 0 => grows toward higher addresses
+    STACK_DIRECTION < 0 => grows toward lower addresses
+    STACK_DIRECTION = 0 => direction of growth unknown */
 /* #undef STACK_DIRECTION */
 
 /* Loads static protocol plugin module initialization functions. */
@@ -570,7 +579,7 @@
 /* #define USE_SM 1 */
 
 /* Version number of package */
-/* #define VERSION "2.0.0cvs" */
+/* #define VERSION "2.0.0dev" */
 
 /* Define to 1 if your processor stores words with the most significant byte
    first (like Motorola and SPARC, unlike Intel and VAX). */
@@ -620,13 +629,17 @@
 /* #undef size_t */
 
 /* socklen_t size */
-#define socklen_t int
+/* #define socklen_t int */
 
 /* Define to unsigned long or unsigned long long if <stdint.h> and
    <inttypes.h> don't define. */
 /* #undef uintmax_t */
 
+#define HAVE_LIBXML 1
+
 /*
  * Following are added for Win32 version of Gaim
  */
 #define HAVE_VSNPRINTF 1
+
+#define SIZEOF_TIME_T 4
--- a/configure.ac	Mon Apr 16 00:43:53 2007 +0000
+++ b/configure.ac	Sun May 20 06:19:49 2007 +0000
@@ -1,8 +1,9 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT([gaim], [2.0.0cvs], [gaim-devel@lists.sourceforge.net])
+AC_INIT([gaim], [2.0.0beta6], [gaim-devel@lists.sourceforge.net])
 AC_CANONICAL_SYSTEM
 AM_CONFIG_HEADER(config.h)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+#AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
 AC_PREREQ([2.50])
 
@@ -17,11 +18,24 @@
 AM_PROG_LIBTOOL
 LIBTOOL="$LIBTOOL --silent"
 AC_PROG_INSTALL
+AC_PROG_INTLTOOL
+PKG_PROG_PKG_CONFIG
+
+GETTEXT_PACKAGE=gaim
+AC_SUBST(GETTEXT_PACKAGE)
 
 # before gettexting, in case iconv matters
 case "$host_os" in
 darwin*)
 	AC_CHECK_LIB(resolv, res_query)
+
+	AC_CHECK_HEADER(CoreFoundation/CoreFoundation.h, [
+		AC_CHECK_HEADER(IOKit/IOKitLib.h, [
+			AC_DEFINE(HAVE_IOKIT, 1, [Define if we have IOKit])
+			LIBS="$LIBS -framework IOKit -framework CoreFoundation"
+		], [])
+	], [])
+
 	AC_MSG_CHECKING([for fink])
 	if test -d /sw; then
 		AC_MSG_RESULT([found, adding /sw to search paths])
@@ -35,9 +49,8 @@
 	;;
 esac
 
-ALL_LINGUAS="am az bg bn bs ca cs da de el en_AU en_CA en_GB es et fi fr gl gu he hi hu it ja ka ko ku lt mk my_MM nb nl nn pa pl pt_BR pt ro ru sk sl sq sr sr@Latn sv ta te tr uk vi xh zh_CN zh_TW"
-AM_GNU_GETTEXT_VERSION(0.10.40)
-AM_GNU_GETTEXT
+ALL_LINGUAS="am ar az bg bn bs ca ca@valencia cs da de dz el en_AU en_CA en_GB eo es et eu fa fi fr gl gu he hi hu it ja ka ko ku lt mk my_MM nb ne nl nn pa pl pt_BR pt ro ru sk sl sq sr sr@Latn sv ta te th tr uk vi xh zh_CN zh_TW"
+AM_GLIB_GNU_GETTEXT
 
 dnl we don't use autobreak on cygwin!!
 dnl AC_CYGWIN
@@ -50,13 +63,16 @@
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 AC_STRUCT_TM
+AC_CHECK_SIZEOF(time_t, ,[
+#include <stdio.h>
+#include <time.h>])
 
 AC_C_BIGENDIAN
 
 dnl Checks for library functions.
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
-AC_CHECK_FUNCS(strdup strstr atexit)
+AC_CHECK_FUNCS(strdup strstr atexit setlocale)
 dnl Checks for getopt in standard library
 AC_CHECK_FUNCS(getopt_long,,
 [
@@ -65,18 +81,19 @@
 ])
 
 dnl Check for inet_aton
-AC_CHECK_FUNC(inet_aton, , [AC_CHECK_LIB(resolv, inet_aton, , 
+AC_CHECK_FUNC(inet_aton, , [AC_CHECK_LIB(resolv, inet_aton, ,
 				         [AC_ERROR(inet_aton not found)])])
 AC_CHECK_LIB(resolv, __res_query)
 AC_CHECK_LIB(nsl, gethostent)
-AC_CHECK_FUNC(socket, , 
-              [AC_CHECK_LIB(socket, socket, , [AC_ERROR([socket not found])])])
+AC_CHECK_FUNC(socket, ,
+	[AC_CHECK_LIB(socket, socket, , [AC_ERROR([socket not found])])])
 dnl If all goes well, by this point the previous two checks will have
 dnl pulled in -lsocket and -lnsl if we need them.
-AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE([HAVE_GETADDRINFO], [1],
-                                      [Define to 1 if you have the getaddrinfo function.])],
-              [AC_CHECK_LIB(socket, getaddrinfo,
-                            [AC_DEFINE([HAVE_GETADDRINFO]) LIBS="-lsocket -lsnl $LIBS"], , , -lnsl)])
+AC_CHECK_FUNC(getaddrinfo,
+	[AC_DEFINE([HAVE_GETADDRINFO], [1],
+		[Define to 1 if you have the getaddrinfo function.])],
+	[AC_CHECK_LIB(socket, getaddrinfo,
+		[AC_DEFINE([HAVE_GETADDRINFO]) LIBS="-lsocket -lsnl $LIBS"], , , -lnsl)])
 
 dnl Check for socklen_t (in Unix98)
 AC_MSG_CHECKING(for socklen_t)
@@ -108,32 +125,401 @@
 dnl FreeBSD doesn't have libdl, dlopen is provided by libc
 AC_CHECK_FUNC(dlopen, LIBDL="", [AC_CHECK_LIB(dl, dlopen, LIBDL="-ldl")])
 
+AC_MSG_CHECKING(for the %z format string in strftime())
+AC_TRY_RUN([
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include <time.h>
+#include <stdio.h>
 
+int main()
+{
+	char buf[6];
+	time_t t = time(NULL);
+
+	if (strftime(buf, sizeof(buf), "%z", localtime(&t)) != 5)
+		return 1;
+
+	fprintf(stderr, "strftime(\"%%z\") yields: \"%s\"\n", buf);
+
+	return !((buf[0] == '-' || buf[0] == '+') &&
+	         (buf[1] >= '0' && buf[1] <= '9') &&
+	         (buf[2] >= '0' && buf[2] <= '9') &&
+	         (buf[3] >= '0' && buf[3] <= '9') &&
+	         (buf[4] >= '0' && buf[4] <= '9')
+	        );
+}
+], [
+	AC_MSG_RESULT(yes)
+	AC_DEFINE([HAVE_STRFTIME_Z_FORMAT], [1],
+		[Define to 1 if you have a strftime() that supports the %z format string.])
+], [
+	AC_MSG_RESULT(no)
+], [
+	# Fallback for Cross Compiling...
+	# This will enable the compatibility code.
+	AC_MSG_RESULT(no)
+]
+)
+
+dnl #######################################################################
+dnl # Check for GLib 2.0 (required)
+dnl #######################################################################
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.0.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
+	AC_MSG_RESULT(no)
+	AC_MSG_ERROR([
+
+You must have the GLib 2.0 development headers installed to build Gaim.
+])])
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+AC_ARG_ENABLE(gtkui, [AC_HELP_STRING([--disable-gtkui],
+		[compile without GTK+ user interface])],
+	enable_gtkui="$enableval", enable_gtkui="yes")
+AC_ARG_ENABLE(consoleui, [AC_HELP_STRING([--disable-consoleui],
+		[compile without console user interface])],
+	enable_consoleui=$enableval, enable_consoleui=yes)
+
+dnl #######################################################################
+dnl # Check for GTK+ 2.0 and other things used by the GTK UI
+dnl #######################################################################
+AC_ARG_ENABLE(screensaver,
+	[AC_HELP_STRING([--disable-screensaver],
+		[compile without X screensaver extension (used to detect idleness)])],
+	enable_screensaver="$enableval", enable_screensaver="yes")
+AC_ARG_ENABLE(sm,
+	[AC_HELP_STRING([--disable-sm],
+		[compile without X session management support])],
+	enable_sm="$enableval", enable_sm="yes")
+AC_ARG_ENABLE(startup-notification,
+	[AC_HELP_STRING([--disable-startup-notification],
+		[compile without startup notification support])],
+	enable_startup_notification="$enableval", enable_startup_notification="yes")
+AC_ARG_ENABLE(gtkspell,
+	[AC_HELP_STRING([--disable-gtkspell],
+		[compile without GtkSpell automatic spell checking])],
+	enable_gtkspell="$enableval", enable_gtkspell="yes")
+AC_ARG_ENABLE(gevolution,
+	[AC_HELP_STRING([--disable-gevolution],
+		[compile without the Gaim Evolution plugin])],
+	enable_gevolution="$enableval", enable_gevolution="yes")
+AC_ARG_ENABLE(cap,
+	[AC_HELP_STRING([--disable-cap],
+		[compile without Contact Availability Prediction plugin])],
+	enable_cap="$enableval", enable_cap="yes")
+
+
+AC_PATH_XTRA
+# We can't assume that $x_libraries will be set, because autoconf does not
+# set it in the case when the X libraries are in a standard place.
+# Ditto for $x_includes
+if test X"$x_libraries" = X"" || test X"$x_libraries" = XNONE; then
+    x_libpath_add=
+else
+    x_libpath_add="-L$x_libraries"
+fi
+if test X"$x_includes" = X"" || test X"$x_includes" = XNONE; then
+    x_incpath_add=
+else
+    x_incpath_add="-I$x_includes"
+fi
+
+if test "x$enable_gtkui" = "xyes" ; then
+	PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.0.0], , [
+		AC_MSG_RESULT(no)
+		AC_MSG_ERROR([
+
+You must have the GTK+ 2.0 development headers installed to compile Gaim's
+GTK+ interface.  If you only want to build the console interface then
+specify --disable-gtkui when running configure.
+])])
+
+	AC_SUBST(GTK_CFLAGS)
+	AC_SUBST(GTK_LIBS)
+
+	dnl #######################################################################
+	dnl # Check for XScreenSaver
+	dnl #######################################################################
+	if test "x$enable_screensaver" = "xyes" ; then
+		old_LIBS="$LIBS"
+		LIBS="$LIBS $GTK_LIBS $x_libpath_add"
+		XSS_LIBS=""
+		XSS_HEADERS=""
+		AC_CHECK_LIB(Xext, XScreenSaverRegister,[XSS_LIBS="$X_LIBS $X_PRE_LIBS -lX11 -lXext $X_EXTRA_LIBS"],[],[-lX11 -lXext -lm])
+		AC_CHECK_LIB(Xss, XScreenSaverRegister,[XSS_LIBS="$X_LIBS $X_PRE_LIBS -lX11 -lXext $X_LIBS $X_EXTRA_LIBS -lXss"],[],[-lX11 -lXext -lm])
+		if test "x$XSS_LIBS" != "x"; then
+			oldCPPFLAGS="$CPPFLAGS"
+			CPPFLAGS="$CPPFLAGS $x_incpath_add"
+			AC_TRY_COMPILE([
+					#include <X11/Xlib.h>
+					#include <X11/extensions/scrnsaver.h>
+				], [], [], [enable_screensaver=no])
+			CPPFLAGS="$oldCPPFLAGS"
+		else
+			enable_screensaver=no
+		fi
+		LIBS="$old_LIBS"
+
+		if test "x$enable_screensaver" = "xyes" ; then
+			AC_DEFINE(USE_SCREENSAVER, 1, [Define if we're using XScreenSaver.])
+			AC_SUBST(XSS_LIBS)
+		fi
+	fi
+
+	dnl #######################################################################
+	dnl # Check for X session management libs
+	dnl #######################################################################
+	if test "x$enable_sm" = "xyes"; then
+		enable_sm=no
+		AC_CHECK_LIB(SM, SmcSaveYourselfDone, found_sm_lib=true, , [$x_libpath_add -lICE])
+		if test "x$found_sm_lib" = "xtrue"; then
+			oldCPPFLAGS="$CPPFLAGS"
+			CPPFLAGS="$CPPFLAGS $x_incpath_add"
+			AC_CHECK_HEADERS(X11/SM/SMlib.h, SM_LIBS="$x_libpath_add -lSM -lICE" enable_sm=yes)
+			CPPFLAGS="$oldCPPFLAGS"
+		fi
+
+		if test "x$enable_sm" = "xyes"; then
+			AC_DEFINE(USE_SM, 1, [Define if we're using X Session Management.])
+			AC_SUBST(SM_LIBS)
+		fi
+	fi
+
+	dnl #######################################################################
+	dnl # Check for startup notification
+	dnl #######################################################################
+	if test "x$enable_startup_notification" = "xyes"; then
+		PKG_CHECK_MODULES(STARTUP_NOTIFICATION, [libstartup-notification-1.0 >= 0.5], , [
+			AC_MSG_RESULT(no)
+			enable_startup_notification=no
+		])
+
+		if test "x$enable_startup_notification" = "xyes"; then
+			AC_DEFINE(HAVE_STARTUP_NOTIFICATION, 1, [Define if we're using libstartup-notification.])
+			AC_SUBST(STARTUP_NOTIFICATION_CFLAGS)
+			AC_SUBST(STARTUP_NOTIFICATION_LIBS)
+		fi
+	fi
+
+	dnl #######################################################################
+	dnl # Check for GtkSpell
+	dnl #######################################################################
+	if test "x$enable_gtkspell" = "xyes" ; then
+		PKG_CHECK_MODULES(GTKSPELL, gtkspell-2.0 >= 2.0.2, , [
+			AC_MSG_RESULT(no)
+			enable_gtkspell=no
+		])
+		if test "x$enable_gtkspell" = "xyes" ; then
+			AC_DEFINE(USE_GTKSPELL, 1, [Define if we're using GtkSpell])
+			AC_SUBST(GTKSPELL_CFLAGS)
+			AC_SUBST(GTKSPELL_LIBS)
+		fi
+	fi
+
+	dnl #######################################################################
+	dnl # Check for stuff needed by the Evolution integration plugin.
+	dnl #######################################################################
+	if test "x$enable_gevolution" = "xyes"; then
+		evo_deps="libebook-1.2 libedata-book-1.2"
+		PKG_CHECK_MODULES(EVOLUTION_ADDRESSBOOK, $evo_deps, , [
+			AC_MSG_RESULT(yes)
+			enable_gevolution="no"
+		])
+		if test "x$enable_gevolution" = "xno"; then
+			evo_deps="libebook-1.0 libedata-book-1.0"
+			PKG_CHECK_MODULES(EVOLUTION_ADDRESSBOOK, $evo_deps, [
+				enable_gevolution="yes"
+			], [
+				AC_MSG_RESULT(yes)
+			])
+		fi
+		if test "x$enable_gevolution" = "xyes"; then
+			AC_DEFINE(HAVE_EVOLUTION_ADDRESSBOOK, 1, [Define if we're using evolution addressbook.])
+			AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
+			AC_SUBST(EVOLUTION_ADDRESSBOOK_LIBS)
+		fi
+	fi
+
+	dnl #######################################################################
+	dnl # Check for libsqlite3 (for the Contact Availability Prediction plugin)
+	dnl #######################################################################
+	if test "x$enable_cap" = "xyes"; then
+		PKG_CHECK_MODULES(SQLITE3, sqlite3 >= 3.3,,[
+													AC_MSG_RESULT(no)
+													enable_cap="no"
+													])
+	fi
+
+else # GTK
+	enable_cap=no
+	enable_gevolution=no
+	enable_gtkspell=no
+	enable_screensaver=no
+	enable_sm=no
+	enable_startup_notification=no
+fi	# GTK
+
+AM_CONDITIONAL(ENABLE_GTK, test "x$enable_gtkui" = "xyes")
+AM_CONDITIONAL(BUILD_GEVOLUTION, test "x$enable_gevolution" = "xyes")
+AM_CONDITIONAL(ENABLE_CAP, test "x$enable_cap" = "xyes")
+
+dnl #######################################################################
+dnl # Check for ncurses and other things used by the console UI
+dnl #######################################################################
+GNT_LIBS=""
+GNT_CFLAGS=""
+AC_ARG_WITH(ncurses-headers, [AC_HELP_STRING([--with-ncurses-headers=DIR],
+		[compile gaim-text against the ncurses includes in DIR])],
+		[ac_ncurses_includes="$withval"], [ac_ncurses_includes=""])
+if test "x$enable_consoleui" = "xyes"; then
+	AC_CHECK_LIB(ncursesw, initscr, [GNT_LIBS="-lncursesw"], [enable_consoleui=no])
+	AC_CHECK_LIB(panelw, update_panels, [GNT_LIBS="$GNT_LIBS -lpanelw"], [enable_consoleui=no])
+
+	if test "x$enable_consoleui" = "xyes"; then
+		dnl # Some distros put the headers in ncursesw/, some don't
+		found_ncurses_h=no
+		for location in $ac_ncurses_includes $NCURSES_HEADERS /usr/include/ncursesw /usr/include
+		do
+			f="$location/ncurses.h"
+			AC_CHECK_HEADER($f,[
+				AC_MSG_CHECKING([if $f supports wide characters])
+				AC_TRY_COMPILE([
+					#define _XOPEN_SOURCE_EXTENDED
+					#include <$f>
+				], [
+					#ifndef get_wch
+					# error get_wch not found!
+					#endif
+				], [
+					dir=$location
+					if test x"$dir" != x"." ; then
+						GNT_CFLAGS="-I$dir/"
+					else
+						GNT_CFLAGS=""
+					fi
+
+					found_ncurses_h=yes
+					AC_MSG_RESULT([yes])
+					break
+				], [
+					AC_MSG_RESULT([no])
+				])
+			])
+		done
+
+		if test x"$found_ncurses_h" = x"no" ; then
+			GNT_LIBS=""
+			GNT_CFLAGS=""
+			enable_consoleui=no
+			AC_MSG_RESULT([no])
+		else
+			AC_MSG_RESULT([yes])
+		fi
+	else
+		# ncursesw was not found. Look for plain old ncurses
+		enable_consoleui=yes
+		AC_CHECK_LIB(ncurses, initscr, [GNT_LIBS="-lncurses"], [enable_consoleui=no])
+		AC_CHECK_LIB(panel, update_panels, [GNT_LIBS="$GNT_LIBS -lpanel"], [enable_consoleui=no])
+		AC_DEFINE(NO_WIDECHAR, 1, [Define to 1 if you don't have wide-character support.])
+		if test x"$ac_ncurses_includes" != "x"; then
+			GNT_CFLAGS="-I$ac_ncurses_includes"
+		else
+			if test x"$NCURSES_HEADERS" != "x"; then
+				GNT_CFLAGS="-I$NCURSES_HEADERS"
+			fi
+		fi
+	fi
+
+	PKG_CHECK_MODULES(X11, x11,
+		[AC_DEFINE(HAVE_X11, 1, [Define to 1 if you have X11])], [AC_MSG_RESULT(no)])
+	AC_SUBST(X11_LIBS)
+	AC_SUBST(X11_CFLAGS)
+fi
+
+AC_SUBST(GNT_LIBS)
+AC_SUBST(GNT_CFLAGS)
+AM_CONDITIONAL(ENABLE_GNT, test "x$enable_consoleui" = "xyes")
+
+#AC_CHECK_FUNC(wcwidth, [AC_DEFINE([HAVE_WCWIDTH], [1], [Define to 1 if you have wcwidth function.])])
+
+dnl #######################################################################
+dnl # Check for LibXML2 (required)
+dnl #######################################################################
+PKG_CHECK_MODULES(LIBXML, [libxml-2.0 >= 2.6.0], , [
+	AC_MSG_RESULT(no)
+	AC_MSG_ERROR([
+
+You must have libxml2 >= 2.6.0 development headers installed to build Gaim.
+])])
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_LIBS)
+
+dnl #######################################################################
+dnl # GConf schemas
+dnl #######################################################################
+AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
+AM_CONDITIONAL(USE_GCONFTOOL, test "x$GCONFTOOL" != "xno")
+AM_GCONF_SOURCE_2
+
+dnl #######################################################################
+dnl # Check for GStreamer
+dnl #######################################################################
+AC_ARG_ENABLE(gstreamer,
+	[AC_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])],
+	enable_gst="$enableval", enable_gst="yes")
+PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], , [
+	AC_MSG_RESULT(no)
+	enable_gst="no"
+])
+if test "x$enable_gst" != "xno"; then
+	AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
+	AC_SUBST(GSTREAMER_CFLAGS)
+	AC_SUBST(GSTREAMER_LIBS)
+fi
 
 dnl #######################################################################
 dnl # Check for Meanwhile headers (for Sametime)
 dnl #######################################################################
-PKG_CHECK_MODULES(MEANWHILE,
-	[meanwhile >= 1.0.0 meanwhile < 2.0.0],
-	[have_meanwhile="yes"],
-	[have_meanwhile="no"])
+PKG_CHECK_MODULES(MEANWHILE, [meanwhile >= 1.0.0 meanwhile < 2.0.0], [
+	have_meanwhile="yes"
+], [
+	AC_MSG_RESULT(no)
+	have_meanwhile="no"
+])
 AC_SUBST(MEANWHILE_CFLAGS)
 AC_SUBST(MEANWHILE_LIBS)
 
-
-
 dnl #######################################################################
 dnl # Check for Howl headers (for Bonjour)
 dnl #######################################################################
-AC_ARG_WITH(howl-includes, [AC_HELP_STRING([--with-howl-includes=DIR], [Compile the Bonjour plugin against the Howl includes in DIR])], [ac_howl_includes="$withval"], [ac_howl_includes="no"])
-AC_ARG_WITH(howl-libs, [AC_HELP_STRING([--with-howl-libs=DIR], [Compile the Bonjour plugin against the Howl libs in DIR])], [ac_howl_libs="$withval"], [ac_howl_libs="no"])
+AC_ARG_WITH(howl-includes, [AC_HELP_STRING([--with-howl-includes=DIR], [compile the Bonjour plugin against the Howl includes in DIR])], [ac_howl_includes="$withval"], [ac_howl_includes="no"])
+AC_ARG_WITH(howl-libs, [AC_HELP_STRING([--with-howl-libs=DIR], [compile the Bonjour plugin against the Howl libs in DIR])], [ac_howl_libs="$withval"], [ac_howl_libs="no"])
 HOWL_CFLAGS=""
 HOWL_LIBS=""
 
+dnl Attempt to autodetect avahi-compat-howl
+PKG_CHECK_MODULES(HOWL, avahi-compat-howl, [
+	howlincludes="yes"
+	howllibs="yes"
+], [
+	AC_MSG_RESULT(no)
+	howlincludes="no"
+	howllibs="no"
+])
+
 dnl Attempt to autodetect Howl
-PKG_CHECK_MODULES(HOWL, howl,
-	[howlincludes="yes" howllibs="yes"],
-	[howlincludes="no" howllibs="no"])
+if test "x$howlincludes" = "xno"; then
+	PKG_CHECK_MODULES(HOWL, howl, [
+		howlincludes="yes"
+		howllibs="yes"
+	], [
+		AC_MSG_RESULT(no)
+		howlincludes="no"
+		howllibs="no"
+	])
+fi
 
 dnl Override HOWL_CFLAGS if the user specified an include dir
 if test "$ac_howl_includes" != "no"; then
@@ -146,20 +532,18 @@
 
 dnl Override HOWL_LIBS if the user specified a libs dir
 if test "$ac_howl_libs" != "no"; then
-	HOWL_LIBS="-L$ac_howl_libs"
+	HOWL_LIBS="-L$ac_howl_libs -lhowl"
 fi
 AC_CHECK_LIB(howl, sw_discovery_init, [howllibs=yes], [howllibs=no], $HOWL_LIBS)
 
 AC_SUBST(HOWL_CFLAGS)
 AC_SUBST(HOWL_LIBS)
 
-
-
 dnl #######################################################################
 dnl # Check for SILC client includes and libraries
 dnl #######################################################################
-AC_ARG_WITH(silc-includes, [AC_HELP_STRING([--with-silc-includes=DIR], [Compile the SILC plugin against includes in DIR])], [ac_silc_includes="$withval"], [ac_silc_includes="no"])
-AC_ARG_WITH(silc-libs, [AC_HELP_STRING([--with-silc-libs=DIR], [Compile the SILC plugin against the SILC libs in DIR])], [ac_silc_libs="$withval"], [ac_silc_libs="no"])
+AC_ARG_WITH(silc-includes, [AC_HELP_STRING([--with-silc-includes=DIR], [compile the SILC plugin against includes in DIR])], [ac_silc_includes="$withval"], [ac_silc_includes="no"])
+AC_ARG_WITH(silc-libs, [AC_HELP_STRING([--with-silc-libs=DIR], [compile the SILC plugin against the SILC libs in DIR])], [ac_silc_libs="$withval"], [ac_silc_libs="no"])
 SILC_CFLAGS=""
 SILC_LIBS=""
 if test -n "$with_silc_includes" || test -n "$with_silc_libs"; then
@@ -172,14 +556,20 @@
 		have_silc="yes"
 		silcincludes="yes"
 		silcclient="yes"
-	], have_silc="no")
+	], [
+		AC_MSG_RESULT(no)
+		have_silc="no"
+	])
 	dnl If silcclient.pc wasn't found, check for just silc.pc
 	if test "x$have_silc" = "xno"; then
 		PKG_CHECK_MODULES(SILC, silc, [
 			have_silc="yes"
 			silcincludes="yes"
 			silcclient="yes"
-		], have_silc="no")
+		], [
+			AC_MSG_RESULT(no)
+			have_silc="no"
+		])
 	fi
 else
 	if test "$ac_silc_includes" != "no"; then
@@ -208,25 +598,93 @@
 #include <silcmime.h>
 		], [], [
 		AC_MSG_RESULT(yes)
-		AC_DEFINE(HAVE_SILCMIME_H, 1, [define if we have silcmime.h])
+		AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h])
 		], [
 		AC_MSG_RESULT(no)
 		])
 	CPPFLAGS="$CPPFLAGS_save"
 fi
 
+dnl #######################################################################
+dnl # Check for Gadu-Gadu client includes and libraries
+dnl #######################################################################
+AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the Gadu-Gadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"])
+AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the Gadu-Gadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"])
+GADU_CFLAGS=""
+GADU_LIBS=""
+if test -n "$with_gadu_includes" || test -n "$with_gadu_libs"; then
+	gadu_manual_check="yes"
+else
+	gadu_manual_check="no"
+fi
+if test "x$gadu_manual_check" = "xno"; then
+	PKG_CHECK_MODULES(GADU, libgadu, [
+		gadu_includes="yes"
+		gadu_libs="yes"
+	], [
+		AC_MSG_RESULT(no)
+	])
+else
+	if test "$ac_gadu_includes" != "no"; then
+		GADU_CFLAGS="-I$ac_gadu_includes"
+	fi
+	CPPFLAGS_save="$CPPFLAGS"
+	CPPFLAGS="$CPPFLAGS $GADU_CFLAGS"
+	AC_CHECK_HEADER(libgadu.h, [gadu_includes=yes])
+	CPPFLAGS="$CPPFLAGS_save"
+
+	if test "$ac_gadu_libs" != "no"; then
+		GADU_LIBS="-L$ac_gadu_libs"
+	fi
+	GADU_LIBS="$GADU_LIBS -lgadu"
+	AC_CHECK_LIB(gadu, gg_libgadu_version, [gadu_libs=yes], , $GADU_LIBS)
+fi
+
+if test "x$gadu_libs" = "xyes"; then
+	AC_MSG_CHECKING(for libgadu GPL compatibility)
+	CPPFLAGS_save="$CPPFLAGS"
+	CPPFLAGS="$CPPFLAGS $GADU_CFLAGS"
+	AC_TRY_COMPILE([#include <libgadu.h>], [
+#ifdef __GG_LIBGADU_HAVE_OPENSSL
+#error "libgadu is not compatible with the GPL when compiled with OpenSSL support."
+#endif
+	], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE([HAVE_LIBGADU], [1],
+			[Define to 1 if you have libgadu.])
+	], [
+		AC_MSG_RESULT(no)
+		echo
+		echo
+		echo "libgadu is not compatible with the GPL when compiled with OpenSSL support."
+		echo "Please recompile libgadu using:"
+		echo "./autogen.sh --disable-libgadu-openssl --disable-static --enable-shared"
+		echo "Then rerun this ./configure"
+		echo
+		echo
+		GADU_LIBS=""
+		GADU_CFLAGS=""
+		gadu_libs=no
+	])
+	CPPFLAGS="$CPPFLAGS_save"
+fi
+
+AM_CONDITIONAL(USE_INTERNAL_LIBGADU, test "x$gadu_libs" != "xyes")
+
+AC_SUBST(GADU_LIBS)
+AC_SUBST(GADU_CFLAGS)
+
 
 AC_ARG_ENABLE(distrib,,,enable_distrib=no)
 AM_CONDITIONAL(DISTRIB, test "x$enable_distrib" = "xyes")
-AC_ARG_ENABLE(prpls,   [  --disable-prpls         don't build dynamic protocol plugins],,enable_prpls=yes)
 DYNAMIC_PRPLS=all
-AC_ARG_WITH(static-prpls,    [  --with-static-prpls     link in certain protocols statically],[STATIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`],STATIC_PRPLS="")
+AC_ARG_WITH(static-prpls, [AC_HELP_STRING([--with-static-prpls], [Link to certain protocols statically])], [STATIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`], [STATIC_PRPLS=""])
 if test "x$STATIC_PRPLS" != "x" -a "x$DYNAMIC_PRPLS" = "xall"; then
 	DYNAMIC_PRPLS=""
 fi
 
 if test "x$STATIC_PRPLS" = "xall" ; then
-	STATIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr"
+	STATIC_PRPLS="bonjour gg irc jabber msn novell oscar qq sametime silc simple yahoo zephyr"
 fi
 if test "x$have_meanwhile" != "xyes" ; then
 	STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'`
@@ -258,6 +716,7 @@
 		msn)		static_msn=yes ;;
 		novell)		static_novell=yes ;;
 		oscar)		static_oscar=yes ;;
+		qq)		static_qq=yes ;;
 		sametime)	static_sametime=yes ;;
 		silc)		static_silc=yes ;;
 		simple)		static_simple=yes ;;
@@ -274,6 +733,7 @@
 AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes")
 AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes")
 AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes")
+AM_CONDITIONAL(STATIC_QQ, test "x$static_qq" = "xyes")
 AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
 AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes")
 AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes")
@@ -286,10 +746,10 @@
 
 AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`])
 if test "x$DYNAMIC_PRPLS" = "xall" ; then
-	DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar sametime silc simple yahoo zephyr"
+	DYNAMIC_PRPLS="bonjour gg irc jabber msn novell oscar qq sametime silc simple yahoo zephyr"
 fi
 if test "x$have_meanwhile" != "xyes"; then
-        DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
+	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
 fi
 if test "x$howlincludes" != "xyes" -o "x$howllibs" != "xyes"; then
 	DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/bonjour//'`
@@ -307,6 +767,7 @@
 		msn)		dynamic_msn=yes ;;
 		novell)		dynamic_novell=yes ;;
 		oscar)		dynamic_oscar=yes ;;
+		qq)		dynamic_qq=yes ;;
 		sametime)	dynamic_sametime=yes ;;
 		silc)		dynamic_silc=yes ;;
 		simple)		dynamic_simple=yes ;;
@@ -323,6 +784,7 @@
 AM_CONDITIONAL(DYNAMIC_MSN, test "x$dynamic_msn" = "xyes")
 AM_CONDITIONAL(DYNAMIC_NOVELL, test "x$dynamic_novell" = "xyes")
 AM_CONDITIONAL(DYNAMIC_OSCAR, test "x$dynamic_oscar" = "xyes")
+AM_CONDITIONAL(DYNAMIC_QQ, test "x$dynamic_qq" = "xyes")
 AM_CONDITIONAL(DYNAMIC_SAMETIME, test "x$dynamic_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
 AM_CONDITIONAL(DYNAMIC_SILC, test "x$dynamic_silc" = "xyes" -a "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes")
 AM_CONDITIONAL(DYNAMIC_SIMPLE, test "x$dynamic_simple" = "xyes")
@@ -330,44 +792,15 @@
 AM_CONDITIONAL(DYNAMIC_YAHOO, test "x$dynamic_yahoo" = "xyes")
 AM_CONDITIONAL(DYNAMIC_ZEPHYR, test "x$dynamic_zephyr" = "xyes")
 
-AC_ARG_ENABLE(audio,   [  --disable-audio         compile without libao/libaudiofile for sound playing],,enable_audio=yes)
-AC_ARG_ENABLE(mono,    [  --enable-mono           compile with Mono runtime support],,enable_mono=no)
-AC_ARG_ENABLE(plugins, [  --disable-plugins       compile without plugin support],,enable_plugins=yes)
-AC_ARG_ENABLE(perl,    [  --disable-perl          compile without perl scripting],,enable_perl=yes)
-AC_ARG_ENABLE(tcl,     [  --disable-tcl           compile without Tcl scripting],,enable_tcl=yes)
-AC_ARG_WITH(tclconfig, [  --with-tclconfig=DIR    directory containing tclConfig.sh])
-AC_ARG_ENABLE(tk,      [  --disable-tk            compile without Tcl support for Tk],,enable_tk=yes)
-AC_ARG_WITH(tkconfig,  [  --with-tkconfig=DIR     directory containing tkConfig.sh])
-AC_ARG_ENABLE(gtkspell, [  --disable-gtkspell      compile without GtkSpell automatic spell checking],,enable_gtkspell=yes)
-AC_ARG_ENABLE(debug,   [  --enable-debug          compile with debugging support],,enable_debug=no)
-AC_ARG_ENABLE(fatal-asserts,   [  --enable-fatal-asserts  make assertions fatal (useful for debugging)],,enable_fatal_asserts=no)
-dnl We know Gaim won't compile with deprecated APIs disabled.
-dnl We have no desire to support two different versions of the
-dnl same code when it's not necessary, so we're sticking with
-dnl the deprecated APIs in many cases.
-dnl This option is being left in case things change.
-dnl AC_ARG_ENABLE(deprecated,    [  --disable-deprecated    compile without deprecated API usage],,enable_deprecated=yes)
-AC_ARG_ENABLE(fortify, [  --disable-fortify       compile without FORTIFY_SOURCE support],,enable_fortify=yes)
-AC_ARG_ENABLE(screensaver,   [  --disable-screensaver   compile without X screensaver extension],,enable_xss=yes)
-AC_ARG_ENABLE(sm,      [  --disable-sm            compile without X session management support],,enable_sm=yes)
-AC_ARG_WITH(krb4,      [  --with-krb4=PREFIX      compile Zephyr plugin with Kerberos 4 support],kerberos="$withval",kerberos="no")
-AC_ARG_WITH(zephyr,    [  --with-zephyr=PREFIX    compile Zephyr plugin against external libzephyr],zephyr="$withval",zephyr="no")
+AC_ARG_ENABLE(plugins, [AC_HELP_STRING([--disable-plugins], [compile without plugin support])], , enable_plugins=yes)
+AC_ARG_WITH(krb4, [AC_HELP_STRING([--with-krb4=PREFIX], [compile Zephyr plugin with Kerberos 4 support])], kerberos="$withval", kerberos="no")
+AC_ARG_WITH(zephyr, [AC_HELP_STRING([--with-zephyr=PREFIX], [compile Zephyr plugin against external libzephyr])], zephyr="$withval", zephyr="no")
 AM_CONDITIONAL(EXTERNAL_LIBZEPHYR, test "x$zephyr" != "xno")
 
 AC_CHECK_HEADER(sys/utsname.h)
 AC_CHECK_FUNC(uname)
 
-if test "x$enable_debug" = "xyes" ; then
-	AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.])
-fi
-
-if test "x$enable_fatal_asserts" = "xyes" ; then
-	AC_DEFINE(GAIM_FATAL_ASSERTS, 1, [Define to make assertions fatal (useful for debugging).])
-fi
-
-if test "x$enable_deprecated" = "xno"; then
-	DEBUG_CFLAGS="$DEBUG_CFLAGS -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
-fi
+AC_ARG_ENABLE(fortify, [AC_HELP_STRING([--disable-fortify], [compile without FORTIFY_SOURCE support])], , enable_fortify=yes)
 
 if test "x$GCC" = "xyes"; then
 	dnl We enable -Wall later.
@@ -446,76 +879,65 @@
 fi
 AC_SUBST(CFLAGS)
 
-AM_PATH_GLIB_2_0(2.0.0,,AC_MSG_ERROR([
-*** GLib 2.0 is required to build Gaim; please make sure you have the GLib
-*** development headers installed. The latest version of GLib is
-*** always available at http://www.gtk.org/.]))
-AM_PATH_GTK_2_0(2.0.0,,AC_MSG_ERROR([
-*** GTK+ 2.0 is required to build Gaim; please make sure you have the GTK+
-*** development headers installed. The latest version of GTK+ is
-*** always available at http://www.gtk.org/.]))
-
 AC_PATH_PROG(gaimpath, gaim)
-AC_SUBST(GTK_CFLAGS)
-AC_SUBST(GLIB_CFLAGS)
-
-AC_PATH_XTRA
-# We can't assume that $x_libraries will be set, because autoconf does not
-# set it in the case when the X libraries are in a standard place.
-# Ditto for $x_includes
-if test X"$x_libraries" = X"" || test X"$x_libraries" = XNONE; then
-	x_libpath_add=
-else
-	x_libpath_add="-L$x_libraries"
-fi
-if test X"$x_includes" = X"" || test X"$x_includes" = XNONE; then
-	x_incpath_add=
-else
-	x_incpath_add="-I$x_includes"
-fi
 
 dnl #######################################################################
 dnl # Check for DBUS libraries
 dnl #######################################################################
 
-AC_ARG_ENABLE(dbus,     [  --enable-dbus           enable DBUS support],,enable_dbus=yes)
+AC_ARG_ENABLE(dbus, [AC_HELP_STRING([--enable-dbus], [enable DBUS support])], , enable_dbus=yes)
 
 if test "x$enable_dbus" = "xyes" ; then
-   AC_CHECK_PROG(enable_dbus, dbus-binding-tool, yes, no)
+	AC_CHECK_PROG(enable_dbus, dbus-binding-tool, yes, no)
 fi
 
 if test "x$enable_dbus" = "xyes" ; then
-   	PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.35 dbus-glib-1 >= 0.35],
-	[
+	PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.35 dbus-glib-1 >= 0.35], [
 		AC_SUBST(DBUS_CFLAGS)
 		AC_SUBST(DBUS_LIBS)
 		enable_dbus=yes
+	], [
+		AC_MSG_RESULT(no)
+		enable_dbus=no
+	])
+
+dnl     Check for libnm_glib; if we don't have it, oh well
+	LIBNM_CFLAGS=""
+	LIBNM_LIBS=""
+	PKG_CHECK_MODULES(LIBNM, libnm_glib,
+	[
+    		AC_DEFINE(HAVE_LIBNM, 1, [Check to see if we have NetworkManager])
 	],
 	[
-		enable_dbus=no
+                AC_MSG_RESULT(no)
 	])
+	AC_SUBST(LIBNM_CFLAGS)
+	AC_SUBST(LIBNM_LIBS)
 fi
 
-dnl  Why do we need python?  
+dnl #######################################################################
+dnl # Check for Python
+dnl #######################################################################
 
-dnl  Python scripts are used to auto-generate about 3000 lines of C
-dnl  and XML code that wraps (part of) the existing Gaim API so that
-dnl  it is now accessible through DBUS.
+dnl Python scripts are used to auto-generate about 3000 lines of C
+dnl and XML code that wraps (part of) the existing Gaim API so that
+dnl it is now accessible through DBUS.
 
-dnl  Python is only required if --enable-dbus is used, and only for
-dnl  the build process to generate the code, not for running gaim.
-dnl  This autogenerated code is system-independent, so in principle we
-dnl  can generate all of it before shipping.  But I thought adding
-dnl  auto-generated stuff to the CVS is inelegant.  Alternatively,
-dnl  these python scripts could be rewritten in C (brrrr ...).
+dnl Python is only required if --enable-dbus is used, and only for
+dnl the build process to generate the code, not for running gaim.
+dnl This autogenerated code is system-independent, so in principle we
+dnl can generate all of it before shipping.  But I thought adding
+dnl auto-generated stuff to the repository is inelegant.
+dnl Alternatively, these python scripts could be rewritten
+dnl in C (brrrr ...).
 
 AC_ARG_WITH([python],
-			AC_HELP_STRING([--with-python],
-						   [Which python interpreter to use for dbus code generation]),
+			AC_HELP_STRING([--with-python=PATH],
+						   [which python interpreter to use for dbus code generation]),
 			PYTHON=$withval)
 
 if test "x$enable_dbus" = "xyes" ; then
-	if test -z "$PYTHON" ; then
+	if test -z "$PYTHON" -o "x$PYTHON" = "xyes"; then
 		AC_PATH_PROG([PYTHON], [python], [no])
 	fi
 
@@ -532,174 +954,72 @@
 	fi
 fi
 
-dnl  Here we locate the directory containing DBus .service files for
-dnl  the session bus.  Adapted from the guifications project.
+dnl ###########################################################################
+dnl # Find the D-Bus services dir.
+dnl #
+dnl # This is a 3 step process that
+dnl #
+dnl # 1. checks if --with-dbus-services was set, if so use that.
+dnl # 2. checks if --prefix was given, if so use that.
+dnl # 3. fallbacks to installing into what should be the correct system
+dnl #    directories.
+dnl #
+dnl # This is still prone to error if one of the legacy directories exist
+dnl # although a newer dbus is installed.  But I have tried to order the
+dnl # directory searching to keep this situation at a minimum.
+dnl ###########################################################################
+AC_ARG_WITH(dbus-services, [AC_HELP_STRING([--with-dbus-services=<dir>], [where the D-Bus services directory is located.])])
+
+DBUS_SERVICES_DIR=""
+
+if test x"$enable_dbus" = "xyes" ; then
+	AC_MSG_CHECKING([location of the D-Bus services directory])
+	if ! test -z "$with_dbus_services" ; then
+		if ! test -d "$with_dbus_services" ; then
+			AC_MSG_ERROR([$with_dbus_services does not exist, if this is the correct location please make sure that it exists.])
+		fi
 
-AC_ARG_WITH(dbus-session-dir, [  --with-dbus-session-dir=<dir>   Location of the D-BUS session directory.])
+		DBUS_SERVICES_DIR="$with_dbus_services"
+	else
+		if test x"$prefix" = x"NONE" ; then
+			dnl # no prefix given, so we look for the correct dbus system paths.
+			dnl # if a prefix is given, we use it.
+
+			serviceprefixes="$datadir $libdir /usr/share /usr/local/share"
+			DBUS_SERVICES_DIR=""
+
+			for d in $serviceprefixes ; do
+				dir="$d/dbus-1/services"
+				if test -d $dir ; then
+					DBUS_SERVICES_DIR="$dir"
+					break
+				fi
+			done
+
+			if test -z $DBUS_SERVICES_DIR ; then
+				AC_MSG_ERROR([D-Bus services directory was not found!  Please use --with-dbus-services and specify it's location.])
+			fi
+		else
+			DBUS_SERVICES_DIR="$datadir/dbus-1/services"
+		fi
+	fi
+	AC_MSG_RESULT([$DBUS_SERVICES_DIR])
+	AC_DEFINE(HAVE_DBUS, 1, [Define if we are re using DBUS.])
+fi
+AC_SUBST(DBUS_SERVICES_DIR)
 
 if test "x$enable_dbus" = "xyes" ; then
-    AC_MSG_CHECKING([location of the D-BUS session directory])
-    if ! test -z "$with_dbus_session_dir"; then
-		if ! test -d "$with_dbus_session_dir"; then
-			AC_MSG_WARN([$with_dbus_session_dir does not exist, if this is the correct location please make sure that it exists.])
-			enable_dbus=no
-		fi
-		DBUS_SESSION_DIR="$with_dbus_session_dir"
-    else
-	dnl # add more to this as needed
-	servicesprefixes="$DATADIR $LIBDIR /usr/share /usr/local/share"
-	DBUS_SESSION_DIR=""
-
-	for p in $servicesprefixes; do
-	    dir="$p/dbus-1/services"
-	    if test -d $dir; then
-		DBUS_SESSION_DIR="$dir"
-		break
-	    fi
-	done
-
-	if test -z $DBUS_SESSION_DIR; then
-	    AC_MSG_WARN([D-BUS session directory was not found!  Please use --with-dbus-session-dir and specify its location.])
-	    enable_dbus=no
-	fi
-    fi
-fi
-
-if test "x$enable_dbus" = "xyes" ; then
-    AC_MSG_RESULT([$DBUS_SESSION_DIR])
-    AC_SUBST(DBUS_SESSION_DIR)
-    AC_DEFINE(HAVE_DBUS, 1, [Define if we are re using DBUS.])
-    echo "Building with DBUS support"
+	echo "Building with DBUS support"
 else
-    echo "Building without DBUS support"
+	echo "Building without DBUS support"
 fi
 
 AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes")
 
-
-
-
-
-
-dnl #######################################################################
-dnl # Check for startup notification
-dnl #######################################################################
-AC_ARG_ENABLE(startup-notification, [  --disable-startup-notification    compile without startup notification support],,enable_startup_notification=yes)
-
-if test "x$enable_startup_notification" = "xyes"; then
-	PKG_CHECK_MODULES(STARTUP_NOTIFICATION, libstartup-notification-1.0 >= 0.5,
-	[
-		AC_DEFINE(HAVE_STARTUP_NOTIFICATION, 1, [Define if we're using libstartup-notification.])
-		echo "Building with libstartup-notification"
-		enable_startup_notification=yes
-	],
-	[
-		echo "Building without libstartup-notification"
-		enable_startup_notification=no
-	])
-
-	AC_SUBST(STARTUP_NOTIFICATION_CFLAGS)
-	AC_SUBST(STARTUP_NOTIFICATION_LIBS)
-fi
-
-
-dnl #######################################################################
-dnl # Check for stuff needed by the evolution integration plugin.
-dnl #######################################################################
-build_gevo=no
-AC_ARG_ENABLE(gevolution, [  --disable-gevolution    compile without the Gaim-Evolution plugin],,enable_gevolution=yes)
-
-if test "x$enable_gevolution" = "xyes"; then
-	evo_deps="libebook-1.2 libedata-book-1.2"
-	PKG_CHECK_MODULES(EVOLUTION_ADDRESSBOOK, $evo_deps, [
-		AC_DEFINE(HAVE_EVOLUTION_ADDRESSBOOK, 1, [Define if we're using evolution addressbook.])
-		build_gevo=yes
-	], build_gevo=no)
-	if test "x$build_gevo" = "xno"; then
-		evo_deps="libebook-1.0 libedata-book-1.0"
-		PKG_CHECK_MODULES(EVOLUTION_ADDRESSBOOK, $evo_deps, [
-			AC_DEFINE(HAVE_EVOLUTION_ADDRESSBOOK, 1, [Define if we're using evolution addressbook.])
-			build_gevo=yes
-		], build_gevo=no)
-	fi
-
-	AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
-	AC_SUBST(EVOLUTION_ADDRESSBOOK_LIBS)
-fi
-
-AM_CONDITIONAL(BUILD_GEVOLUTION, test "x$build_gevo" = "xyes")
-
-dnl #######################################################################
-dnl # Check for XScreenSaver
-dnl #######################################################################
-if test "x$enable_xss" = "xyes" ; then
-	old_LIBS="$LIBS"
-	LIBS="$LIBS $GTK_LIBS $x_libpath_add"
-	XSS_LIBS="no"
-	XSS_HEADERS="no"
-	AC_CHECK_LIB(Xext, XScreenSaverRegister,[XSS_LIBS="$X_LIBS $X_PRE_LIBS -lX11 -lXext $X_EXTRA_LIBS"],[],[-lX11 -lXext -lm])
-	AC_CHECK_LIB(Xss, XScreenSaverRegister,[XSS_LIBS="$X_LIBS $X_PRE_LIBS -lX11 -lXext $X_LIBS $X_EXTRA_LIBS -lXss"],[],[-lX11 -lXext -lm])
-	if test \! "$XSS_LIBS" = "no"; then
-		oldCPPFLAGS="$CPPFLAGS"
-		CPPFLAGS="$CPPFLAGS $x_incpath_add"
-		AC_TRY_COMPILE([
-#include <X11/Xlib.h>
-#include <X11/extensions/scrnsaver.h>
-				],[],[
-				AC_DEFINE(USE_SCREENSAVER, 1, [Define if we're using XScreenSaver.])],[enable_xss=no]
-				)
-		CPPFLAGS="$oldCPPFLAGS"
-	else
-	       XSS_LIBS=""
-	       enable_xss=no
-	fi
-	LIBS="$old_LIBS"
-else
-	XSS_LIBS=""
-	enable_xss=no
-fi
-AC_SUBST(XSS_LIBS)
-
-
-dnl #######################################################################
-dnl # Check for X session management libs
-dnl #######################################################################
-if test "x$enable_sm" = "xyes"; then
-	enable_sm=no
-	AC_CHECK_LIB(SM, SmcSaveYourselfDone, found_sm_lib=true, , [$x_libpath_add -lICE])
-	if test "$found_sm_lib" = "true"; then
-		oldCPPFLAGS="$CPPFLAGS"
-		CPPFLAGS="$CPPFLAGS $x_incpath_add"
-		AC_CHECK_HEADERS(X11/SM/SMlib.h, SM_LIBS="$x_libpath_add -lSM -lICE" enable_sm=yes)
-		CPPFLAGS="$oldCPPFLAGS"
-	fi
-else
-	SM_LIBS=""
-	enable_sm=no
-fi
-AC_SUBST(SM_LIBS)
-if test "$enable_sm" = "yes"; then
-	AC_DEFINE(USE_SM, 1, [Define if we're using X Session Management.])
-fi
-
-
-AC_DEFUN([GC_TM_GMTOFF],
-[AC_REQUIRE([AC_STRUCT_TM])dnl
-AC_CACHE_CHECK([for tm_gmtoff in struct tm], ac_cv_struct_tm_gmtoff,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <$ac_cv_struct_tm>], [struct tm tm; tm.tm_gmtoff;],
-  ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no)])
-if test "$ac_cv_struct_tm_gmtoff" = yes; then
-  AC_DEFINE(HAVE_TM_GMTOFF, 1, [tm_gmtoff is available.])
-fi
-])
-
-GC_TM_GMTOFF
-
 dnl #######################################################################
 dnl # Check for Mono support
 dnl #######################################################################
-
+AC_ARG_ENABLE(mono, [AC_HELP_STRING([--enable-mono], [compile with Mono runtime support (experimental)])], , enable_mono=no)
 if test x"$enable_mono" = x"yes" ; then
 	AC_MSG_CHECKING(for Mono compile flags)
 	MONO_CFLAGS=`pkg-config --cflags mono 2> /dev/null`
@@ -711,19 +1031,19 @@
 	else
 		MONO_LIBS=`pkg-config --libs mono 2> /dev/null`
 		AC_MSG_RESULT(ok)
-		
+
 		oldLIBS="$LIBS"
 		LIBS="$LIBS $MONO_LIBS"
 		AC_MSG_CHECKING(for libmono)
 		AC_CHECK_FUNCS(mono_jit_init, [], enable_mono=no)
 		LIBS="$oldLIBS"
-		
+
 		oldCPPFLAGS="$CPPFLAGS"
 		CPPFLAGS="$CPPFLAGS $MONO_CFLAGS"
 		AC_CHECK_HEADERS(mono/jit/jit.h, [], enable_mono=no)
 		AC_CHECK_HEADERS(mono/metadata/object.h, [], enable_mono=no)
 		CPPFLAGS="$oldCPPFLAGS"
-		
+
 		AC_DEFINE(ENABLE_MONO, 1, [Define if mono enabled.])
 	fi
 else
@@ -739,6 +1059,8 @@
 dnl #######################################################################
 dnl # Check for Perl support
 dnl #######################################################################
+AC_ARG_ENABLE(perl, [AC_HELP_STRING([--disable-perl], [compile without perl scripting])], , enable_perl=yes)
+
 if test "$enable_plugins" = no ; then
 	enable_perl=no
 fi
@@ -788,10 +1110,10 @@
 		AM_CONDITIONAL(USE_PERL, false)
 		AC_MSG_WARN(Compiling perl requires ExtUtils::MakeMaker)
 	else
+		AC_DEFINE(HAVE_PERL, [1], [Compile with support for perl])
 		AC_SUBST(PERL_CFLAGS)
 		AC_SUBST(PERL_LIBS)
 		AM_CONDITIONAL(USE_PERL, true)
-		AC_DEFINE(HAVE_PERL, [1], [Compile with support for perl])
 
 		dnl This is almost definitely wrong, but in case there's
 		dnl something I'm missing, I'll leave it in.
@@ -813,8 +1135,8 @@
 		fi
 
 		AC_ARG_WITH(perl-lib,
-		[  --with-perl-lib=[site|vendor|DIR] Specify where to install the
-                                  Perl libraries for gaim. Default is site.],
+		[AC_HELP_STRING([--with-perl-lib=[site|vendor|DIR]],
+			[specify where to install the Perl libraries for gaim. Default is site.])],
 		[
 			if test "x$withval" = xsite; then
 				PERL_MM_PARAMS=""
@@ -879,26 +1201,26 @@
 dnl These two are inverses of each other <-- stolen from evolution!
 
 AC_ARG_ENABLE(gnutls,
-	[  --enable-gnutls=[yes,no]  Attempt to use GNUTLS for SSL support (preferred) [default=yes]],
+	[  --enable-gnutls=[yes,no]  attempt to use GnuTLS for SSL support (preferred) [default=yes]],
 	[enable_gnutls="$enableval"],
 	[enable_gnutls="yes"])
 
 AC_ARG_ENABLE(nss,
-	[  --enable-nss=[yes,no,static]    Attempt to use Mozilla libnss for SSL support [default=yes]],
+	[  --enable-nss=[yes,no,static]    attempt to use Mozilla libnss for SSL support [default=yes]],
 	[enable_nss="$enableval"],
 	[enable_nss="yes"])
 
-msg_ssl="None (MSN will not work without SSL!)"
+msg_ssl="None (MSN and Google Talk will not work without SSL!)"
 
 dnl #
-dnl # Check for GNUTLS if it's specified.
+dnl # Check for GnuTLS if it's specified.
 dnl #
 if test "x$enable_gnutls" != "xno"; then
 	enable_gnutls="no"
 	prefix=`eval echo $prefix`
 
 	AC_ARG_WITH(gnutls-includes,
-		[  --with-gnutls-includes=PREFIX   Location of GNUTLS includes.],
+		[  --with-gnutls-includes=PREFIX   location of GnuTLS includes.],
 		[ with_gnutls_includes="$withval" ],
 		[ with_gnutls_includes="$prefix/include" ])
 
@@ -907,7 +1229,7 @@
 	if test "x$with_gnutls_includes" != "xno"; then
 		CPPFLAGS_save="$CPPFLAGS"
 
-		AC_MSG_CHECKING(for GNUTLS includes)
+		AC_MSG_CHECKING(for GnuTLS includes)
 		AC_MSG_RESULT("")
 
 		CPPFLAGS="$CPPFLAGS -I$with_gnutls_includes"
@@ -923,35 +1245,35 @@
 			GNUTLS_CFLAGS=""
 		fi
 	else
-		AC_MSG_CHECKING(for GNUTLS includes)
+		AC_MSG_CHECKING(for GnuTLS includes)
 		AC_MSG_RESULT(no)
 	fi
 
 	AC_ARG_WITH(gnutls-libs,
-		[  --with-gnutls-libs=PREFIX       Location of GNUTLS libraries.],
+		[AC_HELP_STRING([--with-gnutls-libs=PREFIX], [location of GnuTLS libraries.])],
 		[ with_gnutls_libs="$withval" ])
 
 	if test "x$with_gnutls_libs"     != "xno" -a \
 	        "x$have_gnutls_includes" != "xno"; then
 
-		LDFLAGS_save="$LDFLAGS"
+		LIBS_save="$LIBS"
 
 		case $with_gnutls_libs in
 			""|-L*) ;;
 			*) with_gnutls_libs="-L$with_gnutls_libs" ;;
 		esac
 
-		AC_CACHE_CHECK([for GNUTLS libraries], gnutls_libs,
+		AC_CACHE_CHECK([for GnuTLS libraries], gnutls_libs,
 		[
-			LDFLAGS="$LDFLAGS $with_gnutls_libs -lgnutls -lgcrypt"
+			LIBS="$LIBS $with_gnutls_libs -lgnutls -lgcrypt"
 			AC_TRY_LINK_FUNC(gnutls_init, gnutls_libs="yes", gnutls_libs="no")
-			LDFLAGS="$LDFLAGS_save"
+			LIBS="$LIBS_save"
 		])
 
 		if test "x$gnutls_libs" != "xno"; then
-			AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GNUTLS])
+			AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS])
 			AC_DEFINE(HAVE_SSL)
-			msg_gnutls="GNUTLS"
+			msg_gnutls="GnuTLS"
 			GNUTLS_LIBS="$with_gnutls_libs -lgnutls -lgcrypt"
 
 			enable_gnutls="yes"
@@ -960,7 +1282,7 @@
 			GNUTLS_LIBS=""
 		fi
 	else
-		AC_MSG_CHECKING(for GNUTLS libraries)
+		AC_MSG_CHECKING(for GnuTLS libraries)
 		AC_MSG_RESULT(no)
 	fi
 else
@@ -975,24 +1297,24 @@
 
 
 dnl #
-dnl # Check for NSS if it's specified, or if GNUTLS checks failed.
+dnl # Check for NSS if it's specified, or if GnuTLS checks failed.
 dnl #
 if test "x$enable_nss" != "xno"; then
 
 	AC_ARG_WITH(nspr-includes,
-		[  --with-nspr-includes=PREFIX     Specify location of Mozilla nspr4 includes.],
+		[AC_HELP_STRING([--with-nspr-includes=PREFIX], [specify location of Mozilla nspr4 includes.])],
 		[with_nspr_includes="$withval"])
 
 	AC_ARG_WITH(nspr-libs,
-		[  --with-nspr-libs=PREFIX         Specify location of Mozilla nspr4 libs.],
+		[AC_HELP_STRING([--with-nspr-libs=PREFIX], [specify location of Mozilla nspr4 libs.])],
 		[with_nspr_libs="$withval"])
 
 	AC_ARG_WITH(nss-includes,
-		[  --with-nss-includes=PREFIX      Specify location of Mozilla nss3 includes.],
+		[AC_HELP_STRING([--with-nss-includes=PREFIX], [specify location of Mozilla nss3 includes.])],
 		[with_nss_includes="$withval"])
 
 	AC_ARG_WITH(nss-libs,
-		[  --with-nss-libs=PREFIX          Specify location of Mozilla nss3 libs.],
+		[AC_HELP_STRING([--with-nss-libs=PREFIX], [specify location of Mozilla nss3 libs.])],
 		[with_nss_libs="$withval"])
 
 
@@ -1009,12 +1331,21 @@
 
 	if test "x$nss_manual_check" = "xno"; then
 		if `$PKG_CONFIG --exists mozilla-nss`; then
-			PKG_CHECK_MODULES(NSS, mozilla-nss, have_nss="yes", have_nss="no")
+			PKG_CHECK_MODULES(NSS, mozilla-nss, [
+				have_nss="yes"
+			], [
+				AC_MSG_RESULT(no)
+				have_nss="no"
+			])
 			mozilla_nspr="mozilla-nspr"
 			mozilla_nss="mozilla-nss"
 		else
 			if `$PKG_CONFIG --exists nss`; then
-				PKG_CHECK_MODULES(NSS, nss, have_nss="yes")
+				PKG_CHECK_MODULES(NSS, nss, [
+					have_nss="yes"
+				], [
+					AC_MSG_RESULT(no)
+				])
 				mozilla_nspr="nspr"
 				mozilla_nss="nss"
 			fi
@@ -1180,7 +1511,7 @@
 			AC_CACHE_CHECK([for Mozilla nss libraries], moz_nss_libs,
 			[
 				LIBS_save=$LIBS
-				LDFLAGS="$LDFLAGS -L$with_nspr_libs $nsprlibs -L$with_nss_libs $nsslibs"
+				LDFLAGS="$LDFLAGS -L$with_nspr_libs -L$with_nss_libs"
 				LIBS="$nsslibs $nsprlibs"
 
 				AC_TRY_LINK_FUNC(NSS_Init,
@@ -1189,7 +1520,8 @@
 
 				if test "x$moz_nss_libs" = "xno"; then
 					nsslibs="-lssl3 -lsmime3 -lnss3 -lsoftokn3"
-					LDFLAGS="$LDFLAGS -L$with_nspr_libs $nsprlibs -L$with_nss_libs $nsslibs"
+					LDFLAGS="$LDFLAGS -L$with_nspr_libs -L$with_nss_libs" 
+					LIBS="$LIBS $nsslibs"
 					AC_TRY_LINK_FUNC(NSS_Init,
 						[moz_nss_libs="yes"],
 						[moz_nss_libs="no"])
@@ -1241,20 +1573,28 @@
 	msg_ssl=$msg_gnutls
 fi
 
-dnl Check for Tcl
+dnl #######################################################################
+dnl # Check for Tcl
+dnl #######################################################################
+AC_ARG_ENABLE(tcl, [AC_HELP_STRING([--disable-tcl],
+	[compile without Tcl scripting])], enable_tcl="$enableval", enable_tcl="yes")
+AC_ARG_WITH(tclconfig, [AC_HELP_STRING([--with-tclconfig=DIR],
+	[directory containing tclConfig.sh])])
+
 if test "$enable_plugins" = no; then
 	enable_tcl=no
 fi
 
 if test "$enable_tcl" = yes; then
 	AC_MSG_CHECKING([for tclConfig.sh])
-        TCLCONFIG=no
+	TCLCONFIG=no
 	TCLCONFIGDIRS="/usr/lib \
-		       /usr/lib/tcl8.4 \
-		       /usr/lib/tcl8.3 \
-		       /usr/lib/tcl8.2 \
-		       /System/Library/Tcl/8.3 \
-		       /usr/local/lib"
+			/usr/lib64 \
+			/usr/lib/tcl8.4 \
+			/usr/lib/tcl8.3 \
+			/usr/lib/tcl8.2 \
+			/System/Library/Tcl/8.3 \
+			/usr/local/lib"
 	for dir in $with_tclconfig $TCLCONFIGDIRS; do
 		if test -f $dir/tclConfig.sh; then
 			TCLCONFIG=$dir/tclConfig.sh
@@ -1279,9 +1619,9 @@
 			oldLIBS=$LIBS
 			LIBS="$LIBS $TCL_LIB_SPEC"
 			AC_TRY_LINK([#include <tcl.h>],
-				    [Tcl_Interp *interp=NULL; Tcl_Init(interp)],
-				    [AC_MSG_RESULT([yes]);enable_tcl=yes],
-				    [AC_MSG_RESULT([no]);enable_tcl=no])
+				[Tcl_Interp *interp=NULL; Tcl_Init(interp)],
+				[AC_MSG_RESULT([yes]);enable_tcl=yes],
+				[AC_MSG_RESULT([no]);enable_tcl=no])
 			CPPFLAGS="$oldCPPFLAGS"
 			LIBS="$oldLIBS"
 		fi
@@ -1291,8 +1631,8 @@
 if test "$enable_tcl" = yes; then
 	AM_CONDITIONAL(USE_TCL, true)
 	TCL_LIBS=$TCL_LIB_SPEC
+	AC_DEFINE(HAVE_TCL, [1], [Compile with support for the Tcl toolkit])
 	AC_SUBST(TCL_LIBS)
-	AC_DEFINE(HAVE_TCL, [1], [Compile with support for the Tcl toolkit])
 	TCL_CFLAGS="$TCL_INCLUDE_SPEC -I$TCL_PREFIX/include"
 	if test "x$GCC" = "xyes"; then
 		TCL_CFLAGS="$TCL_CFLAGS -fno-strict-aliasing"
@@ -1302,15 +1642,23 @@
 	AM_CONDITIONAL(USE_TCL, false)
 fi
 
-dnl Check for Tk
+dnl #######################################################################
+dnl # Check for Tk
+dnl #######################################################################
+AC_ARG_ENABLE(tk, [AC_HELP_STRING([--disable-tk],
+	[compile without Tcl support for Tk])], enable_tk="$enableval", enable_tk="yes")
+AC_ARG_WITH(tkconfig, [AC_HELP_STRING([--with-tkconfig=DIR],
+	[directory containing tkConfig.sh])])
+
 if test "$enable_tcl" = yes -a "$enable_tk" = yes; then
 	AC_MSG_CHECKING([for tkConfig.sh])
 	TKCONFIG=no
 	TKCONFIGDIRS="/usr/lib \
-	              /usr/lib/tk8.4 \
-		      /usr/lib/tk8.3 \
-		      /usr/lib/tk8.2 \
-		      /usr/local/lib"
+			/usr/lib64 \
+			/usr/lib/tk8.4 \
+			/usr/lib/tk8.3 \
+			/usr/lib/tk8.2 \
+			/usr/local/lib"
 	for dir in $with_tkconfig $TKCONFIGDIRS; do
 		if test -f $dir/tkConfig.sh; then
 			TKCONFIG=$dir/tkConfig.sh
@@ -1329,9 +1677,9 @@
 		oldLIBS=$LIBS
 		LIBS="$LIBS $TCL_LIB_SPEC $TK_LIB_SPEC"
 		AC_TRY_LINK([#include <tk.h>],
-			    [Tcl_Interp *interp=NULL; Tcl_Init(interp); Tk_Init(interp);],
-			    [AC_MSG_RESULT([yes]);enable_tk=yes],
-			    [AC_MSG_RESULT([no]);enable_tk=no])
+				[Tcl_Interp *interp=NULL; Tcl_Init(interp); Tk_Init(interp);],
+				[AC_MSG_RESULT([yes]);enable_tk=yes],
+				[AC_MSG_RESULT([no]);enable_tk=no])
 		CPPFLAGS="$oldCPPFLAGS"
 		LIBS="$oldLIBS"
 	fi
@@ -1348,33 +1696,6 @@
 	AM_CONDITIONAL(USE_TK, false)
 fi
 
-dnl Thanks, Evan.
-if test "$enable_gtkspell" = yes ; then
-	PKG_CHECK_MODULES(GTKSPELL, gtkspell-2.0 >= 2.0.2, , enable_gtkspell=no)
-	if test "$enable_gtkspell" = "yes" ; then
-		AC_SUBST(GTKSPELL_CFLAGS)
-		AC_SUBST(GTKSPELL_LIBS)
-		AC_DEFINE(USE_GTKSPELL,,[do we have gtkspell?])
-	fi
-fi
-
-if test "$enable_audio" = yes ; then
-	GAIM_PATH_AO(found_ao_lib=true)
-
-	AM_PATH_AUDIOFILE([0.2.0], found_af_lib=true)
-
-	if test "$found_ao_lib" = "true" -a "$found_af_lib" = "true"; then
-		SOUND_LIBS="$SOUND_LIBS $AO_LIBS $AUDIOFILE_LIBS"
-		AC_SUBST(SOUND_LIBS)
-		AC_DEFINE(USE_AO, 1, [Define if we're using libao and libaudiofile for sound playing])
-		enable_audio=yes
-	else
-		enable_audio=no
-	fi
-else
-	enable_audio=no
-fi
-
 if test "$ac_cv_cygwin" = yes ; then
 	LDADD="$LDADD -static"
 	AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.])
@@ -1386,30 +1707,30 @@
 
 if test "x$enable_plugins" = "xyes" ; then
 	AC_DEFINE(GAIM_PLUGINS, 1, [Define if plugins are enabled.])
-	AM_CONDITIONAL(PLUGINS, test "x$enable_plugins" = "xyes")
+	AM_CONDITIONAL(PLUGINS, true)
 else
 	AM_CONDITIONAL(PLUGINS, false)
-	enable_plugins=no
-	enable_prpls=no
 fi
 
-if test "x$enable_prpls" = "xyes" ; then
-	AM_CONDITIONAL(PRPLS, test "x$enable_plugins" = "xyes")
-else
-	AM_CONDITIONAL(PRPLS, false)
-	enable_prpls=no
-fi
-
-dnl checks for jabber
+dnl #######################################################################
+dnl # Check for Cyrus-SASL (for Jabber)
+dnl #######################################################################
 dnl AC_CHECK_SIZEOF(short)
 AC_CHECK_FUNCS(snprintf connect)
 AC_SUBST(SASL_LIBS)
 AC_ARG_ENABLE(cyrus-sasl, AC_HELP_STRING([--enable-cyrus-sasl], [enable Cyrus SASL support for jabberd]), enable_cyrus_sasl=$enableval, enable_cyrus_sasl=no)
-if test "x-$enable_cyrus_sasl" = "x-yes" ; then
-  AC_CHECK_LIB(sasl2, sasl_client_init, [AC_DEFINE(HAVE_CYRUS_SASL, [1], [Define to 1 if Cyrus SASL is present]) SASL_LIBS=-"lsasl2"], [AC_ERROR(Cyrus SASL library not found)])
+if test "x$enable_cyrus_sasl" = "xyes" ; then
+	AC_CHECK_LIB(sasl2, sasl_client_init, [
+			AC_DEFINE(HAVE_CYRUS_SASL, [1], [Define to 1 if Cyrus SASL is present])
+			SASL_LIBS=-"lsasl2"
+		], [
+			AC_ERROR(Cyrus SASL library not found)
+		])
 fi
 
-dnl checks for zephyr
+dnl #######################################################################
+dnl # Check for Kerberos (for Zephyr)
+dnl #######################################################################
 AC_DEFINE(ZEPHYR_INT32, long, [Size of an int32.])
 AC_SUBST(KRB4_CFLAGS)
 AC_SUBST(KRB4_LDFLAGS)
@@ -1445,13 +1766,15 @@
 	LDFLAGS="$orig_LDFLAGS"
 fi
 
-dnl checks for an external libzephyr
+dnl #######################################################################
+dnl # Check for external libzephyr
+dnl #######################################################################
 AC_SUBST(ZEPHYR_CFLAGS)
 AC_SUBST(ZEPHYR_LDFLAGS)
 AC_SUBST(ZEPHYR_LIBS)
 if test "$zephyr" != "no" ; then
-	if test "$zephyr" != "yes" ; then 
-		ZEPHYR_CFLAGS="-I${zephyr}/include" 
+	if test "$zephyr" != "yes" ; then
+		ZEPHYR_CFLAGS="-I${zephyr}/include"
 		ZEPHYR_LDFLAGS="-L${zephyr}/lib"
 	elif test -d /usr/athena/include/zephyr ; then
 		ZEPHYR_CFLAGS="-I/usr/athena/include"
@@ -1460,14 +1783,14 @@
 	elif test -d /usr/local/include/zephyr ; then
 		ZEPHYR_CFLAGS="-I/usr/local/include"
 	fi
-	AC_DEFINE(LIBZEPHYR_EXT, 1 , [Define if external libzephyr should be used.]) 
+	AC_DEFINE(LIBZEPHYR_EXT, 1 , [Define if external libzephyr should be used.])
 	AM_CONDITIONAL(EXTERNAL_LIBZEPHYR, test "x$zephyr" != "xno")
 	orig_LDFLAGS="$LDFLAGS"
 	LDFLAGS="$LDFLAGS $ZEPHYR_LDFLAGS"
 	AC_CHECK_LIB(zephyr, ZInitialize,
-			  [ZEPHYR_LIBS="-lzephyr"],
-			  [AC_ERROR(Zephyr libraries not found)],
-			  -lzephyr)
+		[ZEPHYR_LIBS="-lzephyr"],
+		[AC_ERROR(Zephyr libraries not found)],
+		-lzephyr)
 	orig_LIBS="$LIBS"
 	LIBS="$orig_LIBS"
 	LDFLAGS="$orig_LDFLAGS"
@@ -1485,174 +1808,134 @@
 AC_CHECK_HEADERS(termios.h)
 AC_VAR_TIMEZONE_EXTERNALS
 
+AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff,
+        AC_TRY_COMPILE([
+                #include <time.h>
+        ], [
+                struct tm tm;
+                tm.tm_gmtoff = 1;
+        ], ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no))
+if test $ac_cv_struct_tm_gmtoff = yes; then
+        AC_DEFINE(HAVE_TM_GMTOFF, 1, [Define if you have a tm_gmtoff member in struct tm])
+fi
+
 dnl #######################################################################
-dnl # Doxygen Stuff
+dnl # Check for check
 dnl #######################################################################
-AC_ARG_ENABLE(doxygen, [  --enable-doxygen    enable documentation with doxygen],,enable_doxygen=yes)
-AC_ARG_ENABLE(dot,     [  --enable-dot        enable graphs in doxygen via 'dot'],,enable_dot=yes)
+PKG_CHECK_MODULES(CHECK, check >= 0.9.4, have_check=yes, have_check=no)
+AM_CONDITIONAL(HAVE_CHECK, test "x$have_check" = "xyes")
+AC_SUBST(CHECK_CFLAGS)
+AC_SUBST(CHECK_LIBS)
+
+dnl #######################################################################
+dnl # Check for Doxygen and dot (part of GraphViz)
+dnl #######################################################################
+AC_ARG_ENABLE(doxygen,
+	[AC_HELP_STRING([--disable-doxygen],
+		[enable documentation with doxygen])],
+	enable_doxygen="$enableval", enable_doxygen="yes")
+AC_ARG_ENABLE(dot,
+	[AC_HELP_STRING([--enable-dot],
+		[enable graphs in doxygen via 'dot'])],
+	enable_dot="$enableval", enable_dot="yes")
 
 if test "x$enable_doxygen" = xyes; then
 	AC_CHECK_PROG(DOXYGEN, doxygen, true, false)
 	if test $DOXYGEN = false; then
-		AC_MSG_WARN([*** doxygen not found, docs will not be available])
-		enable_doxygen=no
+		AC_MSG_WARN([*** Doxygen not found, docs will not be available])
+		enable_doxygen="no"
 	else
 		AC_DEFINE_UNQUOTED(HAVE_DOXYGEN, 1, [whether or not we have doxygen])
 
-		if test "x$enable_dot" = xyes; then
+		if test "x$enable_dot" = "xyes"; then
 			AC_CHECK_PROG(DOT, dot, true, false)
 
 			if test $DOT = false; then
 				enable_dot="no";
-				AC_MSG_WARN([*** dot not found, graphs will not be available])
+				AC_MSG_WARN([*** GraphViz dot not found, docs will not have graphs])
 			else
 				AC_DEFINE_UNQUOTED(HAVE_DOT, 1, [whether or not we have dot])
 			fi
-		else
-			AC_MSG_WARN([*** dot not found, graphs will not be available])
 		fi
 	fi
 else
 	enable_dot="no"
 fi
 
-if test "x$enable_doxygen" = xyes; then
-	AM_CONDITIONAL(HAVE_DOXYGEN, true)
-else
-	AM_CONDITIONAL(HAVE_DOXYGEN, false)
-fi
-
 AC_SUBST(enable_doxygen)
 AC_SUBST(enable_dot)
-
-dnl ##############################################################################
-dnl ## Mediastreamer stuff #######################################################
-dnl ##############################################################################
-AC_ARG_ENABLE(vv,     [  --enable-vv         enable Voice and Video support],,enable_vv=no)
-if test "x$enable_vv" = xyes; then
-	AC_DEFINE(HAVE_GLIB, 1, [Gaim always has GLib, but Linphone can be built without it])
-
-	dnl enable truespeech codec support
-	AC_ARG_ENABLE(truespeech, [  --enable-truespeech       Turn on TrueSpeech support (x86 only)],,enable_truespeech=no)
-	TRUESPEECH_CFLAGS=
-	if test x$enable_truespeech = xyes ; then
-	TRUESPEECH_CFLAGS=-DTRUESPEECH
-	fi
-	VV_CFLAGS="$VV_CFLAGS $TRUESPEECH_CFLAGS"
+AM_CONDITIONAL(HAVE_DOXYGEN, test "x$enable_doxygen" = "xyes")
 
-	found_sound=no
-	AC_CHECK_HEADERS(soundcard.h sys/soundcard.h machine/soundcard.h sys/audio.h)
-		if test "${ac_cv_header_sys_soundcard_h}" = "yes" || \
-		test "${ac_cv_header_soundcard_h}" = "yes" || \
-			  test "${ac_cv_header_sys_audio_h}" = "yes" || \
-		test "${ac_cv_header_machine_soundcard_h}" = "yes"; then
-		found_sound=yes
-		fi
-	if test "$found_sound" = "no"; then
-		   AC_MSG_ERROR([Could not find a support sound driver])
-	fi
-	if test "$alsa" = "true"; then
-		AC_CHECK_HEADERS(alsa/asoundlib.h,
-				[ AC_CHECK_LIB(asound,snd_pcm_open,
-			[ALSA_LIBS="-lasound" ; AC_DEFINE(__ALSA_ENABLED__,1,[Defined when alsa support is enabled]) ])
-			]
-		  )
-	fi
-	dnl Check for samplerate libraries
-	dnl Check for jack libraries (sound output plugin)
-	PKG_CHECK_MODULES(JACK,jack >= 0.15.0,
-	[
-		 dnl we've found jack devel files
-		 PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.0.13, [AC_DEFINE(__JACK_ENABLED__,1,[Jack support])] ,
-				  [echo "libsamplerate not found, jack support disabled."])
-		 VV_CFLAGS="$VV_CFLAGS $SAMPLERATE_CFLAGS"
-	 VV_LIBS="$VV_LIBS   $SAMPLERATE_LIBS"
-	],
-	[echo "No jack support."] )
-	VV_CFLAGS="$VV_CFLAGS $JACK_CFLAGS"
-	VV_LIBS="$VV_LIBS $JACK_LIBS"
-
-	dnl check for installed version of speex
-	LP_CHECK_SPEEX
-	VV_CFLAGS="$VV_CFLAGS $SPEEX_CFLAGS"
-	VV_LIBS="$VV_LIBS   $SPEEX_LIBS"
-
-	PKG_CHECK_MODULES(ORTP, ortp >= 0.7.1, enable_ortp=yes, enable_ortp=no)
-	VV_CFLAGS="$VV_CFLAGS $ORTP_CFLAGS"
-	VV_LIBS="$VV_LIBS   $ORTP_LIBS"
-	if test x$enable_ortp = xno; then
-	AC_MSG_ERROR([Could not find a suitable version of oRTP. Please install oRTP >= 0.7.1])
-	fi
-else
-	enable_vv=no
+AC_ARG_ENABLE(debug, [AC_HELP_STRING([--enable-debug],
+	[compile with debugging support])], , enable_debug=no)
+if test "x$enable_debug" = "xyes" ; then
+	AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.])
 fi
 
-if test x$enable_vv = xyes; then
-	AM_CONDITIONAL(HAVE_VV, true)
-	AC_DEFINE(HAVE_VV, [1], [Compile with Voice/Video support])
-else
-	AM_CONDITIONAL(HAVE_VV, false)
+AC_ARG_ENABLE(fatal-asserts, [AC_HELP_STRING([--enable-fatal-asserts],
+	[make assertions fatal (useful for debugging)])], , enable_fatal_asserts=no)
+if test "x$enable_fatal_asserts" = "xyes" ; then
+	AC_DEFINE(GAIM_FATAL_ASSERTS, 1, [Define to make assertions fatal (useful for debugging).])
 fi
 
-AC_SUBST(VV_CFLAGS)
-AC_SUBST(VV_LIBS)
-
-AC_CONFIG_COMMANDS_PRE([
-	if test -e VERSION; then
-		cp -p VERSION VERSION.ac-save
-	fi
-])
-
-AC_CONFIG_COMMANDS_POST([
-	cmp VERSION VERSION.ac-save || touch -r VERSION.ac-save VERSION
-	rm -f VERSION.ac-save
-])
-
 AC_OUTPUT([Makefile
 		   Doxyfile
 		   gaim.apspec
+		   gaim.service
 		   doc/Makefile
 		   doc/gaim.1
-		   intl/Makefile
+		   doc/gaim-text.1
 		   m4macros/Makefile
-		   pixmaps/Makefile
-		   pixmaps/smileys/Makefile
-		   pixmaps/smileys/default/Makefile
-		   pixmaps/smileys/none/Makefile
-		   pixmaps/status/Makefile
-		   pixmaps/status/default/Makefile
-		   plugins/Makefile
-		   plugins/docklet/Makefile
-		   plugins/gevolution/Makefile
-		   plugins/gestures/Makefile
-		   plugins/mono/Makefile
-		   plugins/mono/api/Makefile
-		   plugins/mono/loader/Makefile
-		   plugins/musicmessaging/Makefile
-		   plugins/perl/Makefile
-		   plugins/perl/common/Makefile.PL
-		   plugins/ssl/Makefile
-		   plugins/tcl/Makefile
-		   plugins/ticker/Makefile
+		   gtk/Makefile
+		   gtk/pixmaps/Makefile
+		   gtk/pixmaps/buddy_icons/Makefile
+		   gtk/pixmaps/buddy_icons/qq/Makefile
+		   gtk/pixmaps/smileys/Makefile
+		   gtk/pixmaps/smileys/default/Makefile
+		   gtk/pixmaps/smileys/none/Makefile
+		   gtk/pixmaps/status/Makefile
+		   gtk/pixmaps/status/default/Makefile
+		   gtk/plugins/Makefile
+		   gtk/plugins/cap/Makefile
+		   gtk/plugins/gestures/Makefile
+		   gtk/plugins/gevolution/Makefile
+		   gtk/plugins/musicmessaging/Makefile
+		   gtk/plugins/perl/Makefile
+		   gtk/plugins/perl/common/Makefile.PL
+		   gtk/plugins/ticker/Makefile
+		   gtk/sounds/Makefile
+		   libgaim/gconf/Makefile
+		   libgaim/plugins/Makefile
+		   libgaim/plugins/mono/Makefile
+		   libgaim/plugins/mono/api/Makefile
+		   libgaim/plugins/mono/loader/Makefile
+		   libgaim/plugins/perl/Makefile
+		   libgaim/plugins/perl/common/Makefile.PL
+		   libgaim/plugins/ssl/Makefile
+		   libgaim/plugins/tcl/Makefile
+		   libgaim/Makefile
+		   libgaim/protocols/Makefile
+		   libgaim/protocols/bonjour/Makefile
+		   libgaim/protocols/gg/Makefile
+		   libgaim/protocols/irc/Makefile
+		   libgaim/protocols/jabber/Makefile
+		   libgaim/protocols/msn/Makefile
+		   libgaim/protocols/novell/Makefile
+		   libgaim/protocols/oscar/Makefile
+		   libgaim/protocols/qq/Makefile
+		   libgaim/protocols/sametime/Makefile
+		   libgaim/protocols/silc/Makefile
+		   libgaim/protocols/simple/Makefile
+		   libgaim/protocols/toc/Makefile
+		   libgaim/protocols/yahoo/Makefile
+		   libgaim/protocols/zephyr/Makefile
+		   libgaim/tests/Makefile
+		   console/Makefile
+		   console/libgnt/Makefile
+		   console/libgnt/gnt.pc
+		   console/libgnt/wms/Makefile
+		   console/plugins/Makefile
 		   po/Makefile.in
-		   sounds/Makefile
-		   src/Makefile
-		   src/mediastreamer/Makefile
-		   src/protocols/Makefile
-		   src/protocols/bonjour/Makefile
-		   src/protocols/gg/Makefile
-		   src/protocols/irc/Makefile
-		   src/protocols/jabber/Makefile
-		   src/protocols/msn/Makefile
-		   src/protocols/napster/Makefile
-		   src/protocols/novell/Makefile
-		   src/protocols/oscar/Makefile
-		   src/protocols/sametime/Makefile
-		   src/protocols/silc/Makefile
-		   src/protocols/simple/Makefile
-		   src/protocols/toc/Makefile
-		   src/protocols/yahoo/Makefile
-		   src/protocols/zephyr/Makefile
 		   gaim.pc
 		   gaim.spec
 		  ])
@@ -1661,37 +1944,36 @@
 echo $PACKAGE $VERSION
 
 echo
-echo Build Protocol Plugins........ : $enable_prpls
+echo Build GTK+ 2.x UI............. : $enable_gtkui
+echo Build console UI.............. : $enable_consoleui
+echo
+echo Protocols to build dynamically : $DYNAMIC_PRPLS
 echo Protocols to link statically.. : $STATIC_PRPLS
-echo Protocols to build dynamically : $DYNAMIC_PRPLS
 echo
-echo UI Library.................... : GTK+ 2.x
+echo Build with GStreamer support.. : $enable_gst
+echo Build with DBUS support....... : $enable_dbus
+if test "x$enable_dbus" = "xyes" ; then
+	eval eval echo DBUS services directory....... : $DBUS_SERVICES_DIR
+fi
 echo SSL Library/Libraries......... : $msg_ssl
+echo Build with Cyrus SASL support. : $enable_cyrus_sasl
+echo Use kerberos 4 with zephyr.... : $kerberos
+echo Use external libzephyr........ : $zephyr
+echo Has you....................... : yes
 echo
-echo Build with Plugin support..... : $enable_plugins
+echo Use XScreenSaver Extension.... : $enable_screensaver
+echo Use X Session Management...... : $enable_sm
+echo Use startup notification...... : $enable_startup_notification
+echo Build with GtkSpell support... : $enable_gtkspell
+echo
+echo Build with plugin support..... : $enable_plugins
 echo Build with Mono support....... : $enable_mono
 echo Build with Perl support....... : $enable_perl
 echo Build with Tcl support........ : $enable_tcl
 echo Build with Tk support......... : $enable_tk
-echo Build with Audio support...... : $enable_audio
-echo Build with GtkSpell support... : $enable_gtkspell
-echo Build with Voice/Video support : $enable_vv
-echo Build with DBUS support....... : $enable_dbus
-if test x$enable_dbus = xyes ; then
-echo DBUS session directory........ : $DBUS_SESSION_DIR
-fi
-echo Build with Cyrus SASL support. : $enable_cyrus_sasl
-echo Has you....................... : yes
-echo
-echo
-echo Use kerberos 4 with zephyr.... : $kerberos
-echo Use external libzephyr........ : $zephyr
-echo
-echo Use XScreenSaver Extension.... : $enable_xss
-echo Use X Session Management...... : $enable_sm
-echo Use startup notification.......: $enable_startup_notification
 echo
 echo Print debugging messages...... : $enable_debug
+echo Assertions are fatal.......... : $enable_fatal_asserts
 echo
 eval eval echo Gaim will be installed in $bindir.
 if test "x$gaimpath" != "x" ; then
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/Makefile.am	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,66 @@
+if ENABLE_GNT
+
+SUBDIRS = libgnt plugins
+
+bin_PROGRAMS = gaim-text
+
+gaim_text_SOURCES = \
+	gntaccount.c \
+	gntblist.c \
+	gntconn.c \
+	gntconv.c \
+	gntdebug.c \
+	gntgaim.c \
+	gntnotify.c \
+	gntplugin.c \
+	gntprefs.c \
+	gntrequest.c \
+	gntstatus.c \
+	gntui.c
+
+gaim_text_headers = \
+	gntaccount.h \
+	gntblist.h \
+	gntconn.h \
+	gntconv.h \
+	gntdebug.h \
+	gntgaim.h \
+	gntnotify.h \
+	gntplugin.h \
+	gntprefs.h \
+	gntrequest.h \
+	gntstatus.h \
+	gntui.h
+
+gaim_textincludedir=$(includedir)/gaim/gnt
+gaim_textinclude_HEADERS = \
+	$(gaim_text_headers)
+
+gaim_text_DEPENDENCIES = @LIBOBJS@
+gaim_text_LDFLAGS = -export-dynamic
+gaim_text_LDADD = \
+	@LIBOBJS@ \
+	$(DBUS_LIBS) \
+	$(INTLLIBS) \
+	$(GLIB_LIBS) \
+	$(LIBXML_LIBS) \
+	$(GNT_LIBS) \
+	./libgnt/libgnt.la \
+	$(top_builddir)/libgaim/libgaim.la
+
+AM_CPPFLAGS = \
+	-DSTANDALONE \
+	-DBR_PTHREADS=0 \
+	-DDATADIR=\"$(datadir)\" \
+	-DLIBDIR=\"$(libdir)/gaim/\" \
+	-DLOCALEDIR=\"$(datadir)/locale\" \
+	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-I$(top_srcdir)/libgaim/ \
+	-I$(top_srcdir) \
+	-I$(srcdir)/libgnt/ \
+	$(DEBUG_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	$(LIBXML_CFLAGS) \
+	$(GNT_CFLAGS)
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/getopt.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,737 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Gaim is the legal property of its developers, whose names are too numerous
+   to list here.  Please refer to the COPYRIGHT file distributed with this
+   source distribution.
+
+   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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* NOTE!!!  AIX requires this to be the first thing in the file.
+   Do not put ANYTHING before it!  */
+#if !defined (__GNUC__) && defined (_AIX)
+ #pragma alloca
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Alver says we need this for IRIX. */
+#if HAVE_STRING_H
+#include "string.h"
+#endif
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
+#include <alloca.h>
+#else
+#ifndef _AIX
+char *alloca ();
+#endif
+#endif /* alloca.h */
+#endif /* not __GNUC__ */
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef	__GNU_LIBRARY__
+#undef	alloca
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#else	/* Not GNU C library.  */
+#define	__alloca	alloca
+#endif	/* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+#ifdef	__GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define	my_index	strchr
+#define	my_bcopy(src, dst, n)	memcpy ((dst), (src), (n))
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+	return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+static void
+my_bcopy (from, to, size)
+     const char *from;
+     char *to;
+     int size;
+{
+  int i;
+  for (i = 0; i < size; i++)
+    to[i] = from[i];
+}
+#endif				/* GNU C library.  */
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
+  char **temp = (char **) __alloca (nonopts_size);
+
+  /* Interchange the two blocks of data in ARGV.  */
+
+  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
+  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
+	    (optind - last_nonopt) * sizeof (char *));
+  my_bcopy ((char *) temp,
+	    (char *) &argv[first_nonopt + optind - last_nonopt],
+	    nonopts_size);
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+	{
+	  ordering = RETURN_IN_ORDER;
+	  ++optstring;
+	}
+      else if (optstring[0] == '+')
+	{
+	  ordering = REQUIRE_ORDER;
+	  ++optstring;
+	}
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+	ordering = REQUIRE_ORDER;
+      else
+	ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+	{
+	  /* If we have just processed some options following some non-options,
+	     exchange them so that the options come first.  */
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (last_nonopt != optind)
+	    first_nonopt = optind;
+
+	  /* Now skip any additional non-options
+	     and extend the range of non-options previously skipped.  */
+
+	  while (optind < argc
+		 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+		 && (longopts == NULL
+		     || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif				/* GETOPT_COMPAT */
+		 )
+	    optind++;
+	  last_nonopt = optind;
+	}
+
+      /* Special ARGV-element `--' means premature end of options.
+	 Skip it like a null option,
+	 then exchange with previous non-options as if it were an option,
+	 then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+	{
+	  optind++;
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (first_nonopt == last_nonopt)
+	    first_nonopt = optind;
+	  last_nonopt = argc;
+
+	  optind = argc;
+	}
+
+      /* If we have done all the ARGV-elements, stop the scan
+	 and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+	{
+	  /* Set the next-arg-index to point at the non-options
+	     that we previously skipped, so the caller will digest them.  */
+	  if (first_nonopt != last_nonopt)
+	    optind = first_nonopt;
+	  return EOF;
+	}
+
+      /* If we have come to a non-option and did not permute it,
+	 either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+	  && (longopts == NULL
+	      || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif				/* GETOPT_COMPAT */
+	  )
+	{
+	  if (ordering == REQUIRE_ORDER)
+	    return EOF;
+	  optarg = argv[optind++];
+	  return 1;
+	}
+
+      /* We have found another option-ARGV-element.
+	 Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+		  + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+	   && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+	  || argv[optind][0] == '+'
+#endif				/* GETOPT_COMPAT */
+	  ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound;
+
+      while (*s && *s != '=')
+	s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+	   p++, option_index++)
+	if (!strncmp (p->name, nextchar, s - nextchar))
+	  {
+	    if (s - nextchar == strlen (p->name))
+	      {
+		/* Exact match found.  */
+		pfound = p;
+		indfound = option_index;
+		exact = 1;
+		break;
+	      }
+	    else if (pfound == NULL)
+	      {
+		/* First nonexact match found.  */
+		pfound = p;
+		indfound = option_index;
+	      }
+	    else
+	      /* Second nonexact match found.  */
+	      ambig = 1;
+	  }
+
+      if (ambig && !exact)
+	{
+	  if (opterr)
+	    fprintf (stderr, "%s: option `%s' is ambiguous\n",
+		     argv[0], argv[optind]);
+	  nextchar += strlen (nextchar);
+	  optind++;
+	  return '?';
+	}
+
+      if (pfound != NULL)
+	{
+	  option_index = indfound;
+	  optind++;
+	  if (*s)
+	    {
+	      /* Don't test has_arg with >, because some C compilers don't
+		 allow it to be used on enums.  */
+	      if (pfound->has_arg)
+		optarg = s + 1;
+	      else
+		{
+		  if (opterr)
+		    {
+		      if (argv[optind - 1][1] == '-')
+			/* --option */
+			fprintf (stderr,
+				 "%s: option `--%s' doesn't allow an argument\n",
+				 argv[0], pfound->name);
+		      else
+			/* +option or -option */
+			fprintf (stderr,
+			     "%s: option `%c%s' doesn't allow an argument\n",
+			     argv[0], argv[optind - 1][0], pfound->name);
+		    }
+		  nextchar += strlen (nextchar);
+		  return '?';
+		}
+	    }
+	  else if (pfound->has_arg == 1)
+	    {
+	      if (optind < argc)
+		optarg = argv[optind++];
+	      else
+		{
+		  if (opterr)
+		    fprintf (stderr, "%s: option `%s' requires an argument\n",
+			     argv[0], argv[optind - 1]);
+		  nextchar += strlen (nextchar);
+		  return optstring[0] == ':' ? ':' : '?';
+		}
+	    }
+	  nextchar += strlen (nextchar);
+	  if (longind != NULL)
+	    *longind = option_index;
+	  if (pfound->flag)
+	    {
+	      *(pfound->flag) = pfound->val;
+	      return 0;
+	    }
+	  return pfound->val;
+	}
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+	 or the option starts with '--' or is not a valid short
+	 option, then it's an error.
+	 Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+	  || argv[optind][0] == '+'
+#endif				/* GETOPT_COMPAT */
+	  || my_index (optstring, *nextchar) == NULL)
+	{
+	  if (opterr)
+	    {
+	      if (argv[optind][1] == '-')
+		/* --option */
+		fprintf (stderr, "%s: unrecognized option `--%s'\n",
+			 argv[0], nextchar);
+	      else
+		/* +option or -option */
+		fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+			 argv[0], argv[optind][0], nextchar);
+	    }
+	  nextchar = (char *) "";
+	  optind++;
+	  return '?';
+	}
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+	if (opterr)
+	  {
+#if 0
+	    if (c < 040 || c >= 0177)
+	      fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+		       argv[0], c);
+	    else
+	      fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+	    /* 1003.2 specifies the format of this message.  */
+	    fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+	  }
+	optopt = c;
+	return '?';
+      }
+    if (temp[1] == ':')
+      {
+	if (temp[2] == ':')
+	  {
+	    /* This is an option that accepts an argument optionally.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		optind++;
+	      }
+	    else
+	      optarg = 0;
+	    nextchar = NULL;
+	  }
+	else
+	  {
+	    /* This is an option that requires an argument.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		/* If we end this ARGV-element by taking the rest as an arg,
+		   we must advance to the next element now.  */
+		optind++;
+	      }
+	    else if (optind == argc)
+	      {
+		if (opterr)
+		  {
+#if 0
+		    fprintf (stderr, "%s: option `-%c' requires an argument\n",
+			     argv[0], c);
+#else
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr, "%s: option requires an argument -- %c\n",
+			     argv[0], c);
+#endif
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = '?';
+	      }
+	    else
+	      /* We already incremented `optind' once;
+		 increment it again when taking next ARGV-elt as argument.  */
+	      optarg = argv[optind++];
+	    nextchar = NULL;
+	  }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+			   (const struct option *) 0,
+			   (int *) 0,
+			   0);
+}
+
+#endif	/* _LIBC or not __GNU_LIBRARY__.  */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+	break;
+
+      switch (c)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/getopt.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,136 @@
+/* Declarations for getopt.
+
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Gaim is the legal property of its developers, whose names are too numerous
+   to list here.  Please refer to the COPYRIGHT file distributed with this
+   source distribution.
+
+   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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if	__STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/getopt1.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,177 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Gaim is the legal property of its developers, whose names are too numerous
+   to list here.  Please refer to the COPYRIGHT file distributed with this
+   source distribution.
+
+   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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "getopt.h"
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#else
+char *getenv ();
+#endif
+
+#ifndef	NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif	/* _LIBC or not __GNU_LIBRARY__.  */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+	{"add", 1, 0, 0},
+	{"append", 0, 0, 0},
+	{"delete", 1, 0, 0},
+	{"verbose", 0, 0, 0},
+	{"create", 0, 0, 0},
+	{"file", 1, 0, 0},
+	{0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+		       long_options, &option_index);
+      if (c == EOF)
+	break;
+
+      switch (c)
+	{
+	case 0:
+	  printf ("option %s", long_options[option_index].name);
+	  if (optarg)
+	    printf (" with arg %s", optarg);
+	  printf ("\n");
+	  break;
+
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case 'd':
+	  printf ("option d with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntaccount.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,849 @@
+/**
+ * @file gntaccount.c GNT Account API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntcheckbox.h>
+#include <gntcombobox.h>
+#include <gntentry.h>
+#include <gntlabel.h>
+#include <gntline.h>
+#include <gnttree.h>
+
+#include <account.h>
+#include <accountopt.h>
+#include <connection.h>
+#include <notify.h>
+#include <plugin.h>
+#include <request.h>
+
+#include "gntaccount.h"
+#include "gntgaim.h"
+
+#include <string.h>
+
+typedef struct
+{
+	GntWidget *window;
+	GntWidget *tree;
+} GGAccountList;
+
+static GGAccountList accounts;
+
+typedef struct
+{
+	GaimAccount *account;          /* NULL for a new account */
+
+	GntWidget *window;
+
+	GntWidget *protocol;
+	GntWidget *screenname;
+	GntWidget *password;
+	GntWidget *alias;
+	
+	GntWidget *splits;
+	GList *split_entries;
+
+	GList *prpl_entries;
+	GntWidget *prpls;
+
+	GntWidget *newmail;
+	GntWidget *remember;
+} AccountEditDialog;
+
+/* This is necessary to close an edit-dialog when an account is deleted */
+static GList *accountdialogs;
+
+static void
+account_add(GaimAccount *account)
+{
+	gnt_tree_add_choice(GNT_TREE(accounts.tree), account,
+			gnt_tree_create_row(GNT_TREE(accounts.tree),
+				gaim_account_get_username(account),
+				gaim_account_get_protocol_name(account)),
+			NULL, NULL);
+	gnt_tree_set_choice(GNT_TREE(accounts.tree), account,
+			gaim_account_get_enabled(account, GAIM_GNT_UI));
+}
+
+static void
+edit_dialog_destroy(AccountEditDialog *dialog)
+{
+	accountdialogs = g_list_remove(accountdialogs, dialog);
+	g_list_free(dialog->prpl_entries);
+	g_list_free(dialog->split_entries);
+	g_free(dialog);
+}
+
+static void
+save_account_cb(AccountEditDialog *dialog)
+{
+	GaimAccount *account;
+	GaimPlugin *plugin;
+	GaimPluginProtocolInfo *prplinfo;
+	const char *value;
+	GString *username;
+
+	/* XXX: Do some error checking first. */
+
+	plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol));
+	prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin);
+
+	/* Screenname && user-splits */
+	value = gnt_entry_get_text(GNT_ENTRY(dialog->screenname));
+
+	if (value == NULL || *value == '\0')
+	{
+		gaim_notify_error(NULL, _("Error"), _("Account was not added"),
+				_("Screenname of an account must be non-empty."));
+		return;
+	}
+	
+	username = g_string_new(value);
+
+	if (prplinfo != NULL)
+	{
+		GList *iter, *entries;
+		for (iter = prplinfo->user_splits, entries = dialog->split_entries;
+				iter && entries; iter = iter->next, entries = entries->next)
+		{
+			GaimAccountUserSplit *split = iter->data;
+			GntWidget *entry = entries->data;
+
+			value = gnt_entry_get_text(GNT_ENTRY(entry));
+			if (value == NULL || *value == '\0')
+				value = gaim_account_user_split_get_default_value(split);
+			g_string_append_printf(username, "%c%s",
+					gaim_account_user_split_get_separator(split),
+					value);
+		}
+	}
+
+	if (dialog->account == NULL)
+	{
+		account = gaim_account_new(username->str, gaim_plugin_get_id(plugin));
+		gaim_accounts_add(account);
+	}
+	else
+	{
+		account = dialog->account;
+
+		/* Protocol */
+		gaim_account_set_protocol_id(account, gaim_plugin_get_id(plugin));
+		gaim_account_set_username(account, username->str);
+	}
+	g_string_free(username, TRUE);
+
+	/* Alias */
+	value = gnt_entry_get_text(GNT_ENTRY(dialog->alias));
+	if (value && *value)
+		gaim_account_set_alias(account, value);
+
+	/* Remember password and password */
+	gaim_account_set_remember_password(account,
+			gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->remember)));
+	value = gnt_entry_get_text(GNT_ENTRY(dialog->password));
+	if (value && *value && gaim_account_get_remember_password(account))
+		gaim_account_set_password(account, value);
+	else
+		gaim_account_set_password(account, NULL);
+
+	/* Mail notification */
+	gaim_account_set_check_mail(account,
+			gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->newmail)));
+
+	/* Protocol options */
+	if (prplinfo)
+	{
+		GList *iter, *entries;
+		
+		for (iter = prplinfo->protocol_options, entries = dialog->prpl_entries;
+				iter && entries; iter = iter->next, entries = entries->next)
+		{
+			GaimAccountOption *option = iter->data;
+			GntWidget *entry = entries->data;
+			GaimPrefType type = gaim_account_option_get_type(option);
+			const char *setting = gaim_account_option_get_setting(option);
+
+			if (type == GAIM_PREF_STRING)
+			{
+				const char *value = gnt_entry_get_text(GNT_ENTRY(entry));
+				gaim_account_set_string(account, setting, value);
+			}
+			else if (type == GAIM_PREF_INT)
+			{
+				const char *str = gnt_entry_get_text(GNT_ENTRY(entry));
+				int value = 0;
+				if (str)
+					value = atoi(str);
+				gaim_account_set_int(account, setting, value);
+			}
+			else if (type == GAIM_PREF_BOOLEAN)
+			{
+				gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(entry));
+				gaim_account_set_bool(account, setting, value);
+			}
+			else if (type == GAIM_PREF_STRING_LIST)
+			{
+				/* TODO: */
+			}
+			else
+			{
+				g_assert_not_reached();
+			}
+		}
+	}
+
+	/* XXX: Proxy options */
+
+	gnt_widget_destroy(dialog->window);
+}
+
+static void
+update_user_splits(AccountEditDialog *dialog)
+{
+	GntWidget *hbox;
+	GaimPlugin *plugin;
+	GaimPluginProtocolInfo *prplinfo;
+	GList *iter, *entries;
+	char *username = NULL;
+
+	if (dialog->splits)
+	{
+		gnt_box_remove_all(GNT_BOX(dialog->splits));
+		g_list_free(dialog->split_entries);
+	}
+	else
+	{
+		dialog->splits = gnt_vbox_new(FALSE);
+		gnt_box_set_pad(GNT_BOX(dialog->splits), 0);
+		gnt_box_set_fill(GNT_BOX(dialog->splits), TRUE);
+	}
+
+	dialog->split_entries = NULL;
+
+	plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol));
+	if (!plugin)
+		return;
+	prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin);
+	
+	username = dialog->account ? g_strdup(gaim_account_get_username(dialog->account)) : NULL;
+
+	for (iter = prplinfo->user_splits; iter; iter = iter->next)
+	{
+		GaimAccountUserSplit *split = iter->data;
+		GntWidget *entry;
+		char *buf;
+
+		hbox = gnt_hbox_new(TRUE);
+		gnt_box_add_widget(GNT_BOX(dialog->splits), hbox);
+
+		buf = g_strdup_printf("%s:", gaim_account_user_split_get_text(split));
+		gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(buf));
+
+		entry = gnt_entry_new(NULL);
+		gnt_box_add_widget(GNT_BOX(hbox), entry);
+
+		dialog->split_entries = g_list_append(dialog->split_entries, entry);
+		g_free(buf);
+	}
+
+	for (iter = g_list_last(prplinfo->user_splits), entries = g_list_last(dialog->split_entries);
+			iter && entries; iter = iter->prev, entries = entries->prev)
+	{
+		GntWidget *entry = entries->data;
+		GaimAccountUserSplit *split = iter->data;
+		const char *value = NULL;
+		char *s;
+
+		if (dialog->account)
+		{
+			s = strrchr(username, gaim_account_user_split_get_separator(split));
+			if (s != NULL)
+			{
+				*s = '\0';
+				s++;
+				value = s;
+			}
+		}
+		if (value == NULL)
+			value = gaim_account_user_split_get_default_value(split);
+
+		if (value != NULL)
+			gnt_entry_set_text(GNT_ENTRY(entry), value);
+	}
+
+	if (username != NULL)
+		gnt_entry_set_text(GNT_ENTRY(dialog->screenname), username);
+
+	g_free(username);
+}
+
+static void
+add_protocol_options(AccountEditDialog *dialog)
+{
+	GaimPlugin *plugin;
+	GaimPluginProtocolInfo *prplinfo;
+	GList *iter;
+	GntWidget *vbox, *box;
+	GaimAccount *account;
+
+	if (dialog->prpls)
+		gnt_box_remove_all(GNT_BOX(dialog->prpls));
+	else
+	{
+		dialog->prpls = vbox = gnt_vbox_new(FALSE);
+		gnt_box_set_pad(GNT_BOX(vbox), 0);
+		gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_LEFT);
+		gnt_box_set_fill(GNT_BOX(vbox), TRUE);
+	}
+
+	if (dialog->prpl_entries)
+	{
+		g_list_free(dialog->prpl_entries);
+		dialog->prpl_entries = NULL;
+	}
+
+	vbox = dialog->prpls;
+
+	plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol));
+	if (!plugin)
+		return;
+
+	prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin);
+
+	account = dialog->account;
+
+	for (iter = prplinfo->protocol_options; iter; iter = iter->next)
+	{
+		GaimAccountOption *option = iter->data;
+		GaimPrefType type = gaim_account_option_get_type(option);
+
+		box = gnt_hbox_new(TRUE);
+		gnt_box_set_pad(GNT_BOX(box), 0);
+		gnt_box_add_widget(GNT_BOX(vbox), box);
+
+		if (type == GAIM_PREF_BOOLEAN)
+		{
+			GntWidget *widget = gnt_check_box_new(gaim_account_option_get_text(option));
+			gnt_box_add_widget(GNT_BOX(box), widget);
+			dialog->prpl_entries = g_list_append(dialog->prpl_entries, widget);
+
+			if (account)
+				gnt_check_box_set_checked(GNT_CHECK_BOX(widget),
+						gaim_account_get_bool(account,
+							gaim_account_option_get_setting(option),
+							gaim_account_option_get_default_bool(option)));
+			else
+				gnt_check_box_set_checked(GNT_CHECK_BOX(widget),
+						gaim_account_option_get_default_bool(option));
+		}
+		else
+		{
+			gnt_box_add_widget(GNT_BOX(box),
+					gnt_label_new(gaim_account_option_get_text(option)));
+
+			if (type == GAIM_PREF_STRING_LIST)
+			{
+				/* TODO: Use a combobox */
+				/*       Don't forget to append the widget to prpl_entries */
+			}
+			else
+			{
+				GntWidget *entry = gnt_entry_new(NULL);
+				gnt_box_add_widget(GNT_BOX(box), entry);
+				dialog->prpl_entries = g_list_append(dialog->prpl_entries, entry);
+
+				if (type == GAIM_PREF_STRING)
+				{
+					const char *dv = gaim_account_option_get_default_string(option);
+
+					if (account)
+						gnt_entry_set_text(GNT_ENTRY(entry),
+								gaim_account_get_string(account,
+									gaim_account_option_get_setting(option), dv));
+					else
+						gnt_entry_set_text(GNT_ENTRY(entry), dv);
+				}
+				else if (type == GAIM_PREF_INT)
+				{
+					char str[32];
+					int value = gaim_account_option_get_default_int(option);
+					if (account)
+						value = gaim_account_get_int(account,
+								gaim_account_option_get_setting(option), value);
+					snprintf(str, sizeof(str), "%d", value);
+					gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT);
+					gnt_entry_set_text(GNT_ENTRY(entry), str);
+				}
+				else
+				{
+					g_assert_not_reached();
+				}
+			}
+		}
+	}
+}
+
+static void
+update_user_options(AccountEditDialog *dialog)
+{
+	GaimPlugin *plugin;
+	GaimPluginProtocolInfo *prplinfo;
+
+	plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol));
+	if (!plugin)
+		return;
+
+	prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin);
+
+	if (dialog->newmail == NULL)
+		dialog->newmail = gnt_check_box_new(_("New mail notifications"));
+	if (dialog->account)
+		gnt_check_box_set_checked(GNT_CHECK_BOX(dialog->newmail),
+				gaim_account_get_check_mail(dialog->account));
+	if (!prplinfo || !(prplinfo->options & OPT_PROTO_MAIL_CHECK))
+		gnt_widget_set_visible(dialog->newmail, FALSE);
+	else
+		gnt_widget_set_visible(dialog->newmail, TRUE);
+
+	if (dialog->remember == NULL)
+		dialog->remember = gnt_check_box_new(_("Remember password"));
+	if (dialog->account)
+		gnt_check_box_set_checked(GNT_CHECK_BOX(dialog->remember),
+				gaim_account_get_remember_password(dialog->account));
+}
+
+static void
+prpl_changed_cb(GntWidget *combo, GaimPlugin *old, GaimPlugin *new, AccountEditDialog *dialog)
+{
+	update_user_splits(dialog);
+	add_protocol_options(dialog);
+	update_user_options(dialog);  /* This may not be necessary here */
+	gnt_box_readjust(GNT_BOX(dialog->window));
+	gnt_widget_draw(dialog->window);
+}
+
+static void
+edit_account(GaimAccount *account)
+{
+	GntWidget *window, *hbox;
+	GntWidget *combo, *button, *entry;
+	GList *list, *iter;
+	AccountEditDialog *dialog;
+
+	if (account)
+	{
+		GList *iter;
+		for (iter = accountdialogs; iter; iter = iter->next)
+		{
+			AccountEditDialog *dlg = iter->data;
+			if (dlg->account == account)
+				return;
+		}
+	}
+
+	dialog = g_new0(AccountEditDialog, 1);
+	accountdialogs = g_list_prepend(accountdialogs, dialog);
+
+	dialog->window = window = gnt_vbox_new(FALSE);
+	dialog->account = account;
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), account ? _("Modify Account") : _("New Account"));
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_widget_set_name(window, "edit-account");
+	gnt_box_set_fill(GNT_BOX(window), TRUE);
+
+	hbox = gnt_hbox_new(TRUE);
+	gnt_box_set_pad(GNT_BOX(hbox), 0);
+	gnt_box_add_widget(GNT_BOX(window), hbox);
+
+	dialog->protocol = combo = gnt_combo_box_new();
+	list = gaim_plugins_get_protocols();
+	for (iter = list; iter; iter = iter->next)
+	{
+		gnt_combo_box_add_data(GNT_COMBO_BOX(combo), iter->data,
+				((GaimPlugin*)iter->data)->info->name);
+	}
+
+	if (account)
+		gnt_combo_box_set_selected(GNT_COMBO_BOX(combo),
+				gaim_plugins_find_with_id(gaim_account_get_protocol_id(account)));
+	else
+		gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), list->data);
+
+	g_signal_connect(G_OBJECT(combo), "selection-changed", G_CALLBACK(prpl_changed_cb), dialog);
+
+	gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Protocol:")));
+	gnt_box_add_widget(GNT_BOX(hbox), combo);
+
+	hbox = gnt_hbox_new(TRUE);
+	gnt_box_set_pad(GNT_BOX(hbox), 0);
+	gnt_box_add_widget(GNT_BOX(window), hbox);
+
+	dialog->screenname = entry = gnt_entry_new(NULL);
+	gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Screen name:")));
+	gnt_box_add_widget(GNT_BOX(hbox), entry);
+
+	/* User splits */
+	update_user_splits(dialog);
+	gnt_box_add_widget(GNT_BOX(window), dialog->splits);
+
+	hbox = gnt_hbox_new(TRUE);
+	gnt_box_set_pad(GNT_BOX(hbox), 0);
+	gnt_box_add_widget(GNT_BOX(window), hbox);
+
+	dialog->password = entry = gnt_entry_new(NULL);
+	gnt_entry_set_masked(GNT_ENTRY(entry), TRUE);
+	gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Password:")));
+	gnt_box_add_widget(GNT_BOX(hbox), entry);
+	if (account)
+		gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_password(account));
+
+	hbox = gnt_hbox_new(TRUE);
+	gnt_box_set_pad(GNT_BOX(hbox), 0);
+	gnt_box_add_widget(GNT_BOX(window), hbox);
+
+	dialog->alias = entry = gnt_entry_new(NULL);
+	gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Alias:")));
+	gnt_box_add_widget(GNT_BOX(hbox), entry);
+	if (account)
+		gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_alias(account));
+
+	/* User options */
+	update_user_options(dialog);
+	gnt_box_add_widget(GNT_BOX(window), dialog->remember);
+	gnt_box_add_widget(GNT_BOX(window), dialog->newmail);
+
+	gnt_box_add_widget(GNT_BOX(window), gnt_line_new(FALSE));
+
+	/* The advanced box */
+	add_protocol_options(dialog);
+	gnt_box_add_widget(GNT_BOX(window), dialog->prpls);
+
+	/* TODO: Add proxy options */
+
+	/* The button box */
+	hbox = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), hbox);
+	gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+
+	button = gnt_button_new(_("Cancel"));
+	gnt_box_add_widget(GNT_BOX(hbox), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), window);
+	
+	button = gnt_button_new(_("Save"));
+	gnt_box_add_widget(GNT_BOX(hbox), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(save_account_cb), dialog);
+
+	g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(edit_dialog_destroy), dialog);
+
+	gnt_widget_show(window);
+	gnt_box_readjust(GNT_BOX(window));
+	gnt_widget_draw(window);
+}
+
+static void
+add_account_cb(GntWidget *widget, gpointer null)
+{
+	edit_account(NULL);
+}
+
+static void
+modify_account_cb(GntWidget *widget, GntTree *tree)
+{
+	GaimAccount *account = gnt_tree_get_selection_data(tree);
+	if (!account)
+		return;
+	edit_account(account);
+}
+
+static void
+really_delete_account(GaimAccount *account)
+{
+	GList *iter;
+	for (iter = accountdialogs; iter; iter = iter->next)
+	{
+		AccountEditDialog *dlg = iter->data;
+		if (dlg->account == account)
+		{
+			gnt_widget_destroy(dlg->window);
+			break;
+		}
+	}
+	gaim_accounts_delete(account);
+}
+
+static void
+delete_account_cb(GntWidget *widget, GntTree *tree)
+{
+	GaimAccount *account;
+	char *prompt;
+
+	account  = gnt_tree_get_selection_data(tree);
+	if (!account)
+		return;
+
+	prompt = g_strdup_printf(_("Are you sure you want to delete %s?"),
+			gaim_account_get_username(account));
+
+	gaim_request_close_with_handle(account); /* Close any other opened delete window */
+	gaim_request_action(account, _("Delete Account"), prompt, NULL, 0, account, 2,
+			_("Delete"), really_delete_account, _("Cancel"), NULL);
+	g_free(prompt);
+}
+
+static void
+account_toggled(GntWidget *widget, void *key, gpointer null)
+{
+	GaimAccount *account = key;
+
+	gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key));
+}
+
+static void
+reset_accounts_win(GntWidget *widget, gpointer null)
+{
+	accounts.window = NULL;
+	accounts.tree = NULL;
+}
+
+void gg_accounts_show_all()
+{
+	GList *iter;
+	GntWidget *box, *button;
+
+	if (accounts.window)
+		return;
+
+	accounts.window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE);
+	gnt_box_set_title(GNT_BOX(accounts.window), _("Accounts"));
+	gnt_box_set_pad(GNT_BOX(accounts.window), 0);
+	gnt_box_set_alignment(GNT_BOX(accounts.window), GNT_ALIGN_MID);
+	gnt_widget_set_name(accounts.window, "accounts");
+
+	gnt_box_add_widget(GNT_BOX(accounts.window),
+			gnt_label_new(_("You can enable/disable accounts from the following list.")));
+
+	gnt_box_add_widget(GNT_BOX(accounts.window), gnt_line_new(FALSE));
+
+	accounts.tree = gnt_tree_new_with_columns(2);
+	GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER);
+
+	for (iter = gaim_accounts_get_all(); iter; iter = iter->next)
+	{
+		GaimAccount *account = iter->data;
+		account_add(account);
+	}
+
+	g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL);
+	
+	gnt_tree_set_col_width(GNT_TREE(accounts.tree), 0, 40);
+	gnt_tree_set_col_width(GNT_TREE(accounts.tree), 1, 10);
+	gnt_box_add_widget(GNT_BOX(accounts.window), accounts.tree);
+
+	gnt_box_add_widget(GNT_BOX(accounts.window), gnt_line_new(FALSE));
+
+	box = gnt_hbox_new(FALSE);
+
+	button = gnt_button_new(_("Add"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_account_cb), NULL);
+
+	button = gnt_button_new(_("Modify"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(modify_account_cb), accounts.tree);
+
+	button = gnt_button_new(_("Delete"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_account_cb), accounts.tree);
+	
+	gnt_box_add_widget(GNT_BOX(accounts.window), box);
+
+	g_signal_connect(G_OBJECT(accounts.window), "destroy", G_CALLBACK(reset_accounts_win), NULL);
+	
+	gnt_widget_show(accounts.window);
+}
+
+static gpointer
+gg_accounts_get_handle()
+{
+	static int handle;
+
+	return &handle;
+}
+
+static void
+account_added_callback(GaimAccount *account)
+{
+	if (accounts.window == NULL)
+		return;
+	account_add(account);
+	gnt_widget_draw(accounts.tree);
+}
+
+static void
+account_removed_callback(GaimAccount *account)
+{
+	if (accounts.window == NULL)
+		return;
+
+	gnt_tree_remove(GNT_TREE(accounts.tree), account);
+}
+
+void gg_accounts_init()
+{
+	GList *iter;
+
+	gaim_signal_connect(gaim_accounts_get_handle(), "account-added",
+			gg_accounts_get_handle(), GAIM_CALLBACK(account_added_callback),
+			NULL);
+	gaim_signal_connect(gaim_accounts_get_handle(), "account-removed",
+			gg_accounts_get_handle(), GAIM_CALLBACK(account_removed_callback),
+			NULL);
+	
+	for (iter = gaim_accounts_get_all(); iter; iter = iter->next) {
+		if (gaim_account_get_enabled(iter->data, GAIM_GNT_UI))
+			break;
+	}
+	if (!iter)
+		gg_accounts_show_all();
+}
+
+void gg_accounts_uninit()
+{
+	if (accounts.window)
+		gnt_widget_destroy(accounts.window);
+}
+
+/* The following uiops stuff are copied from gtkaccount.c */
+typedef struct
+{
+	GaimAccount *account;
+	char *username;
+	char *alias;
+} AddUserData;
+
+static char *
+make_info(GaimAccount *account, GaimConnection *gc, const char *remote_user,
+          const char *id, const char *alias, const char *msg)
+{
+	if (msg != NULL && *msg == '\0')
+		msg = NULL;
+
+	return g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s"),
+	                       remote_user,
+	                       (alias != NULL ? " ("  : ""),
+	                       (alias != NULL ? alias : ""),
+	                       (alias != NULL ? ")"   : ""),
+	                       (id != NULL
+	                        ? id
+	                        : (gaim_connection_get_display_name(gc) != NULL
+	                           ? gaim_connection_get_display_name(gc)
+	                           : gaim_account_get_username(account))),
+	                       (msg != NULL ? ": " : "."),
+	                       (msg != NULL ? msg  : ""));
+}
+
+static void
+notify_added(GaimAccount *account, const char *remote_user,
+			const char *id, const char *alias,
+			const char *msg)
+{
+	char *buffer;
+	GaimConnection *gc;
+
+	gc = gaim_account_get_connection(account);
+
+	buffer = make_info(account, gc, remote_user, id, alias, msg);
+
+	gaim_notify_info(NULL, NULL, buffer, NULL);
+
+	g_free(buffer);
+}
+
+static void
+free_add_user_data(AddUserData *data)
+{
+	g_free(data->username);
+
+	if (data->alias != NULL)
+		g_free(data->alias);
+
+	g_free(data);
+}
+
+static void
+add_user_cb(AddUserData *data)
+{
+	GaimConnection *gc = gaim_account_get_connection(data->account);
+
+	if (g_list_find(gaim_connections_get_all(), gc))
+	{
+		gaim_blist_request_add_buddy(data->account, data->username,
+									 NULL, data->alias);
+	}
+
+	free_add_user_data(data);
+}
+
+static void
+request_add(GaimAccount *account, const char *remote_user,
+		  const char *id, const char *alias,
+		  const char *msg)
+{
+	char *buffer;
+	GaimConnection *gc;
+	AddUserData *data;
+
+	gc = gaim_account_get_connection(account);
+
+	data = g_new0(AddUserData, 1);
+	data->account  = account;
+	data->username = g_strdup(remote_user);
+	data->alias    = (alias != NULL ? g_strdup(alias) : NULL);
+
+	buffer = make_info(account, gc, remote_user, id, alias, msg);
+	gaim_request_action(NULL, NULL, _("Add buddy to your list?"),
+	                    buffer, GAIM_DEFAULT_ACTION_NONE, data, 2,
+	                    _("Add"),    G_CALLBACK(add_user_cb),
+	                    _("Cancel"), G_CALLBACK(free_add_user_data));
+	g_free(buffer);
+}
+
+static GaimAccountUiOps ui_ops = 
+{
+	.notify_added = notify_added,
+	.status_changed = NULL,
+	.request_add  = request_add
+};
+
+GaimAccountUiOps *gg_accounts_get_ui_ops()
+{
+	return &ui_ops;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntaccount.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,59 @@
+/**
+ * @file gntaccount.h GNT Account API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_ACCOUNT_H
+#define _GNT_ACCOUNT_H
+
+#include "account.h"
+
+/**********************************************************************
+ * @name GNT Account API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimAccountUiOps structure populated with the appropriate functions.
+ */
+GaimAccountUiOps *gg_accounts_get_ui_ops(void);
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_accounts_init(void);
+
+/**
+ * Perform necessary uninitializations.
+ */
+void gg_accounts_uninit(void);
+
+/**
+ * Show the account-manager dialog.
+ */
+void gg_accounts_show_all(void);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntblist.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,2204 @@
+/**
+ * @file gntblist.c GNT BuddyList API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <account.h>
+#include <blist.h>
+#include <notify.h>
+#include <request.h>
+#include <savedstatuses.h>
+#include <server.h>
+#include <signal.h>
+#include <status.h>
+#include <util.h>
+#include "debug.h"
+
+#include "gntgaim.h"
+#include "gntbox.h"
+#include "gntcombobox.h"
+#include "gntentry.h"
+#include "gntlabel.h"
+#include "gntline.h"
+#include "gntmenu.h"
+#include "gntmenuitem.h"
+#include "gntmenuitemcheck.h"
+#include "gnttree.h"
+#include "gntutils.h"
+#include "gntwindow.h"
+
+#include "gntblist.h"
+#include "gntconv.h"
+#include "gntstatus.h"
+#include <string.h>
+
+#define PREF_ROOT "/gaim/gnt/blist"
+#define TYPING_TIMEOUT 4000
+
+typedef struct
+{
+	GntWidget *window;
+	GntWidget *tree;
+
+	GntWidget *tooltip;
+	GaimBlistNode *tnode;		/* Who is the tooltip being displayed for? */
+	GList *tagged;          /* A list of tagged blistnodes */
+
+	GntWidget *context;
+	GaimBlistNode *cnode;
+
+	/* XXX: I am KISSing */
+	GntWidget *status;          /* Dropdown with the statuses  */
+	GntWidget *statustext;      /* Status message */
+	int typing;
+
+	GntWidget *menu;
+	/* These are the menuitems that get regenerated */
+	GntMenuItem *accounts;
+	GntMenuItem *plugins;
+} GGBlist;
+
+typedef enum
+{
+	STATUS_PRIMITIVE = 0,
+	STATUS_SAVED_POPULAR,
+	STATUS_SAVED_ALL,
+	STATUS_SAVED_NEW
+} StatusType;
+
+typedef struct
+{
+	StatusType type;
+	union
+	{
+		GaimStatusPrimitive prim;
+		GaimSavedStatus *saved;
+	} u;
+} StatusBoxItem;
+
+GGBlist *ggblist;
+
+static void add_buddy(GaimBuddy *buddy, GGBlist *ggblist);
+static void add_contact(GaimContact *contact, GGBlist *ggblist);
+static void add_group(GaimGroup *group, GGBlist *ggblist);
+static void add_chat(GaimChat *chat, GGBlist *ggblist);
+static void add_node(GaimBlistNode *node, GGBlist *ggblist);
+static void draw_tooltip(GGBlist *ggblist);
+static gboolean remove_typing_cb(gpointer null);
+static void remove_peripherals(GGBlist *ggblist);
+static const char * get_display_name(GaimBlistNode *node);
+static void savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old);
+static void blist_show(GaimBuddyList *list);
+static void update_buddy_display(GaimBuddy *buddy, GGBlist *ggblist);
+static void account_signed_on_cb(void);
+
+/* Sort functions */
+static int blist_node_compare_text(GaimBlistNode *n1, GaimBlistNode *n2);
+static int blist_node_compare_status(GaimBlistNode *n1, GaimBlistNode *n2);
+static int blist_node_compare_log(GaimBlistNode *n1, GaimBlistNode *n2);
+
+static gboolean
+is_contact_online(GaimContact *contact)
+{
+	GaimBlistNode *node;
+	for (node = ((GaimBlistNode*)contact)->child; node; node = node->next) {
+		if (GAIM_BUDDY_IS_ONLINE((GaimBuddy*)node))
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+is_group_online(GaimGroup *group)
+{
+	GaimBlistNode *node;
+	for (node = ((GaimBlistNode*)group)->child; node; node = node->next) {
+		if (GAIM_BLIST_NODE_IS_CHAT(node))
+			return TRUE;
+		else if (is_contact_online((GaimContact*)node))
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+new_node(GaimBlistNode *node)
+{
+}
+
+static void add_node(GaimBlistNode *node, GGBlist *ggblist)
+{
+	if (GAIM_BLIST_NODE_IS_BUDDY(node))
+		add_buddy((GaimBuddy*)node, ggblist);
+	else if (GAIM_BLIST_NODE_IS_CONTACT(node))
+		add_contact((GaimContact*)node, ggblist);
+	else if (GAIM_BLIST_NODE_IS_GROUP(node))
+		add_group((GaimGroup*)node, ggblist);
+	else if (GAIM_BLIST_NODE_IS_CHAT(node))
+		add_chat((GaimChat *)node, ggblist);
+	draw_tooltip(ggblist);
+}
+
+static void
+remove_tooltip(GGBlist *ggblist)
+{
+	gnt_widget_destroy(ggblist->tooltip);
+	ggblist->tooltip = NULL;
+	ggblist->tnode = NULL;
+}
+
+static void
+node_remove(GaimBuddyList *list, GaimBlistNode *node)
+{
+	GGBlist *ggblist = list->ui_data;
+
+	if (ggblist == NULL || node->ui_data == NULL)
+		return;
+
+	gnt_tree_remove(GNT_TREE(ggblist->tree), node);
+	node->ui_data = NULL;
+	if (ggblist->tagged)
+		ggblist->tagged = g_list_remove(ggblist->tagged, node);
+
+	if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		GaimContact *contact = (GaimContact*)node->parent;
+		if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) ||
+				contact->currentsize < 1)
+			node_remove(list, (GaimBlistNode*)contact);
+	} else if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		GaimGroup *group = (GaimGroup*)node->parent;
+		if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) ||
+				group->currentsize < 1)
+			node_remove(list, node->parent);
+		for (node = node->child; node; node = node->next)
+			node->ui_data = NULL;
+	}
+
+	draw_tooltip(ggblist);
+}
+
+static void
+node_update(GaimBuddyList *list, GaimBlistNode *node)
+{
+	/* It really looks like this should never happen ... but it does.
+           This will at least emit a warning to the log when it
+           happens, so maybe someone will figure it out. */
+	g_return_if_fail(node != NULL);
+
+	if (list->ui_data == NULL)
+		return;   /* XXX: this is probably the place to auto-join chats */
+
+	if (node->ui_data != NULL) {
+		gnt_tree_change_text(GNT_TREE(ggblist->tree), node,
+				0, get_display_name(node));
+		gnt_tree_sort_row(GNT_TREE(ggblist->tree), node);
+	}
+
+	if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		GaimBuddy *buddy = (GaimBuddy*)node;
+		if (gaim_account_is_connected(buddy->account) &&
+				(GAIM_BUDDY_IS_ONLINE(buddy) || gaim_prefs_get_bool(PREF_ROOT "/showoffline")))
+			add_node((GaimBlistNode*)buddy, list->ui_data);
+		else
+			node_remove(gaim_get_blist(), node);
+
+		node_update(list, node->parent);
+	} else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
+		add_chat((GaimChat *)node, list->ui_data);
+	} else if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		GaimContact *contact = (GaimContact*)node;
+		if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) ||
+				contact->currentsize < 1)
+			node_remove(gaim_get_blist(), node);
+		else
+			add_node(node, list->ui_data);
+	} else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+		GaimGroup *group = (GaimGroup*)node;
+		if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) ||
+				group->currentsize < 1)
+			node_remove(list, node);
+	}
+}
+
+static void
+new_list(GaimBuddyList *list)
+{
+	if (ggblist)
+		return;
+
+	ggblist = g_new0(GGBlist, 1);
+	list->ui_data = ggblist;
+}
+
+static void
+add_buddy_cb(void *data, GaimRequestFields *allfields)
+{
+	const char *username = gaim_request_fields_get_string(allfields, "screenname");
+	const char *alias = gaim_request_fields_get_string(allfields, "alias");
+	const char *group = gaim_request_fields_get_string(allfields, "group");
+	GaimAccount *account = gaim_request_fields_get_account(allfields, "account");
+	const char *error = NULL;
+	GaimGroup *grp;
+	GaimBuddy *buddy;
+
+	if (!username)
+		error = _("You must provide a screename for the buddy.");
+	else if (!group)
+		error = _("You must provide a group.");
+	else if (!account)
+		error = _("You must select an account.");
+
+	if (error)
+	{
+		gaim_notify_error(NULL, _("Error"), _("Error adding buddy"), error);
+		return;
+	}
+
+	grp = gaim_find_group(group);
+	if (!grp)
+	{
+		grp = gaim_group_new(group);
+		gaim_blist_add_group(grp, NULL);
+	}
+
+	buddy = gaim_buddy_new(account, username, alias);
+	gaim_blist_add_buddy(buddy, NULL, grp, NULL);
+	gaim_account_add_buddy(account, buddy);
+}
+
+static void
+gg_request_add_buddy(GaimAccount *account, const char *username, const char *grp, const char *alias)
+{
+	GaimRequestFields *fields = gaim_request_fields_new();
+	GaimRequestFieldGroup *group = gaim_request_field_group_new(NULL);
+	GaimRequestField *field;
+
+	gaim_request_fields_add_group(fields, group);
+
+	field = gaim_request_field_string_new("screenname", _("Screen Name"), username, FALSE);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_string_new("alias", _("Alias"), alias, FALSE);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_string_new("group", _("Group"), grp, FALSE);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_account_new("account", _("Account"), NULL);
+	gaim_request_field_account_set_show_all(field, FALSE);
+	if (account)
+		gaim_request_field_account_set_value(field, account);
+	gaim_request_field_group_add_field(group, field);
+
+	gaim_request_fields(NULL, _("Add Buddy"), NULL, _("Please enter buddy information."),
+			fields, _("Add"), G_CALLBACK(add_buddy_cb), _("Cancel"), NULL, NULL);
+}
+
+static void
+add_chat_cb(void *data, GaimRequestFields *allfields)
+{
+	GaimAccount *account;
+	const char *alias, *name, *group;
+	GaimChat *chat;
+	GaimGroup *grp;
+	GHashTable *hash = NULL;
+	GaimConnection *gc;
+
+	account = gaim_request_fields_get_account(allfields, "account");
+	name = gaim_request_fields_get_string(allfields, "name");
+	alias = gaim_request_fields_get_string(allfields, "alias");
+	group = gaim_request_fields_get_string(allfields, "group");
+
+	if (!gaim_account_is_connected(account) || !name || !*name)
+		return;
+	
+	if (!group || !*group)
+		group = _("Chats");
+
+	gc = gaim_account_get_connection(account);
+
+	if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
+		hash = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, name);
+	
+	chat = gaim_chat_new(account, name, hash);
+
+	if (chat != NULL) {
+		if ((grp = gaim_find_group(group)) == NULL) {
+			grp = gaim_group_new(group);
+			gaim_blist_add_group(grp, NULL);
+		}
+		gaim_blist_add_chat(chat, grp, NULL);
+		gaim_blist_alias_chat(chat, alias);
+	}
+}
+
+static void
+gg_request_add_chat(GaimAccount *account, GaimGroup *grp, const char *alias, const char *name)
+{
+	GaimRequestFields *fields = gaim_request_fields_new();
+	GaimRequestFieldGroup *group = gaim_request_field_group_new(NULL);
+	GaimRequestField *field;
+
+	gaim_request_fields_add_group(fields, group);
+
+	field = gaim_request_field_account_new("account", _("Account"), NULL);
+	gaim_request_field_account_set_show_all(field, FALSE);
+	if (account)
+		gaim_request_field_account_set_value(field, account);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_string_new("name", _("Name"), name, FALSE);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_string_new("alias", _("Alias"), alias, FALSE);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_string_new("group", _("Group"), grp ? grp->name : NULL, FALSE);
+	gaim_request_field_group_add_field(group, field);
+
+	gaim_request_fields(NULL, _("Add Chat"), NULL,
+			_("You can edit more information from the context menu later."),
+			fields, _("Add"), G_CALLBACK(add_chat_cb), _("Cancel"), NULL, NULL);
+}
+
+static void
+add_group_cb(gpointer null, const char *group)
+{
+	GaimGroup *grp;
+
+	if (!group || !*group)
+	{
+		gaim_notify_error(NULL, _("Error"), _("Error adding group"),
+				_("You must give a name for the group to add."));
+		return;
+	}
+
+	grp = gaim_find_group(group);
+	if (!grp)
+	{
+		grp = gaim_group_new(group);
+		gaim_blist_add_group(grp, NULL);
+	}
+	else
+	{
+		gaim_notify_error(NULL, _("Error"), _("Error adding group"),
+				_("A group with the name already exists."));
+	}
+}
+
+static void
+gg_request_add_group()
+{
+	gaim_request_input(NULL, _("Add Group"), NULL, _("Enter the name of the group"),
+			NULL, FALSE, FALSE, NULL,
+			_("Add"), G_CALLBACK(add_group_cb), _("Cancel"), NULL, NULL);
+}
+
+static GaimBlistUiOps blist_ui_ops =
+{
+	new_list,
+	new_node,
+	blist_show,
+	node_update,
+	node_remove,
+	NULL,
+	NULL,
+	.request_add_buddy = gg_request_add_buddy,
+	.request_add_chat = gg_request_add_chat,
+	.request_add_group = gg_request_add_group
+};
+
+static gpointer
+gg_blist_get_handle()
+{
+	static int handle;
+
+	return &handle;
+}
+
+static void
+add_group(GaimGroup *group, GGBlist *ggblist)
+{
+	GaimBlistNode *node = (GaimBlistNode *)group;
+	if (node->ui_data)
+		return;
+	node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), group,
+			gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)), NULL, NULL);
+}
+
+static const char *
+get_display_name(GaimBlistNode *node)
+{
+	static char text[2096];
+	char status[8] = " ";
+	const char *name = NULL;
+
+	if (GAIM_BLIST_NODE_IS_CONTACT(node))
+		node = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)node);  /* XXX: this can return NULL?! */
+	
+	if (node == NULL)
+		return NULL;
+
+	if (GAIM_BLIST_NODE_IS_BUDDY(node))
+	{
+		GaimBuddy *buddy = (GaimBuddy *)node;
+		GaimStatusPrimitive prim;
+		GaimPresence *presence;
+		GaimStatus *now;
+		gboolean ascii = gnt_ascii_only();
+		
+		presence = gaim_buddy_get_presence(buddy);
+		now = gaim_presence_get_active_status(presence);
+
+		prim = gaim_status_type_get_primitive(gaim_status_get_type(now));
+
+		switch(prim)
+		{
+			case GAIM_STATUS_OFFLINE:
+				strncpy(status, ascii ? "x" : "⊗", sizeof(status) - 1);
+				break;
+			case GAIM_STATUS_AVAILABLE:
+				strncpy(status, ascii ? "o" : "◯", sizeof(status) - 1);
+				break;
+			default:
+				strncpy(status, ascii ? "." : "⊖", sizeof(status) - 1);
+				break;
+		}
+		name = gaim_buddy_get_alias(buddy);
+	}
+	else if (GAIM_BLIST_NODE_IS_CHAT(node))
+	{
+		GaimChat *chat = (GaimChat*)node;
+		name = gaim_chat_get_name(chat);
+
+		strncpy(status, "~", sizeof(status) - 1);
+	}
+	else if (GAIM_BLIST_NODE_IS_GROUP(node))
+		return ((GaimGroup*)node)->name;
+
+	snprintf(text, sizeof(text) - 1, "%s %s", status, name);
+
+	return text;
+}
+
+static void
+add_chat(GaimChat *chat, GGBlist *ggblist)
+{
+	GaimGroup *group;
+	GaimBlistNode *node = (GaimBlistNode *)chat;
+	if (node->ui_data)
+		return;
+	if (!gaim_account_is_connected(chat->account))
+		return;
+
+	group = gaim_chat_get_group(chat);
+	add_node((GaimBlistNode*)group, ggblist);
+
+	node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), chat,
+				gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)),
+				group, NULL);
+}
+
+static void
+add_contact(GaimContact *contact, GGBlist *ggblist)
+{
+	GaimGroup *group;
+	GaimBlistNode *node = (GaimBlistNode*)contact;
+	const char *name;
+
+	if (node->ui_data)
+		return;
+	
+	name = get_display_name(node);
+	if (name == NULL)
+		return;
+	
+	group = (GaimGroup*)node->parent;
+	add_node((GaimBlistNode*)group, ggblist);
+
+	node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), contact,
+				gnt_tree_create_row(GNT_TREE(ggblist->tree), name),
+				group, NULL);
+
+	gnt_tree_set_expanded(GNT_TREE(ggblist->tree), contact, FALSE);
+}
+
+static void
+add_buddy(GaimBuddy *buddy, GGBlist *ggblist)
+{
+	GaimContact *contact;
+	GaimBlistNode *node = (GaimBlistNode *)buddy;
+	if (node->ui_data)
+		return;
+
+	contact = (GaimContact*)node->parent;
+	if (!contact)   /* When a new buddy is added and show-offline is set */
+		return;
+	add_node((GaimBlistNode*)contact, ggblist);
+
+	node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy,
+				gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)),
+				contact, NULL);
+	if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) {
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, GNT_TEXT_FLAG_DIM);
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, GNT_TEXT_FLAG_DIM);
+	} else {
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, 0);
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, 0);
+	}
+}
+
+#if 0
+static void
+buddy_signed_on(GaimBuddy *buddy, GGBlist *ggblist)
+{
+	add_node((GaimBlistNode*)buddy, ggblist);
+}
+
+static void
+buddy_signed_off(GaimBuddy *buddy, GGBlist *ggblist)
+{
+	node_remove(gaim_get_blist(), (GaimBlistNode*)buddy);
+}
+#endif
+
+GaimBlistUiOps *gg_blist_get_ui_ops()
+{
+	return &blist_ui_ops;
+}
+
+static void
+selection_activate(GntWidget *widget, GGBlist *ggblist)
+{
+	GntTree *tree = GNT_TREE(ggblist->tree);
+	GaimBlistNode *node = gnt_tree_get_selection_data(tree);
+
+	if (!node)
+		return;
+	
+	if (GAIM_BLIST_NODE_IS_CONTACT(node))
+		node = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)node);
+
+	if (GAIM_BLIST_NODE_IS_BUDDY(node))
+	{
+		GaimBuddy *buddy = (GaimBuddy *)node;
+		GaimConversation *conv =  gaim_conversation_new(GAIM_CONV_TYPE_IM,
+					gaim_buddy_get_account(buddy),
+					gaim_buddy_get_name(buddy));
+		gg_conversation_set_active(conv);
+	}
+	else if (GAIM_BLIST_NODE_IS_CHAT(node))
+	{
+		GaimChat *chat = (GaimChat*)node;
+		serv_join_chat(chat->account->gc, chat->components);
+	}
+}
+
+static void
+context_menu_callback(GntMenuItem *item, gpointer data)
+{
+	GaimMenuAction *action = data;
+	GaimBlistNode *node = ggblist->cnode;
+	if (action) {
+		void (*callback)(GaimBlistNode *, gpointer);
+		callback = (void (*)(GaimBlistNode *, gpointer))action->callback;
+		if (callback)
+			callback(action->data, node);
+		else
+			return;
+	}
+}
+
+static void
+gnt_append_menu_action(GntMenu *menu, GaimMenuAction *action, gpointer parent)
+{
+	GList *list;
+	GntMenuItem *item;
+
+	if (action == NULL)
+		return;
+
+	item = gnt_menuitem_new(action->label);
+	if (action->callback)
+		gnt_menuitem_set_callback(GNT_MENUITEM(item), context_menu_callback, action);
+	gnt_menu_add_item(menu, GNT_MENUITEM(item));
+
+	if (action->children) {
+		GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
+		gnt_menuitem_set_submenu(item, GNT_MENU(sub));
+		for (list = action->children; list; list = list->next)
+			gnt_append_menu_action(GNT_MENU(sub), list->data, action);
+	}
+}
+
+static void
+append_proto_menu(GntMenu *menu, GaimConnection *gc, GaimBlistNode *node)
+{
+	GList *list;
+	GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
+
+	if(!prpl_info || !prpl_info->blist_node_menu)
+		return;
+
+	for(list = prpl_info->blist_node_menu(node); list;
+			list = g_list_delete_link(list, list))
+	{
+		GaimMenuAction *act = (GaimMenuAction *) list->data;
+		act->data = node;
+		gnt_append_menu_action(menu, act, NULL);
+	}
+}
+
+static void
+add_custom_action(GntMenu *menu, const char *label, GaimCallback callback,
+		gpointer data)
+{
+	GaimMenuAction *action = gaim_menu_action_new(label, callback, data, NULL);
+	gnt_append_menu_action(menu, action, NULL);
+	g_signal_connect_swapped(G_OBJECT(menu), "destroy",
+			G_CALLBACK(gaim_menu_action_free), action);
+}
+
+static void
+chat_components_edit_ok(GaimChat *chat, GaimRequestFields *allfields)
+{
+	GList *groups, *fields;
+
+	for (groups = gaim_request_fields_get_groups(allfields); groups; groups = groups->next) {
+		fields = gaim_request_field_group_get_fields(groups->data);
+		for (; fields; fields = fields->next) {
+			GaimRequestField *field = fields->data;
+			const char *id;
+			char *val;
+
+			id = gaim_request_field_get_id(field);
+			if (gaim_request_field_get_type(field) == GAIM_REQUEST_FIELD_INTEGER)
+				val = g_strdup_printf("%d", gaim_request_field_int_get_value(field));
+			else
+				val = g_strdup(gaim_request_field_string_get_value(field));
+
+			g_hash_table_replace(chat->components, g_strdup(id), val);  /* val should not be free'd */
+		}
+	}
+}
+
+static void
+chat_components_edit(GaimChat *chat, GaimBlistNode *selected)
+{
+	GaimRequestFields *fields = gaim_request_fields_new();
+	GaimRequestFieldGroup *group = gaim_request_field_group_new(NULL);
+	GaimRequestField *field;
+	GList *parts, *iter;
+	struct proto_chat_entry *pce;
+
+	gaim_request_fields_add_group(fields, group);
+
+	parts = GAIM_PLUGIN_PROTOCOL_INFO(chat->account->gc->prpl)->chat_info(chat->account->gc);
+
+	for (iter = parts; iter; iter = iter->next) {
+		pce = iter->data;
+		if (pce->is_int) {
+			int val;
+			const char *str = g_hash_table_lookup(chat->components, pce->identifier);
+			if (!str || sscanf(str, "%d", &val) != 1)
+				val = pce->min;
+			field = gaim_request_field_int_new(pce->identifier, pce->label, val);
+		} else {
+			field = gaim_request_field_string_new(pce->identifier, pce->label,
+					g_hash_table_lookup(chat->components, pce->identifier), FALSE);
+		}
+
+		gaim_request_field_group_add_field(group, field);
+		g_free(pce);
+	}
+
+	g_list_free(parts);
+
+	gaim_request_fields(NULL, _("Edit Chat"), NULL, _("Please Update the necessary fields."),
+			fields, _("Edit"), G_CALLBACK(chat_components_edit_ok), _("Cancel"), NULL, chat);
+}
+
+static void
+autojoin_toggled(GntMenuItem *item, gpointer data)
+{
+	GaimMenuAction *action = data;
+	gaim_blist_node_set_bool(action->data, "gnt-autojoin",
+				gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item)));
+}
+
+static void
+create_chat_menu(GntMenu *menu, GaimChat *chat)
+{
+	GaimMenuAction *action = gaim_menu_action_new(_("Auto-join"), NULL, chat, NULL);
+	GntMenuItem *check = gnt_menuitem_check_new(action->label);
+	gnt_menuitem_check_set_checked(GNT_MENUITEM_CHECK(check),
+				gaim_blist_node_get_bool((GaimBlistNode*)chat, "gnt-autojoin"));
+	gnt_menu_add_item(menu, check);
+	gnt_menuitem_set_callback(check, autojoin_toggled, action);
+	g_signal_connect_swapped(G_OBJECT(menu), "destroy",
+			G_CALLBACK(gaim_menu_action_free), action);
+
+	add_custom_action(menu, _("Edit Settings"), (GaimCallback)chat_components_edit, chat);
+}
+
+static void
+gg_add_buddy(GaimGroup *grp, GaimBlistNode *selected)
+{
+	gaim_blist_request_add_buddy(NULL, NULL, grp ? grp->name : NULL, NULL);
+}
+
+static void
+gg_add_group(GaimGroup *grp, GaimBlistNode *selected)
+{
+	gaim_blist_request_add_group();
+}
+
+static void
+gg_add_chat(GaimGroup *grp, GaimBlistNode *selected)
+{
+	gaim_blist_request_add_chat(NULL, grp, NULL, NULL);
+}
+
+static void
+create_group_menu(GntMenu *menu, GaimGroup *group)
+{
+	add_custom_action(menu, _("Add Buddy"),
+			GAIM_CALLBACK(gg_add_buddy), group);
+	add_custom_action(menu, _("Add Chat"),
+			GAIM_CALLBACK(gg_add_chat), group);
+	add_custom_action(menu, _("Add Group"),
+			GAIM_CALLBACK(gg_add_group), group);
+}
+
+static void
+gg_blist_get_buddy_info_cb(GaimBuddy *buddy, GaimBlistNode *selected)
+{
+	serv_get_info(buddy->account->gc, gaim_buddy_get_name(buddy));
+}
+
+static void
+create_buddy_menu(GntMenu *menu, GaimBuddy *buddy)
+{
+	GaimPluginProtocolInfo *prpl_info;
+
+	prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl);
+	if (prpl_info && prpl_info->get_info)
+	{
+		add_custom_action(menu, _("Get Info"),
+				GAIM_CALLBACK(gg_blist_get_buddy_info_cb), buddy);
+	}
+
+#if 0
+	add_custom_action(tree, _("Add Buddy Pounce"),
+			GAIM_CALLBACK(gg_blist_add_buddy_pounce_cb)), buddy);
+
+	if (prpl_info && prpl_info->send_file)
+	{
+		if (!prpl_info->can_receive_file ||
+			prpl_info->can_receive_file(buddy->account->gc, buddy->name))
+			add_custom_action(tree, _("Send File"),
+					GAIM_CALLBACK(gg_blist_show_file_cb)), buddy);
+	}
+
+	add_custom_action(tree, _("View Log"),
+			GAIM_CALLBACK(gg_blist_view_log_cb)), buddy);
+#endif
+
+	/* Protocol actions */
+	append_proto_menu(menu,
+			gaim_account_get_connection(gaim_buddy_get_account(buddy)),
+			(GaimBlistNode*)buddy);
+}
+
+static void
+append_extended_menu(GntMenu *menu, GaimBlistNode *node)
+{
+	GList *iter;
+
+	for (iter = gaim_blist_node_get_extended_menu(node);
+			iter; iter = g_list_delete_link(iter, iter))
+	{
+		gnt_append_menu_action(menu, iter->data, NULL);
+	}
+}
+
+/* Xerox'd from gtkdialogs.c:gaim_gtkdialogs_remove_contact_cb */
+static void
+remove_contact(GaimContact *contact)
+{
+	GaimBlistNode *bnode, *cnode;
+	GaimGroup *group;
+
+	cnode = (GaimBlistNode *)contact;
+	group = (GaimGroup*)cnode->parent;
+	for (bnode = cnode->child; bnode; bnode = bnode->next) {
+		GaimBuddy *buddy = (GaimBuddy*)bnode;
+		if (gaim_account_is_connected(buddy->account))
+			gaim_account_remove_buddy(buddy->account, buddy, group);
+	}
+	gaim_blist_remove_contact(contact);
+}
+
+static void
+rename_blist_node(GaimBlistNode *node, const char *newname)
+{
+	const char *name = newname;
+	if (name && !*name)
+		name = NULL;
+
+	if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		GaimContact *contact = (GaimContact*)node;
+		GaimBuddy *buddy = gaim_contact_get_priority_buddy(contact);
+		gaim_blist_alias_contact(contact, name);
+		gaim_blist_alias_buddy(buddy, name);
+		serv_alias_buddy(buddy);
+	} else if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		gaim_blist_alias_buddy((GaimBuddy*)node, name);
+		serv_alias_buddy((GaimBuddy*)node);
+	} else if (GAIM_BLIST_NODE_IS_CHAT(node))
+		gaim_blist_alias_chat((GaimChat*)node, name);
+	else if (GAIM_BLIST_NODE_IS_GROUP(node) && (name != NULL))
+		gaim_blist_rename_group((GaimGroup*)node, name);
+	else
+		g_return_if_reached();
+}
+
+static void
+gg_blist_rename_node_cb(GaimBlistNode *node, GaimBlistNode *selected)
+{
+	const char *name = NULL;
+	char *prompt;
+
+	if (GAIM_BLIST_NODE_IS_CONTACT(node))
+		name = gaim_contact_get_alias((GaimContact*)node);
+	else if (GAIM_BLIST_NODE_IS_BUDDY(node))
+		name = gaim_buddy_get_contact_alias((GaimBuddy*)node);
+	else if (GAIM_BLIST_NODE_IS_CHAT(node))
+		name = gaim_chat_get_name((GaimChat*)node);
+	else if (GAIM_BLIST_NODE_IS_GROUP(node))
+		name = ((GaimGroup*)node)->name;
+	else
+		g_return_if_reached();
+
+	prompt = g_strdup_printf(_("Please enter the new name for %s"), name);
+
+	gaim_request_input(node, _("Rename"), prompt, _("Enter empty string to reset the name."),
+			name, FALSE, FALSE, NULL, _("Rename"), G_CALLBACK(rename_blist_node),
+			_("Cancel"), NULL, node);
+
+	g_free(prompt);
+}
+
+/* Xeroxed from gtkdialogs.c:gaim_gtkdialogs_remove_group_cb*/
+static void
+remove_group(GaimGroup *group)
+{
+	GaimBlistNode *cnode, *bnode;
+
+	cnode = ((GaimBlistNode*)group)->child;
+
+	while (cnode) {
+		if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) {
+			bnode = cnode->child;
+			cnode = cnode->next;
+			while (bnode) {
+				GaimBuddy *buddy;
+				if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) {
+					buddy = (GaimBuddy*)bnode;
+					bnode = bnode->next;
+					if (gaim_account_is_connected(buddy->account)) {
+						gaim_account_remove_buddy(buddy->account, buddy, group);
+						gaim_blist_remove_buddy(buddy);
+					}
+				} else {
+					bnode = bnode->next;
+				}
+			}
+		} else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) {
+			GaimChat *chat = (GaimChat *)cnode;
+			cnode = cnode->next;
+			if (gaim_account_is_connected(chat->account))
+				gaim_blist_remove_chat(chat);
+		} else {
+			cnode = cnode->next;
+		}
+	}
+
+	gaim_blist_remove_group(group);
+}
+
+static void
+gg_blist_remove_node(GaimBlistNode *node)
+{
+	if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		remove_contact((GaimContact*)node);
+	} else if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		GaimBuddy *buddy = (GaimBuddy*)node;
+		GaimGroup *group = gaim_buddy_get_group(buddy);
+		gaim_account_remove_buddy(gaim_buddy_get_account(buddy), buddy, group);
+		gaim_blist_remove_buddy(buddy);
+	} else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
+		gaim_blist_remove_chat((GaimChat*)node);
+	} else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+		remove_group((GaimGroup*)node);
+	}
+}
+
+static void
+gg_blist_remove_node_cb(GaimBlistNode *node, GaimBlistNode *selected)
+{
+	char *primary;
+	const char *name, *sec = NULL;
+
+	/* XXX: could be a contact */
+	if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		GaimContact *c = (GaimContact*)node;
+		name = gaim_contact_get_alias(c);
+		if (c->totalsize > 1)
+			sec = _("Removing this contact will also remove all the buddies in the contact");
+	} else if (GAIM_BLIST_NODE_IS_BUDDY(node))
+		name = gaim_buddy_get_name((GaimBuddy*)node);
+	else if (GAIM_BLIST_NODE_IS_CHAT(node))
+		name = gaim_chat_get_name((GaimChat*)node);
+	else if (GAIM_BLIST_NODE_IS_GROUP(node))
+	{
+		name = ((GaimGroup*)node)->name;
+		sec = _("Removing this group will also remove all the buddies in the group");
+	}
+	else
+		return;
+
+	primary = g_strdup_printf(_("Are you sure you want to remove %s?"), name);
+
+	/* XXX: anything to do with the returned ui-handle? */
+	gaim_request_action(node, _("Confirm Remove"),
+			primary, sec,
+			1, node, 2,
+			_("Remove"), gg_blist_remove_node,
+			_("Cancel"), NULL);
+	g_free(primary);
+}
+
+static void
+gg_blist_toggle_tag_buddy(GaimBlistNode *node)
+{
+	GList *iter;
+	if (node == NULL)
+		return;
+	if (GAIM_BLIST_NODE_IS_CHAT(node) || GAIM_BLIST_NODE_IS_GROUP(node))
+		return;
+	if (ggblist->tagged && (iter = g_list_find(ggblist->tagged, node)) != NULL) {
+		ggblist->tagged = g_list_delete_link(ggblist->tagged, iter);
+	} else {
+		ggblist->tagged = g_list_prepend(ggblist->tagged, node);
+	}
+	if (GAIM_BLIST_NODE_IS_CONTACT(node))
+		node = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)node);
+	update_buddy_display((GaimBuddy*)node, ggblist);
+}
+
+static void
+gg_blist_place_tagged(GaimBlistNode *target)
+{
+	GaimGroup *tg = NULL;
+	GaimContact *tc = NULL;
+
+	if (target == NULL)
+		return;
+
+	/* This target resolution probably needs more clarification; for
+	 * example, if I tag a buddy in a contact, then place on
+	 * another buddy in the same contact, I probably intend to
+	 * place the tagged buddy immediately after (before?) the
+	 * target buddy -- this will simply move the tagged buddy
+	 * within the same contact without reference to position. */
+	if (GAIM_BLIST_NODE_IS_GROUP(target))
+		tg = (GaimGroup*)target;
+	else if (GAIM_BLIST_NODE_IS_CONTACT(target))
+		tc = (GaimContact*)target;
+	else /* Buddy or Chat */
+		tc = (GaimContact*)target->parent;
+
+	if (ggblist->tagged) {
+		GList *list = ggblist->tagged;
+		ggblist->tagged = NULL;
+
+		while (list) {
+			GaimBlistNode *node = list->data;
+			list = g_list_delete_link(list, list);
+			if (tg) {
+				if (GAIM_BLIST_NODE_IS_CONTACT(node))
+					gaim_blist_add_contact((GaimContact*)node, tg, NULL);
+				else
+					gaim_blist_add_buddy((GaimBuddy*)node, NULL, tg, NULL);
+			} else {
+				if (GAIM_BLIST_NODE_IS_BUDDY(node))
+					gaim_blist_add_buddy((GaimBuddy*)node, tc,
+						gaim_buddy_get_group(gaim_contact_get_priority_buddy(tc)), NULL);
+				else if (GAIM_BLIST_NODE_IS_CONTACT(node))
+					gaim_blist_merge_contact((GaimContact*)node, target);
+			}
+		}
+	}
+}
+
+static void
+context_menu_destroyed(GntWidget *widget, GGBlist *ggblist)
+{
+	ggblist->context = NULL;
+}
+
+static void
+draw_context_menu(GGBlist *ggblist)
+{
+	GaimBlistNode *node = NULL;
+	GntWidget *context = NULL;
+	GntTree *tree = NULL;
+	int x, y, top, width;
+	char *title = NULL;
+
+	tree = GNT_TREE(ggblist->tree);
+
+	node = gnt_tree_get_selection_data(tree);
+
+	if (ggblist->tooltip)
+		remove_tooltip(ggblist);
+
+	ggblist->cnode = node;
+
+	ggblist->context = context = gnt_menu_new(GNT_MENU_POPUP);
+	g_signal_connect(G_OBJECT(context), "destroy", G_CALLBACK(context_menu_destroyed), ggblist);
+
+	if (!node) {
+		create_group_menu(GNT_MENU(context), NULL);
+		title = g_strdup(_("Buddy List"));
+	} else if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		create_buddy_menu(GNT_MENU(context),
+			gaim_contact_get_priority_buddy((GaimContact*)node));
+		title = g_strdup(gaim_contact_get_alias((GaimContact*)node));
+	} else if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		GaimBuddy *buddy = (GaimBuddy *)node;
+		create_buddy_menu(GNT_MENU(context), buddy);
+		title = g_strdup(gaim_buddy_get_name(buddy));
+	} else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
+		GaimChat *chat = (GaimChat*)node;
+		create_chat_menu(GNT_MENU(context), chat);
+		title = g_strdup(gaim_chat_get_name(chat));
+	} else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+		GaimGroup *group = (GaimGroup *)node;
+		create_group_menu(GNT_MENU(context), group);
+		title = g_strdup(group->name);
+	}
+
+	append_extended_menu(GNT_MENU(context), node);
+
+	/* These are common for everything */
+	if (node) {
+		add_custom_action(GNT_MENU(context), _("Rename"),
+				GAIM_CALLBACK(gg_blist_rename_node_cb), node);
+		add_custom_action(GNT_MENU(context), _("Remove"),
+				GAIM_CALLBACK(gg_blist_remove_node_cb), node);
+
+		if (ggblist->tagged && (GAIM_BLIST_NODE_IS_CONTACT(node)
+				|| GAIM_BLIST_NODE_IS_GROUP(node))) {
+			add_custom_action(GNT_MENU(context), _("Place tagged"),
+					GAIM_CALLBACK(gg_blist_place_tagged), node);
+		}
+		
+		if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CONTACT(node)) {
+			add_custom_action(GNT_MENU(context), _("Toggle Tag"),
+					GAIM_CALLBACK(gg_blist_toggle_tag_buddy), node);
+		}
+	}
+
+	/* Set the position for the popup */
+	gnt_widget_get_position(GNT_WIDGET(tree), &x, &y);
+	gnt_widget_get_size(GNT_WIDGET(tree), &width, NULL);
+	top = gnt_tree_get_selection_visible_line(tree);
+
+	x += width;
+	y += top - 1;
+
+	gnt_widget_set_position(context, x, y);
+	gnt_screen_menu_show(GNT_MENU(context));
+	g_free(title);
+}
+
+static void
+tooltip_for_buddy(GaimBuddy *buddy, GString *str)
+{
+	GaimPlugin *prpl;
+	GaimPluginProtocolInfo *prpl_info;
+	GaimAccount *account;
+	GaimNotifyUserInfo *user_info;
+	const char *alias = gaim_buddy_get_alias(buddy);
+	char *tmp, *strip;
+
+	user_info = gaim_notify_user_info_new();
+
+	account = gaim_buddy_get_account(buddy);
+
+	if (g_utf8_collate(gaim_buddy_get_name(buddy), alias))
+		gaim_notify_user_info_add_pair(user_info, _("Nickname"), alias);
+
+	tmp = g_strdup_printf("%s (%s)",
+			gaim_account_get_username(account),
+			gaim_account_get_protocol_name(account));
+	gaim_notify_user_info_add_pair(user_info, _("Account"), tmp);
+	g_free(tmp);
+	
+	prpl = gaim_find_prpl(gaim_account_get_protocol_id(account));
+	prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
+	if (prpl_info && prpl_info->tooltip_text) {
+		prpl_info->tooltip_text(buddy, user_info, TRUE);
+	}
+
+	if (gaim_prefs_get_bool("/gaim/gnt/blist/idletime")) {
+		GaimPresence *pre = gaim_buddy_get_presence(buddy);
+		if (gaim_presence_is_idle(pre)) {
+			time_t idle = gaim_presence_get_idle_time(pre);
+			if (idle > 0) {
+				char *st = gaim_str_seconds_to_string(time(NULL) - idle);
+				gaim_notify_user_info_add_pair(user_info, _("Idle"), st);
+				g_free(st);
+			}
+		}
+	}
+	
+	tmp = gaim_notify_user_info_get_text_with_newline(user_info, "<BR>");
+	gaim_notify_user_info_destroy(user_info);
+
+	strip = gaim_markup_strip_html(tmp);
+	g_string_append(str, strip);
+	g_free(strip);
+	g_free(tmp);
+}
+
+static GString*
+make_sure_text_fits(GString *string)
+{
+	int maxw = getmaxx(stdscr) - 3;
+	char *str = gnt_util_onscreen_fit_string(string->str, maxw);
+	string = g_string_assign(string, str);
+	g_free(str);
+	return string;
+}
+
+static gboolean
+draw_tooltip_real(GGBlist *ggblist)
+{
+	GaimBlistNode *node;
+	int x, y, top, width, w, h;
+	GString *str;
+	GntTree *tree;
+	GntWidget *widget, *box, *tv;
+	char *title = NULL;
+	int lastseen = 0;
+
+	widget = ggblist->tree;
+	tree = GNT_TREE(widget);
+
+	if (!gnt_widget_has_focus(ggblist->tree) || 
+			(ggblist->context && !GNT_WIDGET_IS_FLAG_SET(ggblist->context, GNT_WIDGET_INVISIBLE)))
+		return FALSE;
+
+	if (ggblist->tooltip)
+	{
+		/* XXX: Once we can properly redraw on expose events, this can be removed at the end
+		 * to avoid the blinking*/
+		remove_tooltip(ggblist);
+	}
+
+	node = gnt_tree_get_selection_data(tree);
+	if (!node)
+		return FALSE;
+
+	str = g_string_new("");
+
+	if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
+		GaimBuddy *pr = gaim_contact_get_priority_buddy((GaimContact*)node);
+		gboolean offline = !GAIM_BUDDY_IS_ONLINE(pr);
+		gboolean showoffline = gaim_prefs_get_bool(PREF_ROOT "/showoffline");
+		const char *name = gaim_buddy_get_name(pr);
+
+		title = g_strdup(name);
+		tooltip_for_buddy(pr, str);
+		for (node = node->child; node; node = node->next) {
+			GaimBuddy *buddy = (GaimBuddy*)node;
+			if (offline) {
+				int value = gaim_blist_node_get_int(node, "last_seen");
+				if (value > lastseen)
+					lastseen = value;
+			}
+			if (node == (GaimBlistNode*)pr)
+				continue;
+			if (!gaim_account_is_connected(buddy->account))
+				continue;
+			if (!showoffline && !GAIM_BUDDY_IS_ONLINE(buddy))
+				continue;
+			str = g_string_append(str, "\n----------\n");
+			tooltip_for_buddy(buddy, str);
+		}
+	} else if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
+		GaimBuddy *buddy = (GaimBuddy *)node;
+		tooltip_for_buddy(buddy, str);
+		title = g_strdup(gaim_buddy_get_name(buddy));
+		if (!GAIM_BUDDY_IS_ONLINE((GaimBuddy*)node))
+			lastseen = gaim_blist_node_get_int(node, "last_seen");
+	} else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
+		GaimGroup *group = (GaimGroup *)node;
+
+		g_string_append_printf(str, _("Online: %d\nTotal: %d"),
+						gaim_blist_get_group_online_count(group),
+						gaim_blist_get_group_size(group, FALSE));
+
+		title = g_strdup(group->name);
+	} else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
+		GaimChat *chat = (GaimChat *)node;
+		GaimAccount *account = chat->account;
+
+		g_string_append_printf(str, _("Account: %s (%s)"),
+				gaim_account_get_username(account),
+				gaim_account_get_protocol_name(account));
+
+		title = g_strdup(gaim_chat_get_name(chat));
+	} else {
+		g_string_free(str, TRUE);
+		return FALSE;
+	}
+
+	if (lastseen > 0) {
+		char *tmp = gaim_str_seconds_to_string(time(NULL) - lastseen);
+		g_string_append_printf(str, _("\nLast Seen: %s ago"), tmp);
+		g_free(tmp);
+	}
+
+	gnt_widget_get_position(widget, &x, &y);
+	gnt_widget_get_size(widget, &width, NULL);
+	top = gnt_tree_get_selection_visible_line(tree);
+
+	x += width;
+	y += top - 1;
+
+	box = gnt_box_new(FALSE, FALSE);
+	gnt_box_set_toplevel(GNT_BOX(box), TRUE);
+	GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW);
+	gnt_box_set_title(GNT_BOX(box), title);
+
+	str = make_sure_text_fits(str);
+	gnt_util_get_text_bound(str->str, &w, &h);
+	h = MAX(2, h);
+	tv = gnt_text_view_new();
+	gnt_widget_set_size(tv, w + 1, h);
+	gnt_box_add_widget(GNT_BOX(box), tv);
+
+	gnt_widget_set_position(box, x, y);
+	GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_CAN_TAKE_FOCUS);
+	GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT);
+	gnt_widget_draw(box);
+
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(tv), str->str, GNT_TEXT_FLAG_NORMAL);
+	gnt_text_view_scroll(GNT_TEXT_VIEW(tv), 0);
+
+	g_free(title);
+	g_string_free(str, TRUE);
+	ggblist->tooltip = box;
+	ggblist->tnode = node;
+
+	gnt_widget_set_name(ggblist->tooltip, "tooltip");
+	return FALSE;
+}
+
+static void
+draw_tooltip(GGBlist *ggblist)
+{
+	/* When an account has signed off, it removes one buddy at a time.
+	 * Drawing the tooltip after removing each buddy is expensive. On
+	 * top of that, if the selected buddy belongs to the disconnected
+	 * account, then retreiving the tooltip for that causes crash. So
+	 * let's make sure we wait for all the buddies to be removed first.*/
+	int id = g_timeout_add(0, (GSourceFunc)draw_tooltip_real, ggblist);
+	g_object_set_data_full(G_OBJECT(ggblist->window), "draw_tooltip_calback",
+				GINT_TO_POINTER(id), (GDestroyNotify)g_source_remove);
+}
+
+static void
+selection_changed(GntWidget *widget, gpointer old, gpointer current, GGBlist *ggblist)
+{
+	draw_tooltip(ggblist);
+}
+
+static gboolean
+context_menu(GntWidget *widget, GGBlist *ggblist)
+{
+	draw_context_menu(ggblist);
+	return TRUE;
+}
+
+static gboolean
+key_pressed(GntWidget *widget, const char *text, GGBlist *ggblist)
+{
+	if (text[0] == 27 && text[1] == 0) {
+		/* Escape was pressed */
+		remove_peripherals(ggblist);
+	} else if (strcmp(text, GNT_KEY_CTRL_O) == 0) {
+		gaim_prefs_set_bool(PREF_ROOT "/showoffline",
+				!gaim_prefs_get_bool(PREF_ROOT "/showoffline"));
+	} else if (GNT_TREE(ggblist->tree)->search == NULL) {
+		if (strcmp(text, "t") == 0) {
+			gg_blist_toggle_tag_buddy(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree)));
+			gnt_bindable_perform_action_named(GNT_BINDABLE(ggblist->tree), "move-down");
+		} else if (strcmp(text, "a") == 0) {
+			gg_blist_place_tagged(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree)));
+		} else
+			return FALSE;
+	} else
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+update_buddy_display(GaimBuddy *buddy, GGBlist *ggblist)
+{
+	GaimContact *contact;
+	GntTextFormatFlags bflag = 0, cflag = 0;
+	
+	contact = gaim_buddy_get_contact(buddy);
+
+	gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, 0, get_display_name((GaimBlistNode*)buddy));
+	gnt_tree_change_text(GNT_TREE(ggblist->tree), contact, 0, get_display_name((GaimBlistNode*)contact));
+
+	if (ggblist->tagged && g_list_find(ggblist->tagged, buddy))
+		bflag |= GNT_TEXT_FLAG_BOLD;
+	if (ggblist->tagged && g_list_find(ggblist->tagged, contact))
+		cflag |= GNT_TEXT_FLAG_BOLD;
+
+	if (ggblist->tnode == (GaimBlistNode*)buddy)
+		draw_tooltip(ggblist);
+
+	if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) {
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag | GNT_TEXT_FLAG_DIM);
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag | GNT_TEXT_FLAG_DIM);
+	} else {
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag);
+		gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag);
+	}
+}
+
+static void
+buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist)
+{
+	update_buddy_display(buddy, ggblist);
+}
+
+static void
+buddy_idle_changed(GaimBuddy *buddy, int old, int new, GGBlist *ggblist)
+{
+	update_buddy_display(buddy, ggblist);
+}
+
+static void
+remove_peripherals(GGBlist *ggblist)
+{
+	if (ggblist->tooltip)
+		remove_tooltip(ggblist);
+	else if (ggblist->context)
+		gnt_widget_destroy(ggblist->context);
+}
+
+static void
+size_changed_cb(GntWidget *w, int wi, int h)
+{
+	int width, height;
+	gnt_widget_get_size(w, &width, &height);
+	gaim_prefs_set_int(PREF_ROOT "/size/width", width);
+	gaim_prefs_set_int(PREF_ROOT "/size/height", height);
+}
+
+static void
+save_position_cb(GntWidget *w, int x, int y)
+{
+	gaim_prefs_set_int(PREF_ROOT "/position/x", x);
+	gaim_prefs_set_int(PREF_ROOT "/position/y", y);
+}
+
+static void
+reset_blist_window(GntWidget *window, gpointer null)
+{
+	GaimBlistNode *node;
+	gaim_signals_disconnect_by_handle(gg_blist_get_handle());
+	gaim_get_blist()->ui_data = NULL;
+
+	node = gaim_blist_get_root();
+	while (node) {
+		node->ui_data = NULL;
+		node = gaim_blist_node_next(node, TRUE);
+	}
+
+	if (ggblist->typing)
+		g_source_remove(ggblist->typing);
+	remove_peripherals(ggblist);
+	if (ggblist->tagged)
+		g_list_free(ggblist->tagged);
+	g_free(ggblist);
+	ggblist = NULL;
+}
+
+static void
+populate_buddylist()
+{
+	GaimBlistNode *node;
+	GaimBuddyList *list;
+
+	if (strcmp(gaim_prefs_get_string(PREF_ROOT "/sort_type"), "text") == 0) {
+		gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
+			(GCompareFunc)blist_node_compare_text);
+	} else if (strcmp(gaim_prefs_get_string(PREF_ROOT "/sort_type"), "status") == 0) {
+		gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
+			(GCompareFunc)blist_node_compare_status);
+	} else if (strcmp(gaim_prefs_get_string(PREF_ROOT "/sort_type"), "log") == 0) {
+		gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
+			(GCompareFunc)blist_node_compare_log);
+	}
+	
+	list = gaim_get_blist();
+	node = gaim_blist_get_root();
+	while (node)
+	{
+		node_update(list, node);
+		node = gaim_blist_node_next(node, FALSE);
+	}
+}
+
+static void
+destroy_status_list(GList *list)
+{
+	g_list_foreach(list, (GFunc)g_free, NULL);
+	g_list_free(list);
+}
+
+static void
+populate_status_dropdown()
+{
+	int i;
+	GList *iter;
+	GList *items = NULL;
+	StatusBoxItem *item = NULL;
+
+	/* First the primitives */
+	GaimStatusPrimitive prims[] = {GAIM_STATUS_AVAILABLE, GAIM_STATUS_AWAY,
+			GAIM_STATUS_INVISIBLE, GAIM_STATUS_OFFLINE, GAIM_STATUS_UNSET};
+
+	gnt_combo_box_remove_all(GNT_COMBO_BOX(ggblist->status));
+
+	for (i = 0; prims[i] != GAIM_STATUS_UNSET; i++)
+	{
+		item = g_new0(StatusBoxItem, 1);
+		item->type = STATUS_PRIMITIVE;
+		item->u.prim = prims[i];
+		items = g_list_prepend(items, item);
+		gnt_combo_box_add_data(GNT_COMBO_BOX(ggblist->status), item,
+				gaim_primitive_get_name_from_type(prims[i]));
+	}
+
+	/* Now the popular statuses */
+	for (iter = gaim_savedstatuses_get_popular(6); iter; iter = iter->next)
+	{
+		item = g_new0(StatusBoxItem, 1);
+		item->type = STATUS_SAVED_POPULAR;
+		item->u.saved = iter->data;
+		items = g_list_prepend(items, item);
+		gnt_combo_box_add_data(GNT_COMBO_BOX(ggblist->status), item,
+				gaim_savedstatus_get_title(iter->data));
+	}
+
+	/* New savedstatus */
+	item = g_new0(StatusBoxItem, 1);
+	item->type = STATUS_SAVED_NEW;
+	items = g_list_prepend(items, item);
+	gnt_combo_box_add_data(GNT_COMBO_BOX(ggblist->status), item,
+			_("New..."));
+
+	/* More savedstatuses */
+	item = g_new0(StatusBoxItem, 1);
+	item->type = STATUS_SAVED_ALL;
+	items = g_list_prepend(items, item);
+	gnt_combo_box_add_data(GNT_COMBO_BOX(ggblist->status), item,
+			_("Saved..."));
+
+	/* The keys for the combobox are created here, and never used
+	 * anywhere else. So make sure the keys are freed when the widget
+	 * is destroyed. */
+	g_object_set_data_full(G_OBJECT(ggblist->status), "list of statuses",
+			items, (GDestroyNotify)destroy_status_list);
+}
+
+static void
+redraw_blist(const char *name, GaimPrefType type, gconstpointer val, gpointer data)
+{
+	GaimBlistNode *node, *sel;
+	if (ggblist == NULL || ggblist->window == NULL)
+		return;
+
+	sel = gnt_tree_get_selection_data(GNT_TREE(ggblist->tree));
+	gnt_tree_remove_all(GNT_TREE(ggblist->tree));
+	node = gaim_blist_get_root();
+	for (; node; node = gaim_blist_node_next(node, TRUE))
+		node->ui_data = NULL;
+	populate_buddylist();
+	gnt_tree_set_selected(GNT_TREE(ggblist->tree), sel);
+	draw_tooltip(ggblist);
+}
+
+void gg_blist_init()
+{
+	gaim_prefs_add_none(PREF_ROOT);
+	gaim_prefs_add_none(PREF_ROOT "/size");
+	gaim_prefs_add_int(PREF_ROOT "/size/width", 20);
+	gaim_prefs_add_int(PREF_ROOT "/size/height", 17);
+	gaim_prefs_add_none(PREF_ROOT "/position");
+	gaim_prefs_add_int(PREF_ROOT "/position/x", 0);
+	gaim_prefs_add_int(PREF_ROOT "/position/y", 0);
+	gaim_prefs_add_bool(PREF_ROOT "/idletime", TRUE);
+	gaim_prefs_add_bool(PREF_ROOT "/showoffline", FALSE);
+	gaim_prefs_add_string(PREF_ROOT "/sort_type", "text");
+
+	gaim_prefs_connect_callback(gg_blist_get_handle(),
+			PREF_ROOT "/showoffline", redraw_blist, NULL);
+	gaim_prefs_connect_callback(gg_blist_get_handle(),
+			PREF_ROOT "/sort_type", redraw_blist, NULL);
+
+	gaim_signal_connect(gaim_connections_get_handle(), "signed-on", gaim_blist_get_handle(),
+			G_CALLBACK(account_signed_on_cb), NULL);
+	return;
+}
+
+static gboolean
+remove_typing_cb(gpointer null)
+{
+	GaimSavedStatus *current;
+	const char *message, *newmessage;
+	GaimStatusPrimitive prim, newprim;
+	StatusBoxItem *item;
+
+	current = gaim_savedstatus_get_current();
+	message = gaim_savedstatus_get_message(current);
+	prim = gaim_savedstatus_get_type(current);
+
+	newmessage = gnt_entry_get_text(GNT_ENTRY(ggblist->statustext));
+	item = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(ggblist->status));
+	g_return_val_if_fail(item->type == STATUS_PRIMITIVE, FALSE);
+	newprim = item->u.prim;
+
+	if (newprim != prim || ((message && !newmessage) ||
+				(!message && newmessage) ||
+				(message && newmessage && g_utf8_collate(message, newmessage) != 0)))
+	{
+		GaimSavedStatus *status = gaim_savedstatus_find_transient_by_type_and_message(newprim, newmessage);
+									/* Holy Crap! That's a LAWNG function name */
+		if (status == NULL)
+		{
+			status = gaim_savedstatus_new(NULL, newprim);
+			gaim_savedstatus_set_message(status, newmessage);
+		}
+
+		gaim_savedstatus_activate(status);
+	}
+
+	gnt_box_give_focus_to_child(GNT_BOX(ggblist->window), ggblist->tree);
+	if (ggblist->typing)
+		g_source_remove(ggblist->typing);
+	ggblist->typing = 0;
+	return FALSE;
+}
+
+static void
+status_selection_changed(GntComboBox *box, StatusBoxItem *old, StatusBoxItem *now, gpointer null)
+{
+	gnt_entry_set_text(GNT_ENTRY(ggblist->statustext), NULL);
+	if (now->type == STATUS_SAVED_POPULAR)
+	{
+		/* Set the status immediately */
+		gaim_savedstatus_activate(now->u.saved);
+	}
+	else if (now->type == STATUS_PRIMITIVE)
+	{
+		/* Move the focus to the entry box */
+		/* XXX: Make sure the selected status can have a message */
+		gnt_box_move_focus(GNT_BOX(ggblist->window), 1);
+		ggblist->typing = g_timeout_add(TYPING_TIMEOUT, (GSourceFunc)remove_typing_cb, NULL);
+	}
+	else if (now->type == STATUS_SAVED_ALL)
+	{
+		/* Restore the selection to reflect current status. */
+		savedstatus_changed(gaim_savedstatus_get_current(), NULL);
+		gnt_box_give_focus_to_child(GNT_BOX(ggblist->window), ggblist->tree);
+		gg_savedstatus_show_all();
+	}
+	else if (now->type == STATUS_SAVED_NEW)
+	{
+		savedstatus_changed(gaim_savedstatus_get_current(), NULL);
+		gnt_box_give_focus_to_child(GNT_BOX(ggblist->window), ggblist->tree);
+		gg_savedstatus_edit(NULL);
+	}
+	else
+		g_return_if_reached();
+}
+
+static gboolean
+status_text_changed(GntEntry *entry, const char *text, gpointer null)
+{
+	if ((text[0] == 27 || (text[0] == '\t' && text[1] == '\0')) && ggblist->typing == 0)
+		return FALSE;
+
+	if (ggblist->typing)
+		g_source_remove(ggblist->typing);
+	ggblist->typing = 0;
+
+	if (text[0] == '\r' && text[1] == 0)
+	{
+		/* Set the status only after you press 'Enter' */
+		remove_typing_cb(NULL);
+		return TRUE;
+	}
+
+	ggblist->typing = g_timeout_add(TYPING_TIMEOUT, (GSourceFunc)remove_typing_cb, NULL);
+	return FALSE;
+}
+
+static void
+savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old)
+{
+	GList *list;
+	GaimStatusPrimitive prim;
+	const char *message;
+
+	if (!ggblist)
+		return;
+
+	/* Block the signals we don't want to emit */
+	g_signal_handlers_block_matched(ggblist->status, G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL, status_selection_changed, NULL);
+	g_signal_handlers_block_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL, status_text_changed, NULL);
+
+	prim = gaim_savedstatus_get_type(now);
+	message = gaim_savedstatus_get_message(now);
+
+	/* Rebuild the status dropdown */
+	populate_status_dropdown();
+
+	list = g_object_get_data(G_OBJECT(ggblist->status), "list of statuses");
+	for (; list; list = list->next)
+	{
+		StatusBoxItem *item = list->data;
+		if (item->type == STATUS_PRIMITIVE && item->u.prim == prim)
+		{
+			char *mess = gaim_unescape_html(message);
+			gnt_combo_box_set_selected(GNT_COMBO_BOX(ggblist->status), item);
+			gnt_entry_set_text(GNT_ENTRY(ggblist->statustext), mess);
+			gnt_widget_draw(ggblist->status);
+			g_free(mess);
+			break;
+		}
+	}
+
+	g_signal_handlers_unblock_matched(ggblist->status, G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL, status_selection_changed, NULL);
+	g_signal_handlers_unblock_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL, status_text_changed, NULL);
+}
+
+static int
+blist_node_compare_text(GaimBlistNode *n1, GaimBlistNode *n2)
+{
+	const char *s1, *s2;
+	char *us1, *us2;
+	int ret;
+	
+	g_return_val_if_fail(n1->type == n2->type, -1);
+	
+	switch (n1->type)
+	{
+		case GAIM_BLIST_GROUP_NODE:
+			s1 = ((GaimGroup*)n1)->name;
+			s2 = ((GaimGroup*)n2)->name;
+			break;
+		case GAIM_BLIST_CHAT_NODE:
+			s1 = gaim_chat_get_name((GaimChat*)n1);
+			s2 = gaim_chat_get_name((GaimChat*)n2);
+			break;
+		case GAIM_BLIST_BUDDY_NODE:
+			return gaim_presence_compare(gaim_buddy_get_presence((GaimBuddy*)n1),
+					gaim_buddy_get_presence((GaimBuddy*)n2));
+			break;
+		case GAIM_BLIST_CONTACT_NODE:
+			s1 = gaim_contact_get_alias((GaimContact*)n1);
+			s2 = gaim_contact_get_alias((GaimContact*)n2);
+			break;
+		default:
+			return -1;
+	}
+
+	us1 = g_utf8_strup(s1, -1);
+	us2 = g_utf8_strup(s2, -1);
+	ret = g_utf8_collate(us1, us2);
+	g_free(us1);
+	g_free(us2);
+
+	return ret;
+}
+
+static int
+blist_node_compare_status(GaimBlistNode *n1, GaimBlistNode *n2)
+{
+	int ret;
+
+	g_return_val_if_fail(n1->type == n2->type, -1);
+
+	switch (n1->type) {
+		case GAIM_BLIST_CONTACT_NODE:
+			n1 = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)n1);
+			n2 = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)n2);
+			/* now compare the presence of the priority buddies */
+		case GAIM_BLIST_BUDDY_NODE:
+			ret = gaim_presence_compare(gaim_buddy_get_presence((GaimBuddy*)n1),
+					gaim_buddy_get_presence((GaimBuddy*)n2));
+			if (ret != 0)
+				return ret;
+			break;
+		default:
+			break;
+	}
+
+	/* Sort alphabetically if presence is not comparable */
+	ret = blist_node_compare_text(n1, n2);
+
+	return ret;
+}
+
+static int
+get_contact_log_size(GaimBlistNode *c)
+{
+	int log = 0;
+	GaimBlistNode *node;
+
+	for (node = c->child; node; node = node->next) {
+		GaimBuddy *b = (GaimBuddy*)node;
+		log += gaim_log_get_total_size(GAIM_LOG_IM, b->name, b->account);
+	}
+
+	return log;
+}
+
+static int
+blist_node_compare_log(GaimBlistNode *n1, GaimBlistNode *n2)
+{
+	int ret;
+	GaimBuddy *b1, *b2;
+
+	g_return_val_if_fail(n1->type == n2->type, -1);
+
+	switch (n1->type) {
+		case GAIM_BLIST_BUDDY_NODE:
+			b1 = (GaimBuddy*)n1;
+			b2 = (GaimBuddy*)n2;
+			ret = gaim_log_get_total_size(GAIM_LOG_IM, b2->name, b2->account) - 
+					gaim_log_get_total_size(GAIM_LOG_IM, b1->name, b1->account);
+			if (ret != 0)
+				return ret;
+			break;
+		case GAIM_BLIST_CONTACT_NODE:
+			ret = get_contact_log_size(n2) - get_contact_log_size(n1);
+			if (ret != 0)
+				return ret;
+			break;
+		default:
+			break;
+	}
+	ret = blist_node_compare_text(n1, n2);
+	return ret;
+}
+
+static gboolean
+blist_clicked(GntTree *tree, GntMouseEvent event, int x, int y, gpointer ggblist)
+{
+	if (event == GNT_RIGHT_MOUSE_DOWN) {
+		draw_context_menu(ggblist);
+	}
+	return FALSE;
+}
+
+static void
+plugin_action(GntMenuItem *item, gpointer data)
+{
+	GaimPluginAction *action = data;
+	if (action && action->callback)
+		action->callback(action);
+}
+
+static void
+build_plugin_actions(GntMenuItem *item, GaimPlugin *plugin, gpointer context)
+{
+	GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
+	GList *actions;
+	GntMenuItem *menuitem;
+
+	gnt_menuitem_set_submenu(item, GNT_MENU(sub));
+	for (actions = GAIM_PLUGIN_ACTIONS(plugin, context); actions;
+			actions = g_list_delete_link(actions, actions)) {
+		if (actions->data) {
+			GaimPluginAction *action = actions->data;
+			action->plugin = plugin;
+			action->context = context;
+			menuitem = gnt_menuitem_new(action->label);
+			gnt_menu_add_item(GNT_MENU(sub), menuitem);
+
+			gnt_menuitem_set_callback(menuitem, plugin_action, action);
+			g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
+								   action, (GDestroyNotify)gaim_plugin_action_free);
+		}
+	}
+}
+
+static void
+reconstruct_plugins_menu()
+{
+	GntWidget *sub;
+	GntMenuItem *plg;
+	GList *iter;
+
+	if (!ggblist)
+		return;
+
+	if (ggblist->plugins == NULL)
+		ggblist->plugins = gnt_menuitem_new(_("Plugins"));
+
+	plg = ggblist->plugins;
+	sub = gnt_menu_new(GNT_MENU_POPUP);
+	gnt_menuitem_set_submenu(plg, GNT_MENU(sub));
+
+	for (iter = gaim_plugins_get_loaded(); iter; iter = iter->next) {
+		GaimPlugin *plugin = iter->data;
+		GntMenuItem *item;
+		if (GAIM_IS_PROTOCOL_PLUGIN(plugin))
+			continue;
+
+		if (!GAIM_PLUGIN_HAS_ACTIONS(plugin))
+			continue;
+
+		item = gnt_menuitem_new(_(plugin->info->name));
+		gnt_menu_add_item(GNT_MENU(sub), item);
+		build_plugin_actions(item, plugin, NULL);
+	}
+}
+
+static void
+reconstruct_accounts_menu()
+{
+	GntWidget *sub;
+	GntMenuItem *acc, *item;
+	GList *iter;
+
+	if (!ggblist)
+		return;
+
+	if (ggblist->accounts == NULL)
+		ggblist->accounts = gnt_menuitem_new(_("Accounts"));
+
+	acc = ggblist->accounts;
+	sub = gnt_menu_new(GNT_MENU_POPUP);
+	gnt_menuitem_set_submenu(acc, GNT_MENU(sub));
+
+	for (iter = gaim_accounts_get_all_active(); iter;
+			iter = g_list_delete_link(iter, iter)) {
+		GaimAccount *account = iter->data;
+		GaimConnection *gc = gaim_account_get_connection(account);
+		GaimPlugin *prpl;
+		
+		if (!gc || !GAIM_CONNECTION_IS_CONNECTED(gc))
+			continue;
+		prpl = gc->prpl;
+
+		if (GAIM_PLUGIN_HAS_ACTIONS(prpl)) {
+			item = gnt_menuitem_new(gaim_account_get_username(account));
+			gnt_menu_add_item(GNT_MENU(sub), item);
+			build_plugin_actions(item, prpl, gc);
+		}
+	}
+}
+
+static void
+account_signed_on_cb()
+{
+	GaimBlistNode *node;
+
+	for (node = gaim_blist_get_root(); node;
+			node = gaim_blist_node_next(node, FALSE)) {
+		if (GAIM_BLIST_NODE_IS_CHAT(node)) {
+			GaimChat *chat = (GaimChat*)node;
+			if (gaim_blist_node_get_bool(node, "gnt-autojoin"))
+				serv_join_chat(gaim_account_get_connection(chat->account), chat->components);
+		}
+	}
+}
+
+static void show_offline_cb(GntMenuItem *item, gpointer n)
+{
+	gaim_prefs_set_bool(PREF_ROOT "/showoffline",
+		!gaim_prefs_get_bool(PREF_ROOT "/showoffline"));
+}
+
+static void sort_blist_change_cb(GntMenuItem *item, gpointer n)
+{
+	gaim_prefs_set_string(PREF_ROOT "/sort_type", n);
+}
+
+/* XXX: send_im_select* -- Xerox */
+static void
+send_im_select_cb(gpointer data, GaimRequestFields *fields)
+{
+	GaimAccount *account;
+	const char *username;
+
+	account  = gaim_request_fields_get_account(fields, "account");
+	username = gaim_request_fields_get_string(fields,  "screenname");
+
+	gaim_conversation_new(GAIM_CONV_TYPE_IM, account, username);
+}
+
+static void
+send_im_select(GntMenuItem *item, gpointer n)
+{
+	GaimRequestFields *fields;
+	GaimRequestFieldGroup *group;
+	GaimRequestField *field;
+
+	fields = gaim_request_fields_new();
+
+	group = gaim_request_field_group_new(NULL);
+	gaim_request_fields_add_group(fields, group);
+
+	field = gaim_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
+	gaim_request_field_set_type_hint(field, "screenname");
+	gaim_request_field_set_required(field, TRUE);
+	gaim_request_field_group_add_field(group, field);
+
+	field = gaim_request_field_account_new("account", _("_Account"), NULL);
+	gaim_request_field_set_type_hint(field, "account");
+	gaim_request_field_set_visible(field,
+		(gaim_connections_get_all() != NULL &&
+		 gaim_connections_get_all()->next != NULL));
+	gaim_request_field_set_required(field, TRUE);
+	gaim_request_field_group_add_field(group, field);
+
+	gaim_request_fields(gaim_get_blist(), _("New Instant Message"),
+						NULL,
+						_("Please enter the screen name or alias of the person "
+						  "you would like to IM."),
+						fields,
+						_("OK"), G_CALLBACK(send_im_select_cb),
+						_("Cancel"), NULL,
+						NULL);
+}
+
+static void
+create_menu()
+{
+	GntWidget *menu, *sub;
+	GntMenuItem *item;
+	GntWindow *window;
+
+	if (!ggblist)
+		return;
+
+	window = GNT_WINDOW(ggblist->window);
+	ggblist->menu = menu = gnt_menu_new(GNT_MENU_TOPLEVEL);
+	gnt_window_set_menu(window, GNT_MENU(menu));
+
+	item = gnt_menuitem_new(_("Options"));
+	gnt_menu_add_item(GNT_MENU(menu), item);
+
+	sub = gnt_menu_new(GNT_MENU_POPUP);
+	gnt_menuitem_set_submenu(item, GNT_MENU(sub));
+
+	item = gnt_menuitem_new(_("Send IM..."));
+	gnt_menu_add_item(GNT_MENU(sub), item);
+	gnt_menuitem_set_callback(GNT_MENUITEM(item), send_im_select, NULL);
+
+	item = gnt_menuitem_new(_("Toggle offline buddies"));
+	gnt_menu_add_item(GNT_MENU(sub), item);
+	gnt_menuitem_set_callback(GNT_MENUITEM(item), show_offline_cb, NULL);
+
+	item = gnt_menuitem_new(_("Sort by status"));
+	gnt_menu_add_item(GNT_MENU(sub), item);
+	gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "status");
+
+	item = gnt_menuitem_new(_("Sort alphabetically"));
+	gnt_menu_add_item(GNT_MENU(sub), item);
+	gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "text");
+
+	item = gnt_menuitem_new(_("Sort by log size"));
+	gnt_menu_add_item(GNT_MENU(sub), item);
+	gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "log");
+
+	reconstruct_accounts_menu();
+	gnt_menu_add_item(GNT_MENU(menu), ggblist->accounts);
+
+	reconstruct_plugins_menu();
+	gnt_menu_add_item(GNT_MENU(menu), ggblist->plugins);
+}
+
+void gg_blist_show()
+{
+	blist_show(gaim_get_blist());
+}
+
+static void
+blist_show(GaimBuddyList *list)
+{
+	if (ggblist == NULL)
+		new_list(list);
+	else if (ggblist->window)
+		return;
+
+	ggblist->window = gnt_vwindow_new(FALSE);
+	gnt_widget_set_name(ggblist->window, "buddylist");
+	gnt_box_set_toplevel(GNT_BOX(ggblist->window), TRUE);
+	gnt_box_set_title(GNT_BOX(ggblist->window), _("Buddy List"));
+	gnt_box_set_pad(GNT_BOX(ggblist->window), 0);
+
+	ggblist->tree = gnt_tree_new();
+
+	GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER);
+	gnt_widget_set_size(ggblist->tree, gaim_prefs_get_int(PREF_ROOT "/size/width"),
+			gaim_prefs_get_int(PREF_ROOT "/size/height"));
+	gnt_widget_set_position(ggblist->window, gaim_prefs_get_int(PREF_ROOT "/position/x"),
+			gaim_prefs_get_int(PREF_ROOT "/position/y"));
+
+	gnt_tree_set_col_width(GNT_TREE(ggblist->tree), 0,
+			gaim_prefs_get_int(PREF_ROOT "/size/width") - 1);
+
+	gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->tree);
+
+	ggblist->status = gnt_combo_box_new();
+	gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->status);
+	ggblist->statustext = gnt_entry_new(NULL);
+	gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->statustext);
+
+	gnt_widget_show(ggblist->window);
+
+	gaim_signal_connect(gaim_connections_get_handle(), "signed-on", gg_blist_get_handle(),
+				GAIM_CALLBACK(reconstruct_accounts_menu), NULL);
+	gaim_signal_connect(gaim_connections_get_handle(), "signed-off", gg_blist_get_handle(),
+				GAIM_CALLBACK(reconstruct_accounts_menu), NULL);
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(),
+				GAIM_CALLBACK(buddy_status_changed), ggblist);
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-idle-changed", gg_blist_get_handle(),
+				GAIM_CALLBACK(buddy_idle_changed), ggblist);
+
+	gaim_signal_connect(gaim_plugins_get_handle(), "plugin-load", gg_blist_get_handle(),
+				GAIM_CALLBACK(reconstruct_plugins_menu), NULL);
+	gaim_signal_connect(gaim_plugins_get_handle(), "plugin-unload", gg_blist_get_handle(),
+				GAIM_CALLBACK(reconstruct_plugins_menu), NULL);
+
+#if 0
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gg_blist_get_handle(),
+				GAIM_CALLBACK(buddy_signed_on), ggblist);
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", gg_blist_get_handle(),
+				GAIM_CALLBACK(buddy_signed_off), ggblist);
+
+	/* These I plan to use to indicate unread-messages etc. */
+	gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", gg_blist_get_handle(),
+				GAIM_CALLBACK(received_im_msg), list);
+	gaim_signal_connect(gaim_conversations_get_handle(), "sent-im-msg", gg_blist_get_handle(),
+				GAIM_CALLBACK(sent_im_msg), NULL);
+
+	gaim_signal_connect(gaim_conversations_get_handle(), "received-chat-msg", gg_blist_get_handle(),
+				GAIM_CALLBACK(received_chat_msg), list);
+#endif
+
+	g_signal_connect(G_OBJECT(ggblist->tree), "selection_changed", G_CALLBACK(selection_changed), ggblist);
+	g_signal_connect(G_OBJECT(ggblist->tree), "key_pressed", G_CALLBACK(key_pressed), ggblist);
+	g_signal_connect(G_OBJECT(ggblist->tree), "context-menu", G_CALLBACK(context_menu), ggblist);
+	g_signal_connect_after(G_OBJECT(ggblist->tree), "clicked", G_CALLBACK(blist_clicked), ggblist);
+	g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist);
+	g_signal_connect_data(G_OBJECT(ggblist->tree), "gained-focus", G_CALLBACK(draw_tooltip),
+				ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+	g_signal_connect_data(G_OBJECT(ggblist->tree), "lost-focus", G_CALLBACK(remove_peripherals),
+				ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+	g_signal_connect(G_OBJECT(ggblist->tree), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+	g_signal_connect(G_OBJECT(ggblist->window), "position_set", G_CALLBACK(save_position_cb), NULL);
+	g_signal_connect(G_OBJECT(ggblist->window), "destroy", G_CALLBACK(reset_blist_window), NULL);
+
+	/* Status signals */
+	gaim_signal_connect(gaim_savedstatuses_get_handle(), "savedstatus-changed", gg_blist_get_handle(),
+				GAIM_CALLBACK(savedstatus_changed), NULL);
+	g_signal_connect(G_OBJECT(ggblist->status), "selection_changed",
+				G_CALLBACK(status_selection_changed), NULL);
+	g_signal_connect(G_OBJECT(ggblist->statustext), "key_pressed",
+				G_CALLBACK(status_text_changed), NULL);
+
+	create_menu();
+
+	populate_buddylist();
+
+	savedstatus_changed(gaim_savedstatus_get_current(), NULL);
+}
+
+void gg_blist_uninit()
+{
+	if (ggblist == NULL)
+		return;
+
+	gnt_widget_destroy(ggblist->window);
+	g_free(ggblist);
+	ggblist = NULL;
+}
+
+gboolean gg_blist_get_position(int *x, int *y)
+{
+	if (!ggblist || !ggblist->window)
+		return FALSE;
+	gnt_widget_get_position(ggblist->window, x, y);
+	return TRUE;
+}
+
+void gg_blist_set_position(int x, int y)
+{
+	gnt_widget_set_position(ggblist->window, x, y);
+}
+
+gboolean gg_blist_get_size(int *width, int *height)
+{
+	if (!ggblist || !ggblist->window)
+		return FALSE;
+	gnt_widget_get_size(ggblist->window, width, height);
+	return TRUE;
+}
+
+void gg_blist_set_size(int width, int height)
+{
+	gnt_widget_set_size(ggblist->window, width, height);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntblist.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,95 @@
+/**
+ * @file gntblist.h GNT BuddyList API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_BLIST_H
+#define _GNT_BLIST_H
+
+#include "blist.h"
+
+/**********************************************************************
+ * @name GNT BuddyList API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimBlistUiOps structure populated with the appropriate functions.
+ */
+GaimBlistUiOps * gg_blist_get_ui_ops(void);
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_blist_init(void);
+
+/**
+ * Perform necessary uninitializations.
+ */
+void gg_blist_uninit(void);
+
+/**
+ * Show the buddy list.
+ */
+void gg_blist_show(void);
+
+/**
+ * Get the position of the buddy list.
+ *
+ * @param x The x-coordinate is set here if not @ NULL.
+ * @param y The y-coordinate is set here if not @c NULL.
+ *
+ * @return Returns @c TRUE if the values were set, @c FALSE otherwise.
+ */
+gboolean gg_blist_get_position(int *x, int *y);
+
+/**
+ * Set the position of the buddy list.
+ *
+ * @param x The x-coordinate of the buddy list.
+ * @param y The y-coordinate of the buddy list.
+ */
+void gg_blist_set_position(int x, int y);
+
+/**
+ * Get the size of the buddy list.
+ *
+ * @param width  The width is set here if not @ NULL.
+ * @param height The height is set here if not @c NULL.
+ *
+ * @return Returns @c TRUE if the values were set, @c FALSE otherwise.
+ */
+gboolean gg_blist_get_size(int *width, int *height);
+
+/**
+ * Set the size of the buddy list.
+ *
+ * @param width  The width of the buddy list.
+ * @param height The height of the buddy list.
+ */
+void gg_blist_set_size(int width, int height);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntconn.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,69 @@
+/**
+ * @file gntconn.c GNT Connection API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 "notify.h"
+
+#include "gntconn.h"
+#include "gntgaim.h"
+
+static void
+gg_connection_report_disconnect(GaimConnection *gc, const char *text)
+{
+	char *act, *primary, *secondary;
+	GaimAccount *account = gaim_connection_get_account(gc);
+
+	act = g_strdup_printf(_("%s (%s)"), gaim_account_get_username(account),
+			gaim_account_get_protocol_name(account));
+
+	primary = g_strdup_printf(_("%s disconnected."), act);
+	secondary = g_strdup_printf(_("%s was disconnected due to the following error:\n%s"),
+			act, text);
+
+	gaim_notify_error(account, _("Connection Error"), primary, secondary);
+
+	g_free(act);
+	g_free(primary);
+	g_free(secondary);
+}
+
+static GaimConnectionUiOps ops = 
+{
+	.connect_progress = NULL,
+	.connected = NULL,
+	.disconnected = NULL,
+	.notice = NULL,
+	.report_disconnect = gg_connection_report_disconnect
+};
+
+GaimConnectionUiOps *gg_connections_get_ui_ops()
+{
+	return &ops;
+}
+
+void gg_connections_init()
+{}
+
+void gg_connections_uninit()
+{}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntconn.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,54 @@
+/**
+ * @file gntconn.h GNT Connection API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_CONN_H
+#define _GNT_CONN_H
+
+#include "connection.h"
+
+/**********************************************************************
+ * @name GNT Connection API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimConnectionUiOps structure populated with the appropriate functions.
+ */
+GaimConnectionUiOps *gg_connections_get_ui_ops(void);
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_connections_init(void);
+
+/**
+ * Perform necessary uninitializations.
+ */
+void gg_connections_uninit(void);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntconv.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,756 @@
+/**
+ * @file gntconv.c GNT Conversation API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <string.h>
+
+#include <cmds.h>
+#include <prefs.h>
+#include <util.h>
+
+#include "gntgaim.h"
+#include "gntaccount.h"
+#include "gntblist.h"
+#include "gntconv.h"
+#include "gntdebug.h"
+#include "gntplugin.h"
+#include "gntprefs.h"
+#include "gntstatus.h"
+
+#include "gnt.h"
+#include "gntbox.h"
+#include "gntentry.h"
+#include "gnttextview.h"
+
+#define PREF_ROOT	"/gaim/gnt/conversations"
+
+#include "config.h"
+
+static void
+send_typing_notification(GntWidget *w, GGConv *ggconv)
+{
+	const char *text = gnt_entry_get_text(GNT_ENTRY(ggconv->entry));
+	gboolean empty = (!text || !*text);
+	if (gaim_prefs_get_bool("/gaim/gnt/conversations/notify_typing")) {
+		GaimConversation *conv = ggconv->active_conv;
+		GaimConvIm *im = GAIM_CONV_IM(conv);
+		if (!empty) {
+			gboolean send = (gaim_conv_im_get_send_typed_timeout(im) == 0);
+
+			gaim_conv_im_stop_send_typed_timeout(im);
+			gaim_conv_im_start_send_typed_timeout(im);
+			if (send || (gaim_conv_im_get_type_again(im) != 0 &&
+						  time(NULL) > gaim_conv_im_get_type_again(im))) {
+				unsigned int timeout;
+				timeout = serv_send_typing(gaim_conversation_get_gc(conv),
+										   gaim_conversation_get_name(conv),
+										   GAIM_TYPING);
+				gaim_conv_im_set_type_again(im, timeout);
+			}
+		} else {
+			gaim_conv_im_stop_send_typed_timeout(im);
+
+			serv_send_typing(gaim_conversation_get_gc(conv),
+							 gaim_conversation_get_name(conv),
+							 GAIM_NOT_TYPING);
+		}
+	}
+}
+
+static gboolean
+entry_key_pressed(GntWidget *w, const char *key, GGConv *ggconv)
+{
+	if (key[0] == '\r' && key[1] == 0)
+	{
+		const char *text = gnt_entry_get_text(GNT_ENTRY(ggconv->entry));
+		if (*text == '/')
+		{
+			GaimConversation *conv = ggconv->active_conv;
+			GaimCmdStatus status;
+			const char *cmdline = text + 1;
+			char *error = NULL, *escape;
+
+			escape = g_markup_escape_text(cmdline, -1);
+			status = gaim_cmd_do_command(conv, cmdline, escape, &error);
+			g_free(escape);
+
+			switch (status)
+			{
+				case GAIM_CMD_STATUS_OK:
+					break;
+				case GAIM_CMD_STATUS_NOT_FOUND:
+					gaim_conversation_write(conv, "", _("No such command."),
+							GAIM_MESSAGE_NO_LOG, time(NULL));
+					break;
+				case GAIM_CMD_STATUS_WRONG_ARGS:
+					gaim_conversation_write(conv, "", _("Syntax Error:  You typed the wrong number of arguments "
+										"to that command."),
+							GAIM_MESSAGE_NO_LOG, time(NULL));
+					break;
+				case GAIM_CMD_STATUS_FAILED:
+					gaim_conversation_write(conv, "", error ? error : _("Your command failed for an unknown reason."),
+							GAIM_MESSAGE_NO_LOG, time(NULL));
+					break;
+				case GAIM_CMD_STATUS_WRONG_TYPE:
+					if(gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM)
+						gaim_conversation_write(conv, "", _("That command only works in chats, not IMs."),
+								GAIM_MESSAGE_NO_LOG, time(NULL));
+					else
+						gaim_conversation_write(conv, "", _("That command only works in IMs, not chats."),
+								GAIM_MESSAGE_NO_LOG, time(NULL));
+					break;
+				case GAIM_CMD_STATUS_WRONG_PRPL:
+					gaim_conversation_write(conv, "", _("That command doesn't work on this protocol."),
+							GAIM_MESSAGE_NO_LOG, time(NULL));
+					break;
+			}
+			g_free(error);
+#if 0
+			gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv),
+					_("Commands are not supported yet. Message was NOT sent."),
+					GNT_TEXT_FLAG_DIM | GNT_TEXT_FLAG_UNDERLINE);
+			gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv));
+			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0);
+#endif
+		}
+		else
+		{
+			char *escape = g_markup_escape_text(text, -1);
+			char *apos = gaim_strreplace(escape, "&apos;", "'");
+			g_free(escape);
+			escape = apos;
+			switch (gaim_conversation_get_type(ggconv->active_conv))
+			{
+				case GAIM_CONV_TYPE_IM:
+					gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->active_conv), escape, GAIM_MESSAGE_SEND);
+					break;
+				case GAIM_CONV_TYPE_CHAT:
+					gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->active_conv), escape);
+					break;
+				default:
+					g_free(escape);
+					g_return_val_if_reached(FALSE);
+			}
+			g_free(escape);
+		}
+		gnt_entry_add_to_history(GNT_ENTRY(ggconv->entry), text);
+		gnt_entry_clear(GNT_ENTRY(ggconv->entry));
+		return TRUE;
+	}
+	else if (key[0] == 27)
+	{
+		if (strcmp(key, GNT_KEY_DOWN) == 0)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 1);
+		else if (strcmp(key, GNT_KEY_UP) == 0)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -1);
+		else if (strcmp(key, GNT_KEY_PGDOWN) == 0)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), ggconv->tv->priv.height - 2);
+		else if (strcmp(key, GNT_KEY_PGUP) == 0)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -(ggconv->tv->priv.height - 2));
+		else
+			return FALSE;
+		return TRUE;
+	}
+	else
+	{
+	}
+
+	return FALSE;
+}
+
+static void
+closing_window(GntWidget *window, GGConv *ggconv)
+{
+	GList *list = ggconv->list;
+	ggconv->window = NULL;
+	while (list) {
+		GaimConversation *conv = list->data;
+		list = list->next;
+		gaim_conversation_destroy(conv);
+	}
+}
+
+static void
+size_changed_cb(GntWidget *widget, int width, int height)
+{
+	int w, h;
+	gnt_widget_get_size(widget, &w, &h);
+	gaim_prefs_set_int(PREF_ROOT "/size/width", w);
+	gaim_prefs_set_int(PREF_ROOT "/size/height", h);
+}
+
+static void
+save_position_cb(GntWidget *w, int x, int y)
+{
+	gaim_prefs_set_int(PREF_ROOT "/position/x", x);
+	gaim_prefs_set_int(PREF_ROOT "/position/y", y);
+}
+
+static GaimConversation *
+find_conv_with_contact(GaimConversation *conv)
+{
+	GaimBlistNode *node;
+	GaimBuddy *buddy = gaim_find_buddy(conv->account, conv->name);
+	GaimConversation *ret = NULL;
+
+	if (!buddy)
+		return NULL;
+
+	for (node = ((GaimBlistNode*)buddy)->parent->child; node; node = node->next) {
+		if (node == (GaimBlistNode*)buddy)
+			continue;
+		if ((ret = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM,
+				((GaimBuddy*)node)->name, ((GaimBuddy*)node)->account)) != NULL)
+			break;
+	}
+	return ret;
+}
+
+static char *
+get_conversation_title(GaimConversation *conv, GaimAccount *account)
+{
+	return g_strdup_printf(_("%s (%s -- %s)"), gaim_conversation_get_title(conv),
+		gaim_account_get_username(account), gaim_account_get_protocol_name(account));
+}
+
+static void
+update_buddy_typing(GaimAccount *account, const char *who, gpointer null)
+{
+	GaimConversation *conv;
+	GGConv *ggc;
+	GaimConvIm *im = NULL;
+	char *title, *str;
+
+	conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, account);
+
+	if (!conv)
+		return;
+
+	im = GAIM_CONV_IM(conv);
+	ggc = conv->ui_data;
+
+	if (gaim_conv_im_get_typing_state(im) == GAIM_TYPING) {
+		int scroll;
+		str = get_conversation_title(conv, account);
+		title = g_strdup_printf(_("%s [%s]"), str,
+			gnt_ascii_only() ? "T" : "\342\243\277");
+		g_free(str);
+
+		scroll = gnt_text_view_get_lines_below(GNT_TEXT_VIEW(ggc->tv));
+		str = g_strdup_printf(_("\n%s is typing..."), gaim_conversation_get_name(conv));
+		/* Updating is a little buggy. So just remove and add a new one */
+		gnt_text_view_tag_change(GNT_TEXT_VIEW(ggc->tv), "typing", NULL, TRUE);
+		gnt_text_view_append_text_with_tag(GNT_TEXT_VIEW(ggc->tv),
+					str, GNT_TEXT_FLAG_DIM, "typing");
+		g_free(str);
+		if (scroll <= 1)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(ggc->tv), 0);
+ 	} else {
+		title = get_conversation_title(conv, account);
+		gnt_text_view_tag_change(GNT_TEXT_VIEW(ggc->tv), "typing", NULL, TRUE);
+	}
+	gnt_screen_rename_widget(ggc->window, title);
+	g_free(title);
+}
+
+static gpointer
+gg_conv_get_handle()
+{
+	static int handle;
+	return &handle;
+}
+
+static void
+gg_create_conversation(GaimConversation *conv)
+{
+	GGConv *ggc = conv->ui_data;
+	char *title;
+	GaimConversationType type;
+	GaimConversation *cc;
+	GaimAccount *account;
+
+	if (ggc)
+		return;
+
+	cc = find_conv_with_contact(conv);
+	if (cc && cc->ui_data)
+		ggc = cc->ui_data;
+	else
+		ggc = g_new0(GGConv, 1);
+
+	ggc->list = g_list_prepend(ggc->list, conv);
+	ggc->active_conv = conv;
+	conv->ui_data = ggc;
+
+	if (cc && cc->ui_data) {
+		gg_conversation_set_active(conv);
+		return;
+	}
+
+	account = gaim_conversation_get_account(conv);
+	type = gaim_conversation_get_type(conv);
+	title = get_conversation_title(conv, account);
+
+	ggc->window = gnt_box_new(FALSE, TRUE);
+	gnt_box_set_title(GNT_BOX(ggc->window), title);
+	gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE);
+	gnt_box_set_pad(GNT_BOX(ggc->window), 0);
+	gnt_widget_set_name(ggc->window, "conversation-window");
+
+	ggc->tv = gnt_text_view_new();
+	gnt_box_add_widget(GNT_BOX(ggc->window), ggc->tv);
+	gnt_widget_set_name(ggc->tv, "conversation-window-textview");
+	gnt_widget_set_size(ggc->tv, gaim_prefs_get_int(PREF_ROOT "/size/width"),
+			gaim_prefs_get_int(PREF_ROOT "/size/height"));
+
+	ggc->entry = gnt_entry_new(NULL);
+	gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry);
+	gnt_widget_set_name(ggc->entry, "conversation-window-entry");
+	gnt_entry_set_history_length(GNT_ENTRY(ggc->entry), -1);
+	gnt_entry_set_word_suggest(GNT_ENTRY(ggc->entry), TRUE);
+	gnt_entry_set_always_suggest(GNT_ENTRY(ggc->entry), FALSE);
+
+	g_signal_connect_after(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc);
+	g_signal_connect(G_OBJECT(ggc->entry), "text_changed", G_CALLBACK(send_typing_notification), ggc);
+	g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc);
+
+	gnt_widget_set_position(ggc->window, gaim_prefs_get_int(PREF_ROOT "/position/x"),
+			gaim_prefs_get_int(PREF_ROOT "/position/y"));
+	gnt_widget_show(ggc->window);
+
+	g_signal_connect(G_OBJECT(ggc->tv), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+	g_signal_connect(G_OBJECT(ggc->window), "position_set", G_CALLBACK(save_position_cb), NULL);
+
+	gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing", gg_conv_get_handle(),
+	                GAIM_CALLBACK(update_buddy_typing), NULL);
+	gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing-stopped", gg_conv_get_handle(),
+	                GAIM_CALLBACK(update_buddy_typing), NULL);
+
+	g_free(title);
+}
+
+static void
+gg_destroy_conversation(GaimConversation *conv)
+{
+	/* do stuff here */
+	GGConv *ggc = conv->ui_data;
+	ggc->list = g_list_remove(ggc->list, conv);
+	if (ggc->list && conv == ggc->active_conv)
+		ggc->active_conv = ggc->list->data;
+	
+	if (ggc->list == NULL) {
+		gnt_widget_destroy(ggc->window);
+		g_free(ggc);
+	}
+}
+
+static void
+gg_write_common(GaimConversation *conv, const char *who, const char *message,
+		GaimMessageFlags flags, time_t mtime)
+{
+	GGConv *ggconv = conv->ui_data;
+	char *strip, *newline;
+	GntTextFormatFlags fl = 0;
+	int pos;
+	gboolean notify;
+
+	g_return_if_fail(ggconv != NULL);
+
+	if (ggconv->active_conv != conv) {
+		if (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV))
+			gg_conversation_set_active(conv);
+		else
+			return;
+	}
+
+	pos = gnt_text_view_get_lines_below(GNT_TEXT_VIEW(ggconv->tv));
+
+	notify = !!gnt_text_view_tag_change(GNT_TEXT_VIEW(ggconv->tv), "typing", NULL, TRUE);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), "\n", GNT_TEXT_FLAG_NORMAL);
+
+	/* Unnecessary to print the timestamp for delayed message */
+	if (!(flags & GAIM_MESSAGE_DELAYED) &&
+			gaim_prefs_get_bool("/gaim/gnt/conversations/timestamps"))
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv),
+					gaim_utf8_strftime("(%H:%M:%S) ", localtime(&mtime)), GNT_TEXT_FLAG_DIM);
+
+	if (flags & GAIM_MESSAGE_AUTO_RESP)
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv),
+					_("<AUTO-REPLY> "), GNT_TEXT_FLAG_BOLD);
+
+	if (who && *who && (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV)))
+	{
+		char * name = NULL;
+
+		if (gaim_message_meify((char*)message, -1))
+			name = g_strdup_printf("*** %s ", who);
+		else
+			name =  g_strdup_printf("%s: ", who);
+
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv),
+				name, GNT_TEXT_FLAG_BOLD);
+		g_free(name);
+	}
+	else
+		fl = GNT_TEXT_FLAG_DIM;
+
+	if (flags & GAIM_MESSAGE_ERROR)
+		fl |= GNT_TEXT_FLAG_BOLD;
+	if (flags & GAIM_MESSAGE_NICK)
+		fl |= GNT_TEXT_FLAG_UNDERLINE;
+
+	/* XXX: Remove this workaround when textview can parse messages. */
+	newline = gaim_strdup_withhtml(message);
+	strip = gaim_markup_strip_html(newline);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv),
+				strip, fl);
+
+	g_free(newline);
+	g_free(strip);
+
+	if (notify) {
+		strip = g_strdup_printf(_("\n%s is typing..."), gaim_conversation_get_name(conv));
+		gnt_text_view_append_text_with_tag(GNT_TEXT_VIEW(ggconv->tv),
+					strip, GNT_TEXT_FLAG_DIM, "typing");
+		g_free(strip);
+	}
+
+	if (pos <= 1)
+		gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 0);
+
+	if (flags & (GAIM_MESSAGE_RECV | GAIM_MESSAGE_NICK | GAIM_MESSAGE_ERROR))
+		gnt_widget_set_urgent(ggconv->tv);
+}
+
+static void
+gg_write_chat(GaimConversation *conv, const char *who, const char *message,
+		GaimMessageFlags flags, time_t mtime)
+{
+	gaim_conversation_write(conv, who, message, flags, mtime);
+}
+
+static void
+gg_write_im(GaimConversation *conv, const char *who, const char *message,
+		GaimMessageFlags flags, time_t mtime)
+{
+	GaimAccount *account = gaim_conversation_get_account(conv);
+	if (flags & GAIM_MESSAGE_SEND)
+	{
+		who = gaim_connection_get_display_name(gaim_account_get_connection(account));
+		if (!who)
+			who = gaim_account_get_alias(account);
+		if (!who)
+			who = gaim_account_get_username(account);
+	}
+	else if (flags & GAIM_MESSAGE_RECV)
+	{
+		GaimBuddy *buddy;
+		who = gaim_conversation_get_name(conv);
+		buddy = gaim_find_buddy(account, who);
+		if (buddy)
+			who = gaim_buddy_get_contact_alias(buddy);
+	}
+
+	gaim_conversation_write(conv, who, message, flags, mtime);
+}
+
+static void
+gg_write_conv(GaimConversation *conv, const char *who, const char *alias,
+		const char *message, GaimMessageFlags flags, time_t mtime)
+{
+	const char *name;
+	if (alias && *alias)
+		name = alias;
+	else if (who && *who)
+		name = who;
+	else
+		name = NULL;
+
+	gg_write_common(conv, name, message, flags, mtime);
+}
+
+static void
+gg_chat_add_users(GaimConversation *conv, GList *users, gboolean new_arrivals)
+{
+	GGConv *ggc = conv->ui_data;
+	GntEntry *entry = GNT_ENTRY(ggc->entry);
+
+	if (!new_arrivals)
+	{
+		/* Print the list of users in the room */
+		GString *string = g_string_new(_("List of users:\n"));
+		GList *iter;
+
+		for (iter = users; iter; iter = iter->next)
+		{
+			GaimConvChatBuddy *cbuddy = iter->data;
+			char *str;
+
+			if ((str = cbuddy->alias) == NULL)
+				str = cbuddy->name;
+			g_string_append_printf(string, "[ %s ]", str);
+		}
+
+		gaim_conversation_write(conv, NULL, string->str,
+				GAIM_MESSAGE_SYSTEM, time(NULL));
+		g_string_free(string, TRUE);
+	}
+
+	for (; users; users = users->next)
+	{
+		GaimConvChatBuddy *cbuddy = users->data;
+		gnt_entry_add_suggest(entry, cbuddy->name);
+		gnt_entry_add_suggest(entry, cbuddy->alias);
+	}
+}
+
+static void
+gg_chat_rename_user(GaimConversation *conv, const char *old, const char *new_n, const char *new_a)
+{
+	/* Update the name for string completion */
+	GGConv *ggc = conv->ui_data;
+	GntEntry *entry = GNT_ENTRY(ggc->entry);
+	gnt_entry_remove_suggest(entry, old);
+	gnt_entry_add_suggest(entry, new_n);
+	gnt_entry_add_suggest(entry, new_a);
+}
+
+static void
+gg_chat_remove_user(GaimConversation *conv, GList *list)
+{
+	/* Remove the name from string completion */
+	GGConv *ggc = conv->ui_data;
+	GntEntry *entry = GNT_ENTRY(ggc->entry);
+	for (; list; list = list->next)
+		gnt_entry_remove_suggest(entry, list->data);
+}
+
+static void
+gg_chat_update_user(GaimConversation *conv, const char *user)
+{
+}
+
+static GaimConversationUiOps conv_ui_ops = 
+{
+	.create_conversation = gg_create_conversation,
+	.destroy_conversation = gg_destroy_conversation,
+	.write_chat = gg_write_chat,
+	.write_im = gg_write_im,
+	.write_conv = gg_write_conv,
+	.chat_add_users = gg_chat_add_users,
+	.chat_rename_user = gg_chat_rename_user,
+	.chat_remove_users = gg_chat_remove_user,
+	.chat_update_user = gg_chat_update_user,
+	.present = NULL,
+	.has_focus = NULL,
+	.custom_smiley_add = NULL,
+	.custom_smiley_write = NULL,
+	.custom_smiley_close = NULL
+};
+
+GaimConversationUiOps *gg_conv_get_ui_ops()
+{
+	return &conv_ui_ops;
+}
+
+/* Xerox */
+static GaimCmdRet
+say_command_cb(GaimConversation *conv,
+              const char *cmd, char **args, char **error, void *data)
+{
+	if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM)
+		gaim_conv_im_send(GAIM_CONV_IM(conv), args[0]);
+	else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT)
+		gaim_conv_chat_send(GAIM_CONV_CHAT(conv), args[0]);
+
+	return GAIM_CMD_RET_OK;
+}
+
+/* Xerox */
+static GaimCmdRet
+me_command_cb(GaimConversation *conv,
+              const char *cmd, char **args, char **error, void *data)
+{
+	char *tmp;
+
+	tmp = g_strdup_printf("/me %s", args[0]);
+
+	if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM)
+		gaim_conv_im_send(GAIM_CONV_IM(conv), tmp);
+	else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT)
+		gaim_conv_chat_send(GAIM_CONV_CHAT(conv), tmp);
+
+	g_free(tmp);
+	return GAIM_CMD_RET_OK;
+}
+
+/* Xerox */
+static GaimCmdRet
+debug_command_cb(GaimConversation *conv,
+                 const char *cmd, char **args, char **error, void *data)
+{
+	char *tmp, *markup;
+	GaimCmdStatus status;
+
+	if (!g_ascii_strcasecmp(args[0], "version")) {
+		tmp = g_strdup_printf("me is using %s.", VERSION);
+		markup = g_markup_escape_text(tmp, -1);
+
+		status = gaim_cmd_do_command(conv, tmp, markup, error);
+
+		g_free(tmp);
+		g_free(markup);
+		return status;
+	} else {
+		gaim_conversation_write(conv, NULL, _("Supported debug options are:  version"),
+		                        GAIM_MESSAGE_NO_LOG|GAIM_MESSAGE_ERROR, time(NULL));
+		return GAIM_CMD_STATUS_OK;
+	}
+}
+
+/* Xerox */
+static GaimCmdRet
+clear_command_cb(GaimConversation *conv,
+                 const char *cmd, char **args, char **error, void *data)
+{
+	GGConv *ggconv = conv->ui_data;
+	gnt_text_view_clear(GNT_TEXT_VIEW(ggconv->tv));
+	return GAIM_CMD_STATUS_OK;
+}
+
+/* Xerox */
+static GaimCmdRet
+help_command_cb(GaimConversation *conv,
+                 const char *cmd, char **args, char **error, void *data)
+{
+	GList *l, *text;
+	GString *s;
+
+	if (args[0] != NULL) {
+		s = g_string_new("");
+		text = gaim_cmd_help(conv, args[0]);
+
+		if (text) {
+			for (l = text; l; l = l->next)
+				if (l->next)
+					g_string_append_printf(s, "%s\n", (char *)l->data);
+				else
+					g_string_append_printf(s, "%s", (char *)l->data);
+		} else {
+			g_string_append(s, _("No such command (in this context)."));
+		}
+	} else {
+		s = g_string_new(_("Use \"/help &lt;command&gt;\" for help on a specific command.\n"
+											 "The following commands are available in this context:\n"));
+
+		text = gaim_cmd_list(conv);
+		for (l = text; l; l = l->next)
+			if (l->next)
+				g_string_append_printf(s, "%s, ", (char *)l->data);
+			else
+				g_string_append_printf(s, "%s.", (char *)l->data);
+		g_list_free(text);
+	}
+
+	gaim_conversation_write(conv, NULL, s->str, GAIM_MESSAGE_NO_LOG, time(NULL));
+	g_string_free(s, TRUE);
+
+	return GAIM_CMD_STATUS_OK;
+}
+
+static GaimCmdRet
+cmd_show_window(GaimConversation *conv, const char *cmd, char **args, char **error, gpointer data)
+{
+	void (*callback)() = data;
+	callback();
+	return GAIM_CMD_STATUS_OK;
+}
+
+void gg_conversation_init()
+{
+	gaim_prefs_add_none(PREF_ROOT);
+	gaim_prefs_add_none(PREF_ROOT "/size");
+	gaim_prefs_add_int(PREF_ROOT "/size/width", 70);
+	gaim_prefs_add_int(PREF_ROOT "/size/height", 20);
+	gaim_prefs_add_none(PREF_ROOT "/position");
+	gaim_prefs_add_int(PREF_ROOT "/position/x", 0);
+	gaim_prefs_add_int(PREF_ROOT "/position/y", 0);
+
+	/* Xerox the commands */
+	gaim_cmd_register("say", "S", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  say_command_cb, _("say &lt;message&gt;:  Send a message normally as if you weren't using a command."), NULL);
+	gaim_cmd_register("me", "S", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  me_command_cb, _("me &lt;action&gt;:  Send an IRC style action to a buddy or chat."), NULL);
+	gaim_cmd_register("debug", "w", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  debug_command_cb, _("debug &lt;option&gt;:  Send various debug information to the current conversation."), NULL);
+	gaim_cmd_register("clear", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  clear_command_cb, _("clear: Clears the conversation scrollback."), NULL);
+	gaim_cmd_register("help", "w", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, NULL,
+	                  help_command_cb, _("help &lt;command&gt;:  Help on a specific command."), NULL);
+
+	/* Now some commands to bring up some other windows */
+	gaim_cmd_register("plugins", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  cmd_show_window, _("plugins: Show the plugins window."), gg_plugins_show_all);
+	gaim_cmd_register("buddylist", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  cmd_show_window, _("buddylist: Show the buddylist."), gg_blist_show);
+	gaim_cmd_register("accounts", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  cmd_show_window, _("accounts: Show the accounts window."), gg_accounts_show_all);
+	gaim_cmd_register("debugwin", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  cmd_show_window, _("debugwin: Show the debug window."), gg_debug_window_show);
+	gaim_cmd_register("prefs", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  cmd_show_window, _("prefs: Show the preference window."), gg_prefs_show_all);
+	gaim_cmd_register("status", "", GAIM_CMD_P_DEFAULT,
+	                  GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL,
+	                  cmd_show_window, _("statuses: Show the savedstatuses window."), gg_savedstatus_show_all);
+}
+
+void gg_conversation_uninit()
+{
+}
+
+void gg_conversation_set_active(GaimConversation *conv)
+{
+	GGConv *ggconv = conv->ui_data;
+	GaimAccount *account;
+	char *title;
+
+	g_return_if_fail(ggconv);
+	g_return_if_fail(g_list_find(ggconv->list, conv));
+
+	ggconv->active_conv = conv;
+	account = gaim_conversation_get_account(conv);
+	title = get_conversation_title(conv, account);
+	gnt_screen_rename_widget(ggconv->window, title);
+	g_free(title);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntconv.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,94 @@
+/**
+ * @file gntconv.h GNT Conversation API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_CONV_H
+#define _GNT_CONV_H
+
+#include <gnt.h>
+#include <gntwidget.h>
+
+#include "conversation.h"
+
+/***************************************************************************
+ * @name GNT Conversations API
+ ***************************************************************************/
+/*@{*/
+
+typedef struct _GGConv GGConv;
+typedef struct _GGConvChat GGConvChat;
+typedef struct _GGConvIm GGConvIm;
+
+struct _GGConv
+{
+	GList *list;
+	GaimConversation *active_conv;
+
+	GntWidget *window;        /* the container */
+	GntWidget *entry;         /* entry */
+	GntWidget *tv;            /* text-view */
+
+	union
+	{
+		GGConvChat *chat;
+		GGConvIm *im;
+	} u;
+};
+
+struct _GGConvChat
+{
+	GntWidget *userlist;       /* the userlist */
+};
+
+struct _GGConvIm
+{
+	void *nothing_for_now;
+};
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimConversationUiOps populated with the appropriate functions.
+ */
+GaimConversationUiOps *gg_conv_get_ui_ops(void);
+
+/**
+ * Perform the necessary initializations.
+ */
+void gg_conversation_init(void);
+
+/**
+ * Perform the necessary uninitializations.
+ */
+void gg_conversation_uninit(void);
+
+/**
+ * Set a conversation as active in a contactized conversation
+ *
+ * @param conv The conversation to make active.
+ */
+void gg_conversation_set_active(GaimConversation *conv);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntdebug.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,299 @@
+/**
+ * @file gntdebug.c GNT Debug API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <gnt.h>
+#include <gntbox.h>
+#include <gnttextview.h>
+#include <gntbutton.h>
+#include <gntcheckbox.h>
+#include <gntline.h>
+
+#include "gntdebug.h"
+#include "gntgaim.h"
+#include "util.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#define PREF_ROOT "/gaim/gnt/debug"
+
+static struct
+{
+	GntWidget *window;
+	GntWidget *tview;
+	gboolean paused;
+	gboolean timestamps;
+} debug;
+
+static gboolean
+debug_window_kpress_cb(GntWidget *wid, const char *key, GntTextView *view)
+{
+	if (key[0] == 27)
+	{
+		if (strcmp(key, GNT_KEY_DOWN) == 0)
+			gnt_text_view_scroll(view, 1);
+		else if (strcmp(key, GNT_KEY_UP) == 0)
+			gnt_text_view_scroll(view, -1);
+		else if (strcmp(key, GNT_KEY_PGDOWN) == 0)
+			gnt_text_view_scroll(view, wid->priv.height - 2);
+		else if (strcmp(key, GNT_KEY_PGUP) == 0)
+			gnt_text_view_scroll(view, -(wid->priv.height - 2));
+		else
+			return FALSE;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+gg_debug_print(GaimDebugLevel level, const char *category,
+		const char *args)
+{
+	if (debug.window && !debug.paused)
+	{
+		int pos = gnt_text_view_get_lines_below(GNT_TEXT_VIEW(debug.tview));
+		GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL;
+
+		if (debug.timestamps) {
+			const char *mdate;
+			time_t mtime = time(NULL);
+			mdate = gaim_utf8_strftime("%H:%M:%S ", localtime(&mtime));
+			gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview),
+					mdate, flag);
+		}
+
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview),
+				category, GNT_TEXT_FLAG_BOLD);
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview),
+				": ", GNT_TEXT_FLAG_BOLD);
+
+		switch (level)
+		{
+			case GAIM_DEBUG_WARNING:
+				flag |= GNT_TEXT_FLAG_UNDERLINE;
+			case GAIM_DEBUG_ERROR:
+			case GAIM_DEBUG_FATAL:
+				flag |= GNT_TEXT_FLAG_BOLD;
+				break;
+			default:
+				break;
+		}
+
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(debug.tview), args, flag);
+		if (pos <= 1)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(debug.tview), 0);
+	}
+}
+
+static GaimDebugUiOps uiops =
+{
+	gg_debug_print,
+};
+
+GaimDebugUiOps *gg_debug_get_ui_ops()
+{
+	return &uiops;
+}
+
+static void
+reset_debug_win(GntWidget *w, gpointer null)
+{
+	debug.window = debug.tview = NULL;
+}
+
+static void
+clear_debug_win(GntWidget *w, GntTextView *tv)
+{
+	gnt_text_view_clear(tv);
+}
+
+static void
+print_stderr(const char *string)
+{
+	g_printerr("%s", string);
+}
+
+static void
+toggle_pause(GntWidget *w, gpointer n)
+{
+	debug.paused = !debug.paused;
+}
+
+static void
+toggle_timestamps(GntWidget *w, gpointer n)
+{
+	debug.timestamps = !debug.timestamps;
+	gaim_prefs_set_bool("/core/debug/timestamps", debug.timestamps);
+}
+
+/* Xerox */
+static void
+gaim_glib_log_handler(const gchar *domain, GLogLevelFlags flags,
+					  const gchar *msg, gpointer user_data)
+{
+	GaimDebugLevel level;
+	char *new_msg = NULL;
+	char *new_domain = NULL;
+
+	if ((flags & G_LOG_LEVEL_ERROR) == G_LOG_LEVEL_ERROR)
+		level = GAIM_DEBUG_ERROR;
+	else if ((flags & G_LOG_LEVEL_CRITICAL) == G_LOG_LEVEL_CRITICAL)
+		level = GAIM_DEBUG_FATAL;
+	else if ((flags & G_LOG_LEVEL_WARNING) == G_LOG_LEVEL_WARNING)
+		level = GAIM_DEBUG_WARNING;
+	else if ((flags & G_LOG_LEVEL_MESSAGE) == G_LOG_LEVEL_MESSAGE)
+		level = GAIM_DEBUG_INFO;
+	else if ((flags & G_LOG_LEVEL_INFO) == G_LOG_LEVEL_INFO)
+		level = GAIM_DEBUG_INFO;
+	else if ((flags & G_LOG_LEVEL_DEBUG) == G_LOG_LEVEL_DEBUG)
+		level = GAIM_DEBUG_MISC;
+	else
+	{
+		gaim_debug_warning("gntdebug",
+				   "Unknown glib logging level in %d\n", flags);
+
+		level = GAIM_DEBUG_MISC; /* This will never happen. */
+	}
+
+	if (msg != NULL)
+		new_msg = gaim_utf8_try_convert(msg);
+
+	if (domain != NULL)
+		new_domain = gaim_utf8_try_convert(domain);
+
+	if (new_msg != NULL)
+	{
+		gaim_debug(level, (new_domain != NULL ? new_domain : "g_log"),
+				   "%s\n", new_msg);
+
+		g_free(new_msg);
+	}
+
+	g_free(new_domain);
+}
+
+static void
+size_changed_cb(GntWidget *widget, int oldw, int oldh)
+{
+	int w, h;
+	gnt_widget_get_size(widget, &w, &h);
+	gaim_prefs_set_int(PREF_ROOT "/size/width", w);
+	gaim_prefs_set_int(PREF_ROOT "/size/height", h);
+}
+
+void gg_debug_window_show()
+{
+	debug.paused = FALSE;
+	debug.timestamps = gaim_prefs_get_bool("/core/debug/timestamps");
+	if (debug.window == NULL)
+	{
+		GntWidget *wid, *box;
+		debug.window = gnt_vbox_new(FALSE);
+		gnt_box_set_toplevel(GNT_BOX(debug.window), TRUE);
+		gnt_box_set_title(GNT_BOX(debug.window), _("Debug Window"));
+		gnt_box_set_pad(GNT_BOX(debug.window), 0);
+		gnt_box_set_alignment(GNT_BOX(debug.window), GNT_ALIGN_MID);
+
+		debug.tview = gnt_text_view_new();
+		gnt_box_add_widget(GNT_BOX(debug.window), debug.tview);
+		gnt_widget_set_size(debug.tview,
+				gaim_prefs_get_int(PREF_ROOT "/size/width"),
+				gaim_prefs_get_int(PREF_ROOT "/size/height"));
+		g_signal_connect(G_OBJECT(debug.tview), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+
+		gnt_box_add_widget(GNT_BOX(debug.window), gnt_line_new(FALSE));
+
+		box = gnt_hbox_new(FALSE);
+		gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID);
+		gnt_box_set_fill(GNT_BOX(box), FALSE);
+
+		/* XXX: Setting the GROW_Y for the following widgets don't make sense. But right now
+		 * it's necessary to make the width of the debug window resizable ... like I said,
+		 * it doesn't make sense. The bug is likely in the packing in gntbox.c.
+		 */
+		wid = gnt_button_new(_("Clear"));
+		g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(clear_debug_win), debug.tview);
+		GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
+		gnt_box_add_widget(GNT_BOX(box), wid);
+
+		wid = gnt_check_box_new(_("Pause"));
+		g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_pause), NULL);
+		GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
+		gnt_box_add_widget(GNT_BOX(box), wid);
+
+		wid = gnt_check_box_new(_("Timestamps"));
+		gnt_check_box_set_checked(GNT_CHECK_BOX(wid), debug.timestamps);
+		g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_timestamps), NULL);
+		GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
+		gnt_box_add_widget(GNT_BOX(box), wid);
+
+		gnt_box_add_widget(GNT_BOX(debug.window), box);
+		GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_GROW_Y);
+
+		gnt_widget_set_name(debug.window, "debug-window");
+
+		g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL);
+		g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview);
+	}
+
+	gnt_widget_show(debug.window);
+}
+
+static gboolean
+start_with_debugwin(gpointer null)
+{
+	gg_debug_window_show();
+	return FALSE;
+}
+
+void gg_debug_init()
+{
+/* Xerox */
+#define REGISTER_G_LOG_HANDLER(name) \
+	g_log_set_handler((name), G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL \
+					  | G_LOG_FLAG_RECURSION, \
+					  gaim_glib_log_handler, NULL)
+
+	/* Register the glib log handlers. */
+	REGISTER_G_LOG_HANDLER(NULL);
+	REGISTER_G_LOG_HANDLER("GLib");
+	REGISTER_G_LOG_HANDLER("GModule");
+	REGISTER_G_LOG_HANDLER("GLib-GObject");
+	REGISTER_G_LOG_HANDLER("GThread");
+
+	g_set_print_handler(print_stderr);   /* Redirect the debug messages to stderr */
+
+	gaim_prefs_add_none(PREF_ROOT);
+	gaim_prefs_add_none(PREF_ROOT "/size");
+	gaim_prefs_add_int(PREF_ROOT "/size/width", 60);
+	gaim_prefs_add_int(PREF_ROOT "/size/height", 15);
+
+	if (gaim_debug_is_enabled())
+		g_timeout_add(0, start_with_debugwin, NULL);
+}
+
+void gg_debug_uninit()
+{
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntdebug.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,59 @@
+/**
+ * @file gntdebug.h GNT Debug API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_DEBUG_H
+#define _GNT_DEBUG_H
+
+#include "debug.h"
+
+/**********************************************************************
+ * @name GNT Debug API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimDebugUiOps structure populated with the appropriate functions.
+ */
+GaimDebugUiOps *gg_debug_get_ui_ops(void);
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_debug_init(void);
+
+/**
+ * Perform necessary uninitializations.
+ */
+void gg_debug_uninit(void);
+
+/**
+ * Show the debug window.
+ */
+void gg_debug_window_show(void);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntgaim.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,417 @@
+/**
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 "account.h"
+#include "conversation.h"
+#include "core.h"
+#include "debug.h"
+#include "eventloop.h"
+#include "ft.h"
+#include "log.h"
+#include "notify.h"
+#include "prefix.h"
+#include "prefs.h"
+#include "prpl.h"
+#include "pounce.h"
+#include "savedstatuses.h"
+#include "sound.h"
+#include "status.h"
+#include "util.h"
+#include "whiteboard.h"
+
+#include "gntdebug.h"
+#include "gntgaim.h"
+#include "gntprefs.h"
+#include "gntui.h"
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include "config.h"
+
+static void
+debug_init()
+{
+	gg_debug_init();
+	gaim_debug_set_ui_ops(gg_debug_get_ui_ops());
+}
+
+static GaimCoreUiOps core_ops =
+{
+	gg_prefs_init,
+	debug_init,
+	gnt_ui_init,
+	gnt_ui_uninit
+};
+
+static GaimCoreUiOps *
+gnt_core_get_ui_ops()
+{
+	return &core_ops;
+}
+
+/* Anything IO-related is directly copied from gtkgaim's source tree */
+
+#define GAIM_GTK_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)
+#define GAIM_GTK_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
+
+typedef struct _GaimGtkIOClosure {
+	GaimInputFunction function;
+	guint result;
+	gpointer data;
+
+} GaimGtkIOClosure;
+
+static void gaim_gnt_io_destroy(gpointer data)
+{
+	g_free(data);
+}
+
+static gboolean gaim_gnt_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+	GaimGtkIOClosure *closure = data;
+	GaimInputCondition gaim_cond = 0;
+
+	if (condition & GAIM_GTK_READ_COND)
+		gaim_cond |= GAIM_INPUT_READ;
+	if (condition & GAIM_GTK_WRITE_COND)
+		gaim_cond |= GAIM_INPUT_WRITE;
+
+#if 0
+	gaim_debug(GAIM_DEBUG_MISC, "gtk_eventloop",
+			   "CLOSURE: callback for %d, fd is %d\n",
+			   closure->result, g_io_channel_unix_get_fd(source));
+#endif
+
+#ifdef _WIN32
+	if(! gaim_cond) {
+#if DEBUG
+		gaim_debug_misc("gnt_eventloop",
+			   "CLOSURE received GIOCondition of 0x%x, which does not"
+			   " match 0x%x (READ) or 0x%x (WRITE)\n",
+			   condition, GAIM_GTK_READ_COND, GAIM_GTK_WRITE_COND);
+#endif /* DEBUG */
+
+		return TRUE;
+	}
+#endif /* _WIN32 */
+
+	closure->function(closure->data, g_io_channel_unix_get_fd(source),
+			  gaim_cond);
+
+	return TRUE;
+}
+
+static guint gnt_input_add(gint fd, GaimInputCondition condition, GaimInputFunction function,
+							   gpointer data)
+{
+	GaimGtkIOClosure *closure = g_new0(GaimGtkIOClosure, 1);
+	GIOChannel *channel;
+	GIOCondition cond = 0;
+
+	closure->function = function;
+	closure->data = data;
+
+	if (condition & GAIM_INPUT_READ)
+		cond |= GAIM_GTK_READ_COND;
+	if (condition & GAIM_INPUT_WRITE)
+		cond |= GAIM_GTK_WRITE_COND;
+
+	channel = g_io_channel_unix_new(fd);
+	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
+					      gaim_gnt_io_invoke, closure, gaim_gnt_io_destroy);
+
+	g_io_channel_unref(channel);
+	return closure->result;
+}
+
+static GaimEventLoopUiOps eventloop_ops =
+{
+	g_timeout_add,
+	(guint (*)(guint))g_source_remove,
+	gnt_input_add,
+	(guint (*)(guint))g_source_remove
+};
+
+static GaimEventLoopUiOps *
+gnt_eventloop_get_ui_ops(void)
+{
+	return &eventloop_ops;
+}
+
+/* This is copied from gtkgaim */
+static char *
+gnt_find_binary_location(void *symbol, void *data)
+{
+	static char *fullname = NULL;
+	static gboolean first = TRUE;
+
+	char *argv0 = data;
+	struct stat st;
+	char *basebuf, *linkbuf, *fullbuf;
+
+	if (!first)
+		/* We've already been through this. */
+		return strdup(fullname);
+
+	first = FALSE;
+
+	if (!argv0)
+		return NULL;
+
+
+	basebuf = g_find_program_in_path(argv0);
+
+	/* But we still need to deal with symbolic links */
+	g_lstat(basebuf, &st);
+	while ((st.st_mode & S_IFLNK) == S_IFLNK) {
+		int written;
+		linkbuf = g_malloc(1024);
+		written = readlink(basebuf, linkbuf, 1024 - 1);
+		if (written == -1)
+		{
+			/* This really shouldn't happen, but do we
+			 * need something better here? */
+			g_free(linkbuf);
+			continue;
+		}
+		linkbuf[written] = '\0';
+		if (linkbuf[0] == G_DIR_SEPARATOR) {
+			/* an absolute path */
+			fullbuf = g_strdup(linkbuf);
+		} else {
+			char *dirbuf = g_path_get_dirname(basebuf);
+			/* a relative path */
+			fullbuf = g_strdup_printf("%s%s%s",
+					dirbuf, G_DIR_SEPARATOR_S,
+					linkbuf);
+			g_free(dirbuf);
+		}
+		/* There's no memory leak here.  Really! */
+		g_free(linkbuf);
+		g_free(basebuf);
+		basebuf = fullbuf;
+		g_lstat(basebuf, &st);
+	}
+
+	fullname = basebuf;
+	return strdup(fullname);
+}
+
+
+/* This is mostly copied from gtkgaim's source tree */
+static void
+show_usage(const char *name, gboolean terse)
+{
+	char *text;
+
+	if (terse) {
+		text = g_strdup_printf(_("%s. Try `%s -h' for more information.\n"), VERSION, name);
+	} else {
+		text = g_strdup_printf(_("%s\n"
+		       "Usage: %s [OPTION]...\n\n"
+		       "  -c, --config=DIR    use DIR for config files\n"
+		       "  -d, --debug         print debugging messages to stdout\n"
+		       "  -h, --help          display this help and exit\n"
+		       "  -n, --nologin       don't automatically login\n"
+		       "  -v, --version       display the current version and exit\n"), VERSION, name);
+	}
+
+	gaim_print_utf8_to_console(stdout, text);
+	g_free(text);
+}
+
+static int
+init_libgaim(int argc, char **argv)
+{
+	char *path;
+	int opt;
+	gboolean opt_help = FALSE;
+	gboolean opt_nologin = FALSE;
+	gboolean opt_version = FALSE;
+	char *opt_config_dir_arg = NULL;
+	char *opt_session_arg = NULL;
+	gboolean debug_enabled = FALSE;
+
+	struct option long_options[] = {
+		{"config",   required_argument, NULL, 'c'},
+		{"debug",    no_argument,       NULL, 'd'},
+		{"help",     no_argument,       NULL, 'h'},
+		{"nologin",  no_argument,       NULL, 'n'},
+		{"session",  required_argument, NULL, 's'},
+		{"version",  no_argument,       NULL, 'v'},
+		{0, 0, 0, 0}
+	};
+
+	gaim_br_set_locate_fallback_func(gnt_find_binary_location, argv[0]);
+
+#ifdef ENABLE_NLS
+	bindtextdomain(PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset(PACKAGE, "UTF-8");
+	textdomain(PACKAGE);
+#endif
+
+#ifdef HAVE_SETLOCALE
+	setlocale(LC_ALL, "");
+#endif
+
+	/* scan command-line options */
+	opterr = 1;
+	while ((opt = getopt_long(argc, argv,
+#ifndef _WIN32
+				  "c:dhn::s:v",
+#else
+				  "c:dhn::v",
+#endif
+				  long_options, NULL)) != -1) {
+		switch (opt) {
+		case 'c':	/* config dir */
+			g_free(opt_config_dir_arg);
+			opt_config_dir_arg = g_strdup(optarg);
+			break;
+		case 'd':	/* debug */
+			debug_enabled = TRUE;
+			break;
+		case 'h':	/* help */
+			opt_help = TRUE;
+			break;
+		case 'n':	/* no autologin */
+			opt_nologin = TRUE;
+			break;
+		case 's':	/* use existing session ID */
+			g_free(opt_session_arg);
+			opt_session_arg = g_strdup(optarg);
+			break;
+		case 'v':	/* version */
+			opt_version = TRUE;
+			break;
+		case '?':	/* show terse help */
+		default:
+			show_usage(argv[0], TRUE);
+			return 0;
+			break;
+		}
+	}
+
+	/* show help message */
+	if (opt_help) {
+		show_usage(argv[0], FALSE);
+		return 0;
+	}
+	/* show version message */
+	if (opt_version) {
+		printf("gaim-text %s\n", VERSION);
+		return 0;
+	}
+
+	/* set a user-specified config directory */
+	if (opt_config_dir_arg != NULL) {
+		gaim_util_set_user_dir(opt_config_dir_arg);
+		g_free(opt_config_dir_arg);
+	}
+
+	/*
+	 * We're done piddling around with command line arguments.
+	 * Fire up this baby.
+	 */
+
+	/* Because we don't want debug-messages to show up and corrup the display */
+	gaim_debug_set_enabled(debug_enabled);
+
+	gaim_core_set_ui_ops(gnt_core_get_ui_ops());
+	gaim_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops());
+
+	path = g_build_filename(gaim_user_dir(), "plugins", NULL);
+	gaim_plugins_add_search_path(path);
+	g_free(path);
+
+	gaim_plugins_add_search_path(LIBDIR);
+
+	if (!gaim_core_init(GAIM_GNT_UI))
+	{
+		fprintf(stderr,
+				"Initialization of the Gaim core failed. Dumping core.\n"
+				"Please report this!\n");
+		abort();
+	}
+
+	/* TODO: Move blist loading into gaim_blist_init() */
+	gaim_set_blist(gaim_blist_new());
+	gaim_blist_load();
+
+	/* TODO: Move prefs loading into gaim_prefs_init() */
+	gaim_prefs_load();
+	gaim_prefs_update_old();
+
+	/* load plugins we had when we quit */
+	gaim_plugins_load_saved("/gaim/gnt/plugins/loaded");
+
+	/* TODO: Move pounces loading into gaim_pounces_init() */
+	gaim_pounces_load();
+
+	if (opt_nologin)
+	{
+		/* Set all accounts to "offline" */
+		GaimSavedStatus *saved_status;
+
+		/* If we've used this type+message before, lookup the transient status */
+		saved_status = gaim_savedstatus_find_transient_by_type_and_message(
+							GAIM_STATUS_OFFLINE, NULL);
+
+		/* If this type+message is unique then create a new transient saved status */
+		if (saved_status == NULL)
+			saved_status = gaim_savedstatus_new(NULL, GAIM_STATUS_OFFLINE);
+
+		/* Set the status for each account */
+		gaim_savedstatus_activate(saved_status);
+	}
+	else
+	{
+		/* Everything is good to go--sign on already */
+		if (!gaim_prefs_get_bool("/core/savedstatus/startup_current_status"))
+			gaim_savedstatus_activate(gaim_savedstatus_get_startup());
+		gaim_accounts_restore_current_statuses();
+	}
+
+	return 1;
+}
+
+int main(int argc, char **argv)
+{
+	/* XXX: Don't puke */
+	freopen(".error", "w", stderr);
+
+	signal(SIGPIPE, SIG_IGN);
+
+	/* Initialize the libgaim stuff */
+	if (!init_libgaim(argc, argv))
+		return 0;
+
+	gaim_blist_show();
+	gnt_main();
+
+#ifdef STANDALONE
+	gaim_core_quit();
+#endif
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntgaim.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,27 @@
+/**
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <glib.h>
+
+#include "libgaim/internal.h"
+
+#define GAIM_GNT_UI "gnt-gaim"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntnotify.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,374 @@
+/**
+ * @file gntnotify.c GNT Notify API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntlabel.h>
+#include <gnttree.h>
+
+#include <util.h>
+
+#include "gntnotify.h"
+#include "gntgaim.h"
+
+static struct
+{
+	GntWidget *window;
+	GntWidget *tree;
+} emaildialog;
+
+static void
+notify_msg_window_destroy_cb(GntWidget *window, GaimNotifyMsgType type)
+{
+	gaim_notify_close(type, window);
+}
+
+static void *
+gg_notify_message(GaimNotifyMsgType type, const char *title,
+		const char *primary, const char *secondary)
+{
+	GntWidget *window, *button;
+	GntTextFormatFlags pf = 0, sf = 0;
+
+	switch (type)
+	{
+		case GAIM_NOTIFY_MSG_ERROR:
+			sf |= GNT_TEXT_FLAG_BOLD;
+		case GAIM_NOTIFY_MSG_WARNING:
+			pf |= GNT_TEXT_FLAG_UNDERLINE;
+		case GAIM_NOTIFY_MSG_INFO:
+			pf |= GNT_TEXT_FLAG_BOLD;
+			break;
+	}
+
+	window = gnt_box_new(FALSE, TRUE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), title);
+	gnt_box_set_fill(GNT_BOX(window), FALSE);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+	if (primary)
+		gnt_box_add_widget(GNT_BOX(window),
+				gnt_label_new_with_format(primary, pf));
+	if (secondary)
+		gnt_box_add_widget(GNT_BOX(window),
+				gnt_label_new_with_format(secondary, sf));
+
+	button = gnt_button_new(_("OK"));
+	gnt_box_add_widget(GNT_BOX(window), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate",
+			G_CALLBACK(gnt_widget_destroy), window);
+	g_signal_connect(G_OBJECT(window), "destroy",
+			G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(type));
+
+	gnt_widget_show(window);
+	return window;
+}
+
+/* handle is, in all/most occasions, a GntWidget * */
+static void gg_close_notify(GaimNotifyType type, void *handle)
+{
+	GntWidget *widget = handle;
+
+	if (!widget)
+		return;
+
+	while (widget->parent)
+		widget = widget->parent;
+	
+	if (type == GAIM_NOTIFY_SEARCHRESULTS)
+		gaim_notify_searchresults_free(g_object_get_data(handle, "notify-results"));
+#if 1
+	/* This did not seem to be necessary */
+	g_signal_handlers_disconnect_by_func(G_OBJECT(widget),
+			G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(type));
+#endif
+	gnt_widget_destroy(widget);
+}
+
+static void *gg_notify_formatted(const char *title, const char *primary,
+		const char *secondary, const char *text)
+{
+	/* XXX: For now, simply strip the html and use _notify_message. For future use,
+	 * there should be some way of parsing the makrups from GntTextView */
+	char *unformat = gaim_markup_strip_html(text);
+	char *t = g_strdup_printf("%s%s%s",
+			secondary ? secondary : "",
+			secondary ? "\n" : "",
+			unformat ? unformat : "");
+
+	void *ret = gg_notify_message(GAIM_NOTIFY_FORMATTED, title, primary, t);
+
+	g_free(t);
+	g_free(unformat);
+
+	return ret;
+}
+
+static void
+reset_email_dialog()
+{
+	emaildialog.window = NULL;
+	emaildialog.tree = NULL;
+}
+
+static void
+setup_email_dialog()
+{
+	GntWidget *box, *tree, *button;
+	if (emaildialog.window)
+		return;
+
+	emaildialog.window = box = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(box), TRUE);
+	gnt_box_set_title(GNT_BOX(box), _("Emails"));
+	gnt_box_set_fill(GNT_BOX(box), FALSE);
+	gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID);
+	gnt_box_set_pad(GNT_BOX(box), 0);
+
+	gnt_box_add_widget(GNT_BOX(box),
+			gnt_label_new_with_format(_("You have mail!"), GNT_TEXT_FLAG_BOLD));
+
+	emaildialog.tree = tree = gnt_tree_new_with_columns(3);
+	gnt_tree_set_column_titles(GNT_TREE(tree), _("Account"), _("From"), _("Subject"));
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 15);
+	gnt_tree_set_col_width(GNT_TREE(tree), 1, 25);
+	gnt_tree_set_col_width(GNT_TREE(tree), 2, 25);
+
+	gnt_box_add_widget(GNT_BOX(box), tree);
+
+	button = gnt_button_new(_("Close"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+
+	g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), box);
+	g_signal_connect(G_OBJECT(box), "destroy", G_CALLBACK(reset_email_dialog), NULL);
+}
+
+static void *
+gg_notify_emails(GaimConnection *gc, size_t count, gboolean detailed,
+		const char **subjects, const char **froms, const char **tos,
+		const char **urls)
+{
+	GaimAccount *account = gaim_connection_get_account(gc);
+	GString *message = g_string_new(NULL);
+	void *ret;
+
+	if (!detailed)
+	{
+		g_string_append_printf(message,
+				ngettext("%s (%s) has %d new message.",
+					     "%s (%s) has %d new messages.",
+						 (int)count),
+				tos ? *tos : gaim_account_get_username(account),
+				gaim_account_get_protocol_name(account), (int)count);
+	}
+	else
+	{
+		char *to;
+
+		setup_email_dialog();
+
+		to = g_strdup_printf("%s (%s)", tos ? *tos : gaim_account_get_username(account),
+					gaim_account_get_protocol_name(account));
+		gnt_tree_add_row_after(GNT_TREE(emaildialog.tree), GINT_TO_POINTER(time(NULL)),
+				gnt_tree_create_row(GNT_TREE(emaildialog.tree), to,
+					froms ? *froms : "[Unknown sender]",
+					*subjects),
+				NULL, NULL);
+		g_free(to);
+		gnt_widget_show(emaildialog.window);
+		return NULL;
+	}
+
+	ret = gg_notify_message(GAIM_NOTIFY_EMAIL, _("New Mail"), _("You have mail!"), message->str);
+	g_string_free(message, TRUE);
+	return ret;
+}
+
+static void *
+gg_notify_email(GaimConnection *gc, const char *subject, const char *from,
+		const char *to, const char *url)
+{
+	return gg_notify_emails(gc, 1, subject != NULL,
+			subject ? &subject : NULL,
+			from ? &from : NULL,
+			to ? &to : NULL,
+			url ? &url : NULL);
+}
+
+static void *
+gg_notify_userinfo(GaimConnection *gc, const char *who, GaimNotifyUserInfo *user_info)
+{
+	/* Xeroxed from gtknotify.c */
+	char *primary;
+	char *info;
+	void *ui_handle;
+	
+	primary = g_strdup_printf(_("Info for %s"), who);
+	info = gaim_notify_user_info_get_text_with_newline(user_info, "<BR>");
+	ui_handle = gg_notify_formatted(_("Buddy Information"), primary, NULL, info);
+	g_free(info);
+	g_free(primary);
+	return ui_handle;
+}
+
+static void
+notify_button_activated(GntWidget *widget, GaimNotifySearchButton *b)
+{
+	GList *list = NULL;
+	GaimAccount *account = g_object_get_data(G_OBJECT(widget), "notify-account");
+	gpointer data = g_object_get_data(G_OBJECT(widget), "notify-data");
+
+	list = gnt_tree_get_selection_text_list(GNT_TREE(widget));
+
+	b->callback(gaim_account_get_connection(account), list, data);
+	g_list_foreach(list, (GFunc)g_free, NULL);
+	g_list_free(list);
+}
+
+static void
+gg_notify_sr_new_rows(GaimConnection *gc,
+		GaimNotifySearchResults *results, void *data)
+{
+	GntTree *tree = GNT_TREE(data);
+	GList *o;
+
+	/* XXX: Do I need to empty the tree here? */
+
+	for (o = results->rows; o; o = o->next)
+	{
+		gnt_tree_add_row_after(GNT_TREE(tree), o->data,
+				gnt_tree_create_row_from_list(GNT_TREE(tree), o->data),
+				NULL, NULL);
+	}
+}
+
+static void *
+gg_notify_searchresults(GaimConnection *gc, const char *title,
+		const char *primary, const char *secondary,
+		GaimNotifySearchResults *results, gpointer data)
+{
+	GntWidget *window, *tree, *box, *button;
+	GList *iter;
+
+	window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), title);
+	gnt_box_set_fill(GNT_BOX(window), FALSE);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD));
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new_with_format(secondary, GNT_TEXT_FLAG_NORMAL));
+
+	tree = gnt_tree_new_with_columns(g_list_length(results->columns));
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+	gnt_box_add_widget(GNT_BOX(window), tree);
+
+	box = gnt_hbox_new(TRUE);
+
+	for (iter = results->buttons; iter; iter = iter->next)
+	{
+		GaimNotifySearchButton *b = iter->data;
+		const char *text;
+
+		switch (b->type)
+		{
+			case GAIM_NOTIFY_BUTTON_LABELED:
+				text = b->label;
+				break;
+			case GAIM_NOTIFY_BUTTON_CONTINUE:
+				text = _("Continue");
+				break;
+			case GAIM_NOTIFY_BUTTON_ADD:
+				text = _("Add");
+				break;
+			case GAIM_NOTIFY_BUTTON_INFO:
+				text = _("Info");
+				break;
+			case GAIM_NOTIFY_BUTTON_IM:
+				text = _("IM");
+				break;
+			case GAIM_NOTIFY_BUTTON_JOIN:
+				text = _("Join");
+				break;
+			case GAIM_NOTIFY_BUTTON_INVITE:
+				text = _("Invite");
+				break;
+			default:
+				text = _("(none)");
+		}
+
+		button = gnt_button_new(text);
+		g_object_set_data(G_OBJECT(button), "notify-account", gaim_connection_get_account(gc));
+		g_object_set_data(G_OBJECT(button), "notify-data", data);
+		g_signal_connect_swapped(G_OBJECT(button), "activate",
+				G_CALLBACK(notify_button_activated), b);
+
+		gnt_box_add_widget(GNT_BOX(box), button);
+	}
+
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	gg_notify_sr_new_rows(gc, results, tree);
+
+	gnt_widget_show(window);
+	g_object_set_data(G_OBJECT(window), "notify-results", results);
+
+	return tree;
+}
+
+static GaimNotifyUiOps ops = 
+{
+	.notify_message = gg_notify_message,
+	.close_notify = gg_close_notify,       /* The rest of the notify-uiops return a GntWidget.
+                                              These widgets should be destroyed from here. */
+	.notify_formatted = gg_notify_formatted,
+	.notify_email = gg_notify_email,
+	.notify_emails = gg_notify_emails,
+	.notify_userinfo = gg_notify_userinfo,
+
+	.notify_searchresults = gg_notify_searchresults,
+	.notify_searchresults_new_rows = gg_notify_sr_new_rows,
+	.notify_uri = NULL                     /* This is of low-priority to me */
+};
+
+GaimNotifyUiOps *gg_notify_get_ui_ops()
+{
+	return &ops;
+}
+
+void gg_notify_init()
+{
+}
+
+void gg_notify_uninit()
+{
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntnotify.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,55 @@
+/**
+ * @file gntnotify.h GNT Notify API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_NOTIFY_H
+#define _GNT_NOTIFY_H
+
+#include "notify.h"
+
+/**********************************************************************
+ * @name GNT Notify API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimNotifyUiOps structure populated with the appropriate functions.
+ */
+GaimNotifyUiOps *gg_notify_get_ui_ops(void);
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_notify_init(void);
+
+/**
+ * Perform necessary uninitializations.
+ */
+void gg_notify_uninit(void);
+
+/*@}*/
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntplugin.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,274 @@
+/**
+ * @file gntplugin.c GNT Plugins API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntlabel.h>
+#include <gntline.h>
+#include <gnttree.h>
+
+#include "notify.h"
+
+#include "gntgaim.h"
+#include "gntplugin.h"
+
+static struct
+{
+	GntWidget *tree;
+	GntWidget *window;
+	GntWidget *aboot;
+	GntWidget *conf;
+} plugins;
+
+static GHashTable *confwins;
+
+static void
+decide_conf_button(GaimPlugin *plugin)
+{
+	if (gaim_plugin_is_loaded(plugin) && 
+		((GAIM_IS_GNT_PLUGIN(plugin) &&
+			GAIM_GNT_PLUGIN_UI_INFO(plugin) != NULL) ||
+		(plugin->info->prefs_info &&
+			plugin->info->prefs_info->get_plugin_pref_frame)))
+		gnt_widget_set_visible(plugins.conf, TRUE);
+	else
+		gnt_widget_set_visible(plugins.conf, FALSE);
+
+	gnt_box_readjust(GNT_BOX(plugins.window));
+	gnt_widget_draw(plugins.window);
+}
+
+static void
+plugin_toggled_cb(GntWidget *tree, GaimPlugin *plugin, gpointer null)
+{
+	if (gnt_tree_get_choice(GNT_TREE(tree), plugin))
+	{
+		if(!gaim_plugin_load(plugin))
+			gaim_notify_error(NULL, "ERROR", "loading plugin failed", NULL);
+	}
+	else
+	{
+		GntWidget *win;
+
+		if (!gaim_plugin_unload(plugin))
+			gaim_notify_error(NULL, "ERROR", "unloading plugin failed", NULL);
+
+		if ((win = g_hash_table_lookup(confwins, plugin)) != NULL)
+		{
+			gnt_widget_destroy(win);
+		}
+	}
+	decide_conf_button(plugin);
+	gg_plugins_save_loaded();
+}
+
+/* Xerox */
+void
+gg_plugins_save_loaded(void)
+{
+	gaim_plugins_save_loaded("/gaim/gnt/plugins/loaded");
+}
+
+static void
+selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
+{
+	GaimPlugin *plugin = current;
+	char *text;
+
+	/* XXX: Use formatting and stuff */
+	gnt_text_view_clear(GNT_TEXT_VIEW(plugins.aboot));
+	text = g_strdup_printf(_("Name: %s\nVersion: %s\nDescription: %s\nAuthor: %s\nWebsite: %s\nFilename: %s\n"),
+			SAFE(plugin->info->name), SAFE(plugin->info->version), SAFE(plugin->info->description),
+			SAFE(plugin->info->author), SAFE(plugin->info->homepage), SAFE(plugin->path));
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(plugins.aboot),
+			text, GNT_TEXT_FLAG_NORMAL);
+	gnt_text_view_scroll(GNT_TEXT_VIEW(plugins.aboot), 0);
+	g_free(text);
+	decide_conf_button(plugin);
+}
+
+static void
+reset_plugin_window(GntWidget *window, gpointer null)
+{
+	plugins.window = NULL;
+	plugins.tree = NULL;
+	plugins.aboot = NULL;
+}
+
+static int
+plugin_compare(GaimPlugin *p1, GaimPlugin *p2)
+{
+	char *s1 = g_utf8_strup(p1->info->name, -1);
+	char *s2 = g_utf8_strup(p2->info->name, -1);
+	int ret = g_utf8_collate(s1, s2);
+	g_free(s1);
+	g_free(s2);
+	return ret;
+}
+
+static void
+confwin_init()
+{
+	confwins = g_hash_table_new(g_direct_hash, g_direct_equal);
+}
+
+static void
+remove_confwin(GntWidget *window, gpointer plugin)
+{
+	g_hash_table_remove(confwins, plugin);
+}
+
+static void
+configure_plugin_cb(GntWidget *button, gpointer null)
+{
+	GaimPlugin *plugin;
+	GGPluginFrame callback;
+
+	g_return_if_fail(plugins.tree != NULL);
+
+	plugin = gnt_tree_get_selection_data(GNT_TREE(plugins.tree));
+	if (!gaim_plugin_is_loaded(plugin))
+	{
+		gaim_notify_error(plugin, _("Error"),
+			_("Plugin need to be loaded before you can configure it."), NULL);
+		return;
+	}
+
+	if (confwins && g_hash_table_lookup(confwins, plugin))
+		return;
+
+	if (GAIM_IS_GNT_PLUGIN(plugin) &&
+			(callback = GAIM_GNT_PLUGIN_UI_INFO(plugin)) != NULL)
+	{
+		GntWidget *window = gnt_vbox_new(FALSE);
+		GntWidget *box, *button;
+
+		gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+		gnt_box_set_title(GNT_BOX(window), plugin->info->name);
+		gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+		box = callback();
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		box = gnt_hbox_new(FALSE);
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		button = gnt_button_new(_("Close"));
+		gnt_box_add_widget(GNT_BOX(box), button);
+		g_signal_connect_swapped(G_OBJECT(button), "activate",
+				G_CALLBACK(gnt_widget_destroy), window);
+		g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(remove_confwin), plugin);
+
+		gnt_widget_show(window);
+
+		if (confwins == NULL)
+			confwin_init();
+		g_hash_table_insert(confwins, plugin, window);
+	}
+	else if (plugin->info->prefs_info &&
+			plugin->info->prefs_info->get_plugin_pref_frame)
+	{
+		gaim_notify_info(plugin, _("..."),
+			_("Still need to do something about this."), NULL);
+		return;
+	}
+	else
+	{
+		gaim_notify_info(plugin, _("Error"),
+			_("No configuration options for this plugin."), NULL);
+		return;
+	}
+}
+
+void gg_plugins_show_all()
+{
+	GntWidget *window, *tree, *box, *aboot, *button;
+	GList *iter;
+	if (plugins.window)
+		return;
+
+	gaim_plugins_probe(G_MODULE_SUFFIX);
+
+	plugins.window = window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), _("Plugins"));
+	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new(_("You can (un)load plugins from the following list.")));
+	gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+	gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
+
+	gnt_box_set_pad(GNT_BOX(box), 0);
+	plugins.tree = tree = gnt_tree_new();
+	gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)plugin_compare);
+	GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
+	gnt_box_add_widget(GNT_BOX(box), tree);
+	gnt_box_add_widget(GNT_BOX(box), gnt_vline_new());
+
+	plugins.aboot = aboot = gnt_text_view_new();
+	gnt_widget_set_size(aboot, 40, 20);
+	gnt_box_add_widget(GNT_BOX(box), aboot);
+
+	for (iter = gaim_plugins_get_all(); iter; iter = iter->next)
+	{
+		GaimPlugin *plug = iter->data;
+
+		if (plug->info->type != GAIM_PLUGIN_STANDARD ||
+			(plug->info->flags & GAIM_PLUGIN_FLAG_INVISIBLE) ||
+			plug->error)
+			continue;
+
+		gnt_tree_add_choice(GNT_TREE(tree), plug,
+				gnt_tree_create_row(GNT_TREE(tree), plug->info->name), NULL, NULL);
+		gnt_tree_set_choice(GNT_TREE(tree), plug, gaim_plugin_is_loaded(plug));
+	}
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 30);
+	g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(plugin_toggled_cb), NULL);
+	g_signal_connect(G_OBJECT(tree), "selection_changed", G_CALLBACK(selection_changed), NULL);
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	button = gnt_button_new(_("Close"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate",
+			G_CALLBACK(gnt_widget_destroy), window);
+
+	plugins.conf = button = gnt_button_new(_("Configure Plugin"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(configure_plugin_cb), NULL);
+
+	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(reset_plugin_window), NULL);
+
+	gnt_widget_show(window);
+
+	decide_conf_button(gnt_tree_get_selection_data(GNT_TREE(tree)));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntplugin.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,71 @@
+/**
+ * @file gntplugin.h GNT Plugins API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_PLUGIN_H
+#define _GNT_PLUGIN_H
+
+#include <gnt.h>
+
+#include <plugin.h>
+
+#include <string.h>
+
+#include "gntgaim.h"
+
+/**********************************************************************
+ * @name GNT Plugins API
+ **********************************************************************/
+/*@{*/
+
+typedef GntWidget* (*GGPluginFrame) ();
+
+/* Guess where these came from */
+#define GAIM_GNT_PLUGIN_TYPE GAIM_GNT_UI
+
+/**
+ * Decide whether a plugin is a GNT-plugin.
+ */
+#define GAIM_IS_GNT_PLUGIN(plugin) \
+	((plugin)->info != NULL && (plugin)->info->ui_info != NULL && \
+	 !strcmp((plugin)->info->ui_requirement, GAIM_GNT_PLUGIN_TYPE))
+
+/**
+ * Get the ui-info from GNT-plugins.
+ */
+#define GAIM_GNT_PLUGIN_UI_INFO(plugin) \
+	(GGPluginFrame)((plugin)->info->ui_info)
+
+/**
+ * Show a list of plugins.
+ */
+void gg_plugins_show_all(void);
+
+/**
+ * Save the list of loaded plugins.
+ */
+void gg_plugins_save_loaded(void);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntprefs.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,226 @@
+/**
+ * @file gntprefs.c GNT Preferences API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <prefs.h>
+
+#include "gntgaim.h"
+#include "gntprefs.h"
+#include "gntrequest.h"
+
+#include <string.h>
+
+void gg_prefs_init()
+{
+	gaim_prefs_add_none("/gaim");
+	gaim_prefs_add_none("/gaim/gnt");
+
+	gaim_prefs_add_none("/gaim/gnt/plugins");
+	gaim_prefs_add_path_list("/gaim/gnt/plugins/loaded", NULL);
+
+	gaim_prefs_add_none("/gaim/gnt/conversations");
+	gaim_prefs_add_bool("/gaim/gnt/conversations/timestamps", TRUE);
+	gaim_prefs_add_bool("/gaim/gnt/conversations/notify_typing", FALSE); /* XXX: Not functional yet */
+}
+
+typedef struct
+{
+	GaimPrefType type;
+	const char *pref;
+	const char *label;
+	GList *(*lv)();   /* If the value is to be selected from a number of choices */
+} Prefs;
+
+static GList *
+get_log_options()
+{
+	return gaim_log_logger_get_options();
+}
+
+static GaimRequestField *
+get_pref_field(Prefs *prefs)
+{
+	GaimRequestField *field = NULL;
+
+	if (prefs->lv == NULL)
+	{
+		switch (prefs->type)
+		{
+			case GAIM_PREF_BOOLEAN:
+				field = gaim_request_field_bool_new(prefs->pref, _(prefs->label),
+						gaim_prefs_get_bool(prefs->pref));
+				break;
+			case GAIM_PREF_INT:
+				field = gaim_request_field_int_new(prefs->pref, _(prefs->label),
+						gaim_prefs_get_int(prefs->pref));
+				break;
+			case GAIM_PREF_STRING:
+				field = gaim_request_field_string_new(prefs->pref, _(prefs->label),
+						gaim_prefs_get_string(prefs->pref), FALSE);
+				break;
+			default:
+				break;
+		}
+	}
+	else
+	{
+		GList *list = prefs->lv(), *iter;
+		field = gaim_request_field_list_new(prefs->pref, _(prefs->label));
+		for (iter = list; iter; iter = iter->next)
+		{
+			gboolean select = FALSE;
+			const char *data = iter->data;
+			iter = iter->next;
+			switch (prefs->type)
+			{
+				case GAIM_PREF_BOOLEAN:
+					if (gaim_prefs_get_bool(prefs->pref) == GPOINTER_TO_INT(iter->data))
+						select = TRUE;
+					break;
+				case GAIM_PREF_INT:
+					if (gaim_prefs_get_int(prefs->pref) == GPOINTER_TO_INT(iter->data))
+						select = TRUE;
+					break;
+				case GAIM_PREF_STRING:
+					if (strcmp(gaim_prefs_get_string(prefs->pref), iter->data) == 0)
+						select = TRUE;
+					break;
+				default:
+					break;
+			}
+			gaim_request_field_list_add(field, data, iter->data);
+			if (select)
+				gaim_request_field_list_add_selected(field, data);
+		}
+		g_list_free(list);
+	}
+	return field;
+}
+
+static Prefs blist[] = 
+{
+	{GAIM_PREF_BOOLEAN, "/gaim/gnt/blist/idletime", N_("Show Idle Time"), NULL},
+	{GAIM_PREF_BOOLEAN, "/gaim/gnt/blist/showoffline", N_("Show Offline Buddies"), NULL},
+	{GAIM_PREF_NONE, NULL, NULL, NULL}
+};
+
+static Prefs convs[] = 
+{
+	{GAIM_PREF_BOOLEAN, "/gaim/gnt/conversations/timestamps", N_("Show Timestamps"), NULL},
+	{GAIM_PREF_BOOLEAN, "/gaim/gnt/conversations/notify_typing", N_("Notify buddies when you are typing"), NULL},
+	{GAIM_PREF_NONE, NULL, NULL, NULL}
+};
+
+static Prefs logging[] = 
+{
+	{GAIM_PREF_STRING, "/core/logging/format", N_("Log format"), get_log_options},
+	{GAIM_PREF_BOOLEAN, "/core/logging/log_ims", N_("Log IMs"), NULL},
+	{GAIM_PREF_BOOLEAN, "/core/logging/log_chats", N_("Log chats"), NULL},
+	{GAIM_PREF_BOOLEAN, "/core/logging/log_system", N_("Log status change events"), NULL},
+	{GAIM_PREF_NONE, NULL, NULL, NULL},
+};
+
+static void
+save_cb(void *data, GaimRequestFields *allfields)
+{
+	GList *list;
+	for (list = gaim_request_fields_get_groups(allfields); list; list = list->next)
+	{
+		GaimRequestFieldGroup *group = list->data;
+		GList *fields = gaim_request_field_group_get_fields(group);
+		
+		for (; fields ; fields = fields->next)
+		{
+			GaimRequestField *field = fields->data;
+			GaimRequestFieldType type = gaim_request_field_get_type(field);
+			GaimPrefType pt;
+			gpointer val = NULL;
+			const char *id = gaim_request_field_get_id(field);
+
+			switch (type)
+			{
+				case GAIM_REQUEST_FIELD_LIST:
+					val = gaim_request_field_list_get_selected(field)->data;
+					break;
+				case GAIM_REQUEST_FIELD_BOOLEAN:
+					val = GINT_TO_POINTER(gaim_request_field_bool_get_value(field));
+					break;
+				case GAIM_REQUEST_FIELD_INTEGER:
+					val = GINT_TO_POINTER(gaim_request_field_int_get_value(field));
+					break;
+				case GAIM_REQUEST_FIELD_STRING:
+					val = (gpointer)gaim_request_field_string_get_value(field);
+					break;
+				default:
+					break;
+			}
+
+			pt = gaim_prefs_get_type(id);
+			switch (pt)
+			{
+				case GAIM_PREF_INT:
+					gaim_prefs_set_int(id, GPOINTER_TO_INT(val));
+					break;
+				case GAIM_PREF_BOOLEAN:
+					gaim_prefs_set_bool(id, GPOINTER_TO_INT(val));
+					break;
+				case GAIM_PREF_STRING:
+					gaim_prefs_set_string(id, val);
+					break;
+				default:
+					break;
+			}
+		}
+	}
+}
+
+static void
+add_pref_group(GaimRequestFields *fields, const char *title, Prefs *prefs)
+{
+	GaimRequestField *field;
+	GaimRequestFieldGroup *group;
+	int i;
+
+	group = gaim_request_field_group_new(title);
+	gaim_request_fields_add_group(fields, group);
+	for (i = 0; prefs[i].pref; i++)
+	{
+		field = get_pref_field(prefs + i);
+		gaim_request_field_group_add_field(group, field);
+	}
+}
+
+void gg_prefs_show_all()
+{
+	GaimRequestFields *fields;
+
+	fields = gaim_request_fields_new();
+
+	add_pref_group(fields, _("Buddy List"), blist);
+	add_pref_group(fields, _("Conversations"), convs);
+	add_pref_group(fields, _("Logging"), logging);
+
+	gaim_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
+			_("Save"), G_CALLBACK(save_cb), _("Cancel"), NULL, NULL);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntprefs.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,45 @@
+/**
+ * @file gntprefs.h GNT Preferences API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_PREFS_H
+#define _GNT_PREFS_H
+
+/**********************************************************************
+ * @name GNT Preferences API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_prefs_init(void);
+
+/**
+ * Show the preferences dialog.
+ */
+void gg_prefs_show_all(void);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntrequest.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,536 @@
+/**
+ * @file gntrequest.c GNT Request API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntcheckbox.h>
+#include <gntcombobox.h>
+#include <gntentry.h>
+#include <gntlabel.h>
+#include <gntline.h>
+#include <gnttree.h>
+
+#include "gntgaim.h"
+#include "gntrequest.h"
+
+static GntWidget *
+setup_request_window(const char *title, const char *primary,
+		const char *secondary, GaimRequestType type)
+{
+	GntWidget *window;
+
+	window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), title);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+
+	if (primary)
+		gnt_box_add_widget(GNT_BOX(window),
+				gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD));
+	if (secondary)
+		gnt_box_add_widget(GNT_BOX(window), gnt_label_new(secondary));
+
+	g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gaim_request_close),
+			GINT_TO_POINTER(type));
+
+	return window;
+}
+
+static GntWidget *
+setup_button_box(gpointer userdata, gpointer cb, gpointer data, ...)
+{
+	GntWidget *box, *button;
+	va_list list;
+	const char *text;
+	gpointer callback;
+
+	box = gnt_hbox_new(FALSE);
+
+	va_start(list, data);
+
+	while ((text = va_arg(list, const char *)))
+	{
+		callback = va_arg(list, gpointer);
+		button = gnt_button_new(text);
+		gnt_box_add_widget(GNT_BOX(box), button);
+		g_object_set_data(G_OBJECT(button), "activate-callback", callback);
+		g_object_set_data(G_OBJECT(button), "activate-userdata", userdata);
+		g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(cb), data);
+	}
+
+	va_end(list);
+	return box;
+}
+
+static void
+notify_input_cb(GntWidget *button, GntWidget *entry)
+{
+	GaimRequestInputCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
+	gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
+	const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
+
+	if (callback)
+		callback(data, text);
+
+	while (button->parent)
+		button = button->parent;
+
+	gaim_request_close(GAIM_REQUEST_INPUT, button);
+}
+
+static void *
+gg_request_input(const char *title, const char *primary,
+		const char *secondary, const char *default_value,
+		gboolean multiline, gboolean masked, gchar *hint,
+		const char *ok_text, GCallback ok_cb,
+		const char *cancel_text, GCallback cancel_cb,
+		void *user_data)
+{
+	GntWidget *window, *box, *entry;
+
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_INPUT);
+
+	entry = gnt_entry_new(default_value);
+	if (masked)
+		gnt_entry_set_masked(GNT_ENTRY(entry), TRUE);
+	gnt_box_add_widget(GNT_BOX(window), entry);
+
+	box = setup_button_box(user_data, notify_input_cb, entry,
+			ok_text, ok_cb, cancel_text, cancel_cb, NULL);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	gnt_widget_show(window);
+
+	return window;
+}
+
+static void
+gg_close_request(GaimRequestType type, gpointer ui_handle)
+{
+	GntWidget *widget = GNT_WIDGET(ui_handle);
+	while (widget->parent)
+		widget = widget->parent;
+	gnt_widget_destroy(widget);
+}
+
+static void
+request_choice_cb(GntWidget *button, GntComboBox *combo)
+{
+	GaimRequestChoiceCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
+	gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
+	int choice = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))) - 1;
+
+	if (callback)
+		callback(data, choice);
+
+	while (button->parent)
+		button = button->parent;
+
+	gaim_request_close(GAIM_REQUEST_INPUT, button);
+}
+
+static void *
+gg_request_choice(const char *title, const char *primary,
+		const char *secondary, unsigned int default_value,
+		const char *ok_text, GCallback ok_cb,
+		const char *cancel_text, GCallback cancel_cb,
+		void *user_data, va_list choices)
+{
+	GntWidget *window, *combo, *box;
+	const char *text;
+	int val;
+
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_CHOICE);
+
+	combo = gnt_combo_box_new();
+	gnt_box_add_widget(GNT_BOX(window), combo);
+	while ((text = va_arg(choices, const char *)))
+	{
+		val = va_arg(choices, int);
+		gnt_combo_box_add_data(GNT_COMBO_BOX(combo), GINT_TO_POINTER(val + 1), text);
+	}
+	gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), GINT_TO_POINTER(default_value + 1));
+
+	box = setup_button_box(user_data, request_choice_cb, combo,
+			ok_text, ok_cb, cancel_text, cancel_cb, NULL);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	gnt_widget_show(window);
+	
+	return window;
+}
+
+static void
+request_action_cb(GntWidget *button, GntWidget *window)
+{
+	GaimRequestActionCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
+	gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
+	int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "activate-id"));
+
+	if (callback)
+		callback(data, id);
+
+	gaim_request_close(GAIM_REQUEST_ACTION, window);
+}
+
+static void*
+gg_request_action(const char *title, const char *primary,
+		const char *secondary, unsigned int default_value,
+		void *user_data, size_t actioncount,
+		va_list actions)
+{
+	GntWidget *window, *box, *button;
+	int i;
+
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_ACTION);
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+	for (i = 0; i < actioncount; i++)
+	{
+		const char *text = va_arg(actions, const char *);
+		GaimRequestActionCb callback = va_arg(actions, GaimRequestActionCb);
+
+		button = gnt_button_new(text);
+		gnt_box_add_widget(GNT_BOX(box), button);
+
+		g_object_set_data(G_OBJECT(button), "activate-callback", callback);
+		g_object_set_data(G_OBJECT(button), "activate-userdata", user_data);
+		g_object_set_data(G_OBJECT(button), "activate-id", GINT_TO_POINTER(i));
+		g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(request_action_cb), window);
+	}
+
+	gnt_widget_show(window);
+
+	return window;
+}
+
+static void
+request_fields_cb(GntWidget *button, GaimRequestFields *fields)
+{
+	GaimRequestFieldsCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
+	gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
+	GList *list;
+
+	/* Update the data of the fields. GtkGaim does this differently. Instead of
+	 * updating the fields at the end like here, it updates the appropriate field
+	 * instantly whenever a change is made. That allows it to make sure the
+	 * 'required' fields are entered before the user can hit OK. It's not the case
+	 * here, althought it can be done. I am not honouring the 'required' fields
+	 * for the moment. */
+	for (list = gaim_request_fields_get_groups(fields); list; list = list->next)
+	{
+		GaimRequestFieldGroup *group = list->data;
+		GList *fields = gaim_request_field_group_get_fields(group);
+		
+		for (; fields ; fields = fields->next)
+		{
+			GaimRequestField *field = fields->data;
+			GaimRequestFieldType type = gaim_request_field_get_type(field);
+			if (type == GAIM_REQUEST_FIELD_BOOLEAN)
+			{
+				GntWidget *check = field->ui_data;
+				gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(check));
+				gaim_request_field_bool_set_value(field, value);
+			}
+			else if (type == GAIM_REQUEST_FIELD_STRING)
+			{
+				GntWidget *entry = field->ui_data;
+				const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
+				gaim_request_field_string_set_value(field, (text && *text) ? text : NULL);
+			}
+			else if (type == GAIM_REQUEST_FIELD_INTEGER)
+			{
+				GntWidget *entry = field->ui_data;
+				const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
+				int value = (text && *text) ? atoi(text) : 0;
+				gaim_request_field_int_set_value(field, value);
+			}
+			else if (type == GAIM_REQUEST_FIELD_CHOICE)
+			{
+				GntWidget *combo = field->ui_data;
+				int id;
+				id = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)));
+				gaim_request_field_choice_set_value(field, id);
+			}
+			else if (type == GAIM_REQUEST_FIELD_LIST)
+			{
+				GList *list = NULL;
+				if (gaim_request_field_list_get_multi_select(field))
+				{
+					const GList *iter;
+					GntWidget *tree = field->ui_data;
+
+					iter = gaim_request_field_list_get_items(field);
+					for (; iter; iter = iter->next)
+					{
+						const char *text = iter->data;
+						gpointer key = gaim_request_field_list_get_data(field, text);
+						if (gnt_tree_get_choice(GNT_TREE(tree), key))
+							list = g_list_prepend(list, key);
+					}
+				}
+				else
+				{
+					GntWidget *combo = field->ui_data;
+					gpointer data = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
+					list = g_list_append(list, data);
+				}
+
+				gaim_request_field_list_set_selected(field, list);
+				g_list_free(list);
+			}
+			else if (type == GAIM_REQUEST_FIELD_ACCOUNT)
+			{
+				GntWidget *combo = field->ui_data;
+				GaimAccount *acc = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
+				gaim_request_field_account_set_value(field, acc);
+			}
+		}
+	}
+
+	if (callback)
+		callback(data, fields);
+
+	while (button->parent)
+		button = button->parent;
+
+	gaim_request_close(GAIM_REQUEST_FIELDS, button);
+}
+
+static void *
+gg_request_fields(const char *title, const char *primary,
+		const char *secondary, GaimRequestFields *allfields,
+		const char *ok, GCallback ok_cb,
+		const char *cancel, GCallback cancel_cb,
+		void *userdata)
+{
+	GntWidget *window, *box;
+	GList *grlist;
+
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_FIELDS);
+
+	/* This is how it's going to work: the request-groups are going to be
+	 * stacked vertically one after the other. A GntLine will be separating
+	 * the groups. */
+	box = gnt_vbox_new(FALSE);
+	gnt_box_set_pad(GNT_BOX(box), 0);
+	gnt_box_set_fill(GNT_BOX(box), TRUE);
+	for (grlist = gaim_request_fields_get_groups(allfields); grlist; grlist = grlist->next)
+	{
+		GaimRequestFieldGroup *group = grlist->data;
+		GList *fields = gaim_request_field_group_get_fields(group);
+		GntWidget *hbox;
+		const char *title = gaim_request_field_group_get_title(group);
+
+		if (title)
+			gnt_box_add_widget(GNT_BOX(box),
+					gnt_label_new_with_format(title, GNT_TEXT_FLAG_BOLD));
+
+		for (; fields ; fields = fields->next)
+		{
+			/* XXX: Break each of the fields into a separate function? */
+			GaimRequestField *field = fields->data;
+			GaimRequestFieldType type = gaim_request_field_get_type(field);
+			const char *label = gaim_request_field_get_label(field);
+				
+			hbox = gnt_hbox_new(TRUE);   /* hrm */
+			gnt_box_add_widget(GNT_BOX(box), hbox);
+			
+			if (type != GAIM_REQUEST_FIELD_BOOLEAN && label)
+			{
+				GntWidget *l = gnt_label_new(label);
+				gnt_widget_set_size(l, 0, 1);
+				gnt_box_add_widget(GNT_BOX(hbox), l);
+			}
+
+			if (type == GAIM_REQUEST_FIELD_BOOLEAN)
+			{
+				GntWidget *check = gnt_check_box_new(label);
+				gnt_check_box_set_checked(GNT_CHECK_BOX(check),
+						gaim_request_field_bool_get_default_value(field));
+				gnt_box_add_widget(GNT_BOX(hbox), check);
+				field->ui_data = check;
+			}
+			else if (type == GAIM_REQUEST_FIELD_STRING)
+			{
+				GntWidget *entry = gnt_entry_new(
+							gaim_request_field_string_get_default_value(field));
+				gnt_entry_set_masked(GNT_ENTRY(entry),
+						gaim_request_field_string_is_masked(field));
+				gnt_box_add_widget(GNT_BOX(hbox), entry);
+				field->ui_data = entry;
+			}
+			else if (type == GAIM_REQUEST_FIELD_INTEGER)
+			{
+				char str[256];
+				int val = gaim_request_field_int_get_default_value(field);
+				GntWidget *entry;
+				
+				snprintf(str, sizeof(str), "%d", val);
+				entry = gnt_entry_new(str);
+				gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT);
+				gnt_box_add_widget(GNT_BOX(hbox), entry);
+				field->ui_data = entry;
+			}
+			else if (type == GAIM_REQUEST_FIELD_CHOICE)
+			{
+				int id;
+				const GList *list;
+				GntWidget *combo = gnt_combo_box_new();
+				gnt_box_add_widget(GNT_BOX(hbox), combo);
+				field->ui_data = combo;
+
+				list = gaim_request_field_choice_get_labels(field);
+				for (id = 1; list; list = list->next, id++)
+				{
+					gnt_combo_box_add_data(GNT_COMBO_BOX(combo),
+							GINT_TO_POINTER(id), list->data);
+				}
+				gnt_combo_box_set_selected(GNT_COMBO_BOX(combo),
+						GINT_TO_POINTER(gaim_request_field_choice_get_default_value(field)));
+			}
+			else if (type == GAIM_REQUEST_FIELD_LIST)
+			{
+				const GList *list;
+				gboolean multi = gaim_request_field_list_get_multi_select(field);
+				if (multi)
+				{
+					GntWidget *tree = gnt_tree_new();
+					gnt_box_add_widget(GNT_BOX(hbox), tree);
+					field->ui_data = tree;
+
+					list = gaim_request_field_list_get_items(field);
+					for (; list; list = list->next)
+					{
+						const char *text = list->data;
+						gpointer key = gaim_request_field_list_get_data(field, text);
+						gnt_tree_add_choice(GNT_TREE(tree), key,
+								gnt_tree_create_row(GNT_TREE(tree), text), NULL, NULL);
+						if (gaim_request_field_list_is_selected(field, text))
+							gnt_tree_set_choice(GNT_TREE(tree), key, TRUE);
+					}
+				}
+				else
+				{
+					GntWidget *combo = gnt_combo_box_new();
+					gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+					gnt_box_add_widget(GNT_BOX(hbox), combo);
+					field->ui_data = combo;
+
+					list = gaim_request_field_list_get_items(field);
+					for (; list; list = list->next)
+					{
+						const char *text = list->data;
+						gpointer key = gaim_request_field_list_get_data(field, text);
+						gnt_combo_box_add_data(GNT_COMBO_BOX(combo), key, text);
+						if (gaim_request_field_list_is_selected(field, text))
+							gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), key);
+					}
+				}
+			}
+			else if (type == GAIM_REQUEST_FIELD_ACCOUNT)
+			{
+				gboolean all;
+				GaimAccount *def;
+				GList *list;
+				GntWidget *combo = gnt_combo_box_new();
+				gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+				gnt_box_add_widget(GNT_BOX(hbox), combo);
+				field->ui_data = combo;
+
+				all = gaim_request_field_account_get_show_all(field);
+				def = gaim_request_field_account_get_default_value(field);
+
+				if (all)
+					list = gaim_accounts_get_all();
+				else
+					list = gaim_connections_get_all();
+
+				for (; list; list = list->next)
+				{
+					GaimAccount *account;
+					char *text;
+
+					if (all)
+						account = list->data;
+					else
+						account = gaim_connection_get_account(list->data);
+
+					text = g_strdup_printf("%s (%s)",
+							gaim_account_get_username(account),
+							gaim_account_get_protocol_name(account));
+					gnt_combo_box_add_data(GNT_COMBO_BOX(combo), account, text);
+					g_free(text);
+					if (account == def)
+						gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), account);
+				}
+				gnt_widget_set_size(combo, 20, 3); /* ew */
+			}
+			else
+			{
+				gnt_box_add_widget(GNT_BOX(hbox),
+						gnt_label_new_with_format(_("Not implemented yet."),
+							GNT_TEXT_FLAG_BOLD));
+			}
+		}
+		if (grlist->next)
+			gnt_box_add_widget(GNT_BOX(box), gnt_hline_new());
+	}
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	box = setup_button_box(userdata, request_fields_cb, allfields,
+			ok, ok_cb, cancel, cancel_cb, NULL);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	gnt_widget_show(window);
+	
+	return window;
+}
+
+static GaimRequestUiOps uiops =
+{
+	.request_input = gg_request_input,
+	.close_request = gg_close_request,
+	.request_choice = gg_request_choice,
+	.request_action = gg_request_action,
+	.request_fields = gg_request_fields,
+	.request_file = NULL,                  /* No plans for these */
+	.request_folder = NULL
+};
+
+GaimRequestUiOps *gg_request_get_ui_ops()
+{
+	return &uiops;
+}
+
+void gg_request_init()
+{
+}
+
+void gg_request_uninit()
+{
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntrequest.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,54 @@
+/**
+ * @file gntrequest.h GNT Request API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_REQUEST_H
+#define _GNT_REQUEST_H
+
+#include "request.h"
+
+/**********************************************************************
+ * @name GNT Request API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Get the ui-functions.
+ *
+ * @return The GaimRequestUiOps structure populated with the appropriate functions.
+ */
+GaimRequestUiOps *gg_request_get_ui_ops(void);
+
+/**
+ * Perform necessary initializations.
+ */
+void gg_request_init(void);
+
+/**
+ * Perform necessary uninitializations.
+ */
+void gg_request_uninit(void);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntstatus.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,606 @@
+/**
+ * @file gntstatus.c GNT Status API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntcombobox.h>
+#include <gntentry.h>
+#include <gntlabel.h>
+#include <gntline.h>
+#include <gnttree.h>
+
+#include <notify.h>
+#include <request.h>
+
+#include "gntgaim.h"
+#include "gntstatus.h"
+
+static struct
+{
+	GntWidget *window;
+	GntWidget *tree;
+} statuses;
+
+typedef struct
+{
+	GaimSavedStatus *saved;
+	GntWidget *window;
+	GntWidget *title;
+	GntWidget *type;
+	GntWidget *message;
+	GntWidget *tree;
+	GHashTable *hash;  /* list of windows for substatuses */
+} EditStatus;
+
+typedef struct
+{
+	GaimAccount *account;
+	const GaimStatusType *type;
+	char *message;
+} RowInfo;
+
+typedef struct
+{
+	GntWidget *window;
+	GntWidget *type;
+	GntWidget *message;
+
+	EditStatus *parent;
+	RowInfo *key;
+} EditSubStatus;
+
+static GList *edits;  /* List of opened edit-status dialogs */
+
+static void
+reset_status_window(GntWidget *widget, gpointer null)
+{
+	statuses.window = NULL;
+	statuses.tree = NULL;
+}
+
+static void
+populate_statuses(GntTree *tree)
+{
+	const GList *list;
+
+	for (list = gaim_savedstatuses_get_all(); list; list = list->next)
+	{
+		GaimSavedStatus *saved = list->data;
+		const char *title, *type, *message;
+
+		if (gaim_savedstatus_is_transient(saved))
+			continue;
+
+		title = gaim_savedstatus_get_title(saved);
+		type = gaim_primitive_get_name_from_type(gaim_savedstatus_get_type(saved));
+		message = gaim_savedstatus_get_message(saved);  /* XXX: Strip possible markups */
+
+		gnt_tree_add_row_last(tree, saved,
+				gnt_tree_create_row(tree, title, type, message), NULL);
+	}
+}
+
+static void
+really_delete_status(GaimSavedStatus *saved)
+{
+	GList *iter;
+
+	for (iter = edits; iter; iter = iter->next)
+	{
+		EditStatus *edit = iter->data;
+		if (edit->saved == saved)
+		{
+			gnt_widget_destroy(edit->window);
+			break;
+		}
+	}
+
+	if (statuses.tree)
+		gnt_tree_remove(GNT_TREE(statuses.tree), saved);
+
+	gaim_savedstatus_delete(gaim_savedstatus_get_title(saved));
+}
+
+static void
+ask_before_delete(GntWidget *button, gpointer null)
+{
+	char *ask;
+	GaimSavedStatus *saved;
+
+	g_return_if_fail(statuses.tree != NULL);
+
+	saved = gnt_tree_get_selection_data(GNT_TREE(statuses.tree));
+	ask = g_strdup_printf(_("Are you sure you want to delete \"%s\""),
+			gaim_savedstatus_get_title(saved));
+
+	gaim_request_action(saved, _("Delete Status"), ask, NULL, 0, saved, 2,
+			_("Delete"), really_delete_status, _("Cancel"), NULL);
+	g_free(ask);
+}
+
+static void
+use_savedstatus_cb(GntWidget *widget, gpointer null)
+{
+	g_return_if_fail(statuses.tree != NULL);
+
+	gaim_savedstatus_activate(gnt_tree_get_selection_data(GNT_TREE(statuses.tree)));
+}
+
+static void
+edit_savedstatus_cb(GntWidget *widget, gpointer null)
+{
+	g_return_if_fail(statuses.tree != NULL);
+
+	gg_savedstatus_edit(gnt_tree_get_selection_data(GNT_TREE(statuses.tree)));
+}
+
+void gg_savedstatus_show_all()
+{
+	GntWidget *window, *tree, *box, *button;
+	if (statuses.window)
+		return;
+
+	statuses.window = window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), _("Saved Statuses"));
+	gnt_box_set_fill(GNT_BOX(window), FALSE);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+
+	/* XXX: Add some sorting function to sort alphabetically, perhaps */
+	statuses.tree = tree = gnt_tree_new_with_columns(3);
+	gnt_tree_set_column_titles(GNT_TREE(tree), _("Title"), _("Type"), _("Message"));
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 25);
+	gnt_tree_set_col_width(GNT_TREE(tree), 1, 12);
+	gnt_tree_set_col_width(GNT_TREE(tree), 2, 35);
+	gnt_box_add_widget(GNT_BOX(window), tree);
+
+	populate_statuses(GNT_TREE(tree));
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	button = gnt_button_new(_("Use"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate",
+			G_CALLBACK(use_savedstatus_cb), NULL);
+
+	button = gnt_button_new(_("Add"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate",
+			G_CALLBACK(gg_savedstatus_edit), NULL);
+
+	button = gnt_button_new(_("Edit"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate",
+			G_CALLBACK(edit_savedstatus_cb), NULL);
+
+	button = gnt_button_new(_("Delete"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate",
+			G_CALLBACK(ask_before_delete), NULL);
+
+	button = gnt_button_new(_("Close"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate",
+			G_CALLBACK(gnt_widget_destroy), window);
+
+	g_signal_connect(G_OBJECT(window), "destroy",
+			G_CALLBACK(reset_status_window), NULL);
+	gnt_widget_show(window);
+}
+
+static void
+destroy_substatus_win(GaimAccount *account, EditSubStatus *sub, gpointer null)
+{
+	gnt_widget_destroy(sub->window);   /* the "destroy" callback will remove entry from the hashtable */
+}
+
+static void
+free_key(gpointer key, gpointer n)
+{
+	RowInfo *row = key;
+	g_free(row->message);
+	g_free(key);
+}
+
+
+static void
+update_edit_list(GntWidget *widget, EditStatus *edit)
+{
+	edits = g_list_remove(edits, edit);
+	gaim_notify_close_with_handle(edit);
+	g_hash_table_foreach(edit->hash, (GHFunc)destroy_substatus_win, NULL);
+	g_list_foreach((GList*)gnt_tree_get_rows(GNT_TREE(edit->tree)), free_key, NULL);
+	g_free(edit);
+}
+
+static void
+set_substatuses(EditStatus *edit)
+{
+	const GList *iter;
+	for (iter = gnt_tree_get_rows(GNT_TREE(edit->tree)); iter; iter = iter->next) {
+		RowInfo *key = iter->data;
+		if (gnt_tree_get_choice(GNT_TREE(edit->tree), key)) {
+			gaim_savedstatus_set_substatus(edit->saved, key->account, key->type, key->message);
+		}
+	}
+}
+
+
+static void
+use_trans_status_cb(GntWidget *button, EditStatus *edit)
+{
+	const char *message;
+	GaimStatusPrimitive prim;
+	GaimSavedStatus *saved;
+
+	message = gnt_entry_get_text(GNT_ENTRY(edit->message));
+	prim = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(edit->type)));
+
+	saved = gaim_savedstatus_find_transient_by_type_and_message(prim, message);
+	if (saved == NULL) {
+		saved = gaim_savedstatus_new(NULL, prim);
+		edit->saved = saved;
+		set_substatuses(edit);
+	}
+	gaim_savedstatus_set_message(saved, message);
+	gaim_savedstatus_activate(saved);
+	gnt_widget_destroy(edit->window);
+}
+
+static void
+save_savedstatus_cb(GntWidget *button, EditStatus *edit)
+{
+	const char *title, *message;
+	GaimStatusPrimitive prim;
+	GaimSavedStatus *find;
+
+	title = gnt_entry_get_text(GNT_ENTRY(edit->title));
+	message = gnt_entry_get_text(GNT_ENTRY(edit->message));
+	if (!message || !*message)
+		message = NULL;
+
+	prim = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(edit->type)));
+
+	if (!title || !*title)
+	{
+		gaim_notify_error(edit, _("Error"), _("Invalid title"),
+				_("Please enter a non-empty title for the status."));
+		return;
+	}
+
+	find = gaim_savedstatus_find(title);
+	if (find && find != edit->saved)
+	{
+		gaim_notify_error(edit, _("Error"), _("Duplicate title"),
+				_("Please enter a different title for the status."));
+		return;
+	}
+	
+	if (edit->saved == NULL)
+	{
+		edit->saved = gaim_savedstatus_new(title, prim);
+		gaim_savedstatus_set_message(edit->saved, message);
+		set_substatuses(edit);
+		if (statuses.tree)
+			gnt_tree_add_row_last(GNT_TREE(statuses.tree), edit->saved,
+					gnt_tree_create_row(GNT_TREE(statuses.tree), title,
+						gaim_primitive_get_name_from_type(prim), message), NULL);
+	}
+	else
+	{
+		gaim_savedstatus_set_title(edit->saved, title);
+		gaim_savedstatus_set_type(edit->saved, prim);
+		gaim_savedstatus_set_message(edit->saved, message);
+		if (statuses.tree)
+		{
+			gnt_tree_change_text(GNT_TREE(statuses.tree), edit->saved, 0, title);
+			gnt_tree_change_text(GNT_TREE(statuses.tree), edit->saved, 1,
+						gaim_primitive_get_name_from_type(prim));
+			gnt_tree_change_text(GNT_TREE(statuses.tree), edit->saved, 2, message);
+		}
+	}
+
+	if (g_object_get_data(G_OBJECT(button), "use"))
+		gaim_savedstatus_activate(edit->saved);
+
+	gnt_widget_destroy(edit->window);
+}
+
+static void
+add_substatus(EditStatus *edit, GaimAccount *account)
+{
+	char *name;
+	const char *type = NULL, *message = NULL;
+	GaimSavedStatusSub *sub = NULL;
+	RowInfo *key;
+
+	if (!edit || !edit->tree)
+		return;
+
+	if (edit->saved)
+		sub = gaim_savedstatus_get_substatus(edit->saved, account);
+
+	key = g_new0(RowInfo, 1);
+	key->account = account;
+
+	if (sub)
+	{
+		key->type = gaim_savedstatus_substatus_get_type(sub);
+		type = gaim_status_type_get_name(key->type);
+		message = gaim_savedstatus_substatus_get_message(sub);
+		key->message = g_strdup(message);
+	}
+
+	name = g_strdup_printf("%s (%s)", gaim_account_get_username(account),
+			gaim_account_get_protocol_name(account));
+	gnt_tree_add_choice(GNT_TREE(edit->tree), key,
+			gnt_tree_create_row(GNT_TREE(edit->tree),
+				name, type ? type : "", message ? message : ""), NULL, NULL);
+
+	if (sub)
+		gnt_tree_set_choice(GNT_TREE(edit->tree), key, TRUE);
+	g_free(name);
+}
+
+static void
+substatus_window_destroy_cb(GntWidget *window, EditSubStatus *sub)
+{
+	g_hash_table_remove(sub->parent->hash, sub->key->account);
+	g_free(sub);
+}
+
+static void
+save_substatus_cb(GntWidget *widget, EditSubStatus *sub)
+{
+	GaimSavedStatus *saved = sub->parent->saved;
+	RowInfo *row = sub->key;
+	const char *message;
+	GaimStatusType *type;
+
+	type = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(sub->type));
+	message = gnt_entry_get_text(GNT_ENTRY(sub->message));
+
+	row->type = type;
+	row->message = g_strdup(message);
+
+	if (saved)    /* Save the substatus if the savedstatus actually exists. */
+		gaim_savedstatus_set_substatus(saved, row->account, type, message);
+
+	gnt_tree_set_choice(GNT_TREE(sub->parent->tree), row, TRUE);
+	gnt_tree_change_text(GNT_TREE(sub->parent->tree), row, 1,
+			gaim_status_type_get_name(type));
+	gnt_tree_change_text(GNT_TREE(sub->parent->tree), row, 2, message);
+	
+	gnt_widget_destroy(sub->window);
+}
+
+static gboolean
+popup_substatus(GntTree *tree, const char *key, EditStatus *edit)
+{
+	if (key[0] == ' ' && key[1] == 0)
+	{
+		EditSubStatus *sub;
+		GntWidget *window, *combo, *entry, *box, *button, *l;
+		GaimSavedStatusSub *substatus = NULL;
+		const GList *iter;
+		char *name;
+		RowInfo *selected = gnt_tree_get_selection_data(tree);
+		GaimAccount *account = selected->account;
+
+		if (gnt_tree_get_choice(tree, selected))
+		{
+			/* There was a savedstatus for this account. Now remove it. */
+			g_free(selected->message);
+			selected->type = NULL;
+			selected->message = NULL;
+			/* XXX: should we really be saving it right now? */
+			gaim_savedstatus_unset_substatus(edit->saved, account);
+			gnt_tree_change_text(tree, account, 1, NULL);
+			gnt_tree_change_text(tree, account, 2, NULL);
+			return FALSE;
+		}
+
+		if (g_hash_table_lookup(edit->hash, account))
+			return TRUE;
+
+		if (edit->saved)
+			substatus = gaim_savedstatus_get_substatus(edit->saved, account);
+
+		sub = g_new0(EditSubStatus, 1);
+		sub->parent = edit;
+		sub->key = selected;
+
+		sub->window = window = gnt_vbox_new(FALSE);
+		gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+		gnt_box_set_title(GNT_BOX(window), _("Substatus"));  /* XXX: a better title */
+
+		box = gnt_hbox_new(FALSE);
+		gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Account:")));
+		name = g_strdup_printf("%s (%s)", gaim_account_get_username(account),
+				gaim_account_get_protocol_name(account));
+		gnt_box_add_widget(GNT_BOX(box), gnt_label_new(name));
+		g_free(name);
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		box = gnt_hbox_new(FALSE);
+		gnt_box_add_widget(GNT_BOX(box), (l = gnt_label_new(_("Status:"))));
+		gnt_widget_set_size(l, 0, 1);   /* I don't like having to do this */
+		sub->type = combo = gnt_combo_box_new();
+		gnt_box_add_widget(GNT_BOX(box), combo);
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		for (iter = gaim_account_get_status_types(account); iter; iter = iter->next)
+		{
+			GaimStatusType *type = iter->data;
+			if (!gaim_status_type_is_user_settable(type))
+				continue;
+			gnt_combo_box_add_data(GNT_COMBO_BOX(combo), type, gaim_status_type_get_name(type));
+		}
+
+		box = gnt_hbox_new(FALSE);
+		gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Message:")));
+		sub->message = entry = gnt_entry_new(substatus ? gaim_savedstatus_substatus_get_message(substatus) : NULL);
+		gnt_box_add_widget(GNT_BOX(box), entry);
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		box  = gnt_hbox_new(FALSE);
+		button = gnt_button_new(_("Cancel"));
+		g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), window);
+		gnt_box_add_widget(GNT_BOX(box), button);
+		button = gnt_button_new(_("Save"));
+		g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(save_substatus_cb), sub);
+		gnt_box_add_widget(GNT_BOX(box), button);
+		gnt_box_add_widget(GNT_BOX(window), box);
+
+		gnt_widget_show(window);
+
+		g_hash_table_insert(edit->hash, account, sub);
+
+		g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(substatus_window_destroy_cb), sub);
+
+		return TRUE;
+	}
+	return FALSE;
+}
+
+void gg_savedstatus_edit(GaimSavedStatus *saved)
+{
+	EditStatus *edit;
+	GntWidget *window, *box, *button, *entry, *combo, *label, *tree;
+	GaimStatusPrimitive prims[] = {GAIM_STATUS_AVAILABLE, GAIM_STATUS_AWAY,
+		GAIM_STATUS_INVISIBLE, GAIM_STATUS_OFFLINE, GAIM_STATUS_UNSET}, current;
+	GList *iter;
+	int i;
+
+	if (saved)
+	{
+		GList *iter;
+		for (iter = edits; iter; iter = iter->next)
+		{
+			edit = iter->data;
+			if (edit->saved == saved)
+				return;
+		}
+	}
+
+	edit = g_new0(EditStatus, 1);
+	edit->saved = saved;
+	edit->window = window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+	gnt_box_set_title(GNT_BOX(window), _("Edit Status"));
+	gnt_box_set_fill(GNT_BOX(window), TRUE);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_LEFT);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+
+	edits = g_list_append(edits, edit);
+
+	/* Title */
+	box = gnt_hbox_new(FALSE);
+	gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_LEFT);
+	gnt_box_add_widget(GNT_BOX(window), box);
+	gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Title")));
+
+	edit->title = entry = gnt_entry_new(saved ? gaim_savedstatus_get_title(saved) : NULL);
+	gnt_box_add_widget(GNT_BOX(box), entry);
+
+	/* Type */
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+	gnt_box_add_widget(GNT_BOX(box), label = gnt_label_new(_("Status")));
+	gnt_widget_set_size(label, 0, 1);
+
+	edit->type = combo = gnt_combo_box_new();
+	gnt_box_add_widget(GNT_BOX(box), combo);
+	current = saved ? gaim_savedstatus_get_type(saved) : GAIM_STATUS_UNSET;
+	for (i = 0; prims[i] != GAIM_STATUS_UNSET; i++)
+	{
+		gnt_combo_box_add_data(GNT_COMBO_BOX(combo), GINT_TO_POINTER(prims[i]),
+				gaim_primitive_get_name_from_type(prims[i]));
+		if (prims[i] == current)
+			gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), GINT_TO_POINTER(current));
+	}
+
+	/* Message */
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+	gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Message")));
+
+	edit->message = entry = gnt_entry_new(saved ? gaim_savedstatus_get_message(saved) : NULL);
+	gnt_box_add_widget(GNT_BOX(window), entry);
+
+	gnt_box_add_widget(GNT_BOX(window), gnt_hline_new());
+	gnt_box_add_widget(GNT_BOX(window), gnt_label_new(_("Use different status for following accounts")));
+
+	edit->hash = g_hash_table_new(g_direct_hash, g_direct_equal);
+	edit->tree = tree = gnt_tree_new_with_columns(3);
+	gnt_box_add_widget(GNT_BOX(window), tree);
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+	gnt_tree_set_column_titles(GNT_TREE(tree), _("Account"), _("Status"), _("Message"));
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 30);
+	gnt_tree_set_col_width(GNT_TREE(tree), 1, 10);
+	gnt_tree_set_col_width(GNT_TREE(tree), 2, 30);
+
+	for (iter = gaim_accounts_get_all(); iter; iter = iter->next)
+	{
+		add_substatus(edit, iter->data);
+	}
+
+	g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(popup_substatus), edit);
+
+	/* The buttons */
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	/* Use */
+	button = gnt_button_new(_("Use"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(use_trans_status_cb), edit);
+
+	/* Save */
+	button = gnt_button_new(_("Save"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_object_set_data(G_OBJECT(button), "use", NULL);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(save_savedstatus_cb), edit);
+
+	/* Save & Use */
+	button = gnt_button_new(_("Save & Use"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_object_set_data(G_OBJECT(button), "use", GINT_TO_POINTER(TRUE));
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(save_savedstatus_cb), edit);
+
+	/* Cancel */
+	button = gnt_button_new(_("Cancel"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate",
+			G_CALLBACK(gnt_widget_destroy), window);
+
+	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(update_edit_list), edit);
+
+	gnt_widget_show(window);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntstatus.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,50 @@
+/**
+ * @file gntstatus.h GNT Status API
+ * @ingroup gntui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_STATUS_H
+#define _GNT_STATUS_H
+
+#include <status.h>
+#include <savedstatuses.h>
+
+/**********************************************************************
+ * @name GNT BuddyList API
+ **********************************************************************/
+/*@{*/
+
+/**
+ * Show a dialog with all the saved statuses.
+ */
+void gg_savedstatus_show_all(void);
+
+/**
+ * Show a dialog to edit a status.
+ *
+ * @param saved The saved status to edit. Set it to @c NULL to create a new status.
+ */
+void gg_savedstatus_edit(GaimSavedStatus *saved);
+
+/*@}*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntui.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,105 @@
+/**
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 "gntui.h"
+
+#include "gntaccount.h"
+#include "gntblist.h"
+#include "gntconn.h"
+#include "gntconv.h"
+#include "gntdebug.h"
+#include "gntnotify.h"
+#include "gntplugin.h"
+#include "gntprefs.h"
+#include "gntrequest.h"
+#include "gntstatus.h"
+
+#include "internal.h"
+
+#include <prefs.h>
+
+void gnt_ui_init()
+{
+#ifdef STANDALONE
+	gnt_init();
+#endif
+
+	gaim_prefs_add_none("/gaim/gnt");
+	
+	/* Accounts */
+	gg_accounts_init();
+	gaim_accounts_set_ui_ops(gg_accounts_get_ui_ops());
+
+	/* Connections */
+	gg_connections_init();
+	gaim_connections_set_ui_ops(gg_connections_get_ui_ops());
+
+	/* Initialize the buddy list */
+	gg_blist_init();
+	gaim_blist_set_ui_ops(gg_blist_get_ui_ops());
+
+	/* Now the conversations */
+	gg_conversation_init();
+	gaim_conversations_set_ui_ops(gg_conv_get_ui_ops());
+
+	/* Notify */
+	gg_notify_init();
+	gaim_notify_set_ui_ops(gg_notify_get_ui_ops());
+
+	gg_request_init();
+	gaim_request_set_ui_ops(gg_request_get_ui_ops());
+
+	gnt_register_action(_("Accounts"), gg_accounts_show_all);
+	gnt_register_action(_("Buddy List"), gg_blist_show);
+	gnt_register_action(_("Debug Window"), gg_debug_window_show);
+	gnt_register_action(_("Plugins"), gg_plugins_show_all);
+	gnt_register_action(_("Preferences"), gg_prefs_show_all);
+	gnt_register_action(_("Statuses"), gg_savedstatus_show_all);
+
+#ifdef STANDALONE
+
+	gg_plugins_save_loaded();
+}
+
+void gnt_ui_uninit()
+{
+	gaim_accounts_set_ui_ops(NULL);
+	gg_accounts_uninit();
+
+	gaim_connections_set_ui_ops(NULL);
+	gg_connections_uninit();
+
+	gaim_blist_set_ui_ops(NULL);
+	gg_blist_uninit();
+
+	gaim_conversations_set_ui_ops(NULL);
+	gg_conversation_uninit();
+
+	gaim_notify_set_ui_ops(NULL);
+	gg_notify_uninit();
+
+	gaim_request_set_ui_ops(NULL);
+	gg_request_uninit();
+
+	gnt_quit();
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/gntui.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,30 @@
+/**
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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
+ */
+#ifndef _GNT_UI_H
+#define _GNT_UI_H
+
+#include "gnt.h"
+
+void gnt_ui_init(void);
+void gnt_ui_uninit(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/COPYING	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/INSTALL	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,229 @@
+Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/Makefile.am	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,79 @@
+EXTRA_DIST=genmarshal
+
+SUBDIRS = . wms
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gnt.pc
+
+lib_LTLIBRARIES = libgnt.la
+
+libgnt_la_SOURCES = \
+	gntmarshal.c \
+	gntwidget.c \
+	gntbindable.c \
+	gntbox.c \
+	gntbutton.c \
+	gntcheckbox.c \
+	gntcolors.c \
+	gntcombobox.c \
+	gntentry.c \
+	gntkeys.c \
+	gntlabel.c \
+	gntline.c \
+	gntmenu.c \
+	gntmenuitem.c \
+	gntmenuitemcheck.c \
+	gntstyle.c \
+	gnttextview.c \
+	gnttree.c \
+	gntutils.c \
+	gntwindow.c \
+	gntwm.c \
+	gntmain.c
+
+libgnt_la_headers = \
+	gntwidget.h \
+	gntbindable.h \
+	gntbox.h \
+	gntbutton.h \
+	gntcheckbox.h \
+	gntcolors.h \
+	gntcombobox.h \
+	gntentry.h \
+	gntkeys.h \
+	gntlabel.h \
+	gntline.h \
+	gntmarshal.h \
+	gntmenu.h \
+	gntmenuitem.h \
+	gntmenuitemcheck.h \
+	gntstyle.h \
+	gnttextview.h \
+	gnttree.h \
+	gntutils.h \
+	gntwindow.h \
+	gntwm.h \
+	gnt.h
+
+CLEANFILES = \
+	gntmarshal.h \
+	gntmarshal.c
+
+gntmarshal.c: genmarshal gntmarshal.h
+	cat genmarshal | glib-genmarshal --prefix=gnt_closure_marshal --body > $@
+
+gntmarshal.h: genmarshal
+	cat genmarshal | glib-genmarshal --prefix=gnt_closure_marshal --header > $@
+
+libgnt_laincludedir=$(includedir)/gnt
+libgnt_lainclude_HEADERS = \
+	$(libgnt_la_headers)
+
+libgnt_la_DEPENDENCIES = 
+libgnt_la_LDFLAGS = -export-dynamic
+libgnt_la_LIBADD = \
+	$(GLIB_LIBS) \
+	$(GNT_LIBS)
+
+AM_CPPFLAGS = \
+	$(GLIB_CFLAGS) \
+	$(GNT_CFLAGS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/autogen.sh	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have libtool installed to compile LibGNT";
+	echo;
+	exit;
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have automake installed to compile LibGNT";
+	echo;
+	exit;
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have autoconf installed to compile LibGNT";
+	echo;
+	exit;
+}
+
+echo "Generating configuration files for LibGNT, please wait...."
+echo;
+
+echo "Running libtoolize, please ignore non-fatal messages...."
+echo n | libtoolize --copy --force || exit;
+
+# Add other directories to this list if people continue to experience
+# brokennesses ...  Obviously the real answer is for them to fix it
+# themselves, but for Luke's sake we have this.
+for dir in "/usr/local/share/aclocal" \
+           "/opt/gnome-1.4/share/aclocal"
+do
+	if test -d $dir ; then
+		ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I $dir"
+	fi
+done
+
+libtoolize -c -f --automake
+aclocal $ACLOCAL_FLAGS || exit;
+autoheader || exit;
+automake --add-missing --copy;
+autoconf || exit;
+automake || exit;
+./configure $@
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/configure.ac	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,257 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT([libgnt], [0.0.0dev], [gaim-devel@lists.sourceforge.net])
+AC_CANONICAL_SYSTEM
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+
+AC_PREREQ([2.50])
+
+AC_PATH_PROG(sedpath, sed)
+
+dnl Storing configure arguments
+AC_DEFINE_UNQUOTED(CONFIG_ARGS, "$ac_configure_args", [configure arguments])
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_DISABLE_STATIC
+AM_PROG_LIBTOOL
+LIBTOOL="$LIBTOOL --silent"
+AC_PROG_INSTALL
+
+dnl we don't use autobreak on cygwin!!
+dnl AC_CYGWIN
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h regex.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_STRUCT_TM
+
+AC_C_BIGENDIAN
+
+dnl Checks for library functions.
+AC_TYPE_SIGNAL
+AC_FUNC_STRFTIME
+AC_CHECK_FUNCS(strdup strstr atexit setlocale)
+
+dnl to prevent the g_stat()/g_unlink() crash,
+dnl (09:50:07) Robot101: LSchiere2: it's easy. +LC_SYS_LARGEFILE somewhere in configure.ac
+AC_SYS_LARGEFILE
+
+dnl FreeBSD doesn't have libdl, dlopen is provided by libc
+AC_CHECK_FUNC(dlopen, LIBDL="", [AC_CHECK_LIB(dl, dlopen, LIBDL="-ldl")])
+
+AC_MSG_CHECKING(for the %z format string in strftime())
+AC_TRY_RUN([
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include <time.h>
+#include <stdio.h>
+
+int main()
+{
+	char buf[6];
+	time_t t = time(NULL);
+
+	if (strftime(buf, sizeof(buf), "%z", localtime(&t)) != 5)
+		return 1;
+
+	fprintf(stderr, "strftime(\"%%z\") yields: \"%s\"\n", buf);
+
+	return !((buf[0] == '-' || buf[0] == '+') &&
+	         (buf[1] >= '0' && buf[1] <= '9') &&
+	         (buf[2] >= '0' && buf[2] <= '9') &&
+	         (buf[3] >= '0' && buf[3] <= '9') &&
+	         (buf[4] >= '0' && buf[4] <= '9')
+	        );
+}
+],
+[
+	AC_MSG_RESULT(yes)
+	AC_DEFINE([HAVE_STRFTIME_Z_FORMAT], [1],
+                                      [Define to 1 if you have a strftime() that supports the %z format string.])
+],
+[
+	AC_MSG_RESULT(no)
+],
+[
+	# Fallback for Cross Compiling...
+	# This will enable the compatibility code.
+	AC_MSG_RESULT(no)
+]
+)
+
+
+AC_CHECK_HEADER(sys/utsname.h)
+AC_CHECK_FUNC(uname)
+
+if test "x$enable_debug" = "xyes" ; then
+	AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.])
+	enable_fatal_asserts="yes"
+fi
+
+if test "x$enable_fatal_asserts" = "xyes" ; then
+	AC_DEFINE(GAIM_FATAL_ASSERTS, 1, [Define to make assertions fatal (useful for debugging).])
+fi
+
+if test "x$enable_deprecated" = "xno"; then
+	DEBUG_CFLAGS="$DEBUG_CFLAGS -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
+fi
+
+if test "x$GCC" = "xyes"; then
+	dnl We enable -Wall later.
+	dnl If it's set after the warning CFLAGS in the compiler invocation, it counteracts the -Wno... flags.
+	dnl This leads to warnings we don't want.
+	CFLAGS=`echo $CFLAGS |$sedpath 's/-Wall//'`
+
+	dnl ENABLE WARNINGS SUPPORTED BY THE VERSION OF GCC IN USE
+	dnl
+	dnl Future Possibilities
+	dnl
+	dnl Consider adding -Wbad-function-cast.
+	dnl	This leads to spurious warnings using GPOINTER_TO_INT(), et al. directly on a function call.
+	dnl		We'd need an intermediate variable.
+	dnl
+	dnl Consider adding -Wfloat-equal.
+	dnl	This leads to warnings with Perl.
+	dnl 		Perhaps we could write ugly configure magic and pass -Wno-float-equal down to that subdirectory.
+	dnl		On the other hand, it's probably actually broken, so maybe the Perl folks should fix that?
+	dnl
+	dnl Consider removing -Wno-sign-compare (from the -Wextra set) and fixing all those cases.
+	dnl	This is likely non-trivial.
+	dnl
+	for newflag in \
+			"-Waggregate-return" \
+			"-Wcast-align" \
+			"-Wdeclaration-after-statement" \
+			"-Werror-implicit-function-declaration" \
+			"-Wextra -Wno-sign-compare -Wno-unused-parameter" \
+			"-Winit-self" \
+			"-Wmissing-declarations" \
+			"-Wmissing-prototypes" \
+			"-Wnested-externs" \
+			"-Wpointer-arith" \
+			"-Wundef" \
+	; do
+		orig_CFLAGS="$CFLAGS"
+		CFLAGS="$CFLAGS $newflag"
+		AC_MSG_CHECKING(for $newflag option to gcc)
+		AC_TRY_COMPILE([], [
+			int main() {return 0;}
+		], [
+			AC_MSG_RESULT(yes)
+			CFLAGS="$orig_CFLAGS"
+			DEBUG_CFLAGS="$DEBUG_CFLAGS $newflag"
+		], [
+			AC_MSG_RESULT(no)
+			CFLAGS="$orig_CFLAGS"
+		])
+	done
+
+	if test "x$enable_fortify" = "xyes"; then
+		AC_MSG_CHECKING(for FORTIFY_SOURCE support)
+		AC_TRY_COMPILE([#include <features.h>], [
+			int main() {
+			#if !(__GNUC_PREREQ (4, 1) \
+				|| (defined __GNUC_RH_RELEASE__ && __GNUC_PREREQ (4, 0)) \
+				|| (defined __GNUC_RH_RELEASE__ && __GNUC_PREREQ (3, 4) \
+					&& __GNUC_MINOR__ == 4 \
+					&& (__GNUC_PATCHLEVEL__ > 2 \
+						|| (__GNUC_PATCHLEVEL__ == 2 && __GNUC_RH_RELEASE__ >= 8))))
+			#error No FORTIFY_SOURCE support
+			#endif
+				return 0;
+			}
+		], [
+			AC_MSG_RESULT(yes)
+			DEBUG_CFLAGS="$DEBUG_CFLAGS -D_FORTIFY_SOURCE=2"
+		], [
+			AC_MSG_RESULT(no)
+		])
+	fi
+
+	DEBUG_CFLAGS="-Wall $DEBUG_CFLAGS"
+	CFLAGS="-g $CFLAGS"
+fi
+AC_SUBST(CFLAGS)
+
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.0.0 gobject-2.0 gmodule-2.0],,
+	[
+		AC_MSG_ERROR([
+*** GLib 2.0 is required to build LibGNT; please make sure you have the GLib
+*** development headers installed. The latest version of GLib is
+*** always available at http://www.gtk.org/.])
+	])
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+
+AC_MSG_CHECKING(for me pot o' gold)
+AC_MSG_RESULT(no)
+AC_CHECK_FUNCS(gethostid lrand48)
+AC_CHECK_FUNCS(memcpy memmove random strchr strerror vprintf)
+AC_CHECK_HEADERS(malloc.h paths.h sgtty.h stdarg.h sys/cdefs.h)
+AC_CHECK_HEADERS(sys/file.h sys/filio.h sys/ioctl.h sys/msgbuf.h)
+AC_CHECK_HEADERS(sys/select.h sys/uio.h sys/utsname.h sys/wait.h)
+AC_CHECK_HEADERS(termios.h)
+#AC_CHECK_FUNC(wcwidth, [AC_DEFINE([HAVE_WCWIDTH], [1], [Define to 1 if you have wcwidth function.])])
+#AC_VAR_TIMEZONE_EXTERNALS
+
+GNT_CFLAGS=
+GNT_LIBS=
+AC_CHECK_LIB(ncursesw, initscr, [GNT_LIBS="-lncursesw"], [enable_gnt=no])
+AC_CHECK_LIB(panelw, update_panels, [GNT_LIBS="$GNT_LIBS -lpanelw"], [enable_gnt=no])
+
+# If ncursesw is not found, look for plain old ncurses
+if test "x$enable_gnt" = "xno"; then
+	AC_CHECK_LIB(ncurses, initscr, [[GNT_LIBS="-lncurses"] [enable_gnt=yes]], [enable_gnt=no])
+	AC_CHECK_LIB(panel, update_panels, [[GNT_LIBS="$GNT_LIBS -lpanel"] [enable_gnt=yes]], [enable_gnt=no])
+	AC_DEFINE(NO_WIDECHAR, [1], [Define to 1 if you do not have ncursesw.])
+else
+	dnl # Some distros put the headers in ncursesw/, some don't
+	found_ncurses_h=no
+	for f in /usr/include/ncursesw/ncurses.h /usr/include/ncurses.h
+	do
+		AC_CHECK_HEADER($f,[
+			AC_MSG_CHECKING([if $f supports wide characters])
+			AC_TRY_COMPILE([
+				#define _XOPEN_SOURCE_EXTENDED
+				#include <$f>
+			], [
+				#ifndef get_wch
+				# error get_wch not found!
+				#endif
+			], [
+				dir=`dirname $f`
+				if test x"$dir" != x"." ; then
+					GNT_CFLAGS="-I$dir/"
+				else
+					GNT_CFLAGS=""
+				fi
+
+				found_ncurses_h=yes
+				AC_MSG_RESULT([yes])
+				break
+			], [
+				AC_MSG_RESULT([no])
+			])
+		])
+	done
+fi
+AC_SUBST(GNT_CFLAGS)
+AC_SUBST(GNT_LIBS)
+
+if test "x$enable_gnt" = "xno"; then
+	AC_MSG_ERROR([
+*** You need ncursesw or ncurses.])
+fi
+
+AC_OUTPUT([Makefile
+           gnt.pc
+           wms/Makefile
+		  ])
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/genmarshal	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,10 @@
+BOOLEAN:VOID
+BOOLEAN:STRING
+VOID:INT,INT,INT,INT
+VOID:INT,INT
+VOID:POINTER,POINTER
+BOOLEAN:INT,INT
+BOOLEAN:INT,INT,INT
+BOOLEAN:POINTER,POINTER,POINTER
+BOOLEAN:INT,INT,INT,POINTER
+VOID:STRING,STRING
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnt-skel.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,106 @@
+#include "gnt-skel.h"
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+
+static void
+gnt_skel_draw(GntWidget *widget)
+{
+	GNTDEBUG;
+}
+
+static void
+gnt_skel_size_request(GntWidget *widget)
+{
+}
+
+static void
+gnt_skel_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static gboolean
+gnt_skel_key_pressed(GntWidget *widget, const char *text)
+{
+	return FALSE;
+}
+
+static void
+gnt_skel_destroy(GntWidget *widget)
+{
+}
+
+static void
+gnt_skel_class_init(GntSkelClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_skel_destroy;
+	parent_class->draw = gnt_skel_draw;
+	parent_class->map = gnt_skel_map;
+	parent_class->size_request = gnt_skel_size_request;
+	parent_class->key_pressed = gnt_skel_key_pressed;
+
+	parent_class->actions = g_hash_table_duplicate(parent_class->actions, g_str_hash,
+				g_str_equal, NULL, (GDestroyNotify)gnt_widget_action_free);
+	parent_class->bindings = g_hash_table_duplicate(parent_class->bindings, g_str_hash,
+				g_str_equal, NULL, (GDestroyNotify)gnt_widget_action_param_free);
+
+	gnt_widget_actions_read(G_OBJECT_CLASS_TYPE(klass), klass);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_skel_init(GTypeInstance *instance, gpointer class)
+{
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntSkel API
+ *****************************************************************************/
+GType
+gnt_skel_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntSkelClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_skel_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntSkel),
+			0,						/* n_preallocs		*/
+			gnt_skel_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntSkel",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_skel_new()
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_SKEL, NULL);
+	GntSkel *skel = GNT_SKEL(widget);
+
+	return widget;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnt-skel.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,47 @@
+#ifndef GNT_SKEL_H
+#define GNT_SKEL_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_SKEL				(gnt_skel_get_gtype())
+#define GNT_SKEL(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_SKEL, GntSkel))
+#define GNT_SKEL_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_SKEL, GntSkelClass))
+#define GNT_IS_SKEL(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_SKEL))
+#define GNT_IS_SKEL_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_SKEL))
+#define GNT_SKEL_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_SKEL, GntSkelClass))
+
+#define GNT_SKEL_FLAGS(obj)				(GNT_SKEL(obj)->priv.flags)
+#define GNT_SKEL_SET_FLAGS(obj, flags)		(GNT_SKEL_FLAGS(obj) |= flags)
+#define GNT_SKEL_UNSET_FLAGS(obj, flags)	(GNT_SKEL_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnSkel			GntSkel;
+typedef struct _GnSkelPriv		GntSkelPriv;
+typedef struct _GnSkelClass		GntSkelClass;
+
+struct _GnSkel
+{
+	GntWidget parent;
+};
+
+struct _GnSkelClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_skel_get_gtype(void);
+
+GntWidget *gnt_skel_new();
+
+G_END_DECLS
+
+#endif /* GNT_SKEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnt.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,35 @@
+#include <glib.h>
+#include "gntwidget.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+void gnt_init();
+
+void gnt_main();
+
+gboolean gnt_ascii_only();
+
+void gnt_screen_occupy(GntWidget *widget);
+
+void gnt_screen_release(GntWidget *widget);
+
+void gnt_screen_update(GntWidget *widget);
+
+void gnt_screen_take_focus(GntWidget *widget);
+
+void gnt_screen_resize_widget(GntWidget *widget, int width, int height);
+
+void gnt_screen_move_widget(GntWidget *widget, int x, int y);
+
+void gnt_screen_rename_widget(GntWidget *widget, const char *text);
+
+gboolean gnt_widget_has_focus(GntWidget *widget);
+
+void gnt_widget_set_urgent(GntWidget *widget);
+
+void gnt_register_action(const char *label, void (*callback)());
+
+gboolean gnt_screen_menu_show(gpointer menu);
+
+void gnt_quit();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnt.pc.in	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+ 
+Name: LibGNT
+Description: Gaim Ncurses Toolkit is a collection of curses-widgets.
+Version: @VERSION@
+Requires: glib-2.0
+Cflags: -I${includedir}/gnt
+Libs: -L${libdir} -lgnt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbindable.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,229 @@
+#include "gntbindable.h"
+#include "gntstyle.h"
+#include "gnt.h"
+#include "gntutils.h"
+
+static GObjectClass *parent_class = NULL;
+
+static void
+gnt_bindable_class_init(GntBindableClass *klass)
+{
+	parent_class = g_type_class_peek_parent(klass);
+
+	klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+				(GDestroyNotify)gnt_bindable_action_free);
+	klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+				(GDestroyNotify)gnt_bindable_action_param_free);
+
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
+	GNTDEBUG;
+}
+
+static gpointer
+bindable_clone(GntBindableAction *action)
+{
+	GntBindableAction *ret = g_new0(GntBindableAction, 1);
+	ret->name = g_strdup(action->name);
+	ret->u = action->u;
+	return ret;
+}
+
+static gpointer
+binding_clone(GntBindableActionParam *param)
+{
+	GntBindableActionParam *p = g_new0(GntBindableActionParam, 1);
+	p->list = g_list_copy(param->list);
+	p->action = param->action;
+	return p;
+}
+
+static void
+duplicate_hashes(GntBindableClass *klass)
+{
+	/* Duplicate the bindings from parent class */
+	if (klass->actions) {
+		klass->actions = g_hash_table_duplicate(klass->actions, g_str_hash,
+					g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_free,
+					(GDupFunc)g_strdup, (GDupFunc)bindable_clone);
+		klass->bindings = g_hash_table_duplicate(klass->bindings, g_str_hash,
+					g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_param_free,
+					(GDupFunc)g_strdup, (GDupFunc)binding_clone);
+	} else {
+		klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+					(GDestroyNotify)gnt_bindable_action_free);
+		klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+					(GDestroyNotify)gnt_bindable_action_param_free);
+	}
+
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntBindable API
+ *****************************************************************************/
+GType
+gnt_bindable_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(GntBindableClass),
+			(GBaseInitFunc)duplicate_hashes,	/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_bindable_class_init,
+			NULL,
+			NULL,					/* class_data		*/
+			sizeof(GntBindable),
+			0,						/* n_preallocs		*/
+			NULL,					/* instance_init	*/
+		};
+
+		type = g_type_register_static(G_TYPE_OBJECT,
+									  "GntBindable",
+									  &info, G_TYPE_FLAG_ABSTRACT);
+	}
+
+	return type;
+}
+
+/**
+ * Key Remaps
+ */
+const char *
+gnt_bindable_remap_keys(GntBindable *bindable, const char *text)
+{
+	const char *remap = NULL;
+	GType type = G_OBJECT_TYPE(bindable);
+	GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable));
+
+	if (klass->remaps == NULL)
+	{
+		klass->remaps = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+		gnt_styles_get_keyremaps(type, klass->remaps);
+	}
+
+	remap = g_hash_table_lookup(klass->remaps, text);
+
+	return (remap ? remap : text);
+}
+
+/**
+ * Actions and Bindings
+ */
+gboolean
+gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...)
+{
+	GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable));
+	GList *list = NULL;
+	va_list args;
+	GntBindableAction *action;
+	void *p;
+
+	va_start(args, name);
+	while ((p = va_arg(args, void *)) != NULL)
+		list = g_list_append(list, p);
+	va_end(args);
+	
+	action = g_hash_table_lookup(klass->actions, name);
+	if (action && action->u.action) {
+		return action->u.action(bindable, list);
+	}
+	return FALSE;
+}
+
+gboolean
+gnt_bindable_perform_action_key(GntBindable *bindable, const char *keys)
+{
+	GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable));
+	GntBindableActionParam *param = g_hash_table_lookup(klass->bindings, keys);
+
+	if (param && param->action) {
+		if (param->list)
+			return param->action->u.action(bindable, param->list);
+		else
+			return param->action->u.action_noparam(bindable);
+	}
+	return FALSE;
+}
+
+static void
+register_binding(GntBindableClass *klass, const char *name, const char *trigger, GList *list)
+{
+	GntBindableActionParam *param;
+	GntBindableAction *action;
+
+	if (name == NULL || *name == '\0') {
+		g_hash_table_remove(klass->bindings, (char*)trigger);
+		return;
+	}
+
+	action = g_hash_table_lookup(klass->actions, name);
+	if (!action) {
+		g_printerr("GntWidget: Invalid action name %s for %s\n",
+				name, g_type_name(G_OBJECT_CLASS_TYPE(klass)));
+		if (list)
+			g_list_free(list);
+		return;
+	}
+
+	param = g_new0(GntBindableActionParam, 1);
+	param->action = action;
+	param->list = list;
+	g_hash_table_replace(klass->bindings, g_strdup(trigger), param);
+}
+
+void gnt_bindable_register_binding(GntBindableClass *klass, const char *name,
+			const char *trigger, ...)
+{
+	GList *list = NULL;
+	va_list args;
+	void *data;
+
+	va_start(args, trigger);
+	while ((data = va_arg(args, void *))) {
+		list = g_list_append(list, data);
+	}
+	va_end(args);
+
+	register_binding(klass, name, trigger, list);
+}
+
+void gnt_bindable_class_register_action(GntBindableClass *klass, const char *name,
+			GntBindableActionCallback callback, const char *trigger, ...)
+{
+	void *data;
+	va_list args;
+	GntBindableAction *action = g_new0(GntBindableAction, 1);
+	GList *list;
+
+	action->name = g_strdup(name);
+	action->u.action = callback;
+
+	g_hash_table_replace(klass->actions, g_strdup(name), action);
+
+	if (trigger && *trigger) {
+		list = NULL;
+		va_start(args, trigger);
+		while ((data = va_arg(args, void *))) {
+			list = g_list_append(list, data);
+		}
+		va_end(args);
+
+		register_binding(klass, name, trigger, list);
+	}
+}
+
+void gnt_bindable_action_free(GntBindableAction *action)
+{
+	g_free(action->name);
+	g_free(action);
+}
+
+void gnt_bindable_action_param_free(GntBindableActionParam *param)
+{
+	g_list_free(param->list);   /* XXX: There may be a leak here for string parameters */
+	g_free(param);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbindable.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,90 @@
+#ifndef GNT_BINDABLE_H
+#define GNT_BINDABLE_H
+
+#include <stdio.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <ncurses.h>
+
+#define GNT_TYPE_BINDABLE				(gnt_bindable_get_gtype())
+#define GNT_BINDABLE(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BINDABLE, GntBindable))
+#define GNT_BINDABLE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BINDABLE, GntBindableClass))
+#define GNT_IS_BINDABLE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BINDABLE))
+#define GNT_IS_BINDABLE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BINDABLE))
+#define GNT_BINDABLE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BINDABLE, GntBindableClass))
+
+#define	GNTDEBUG	fprintf(stderr, "%s\n", __FUNCTION__)
+
+typedef struct _GnBindable			GntBindable;
+typedef struct _GnBindableClass		GntBindableClass;
+
+struct _GnBindable
+{
+	GObject inherit;
+};
+
+struct _GnBindableClass
+{
+	GObjectClass parent;
+
+	GHashTable *remaps;   /* Key remaps */
+	GHashTable *actions;  /* name -> Action */
+	GHashTable *bindings; /* key -> ActionParam */
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_bindable_get_gtype(void);
+
+/******************/
+/*   Key Remaps   */
+/******************/
+const char * gnt_bindable_remap_keys(GntBindable *bindable, const char *text);
+
+/******************/
+/* Bindable Actions */
+/******************/
+typedef gboolean (*GntBindableActionCallback) (GntBindable *bindable, GList *params);
+typedef gboolean (*GntBindableActionCallbackNoParam)(GntBindable *bindable);
+
+typedef struct _GnBindableAction GntBindableAction;
+typedef struct _GnBindableActionParam GntBindableActionParam;
+
+struct _GnBindableAction
+{
+	char *name;        /* The name of the action */
+	union {
+		gboolean (*action)(GntBindable *bindable, GList *params);
+		gboolean (*action_noparam)(GntBindable *bindable);
+	} u;
+};
+
+struct _GnBindableActionParam
+{
+	GntBindableAction *action;
+	GList *list;
+};
+
+
+/*GntBindableAction *gnt_bindable_action_parse(const char *name);*/
+
+void gnt_bindable_action_free(GntBindableAction *action);
+void gnt_bindable_action_param_free(GntBindableActionParam *param);
+
+void gnt_bindable_class_register_action(GntBindableClass *klass, const char *name,
+			GntBindableActionCallback callback, const char *trigger, ...);
+void gnt_bindable_register_binding(GntBindableClass *klass, const char *name,
+			const char *trigger, ...);
+
+gboolean gnt_bindable_perform_action_key(GntBindable *bindable, const char *keys);
+gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...);
+
+G_END_DECLS
+
+#endif /* GNT_BINDABLE_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbox.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,787 @@
+#include "gntbox.h"
+#include "gntutils.h"
+
+#include <string.h>
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+
+static GntWidget * find_focusable_widget(GntBox *box);
+
+static void
+add_to_focus(gpointer value, gpointer data)
+{
+	GntBox *box = GNT_BOX(data);
+	GntWidget *w = GNT_WIDGET(value);
+
+	if (GNT_IS_BOX(w))
+		g_list_foreach(GNT_BOX(w)->list, add_to_focus, box);
+	else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS))
+		box->focus = g_list_append(box->focus, w);
+}
+
+static void
+get_title_thingies(GntBox *box, char *title, int *p, int *r)
+{
+	GntWidget *widget = GNT_WIDGET(box);
+	int len;
+	char *end = (char*)gnt_util_onscreen_width_to_pointer(title, widget->priv.width - 4, &len);
+	
+	if (p)
+		*p = (widget->priv.width - len) / 2;
+	if (r)
+		*r = (widget->priv.width + len) / 2;
+	*end = '\0';
+}
+
+static void
+gnt_box_draw(GntWidget *widget)
+{
+	GntBox *box = GNT_BOX(widget);
+
+	if (box->focus == NULL && widget->parent == NULL)
+		g_list_foreach(box->list, add_to_focus, box);
+
+	g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL);
+
+	gnt_box_sync_children(box);
+
+	if (box->title && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+	{
+		int pos, right;
+		char *title = g_strdup(box->title);
+		
+		get_title_thingies(box, title, &pos, &right);
+
+		if (gnt_widget_has_focus(widget))
+			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE));
+		else
+			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE_D));
+		mvwaddch(widget->window, 0, pos-1, ACS_RTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
+		mvwprintw(widget->window, 0, pos, title);
+		mvwaddch(widget->window, 0, right, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
+		g_free(title);
+	}
+	
+	GNTDEBUG;
+}
+
+static void
+reposition_children(GntWidget *widget)
+{
+	GList *iter;
+	GntBox *box = GNT_BOX(widget);
+	int w, h, curx, cury, max;
+	gboolean has_border = FALSE;
+
+	w = h = 0;
+	max = 0;
+	curx = widget->priv.x;
+	cury = widget->priv.y;
+	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
+	{
+		has_border = TRUE;
+		curx += 1;
+		cury += 1;
+	}
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(iter->data), GNT_WIDGET_INVISIBLE))
+			continue;
+		gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury);
+		gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
+		if (box->vertical)
+		{
+			if (h)
+			{
+				cury += h + box->pad;
+				if (max < w)
+					max = w;
+			}
+		}
+		else
+		{
+			if (w)
+			{
+				curx += w + box->pad;
+				if (max < h)
+					max = h;
+			}
+		}
+	}
+
+	if (has_border)
+	{
+		curx += 1;
+		cury += 1;
+		max += 2;
+	}
+
+	if (box->list)
+	{
+		if (box->vertical)
+			cury -= box->pad;
+		else
+			curx -= box->pad;
+	}
+
+	if (box->vertical)
+	{
+		widget->priv.width = max;
+		widget->priv.height = cury - widget->priv.y;
+	}
+	else
+	{
+		widget->priv.width = curx - widget->priv.x;
+		widget->priv.height = max;
+	}
+}
+
+static void
+gnt_box_set_position(GntWidget *widget, int x, int y)
+{
+	GList *iter;
+	int changex, changey;
+
+	changex = widget->priv.x - x;
+	changey = widget->priv.y - y;
+
+	for (iter = GNT_BOX(widget)->list; iter; iter = iter->next)
+	{
+		GntWidget *w = GNT_WIDGET(iter->data);
+		gnt_widget_set_position(w, w->priv.x - changex,
+				w->priv.y - changey);
+	}
+}
+
+static void
+gnt_box_size_request(GntWidget *widget)
+{
+	GntBox *box = GNT_BOX(widget);
+	GList *iter;
+	int maxw = 0, maxh = 0;
+	
+	g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		int w, h;
+		gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);
+		if (maxh < h)
+			maxh = h;
+		if (maxw < w)
+			maxw = w;
+	}
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		int w, h;
+		GntWidget *wid = GNT_WIDGET(iter->data);
+
+		gnt_widget_get_size(wid, &w, &h);
+
+		if (box->homogeneous)
+		{
+			if (box->vertical)
+				h = maxh;
+			else
+				w = maxw;
+		}
+		if (box->fill)
+		{
+			if (box->vertical)
+				w = maxw;
+			else
+				h = maxh;
+		}
+
+		gnt_widget_set_size(wid, w, h);
+	}
+
+	reposition_children(widget);
+}
+
+static void
+gnt_box_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+	{
+		gnt_widget_size_request(widget);
+		find_focusable_widget(GNT_BOX(widget));
+	}
+	GNTDEBUG;
+}
+
+/* Ensures that the current widget can take focus */
+static GntWidget *
+find_focusable_widget(GntBox *box)
+{
+	/* XXX: Make sure the widget is visible? */
+	if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL)
+		g_list_foreach(box->list, add_to_focus, box);
+
+	if (box->active == NULL && box->focus)
+		box->active = box->focus->data;
+
+	return box->active;
+}
+
+static void
+find_next_focus(GntBox *box)
+{
+	gpointer last = box->active;
+	do
+	{
+		GList *iter = g_list_find(box->focus, box->active);
+		if (iter && iter->next)
+			box->active = iter->next->data;
+		else if (box->focus)
+			box->active = box->focus->data;
+		if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))
+			break;
+	} while (box->active != last);
+}
+
+static void
+find_prev_focus(GntBox *box)
+{
+	gpointer last = box->active;
+
+	if (!box->focus)
+		return;
+
+	do
+	{
+		GList *iter = g_list_find(box->focus, box->active);
+		if (!iter)
+			box->active = box->focus->data;
+		else if (!iter->prev)
+			box->active = g_list_last(box->focus)->data;
+		else
+			box->active = iter->prev->data;
+		if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))
+			break;
+	} while (box->active != last);
+}
+
+static gboolean
+gnt_box_key_pressed(GntWidget *widget, const char *text)
+{
+	GntBox *box = GNT_BOX(widget);
+	GntWidget *now;
+
+	if (box->active == NULL && !find_focusable_widget(box))
+		return FALSE;
+
+	if (gnt_widget_key_pressed(box->active, text))
+		return TRUE;
+	
+	now = box->active;
+
+	if (text[0] == 27)
+	{
+		if (strcmp(text, GNT_KEY_LEFT) == 0)
+		{
+			find_prev_focus(box);
+		}
+		else if (strcmp(text, GNT_KEY_RIGHT) == 0)
+		{
+			find_next_focus(box);
+		}
+	}
+	else if (text[0] == '\t')
+	{
+		find_next_focus(box);
+	}
+
+	if (now && now != box->active)
+	{
+		gnt_widget_set_focus(now, FALSE);
+		gnt_widget_set_focus(box->active, TRUE);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+gnt_box_lost_focus(GntWidget *widget)
+{
+	GntWidget *w = GNT_BOX(widget)->active;
+	if (w)
+		gnt_widget_set_focus(w, FALSE);
+	gnt_widget_draw(widget);
+}
+
+static void
+gnt_box_gained_focus(GntWidget *widget)
+{
+	GntWidget *w = GNT_BOX(widget)->active;
+	if (w)
+		gnt_widget_set_focus(w, TRUE);
+	gnt_widget_draw(widget);
+}
+
+static void
+gnt_box_destroy(GntWidget *w)
+{
+	GntBox *box = GNT_BOX(w);
+
+	gnt_box_remove_all(box);
+	gnt_screen_release(w);
+}
+
+static void
+gnt_box_expose(GntWidget *widget, int x, int y, int width, int height)
+{
+	WINDOW *win = newwin(height, width, widget->priv.y + y, widget->priv.x + x);
+	copywin(widget->window, win, y, x, 0, 0, height - 1, width - 1, FALSE);
+	wrefresh(win);
+	delwin(win);
+}
+
+static gboolean
+gnt_box_confirm_size(GntWidget *widget, int width, int height)
+{
+	GList *iter;
+	GntBox *box = GNT_BOX(widget);
+	int wchange, hchange;
+
+	if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
+		return FALSE;
+	if (widget->priv.height != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
+		return FALSE;
+
+	if (!box->list)
+		return TRUE;
+
+	wchange = widget->priv.width - width;
+	hchange = widget->priv.height - height;
+
+	if (wchange == 0 && hchange == 0)
+		return TRUE;		/* Quit playing games */
+
+	/* XXX: Right now, I am trying to just apply all the changes to 
+	 * just one widget. It should be possible to distribute the
+	 * changes to all the widgets in the box. */
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		GntWidget *wid = iter->data;
+		int w, h;
+
+		gnt_widget_get_size(wid, &w, &h);
+
+		if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))
+		{
+			GList *i;
+
+			for (i = box->list; i; i = i->next)
+			{
+				int tw, th;
+				if (i == iter) continue;
+				gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
+				if (box->vertical)
+				{
+					if (!gnt_widget_confirm_size(i->data, tw - wchange, th))
+						return FALSE;
+				}
+				else
+				{
+					if (!gnt_widget_confirm_size(i->data, tw, th - hchange))
+						return FALSE;
+				}
+			}
+#if 0
+			gnt_widget_set_size(wid, w - wchange, h - hchange);
+			if (box->vertical)
+				hchange = 0;
+			else
+				wchange = 0;
+
+			for (i = box->list; i; i = i->next)
+			{
+				int tw, th;
+				if (i == iter) continue;
+				gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
+				gnt_widget_set_size(i->data, tw - wchange, th - hchange);
+			}
+#endif
+			g_object_set_data(G_OBJECT(box), "size-queued", wid);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static void
+gnt_box_size_changed(GntWidget *widget, int oldw, int oldh)
+{
+	int wchange, hchange;
+	GList *i;
+	GntBox *box = GNT_BOX(widget);
+	GntWidget *wid;
+	int tw, th;
+		
+	wchange = widget->priv.width - oldw;
+	hchange = widget->priv.height - oldh;
+	
+	wid = g_object_get_data(G_OBJECT(box), "size-queued");
+	if (wid)
+	{
+		gnt_widget_get_size(wid, &tw, &th);
+		gnt_widget_set_size(wid, tw + wchange, th + hchange);
+		g_object_set_data(G_OBJECT(box), "size-queued", NULL);
+	}
+
+	if (box->vertical)
+		hchange = 0;
+	else
+		wchange = 0;
+
+	for (i = box->list; i; i = i->next)
+	{
+		if (wid != i->data)
+		{
+			gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);
+			gnt_widget_set_size(i->data, tw + wchange, th + hchange);
+		}
+	}
+
+	reposition_children(widget);
+}
+
+static gboolean
+gnt_box_clicked(GntWidget *widget, GntMouseEvent event, int cx, int cy)
+{
+	GList *iter;
+	for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) {
+		int x, y, w, h;
+		GntWidget *wid = iter->data;
+
+		gnt_widget_get_position(wid, &x, &y);
+		gnt_widget_get_size(wid, &w, &h);
+
+		if (cx >= x && cx < x + w && cy >= y && cy < y + h) {
+			if (event <= GNT_MIDDLE_MOUSE_DOWN &&
+				GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_CAN_TAKE_FOCUS)) {
+				while (widget->parent)
+					widget = widget->parent;
+				gnt_box_give_focus_to_child(GNT_BOX(widget), wid);
+			}
+			return gnt_widget_clicked(wid, event, cx, cy);
+		}
+	}
+	return FALSE;
+}
+
+static void
+gnt_box_class_init(GntBoxClass *klass)
+{
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_box_destroy;
+	parent_class->draw = gnt_box_draw;
+	parent_class->expose = gnt_box_expose;
+	parent_class->map = gnt_box_map;
+	parent_class->size_request = gnt_box_size_request;
+	parent_class->set_position = gnt_box_set_position;
+	parent_class->key_pressed = gnt_box_key_pressed;
+	parent_class->clicked = gnt_box_clicked;
+	parent_class->lost_focus = gnt_box_lost_focus;
+	parent_class->gained_focus = gnt_box_gained_focus;
+	parent_class->confirm_size = gnt_box_confirm_size;
+	parent_class->size_changed = gnt_box_size_changed;
+
+	GNTDEBUG;
+}
+
+static void
+gnt_box_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GntBox *box = GNT_BOX(widget);
+	/* Initially make both the height and width resizable.
+	 * Update the flags as necessary when widgets are added to it. */
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+	box->pad = 1;
+	box->fill = TRUE;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntBox API
+ *****************************************************************************/
+GType
+gnt_box_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntBoxClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_box_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntBox),
+			0,						/* n_preallocs		*/
+			gnt_box_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntBox",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_box_new(gboolean homo, gboolean vert)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL);
+	GntBox *box = GNT_BOX(widget);
+
+	box->homogeneous = homo;
+	box->vertical = vert;
+	box->alignment = vert ? GNT_ALIGN_LEFT : GNT_ALIGN_MID;
+
+	return widget;
+}
+
+void gnt_box_add_widget(GntBox *b, GntWidget *widget)
+{
+	b->list = g_list_append(b->list, widget);
+	widget->parent = GNT_WIDGET(b);
+
+	if (b->vertical)
+	{
+		if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
+			GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_X);
+	}
+	else
+	{
+		if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
+			GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(b), GNT_WIDGET_GROW_Y);
+	}
+}
+
+void gnt_box_set_title(GntBox *b, const char *title)
+{
+	char *prev = b->title;
+	GntWidget *w = GNT_WIDGET(b);
+	b->title = g_strdup(title);
+	if (w->window && !GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_NO_BORDER)) {
+		/* Erase the old title */
+		int pos, right;
+		get_title_thingies(b, prev, &pos, &right);
+		mvwhline(w->window, 0, pos - 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				right - pos + 2);
+		g_free(prev);
+	}
+}
+
+void gnt_box_set_pad(GntBox *box, int pad)
+{
+	box->pad = pad;
+	/* XXX: Perhaps redraw if already showing? */
+}
+
+void gnt_box_set_toplevel(GntBox *box, gboolean set)
+{
+	GntWidget *widget = GNT_WIDGET(box);
+	if (set)
+	{
+		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
+	}
+	else
+	{
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
+	}
+}
+
+void gnt_box_sync_children(GntBox *box)
+{
+	GList *iter;
+	GntWidget *widget = GNT_WIDGET(box);
+	int pos = 1;
+
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		pos = 0;
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		GntWidget *w = GNT_WIDGET(iter->data);
+		int height, width;
+		int x, y;
+
+		if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_INVISIBLE))
+			continue;
+
+		if (GNT_IS_BOX(w))
+			gnt_box_sync_children(GNT_BOX(w));
+
+		gnt_widget_get_size(w, &width, &height);
+
+		x = w->priv.x - widget->priv.x;
+		y = w->priv.y - widget->priv.y;
+
+		if (box->vertical)
+		{
+			x = pos;
+			if (box->alignment == GNT_ALIGN_RIGHT)
+				x += widget->priv.width - width;
+			else if (box->alignment == GNT_ALIGN_MID)
+				x += (widget->priv.width - width)/2;
+			if (x + width > widget->priv.width - pos)
+				x -= x + width - (widget->priv.width - pos);
+		}
+		else
+		{
+			y = pos;
+			if (box->alignment == GNT_ALIGN_BOTTOM)
+				y += widget->priv.height - height;
+			else if (box->alignment == GNT_ALIGN_MID)
+				y += (widget->priv.height - height)/2;
+			if (y + height >= widget->priv.height - pos)
+				y = widget->priv.height - height - pos;
+		}
+
+		copywin(w->window, widget->window, 0, 0,
+				y, x, y + height - 1, x + width - 1, FALSE);
+		gnt_widget_set_position(w, x + widget->priv.x, y + widget->priv.y);
+	}
+}
+
+void gnt_box_set_alignment(GntBox *box, GntAlignment alignment)
+{
+	box->alignment = alignment;
+}
+
+void gnt_box_remove(GntBox *box, GntWidget *widget)
+{
+	box->list = g_list_remove(box->list, widget);
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)
+			&& GNT_WIDGET(box)->parent == NULL && box->focus)
+	{
+		if (widget == box->active)
+		{
+			find_next_focus(box);
+			if (box->active == widget) /* There's only one widget */
+				box->active = NULL;
+		}
+		box->focus = g_list_remove(box->focus, widget);
+	}
+
+	if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(box), GNT_WIDGET_MAPPED))
+		gnt_widget_draw(GNT_WIDGET(box));
+}
+
+void gnt_box_remove_all(GntBox *box)
+{
+	g_list_foreach(box->list, (GFunc)gnt_widget_destroy, NULL);
+	g_list_free(box->list);
+	g_list_free(box->focus);
+	box->list = NULL;
+	box->focus = NULL;
+	GNT_WIDGET(box)->priv.width = 0;
+	GNT_WIDGET(box)->priv.height = 0;
+}
+
+void gnt_box_readjust(GntBox *box)
+{
+	GList *iter;
+	GntWidget *wid;
+	int width, height;
+
+	if (GNT_WIDGET(box)->parent != NULL)
+		return;
+
+	for (iter = box->list; iter; iter = iter->next)
+	{
+		GntWidget *w = iter->data;
+		if (GNT_IS_BOX(w))
+			gnt_box_readjust(GNT_BOX(w));
+		else
+		{
+			GNT_WIDGET_UNSET_FLAGS(w, GNT_WIDGET_MAPPED);
+			w->priv.width = 0;
+			w->priv.height = 0;
+		}
+	}
+
+	wid = GNT_WIDGET(box);
+	GNT_WIDGET_UNSET_FLAGS(wid, GNT_WIDGET_MAPPED);
+	wid->priv.width = 0;
+	wid->priv.height = 0;
+
+	if (wid->parent == NULL)
+	{
+		g_list_free(box->focus);
+		box->focus = NULL;
+		box->active = NULL;
+		gnt_widget_size_request(wid);
+		gnt_widget_get_size(wid, &width, &height);
+		gnt_screen_resize_widget(wid, width, height);
+		find_focusable_widget(box);
+	}
+}
+
+void gnt_box_set_fill(GntBox *box, gboolean fill)
+{
+	box->fill = fill;
+}
+
+void gnt_box_move_focus(GntBox *box, int dir)
+{
+	GntWidget *now;
+
+	if (box->active == NULL)
+	{
+		find_focusable_widget(box);
+		return;
+	}
+
+	now = box->active;
+
+	if (dir == 1)
+		find_next_focus(box);
+	else if (dir == -1)
+		find_prev_focus(box);
+
+	if (now && now != box->active)
+	{
+		gnt_widget_set_focus(now, FALSE);
+		gnt_widget_set_focus(box->active, TRUE);
+	}
+
+	if (GNT_WIDGET(box)->window)
+		gnt_widget_draw(GNT_WIDGET(box));
+}
+
+void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget)
+{
+	GList *find = g_list_find(box->focus, widget);
+	gpointer now = box->active;
+	if (find)
+		box->active = widget;
+	if (now && now != box->active)
+	{
+		gnt_widget_set_focus(now, FALSE);
+		gnt_widget_set_focus(box->active, TRUE);
+	}
+
+	if (GNT_WIDGET(box)->window)
+		gnt_widget_draw(GNT_WIDGET(box));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbox.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,98 @@
+#ifndef GNT_BOX_H
+#define GNT_BOX_H
+
+#include "gnt.h"
+#include "gntwidget.h"
+
+#define GNT_TYPE_BOX				(gnt_box_get_gtype())
+#define GNT_BOX(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BOX, GntBox))
+#define GNT_BOX_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BOX, GntBoxClass))
+#define GNT_IS_BOX(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BOX))
+#define GNT_IS_BOX_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BOX))
+#define GNT_BOX_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BOX, GntBoxClass))
+
+typedef struct _GnBox			GntBox;
+typedef struct _GnBoxClass		GntBoxClass;
+
+typedef enum
+{
+	/* These for vertical boxes */
+	GNT_ALIGN_LEFT,
+	GNT_ALIGN_RIGHT,
+
+	GNT_ALIGN_MID,
+
+	/* These for horizontal boxes */
+	GNT_ALIGN_TOP,
+	GNT_ALIGN_BOTTOM
+} GntAlignment;
+
+struct _GnBox
+{
+	GntWidget parent;
+
+	gboolean vertical;
+	gboolean homogeneous;
+	gboolean fill;
+	GList *list;		/* List of widgets */
+
+	GntWidget *active;
+	int pad;			/* Number of spaces to use between widgets */
+	GntAlignment alignment;  /* How are the widgets going to be aligned? */
+
+	char *title;
+	GList *focus;		/* List of widgets to cycle focus (only valid for parent boxes) */
+
+    void (*gnt_reserved1)(void);
+    void (*gnt_reserved2)(void);
+    void (*gnt_reserved3)(void);
+    void (*gnt_reserved4)(void);
+};
+
+struct _GnBoxClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_box_get_gtype(void);
+
+#define gnt_vbox_new(homo) gnt_box_new(homo, TRUE)
+#define gnt_hbox_new(homo) gnt_box_new(homo, FALSE)
+
+GntWidget *gnt_box_new(gboolean homo, gboolean vert);
+
+void gnt_box_add_widget(GntBox *box, GntWidget *widget);
+
+void gnt_box_set_title(GntBox *box, const char *title);
+
+void gnt_box_set_pad(GntBox *box, int pad);
+
+void gnt_box_set_toplevel(GntBox *box, gboolean set);
+
+void gnt_box_sync_children(GntBox *box);
+
+void gnt_box_set_alignment(GntBox *box, GntAlignment alignment);
+
+void gnt_box_remove(GntBox *box, GntWidget *widget); /* XXX: does NOT destroy widget */
+
+void gnt_box_remove_all(GntBox *box);      /* Removes AND destroys all the widgets in it */
+
+void gnt_box_readjust(GntBox *box);
+
+void gnt_box_set_fill(GntBox *box, gboolean fill);
+
+void gnt_box_move_focus(GntBox *box, int dir);  /* +1 to move forward, -1 for backward */
+
+void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget);
+
+G_END_DECLS
+
+#endif /* GNT_BOX_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbutton.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,135 @@
+#include <string.h>
+
+#include "gntbutton.h"
+#include "gntutils.h"
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+
+static void
+gnt_button_draw(GntWidget *widget)
+{
+	GntButton *button = GNT_BUTTON(widget);
+	GntColorType type;
+
+	if (gnt_widget_has_focus(widget))
+		type = GNT_COLOR_HIGHLIGHT;
+	else
+		type = GNT_COLOR_NORMAL;
+	
+	wbkgdset(widget->window, '\0' | COLOR_PAIR(type));
+	mvwprintw(widget->window, 1, 2, button->priv->text);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_button_size_request(GntWidget *widget)
+{
+	GntButton *button = GNT_BUTTON(widget);
+	gnt_util_get_text_bound(button->priv->text,
+			&widget->priv.width, &widget->priv.height);
+	widget->priv.width += 4;
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		widget->priv.height += 2;
+}
+
+static void
+gnt_button_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static gboolean
+gnt_button_key_pressed(GntWidget *widget, const char *key)
+{
+	if (strcmp(key, GNT_KEY_ENTER) == 0)
+	{
+		gnt_widget_activate(widget);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+gnt_button_clicked(GntWidget *widget, GntMouseEvent event, int x, int y)
+{
+	if (event == GNT_LEFT_MOUSE_DOWN) {
+		gnt_widget_activate(widget);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+gnt_button_class_init(GntWidgetClass *klass)
+{
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->draw = gnt_button_draw;
+	parent_class->map = gnt_button_map;
+	parent_class->size_request = gnt_button_size_request;
+	parent_class->key_pressed = gnt_button_key_pressed;
+	parent_class->clicked = gnt_button_clicked;
+
+	GNTDEBUG;
+}
+
+static void
+gnt_button_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GntButton *button = GNT_BUTTON(instance);
+	button->priv = g_new0(GntButtonPriv, 1);
+
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X);
+
+	widget->priv.minw = 4;
+	widget->priv.minh = 3;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntButton API
+ *****************************************************************************/
+GType
+gnt_button_get_gtype(void) {
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(GntButtonClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_button_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntButton),
+			0,						/* n_preallocs		*/
+			gnt_button_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntButton",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_button_new(const char *text)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_BUTTON, NULL);
+	GntButton *button = GNT_BUTTON(widget);
+
+	button->priv->text = gnt_util_onscreen_fit_string(text, -1);
+	gnt_widget_set_take_focus(widget, TRUE);
+
+	return widget;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntbutton.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,55 @@
+#ifndef GNT_BUTTON_H
+#define GNT_BUTTON_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include "gnt.h"
+#include "gntwidget.h"
+
+#define GNT_TYPE_BUTTON				(gnt_button_get_gtype())
+#define GNT_BUTTON(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BUTTON, GntButton))
+#define GNT_BUTTON_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BUTTON, GntButtonClass))
+#define GNT_IS_BUTTON(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BUTTON))
+#define GNT_IS_BUTTON_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BUTTON))
+#define GNT_BUTTON_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BUTTON, GntButtonClass))
+
+typedef struct _GnButton			GntButton;
+typedef struct _GnButtonPriv		GntButtonPriv;
+typedef struct _GnButtonClass		GntButtonClass;
+
+struct _GnButtonPriv
+{
+	char *text;
+};
+
+struct _GnButton
+{
+	GntWidget parent;
+
+	GntButtonPriv *priv;
+
+    void (*gnt_reserved1)(void);
+    void (*gnt_reserved2)(void);
+    void (*gnt_reserved3)(void);
+    void (*gnt_reserved4)(void);
+};
+
+struct _GnButtonClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_button_get_gtype(void);
+
+GntWidget *gnt_button_new(const char *text);
+
+G_END_DECLS
+
+#endif /* GNT_BUTTON_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntcheckbox.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,155 @@
+#include "gntcheckbox.h"
+
+enum
+{
+	SIG_TOGGLED = 1,
+	SIGS,
+};
+
+static GntButtonClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+
+static void
+gnt_check_box_draw(GntWidget *widget)
+{
+	GntCheckBox *cb = GNT_CHECK_BOX(widget);
+	GntColorType type;
+	char *text;
+
+	if (gnt_widget_has_focus(widget))
+		type = GNT_COLOR_HIGHLIGHT;
+	else
+		type = GNT_COLOR_NORMAL;
+	
+	wbkgdset(widget->window, '\0' | COLOR_PAIR(type));
+
+	text = g_strdup_printf("[%c]", cb->checked ? 'X' : ' ');
+	mvwprintw(widget->window, 0, 0, text);
+	g_free(text);
+
+	wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
+	mvwprintw(widget->window, 0, 4, GNT_BUTTON(cb)->priv->text);
+	
+	GNTDEBUG;
+}
+
+static void
+toggle_selection(GntWidget *widget)
+{
+	GNT_CHECK_BOX(widget)->checked = !GNT_CHECK_BOX(widget)->checked;
+	g_signal_emit(widget, signals[SIG_TOGGLED], 0);
+	gnt_widget_draw(widget);
+}
+
+static gboolean
+gnt_check_box_key_pressed(GntWidget *widget, const char *text)
+{
+	if (text[0] == ' ' && text[1] == '\0')
+	{
+		toggle_selection(widget);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+gnt_check_box_clicked(GntWidget *widget, GntMouseEvent event, int x, int y)
+{
+	if (event == GNT_LEFT_MOUSE_DOWN) {
+		toggle_selection(widget);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+gnt_check_box_class_init(GntCheckBoxClass *klass)
+{
+	GntWidgetClass *wclass = GNT_WIDGET_CLASS(klass);
+
+	parent_class = GNT_BUTTON_CLASS(klass);
+	/*parent_class->destroy = gnt_check_box_destroy;*/
+	wclass->draw = gnt_check_box_draw;
+	/*parent_class->map = gnt_check_box_map;*/
+	/*parent_class->size_request = gnt_check_box_size_request;*/
+	wclass->key_pressed = gnt_check_box_key_pressed;
+	wclass->clicked = gnt_check_box_clicked;
+
+	signals[SIG_TOGGLED] = 
+		g_signal_new("toggled",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntCheckBoxClass, toggled),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	GNTDEBUG;
+}
+
+static void
+gnt_check_box_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	widget->priv.minh = 1;
+	widget->priv.minw = 4;
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntCheckBox API
+ *****************************************************************************/
+GType
+gnt_check_box_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntCheckBoxClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_check_box_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntCheckBox),
+			0,						/* n_preallocs		*/
+			gnt_check_box_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_BUTTON,
+									  "GntCheckBox",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_check_box_new(const char *text)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_CHECK_BOX, NULL);
+
+	GNT_BUTTON(widget)->priv->text = g_strdup(text);
+	gnt_widget_set_take_focus(widget, TRUE);
+
+	return widget;
+}
+
+void gnt_check_box_set_checked(GntCheckBox *box, gboolean set)
+{
+	if (set != box->checked)
+	{
+		box->checked = set;
+		g_signal_emit(box, signals[SIG_TOGGLED], 0);
+	}
+}
+
+gboolean gnt_check_box_get_checked(GntCheckBox *box)
+{
+	return box->checked;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntcheckbox.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,54 @@
+#ifndef GNT_CHECK_BOX_H
+#define GNT_CHECK_BOX_H
+
+#include "gntbutton.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_CHECK_BOX				(gnt_check_box_get_gtype())
+#define GNT_CHECK_BOX(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_CHECK_BOX, GntCheckBox))
+#define GNT_CHECK_BOX_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_CHECK_BOX, GntCheckBoxClass))
+#define GNT_IS_CHECK_BOX(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_CHECK_BOX))
+#define GNT_IS_CHECK_BOX_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_CHECK_BOX))
+#define GNT_CHECK_BOX_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_CHECK_BOX, GntCheckBoxClass))
+
+#define GNT_CHECK_BOX_FLAGS(obj)				(GNT_CHECK_BOX(obj)->priv.flags)
+#define GNT_CHECK_BOX_SET_FLAGS(obj, flags)		(GNT_CHECK_BOX_FLAGS(obj) |= flags)
+#define GNT_CHECK_BOX_UNSET_FLAGS(obj, flags)	(GNT_CHECK_BOX_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnCheckBox			GntCheckBox;
+typedef struct _GnCheckBoxPriv		GntCheckBoxPriv;
+typedef struct _GnCheckBoxClass		GntCheckBoxClass;
+
+struct _GnCheckBox
+{
+	GntButton parent;
+	gboolean checked;
+};
+
+struct _GnCheckBoxClass
+{
+	GntButtonClass parent;
+
+	void (*toggled)(void);
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_check_box_get_gtype(void);
+
+GntWidget *gnt_check_box_new(const char *text);
+
+void gnt_check_box_set_checked(GntCheckBox *box, gboolean set);
+
+gboolean gnt_check_box_get_checked(GntCheckBox *box);
+
+G_END_DECLS
+
+#endif /* GNT_CHECK_BOX_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntcolors.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,248 @@
+#include "config.h"
+
+#include <ncurses.h>
+
+#include "gntcolors.h"
+#include "gntstyle.h"
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static struct
+{
+	short r, g, b;
+} colors[GNT_TOTAL_COLORS];
+
+static void
+backup_colors()
+{
+	short i;
+	for (i = 0; i < GNT_TOTAL_COLORS; i++)
+	{
+		color_content(i, &colors[i].r,
+				&colors[i].g, &colors[i].b);
+	}
+}
+
+static gboolean
+can_use_custom_color()
+{
+	return (gnt_style_get_bool(GNT_STYLE_COLOR, FALSE) && can_change_color());
+}
+
+static void
+restore_colors()
+{
+	short i;
+	for (i = 0; i < GNT_TOTAL_COLORS; i++)
+	{
+		init_color(i, colors[i].r,
+				colors[i].g, colors[i].b);
+	}
+}
+
+void gnt_init_colors()
+{
+	static gboolean init = FALSE;
+	int defaults;
+
+	if (init)
+		return;
+	init = TRUE;
+
+	start_color();
+	defaults = use_default_colors();
+
+	if (can_use_custom_color())
+	{
+		backup_colors();
+
+		/* Do some init_color()s */
+		init_color(GNT_COLOR_BLACK, 0, 0, 0);
+		init_color(GNT_COLOR_RED, 1000, 0, 0);
+		init_color(GNT_COLOR_GREEN, 0, 1000, 0);
+		init_color(GNT_COLOR_BLUE, 250, 250, 700);
+		init_color(GNT_COLOR_WHITE, 1000, 1000, 1000);
+		init_color(GNT_COLOR_GRAY, 699, 699, 699);
+		init_color(GNT_COLOR_DARK_GRAY, 256, 256, 256);
+
+		/* Now some init_pair()s */
+		init_pair(GNT_COLOR_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_WHITE);
+		init_pair(GNT_COLOR_HIGHLIGHT, GNT_COLOR_WHITE, GNT_COLOR_BLUE);
+		init_pair(GNT_COLOR_SHADOW, GNT_COLOR_BLACK, GNT_COLOR_DARK_GRAY);
+
+		init_pair(GNT_COLOR_TITLE, GNT_COLOR_WHITE, GNT_COLOR_BLUE);
+		init_pair(GNT_COLOR_TITLE_D, GNT_COLOR_WHITE, GNT_COLOR_GRAY);
+
+		init_pair(GNT_COLOR_TEXT_NORMAL, GNT_COLOR_WHITE, GNT_COLOR_BLUE);
+		init_pair(GNT_COLOR_HIGHLIGHT_D, GNT_COLOR_BLACK, GNT_COLOR_GRAY);
+		init_pair(GNT_COLOR_DISABLED, GNT_COLOR_GRAY, GNT_COLOR_WHITE);
+		init_pair(GNT_COLOR_URGENT, GNT_COLOR_WHITE, GNT_COLOR_RED);
+	}
+	else
+	{
+		int bg;
+
+		if (defaults == OK) {
+			init_pair(GNT_COLOR_NORMAL, -1, -1);
+			bg = -1;
+		} else {
+			init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE);
+			bg = COLOR_WHITE;
+		}
+		init_pair(GNT_COLOR_DISABLED, COLOR_YELLOW, bg);
+		init_pair(GNT_COLOR_URGENT, COLOR_GREEN, bg);
+
+		init_pair(GNT_COLOR_HIGHLIGHT, COLOR_WHITE, COLOR_BLUE);
+		init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK);
+		init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLUE);
+		init_pair(GNT_COLOR_TITLE_D, COLOR_WHITE, COLOR_BLACK);
+		init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_WHITE, COLOR_BLUE);
+		init_pair(GNT_COLOR_HIGHLIGHT_D, COLOR_CYAN, COLOR_BLACK);
+	}
+}
+
+void
+gnt_uninit_colors()
+{
+	if (can_use_custom_color())
+		restore_colors();
+}
+
+static int
+get_color(char *key)
+{
+	int color;
+	gboolean custom = can_use_custom_color();
+
+	key = g_strstrip(key);
+
+	if (strcmp(key, "black") == 0)
+		color = custom ? GNT_COLOR_BLACK : COLOR_BLACK;
+	else if (strcmp(key, "red") == 0)
+		color = custom ? GNT_COLOR_RED : COLOR_RED;
+	else if (strcmp(key, "green") == 0)
+		color = custom ? GNT_COLOR_GREEN : COLOR_GREEN;
+	else if (strcmp(key, "blue") == 0)
+		color = custom ? GNT_COLOR_BLUE : COLOR_BLUE;
+	else if (strcmp(key, "white") == 0)
+		color = custom ? GNT_COLOR_WHITE : COLOR_WHITE;
+	else if (strcmp(key, "gray") == 0)
+		color = custom ? GNT_COLOR_GRAY : COLOR_YELLOW;  /* eh? */
+	else if (strcmp(key, "darkgray") == 0)
+		color = custom ? GNT_COLOR_DARK_GRAY : COLOR_BLACK;
+	else if (strcmp(key, "magenta") == 0)
+		color = COLOR_MAGENTA;
+	else if (strcmp(key, "cyan") == 0)
+		color = COLOR_CYAN;
+	else
+		color = -1;
+	return color;
+}
+
+#if GLIB_CHECK_VERSION(2,6,0)
+void gnt_colors_parse(GKeyFile *kfile)
+{
+	GError *error = NULL;
+	gsize nkeys;
+	char **keys = g_key_file_get_keys(kfile, "colors", &nkeys, &error);
+
+	if (error)
+	{
+		g_printerr("GntColors: %s\n", error->message);
+		g_error_free(error);
+		error = NULL;
+	}
+	else if (nkeys)
+	{
+		gnt_init_colors();
+		while (nkeys--)
+		{
+			gsize len;
+			char *key = keys[nkeys];
+			char **list = g_key_file_get_string_list(kfile, "colors", key, &len, NULL);
+			if (len == 3)
+			{
+				int r = atoi(list[0]);
+				int g = atoi(list[1]);
+				int b = atoi(list[2]);
+				int color = -1;
+
+				g_ascii_strdown(key, -1);
+				color = get_color(key);
+				if (color == -1)
+					continue;
+
+				init_color(color, r, g, b);
+			}
+			g_strfreev(list);
+		}
+
+		g_strfreev(keys);
+	}
+
+	gnt_color_pairs_parse(kfile);
+}
+
+void gnt_color_pairs_parse(GKeyFile *kfile)
+{
+	GError *error = NULL;
+	gsize nkeys;
+	char **keys = g_key_file_get_keys(kfile, "colorpairs", &nkeys, &error);
+
+	if (error)
+	{
+		g_printerr("GntColors: %s\n", error->message);
+		g_error_free(error);
+		return;
+	}
+	else if (nkeys)
+		gnt_init_colors();
+
+	while (nkeys--)
+	{
+		gsize len;
+		char *key = keys[nkeys];
+		char **list = g_key_file_get_string_list(kfile, "colorpairs", key, &len, NULL);
+		if (len == 2)
+		{
+			GntColorType type = 0;
+			int fg = get_color(g_ascii_strdown(list[0], -1));
+			int bg = get_color(g_ascii_strdown(list[1], -1));
+			if (fg == -1 || bg == -1)
+				continue;
+
+			g_ascii_strdown(key, -1);
+
+			if (strcmp(key, "normal") == 0)
+				type = GNT_COLOR_NORMAL;
+			else if (strcmp(key, "highlight") == 0)
+				type = GNT_COLOR_HIGHLIGHT;
+			else if (strcmp(key, "highlightd") == 0)
+				type = GNT_COLOR_HIGHLIGHT_D;
+			else if (strcmp(key, "shadow") == 0)
+				type = GNT_COLOR_SHADOW;
+			else if (strcmp(key, "title") == 0)
+				type = GNT_COLOR_TITLE;
+			else if (strcmp(key, "titled") == 0)
+				type = GNT_COLOR_TITLE_D;
+			else if (strcmp(key, "text") == 0)
+				type = GNT_COLOR_TEXT_NORMAL;
+			else if (strcmp(key, "disabled") == 0)
+				type = GNT_COLOR_DISABLED;
+			else if (strcmp(key, "urgent") == 0)
+				type = GNT_COLOR_URGENT;
+			else
+				continue;
+
+			init_pair(type, fg, bg);
+		}
+		g_strfreev(list);
+	}
+
+	g_strfreev(keys);
+}
+
+#endif  /* GKeyFile */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntcolors.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,46 @@
+#ifndef GNT_COLORS_H
+#define GNT_COLORS_H
+
+#include <glib.h>
+
+typedef enum
+{
+	GNT_COLOR_NORMAL = 1,
+	GNT_COLOR_HIGHLIGHT,		/* eg. when a button is selected */
+	GNT_COLOR_DISABLED,		/* eg. when a button is disabled */
+	GNT_COLOR_HIGHLIGHT_D,	/* eg. when a button is selected, but some other window is in focus */
+	GNT_COLOR_TEXT_NORMAL,
+	GNT_COLOR_TEXT_INACTIVE,	/* when the entry is out of focus */
+	GNT_COLOR_MNEMONIC,
+	GNT_COLOR_MNEMONIC_D,
+	GNT_COLOR_SHADOW,
+	GNT_COLOR_TITLE,
+	GNT_COLOR_TITLE_D,
+	GNT_COLOR_URGENT,       /* this is for the 'urgent' windows */
+	GNT_COLORS
+} GntColorType;
+
+enum
+{
+	GNT_COLOR_BLACK = 0,
+	GNT_COLOR_RED,
+	GNT_COLOR_GREEN,
+	GNT_COLOR_BLUE,
+	GNT_COLOR_WHITE,
+	GNT_COLOR_GRAY,
+	GNT_COLOR_DARK_GRAY,
+	GNT_TOTAL_COLORS
+};
+
+/* populate some default colors */
+void gnt_init_colors();
+
+void gnt_uninit_colors();
+
+#if GLIB_CHECK_VERSION(2,6,0)
+void gnt_colors_parse(GKeyFile *kfile);
+
+void gnt_color_pairs_parse(GKeyFile *kfile);
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntcombobox.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,305 @@
+#include "gntbox.h"
+#include "gntcombobox.h"
+#include "gnttree.h"
+#include "gntmarshal.h"
+#include "gntutils.h"
+
+#include <string.h>
+
+enum
+{
+	SIG_SELECTION_CHANGED,
+	SIGS,
+};
+
+static GntWidgetClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+static void (*widget_lost_focus)(GntWidget *widget);
+
+static void
+set_selection(GntComboBox *box, gpointer key)
+{
+	if (box->selected != key)
+	{
+		/* XXX: make sure the key actually does exist */
+		gpointer old = box->selected;
+		box->selected = key;
+		if (GNT_WIDGET(box)->window)
+			gnt_widget_draw(GNT_WIDGET(box));
+		if (box->dropdown)
+			gnt_tree_set_selected(GNT_TREE(box->dropdown), key);
+		g_signal_emit(box, signals[SIG_SELECTION_CHANGED], 0, old, key);
+	}
+}
+
+static void
+gnt_combo_box_draw(GntWidget *widget)
+{
+	GntComboBox *box = GNT_COMBO_BOX(widget);
+	char *text = NULL, *s;
+	GntColorType type;
+	int len;
+	
+	if (box->dropdown && box->selected)
+		text = gnt_tree_get_selection_text(GNT_TREE(box->dropdown));
+
+	if (text == NULL)
+		text = g_strdup("");
+
+	if (gnt_widget_has_focus(widget))
+		type = GNT_COLOR_HIGHLIGHT;
+	else
+		type = GNT_COLOR_NORMAL;
+
+	wbkgdset(widget->window, '\0' | COLOR_PAIR(type));
+
+	s = (char*)gnt_util_onscreen_width_to_pointer(text, widget->priv.width - 4, &len);
+	*s = '\0';
+
+	mvwprintw(widget->window, 1, 1, text);
+	whline(widget->window, ' ' | COLOR_PAIR(type), widget->priv.width - 4 - len);
+	mvwaddch(widget->window, 1, widget->priv.width - 3, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL));
+	mvwaddch(widget->window, 1, widget->priv.width - 2, ACS_DARROW | COLOR_PAIR(GNT_COLOR_NORMAL));
+
+	g_free(text);
+	GNTDEBUG;
+}
+
+static void
+gnt_combo_box_size_request(GntWidget *widget)
+{
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		GntWidget *dd = GNT_COMBO_BOX(widget)->dropdown;
+		gnt_widget_size_request(dd);
+		widget->priv.height = 3;   /* For now, a combobox will have border */
+		widget->priv.width = MAX(10, dd->priv.width + 4);
+	}
+}
+
+static void
+gnt_combo_box_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static void
+popup_dropdown(GntComboBox *box)
+{
+	GntWidget *widget = GNT_WIDGET(box);
+	GntWidget *parent = box->dropdown->parent;
+	int height = g_list_length(GNT_TREE(box->dropdown)->list);
+	int y = widget->priv.y + widget->priv.height - 1;
+	gnt_widget_set_size(box->dropdown, widget->priv.width, height + 2);
+
+	if (y + height + 2 >= getmaxy(stdscr))
+		y = widget->priv.y - height - 1;
+	gnt_widget_set_position(parent, widget->priv.x, y);
+	if (parent->window)
+	{
+		mvwin(parent->window, y, widget->priv.x);
+		wresize(parent->window, height+2, widget->priv.width);
+	}
+	parent->priv.width = widget->priv.width;
+	parent->priv.height = height + 2;
+
+	GNT_WIDGET_UNSET_FLAGS(parent, GNT_WIDGET_INVISIBLE);
+	gnt_widget_draw(parent);
+}
+
+static gboolean
+gnt_combo_box_key_pressed(GntWidget *widget, const char *text)
+{
+	GntComboBox *box = GNT_COMBO_BOX(widget);
+	if (GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED))
+	{
+		if (text[1] == 0)
+		{
+			switch (text[0])
+			{
+				case '\r':
+				case '\t':
+					set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown)));
+				case 27:
+					gnt_tree_set_selected(GNT_TREE(box->dropdown), box->selected);
+					gnt_widget_hide(box->dropdown->parent);
+					return TRUE;
+					break;
+			}
+		}
+		if (gnt_widget_key_pressed(box->dropdown, text))
+			return TRUE;
+	}
+	else
+	{
+		if (text[0] == 27)
+		{
+			if (strcmp(text, GNT_KEY_UP) == 0 ||
+					strcmp(text, GNT_KEY_DOWN) == 0)
+			{
+				popup_dropdown(box);
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+static void
+gnt_combo_box_destroy(GntWidget *widget)
+{
+	gnt_widget_destroy(GNT_COMBO_BOX(widget)->dropdown->parent);
+}
+
+static void
+gnt_combo_box_lost_focus(GntWidget *widget)
+{
+	GntComboBox *combo = GNT_COMBO_BOX(widget);
+	if (GNT_WIDGET_IS_FLAG_SET(combo->dropdown->parent, GNT_WIDGET_MAPPED))
+		gnt_widget_hide(GNT_COMBO_BOX(widget)->dropdown->parent);
+	widget_lost_focus(widget);
+}
+
+static gboolean
+gnt_combo_box_clicked(GntWidget *widget, GntMouseEvent event, int x, int y)
+{
+	GntComboBox *box = GNT_COMBO_BOX(widget);
+	gboolean dshowing = GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED);
+
+	if (event == GNT_MOUSE_SCROLL_UP) {
+		if (dshowing)
+			gnt_widget_key_pressed(box->dropdown, GNT_KEY_UP);
+	} else if (event == GNT_MOUSE_SCROLL_DOWN) {
+		if (dshowing)
+			gnt_widget_key_pressed(box->dropdown, GNT_KEY_DOWN);
+	} else if (event == GNT_LEFT_MOUSE_DOWN) {
+		if (dshowing) {
+			set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown)));
+			gnt_widget_hide(box->dropdown->parent);
+		} else {
+			popup_dropdown(GNT_COMBO_BOX(widget));
+		}
+	} else
+		return FALSE;
+	return TRUE;
+}
+
+static void
+gnt_combo_box_class_init(GntComboBoxClass *klass)
+{
+	parent_class = GNT_WIDGET_CLASS(klass);
+
+	parent_class->destroy = gnt_combo_box_destroy;
+	parent_class->draw = gnt_combo_box_draw;
+	parent_class->map = gnt_combo_box_map;
+	parent_class->size_request = gnt_combo_box_size_request;
+	parent_class->key_pressed = gnt_combo_box_key_pressed;
+	parent_class->clicked = gnt_combo_box_clicked;
+
+	widget_lost_focus = parent_class->lost_focus;
+	parent_class->lost_focus = gnt_combo_box_lost_focus;
+
+	signals[SIG_SELECTION_CHANGED] = 
+		g_signal_new("selection-changed",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 0,
+					 NULL, NULL,
+					 gnt_closure_marshal_VOID__POINTER_POINTER,
+					 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_combo_box_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *box;
+	GntWidget *widget = GNT_WIDGET(instance);
+	GntComboBox *combo = GNT_COMBO_BOX(instance);
+
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance),
+			GNT_WIDGET_GROW_X | GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_NO_SHADOW);
+	combo->dropdown = gnt_tree_new();
+
+	box = gnt_box_new(FALSE, FALSE);
+	GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT);
+	gnt_box_set_pad(GNT_BOX(box), 0);
+	gnt_box_add_widget(GNT_BOX(box), combo->dropdown);
+	
+	widget->priv.minw = 4;
+	widget->priv.minh = 3;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntComboBox API
+ *****************************************************************************/
+GType
+gnt_combo_box_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntComboBoxClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_combo_box_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntComboBox),
+			0,						/* n_preallocs		*/
+			gnt_combo_box_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntComboBox",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_combo_box_new()
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_COMBO_BOX, NULL);
+
+	return widget;
+}
+
+void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text)
+{
+	gnt_tree_add_row_last(GNT_TREE(box->dropdown), key,
+			gnt_tree_create_row(GNT_TREE(box->dropdown), text), NULL);
+	if (box->selected == NULL)
+		set_selection(box, key);
+}
+
+gpointer gnt_combo_box_get_selected_data(GntComboBox *box)
+{
+	return box->selected;
+}
+
+void gnt_combo_box_set_selected(GntComboBox *box, gpointer key)
+{
+	set_selection(box, key);
+}
+
+void gnt_combo_box_remove(GntComboBox *box, gpointer key)
+{
+	gnt_tree_remove(GNT_TREE(box->dropdown), key);
+	if (box->selected == key)
+		set_selection(box, NULL);
+}
+
+void gnt_combo_box_remove_all(GntComboBox *box)
+{
+	gnt_tree_remove_all(GNT_TREE(box->dropdown));
+	set_selection(box, NULL);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntcombobox.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,61 @@
+#ifndef GNT_COMBO_BOX_H
+#define GNT_COMBO_BOX_H
+
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+#include "gntwidget.h"
+
+#define GNT_TYPE_COMBO_BOX				(gnt_combo_box_get_gtype())
+#define GNT_COMBO_BOX(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_COMBO_BOX, GntComboBox))
+#define GNT_COMBO_BOX_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_COMBO_BOX, GntComboBoxClass))
+#define GNT_IS_COMBO_BOX(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_COMBO_BOX))
+#define GNT_IS_COMBO_BOX_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_COMBO_BOX))
+#define GNT_COMBO_BOX_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_COMBO_BOX, GntComboBoxClass))
+
+#define GNT_COMBO_BOX_FLAGS(obj)				(GNT_COMBO_BOX(obj)->priv.flags)
+#define GNT_COMBO_BOX_SET_FLAGS(obj, flags)		(GNT_COMBO_BOX_FLAGS(obj) |= flags)
+#define GNT_COMBO_BOX_UNSET_FLAGS(obj, flags)	(GNT_COMBO_BOX_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnComboBox			GntComboBox;
+typedef struct _GnComboBoxPriv		GntComboBoxPriv;
+typedef struct _GnComboBoxClass		GntComboBoxClass;
+
+struct _GnComboBox
+{
+	GntWidget parent;
+
+	GntWidget *dropdown;   /* This is a GntTree */
+
+	void *selected;        /* Currently selected key */
+};
+
+struct _GnComboBoxClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_combo_box_get_gtype(void);
+
+GntWidget *gnt_combo_box_new();
+
+void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text);
+
+void gnt_combo_box_remove(GntComboBox *box, gpointer key);
+
+void gnt_combo_box_remove_all(GntComboBox *box);
+
+gpointer gnt_combo_box_get_selected_data(GntComboBox *box);
+
+void gnt_combo_box_set_selected(GntComboBox *box, gpointer key);
+
+G_END_DECLS
+
+#endif /* GNT_COMBO_BOX_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntentry.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,909 @@
+#include <ctype.h>
+#include <string.h>
+
+#include "gntbox.h"
+#include "gntentry.h"
+#include "gntstyle.h"
+#include "gnttree.h"
+#include "gntutils.h"
+
+enum
+{
+	SIG_TEXT_CHANGED,
+	SIGS,
+};
+static guint signals[SIGS] = { 0 };
+
+static GntWidgetClass *parent_class = NULL;
+
+static void gnt_entry_set_text_internal(GntEntry *entry, const char *text);
+
+static void
+destroy_suggest(GntEntry *entry)
+{
+	if (entry->ddown)
+	{
+		gnt_widget_destroy(entry->ddown->parent);
+		entry->ddown = NULL;
+	}
+}
+
+static char *
+get_beginning_of_word(GntEntry *entry)
+{
+	char *s = entry->cursor;
+	while (s > entry->start)
+	{
+		char *t = g_utf8_find_prev_char(entry->start, s);
+		if (isspace(*t))
+			break;
+		s = t;
+	}
+	return s;
+}
+
+static gboolean
+show_suggest_dropdown(GntEntry *entry)
+{
+	char *suggest = NULL;
+	int len;
+	int offset = 0, x, y;
+	int count = 0;
+	GList *iter;
+
+	if (entry->word)
+	{
+		char *s = get_beginning_of_word(entry);
+		suggest = g_strndup(s, entry->cursor - s);
+		if (entry->scroll < s)
+			offset = gnt_util_onscreen_width(entry->scroll, s);
+	}
+	else
+		suggest = g_strdup(entry->start);
+	len = strlen(suggest);  /* Don't need to use the utf8-function here */
+	
+	if (entry->ddown == NULL)
+	{
+		GntWidget *box = gnt_vbox_new(FALSE);
+		entry->ddown = gnt_tree_new();
+		gnt_tree_set_compare_func(GNT_TREE(entry->ddown), (GCompareFunc)g_utf8_collate);
+		gnt_box_add_widget(GNT_BOX(box), entry->ddown);
+		/* XXX: Connect to the "activate" signal for the dropdown tree */
+
+		GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT);
+
+		gnt_widget_get_position(GNT_WIDGET(entry), &x, &y);
+		x += offset;
+		y++;
+		if (y + 10 >= getmaxy(stdscr))
+			y -= 11;
+		gnt_widget_set_position(box, x, y);
+	}
+	else
+		gnt_tree_remove_all(GNT_TREE(entry->ddown));
+
+	for (count = 0, iter = entry->suggests; iter; iter = iter->next)
+	{
+		const char *text = iter->data;
+		if (g_ascii_strncasecmp(suggest, text, len) == 0 && strlen(text) >= len)
+		{
+			gnt_tree_add_row_after(GNT_TREE(entry->ddown), (gpointer)text,
+					gnt_tree_create_row(GNT_TREE(entry->ddown), text),
+					NULL, NULL);
+			count++;
+		}
+	}
+	g_free(suggest);
+
+	if (count == 0)
+	{
+		destroy_suggest(entry);
+		return FALSE;
+	}
+
+	gnt_widget_draw(entry->ddown->parent);
+	return TRUE;
+}
+
+static void
+gnt_entry_draw(GntWidget *widget)
+{
+	GntEntry *entry = GNT_ENTRY(widget);
+	int stop;
+	gboolean focus;
+
+	if ((focus = gnt_widget_has_focus(widget)))
+		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TEXT_NORMAL));
+	else
+		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+
+	if (entry->masked)
+	{
+		mvwhline(widget->window, 0, 0, gnt_ascii_only() ? '*' : ACS_BULLET,
+				g_utf8_pointer_to_offset(entry->scroll, entry->end));
+	}
+	else
+		mvwprintw(widget->window, 0, 0, "%s", entry->scroll);
+
+	stop = gnt_util_onscreen_width(entry->scroll, entry->end);
+	if (stop < widget->priv.width)
+		whline(widget->window, ENTRY_CHAR, widget->priv.width - stop);
+
+	if (focus)
+		mvwchgat(widget->window, 0, gnt_util_onscreen_width(entry->scroll, entry->cursor),
+				1, A_REVERSE, GNT_COLOR_TEXT_NORMAL, NULL);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_entry_size_request(GntWidget *widget)
+{
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		widget->priv.height = 1;
+		widget->priv.width = 20;
+	}
+}
+
+static void
+gnt_entry_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static void
+entry_redraw(GntWidget *widget)
+{
+	gnt_entry_draw(widget);
+	gnt_widget_queue_update(widget);
+}
+
+static void
+entry_text_changed(GntEntry *entry)
+{
+	g_signal_emit(entry, signals[SIG_TEXT_CHANGED], 0);
+}
+
+static gboolean
+move_back(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->cursor <= entry->start)
+		return FALSE;
+	entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);
+	if (entry->cursor < entry->scroll)
+		entry->scroll = entry->cursor;
+	entry_redraw(GNT_WIDGET(entry));
+	return TRUE;
+}
+
+static gboolean
+move_forward(GntBindable *bind, GList *list)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->cursor >= entry->end)
+		return FALSE;
+	entry->cursor = g_utf8_find_next_char(entry->cursor, NULL);
+	while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width)
+		entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
+	entry_redraw(GNT_WIDGET(entry));
+	return TRUE;
+}
+
+static gboolean
+backspace(GntBindable *bind, GList *null)
+{
+	int len;
+	GntEntry *entry = GNT_ENTRY(bind);
+
+	if (entry->cursor <= entry->start)
+		return TRUE;
+	
+	len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor);
+	entry->cursor -= len;
+	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor);
+	entry->end -= len;
+
+	if (entry->scroll > entry->start)
+		entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll);
+
+	entry_redraw(GNT_WIDGET(entry));
+	if (entry->ddown)
+		show_suggest_dropdown(entry);
+	entry_text_changed(entry);
+	return TRUE;
+}
+
+static gboolean
+delkey(GntBindable *bind, GList *null)
+{
+	int len;
+	GntEntry *entry = GNT_ENTRY(bind);
+
+	if (entry->cursor >= entry->end)
+		return FALSE;
+	
+	len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor;
+	memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1);
+	entry->end -= len;
+	entry_redraw(GNT_WIDGET(entry));
+
+	if (entry->ddown)
+		show_suggest_dropdown(entry);
+	entry_text_changed(entry);
+	return TRUE;
+}
+
+static gboolean
+move_start(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	entry->scroll = entry->cursor = entry->start;
+	entry_redraw(GNT_WIDGET(entry));
+	return TRUE;
+}
+
+static gboolean
+move_end(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	entry->cursor = entry->end;
+	/* This should be better than this */
+	while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width)
+		entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
+	entry_redraw(GNT_WIDGET(entry));
+	return TRUE;
+}
+
+static gboolean
+history_prev(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->histlength && entry->history->prev)
+	{
+		entry->history = entry->history->prev;
+		gnt_entry_set_text_internal(entry, entry->history->data);
+		destroy_suggest(entry);
+		entry_text_changed(entry);
+
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+history_next(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->histlength && entry->history->next)
+	{
+		if (entry->history->prev == NULL)
+		{
+			/* Save the current contents */
+			char *text = g_strdup(gnt_entry_get_text(entry));
+			g_free(entry->history->data);
+			entry->history->data = text;
+		}
+
+		entry->history = entry->history->next;
+		gnt_entry_set_text_internal(entry, entry->history->data);
+		destroy_suggest(entry);
+		entry_text_changed(entry);
+
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+suggest_show(GntBindable *bind, GList *null)
+{
+	return show_suggest_dropdown(GNT_ENTRY(bind));
+}
+
+static gboolean
+suggest_next(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->ddown) {
+		gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down", NULL);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+suggest_prev(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->ddown) {
+		gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-up", NULL);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+del_to_home(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->cursor <= entry->start)
+		return TRUE;
+	memmove(entry->start, entry->cursor, entry->end - entry->cursor);
+	entry->end -= (entry->cursor - entry->start);
+	entry->cursor = entry->scroll = entry->start;
+	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
+	entry_redraw(GNT_WIDGET(bind));
+	entry_text_changed(entry);
+	return TRUE;
+}
+
+static gboolean
+del_to_end(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	if (entry->end <= entry->cursor)
+		return TRUE;
+	entry->end = entry->cursor;
+	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
+	entry_redraw(GNT_WIDGET(bind));
+	entry_text_changed(entry);
+	return TRUE;
+}
+
+#define SAME(a,b)    ((g_unichar_isalpha(a) && g_unichar_isalpha(b)) || \
+				(g_unichar_isdigit(a) && g_unichar_isdigit(b)) || \
+				(g_unichar_isspace(a) && g_unichar_isspace(b)) || \
+				(g_unichar_iswide(a) && g_unichar_iswide(b)))
+
+static const char *
+begin_word(const char *text, const char *begin)
+{
+	gunichar ch = 0;
+	while (text > begin && (!*text || g_unichar_isspace(g_utf8_get_char(text))))
+		text = g_utf8_find_prev_char(begin, text);
+	ch = g_utf8_get_char(text);
+	while ((text = g_utf8_find_prev_char(begin, text)) >= begin) {
+		gunichar cur = g_utf8_get_char(text);
+		if (!SAME(ch, cur))
+			break;
+	}
+
+	return (text ? g_utf8_find_next_char(text, NULL) : begin);
+}
+
+static const char *
+next_begin_word(const char *text, const char *end)
+{
+	gunichar ch = 0;
+	ch = g_utf8_get_char(text);
+	while ((text = g_utf8_find_next_char(text, end)) != NULL && text <= end) {
+		gunichar cur = g_utf8_get_char(text);
+		if (!SAME(ch, cur))
+			break;
+	}
+
+	while (text && text < end && g_unichar_isspace(g_utf8_get_char(text)))
+		text = g_utf8_find_next_char(text, end);
+	return (text ? text : end);
+}
+
+#undef SAME
+static gboolean
+move_back_word(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	const char *iter = g_utf8_find_prev_char(entry->start, entry->cursor);
+
+	if (iter < entry->start)
+		return TRUE;
+	iter = begin_word(iter, entry->start);
+	entry->cursor = (char*)iter;
+	if (entry->cursor < entry->scroll)
+		entry->scroll = entry->cursor;
+	entry_redraw(GNT_WIDGET(bind));
+	return TRUE;
+}
+
+static gboolean
+del_prev_word(GntBindable *bind, GList *null)
+{
+	GntWidget *widget = GNT_WIDGET(bind);
+	GntEntry *entry = GNT_ENTRY(bind);
+	char *iter = g_utf8_find_prev_char(entry->start, entry->cursor);
+	int count;
+
+	if (iter < entry->start)
+		return TRUE;
+	iter = (char*)begin_word(iter, entry->start);
+	count = entry->cursor - iter;
+	memmove(iter, entry->cursor, entry->end - entry->cursor);
+	entry->end -= count;
+	entry->cursor = iter;
+	if (entry->cursor <= entry->scroll) {
+		entry->scroll = entry->cursor - widget->priv.width + 2;
+		if (entry->scroll < entry->start)
+			entry->scroll = entry->start;
+	}
+	memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
+	entry_redraw(widget);
+	entry_text_changed(entry);
+
+	return TRUE;
+}
+
+static gboolean
+move_forward_word(GntBindable *bind, GList *list)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	GntWidget *widget = GNT_WIDGET(bind);
+	entry->cursor = (char *)next_begin_word(entry->cursor, entry->end);
+	while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width) {
+		entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
+	}
+	entry_redraw(widget);
+	return TRUE;
+}
+
+static gboolean
+delete_forward_word(GntBindable *bind, GList *list)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	GntWidget *widget = GNT_WIDGET(bind);
+	char *iter = (char *)next_begin_word(entry->cursor, entry->end);
+	int len = entry->end - iter + 1;
+	if (len <= 0)
+		return TRUE;
+	memmove(entry->cursor, iter, len);
+	len = iter - entry->cursor;
+	entry->end -= len;
+	memset(entry->end, '\0', len);
+	entry_redraw(widget);
+	entry_text_changed(entry);
+	return TRUE;
+}
+
+static gboolean
+gnt_entry_key_pressed(GntWidget *widget, const char *text)
+{
+	GntEntry *entry = GNT_ENTRY(widget);
+
+	if (text[0] == 27)
+	{
+		if (text[1] == 0)
+		{
+			destroy_suggest(entry);
+			return TRUE;
+		}
+
+		return FALSE;
+	}
+	else
+	{
+		if (text[0] == '\t')
+		{
+			if (entry->ddown)
+				destroy_suggest(entry);
+			else if (entry->suggests)
+				return show_suggest_dropdown(entry);
+
+			return FALSE;
+		}
+		else if (text[0] == '\r' && entry->ddown)
+		{
+			char *text = g_strdup(gnt_tree_get_selection_data(GNT_TREE(entry->ddown)));
+			destroy_suggest(entry);
+			if (entry->word)
+			{
+				char *s = get_beginning_of_word(entry);
+				char *iter = text;
+				while (*iter && toupper(*s) == toupper(*iter))
+				{
+					*s++ = *iter++;
+				}
+				gnt_entry_key_pressed(widget, iter);
+			}
+			else
+			{
+				gnt_entry_set_text_internal(entry, text);
+			}
+			g_free(text);
+			entry_text_changed(entry);
+			return TRUE;
+		}
+
+		if (!iscntrl(text[0]))
+		{
+			const char *str, *next;
+
+			for (str = text; *str; str = next)
+			{
+				int len;
+				next = g_utf8_find_next_char(str, NULL);
+				len = next - str;
+
+				/* Valid input? */
+				/* XXX: Is it necessary to use _unichar_ variants here? */
+				if (ispunct(*str) && (entry->flag & GNT_ENTRY_FLAG_NO_PUNCT))
+					continue;
+				if (isspace(*str) && (entry->flag & GNT_ENTRY_FLAG_NO_SPACE))
+					continue;
+				if (isalpha(*str) && !(entry->flag & GNT_ENTRY_FLAG_ALPHA))
+					continue;
+				if (isdigit(*str) && !(entry->flag & GNT_ENTRY_FLAG_INT))
+					continue;
+
+				/* Reached the max? */
+				if (entry->max && g_utf8_pointer_to_offset(entry->start, entry->end) >= entry->max)
+					continue;
+
+				if (entry->end + len - entry->start >= entry->buffer)
+				{
+					/* This will cause the buffer to grow */
+					char *tmp = g_strdup_printf("%s%*s", entry->start, len, "");
+					gnt_entry_set_text_internal(entry, tmp);
+					g_free(tmp);
+				}
+
+				memmove(entry->cursor + len, entry->cursor, entry->end - entry->cursor + 1);
+				entry->end += len;
+
+				while (str < next)
+				{
+					if (*str == '\r' || *str == '\n')
+						*entry->cursor = ' ';
+					else
+						*entry->cursor = *str;
+					entry->cursor++;
+					str++;
+				}
+
+				while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width)
+					entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
+
+				if (entry->ddown)
+					show_suggest_dropdown(entry);
+			}
+			entry_redraw(widget);
+			entry_text_changed(entry);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static void
+gnt_entry_destroy(GntWidget *widget)
+{
+	GntEntry *entry = GNT_ENTRY(widget);
+	g_free(entry->start);
+
+	if (entry->history)
+	{
+		entry->history = g_list_first(entry->history);
+		g_list_foreach(entry->history, (GFunc)g_free, NULL);
+		g_list_free(entry->history);
+	}
+
+	if (entry->suggests)
+	{
+		g_list_foreach(entry->suggests, (GFunc)g_free, NULL);
+		g_list_free(entry->suggests);
+	}
+
+	if (entry->ddown)
+	{
+		gnt_widget_destroy(entry->ddown->parent);
+	}
+}
+
+static void
+gnt_entry_lost_focus(GntWidget *widget)
+{
+	GntEntry *entry = GNT_ENTRY(widget);
+	destroy_suggest(entry);
+	entry_redraw(widget);
+}
+
+static void
+gnt_entry_class_init(GntEntryClass *klass)
+{
+	GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass);
+	char s[2] = {erasechar(), 0};
+
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_entry_destroy;
+	parent_class->draw = gnt_entry_draw;
+	parent_class->map = gnt_entry_map;
+	parent_class->size_request = gnt_entry_size_request;
+	parent_class->key_pressed = gnt_entry_key_pressed;
+	parent_class->lost_focus = gnt_entry_lost_focus;
+
+	signals[SIG_TEXT_CHANGED] =
+		g_signal_new("text_changed",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntEntryClass, text_changed),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+
+	gnt_bindable_class_register_action(bindable, "cursor-home", move_start,
+				GNT_KEY_CTRL_A, NULL);
+	gnt_bindable_register_binding(bindable, "cursor-home", GNT_KEY_HOME, NULL);
+	gnt_bindable_class_register_action(bindable, "cursor-end", move_end,
+				GNT_KEY_CTRL_E, NULL);
+	gnt_bindable_register_binding(bindable, "cursor-end", GNT_KEY_END, NULL);
+	gnt_bindable_class_register_action(bindable, "delete-prev", backspace,
+				GNT_KEY_BACKSPACE, NULL);
+	gnt_bindable_register_binding(bindable, "delete-prev", s, NULL);
+	gnt_bindable_register_binding(bindable, "delete-prev", GNT_KEY_CTRL_H, NULL);
+	gnt_bindable_class_register_action(bindable, "delete-next", delkey,
+				GNT_KEY_DEL, NULL);
+	gnt_bindable_register_binding(bindable, "delete-next", GNT_KEY_CTRL_D, NULL);
+	gnt_bindable_class_register_action(bindable, "delete-start", del_to_home,
+				GNT_KEY_CTRL_U, NULL);
+	gnt_bindable_class_register_action(bindable, "delete-end", del_to_end,
+				GNT_KEY_CTRL_K, NULL);
+	gnt_bindable_class_register_action(bindable, "delete-prev-word", del_prev_word,
+				GNT_KEY_CTRL_W, NULL);
+	gnt_bindable_class_register_action(bindable, "cursor-prev-word", move_back_word,
+				"\033" "b", NULL);
+	gnt_bindable_class_register_action(bindable, "cursor-prev", move_back,
+				GNT_KEY_LEFT, NULL);
+	gnt_bindable_register_binding(bindable, "cursor-prev", GNT_KEY_CTRL_B, NULL);
+	gnt_bindable_class_register_action(bindable, "cursor-next", move_forward,
+				GNT_KEY_RIGHT, NULL);
+	gnt_bindable_register_binding(bindable, "cursor-next", GNT_KEY_CTRL_F, NULL);
+	gnt_bindable_class_register_action(bindable, "cursor-next-word", move_forward_word,
+				"\033" "f", NULL);
+	gnt_bindable_class_register_action(bindable, "delete-next-word", delete_forward_word,
+				"\033" "d", NULL);
+	gnt_bindable_class_register_action(bindable, "suggest-show", suggest_show,
+				"\t", NULL);
+	gnt_bindable_class_register_action(bindable, "suggest-next", suggest_next,
+				GNT_KEY_DOWN, NULL);
+	gnt_bindable_class_register_action(bindable, "suggest-prev", suggest_prev,
+				GNT_KEY_UP, NULL);
+	gnt_bindable_class_register_action(bindable, "history-prev", history_prev,
+				GNT_KEY_CTRL_DOWN, NULL);
+	gnt_bindable_class_register_action(bindable, "history-next", history_next,
+				GNT_KEY_CTRL_UP, NULL);
+
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
+	GNTDEBUG;
+}
+
+static void
+gnt_entry_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GntEntry *entry = GNT_ENTRY(instance);
+
+	entry->flag = GNT_ENTRY_FLAG_ALL;
+	entry->max = 0;
+	
+	entry->histlength = 0;
+	entry->history = NULL;
+
+	entry->word = TRUE;
+	entry->always = FALSE;
+	entry->suggests = NULL;
+
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
+			GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_GROW_X);
+
+	widget->priv.minw = 3;
+	widget->priv.minh = 1;
+	
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntEntry API
+ *****************************************************************************/
+GType
+gnt_entry_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntEntryClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_entry_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntEntry),
+			0,						/* n_preallocs		*/
+			gnt_entry_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntEntry",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_entry_new(const char *text)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_ENTRY, NULL);
+	GntEntry *entry = GNT_ENTRY(widget);
+
+	gnt_entry_set_text_internal(entry, text);
+
+	return widget;
+}
+
+static void
+gnt_entry_set_text_internal(GntEntry *entry, const char *text)
+{
+	int len;
+	int scroll, cursor;
+
+	g_free(entry->start);
+
+	if (text && text[0])
+	{
+		len = strlen(text);
+	}
+	else
+	{
+		len = 0;
+	}
+
+	entry->buffer = len + 128;
+
+	scroll = entry->scroll - entry->start;
+	cursor = entry->end - entry->cursor;
+
+	entry->start = g_new0(char, entry->buffer);
+	if (text)
+		snprintf(entry->start, len + 1, "%s", text);
+	entry->end = entry->start + len;
+
+	entry->scroll = entry->start + scroll;
+	entry->cursor = entry->end - cursor;
+
+	if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(entry), GNT_WIDGET_MAPPED))
+		entry_redraw(GNT_WIDGET(entry));
+}
+
+void gnt_entry_set_text(GntEntry *entry, const char *text)
+{
+	gboolean changed = TRUE;
+	if (text == NULL && entry->start == NULL)
+		changed = FALSE;
+	if (text && entry->start && g_utf8_collate(text, entry->start) == 0)
+		changed = FALSE;
+	gnt_entry_set_text_internal(entry, text);
+	if (changed)
+		entry_text_changed(entry);
+}
+
+void gnt_entry_set_max(GntEntry *entry, int max)
+{
+	entry->max = max;
+}
+
+void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag)
+{
+	entry->flag = flag;
+	/* XXX: Check the existing string to make sure the flags are respected? */
+}
+
+const char *gnt_entry_get_text(GntEntry *entry)
+{
+	return entry->start;
+}
+
+void gnt_entry_clear(GntEntry *entry)
+{
+	gnt_entry_set_text_internal(entry, NULL);
+	entry->scroll = entry->cursor = entry->end = entry->start;
+	entry_redraw(GNT_WIDGET(entry));
+	destroy_suggest(entry);
+	entry_text_changed(entry);
+}
+
+void gnt_entry_set_masked(GntEntry *entry, gboolean set)
+{
+	entry->masked = set;
+}
+
+void gnt_entry_add_to_history(GntEntry *entry, const char *text)
+{
+	g_return_if_fail(entry->history != NULL);   /* Need to set_history_length first */
+
+	if (g_list_length(entry->history) >= entry->histlength)
+		return;
+
+	entry->history = g_list_first(entry->history);
+	g_free(entry->history->data);
+	entry->history->data = g_strdup(text);
+	entry->history = g_list_prepend(entry->history, NULL);
+}
+
+void gnt_entry_set_history_length(GntEntry *entry, int num)
+{
+	if (num == 0)
+	{
+		entry->histlength = num;
+		if (entry->history)
+		{
+			entry->history = g_list_first(entry->history);
+			g_list_foreach(entry->history, (GFunc)g_free, NULL);
+			g_list_free(entry->history);
+			entry->history = NULL;
+		}
+		return;
+	}
+
+	if (entry->histlength == 0)
+	{
+		entry->histlength = num;
+		entry->history = g_list_append(NULL, NULL);
+		return;
+	}
+
+	if (num > 0 && num < entry->histlength)
+	{
+		GList *first, *iter;
+		int index = 0;
+		for (first = entry->history, index = 0; first->prev; first = first->prev, index++);
+		while ((iter = g_list_nth(first, num)) != NULL)
+		{
+			g_free(iter->data);
+			first = g_list_delete_link(first, iter);
+		}
+		entry->histlength = num;
+		if (index >= num)
+			entry->history = g_list_last(first);
+		return;
+	}
+
+	entry->histlength = num;
+}
+
+void gnt_entry_set_word_suggest(GntEntry *entry, gboolean word)
+{
+	entry->word = word;
+}
+
+void gnt_entry_set_always_suggest(GntEntry *entry, gboolean always)
+{
+	entry->always = always;
+}
+
+void gnt_entry_add_suggest(GntEntry *entry, const char *text)
+{
+	GList *find;
+
+	if (!text || !*text)
+		return;
+	
+	find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate);
+	if (find)
+		return;
+	entry->suggests = g_list_append(entry->suggests, g_strdup(text));
+}
+
+void gnt_entry_remove_suggest(GntEntry *entry, const char *text)
+{
+	GList *find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate);
+	if (find)
+	{
+		g_free(find->data);
+		entry->suggests = g_list_delete_link(entry->suggests, find);
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntentry.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,106 @@
+#ifndef GNT_ENTRY_H
+#define GNT_ENTRY_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_ENTRY				(gnt_entry_get_gtype())
+#define GNT_ENTRY(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_ENTRY, GntEntry))
+#define GNT_ENTRY_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_ENTRY, GntEntryClass))
+#define GNT_IS_ENTRY(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_ENTRY))
+#define GNT_IS_ENTRY_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_ENTRY))
+#define GNT_ENTRY_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_ENTRY, GntEntryClass))
+
+#define GNT_ENTRY_FLAGS(obj)				(GNT_ENTRY(obj)->priv.flags)
+#define GNT_ENTRY_SET_FLAGS(obj, flags)		(GNT_ENTRY_FLAGS(obj) |= flags)
+#define GNT_ENTRY_UNSET_FLAGS(obj, flags)	(GNT_ENTRY_FLAGS(obj) &= ~(flags))
+
+#define	ENTRY_CHAR		'_'			/* The character to use to fill in the blank places */
+
+typedef struct _GnEntry			GntEntry;
+typedef struct _GnEntryPriv		GntEntryPriv;
+typedef struct _GnEntryClass	GntEntryClass;
+
+typedef enum
+{
+	GNT_ENTRY_FLAG_ALPHA    = 1 << 0,  /* Only alpha */
+	GNT_ENTRY_FLAG_INT      = 1 << 1,  /* Only integer */
+	GNT_ENTRY_FLAG_NO_SPACE = 1 << 2,  /* No blank space is allowed */
+	GNT_ENTRY_FLAG_NO_PUNCT = 1 << 3,  /* No punctuations */
+	GNT_ENTRY_FLAG_MASK     = 1 << 4,  /* Mask the inputs */
+} GntEntryFlag;
+
+#define GNT_ENTRY_FLAG_ALL    (GNT_ENTRY_FLAG_ALPHA | GNT_ENTRY_FLAG_INT)
+
+struct _GnEntry
+{
+	GntWidget parent;
+
+	GntEntryFlag flag;
+
+	char *start;
+	char *end;
+	char *scroll;   /* Current scrolling position */
+	char *cursor;   /* Cursor location */
+	                /* 0 <= cursor - scroll < widget-width */
+	
+	size_t buffer;  /* Size of the buffer */
+	
+	int max;        /* 0 means infinite */
+	gboolean masked;
+
+	GList *history; /* History of the strings. User can use this by pressing ctrl+up/down */
+	int histlength; /* How long can the history be? */
+
+	GList *suggests;    /* List of suggestions */
+	gboolean word;      /* Are the suggestions for only a word, or for the whole thing? */
+	gboolean always;    /* Should the list of suggestions show at all times, or only on tab-press? */
+	GntWidget *ddown;   /* The dropdown with the suggested list */
+};
+
+struct _GnEntryClass
+{
+	GntWidgetClass parent;
+
+	void (*text_changed)(GntEntry *entry);
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_entry_get_gtype(void);
+
+GntWidget *gnt_entry_new(const char *text);
+
+void gnt_entry_set_max(GntEntry *entry, int max);
+
+void gnt_entry_set_text(GntEntry *entry, const char *text);
+
+void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag);
+
+const char *gnt_entry_get_text(GntEntry *entry);
+
+void gnt_entry_clear(GntEntry *entry);
+
+void gnt_entry_set_masked(GntEntry *entry, gboolean set);
+
+void gnt_entry_add_to_history(GntEntry *entry, const char *text);
+
+void gnt_entry_set_history_length(GntEntry *entry, int num);
+
+void gnt_entry_set_word_suggest(GntEntry *entry, gboolean word);
+
+void gnt_entry_set_always_suggest(GntEntry *entry, gboolean always);
+
+void gnt_entry_add_suggest(GntEntry *entry, const char *text);
+
+void gnt_entry_remove_suggest(GntEntry *entry, const char *text);
+
+G_END_DECLS
+
+#endif /* GNT_ENTRY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntkeys.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,50 @@
+#include "gntkeys.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+char *gnt_key_cup;
+char *gnt_key_cdown;
+char *gnt_key_cleft;
+char *gnt_key_cright;
+
+
+static const char *term;
+
+void gnt_init_keys()
+{
+	if (term == NULL) {
+		term = getenv("TERM");
+		if (!term)
+			term = "";  /* Just in case */
+	}
+
+	if (strcmp(term, "xterm") == 0 || strcmp(term, "rxvt") == 0) {
+		gnt_key_cup    = "\033" "[1;5A";
+		gnt_key_cdown  = "\033" "[1;5B";
+		gnt_key_cright = "\033" "[1;5C";
+		gnt_key_cleft  = "\033" "[1;5D";
+	} else if (strcmp(term, "screen") == 0 || strcmp(term, "rxvt-unicode") == 0) {
+		gnt_key_cup    = "\033" "Oa";
+		gnt_key_cdown  = "\033" "Ob";
+		gnt_key_cright = "\033" "Oc";
+		gnt_key_cleft  = "\033" "Od";
+	}
+}
+
+void gnt_keys_refine(char *text)
+{
+	if (*text == 27 && *(text + 1) == '[' && *(text + 3) == '\0' &&
+			(*(text + 2) >= 'A' && *(text + 2) <= 'D')) {
+		/* Apparently this is necessary for urxvt and screen and xterm */
+		if (strcmp(term, "screen") == 0 || strcmp(term, "rxvt-unicode") == 0 ||
+				strcmp(term, "xterm") == 0)
+			*(text + 1) = 'O';
+	} else if (*(unsigned char*)text == 195) {
+		if (*(text + 2) == 0 && strcmp(term, "xterm") == 0) {
+			*(text) = 27;
+			*(text + 1) -= 64;  /* Say wha? */
+		}
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntkeys.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,94 @@
+#ifndef GNT_KEYS_H
+#define GNT_KEYS_H
+
+#include <curses.h>
+#include <term.h>
+
+/**
+ * terminfo/termcap doesn't provide all the information that I want to use, eg.
+ * ctrl-up, ctrl-down etc. So I am going to hard-code some of the information
+ * for some popular $TERMs
+ */
+extern char *gnt_key_cup;
+extern char *gnt_key_cdown;
+extern char *gnt_key_cleft;
+extern char *gnt_key_cright;
+
+#define SAFE(x)   ((x) ? (x) : "")
+
+#define GNT_KEY_POPUP   SAFE(key_f16)   /* Apparently */
+
+/* Arrow keys */
+#define GNT_KEY_LEFT   SAFE(key_left)
+#define GNT_KEY_RIGHT  SAFE(key_right)
+#define GNT_KEY_UP     SAFE(key_up)
+#define GNT_KEY_DOWN   SAFE(key_down)
+
+#define GNT_KEY_CTRL_UP     SAFE(gnt_key_cup)
+#define GNT_KEY_CTRL_DOWN   SAFE(gnt_key_cdown)
+#define GNT_KEY_CTRL_RIGHT  SAFE(gnt_key_cright)
+#define GNT_KEY_CTRL_LEFT   SAFE(gnt_key_cleft)
+
+#define GNT_KEY_PGUP   SAFE(key_ppage)
+#define GNT_KEY_PGDOWN SAFE(key_npage)
+#define GNT_KEY_HOME   SAFE(key_home)
+#define GNT_KEY_END    SAFE(key_end)
+
+#define GNT_KEY_ENTER  carriage_return
+
+#define GNT_KEY_BACKSPACE SAFE(key_backspace)
+#define GNT_KEY_DEL    SAFE(key_dc)
+#define GNT_KEY_INS    SAFE(key_ic)
+
+#define GNT_KEY_CTRL_A     "\001"
+#define GNT_KEY_CTRL_B     "\002"
+#define GNT_KEY_CTRL_D     "\004"
+#define GNT_KEY_CTRL_E     "\005"
+#define GNT_KEY_CTRL_F     "\006"
+#define GNT_KEY_CTRL_G     "\007"
+#define GNT_KEY_CTRL_H     "\010"
+#define GNT_KEY_CTRL_I     "\011"
+#define GNT_KEY_CTRL_J     "\012"
+#define GNT_KEY_CTRL_K     "\013"
+#define GNT_KEY_CTRL_L     "\014"
+#define GNT_KEY_CTRL_M     "\012"
+#define GNT_KEY_CTRL_N     "\016"
+#define GNT_KEY_CTRL_O     "\017"
+#define GNT_KEY_CTRL_P     "\020"
+#define GNT_KEY_CTRL_R     "\022"
+#define GNT_KEY_CTRL_T     "\024"
+#define GNT_KEY_CTRL_U     "\025"
+#define GNT_KEY_CTRL_V     "\026"
+#define GNT_KEY_CTRL_W     "\027"
+#define GNT_KEY_CTRL_X     "\030"
+#define GNT_KEY_CTRL_Y     "\031"
+
+#define GNT_KEY_F1         SAFE(key_f1)
+#define GNT_KEY_F2         SAFE(key_f2)
+#define GNT_KEY_F3         SAFE(key_f3)
+#define GNT_KEY_F4         SAFE(key_f4)
+#define GNT_KEY_F5         SAFE(key_f5)
+#define GNT_KEY_F6         SAFE(key_f6)
+#define GNT_KEY_F7         SAFE(key_f7)
+#define GNT_KEY_F8         SAFE(key_f8)
+#define GNT_KEY_F9         SAFE(key_f9)
+#define GNT_KEY_F10        SAFE(key_f10)
+#define GNT_KEY_F11        SAFE(key_f11)
+#define GNT_KEY_F12        SAFE(key_f12)
+
+/**
+ * This will do stuff with the terminal settings and stuff.
+ */
+void gnt_init_keys();
+void gnt_keys_refine(char *text);
+
+
+/* A lot of commonly used variable names are defined in <term.h>. 
+ * #undef them to make life easier for everyone. */
+
+#undef columns
+#undef lines
+#undef buttons
+#undef newline
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntlabel.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,123 @@
+#include "gntlabel.h"
+#include "gntutils.h"
+
+#include <string.h>
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+
+static void
+gnt_label_destroy(GntWidget *widget)
+{
+	GntLabel *label = GNT_LABEL(widget);
+	g_free(label->text);
+}
+
+static void
+gnt_label_draw(GntWidget *widget)
+{
+	GntLabel *label = GNT_LABEL(widget);
+	chtype flag = gnt_text_format_flag_to_chtype(label->flags);
+
+	wbkgdset(widget->window, '\0' | flag);
+	mvwprintw(widget->window, 0, 0, label->text);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_label_size_request(GntWidget *widget)
+{
+	GntLabel *label = GNT_LABEL(widget);
+
+	gnt_util_get_text_bound(label->text,
+			&widget->priv.width, &widget->priv.height);
+}
+
+static void
+gnt_label_class_init(GntLabelClass *klass)
+{
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_label_destroy;
+	parent_class->draw = gnt_label_draw;
+	parent_class->map = NULL;
+	parent_class->size_request = gnt_label_size_request;
+
+	GNTDEBUG;
+}
+
+static void
+gnt_label_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X);
+	widget->priv.minw = 3;
+	widget->priv.minh = 1;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntLabel API
+ *****************************************************************************/
+GType
+gnt_label_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntLabelClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_label_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntLabel),
+			0,						/* n_preallocs		*/
+			gnt_label_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntLabel",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_label_new(const char *text)
+{
+	return gnt_label_new_with_format(text, 0);
+}
+
+GntWidget *gnt_label_new_with_format(const char *text, GntTextFormatFlags flags)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_LABEL, NULL);
+	GntLabel *label = GNT_LABEL(widget);
+
+	label->text = gnt_util_onscreen_fit_string(text, -1);
+	label->flags = flags;
+	gnt_widget_set_take_focus(widget, FALSE);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+
+	return widget;
+}
+
+void gnt_label_set_text(GntLabel *label, const char *text)
+{
+	g_free(label->text);
+	label->text = gnt_util_onscreen_fit_string(text, -1);
+
+	if (GNT_WIDGET(label)->window)
+	{
+		gnt_widget_hide(GNT_WIDGET(label));
+		gnt_label_size_request(GNT_WIDGET(label));
+		gnt_widget_draw(GNT_WIDGET(label));
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntlabel.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,54 @@
+#ifndef GNT_LABEL_H
+#define GNT_LABEL_H
+
+#include "gnt.h"
+#include "gntwidget.h"
+#include "gnttextview.h"
+
+#define GNT_TYPE_LABEL				(gnt_label_get_gtype())
+#define GNT_LABEL(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_LABEL, GntLabel))
+#define GNT_LABEL_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_LABEL, GntLabelClass))
+#define GNT_IS_LABEL(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_LABEL))
+#define GNT_IS_LABEL_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LABEL))
+#define GNT_LABEL_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LABEL, GntLabelClass))
+
+typedef struct _GnLabel			GntLabel;
+typedef struct _GnLabelClass	GntLabelClass;
+
+struct _GnLabel
+{
+	GntWidget parent;
+
+	char *text;
+	GntTextFormatFlags flags;
+
+    void (*gnt_reserved1)(void);
+    void (*gnt_reserved2)(void);
+    void (*gnt_reserved3)(void);
+    void (*gnt_reserved4)(void);
+};
+
+struct _GnLabelClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_label_get_gtype(void);
+
+GntWidget *gnt_label_new(const char *text);
+
+GntWidget *gnt_label_new_with_format(const char *text, GntTextFormatFlags flags);
+
+void gnt_label_set_text(GntLabel *label, const char *text);
+
+G_END_DECLS
+
+#endif /* GNT_LABEL_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntline.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,114 @@
+#include "gntline.h"
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+
+static void
+gnt_line_draw(GntWidget *widget)
+{
+	GntLine *line = GNT_LINE(widget);
+	if (line->vertical)
+		mvwvline(widget->window, 1, 0, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				widget->priv.height - 2);
+	else
+		mvwhline(widget->window, 0, 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				widget->priv.width - 2);
+}
+
+static void
+gnt_line_size_request(GntWidget *widget)
+{
+	if (GNT_LINE(widget)->vertical)
+	{
+		widget->priv.width = 1;
+		widget->priv.height = 5;
+	}
+	else
+	{
+		widget->priv.width = 5;
+		widget->priv.height = 1;
+	}
+}
+
+static void
+gnt_line_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static void
+gnt_line_class_init(GntLineClass *klass)
+{
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->draw = gnt_line_draw;
+	parent_class->map = gnt_line_map;
+	parent_class->size_request = gnt_line_size_request;
+
+	GNTDEBUG;
+}
+
+static void
+gnt_line_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER);
+	widget->priv.minw = 1;
+	widget->priv.minh = 1;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntLine API
+ *****************************************************************************/
+GType
+gnt_line_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntLineClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_line_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntLine),
+			0,						/* n_preallocs		*/
+			gnt_line_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntLine",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_line_new(gboolean vertical)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_LINE, NULL);
+	GntLine *line = GNT_LINE(widget);
+
+	line->vertical = vertical;
+
+	if (vertical)
+	{
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_Y);
+	}
+	else
+	{
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X);
+	}
+
+	return widget;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntline.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,52 @@
+#ifndef GNT_LINE_H
+#define GNT_LINE_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_LINE				(gnt_line_get_gtype())
+#define GNT_LINE(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_LINE, GntLine))
+#define GNT_LINE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_LINE, GntLineClass))
+#define GNT_IS_LINE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_LINE))
+#define GNT_IS_LINE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LINE))
+#define GNT_LINE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LINE, GntLineClass))
+
+#define GNT_LINE_FLAGS(obj)				(GNT_LINE(obj)->priv.flags)
+#define GNT_LINE_SET_FLAGS(obj, flags)		(GNT_LINE_FLAGS(obj) |= flags)
+#define GNT_LINE_UNSET_FLAGS(obj, flags)	(GNT_LINE_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnLine			GntLine;
+typedef struct _GnLinePriv		GntLinePriv;
+typedef struct _GnLineClass		GntLineClass;
+
+struct _GnLine
+{
+	GntWidget parent;
+
+	gboolean vertical;
+};
+
+struct _GnLineClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_line_get_gtype(void);
+
+#define gnt_hline_new() gnt_line_new(FALSE)
+#define gnt_vline_new() gnt_line_new(TRUE)
+
+GntWidget *gnt_line_new(gboolean vertical);
+
+G_END_DECLS
+
+#endif /* GNT_LINE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmain.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,477 @@
+#define _GNU_SOURCE
+#if defined(__APPLE__)
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include "config.h"
+
+#include <gmodule.h>
+
+#include "gnt.h"
+#include "gntbox.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+#include "gntmenu.h"
+#include "gntstyle.h"
+#include "gnttree.h"
+#include "gntutils.h"
+#include "gntwm.h"
+
+#include <panel.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/**
+ * Notes: Interesting functions to look at:
+ * 	scr_dump, scr_init, scr_restore: for workspaces
+ *
+ * 	Need to wattrset for colors to use with PDCurses.
+ */
+
+static GIOChannel *channel = NULL;
+
+static gboolean ascii_only;
+static gboolean mouse_enabled;
+
+static void setup_io();
+
+static gboolean refresh_screen();
+
+GntWM *wm;
+
+/**
+ * Mouse support:
+ *  - bring a window on top if you click on its taskbar
+ *  - click on the top-bar of the active window and drag+drop to move a window
+ *  - click on a window to bring it to focus
+ *   - allow scrolling in tree/textview on wheel-scroll event
+ *   - click to activate button or select a row in tree
+ *  wishlist:
+ *   - have a little [X] on the windows, and clicking it will close that window.
+ */
+static gboolean
+detect_mouse_action(const char *buffer)
+{
+	int x, y;
+	static enum {
+		MOUSE_NONE,
+		MOUSE_LEFT,
+		MOUSE_RIGHT,
+		MOUSE_MIDDLE
+	} button = MOUSE_NONE;
+	static GntWidget *remember = NULL;
+	static int offset = 0;
+	GntMouseEvent event;
+	GntWidget *widget = NULL;
+	PANEL *p = NULL;
+
+	if (!wm->ordered || buffer[0] != 27)
+		return FALSE;
+	
+	buffer++;
+	if (strlen(buffer) < 5)
+		return FALSE;
+
+	x = buffer[3];
+	y = buffer[4];
+	if (x < 0)	x += 256;
+	if (y < 0)	y += 256;
+	x -= 33;
+	y -= 33;
+
+	while ((p = panel_below(p)) != NULL) {
+		const GntNode *node = panel_userptr(p);
+		GntWidget *wid;
+		if (!node)
+			continue;
+		wid = node->me;
+		if (x >= wid->priv.x && x < wid->priv.x + wid->priv.width) {
+			if (y >= wid->priv.y && y < wid->priv.y + wid->priv.height) {
+				widget = wid;
+				break;
+			}
+		}
+	}
+
+	if (strncmp(buffer, "[M ", 3) == 0) {
+		/* left button down */
+		/* Bring the window you clicked on to front */
+		/* If you click on the topbar, then you can drag to move the window */
+		event = GNT_LEFT_MOUSE_DOWN;
+	} else if (strncmp(buffer, "[M\"", 3) == 0) {
+		/* right button down */
+		event = GNT_RIGHT_MOUSE_DOWN;
+	} else if (strncmp(buffer, "[M!", 3) == 0) {
+		/* middle button down */
+		event = GNT_MIDDLE_MOUSE_DOWN;
+	} else if (strncmp(buffer, "[M`", 3) == 0) {
+		/* wheel up*/
+		event = GNT_MOUSE_SCROLL_UP;
+	} else if (strncmp(buffer, "[Ma", 3) == 0) {
+		/* wheel down */
+		event = GNT_MOUSE_SCROLL_DOWN;
+	} else if (strncmp(buffer, "[M#", 3) == 0) {
+		/* button up */
+		event = GNT_MOUSE_UP;
+	} else
+		return FALSE;
+	
+	if (gnt_wm_process_click(wm, event, x, y, widget))
+		return TRUE;
+	
+	if (event == GNT_LEFT_MOUSE_DOWN && widget && widget != wm->_list.window &&
+			!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) {
+		if (widget != wm->ordered->data) {
+			gnt_wm_raise_window(wm, widget);
+		}
+		if (y == widget->priv.y) {
+			offset = x - widget->priv.x;
+			remember = widget;
+			button = MOUSE_LEFT;
+		}
+	} else if (event == GNT_MOUSE_UP) {
+		if (button == MOUSE_NONE && y == getmaxy(stdscr) - 1) {
+			/* Clicked on the taskbar */
+			int n = g_list_length(wm->list);
+			if (n) {
+				int width = getmaxx(stdscr) / n;
+				gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "switch-window-n", x/width, NULL);
+			}
+		} else if (button == MOUSE_LEFT && remember) {
+			x -= offset;
+			if (x < 0)	x = 0;
+			if (y < 0)	y = 0;
+			gnt_screen_move_widget(remember, x, y);
+		}
+		button = MOUSE_NONE;
+		remember = NULL;
+		offset = 0;
+	}
+
+	gnt_widget_clicked(widget, event, x, y);
+	return TRUE;
+}
+
+static gboolean
+io_invoke_error(GIOChannel *source, GIOCondition cond, gpointer data)
+{
+	int id = GPOINTER_TO_INT(data);
+	g_source_remove(id);
+	g_io_channel_unref(source);
+
+	channel = NULL;
+	setup_io();
+	return TRUE;
+}
+
+static gboolean
+io_invoke(GIOChannel *source, GIOCondition cond, gpointer null)
+{
+	char keys[256];
+	int rd = read(STDIN_FILENO, keys, sizeof(keys) - 1);
+	if (rd < 0)
+	{
+		int ch = getch(); /* This should return ERR, but let's see what it really returns */
+		endwin();
+		printf("ERROR: %s\n", strerror(errno));
+		printf("File descriptor is: %d\n\nGIOChannel is: %p\ngetch() = %d\n", STDIN_FILENO, source, ch);
+		raise(SIGABRT);
+	}
+	else if (rd == 0)
+	{
+		endwin();
+		printf("EOF\n");
+		raise(SIGABRT);
+	}
+
+	keys[rd] = 0;
+	gnt_keys_refine(keys);
+
+	if (mouse_enabled && detect_mouse_action(keys))
+		return TRUE;
+	
+	gnt_wm_process_input(wm, keys);
+
+	return TRUE;
+}
+
+static void
+setup_io()
+{
+	int result;
+	channel = g_io_channel_unix_new(STDIN_FILENO);
+
+	g_io_channel_set_encoding(channel, NULL, NULL);
+	g_io_channel_set_buffered(channel, FALSE);
+#if 0
+	g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL );
+#endif
+
+	result = g_io_add_watch_full(channel,  G_PRIORITY_HIGH,
+					(G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI),
+					io_invoke, NULL, NULL);
+	
+	g_io_add_watch_full(channel,  G_PRIORITY_HIGH,
+					(G_IO_NVAL),
+					io_invoke_error, GINT_TO_POINTER(result), NULL);
+	
+	g_io_channel_unref(channel);  /* Apparently this caused crashes for some people.
+	                                 But irssi does this, so I am going to assume the
+	                                 crashes were caused by some other stuff. */
+
+	g_printerr("gntmain: setting up IO\n");
+}
+
+static gboolean
+refresh_screen()
+{
+	gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "refresh-screen", NULL);
+	return FALSE;
+}
+
+/* Xerox */
+static void
+clean_pid(void)
+{
+	int status;
+	pid_t pid;
+
+	do {
+		pid = waitpid(-1, &status, WNOHANG);
+	} while (pid != 0 && pid != (pid_t)-1);
+
+	if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
+		char errmsg[BUFSIZ];
+		g_snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
+		perror(errmsg);
+	}
+}
+
+static void
+sighandler(int sig)
+{
+	switch (sig) {
+#ifdef SIGWINCH
+	case SIGWINCH:
+		werase(stdscr);
+		wrefresh(stdscr);
+		g_idle_add(refresh_screen, NULL);
+		signal(SIGWINCH, sighandler);
+		break;
+#endif
+	case SIGCHLD:
+		clean_pid();
+		signal(SIGCHLD, sighandler);
+		break;
+	}
+}
+
+static void
+init_wm()
+{
+	const char *name = gnt_style_get(GNT_STYLE_WM);
+	gpointer handle;
+	
+	if (name && *name) {
+		handle = g_module_open(name, G_MODULE_BIND_LAZY);
+		if (handle) {
+			gboolean (*init)(GntWM **);
+			if (g_module_symbol(handle, "gntwm_init", (gpointer)&init)) {
+				init(&wm);
+			}
+		}
+	}
+	if (wm == NULL)
+		wm = g_object_new(GNT_TYPE_WM, NULL);
+}
+
+void gnt_init()
+{
+	char *filename;
+	const char *locale;
+
+	if (channel)
+		return;
+	
+	setup_io();
+
+	locale = setlocale(LC_ALL, "");
+
+	if (locale && (strstr(locale, "UTF") || strstr(locale, "utf")))
+		ascii_only = FALSE;
+	else
+		ascii_only = TRUE;
+
+	initscr();
+	typeahead(-1);
+	noecho();
+	curs_set(0);
+
+	gnt_init_styles();
+
+	filename = g_build_filename(g_get_home_dir(), ".gntrc", NULL);
+	gnt_style_read_configure_file(filename);
+	g_free(filename);
+
+	gnt_init_colors();
+	gnt_init_keys();
+
+	wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
+	refresh();
+
+#ifdef ALL_MOUSE_EVENTS
+	if ((mouse_enabled = gnt_style_get_bool(GNT_STYLE_MOUSE, FALSE)))
+		mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
+#endif
+
+	wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
+	werase(stdscr);
+	wrefresh(stdscr);
+
+#ifdef SIGWINCH
+	signal(SIGWINCH, sighandler);
+#endif
+	signal(SIGCHLD, sighandler);
+	signal(SIGPIPE, SIG_IGN);
+
+	g_type_init();
+
+	init_wm();
+}
+
+void gnt_main()
+{
+	wm->loop = g_main_loop_new(NULL, FALSE);
+	g_main_loop_run(wm->loop);
+}
+
+/*********************************
+ * Stuff for 'window management' *
+ *********************************/
+
+void gnt_screen_occupy(GntWidget *widget)
+{
+	gnt_wm_new_window(wm, widget);
+}
+
+void gnt_screen_release(GntWidget *widget)
+{
+	gnt_wm_window_close(wm, widget);
+}
+
+void gnt_screen_update(GntWidget *widget)
+{
+	gnt_wm_update_window(wm, widget);
+}
+
+gboolean gnt_widget_has_focus(GntWidget *widget)
+{
+	GntWidget *w;
+	if (!widget)
+		return FALSE;
+	
+	if (GNT_IS_MENU(widget))
+		return TRUE;
+
+	w = widget;
+
+	while (widget->parent)
+		widget = widget->parent;
+
+	if (widget == wm->_list.window)
+		return TRUE;
+	if (wm->ordered && wm->ordered->data == widget) {
+		if (GNT_IS_BOX(widget) &&
+				(GNT_BOX(widget)->active == w || widget == w))
+			return TRUE;
+	}
+	return FALSE;
+}
+
+void gnt_widget_set_urgent(GntWidget *widget)
+{
+	while (widget->parent)
+		widget = widget->parent;
+
+	if (wm->ordered && wm->ordered->data == widget)
+		return;
+
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_URGENT);
+
+	gnt_wm_update_window(wm, widget);
+}
+
+void gnt_quit()
+{
+	g_hash_table_destroy(wm->nodes); /* XXX: */
+	update_panels();
+	doupdate();
+	gnt_uninit_colors();
+	gnt_uninit_styles();
+	endwin();
+}
+
+gboolean gnt_ascii_only()
+{
+	return ascii_only;
+}
+
+void gnt_screen_resize_widget(GntWidget *widget, int width, int height)
+{
+	gnt_wm_resize_window(wm, widget, width, height);
+}
+
+void gnt_screen_move_widget(GntWidget *widget, int x, int y)
+{
+	gnt_wm_move_window(wm, widget, x, y);
+}
+
+void gnt_screen_rename_widget(GntWidget *widget, const char *text)
+{
+	gnt_box_set_title(GNT_BOX(widget), text);
+	gnt_widget_draw(widget);
+	gnt_wm_update_window(wm, widget);
+}
+
+void gnt_register_action(const char *label, void (*callback)())
+{
+	GntAction *action = g_new0(GntAction, 1);
+	action->label = g_strdup(label);
+	action->callback = callback;
+
+	wm->acts = g_list_append(wm->acts, action);
+}
+
+static void
+reset_menu(GntWidget *widget, gpointer null)
+{
+	wm->menu = NULL;
+}
+
+gboolean gnt_screen_menu_show(gpointer newmenu)
+{
+	if (wm->menu) {
+		/* For now, if a menu is being displayed, then another menu
+		 * can NOT take over. */
+		return FALSE;
+	}
+
+	wm->menu = newmenu;
+	GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(wm->menu), GNT_WIDGET_INVISIBLE);
+	gnt_widget_draw(GNT_WIDGET(wm->menu));
+
+	g_signal_connect(G_OBJECT(wm->menu), "hide", G_CALLBACK(reset_menu), NULL);
+
+	return TRUE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmenu.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,315 @@
+#include "gntmenu.h"
+#include "gntmenuitemcheck.h"
+
+#include <string.h>
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntTreeClass *parent_class = NULL;
+
+static void (*org_draw)(GntWidget *wid);
+static void (*org_destroy)(GntWidget *wid);
+static void (*org_map)(GntWidget *wid);
+static gboolean (*org_key_pressed)(GntWidget *w, const char *t);
+
+static void
+gnt_menu_draw(GntWidget *widget)
+{
+	GntMenu *menu = GNT_MENU(widget);
+	GList *iter;
+	chtype type;
+	int i;
+
+	if (menu->type == GNT_MENU_TOPLEVEL) {
+		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
+		werase(widget->window);
+
+		for (i = 0, iter = menu->list; iter; iter = iter->next, i++) {
+			GntMenuItem *item = GNT_MENUITEM(iter->data);
+			type = ' ' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT);
+			if (i == menu->selected)
+				type |= A_REVERSE;
+			item->priv.x = getcurx(widget->window) + widget->priv.x;
+			item->priv.y = getcury(widget->window) + widget->priv.y + 1;
+			wbkgdset(widget->window, type);
+			wprintw(widget->window, " %s   ", item->text);
+		}
+	} else {
+		org_draw(widget);
+	}
+
+	GNTDEBUG;
+}
+
+static void
+gnt_menu_size_request(GntWidget *widget)
+{
+	GntMenu *menu = GNT_MENU(widget);
+
+	if (menu->type == GNT_MENU_TOPLEVEL) {
+		widget->priv.height = 1;
+		widget->priv.width = getmaxx(stdscr);
+	} else {
+		widget->priv.height = g_list_length(menu->list) + 2;
+		widget->priv.width = 25;  /* XXX: */
+	}
+}
+
+static void
+menu_tree_add(GntMenu *menu, GntMenuItem *item, GntMenuItem *parent)
+{
+	if (GNT_IS_MENUITEM_CHECK(item)) {
+		gnt_tree_add_choice(GNT_TREE(menu), item,
+			gnt_tree_create_row(GNT_TREE(menu), item->text, " "), parent, NULL);
+		gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item)));
+	} else
+		gnt_tree_add_row_last(GNT_TREE(menu), item,
+			gnt_tree_create_row(GNT_TREE(menu), item->text, item->submenu ? ">" : " "), parent);
+
+	if (0 && item->submenu) {
+		GntMenu *sub = GNT_MENU(item->submenu);
+		GList *iter;
+		for (iter = sub->list; iter; iter = iter->next) {
+			GntMenuItem *it = GNT_MENUITEM(iter->data);
+			menu_tree_add(menu, it, item);
+		}
+	}
+}
+
+static void
+gnt_menu_map(GntWidget *widget)
+{
+	GntMenu *menu = GNT_MENU(widget);
+
+	if (menu->type == GNT_MENU_TOPLEVEL) {
+		gnt_widget_size_request(widget);
+	} else {
+		/* Populate the tree */
+		GList *iter;
+		gnt_tree_remove_all(GNT_TREE(widget));
+		for (iter = menu->list; iter; iter = iter->next) {
+			GntMenuItem *item = GNT_MENUITEM(iter->data);
+			menu_tree_add(menu, item, NULL);
+		}
+		org_map(widget);
+		gnt_tree_adjust_columns(GNT_TREE(widget));
+	}
+	GNTDEBUG;
+}
+
+static void
+menuitem_activate(GntMenu *menu, GntMenuItem *item)
+{
+	if (item) {
+		if (item->submenu) {
+			GntMenu *sub = GNT_MENU(item->submenu);
+			menu->submenu = sub;
+			sub->type = GNT_MENU_POPUP;	/* Submenus are *never* toplevel */
+			sub->parentmenu = menu;
+			if (menu->type != GNT_MENU_TOPLEVEL) {
+				GntWidget *widget = GNT_WIDGET(menu);
+				item->priv.x = widget->priv.x + widget->priv.width - 1;
+				item->priv.y = widget->priv.y + gnt_tree_get_selection_visible_line(GNT_TREE(menu));
+			}
+			gnt_widget_set_position(GNT_WIDGET(sub), item->priv.x, item->priv.y);
+			GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(sub), GNT_WIDGET_INVISIBLE);
+			gnt_widget_draw(GNT_WIDGET(sub));
+		} else if (item->callback) {
+			item->callback(item, item->callbackdata);
+			while (menu) {
+				gnt_widget_hide(GNT_WIDGET(menu));
+				menu = menu->parentmenu;
+			}
+		}
+	}
+}
+
+static gboolean
+gnt_menu_key_pressed(GntWidget *widget, const char *text)
+{
+	GntMenu *menu = GNT_MENU(widget);
+	int current = menu->selected;
+
+	if (menu->submenu) {
+		return (gnt_widget_key_pressed(GNT_WIDGET(menu->submenu), text));
+	}
+
+	if (text[0] == 27 && text[1] == 0) {
+		/* Escape closes menu */
+		GntMenu *par = menu->parentmenu;
+		if (par != NULL) {
+			par->submenu = NULL;
+			gnt_widget_hide(widget);
+		} else
+			gnt_widget_hide(widget);
+		return TRUE;
+	}
+
+	if (menu->type == GNT_MENU_TOPLEVEL) {
+		if (strcmp(text, GNT_KEY_LEFT) == 0) {
+			menu->selected--;
+			if (menu->selected < 0)
+				menu->selected = g_list_length(menu->list) - 1;
+		} else if (strcmp(text, GNT_KEY_RIGHT) == 0) {
+			menu->selected++;
+			if (menu->selected >= g_list_length(menu->list))
+				menu->selected = 0;
+		} else if (strcmp(text, GNT_KEY_ENTER) == 0) {
+			gnt_widget_activate(widget);
+		}
+
+		if (current != menu->selected) {
+			gnt_widget_draw(widget);
+			return TRUE;
+		}
+	} else {
+		return org_key_pressed(widget, text);
+	}
+
+	return FALSE;
+}
+
+static void
+gnt_menu_destroy(GntWidget *widget)
+{
+	GntMenu *menu = GNT_MENU(widget);
+	g_list_foreach(menu->list, (GFunc)g_object_unref, NULL);
+	g_list_free(menu->list);
+	org_destroy(widget);
+}
+
+static void
+gnt_menu_toggled(GntTree *tree, gpointer key)
+{
+	GntMenuItem *item = GNT_MENUITEM(key);
+	GntMenu *menu = GNT_MENU(tree);
+	gboolean check = gnt_menuitem_check_get_checked(GNT_MENUITEM_CHECK(item));
+	gnt_menuitem_check_set_checked(GNT_MENUITEM_CHECK(item), !check);
+	if (item->callback)
+		item->callback(item, item->callbackdata);
+	while (menu) {
+		gnt_widget_hide(GNT_WIDGET(menu));
+		menu = menu->parentmenu;
+	}
+}
+
+static void
+gnt_menu_activate(GntWidget *widget)
+{
+	GntMenu *menu = GNT_MENU(widget);
+	GntMenuItem *item;
+
+	if (menu->type == GNT_MENU_TOPLEVEL) {
+		item = g_list_nth_data(menu->list, menu->selected);
+	} else {
+		item = gnt_tree_get_selection_data(GNT_TREE(menu));
+	}
+
+	if (item) {
+		if (GNT_IS_MENUITEM_CHECK(item))
+			gnt_menu_toggled(GNT_TREE(widget), item);
+		else
+			menuitem_activate(menu, item);
+	}
+}
+
+static void
+gnt_menu_hide(GntWidget *widget)
+{
+	GntMenu *menu = GNT_MENU(widget);
+	if (menu->parentmenu)
+		menu->parentmenu->submenu = NULL;
+}
+
+static void
+gnt_menu_class_init(GntMenuClass *klass)
+{
+	GntWidgetClass *wid_class = GNT_WIDGET_CLASS(klass);
+	parent_class = GNT_TREE_CLASS(klass);
+
+	org_destroy = wid_class->destroy;
+	org_map = wid_class->map;
+	org_draw = wid_class->draw;
+	org_key_pressed = wid_class->key_pressed;
+
+	wid_class->destroy = gnt_menu_destroy;
+	wid_class->draw = gnt_menu_draw;
+	wid_class->map = gnt_menu_map;
+	wid_class->size_request = gnt_menu_size_request;
+	wid_class->key_pressed = gnt_menu_key_pressed;
+	wid_class->activate = gnt_menu_activate;
+	wid_class->hide = gnt_menu_hide;
+
+	parent_class->toggled = gnt_menu_toggled;
+
+	GNTDEBUG;
+}
+
+static void
+gnt_menu_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER |
+			GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_TRANSIENT);
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntMenu API
+ *****************************************************************************/
+GType
+gnt_menu_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntMenuClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_menu_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntMenu),
+			0,						/* n_preallocs		*/
+			gnt_menu_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_TREE,
+									  "GntMenu",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_menu_new(GntMenuType type)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_MENU, NULL);
+	GntMenu *menu = GNT_MENU(widget);
+	menu->list = NULL;
+	menu->selected = 0;
+	menu->type = type;
+
+	if (type == GNT_MENU_TOPLEVEL) {
+		widget->priv.x = 0;
+		widget->priv.y = 0;
+	} else {
+		GNT_TREE(widget)->show_separator = FALSE;
+		_gnt_tree_init_internals(GNT_TREE(widget), 2);
+		gnt_tree_set_col_width(GNT_TREE(widget), 1, 1);  /* The second column is to indicate that it has a submenu */
+		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
+	}
+
+	return widget;
+}
+
+void gnt_menu_add_item(GntMenu *menu, GntMenuItem *item)
+{
+	menu->list = g_list_append(menu->list, item);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmenu.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,70 @@
+#ifndef GNT_MENU_H
+#define GNT_MENU_H
+
+#include "gnttree.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_MENU				(gnt_menu_get_gtype())
+#define GNT_MENU(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENU, GntMenu))
+#define GNT_MENU_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENU, GntMenuClass))
+#define GNT_IS_MENU(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENU))
+#define GNT_IS_MENU_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENU))
+#define GNT_MENU_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENU, GntMenuClass))
+
+#define GNT_MENU_FLAGS(obj)				(GNT_MENU(obj)->priv.flags)
+#define GNT_MENU_SET_FLAGS(obj, flags)		(GNT_MENU_FLAGS(obj) |= flags)
+#define GNT_MENU_UNSET_FLAGS(obj, flags)	(GNT_MENU_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnMenu			GntMenu;
+typedef struct _GnMenuPriv		GntMenuPriv;
+typedef struct _GnMenuClass		GntMenuClass;
+
+#include "gntmenuitem.h"
+
+/**
+ * A toplevel-menu is displayed at the top of the screen, and it spans accross
+ * the entire width of the screen.
+ * A popup-menu could be displayed, for example, as a context menu for widgets.
+ */
+typedef enum
+{
+	GNT_MENU_TOPLEVEL = 1,  /* Menu for a toplevel window */
+	GNT_MENU_POPUP,         /* A popup menu */
+} GntMenuType;
+
+struct _GnMenu
+{
+	GntTree parent;
+	GntMenuType type;
+	
+	GList *list;
+	int selected;
+
+	/* This will keep track of its immediate submenu which is visible so that
+	 * keystrokes can be passed to it. */
+	GntMenu *submenu;
+	GntMenu *parentmenu;
+};
+
+struct _GnMenuClass
+{
+	GntTreeClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_menu_get_gtype(void);
+
+GntWidget *gnt_menu_new(GntMenuType type);
+
+void gnt_menu_add_item(GntMenu *menu, GntMenuItem *item);
+
+G_END_DECLS
+
+#endif /* GNT_MENU_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmenuitem.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,83 @@
+#include "gntmenu.h"
+#include "gntmenuitem.h"
+
+static GObjectClass *parent_class = NULL;
+
+static void
+gnt_menuitem_destroy(GObject *obj)
+{
+	GntMenuItem *item = GNT_MENUITEM(obj);
+	g_free(item->text);
+	item->text = NULL;
+	if (item->submenu)
+		gnt_widget_destroy(GNT_WIDGET(item->submenu));
+	parent_class->dispose(obj);
+}
+
+static void
+gnt_menuitem_class_init(GntMenuItemClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	parent_class = g_type_class_peek_parent(klass);
+
+	obj_class->dispose = gnt_menuitem_destroy;
+}
+
+static void
+gnt_menuitem_init(GTypeInstance *instance, gpointer class)
+{
+}
+
+/******************************************************************************
+ * GntMenuItem API
+ *****************************************************************************/
+GType
+gnt_menuitem_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntMenuItemClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_menuitem_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntMenuItem),
+			0,						/* n_preallocs		*/
+			gnt_menuitem_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(G_TYPE_OBJECT,
+									  "GntMenuItem",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntMenuItem *gnt_menuitem_new(const char *text)
+{
+	GObject *item = g_object_new(GNT_TYPE_MENUITEM, NULL);
+	GntMenuItem *menuitem = GNT_MENUITEM(item);
+
+	menuitem->text = g_strdup(text);
+
+	return menuitem;
+}
+
+void gnt_menuitem_set_callback(GntMenuItem *item, GntMenuItemCallback callback, gpointer data)
+{
+	item->callback = callback;
+	item->callbackdata = data;
+}
+
+void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu)
+{
+	if (item->submenu)
+		gnt_widget_destroy(GNT_WIDGET(item->submenu));
+	item->submenu = menu;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmenuitem.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,71 @@
+#ifndef GNT_MENUITEM_H
+#define GNT_MENUITEM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#define GNT_TYPE_MENUITEM				(gnt_menuitem_get_gtype())
+#define GNT_MENUITEM(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENUITEM, GntMenuItem))
+#define GNT_MENUITEM_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENUITEM, GntMenuItemClass))
+#define GNT_IS_MENUITEM(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENUITEM))
+#define GNT_IS_MENUITEM_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENUITEM))
+#define GNT_MENUITEM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENUITEM, GntMenuItemClass))
+
+#define GNT_MENUITEM_FLAGS(obj)				(GNT_MENUITEM(obj)->priv.flags)
+#define GNT_MENUITEM_SET_FLAGS(obj, flags)		(GNT_MENUITEM_FLAGS(obj) |= flags)
+#define GNT_MENUITEM_UNSET_FLAGS(obj, flags)	(GNT_MENUITEM_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnMenuItem			GntMenuItem;
+typedef struct _GnMenuItemPriv		GntMenuItemPriv;
+typedef struct _GnMenuItemClass		GntMenuItemClass;
+
+#include "gntmenu.h"
+
+struct _GnMenuItemPriv
+{
+	/* These will be used to determine the position of the submenu */
+	int x;
+	int y;
+};
+
+typedef void (*GntMenuItemCallback)(GntMenuItem *item, gpointer data);
+
+struct _GnMenuItem
+{
+	GObject parent;
+	GntMenuItemPriv priv;
+
+	char *text;
+
+	/* A GntMenuItem can have a callback associated with it.
+	 * The callback will be activated whenever the suer selects it and presses enter (or clicks).
+	 * However, if the GntMenuItem has some child, then the callback and callbackdata will be ignored. */
+	gpointer callbackdata;
+	GntMenuItemCallback callback;
+
+	GntMenu *submenu;
+};
+
+struct _GnMenuItemClass
+{
+	GObjectClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_menuitem_get_gtype(void);
+
+GntMenuItem *gnt_menuitem_new(const char *text);
+
+void gnt_menuitem_set_callback(GntMenuItem *item, GntMenuItemCallback callback, gpointer data);
+
+void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu);
+
+G_END_DECLS
+
+#endif /* GNT_MENUITEM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmenuitemcheck.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,67 @@
+#include "gntmenuitemcheck.h"
+
+static GntMenuItemClass *parent_class = NULL;
+
+static void
+gnt_menuitem_check_class_init(GntMenuItemCheckClass *klass)
+{
+	parent_class = GNT_MENUITEM_CLASS(klass);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_menuitem_check_init(GTypeInstance *instance, gpointer class)
+{
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntMenuItemCheck API
+ *****************************************************************************/
+GType
+gnt_menuitem_check_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntMenuItemCheckClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_menuitem_check_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntMenuItemCheck),
+			0,						/* n_preallocs		*/
+			gnt_menuitem_check_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_MENUITEM,
+									  "GntMenuItemCheck",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntMenuItem *gnt_menuitem_check_new(const char *text)
+{
+	GntMenuItem *item = g_object_new(GNT_TYPE_MENUITEM_CHECK, NULL);
+	GntMenuItem *menuitem = GNT_MENUITEM(item);
+
+	menuitem->text = g_strdup(text);
+	return item;
+}
+
+gboolean gnt_menuitem_check_get_checked(GntMenuItemCheck *item)
+{
+		return item->checked;
+}
+
+void gnt_menuitem_check_set_checked(GntMenuItemCheck *item, gboolean set)
+{
+		item->checked = set;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntmenuitemcheck.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,52 @@
+#ifndef GNT_MENUITEM_CHECK_H
+#define GNT_MENUITEM_CHECK_H
+
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+#include "gntmenuitem.h"
+
+#define GNT_TYPE_MENUITEM_CHECK				(gnt_menuitem_check_get_gtype())
+#define GNT_MENUITEM_CHECK(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENUITEM_CHECK, GntMenuItemCheck))
+#define GNT_MENUITEM_CHECK_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENUITEM_CHECK, GntMenuItemCheckClass))
+#define GNT_IS_MENUITEM_CHECK(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENUITEM_CHECK))
+#define GNT_IS_MENUITEM_CHECK_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENUITEM_CHECK))
+#define GNT_MENUITEM_CHECK_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENUITEM_CHECK, GntMenuItemCheckClass))
+
+#define GNT_MENUITEM_CHECK_FLAGS(obj)				(GNT_MENUITEM_CHECK(obj)->priv.flags)
+#define GNT_MENUITEM_CHECK_SET_FLAGS(obj, flags)		(GNT_MENUITEM_CHECK_FLAGS(obj) |= flags)
+#define GNT_MENUITEM_CHECK_UNSET_FLAGS(obj, flags)	(GNT_MENUITEM_CHECK_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnMenuItemCheck			GntMenuItemCheck;
+typedef struct _GnMenuItemCheckPriv		GntMenuItemCheckPriv;
+typedef struct _GnMenuItemCheckClass		GntMenuItemCheckClass;
+
+struct _GnMenuItemCheck
+{
+	GntMenuItem parent;
+	gboolean checked;
+};
+
+struct _GnMenuItemCheckClass
+{
+	GntMenuItemClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_menuitem_check_get_gtype(void);
+
+GntMenuItem *gnt_menuitem_check_new(const char *text);
+
+gboolean gnt_menuitem_check_get_checked(GntMenuItemCheck *item);
+
+void gnt_menuitem_check_set_checked(GntMenuItemCheck *item, gboolean set);
+
+G_END_DECLS
+
+#endif /* GNT_MENUITEM_CHECK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntrc.sample	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,21 @@
+[general]
+shadow = 0
+
+[colors]
+black = 0; 0; 0
+red = 1000; 0; 0
+green = 0; 1000; 0
+blue = 250; 250; 700
+white = 1000; 1000; 1000
+gray = 700; 700; 700
+darkgray = 256; 256; 256
+
+[colorpairs]
+normal = black; white
+highlight = white; blue
+highlightd = black; gray
+shadow = black; darkgray
+title = white; blue
+titled = white; gray
+text = white; blue
+disabled = gray; white
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntstyle.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,344 @@
+#include "gntstyle.h"
+#include "gntcolors.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#if GLIB_CHECK_VERSION(2,6,0)
+static GKeyFile *gkfile;
+#endif
+
+static char * str_styles[GNT_STYLES];
+static int int_styles[GNT_STYLES];
+static int bool_styles[GNT_STYLES];
+
+const char *gnt_style_get(GntStyle style)
+{
+	return str_styles[style];
+}
+
+gboolean gnt_style_get_bool(GntStyle style, gboolean def)
+{
+	int i;
+	const char * str;
+
+	if (bool_styles[style] != -1)
+		return bool_styles[style];
+	
+	str = gnt_style_get(style);
+
+	if (str)
+	{
+		if (strcmp(str, "false") == 0)
+			def = FALSE;
+		else if (strcmp(str, "true") == 0)
+			def = TRUE;
+		else if (sscanf(str, "%d", &i) == 1)
+		{
+			if (i)
+				def = TRUE;
+			else
+				def = FALSE;
+		}
+	}
+
+	bool_styles[style] = def;
+	return bool_styles[style];
+}
+
+static void
+refine(char *text)
+{
+	char *s = text, *t = text;
+
+	while (*s)
+	{
+		if (*s == '^' && *(s + 1) == '[')
+		{
+			*t = '\033';  /* escape */
+			s++;
+		}
+		else if (*s == '\\')
+		{
+			if (*(s + 1) == '\0')
+				*t = ' ';
+			else
+			{
+				s++;
+				if (*s == 'r' || *s == 'n')
+					*t = '\r';
+				else if (*s == 't')
+					*t = '\t';
+				else
+					*t = *s;
+			}
+		}
+		else
+			*t = *s;
+		t++;
+		s++;
+	}
+	*t = '\0';
+}
+
+static char *
+parse_key(const char *key)
+{
+	char *ret = NULL;
+	int ctrl = 0, alt = 0;
+	char k;
+
+	/* XXX: Need to do something about ctrl/alt+home, end etc. */
+
+#define SPECIAL_KEY(k, code) do { \
+		if (strcasecmp(key, k) == 0) \
+			return g_strdup(code); \
+	} while (0)
+
+	SPECIAL_KEY("home",     GNT_KEY_HOME);
+	SPECIAL_KEY("end",      GNT_KEY_END);
+	SPECIAL_KEY("pageup",   GNT_KEY_PGUP);
+	SPECIAL_KEY("pagedown", GNT_KEY_PGDOWN);
+	SPECIAL_KEY("insert",   GNT_KEY_INS);
+	SPECIAL_KEY("delete",   GNT_KEY_DEL);
+
+	SPECIAL_KEY("left",   GNT_KEY_LEFT);
+	SPECIAL_KEY("right",  GNT_KEY_RIGHT);
+	SPECIAL_KEY("up",     GNT_KEY_UP);
+	SPECIAL_KEY("down",   GNT_KEY_DOWN);
+
+	SPECIAL_KEY("tab",    "\t");
+	SPECIAL_KEY("menu",   GNT_KEY_POPUP);
+
+	SPECIAL_KEY("f1",   GNT_KEY_F1);
+	SPECIAL_KEY("f2",   GNT_KEY_F2);
+	SPECIAL_KEY("f3",   GNT_KEY_F3);
+	SPECIAL_KEY("f4",   GNT_KEY_F4);
+	SPECIAL_KEY("f5",   GNT_KEY_F5);
+	SPECIAL_KEY("f6",   GNT_KEY_F6);
+	SPECIAL_KEY("f7",   GNT_KEY_F7);
+	SPECIAL_KEY("f8",   GNT_KEY_F8);
+	SPECIAL_KEY("f9",   GNT_KEY_F9);
+	SPECIAL_KEY("f10",  GNT_KEY_F10);
+	SPECIAL_KEY("f11",  GNT_KEY_F11);
+	SPECIAL_KEY("f12",  GNT_KEY_F12);
+
+#undef SPECIAL_KEY
+
+#define MATCH(string, var)	do { \
+		if (strncasecmp(key, string, sizeof(string) - 1) == 0) { \
+			key += sizeof(string) - 1; \
+			var = 1; \
+		} \
+	}while (0)
+
+	MATCH("c-", ctrl);
+	MATCH("ctl-", ctrl);
+	MATCH("ctr-", ctrl);
+	MATCH("ctrl-", ctrl);
+
+	MATCH("alt-", alt);
+	MATCH("a-", alt);
+	MATCH("m-", alt);
+	MATCH("meta-", alt);
+
+	if (strlen(key) != 1)  /* We can only have stuff like "ctrl-alt-a" */
+		return NULL;
+
+	if (ctrl && !isalpha(*key)) {
+		/* These keys cannot be used with ctrl */
+		return NULL;
+	}
+
+	if (ctrl)
+		k = *key | 0x20;
+	else
+		k = *key;
+
+	ret = g_strdup_printf("%s%c", alt ? "\033" : "", ctrl ? k - 0x60 : k);
+
+#undef MATCH
+
+	return ret;
+}
+
+void gnt_style_read_actions(GType type, GntBindableClass *klass)
+{
+#if GLIB_CHECK_VERSION(2,6,0)
+	char *name;
+	GError *error = NULL;
+
+	name = g_strdup_printf("%s::binding", g_type_name(type));
+
+	if (g_key_file_has_group(gkfile, name))
+	{
+		gsize len = 0;
+		char **keys;
+		
+		keys = g_key_file_get_keys(gkfile, name, &len, &error);
+		if (error)
+		{
+			g_printerr("GntStyle: %s\n", error->message);
+			g_error_free(error);
+			g_free(name);
+			return;
+		}
+
+		while (len--)
+		{
+			char *key, *action;
+
+			key = g_strdup(keys[len]);
+			action = g_key_file_get_string(gkfile, name, keys[len], &error);
+
+			if (error)
+			{
+				g_printerr("GntStyle: %s\n", error->message);
+				g_error_free(error);
+				error = NULL;
+			}
+			else
+			{
+				char *keycode = parse_key(key);
+				if (keycode == NULL) {
+					g_printerr("GntStyle: Invalid key-binding %s\n", key);
+				} else {
+					gnt_bindable_register_binding(klass, action, keycode, NULL);
+					g_free(keycode);
+				}
+			}
+			g_free(key);
+			g_free(action);
+		}
+		g_strfreev(keys);
+	}
+	g_free(name);
+#endif
+}
+
+void gnt_styles_get_keyremaps(GType type, GHashTable *hash)
+{
+#if GLIB_CHECK_VERSION(2,6,0)
+	char *name;
+	GError *error = NULL;
+	
+	name = g_strdup_printf("%s::remap", g_type_name(type));
+
+	if (g_key_file_has_group(gkfile, name))
+	{
+		gsize len = 0;
+		char **keys;
+		
+		keys = g_key_file_get_keys(gkfile, name, &len, &error);
+		if (error)
+		{
+			g_printerr("GntStyle: %s\n", error->message);
+			g_error_free(error);
+			g_free(name);
+			return;
+		}
+
+		while (len--)
+		{
+			char *key, *replace;
+
+			key = g_strdup(keys[len]);
+			replace = g_key_file_get_string(gkfile, name, keys[len], &error);
+
+			if (error)
+			{
+				g_printerr("GntStyle: %s\n", error->message);
+				g_error_free(error);
+				error = NULL;
+				g_free(key);
+			}
+			else
+			{
+				refine(key);
+				refine(replace);
+				g_hash_table_insert(hash, key, replace);
+			}
+		}
+		g_strfreev(keys);
+	}
+
+	g_free(name);
+#endif
+}
+
+#if GLIB_CHECK_VERSION(2,6,0)
+static void
+read_general_style(GKeyFile *kfile)
+{
+	GError *error = NULL;
+	gsize nkeys;
+	char **keys = g_key_file_get_keys(kfile, "general", &nkeys, &error);
+	int i;
+	struct
+	{
+		const char *style;
+		GntStyle en;
+	} styles[] = {{"shadow", GNT_STYLE_SHADOW},
+	              {"customcolor", GNT_STYLE_COLOR},
+	              {"mouse", GNT_STYLE_MOUSE},
+	              {"wm", GNT_STYLE_WM},
+	              {"remember_position", GNT_STYLE_REMPOS},
+	              {NULL, 0}};
+
+	if (error)
+	{
+		g_printerr("GntStyle: %s\n", error->message);
+		g_error_free(error);
+	}
+	else
+	{
+		for (i = 0; styles[i].style; i++)
+		{
+			error = NULL;
+			str_styles[styles[i].en] =
+					g_key_file_get_string(kfile, "general", styles[i].style, &error);
+		}
+	}
+	g_strfreev(keys);
+}
+#endif
+
+void gnt_style_read_configure_file(const char *filename)
+{
+#if GLIB_CHECK_VERSION(2,6,0)
+	GError *error = NULL;
+	gkfile = g_key_file_new();
+
+	if (!g_key_file_load_from_file(gkfile, filename, G_KEY_FILE_NONE, &error))
+	{
+		g_printerr("GntStyle: %s\n", error->message);
+		g_error_free(error);
+		return;
+	}
+	gnt_colors_parse(gkfile);
+	read_general_style(gkfile);
+#endif
+}
+
+void gnt_init_styles()
+{
+	int i;
+	for (i = 0; i < GNT_STYLES; i++)
+	{
+		str_styles[i] = NULL;
+		int_styles[i] = -1;
+		bool_styles[i] = -1;
+	}
+}
+
+void gnt_uninit_styles()
+{
+	int i;
+	for (i = 0; i < GNT_STYLES; i++)
+		g_free(str_styles[i]);
+
+#if GLIB_CHECK_VERSION(2,6,0)
+	g_key_file_free(gkfile);
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntstyle.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,27 @@
+#include "gnt.h"
+
+typedef enum
+{
+	GNT_STYLE_SHADOW = 0,
+	GNT_STYLE_COLOR = 1,
+	GNT_STYLE_MOUSE = 2,
+	GNT_STYLE_WM = 3,
+	GNT_STYLE_REMPOS = 4,
+	GNT_STYLES
+} GntStyle;
+
+void gnt_style_read_configure_file(const char *filename);
+
+const char *gnt_style_get(GntStyle style);
+
+gboolean gnt_style_get_bool(GntStyle style, gboolean def);
+
+/* This should be called only once for the each type */
+void gnt_styles_get_keyremaps(GType type, GHashTable *hash);
+
+void gnt_style_read_actions(GType type, GntBindableClass *klass);
+
+void gnt_init_styles();
+
+void gnt_uninit_styles();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnttextview.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,593 @@
+#include "gnttextview.h"
+#include "gntutils.h"
+
+#include <string.h>
+
+enum
+{
+	SIGS = 1,
+};
+
+typedef struct
+{
+	GntTextFormatFlags tvflag;
+	chtype flags;
+	int start;
+	int end;     /* This is the next byte of the last character of this segment */
+} GntTextSegment;
+
+typedef struct
+{
+	GList *segments;         /* A list of GntTextSegments */
+	int length;              /* The current length of the line so far (ie. onscreen width) */
+	gboolean soft;           /* TRUE if it's an overflow from prev. line */
+} GntTextLine;
+
+typedef struct
+{
+	char *name;
+	int start;
+	int end;
+} GntTextTag;
+
+static GntWidgetClass *parent_class = NULL;
+
+static void
+gnt_text_view_draw(GntWidget *widget)
+{
+	GntTextView *view = GNT_TEXT_VIEW(widget);
+	int i = 0;
+	GList *lines;
+	int rows, scrcol;
+
+	werase(widget->window);
+
+	for (i = 0, lines = view->list; i < widget->priv.height && lines; i++, lines = lines->next)
+	{
+		GList *iter;
+		GntTextLine *line = lines->data;
+
+		wmove(widget->window, widget->priv.height - 1 - i, 0);
+
+		for (iter = line->segments; iter; iter = iter->next)
+		{
+			GntTextSegment *seg = iter->data;
+			char *end = view->string->str + seg->end;
+			char back = *end;
+			*end = '\0';
+			wattrset(widget->window, seg->flags);
+			wprintw(widget->window, "%s", (view->string->str + seg->start));
+			*end = back;
+		}
+		wattroff(widget->window, A_UNDERLINE | A_BLINK | A_REVERSE);
+		whline(widget->window, ' ', widget->priv.width - line->length - 1);
+	}
+
+	scrcol = widget->priv.width - 1;
+	rows = widget->priv.height - 2;
+	if (rows > 0)
+	{
+		int total = g_list_length(g_list_first(view->list));
+		int showing, position, up, down;
+
+		showing = rows * rows / total + 1;
+		showing = MIN(rows, showing);
+
+		total -= rows;
+		up = g_list_length(lines);
+		down = total - up;
+
+		position = (rows - showing) * up / MAX(1, up + down);
+		position = MAX((lines != NULL), position);
+
+		if (showing + position > rows)
+			position = rows - showing;
+		
+		if (showing + position == rows && view->list && view->list->prev)
+			position = MAX(1, rows - 1 - showing);
+		else if (showing + position < rows && view->list && !view->list->prev)
+			position = rows - showing;
+
+		mvwvline(widget->window, position + 1, scrcol,
+				ACS_CKBOARD | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D), showing);
+	}
+
+	mvwaddch(widget->window, 0, scrcol,
+			(lines ? ACS_UARROW : ' ') | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+	mvwaddch(widget->window, widget->priv.height - 1, scrcol,
+			((view->list && view->list->prev) ? ACS_DARROW : ' ') |
+				COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+
+	GNTDEBUG;
+}
+
+static void
+gnt_text_view_size_request(GntWidget *widget)
+{
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		gnt_widget_set_size(widget, 64, 20);
+	}
+}
+
+static void
+gnt_text_view_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static gboolean
+gnt_text_view_key_pressed(GntWidget *widget, const char *text)
+{
+	return FALSE;
+}
+
+static void
+free_text_segment(gpointer data, gpointer null)
+{
+	GntTextSegment *seg = data;
+	g_free(seg);
+}
+
+static void
+free_text_line(gpointer data, gpointer null)
+{
+	GntTextLine *line = data;
+	g_list_foreach(line->segments, free_text_segment, NULL);
+	g_list_free(line->segments);
+	g_free(line);
+}
+
+static void
+free_tag(gpointer data, gpointer null)
+{
+	GntTextTag *tag = data;
+	g_free(tag->name);
+	g_free(tag);
+}
+
+static void
+gnt_text_view_destroy(GntWidget *widget)
+{
+	GntTextView *view = GNT_TEXT_VIEW(widget);
+	view->list = g_list_first(view->list);
+	g_list_foreach(view->list, free_text_line, NULL);
+	g_list_free(view->list);
+	g_list_foreach(view->tags, free_tag, NULL);
+	g_list_free(view->tags);
+	g_string_free(view->string, TRUE);
+}
+
+static gboolean
+gnt_text_view_clicked(GntWidget *widget, GntMouseEvent event, int x, int y)
+{
+	if (event == GNT_MOUSE_SCROLL_UP) {
+		gnt_text_view_scroll(GNT_TEXT_VIEW(widget), -1);
+	} else if (event == GNT_MOUSE_SCROLL_DOWN) {
+		gnt_text_view_scroll(GNT_TEXT_VIEW(widget), 1);
+	} else
+		return FALSE;
+	return TRUE;
+}
+
+static void
+gnt_text_view_reflow(GntTextView *view)
+{
+	/* This is pretty ugly, and inefficient. Someone do something about it. */
+	GntTextLine *line;
+	GList *back, *iter, *list;
+	GString *string;
+	int pos = 0;    /* no. of 'real' lines */
+
+	list = view->list;
+	while (list->prev) {
+		line = list->data;
+		if (!line->soft)
+			pos++;
+		list = list->prev;
+	}
+
+	back = g_list_last(view->list);
+	view->list = NULL;
+
+	string = view->string;
+	view->string = NULL;
+	gnt_text_view_clear(view);
+
+	view->string = g_string_set_size(view->string, string->len);
+	view->string->len = 0;
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(view), GNT_WIDGET_DRAWING);
+
+	for (; back; back = back->prev) {
+		line = back->data;
+		if (back->next && !line->soft) {
+			gnt_text_view_append_text_with_flags(view, "\n", GNT_TEXT_FLAG_NORMAL);
+		}
+
+		for (iter = line->segments; iter; iter = iter->next) {
+			GntTextSegment *seg = iter->data;
+			char *start = string->str + seg->start;
+			char *end = string->str + seg->end;
+			char back = *end;
+			*end = '\0';
+			gnt_text_view_append_text_with_flags(view, start, seg->tvflag);
+			*end = back;
+		}
+		free_text_line(line, NULL);
+	}
+	g_list_free(list);
+
+	list = view->list = g_list_first(view->list);
+	/* Go back to the line that was in view before resizing started */
+	while (pos--) {
+		while (((GntTextLine*)list->data)->soft)
+			list = list->next;
+		list = list->next;
+	}
+	view->list = list;
+	GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(view), GNT_WIDGET_DRAWING);
+	if (GNT_WIDGET(view)->window)
+		gnt_widget_draw(GNT_WIDGET(view));
+	g_string_free(string, TRUE);
+}
+
+static void
+gnt_text_view_size_changed(GntWidget *widget, int w, int h)
+{
+	if (w != widget->priv.width) {
+		gnt_text_view_reflow(GNT_TEXT_VIEW(widget));
+	}
+}
+
+static void
+gnt_text_view_class_init(GntTextViewClass *klass)
+{
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_text_view_destroy;
+	parent_class->draw = gnt_text_view_draw;
+	parent_class->map = gnt_text_view_map;
+	parent_class->size_request = gnt_text_view_size_request;
+	parent_class->key_pressed = gnt_text_view_key_pressed;
+	parent_class->clicked = gnt_text_view_clicked;
+	parent_class->size_changed = gnt_text_view_size_changed;
+
+	GNTDEBUG;
+}
+
+static void
+gnt_text_view_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	
+	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_GROW_Y | GNT_WIDGET_GROW_X);
+
+	widget->priv.minw = 5;
+	widget->priv.minh = 2;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntTextView API
+ *****************************************************************************/
+GType
+gnt_text_view_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntTextViewClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_text_view_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntTextView),
+			0,						/* n_preallocs		*/
+			gnt_text_view_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntTextView",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_text_view_new()
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_TEXTVIEW, NULL);
+	GntTextView *view = GNT_TEXT_VIEW(widget);
+	GntTextLine *line = g_new0(GntTextLine, 1);
+
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+
+	view->string = g_string_new(NULL);
+	view->list = g_list_append(view->list, line);
+
+	return widget;
+}
+
+void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextFormatFlags flags)
+{
+	gnt_text_view_append_text_with_tag(view, text, flags, NULL);
+}
+
+void gnt_text_view_append_text_with_tag(GntTextView *view, const char *text,
+			GntTextFormatFlags flags, const char *tagname)
+{
+	GntWidget *widget = GNT_WIDGET(view);
+	int fl = 0;
+	const char *start, *end;
+	GList *list = view->list;
+	GntTextLine *line;
+	int len;
+
+	if (text == NULL || *text == '\0')
+		return;
+
+	fl = gnt_text_format_flag_to_chtype(flags);
+
+	len = view->string->len;
+	view->string = g_string_append(view->string, text);
+
+	if (tagname) {
+		GntTextTag *tag = g_new0(GntTextTag, 1);
+		tag->name = g_strdup(tagname);
+		tag->start = len;
+		tag->end = view->string->len;
+		view->tags = g_list_append(view->tags, tag);
+	}
+
+	view->list = g_list_first(view->list);
+
+	start = end = view->string->str + len;
+
+	while (*start) {
+		GntTextSegment *seg = NULL;
+
+		if (*end == '\n' || *end == '\r') {
+			end++;
+			start = end;
+			gnt_text_view_next_line(view);
+			view->list = g_list_first(view->list);
+			continue;
+		}
+
+		line = view->list->data;
+		if (line->length == widget->priv.width - 1) {
+			/* The last added line was exactly the same width as the widget */
+			line = g_new0(GntTextLine, 1);
+			line->soft = TRUE;
+			view->list = g_list_prepend(view->list, line);
+		}
+
+		if ((end = strchr(start, '\n')) != NULL ||
+			(end = strchr(start, '\r')) != NULL) {
+			len = gnt_util_onscreen_width(start, end - 1);
+			if (len >= widget->priv.width - line->length - 1) {
+				end = NULL;
+			}
+		}
+
+		if (end == NULL)
+			end = gnt_util_onscreen_width_to_pointer(start,
+					widget->priv.width - line->length - 1, &len);
+
+		/* Try to append to the previous segment if possible */
+		if (line->segments) {
+			seg = g_list_last(line->segments)->data;
+			if (seg->flags != fl)
+				seg = NULL;
+		}
+
+		if (seg == NULL) {
+			seg = g_new0(GntTextSegment, 1);
+			seg->start = start - view->string->str;
+			seg->tvflag = flags;
+			seg->flags = fl;
+			line->segments = g_list_append(line->segments, seg);
+		}
+		seg->end = end - view->string->str;
+		line->length += len;
+
+		start = end;
+		if (*end && *end != '\n' && *end != '\r') {
+			line = g_new0(GntTextLine, 1);
+			line->soft = TRUE;
+			view->list = g_list_prepend(view->list, line);
+		}
+	}
+
+	view->list = list;
+
+	gnt_widget_draw(widget);
+}
+
+void gnt_text_view_scroll(GntTextView *view, int scroll)
+{
+	if (scroll == 0)
+	{
+		view->list = g_list_first(view->list);
+	}
+	else if (scroll > 0)
+	{
+		GList *list = g_list_nth_prev(view->list, scroll);
+		if (list == NULL)
+			list = g_list_first(view->list);
+		view->list = list;
+	}
+	else if (scroll < 0)
+	{
+		GList *list = g_list_nth(view->list, -scroll);
+		if (list == NULL)
+			list = g_list_last(view->list);
+		view->list = list;
+	}
+		
+	gnt_widget_draw(GNT_WIDGET(view));
+}
+
+void gnt_text_view_next_line(GntTextView *view)
+{
+	GntTextLine *line = g_new0(GntTextLine, 1);
+	GList *list = view->list;
+	
+	view->list = g_list_prepend(g_list_first(view->list), line);
+	view->list = list;
+	gnt_widget_draw(GNT_WIDGET(view));
+}
+
+chtype gnt_text_format_flag_to_chtype(GntTextFormatFlags flags)
+{
+	chtype fl = 0;
+
+	if (flags & GNT_TEXT_FLAG_BOLD)
+		fl |= A_BOLD;
+	if (flags & GNT_TEXT_FLAG_UNDERLINE)
+		fl |= A_UNDERLINE;
+	if (flags & GNT_TEXT_FLAG_BLINK)
+		fl |= A_BLINK;
+
+	if (flags & GNT_TEXT_FLAG_DIM)
+		fl |= (A_DIM | COLOR_PAIR(GNT_COLOR_DISABLED));
+	else if (flags & GNT_TEXT_FLAG_HIGHLIGHT)
+		fl |= (A_DIM | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
+	else
+		fl |= COLOR_PAIR(GNT_COLOR_NORMAL);
+
+	return fl;
+}
+
+void gnt_text_view_clear(GntTextView *view)
+{
+	GntTextLine *line;
+
+	g_list_foreach(view->list, free_text_line, NULL);
+	g_list_free(view->list);
+	view->list = NULL;
+
+	line = g_new0(GntTextLine, 1);
+	view->list = g_list_append(view->list, line);
+	if (view->string)
+		g_string_free(view->string, TRUE);
+	view->string = g_string_new(NULL);
+
+	if (GNT_WIDGET(view)->window)
+		gnt_widget_draw(GNT_WIDGET(view));
+}
+
+int gnt_text_view_get_lines_below(GntTextView *view)
+{
+	int below = 0;
+	GList *list = view->list;
+	while ((list = list->prev))
+		++below;
+	return below;
+}
+
+int gnt_text_view_get_lines_above(GntTextView *view)
+{
+	int above = 0;
+	GList *list = view->list;
+	list = g_list_nth(view->list, GNT_WIDGET(view)->priv.height);
+	if (!list)
+		return 0;
+	while ((list = list->next))
+		++above;
+	return above;
+}
+
+/**
+ * XXX: There are quite possibly more than a few bugs here.
+ */
+int gnt_text_view_tag_change(GntTextView *view, const char *name, const char *text, gboolean all)
+{
+	GList *alllines = g_list_first(view->list);
+	GList *list, *next, *iter, *inext;
+	const int text_length = text ? strlen(text) : 0;
+	int count = 0;
+	for (list = view->tags; list; list = next) {
+		GntTextTag *tag = list->data;
+		next = list->next;
+		if (strcmp(tag->name, name) == 0) {
+			int change;
+			char *before, *after;
+
+			count++;
+
+			before = g_strndup(view->string->str, tag->start);
+			after = g_strdup(view->string->str + tag->end);
+			change = (tag->end - tag->start) - text_length;
+
+			g_string_printf(view->string, "%s%s%s", before, text ? text : "", after);
+			g_free(before);
+			g_free(after);
+
+			/* Update the offsets of the next tags */
+			for (iter = next; iter; iter = iter->next) {
+				GntTextTag *t = iter->data;
+				t->start -= change;
+				t->end -= change;
+			}
+
+			/* Update the offsets of the segments */
+			for (iter = alllines; iter; iter = inext) {
+				GList *segs, *snext;
+				GntTextLine *line = iter->data;
+				inext = iter->next;
+				for (segs = line->segments; segs; segs = snext) {
+					GntTextSegment *seg = segs->data;
+					snext = segs->next;
+					if (seg->start >= tag->end) {
+						/* The segment is somewhere after the tag */
+						seg->start -= change;
+						seg->end -= change;
+					} else if (seg->end <= tag->start) {
+						/* This segment is somewhere in front of the tag */
+					} else if (seg->start >= tag->start) {
+						/* This segment starts in the middle of the tag */
+						if (text == NULL) {
+							free_text_segment(seg, NULL);
+							line->segments = g_list_delete_link(line->segments, segs);
+							if (line->segments == NULL) {
+								free_text_line(line, NULL);
+								if (view->list == iter) {
+									if (inext)
+										view->list = inext;
+									else
+										view->list = iter->prev;
+								}
+								alllines = g_list_delete_link(alllines, iter);
+							}
+						} else {
+							/* XXX: (null) */
+							seg->start = tag->start;
+							seg->end = tag->end - change;
+						}
+						line->length -= change;
+						/* XXX: Make things work if the tagged text spans over several lines. */
+					} else {
+						/* XXX: handle the rest of the conditions */
+						g_printerr("WTF! This needs to be handled properly!!\n");
+					}
+				}
+			}
+			if (text == NULL) {
+				/* Remove the tag */
+				view->tags = g_list_delete_link(view->tags, list);
+				free_tag(tag, NULL);
+			} else {
+				tag->end -= change;
+			}
+			if (!all)
+				break;
+		}
+	}
+	return count;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnttextview.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,86 @@
+#ifndef GNT_TEXT_VIEW_H
+#define GNT_TEXT_VIEW_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_TEXTVIEW				(gnt_text_view_get_gtype())
+#define GNT_TEXT_VIEW(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_TEXTVIEW, GntTextView))
+#define GNT_TEXT_VIEW_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_TEXTVIEW, GntTextViewClass))
+#define GNT_IS_TEXTVIEW(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_TEXTVIEW))
+#define GNT_IS_TEXTVIEW_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_TEXTVIEW))
+#define GNT_TEXT_VIEW_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_TEXTVIEW, GntTextViewClass))
+
+#define GNT_TEXT_VIEW_FLAGS(obj)				(GNT_TEXT_VIEW(obj)->priv.flags)
+#define GNT_TEXT_VIEW_SET_FLAGS(obj, flags)		(GNT_TEXT_VIEW_FLAGS(obj) |= flags)
+#define GNT_TEXT_VIEW_UNSET_FLAGS(obj, flags)	(GNT_TEXT_VIEW_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnTextView			GntTextView;
+typedef struct _GnTextViewPriv		GntTextViewPriv;
+typedef struct _GnTextViewClass		GntTextViewClass;
+
+struct _GnTextView
+{
+	GntWidget parent;
+
+	GString *string;
+	GList *list;        /* List of GntTextLine */
+
+	GList *tags;       /* A list of tags */
+};
+
+typedef enum
+{
+	GNT_TEXT_FLAG_NORMAL      = 0,
+	GNT_TEXT_FLAG_BOLD        = 1 << 0,
+	GNT_TEXT_FLAG_UNDERLINE   = 1 << 1,
+	GNT_TEXT_FLAG_BLINK       = 1 << 2,
+	GNT_TEXT_FLAG_DIM         = 1 << 3,
+	GNT_TEXT_FLAG_HIGHLIGHT   = 1 << 4,
+} GntTextFormatFlags;
+
+struct _GnTextViewClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_text_view_get_gtype(void);
+
+/* XXX: For now, don't set a textview to have any border.
+ *      If you want borders real bad, put it in a box. */
+GntWidget *gnt_text_view_new();
+
+/* scroll > 0 means scroll up, < 0 means scroll down, == 0 means scroll to the end */
+void gnt_text_view_scroll(GntTextView *view, int scroll);
+
+void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextFormatFlags flags);
+
+void gnt_text_view_append_text_with_tag(GntTextView *view, const char *text, GntTextFormatFlags flags, const char *tag);
+
+/* Move the cursor to the beginning of the next line and resets text-attributes.
+ * It first completes the current line with the current text-attributes. */
+void gnt_text_view_next_line(GntTextView *view);
+
+chtype gnt_text_format_flag_to_chtype(GntTextFormatFlags flags);
+
+void gnt_text_view_clear(GntTextView *view);
+
+int gnt_text_view_get_lines_below(GntTextView *view);
+
+int gnt_text_view_get_lines_above(GntTextView *view);
+
+/* If text is NULL, then the tag is removed. */
+int gnt_text_view_tag_change(GntTextView *view, const char *name, const char *text, gboolean all);
+
+G_END_DECLS
+
+#endif /* GNT_TEXT_VIEW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnttree.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,1494 @@
+#include "gntmarshal.h"
+#include "gntstyle.h"
+#include "gnttree.h"
+#include "gntutils.h"
+
+#include <string.h>
+#include <ctype.h>
+
+#define SEARCH_TIMEOUT 4000   /* 4 secs */
+
+enum
+{
+	SIG_SELECTION_CHANGED,
+	SIG_SCROLLED,
+	SIG_TOGGLED,
+	SIGS,
+};
+
+#define	TAB_SIZE 3
+
+/* XXX: Make this one into a GObject?
+ * 		 ... Probably not */
+struct _GnTreeRow
+{
+	void *key;
+	void *data;		/* XXX: unused */
+
+	gboolean collapsed;
+	gboolean choice;            /* Is this a choice-box?
+	                               If choice is true, then child will be NULL */
+	gboolean isselected;
+	GntTextFormatFlags flags;
+
+	GntTreeRow *parent;
+	GntTreeRow *child;
+	GntTreeRow *next;
+	GntTreeRow *prev;
+
+	GList *columns;
+	GntTree *tree;
+};
+
+struct _GnTreeCol
+{
+	char *text;
+	int span;       /* How many columns does it span? */
+};
+
+static GntWidgetClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+
+/* Move the item at position old to position new */
+static GList *
+g_list_reposition_child(GList *list, int old, int new)
+{
+	gpointer item = g_list_nth_data(list, old);
+	list = g_list_remove(list, item);
+	if (old < new)
+		new--;   /* because the positions would have shifted after removing the item */
+	list = g_list_insert(list, item, new);
+	return list;
+}
+
+static GntTreeRow *
+_get_next(GntTreeRow *row, gboolean godeep)
+{
+	if (row == NULL)
+		return NULL;
+	if (godeep && row->child)
+		return row->child;
+	if (row->next)
+		return row->next;
+	return _get_next(row->parent, FALSE);
+}
+
+static gboolean
+row_matches_search(GntTreeRow *row)
+{
+	GntTree *t = row->tree;
+	if (t->search && t->search->len > 0) {
+		char *one = g_utf8_casefold(((GntTreeCol*)row->columns->data)->text, -1);
+		char *two = g_utf8_casefold(t->search->str, -1);
+		char *z = strstr(one, two);
+		g_free(one);
+		g_free(two);
+		if (z == NULL)
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static GntTreeRow *
+get_next(GntTreeRow *row)
+{
+	if (row == NULL)
+		return NULL;
+	while ((row = _get_next(row, !row->collapsed)) != NULL) {
+		if (row_matches_search(row))
+			break;
+	}
+	return row;
+}
+
+/* Returns the n-th next row. If it doesn't exist, returns NULL */
+static GntTreeRow *
+get_next_n(GntTreeRow *row, int n)
+{
+	while (row && n--)
+		row = get_next(row);
+	return row;
+}
+
+/* Returns the n-th next row. If it doesn't exist, then the last non-NULL node */
+static GntTreeRow *
+get_next_n_opt(GntTreeRow *row, int n, int *pos)
+{
+	GntTreeRow *next = row;
+	int r = 0;
+
+	if (row == NULL)
+		return NULL;
+
+	while (row && n--)
+	{
+		row = get_next(row);
+		if (row)
+		{
+			next = row;
+			r++;
+		}
+	}
+
+	if (pos)
+		*pos = r;
+
+	return next;
+}
+
+static GntTreeRow *
+get_last_child(GntTreeRow *row)
+{
+	if (row == NULL)
+		return NULL;
+	if (!row->collapsed && row->child)
+		row = row->child;
+	else
+		return row;
+
+	while(row->next)
+		row = row->next;
+	if (!row->collapsed && row->child)
+		row = get_last_child(row->child);
+	return row;
+}
+
+static GntTreeRow *
+get_prev(GntTreeRow *row)
+{
+	if (row == NULL)
+		return NULL;
+	while (row) {
+		if (row->prev)
+			row = get_last_child(row->prev);
+		else
+			row = row->parent;
+		if (!row || row_matches_search(row))
+			break;
+	}
+	return row;
+}
+
+static GntTreeRow *
+get_prev_n(GntTreeRow *row, int n)
+{
+	while (row && n--)
+		row = get_prev(row);
+	return row;
+}
+
+/* Distance of row from the root */
+/* XXX: This is uber-inefficient */
+static int
+get_root_distance(GntTreeRow *row)
+{
+	if (row == NULL)
+		return -1;
+	return get_root_distance(get_prev(row)) + 1;
+}
+
+/* Returns the distance between a and b. 
+ * If a is 'above' b, then the distance is positive */
+static int
+get_distance(GntTreeRow *a, GntTreeRow *b)
+{
+	/* First get the distance from a to the root.
+	 * Then the distance from b to the root.
+	 * Subtract.
+	 * It's not that good, but it works. */
+	int ha = get_root_distance(a);
+	int hb = get_root_distance(b);
+
+	return (hb - ha);
+}
+
+static int
+find_depth(GntTreeRow *row)
+{
+	int dep = -1;
+
+	while (row)
+	{
+		dep++;
+		row = row->parent;
+	}
+
+	return dep;
+}
+
+static char *
+update_row_text(GntTree *tree, GntTreeRow *row)
+{
+	GString *string = g_string_new(NULL);
+	GList *iter;
+	int i;
+
+	for (i = 0, iter = row->columns; i < tree->ncol && iter; i++, iter = iter->next)
+	{
+		GntTreeCol *col = iter->data;
+		const char *text;
+		int len = gnt_util_onscreen_width(col->text, NULL);
+		int fl = 0;
+		gboolean cut = FALSE;
+
+		if (i == 0)
+		{
+			if (row->choice)
+			{
+				g_string_append_printf(string, "[%c] ",
+						row->isselected ? 'X' : ' ');
+				fl = 4;
+			}
+			else if (row->parent == NULL && row->child)
+			{
+				if (row->collapsed)
+				{
+					string = g_string_append(string, "+ ");
+				}
+				else
+				{
+					string = g_string_append(string, "- ");
+				}
+				fl = 2;
+			}
+			else
+			{
+				fl = TAB_SIZE * find_depth(row);
+				g_string_append_printf(string, "%*s", fl, "");
+			}
+			len += fl;
+		}
+		else
+			g_string_append_c(string, '|');
+
+		if (len > tree->columns[i].width) {
+			len = tree->columns[i].width - 1;
+			cut = TRUE;
+		}
+		text = gnt_util_onscreen_width_to_pointer(col->text, len - fl, NULL);
+		string = g_string_append_len(string, col->text, text - col->text);
+		if (cut) { /* ellipsis */
+			if (gnt_ascii_only())
+				g_string_append_c(string, '~');
+			else
+				string = g_string_append(string, "\342\200\246");
+			len++;
+		}
+
+		if (len < tree->columns[i].width && iter->next)
+			g_string_append_printf(string, "%*s", tree->columns[i].width - len, "");
+	}
+	return g_string_free(string, FALSE);
+}
+
+static void
+tree_mark_columns(GntTree *tree, int pos, int y, chtype type)
+{
+	GntWidget *widget = GNT_WIDGET(tree);
+	int i;
+	int x = pos;
+
+	for (i = 0; i < tree->ncol - 1; i++)
+	{
+		x += tree->columns[i].width;
+		mvwaddch(widget->window, y, x + i, type);
+	}
+}
+
+static void
+redraw_tree(GntTree *tree)
+{
+	int start, i;
+	GntWidget *widget = GNT_WIDGET(tree);
+	GntTreeRow *row;
+	int pos, up, down;
+	int rows, scrcol;
+
+	if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_MAPPED))
+		return;
+
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		pos = 0;
+	else
+		pos = 1;
+
+	if (tree->top == NULL)
+		tree->top = tree->root;
+	if (tree->current == NULL)
+		tree->current = tree->root;
+
+	wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
+
+	start = 0;
+	if (tree->show_title)
+	{
+		int i;
+		int x = pos;
+
+		mvwhline(widget->window, pos + 1, pos, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				widget->priv.width - pos - 1);
+		
+		for (i = 0; i < tree->ncol; i++)
+		{
+			mvwprintw(widget->window, pos, x + i, tree->columns[i].title);
+			x += tree->columns[i].width;
+		}
+		if (pos)
+		{
+			tree_mark_columns(tree, pos, 0, ACS_TTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
+			tree_mark_columns(tree, pos, widget->priv.height - pos,
+					ACS_BTEE | COLOR_PAIR(GNT_COLOR_NORMAL));
+		}
+		tree_mark_columns(tree, pos, pos + 1,
+			(tree->show_separator ? ACS_PLUS : ACS_HLINE) | COLOR_PAIR(GNT_COLOR_NORMAL));
+		tree_mark_columns(tree, pos, pos,
+			(tree->show_separator ? ACS_VLINE : ' ') | COLOR_PAIR(GNT_COLOR_NORMAL));
+		start = 2;
+	}
+
+	rows = widget->priv.height - pos * 2 - start - 1;
+	tree->bottom = get_next_n_opt(tree->top, rows, &down);
+	if (down < rows)
+	{
+		tree->top = get_prev_n(tree->bottom, rows);
+		if (tree->top == NULL)
+			tree->top = tree->root;
+	}
+
+	up = get_distance(tree->top, tree->current);
+	if (up < 0)
+		tree->top = tree->current;
+	else if (up >= widget->priv.height - pos)
+		tree->top = get_prev_n(tree->current, rows);
+
+	if (tree->top && !row_matches_search(tree->top))
+		tree->top = get_next(tree->top);
+	row = tree->top;
+	scrcol = widget->priv.width - 1 - 2 * pos;  /* exclude the borders and the scrollbar */
+	for (i = start + pos; row && i < widget->priv.height - pos;
+				i++, row = get_next(row))
+	{
+		char *str;
+		int wr;
+
+		GntTextFormatFlags flags = row->flags;
+		int attr = 0;
+
+		if (!row_matches_search(row))
+			continue;
+		str = update_row_text(tree, row);
+
+		if ((wr = gnt_util_onscreen_width(str, NULL)) > scrcol)
+		{
+			char *s = (char*)gnt_util_onscreen_width_to_pointer(str, scrcol, &wr);
+			*s = '\0';
+		}
+
+		if (flags & GNT_TEXT_FLAG_BOLD)
+			attr |= A_BOLD;
+		if (flags & GNT_TEXT_FLAG_UNDERLINE)
+			attr |= A_UNDERLINE;
+		if (flags & GNT_TEXT_FLAG_BLINK)
+			attr |= A_BLINK;
+
+		if (row == tree->current)
+		{
+			if (gnt_widget_has_focus(widget))
+				attr |= COLOR_PAIR(GNT_COLOR_HIGHLIGHT);
+			else
+				attr |= COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D);
+		}
+		else
+		{
+			if (flags & GNT_TEXT_FLAG_DIM)
+				attr |= (A_DIM | COLOR_PAIR(GNT_COLOR_DISABLED));
+			else if (flags & GNT_TEXT_FLAG_HIGHLIGHT)
+				attr |= (A_DIM | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
+			else
+				attr |= COLOR_PAIR(GNT_COLOR_NORMAL);
+		}
+
+		wbkgdset(widget->window, '\0' | attr);
+		mvwprintw(widget->window, i, pos, str);
+		whline(widget->window, ' ', scrcol - wr);
+		tree->bottom = row;
+		g_free(str);
+		tree_mark_columns(tree, pos, i,
+			(tree->show_separator ? ACS_VLINE : ' ') | attr);
+	}
+
+	wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
+	while (i < widget->priv.height - pos)
+	{
+		mvwhline(widget->window, i, pos, ' ',
+				widget->priv.width - pos * 2 - 1);
+		tree_mark_columns(tree, pos, i,
+			(tree->show_separator ? ACS_VLINE : ' '));
+		i++;
+	}
+
+	scrcol = widget->priv.width - pos - 1;  /* position of the scrollbar */
+	rows--;
+	if (rows > 0)
+	{
+		int total;
+		int showing, position;
+
+		get_next_n_opt(tree->root, g_list_length(tree->list), &total);
+		showing = rows * rows / MAX(total, 1) + 1;
+		showing = MIN(rows, showing);
+
+		total -= rows;
+		up = get_distance(tree->root, tree->top);
+		down = total - up;
+
+		position = (rows - showing) * up / MAX(1, up + down);
+		position = MAX((tree->top != tree->root), position);
+
+		if (showing + position > rows)
+			position = rows - showing;
+
+		if (showing + position == rows  && row)
+			position = MAX(0, rows - 1 - showing);
+		else if (showing + position < rows && !row)
+			position = rows - showing;
+
+		position += pos + start + 1;
+
+		mvwvline(widget->window, pos + start + 1, scrcol,
+				' ' | COLOR_PAIR(GNT_COLOR_NORMAL), rows);
+		mvwvline(widget->window, position, scrcol,
+				ACS_CKBOARD | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D), showing);
+	}
+
+	mvwaddch(widget->window, start + pos, scrcol,
+			((tree->top != tree->root) ?  ACS_UARROW : ' ') |
+				COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+
+	mvwaddch(widget->window, widget->priv.height - pos - 1, scrcol,
+			(row ?  ACS_DARROW : ' ') | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+
+	gnt_widget_queue_update(widget);
+}
+
+static void
+gnt_tree_draw(GntWidget *widget)
+{
+	GntTree *tree = GNT_TREE(widget);
+
+	redraw_tree(tree);
+	
+	GNTDEBUG;
+}
+
+static void
+gnt_tree_size_request(GntWidget *widget)
+{
+	if (widget->priv.height == 0)
+		widget->priv.height = 10;	/* XXX: Why?! */
+	if (widget->priv.width == 0)
+	{
+		GntTree *tree = GNT_TREE(widget);
+		int i, width = 0;
+		for (i = 0; i < tree->ncol; i++)
+			width += tree->columns[i].width;
+		widget->priv.width = width + i;
+	}
+}
+
+static void
+gnt_tree_map(GntWidget *widget)
+{
+	GntTree *tree = GNT_TREE(widget);
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+	{
+		gnt_widget_size_request(widget);
+	}
+	tree->top = tree->root;
+	tree->current = tree->root;
+	GNTDEBUG;
+}
+
+static void
+tree_selection_changed(GntTree *tree, GntTreeRow *old, GntTreeRow *current)
+{
+	g_signal_emit(tree, signals[SIG_SELECTION_CHANGED], 0, old->key, current->key);
+}
+
+static gboolean
+action_down(GntBindable *bind, GList *null)
+{
+	int dist;
+	GntTree *tree = GNT_TREE(bind);
+	GntTreeRow *old = tree->current;
+	GntTreeRow *row = get_next(tree->current);
+	if (row == NULL)
+		return FALSE;
+	tree->current = row;
+	if ((dist = get_distance(tree->current, tree->bottom)) < 0)
+		gnt_tree_scroll(tree, -dist);
+	else
+		redraw_tree(tree);
+	if (old != tree->current)
+		tree_selection_changed(tree, old, tree->current);
+	return TRUE;
+}
+
+static gboolean
+action_up(GntBindable *bind, GList *list)
+{
+	int dist;
+	GntTree *tree = GNT_TREE(bind);
+	GntTreeRow *old = tree->current;
+	GntTreeRow *row = get_prev(tree->current);
+	if (!row)
+		return FALSE;
+	tree->current = row;
+	if ((dist = get_distance(tree->current, tree->top)) > 0)
+		gnt_tree_scroll(tree, -dist);
+	else
+		redraw_tree(tree);
+	if (old != tree->current)
+		tree_selection_changed(tree, old, tree->current);
+
+	return TRUE;
+}
+
+static gboolean
+action_page_down(GntBindable *bind, GList *null)
+{
+	GntTree *tree = GNT_TREE(bind);
+	GntTreeRow *old = tree->current;
+	GntTreeRow *row = get_next(tree->bottom);
+	if (row)
+	{
+		int dist = get_distance(tree->top, tree->current);
+		tree->top = tree->bottom;
+		tree->current = get_next_n_opt(tree->top, dist, NULL);
+		redraw_tree(tree);
+	}
+	else if (tree->current != tree->bottom)
+	{
+		tree->current = tree->bottom;
+		redraw_tree(tree);
+	}
+
+	if (old != tree->current)
+		tree_selection_changed(tree, old, tree->current);
+	return TRUE;
+}
+
+static gboolean
+action_page_up(GntBindable *bind, GList *null)
+{
+	GntWidget *widget = GNT_WIDGET(bind);
+	GntTree *tree = GNT_TREE(bind);
+	GntTreeRow *row;
+	GntTreeRow *old = tree->current;
+
+	if (tree->top != tree->root)
+	{
+		int dist = get_distance(tree->top, tree->current);
+		row = get_prev_n(tree->top, widget->priv.height - 1 -
+			tree->show_title * 2 - 2 * (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER) == 0));
+		if (row == NULL)
+			row = tree->root;
+		tree->top = row;
+		tree->current = get_next_n_opt(tree->top, dist, NULL);
+		redraw_tree(tree);
+	}
+	else if (tree->current != tree->top)
+	{
+		tree->current = tree->top;
+		redraw_tree(tree);
+	}
+	if (old != tree->current)
+		tree_selection_changed(tree, old, tree->current);
+	return TRUE;
+}
+
+static void
+end_search(GntTree *tree)
+{
+	if (tree->search) {
+		g_source_remove(tree->search_timeout);
+		g_string_free(tree->search, TRUE);
+		tree->search = NULL;
+		tree->search_timeout = 0;
+	}
+}
+
+static gboolean
+search_timeout(gpointer data)
+{
+	GntTree *tree = data;
+
+	end_search(tree);
+	redraw_tree(tree);
+
+	return FALSE;
+}
+
+static gboolean
+gnt_tree_key_pressed(GntWidget *widget, const char *text)
+{
+	GntTree *tree = GNT_TREE(widget);
+	GntTreeRow *old = tree->current;
+
+	if (text[0] == '\r') {
+		end_search(tree);
+		gnt_widget_activate(widget);
+	} else if (tree->search) {
+		if (isalnum(*text)) {
+			tree->search = g_string_append_c(tree->search, *text);
+			redraw_tree(tree);
+			g_source_remove(tree->search_timeout);
+			tree->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree);
+		}
+		return TRUE;
+	} else if (text[0] == ' ' && text[1] == 0) {
+		/* Space pressed */
+		GntTreeRow *row = tree->current;
+		if (row && row->child)
+		{
+			row->collapsed = !row->collapsed;
+			redraw_tree(tree);
+		}
+		else if (row && row->choice)
+		{
+			row->isselected = !row->isselected;
+			g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key);
+			redraw_tree(tree);
+		}
+	}
+
+	if (old != tree->current)
+	{
+		tree_selection_changed(tree, old, tree->current);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+gnt_tree_destroy(GntWidget *widget)
+{
+	GntTree *tree = GNT_TREE(widget);
+	int i;
+
+	end_search(tree);
+	g_hash_table_destroy(tree->hash);
+	g_list_free(tree->list);
+
+	for (i = 0; i < tree->ncol; i++)
+	{
+		g_free(tree->columns[i].title);
+	}
+	g_free(tree->columns);
+}
+
+static gboolean
+gnt_tree_clicked(GntWidget *widget, GntMouseEvent event, int x, int y)
+{
+	GntTree *tree = GNT_TREE(widget);
+	GntTreeRow *old = tree->current;
+	if (event == GNT_MOUSE_SCROLL_UP) {
+		action_up(GNT_BINDABLE(widget), NULL);
+	} else if (event == GNT_MOUSE_SCROLL_DOWN) {
+		action_down(GNT_BINDABLE(widget), NULL);
+	} else if (event == GNT_LEFT_MOUSE_DOWN) {
+		GntTreeRow *row;
+		GntTree *tree = GNT_TREE(widget);
+		int pos = 1;
+		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+			pos = 0;
+		if (tree->show_title)
+			pos += 2;
+		pos = y - widget->priv.y - pos;
+		row = get_next_n(tree->top, pos);
+		if (row && tree->current != row) {
+			GntTreeRow *old = tree->current;
+			tree->current = row;
+			redraw_tree(tree);
+			tree_selection_changed(tree, old, tree->current);
+		} else if (row && row == tree->current) {
+			if (row->choice) {
+				row->isselected = !row->isselected;
+				g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key);
+				redraw_tree(tree);
+			} else {
+				gnt_widget_activate(widget);
+			}
+		}
+	} else {
+		return FALSE;
+	}
+	if (old != tree->current) {
+		tree_selection_changed(tree, old, tree->current);
+	}
+	return TRUE;
+}
+
+static void
+gnt_tree_size_changed(GntWidget *widget, int w, int h)
+{
+	GntTree *tree = GNT_TREE(widget);
+	int i;
+	int n = 0;
+	if (widget->priv.width <= 0)
+		return;
+	for (i = 0; i < tree->ncol; ++i)
+		n += tree->columns[i].width;
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		tree->columns[tree->ncol - 1].width += widget->priv.width - n - 1 * tree->ncol;
+	else
+		tree->columns[tree->ncol - 1].width += widget->priv.width - n - 2 - 1 * tree->ncol;
+}
+
+static gboolean
+start_search(GntBindable *bindable, GList *list)
+{
+	GntTree *tree = GNT_TREE(bindable);
+	if (tree->search)
+		return FALSE;
+	tree->search = g_string_new(NULL);
+	tree->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree);
+	return TRUE;
+}
+
+static gboolean
+end_search_action(GntBindable *bindable, GList *list)
+{
+	GntTree *tree = GNT_TREE(bindable);
+	if (tree->search == NULL)
+		return FALSE;
+	end_search(tree);
+	redraw_tree(tree);
+	return TRUE;
+}
+
+static void
+gnt_tree_class_init(GntTreeClass *klass)
+{
+	GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass);
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_tree_destroy;
+	parent_class->draw = gnt_tree_draw;
+	parent_class->map = gnt_tree_map;
+	parent_class->size_request = gnt_tree_size_request;
+	parent_class->key_pressed = gnt_tree_key_pressed;
+	parent_class->clicked = gnt_tree_clicked;
+	parent_class->size_changed = gnt_tree_size_changed;
+
+	signals[SIG_SELECTION_CHANGED] = 
+		g_signal_new("selection-changed",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntTreeClass, selection_changed),
+					 NULL, NULL,
+					 gnt_closure_marshal_VOID__POINTER_POINTER,
+					 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
+	signals[SIG_SCROLLED] = 
+		g_signal_new("scrolled",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 0,
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__INT,
+					 G_TYPE_NONE, 1, G_TYPE_INT);
+	signals[SIG_TOGGLED] = 
+		g_signal_new("toggled",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntTreeClass, toggled),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+	gnt_bindable_class_register_action(bindable, "move-up", action_up,
+				GNT_KEY_UP, NULL);
+	gnt_bindable_register_binding(bindable, "move-up", GNT_KEY_CTRL_P, NULL);
+	gnt_bindable_class_register_action(bindable, "move-down", action_down,
+				GNT_KEY_DOWN, NULL);
+	gnt_bindable_register_binding(bindable, "move-down", GNT_KEY_CTRL_N, NULL);
+	gnt_bindable_class_register_action(bindable, "page-up", action_page_up,
+				GNT_KEY_PGUP, NULL);
+	gnt_bindable_class_register_action(bindable, "page-down", action_page_down,
+				GNT_KEY_PGDOWN, NULL);
+	gnt_bindable_class_register_action(bindable, "start-search", start_search,
+				"/", NULL);
+	gnt_bindable_class_register_action(bindable, "end-search", end_search_action,
+				"\033", NULL);
+
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable);
+	GNTDEBUG;
+}
+
+static void
+gnt_tree_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GntTree *tree = GNT_TREE(widget);
+	tree->show_separator = TRUE;
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);
+	widget->priv.minw = 4;
+	widget->priv.minh = 4;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntTree API
+ *****************************************************************************/
+GType
+gnt_tree_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntTreeClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_tree_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntTree),
+			0,						/* n_preallocs		*/
+			gnt_tree_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntTree",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+static void
+free_tree_col(gpointer data)
+{
+	GntTreeCol *col = data;
+
+	g_free(col->text);
+	g_free(col);
+}
+
+static void
+free_tree_row(gpointer data)
+{
+	GntTreeRow *row = data;
+
+	if (!row)
+		return;
+
+	g_list_foreach(row->columns, (GFunc)free_tree_col, NULL);
+	g_list_free(row->columns);
+	g_free(row);
+}
+
+GntWidget *gnt_tree_new()
+{
+	return gnt_tree_new_with_columns(1);
+}
+
+void gnt_tree_set_visible_rows(GntTree *tree, int rows)
+{
+	GntWidget *widget = GNT_WIDGET(tree);
+	widget->priv.height = rows;
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		widget->priv.height += 2;
+}
+
+int gnt_tree_get_visible_rows(GntTree *tree)
+{
+	GntWidget *widget = GNT_WIDGET(tree);
+	int ret = widget->priv.height;
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		ret -= 2;
+	return ret;
+}
+
+const GList *gnt_tree_get_rows(GntTree *tree)
+{
+	return tree->list;
+}
+
+void gnt_tree_scroll(GntTree *tree, int count)
+{
+	GntTreeRow *row;
+
+	if (count < 0)
+	{
+		if (get_root_distance(tree->top) == 0)
+			return;
+		row = get_prev_n(tree->top, -count);
+		if (row == NULL)
+			row = tree->root;
+		tree->top = row;
+	}
+	else
+	{
+		get_next_n_opt(tree->bottom, count, &count);
+		tree->top = get_next_n(tree->top, count);
+	}
+
+	redraw_tree(tree);
+	g_signal_emit(tree, signals[SIG_SCROLLED], 0, count);
+}
+
+static gpointer
+find_position(GntTree *tree, gpointer key, gpointer parent)
+{
+	GntTreeRow *row;
+
+	if (tree->compare == NULL)
+		return NULL;
+
+	if (parent == NULL)
+		row = tree->root;
+	else
+		row = g_hash_table_lookup(tree->hash, parent);
+
+	if (!row)
+		return NULL;
+
+	if (parent)
+		row = row->child;
+
+	while (row)
+	{
+		if (tree->compare(key, row->key) < 0)
+			return (row->prev ? row->prev->key : NULL);
+		if (row->next)
+			row = row->next;
+		else
+			return row->key;
+	}
+	return NULL;
+}
+
+void gnt_tree_sort_row(GntTree *tree, gpointer key)
+{
+	GntTreeRow *row, *q, *s;
+	int current, newp;
+
+	if (!tree->compare)
+		return;
+
+	row = g_hash_table_lookup(tree->hash, key);
+	g_return_if_fail(row != NULL);
+
+	current = g_list_index(tree->list, key);
+
+	if (row->parent)
+		s = row->parent->child;
+	else
+		s = tree->root;
+
+	q = NULL;
+	while (s) {
+		if (tree->compare(row->key, s->key) < 0)
+			break;
+		q = s;
+		s = s->next;
+	}
+
+	/* Move row between q and s */
+	if (row == q || row == s)
+		return;
+
+	if (q == NULL) {
+		/* row becomes the first child of its parent */
+		row->prev->next = row->next;  /* row->prev cannot be NULL at this point */
+		if (row->next)
+			row->next->prev = row->prev;
+		if (row->parent)
+			row->parent->child = row;
+		else
+			tree->root = row;
+		row->next = s;
+		s->prev = row;  /* s cannot be NULL */
+		row->prev = NULL;
+		newp = g_list_index(tree->list, s) - 1;
+	} else {
+		if (row->prev) {
+			row->prev->next = row->next;
+		} else {
+			/* row was the first child of its parent */
+			if (row->parent)
+				row->parent->child = row->next;
+			else
+				tree->top = row->next;
+		}
+
+		if (row->next)
+			row->next->prev = row->prev;
+
+		q->next = row;
+		row->prev = q;
+		if (s)
+			s->prev = row;
+		row->next = s;
+		newp = g_list_index(tree->list, q) + 1;
+	}
+	tree->list = g_list_reposition_child(tree->list, current, newp);
+
+	redraw_tree(tree);
+}
+
+GntTreeRow *gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro)
+{
+	GntTreeRow *pr = NULL;
+
+	g_hash_table_replace(tree->hash, key, row);
+	row->tree = tree;
+
+	if (bigbro == NULL && tree->compare)
+	{
+		bigbro = find_position(tree, key, parent);
+	}
+
+	if (tree->root == NULL)
+	{
+		tree->root = row;
+		tree->list = g_list_prepend(tree->list, key);
+	}
+	else
+	{
+		int position = 0;
+
+		if (bigbro)
+		{
+			pr = g_hash_table_lookup(tree->hash, bigbro);
+			if (pr)
+			{
+				if (pr->next)	pr->next->prev = row;
+				row->next = pr->next;
+				row->prev = pr;
+				pr->next = row;
+				row->parent = pr->parent;
+
+				position = g_list_index(tree->list, bigbro);
+			}
+		}
+
+		if (pr == NULL && parent)	
+		{
+			pr = g_hash_table_lookup(tree->hash, parent);
+			if (pr)
+			{
+				if (pr->child)	pr->child->prev = row;
+				row->next = pr->child;
+				pr->child = row;
+				row->parent = pr;
+
+				position = g_list_index(tree->list, parent);
+			}
+		}
+
+		if (pr == NULL)
+		{
+			GntTreeRow *r = tree->root;
+			row->next = r;
+			if (r) r->prev = row;
+			if (tree->current == tree->root)
+				tree->current = row;
+			tree->root = row;
+			tree->list = g_list_prepend(tree->list, key);
+		}
+		else
+		{
+			tree->list = g_list_insert(tree->list, key, position + 1);
+		}
+	}
+
+	row->key = key;
+	row->data = NULL;
+
+	redraw_tree(tree);
+
+	return row;
+}
+
+GntTreeRow *gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent)
+{
+	GntTreeRow *pr = NULL, *br = NULL;
+
+	if (parent)
+		pr = g_hash_table_lookup(tree->hash, parent);
+
+	if (pr)
+		br = pr->child;
+	else
+		br = tree->root;
+
+	if (br)
+	{
+		while (br->next)
+			br = br->next;
+	}
+
+	return gnt_tree_add_row_after(tree, key, row, parent, br ? br->key : NULL);
+}
+
+gpointer gnt_tree_get_selection_data(GntTree *tree)
+{
+	if (tree->current)
+		return tree->current->key;	/* XXX: perhaps we should just get rid of 'data' */
+	return NULL;
+}
+
+char *gnt_tree_get_selection_text(GntTree *tree)
+{
+	if (tree->current)
+		return update_row_text(tree, tree->current);
+	return NULL;
+}
+
+GList *gnt_tree_get_selection_text_list(GntTree *tree)
+{
+	GList *list = NULL, *iter;
+	int i;
+
+	if (!tree->current)
+		return NULL;
+
+	for (i = 0, iter = tree->current->columns; i < tree->ncol && iter;
+			i++, iter = iter->next)
+	{
+		GntTreeCol *col = iter->data;
+		list = g_list_append(list, g_strdup(col->text));
+	}
+
+	return list;
+}
+
+void gnt_tree_remove(GntTree *tree, gpointer key)
+{
+	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);
+	if (row)
+	{
+		gboolean redraw = FALSE;
+
+		if (row->child) {
+			GntTreeRow *ch = row->child;
+			while (ch) {
+				GntTreeRow *n = ch->next;
+				tree->list = g_list_remove(tree->list, ch->key);
+				g_hash_table_remove(tree->hash, ch->key);
+				ch = n;
+			}
+		}
+
+		if (get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0)
+			redraw = TRUE;
+
+		/* Update root/top/current/bottom if necessary */
+		if (tree->root == row)
+			tree->root = get_next(row);
+		if (tree->top == row)
+		{
+			if (tree->top != tree->root)
+				tree->top = get_prev(row);
+			else
+				tree->top = get_next(row);
+			if (tree->current == row)
+				tree->current = tree->top;
+		}
+		else if (tree->current == row)
+		{
+			if (tree->current != tree->root)
+				tree->current = get_prev(row);
+			else
+				tree->current = get_next(row);
+		}
+		else if (tree->bottom == row)
+		{
+			tree->bottom = get_prev(row);
+		}
+
+		/* Fix the links */
+		if (row->next)
+			row->next->prev = row->prev;
+		if (row->parent && row->parent->child == row)
+			row->parent->child = row->next;
+		if (row->prev)
+			row->prev->next = row->next;
+		
+		g_hash_table_remove(tree->hash, key);
+		tree->list = g_list_remove(tree->list, key);
+
+		if (redraw)
+		{
+			redraw_tree(tree);
+		}
+	}
+}
+
+static gboolean
+return_true(gpointer key, gpointer data, gpointer null)
+{
+	return TRUE;
+}
+
+void gnt_tree_remove_all(GntTree *tree)
+{
+	tree->root = NULL;
+	g_hash_table_foreach_remove(tree->hash, (GHRFunc)return_true, tree);
+	g_list_free(tree->list);
+	tree->list = NULL;
+	tree->current = tree->top = tree->bottom = NULL;
+}
+
+int gnt_tree_get_selection_visible_line(GntTree *tree)
+{
+	return get_distance(tree->top, tree->current) +
+			!!(GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER));
+}
+
+void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text)
+{
+	GntTreeRow *row;
+	GntTreeCol *col;
+
+	g_return_if_fail(colno < tree->ncol);
+	
+	row = g_hash_table_lookup(tree->hash, key);
+	if (row)
+	{
+		col = g_list_nth_data(row->columns, colno);
+		g_free(col->text);
+		col->text = g_strdup(text);
+
+		if (get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0)
+			redraw_tree(tree);
+	}
+}
+
+GntTreeRow *gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro)
+{
+	GntTreeRow *r;
+	r = g_hash_table_lookup(tree->hash, key);
+	g_return_val_if_fail(!r || !r->choice, NULL);
+
+	if (bigbro == NULL) {
+		r = g_hash_table_lookup(tree->hash, parent);
+		if (!r)
+			r = tree->root;
+		else
+			r = r->child;
+		if (r) {
+			while (r->next)
+				r = r->next;
+			bigbro = r->key;
+		} 
+	}
+	row = gnt_tree_add_row_after(tree, key, row, parent, bigbro);
+	row->choice = TRUE;
+
+	return row;
+}
+
+void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set)
+{
+	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);
+
+	if (!row)
+		return;
+	g_return_if_fail(row->choice);
+
+	row->isselected = set;
+	redraw_tree(tree);
+}
+
+gboolean gnt_tree_get_choice(GntTree *tree, void *key)
+{
+	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);
+
+	if (!row)
+		return FALSE;
+	g_return_val_if_fail(row->choice, FALSE);
+
+	return row->isselected;
+}
+
+void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags)
+{
+	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);
+	if (!row || row->flags == flags)
+		return;
+
+	row->flags = flags;
+	redraw_tree(tree);	/* XXX: It shouldn't be necessary to redraw the whole darned tree */
+}
+
+void gnt_tree_set_selected(GntTree *tree , void *key)
+{
+	int dist;
+	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);
+	if (!row)
+		return;
+
+	if (tree->top == NULL)
+		tree->top = row;
+	if (tree->bottom == NULL)
+		tree->bottom = row;
+
+	tree->current = row;
+	if ((dist = get_distance(tree->current, tree->bottom)) < 0)
+		gnt_tree_scroll(tree, -dist);
+	else if ((dist = get_distance(tree->current, tree->top)) > 0)
+		gnt_tree_scroll(tree, -dist);
+	else
+		redraw_tree(tree);
+}
+
+void _gnt_tree_init_internals(GntTree *tree, int col)
+{
+	tree->ncol = col;
+	tree->hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_tree_row);
+	tree->columns = g_new0(struct _GntTreeColInfo, col);
+	while (col--)
+	{
+		tree->columns[col].width = 15;
+	}
+	tree->list = NULL;
+	tree->show_title = FALSE;
+}
+
+GntWidget *gnt_tree_new_with_columns(int col)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_TREE, NULL);
+	GntTree *tree = GNT_TREE(widget);
+
+	_gnt_tree_init_internals(tree, col);
+	
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW);
+	gnt_widget_set_take_focus(widget, TRUE);
+
+	return widget;
+}
+
+GntTreeRow *gnt_tree_create_row_from_list(GntTree *tree, GList *list)
+{
+	GList *iter;
+	int i;
+	GntTreeRow *row = g_new0(GntTreeRow, 1);
+
+	for (i = 0, iter = list; i < tree->ncol && iter; iter = iter->next, i++)
+	{
+		GntTreeCol *col = g_new0(GntTreeCol, 1);
+		col->span = 1;
+		col->text = g_strdup(iter->data);
+
+		row->columns = g_list_append(row->columns, col);
+	}
+
+	return row;
+}
+
+GntTreeRow *gnt_tree_create_row(GntTree *tree, ...)
+{
+	int i;
+	va_list args;
+	GList *list = NULL;
+	GntTreeRow *row;
+
+	va_start(args, tree);
+	for (i = 0; i < tree->ncol; i++)
+	{
+		list = g_list_append(list, va_arg(args, char *));
+	}
+	va_end(args);
+
+	row = gnt_tree_create_row_from_list(tree, list);
+	g_list_free(list);
+
+	return row;
+}
+
+void gnt_tree_set_col_width(GntTree *tree, int col, int width)
+{
+	g_return_if_fail(col < tree->ncol);
+
+	tree->columns[col].width = width;
+}
+
+void gnt_tree_set_column_titles(GntTree *tree, ...)
+{
+	int i;
+	va_list args;
+
+	va_start(args, tree);
+	for (i = 0; i < tree->ncol; i++)
+	{
+		const char *title = va_arg(args, const char *);
+		tree->columns[i].title = g_strdup(title);
+	}
+	va_end(args);
+}
+
+void gnt_tree_set_show_title(GntTree *tree, gboolean set)
+{
+	tree->show_title = set;
+	GNT_WIDGET(tree)->priv.minh = (set ? 6 : 4);
+}
+
+void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func)
+{
+	tree->compare = func;
+}
+
+void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded)
+{
+	GntTreeRow *row = g_hash_table_lookup(tree->hash, key);
+	if (row) {
+		row->collapsed = !expanded;
+		if (GNT_WIDGET(tree)->window)
+			gnt_widget_draw(GNT_WIDGET(tree));
+	}
+}
+
+void gnt_tree_set_show_separator(GntTree *tree, gboolean set)
+{
+	tree->show_separator = set;
+}
+
+void gnt_tree_adjust_columns(GntTree *tree)
+{
+	GntTreeRow *row = tree->root;
+	int *widths, i, twidth, height;
+
+	widths = g_new0(int, tree->ncol);
+	while (row) {
+		GList *iter;
+		for (i = 0, iter = row->columns; iter; iter = iter->next, i++) {
+			GntTreeCol *col = iter->data;
+			int w = gnt_util_onscreen_width(col->text, NULL);
+			if (widths[i] < w)
+				widths[i] = w;
+		}
+		row = row->next;
+	}
+
+	twidth = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER));
+	for (i = 0; i < tree->ncol; i++) {
+		gnt_tree_set_col_width(tree, i, widths[i]);
+		twidth += widths[i] + (tree->show_separator ? 1 : 0) + 1;
+	}
+	g_free(widths);
+
+	gnt_widget_get_size(GNT_WIDGET(tree), NULL, &height);
+	gnt_widget_set_size(GNT_WIDGET(tree), twidth, height);
+}
+
+void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd)
+{
+	g_hash_table_foreach_remove(tree->hash, return_true, NULL);
+	g_hash_table_destroy(tree->hash);
+	tree->hash = g_hash_table_new_full(hash, eq, kd, free_tree_row);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnttree.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,150 @@
+#ifndef GNT_TREE_H
+#define GNT_TREE_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+#include "gnttextview.h"
+
+#define GNT_TYPE_TREE				(gnt_tree_get_gtype())
+#define GNT_TREE(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_TREE, GntTree))
+#define GNT_TREE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_TREE, GntTreeClass))
+#define GNT_IS_TREE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_TREE))
+#define GNT_IS_TREE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_TREE))
+#define GNT_TREE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_TREE, GntTreeClass))
+
+#define GNT_TREE_FLAGS(obj)				(GNT_TREE(obj)->priv.flags)
+#define GNT_TREE_SET_FLAGS(obj, flags)		(GNT_TREE_FLAGS(obj) |= flags)
+#define GNT_TREE_UNSET_FLAGS(obj, flags)	(GNT_TREE_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnTree			GntTree;
+typedef struct _GnTreePriv		GntTreePriv;
+typedef struct _GnTreeClass		GntTreeClass;
+
+typedef struct _GnTreeRow		GntTreeRow;
+typedef struct _GnTreeCol		GntTreeCol;
+
+struct _GnTree
+{
+	GntWidget parent;
+
+	GntTreeRow *current;    /* current selection */
+
+	GntTreeRow *top;        /* The topmost visible item */
+	GntTreeRow *bottom;     /* The bottommost visible item */
+	
+	GntTreeRow *root;       /* The root of all evil */
+	
+	GList *list;            /* List of GntTreeRow s */
+	GHashTable *hash;       /* We need this for quickly referencing the rows */
+	guint (*hash_func)(gconstpointer);
+	gboolean (*hash_eq_func)(gconstpointer, gconstpointer);
+	GDestroyNotify key_destroy;
+	GDestroyNotify value_destroy;
+
+	int ncol;               /* No. of columns */
+	struct _GntTreeColInfo
+	{
+		int width;
+		char *title;
+	} *columns;             /* Would a GList be better? */
+	gboolean show_title;
+	gboolean show_separator; /* Whether to show column separators */
+
+	GString *search;
+	int search_timeout;
+
+	GCompareFunc compare;
+};
+
+struct _GnTreeClass
+{
+	GntWidgetClass parent;
+
+	void (*selection_changed)(GntTreeRow *old, GntTreeRow * current);
+	void (*toggled)(GntTree *tree, gpointer key);
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_tree_get_gtype(void);
+
+GntWidget *gnt_tree_new();      /* A tree with just one column */
+
+GntWidget *gnt_tree_new_with_columns(int columns);
+
+void gnt_tree_set_visible_rows(GntTree *tree, int rows);
+
+int gnt_tree_get_visible_rows(GntTree *tree);
+
+void gnt_tree_scroll(GntTree *tree, int count);
+
+GntTreeRow *gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro);
+
+GntTreeRow *gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent);
+
+gpointer gnt_tree_get_selection_data(GntTree *tree);
+
+/* Returned string needs to be freed */
+char *gnt_tree_get_selection_text(GntTree *tree);
+
+GList *gnt_tree_get_selection_text_list(GntTree *tree);
+
+const GList *gnt_tree_get_rows(GntTree *tree);
+
+void gnt_tree_remove(GntTree *tree, gpointer key);
+
+void gnt_tree_remove_all(GntTree *tree);
+
+/* Returns the visible line number of the selected row */
+int gnt_tree_get_selection_visible_line(GntTree *tree);
+
+void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text);
+
+GntTreeRow *gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro);
+
+void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set);
+
+gboolean gnt_tree_get_choice(GntTree *tree, void *key);
+
+void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags);
+
+void gnt_tree_set_selected(GntTree *tree , void *key);
+
+GntTreeRow *gnt_tree_create_row(GntTree *tree, ...);
+
+GntTreeRow *gnt_tree_create_row_from_list(GntTree *tree, GList *list);
+
+void gnt_tree_set_col_width(GntTree *tree, int col, int width);
+
+void gnt_tree_set_column_titles(GntTree *tree, ...);
+
+void gnt_tree_set_show_title(GntTree *tree, gboolean set);
+
+void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func);
+
+void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded);
+
+void gnt_tree_set_show_separator(GntTree *tree, gboolean set);
+
+void gnt_tree_sort_row(GntTree *tree, void *row);
+
+/* This will try to automatically adjust the width of the columns in the tree */
+void gnt_tree_adjust_columns(GntTree *tree);
+
+void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd);
+
+G_END_DECLS
+
+/* The following functions should NOT be used by applications. */
+
+/* This should be called by the subclasses of GntTree's in their _new function */
+void _gnt_tree_init_internals(GntTree *tree, int col);
+
+#endif /* GNT_TREE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntutils.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,147 @@
+#include "gntutils.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+
+void gnt_util_get_text_bound(const char *text, int *width, int *height)
+{
+	const char *s = text, *last;
+	int count = 1, max = 0;
+	int len;
+
+	/* XXX: ew ... everyone look away */
+	last = s;
+	if (s)
+	{
+		while (*s)
+		{
+			if (*s == '\n' || *s == '\r')
+			{
+				count++;
+				len = gnt_util_onscreen_width(last, s);
+				if (max < len)
+					max = len;
+				last = s + 1;
+			}
+			s = g_utf8_next_char(s);
+		}
+
+		len = gnt_util_onscreen_width(last, s);
+		if (max < len)
+			max = len;
+	}
+
+	if (height)
+		*height = count;
+	if (width)
+		*width = max + (count > 1);
+}
+
+int gnt_util_onscreen_width(const char *start, const char *end)
+{
+	int width = 0;
+
+	if (end == NULL)
+		end = start + strlen(start);
+
+	while (start < end) {
+		width += g_unichar_iswide(g_utf8_get_char(start)) ? 2 : 1;
+		start = g_utf8_next_char(start);
+	}
+	return width;
+}
+
+const char *gnt_util_onscreen_width_to_pointer(const char *string, int len, int *w)
+{
+	int size;
+	int width = 0;
+	const char *str = string;
+
+	if (len <= 0) {
+		len = gnt_util_onscreen_width(string, NULL);
+	}
+
+	while (width < len && *str) {
+		size = g_unichar_iswide(g_utf8_get_char(str)) ? 2 : 1;
+		if (width + size > len)
+			break;
+		str = g_utf8_next_char(str);
+		width += size;
+	}
+	if (w)
+		*w = width;
+	return str;
+}
+
+char *gnt_util_onscreen_fit_string(const char *string, int maxw)
+{
+	const char *start, *end;
+	GString *str;
+
+	if (maxw <= 0)
+		maxw = getmaxx(stdscr) - 4;
+
+	start = string;
+	str = g_string_new(NULL);
+
+	while (*start) {
+		if ((end = strchr(start, '\n')) != NULL ||
+			(end = strchr(start, '\r')) != NULL) {
+			if (gnt_util_onscreen_width(start, end) > maxw)
+				end = NULL;
+		}
+		if (end == NULL)
+			end = gnt_util_onscreen_width_to_pointer(start, maxw, NULL);
+		str = g_string_append_len(str, start, end - start);
+		if (*end) {
+			str = g_string_append_c(str, '\n');
+			if (*end == '\n' || *end == '\r')
+				end++;
+		}
+		start = end;
+	}
+	return g_string_free(str, FALSE);
+}
+
+struct duplicate_fns
+{
+	GDupFunc key_dup;
+	GDupFunc value_dup;
+	GHashTable *table;
+};
+
+static void
+duplicate_values(gpointer key, gpointer value, gpointer data)
+{
+	struct duplicate_fns *fns = data;
+	g_hash_table_insert(fns->table, fns->key_dup ? fns->key_dup(key) : key,
+			fns->value_dup ? fns->value_dup(value) : value);
+}
+
+GHashTable *g_hash_table_duplicate(GHashTable *src, GHashFunc hash,
+		GEqualFunc equal, GDestroyNotify key_d, GDestroyNotify value_d,
+		GDupFunc key_dup, GDupFunc value_dup)
+{
+	GHashTable *dest = g_hash_table_new_full(hash, equal, key_d, value_d);
+	struct duplicate_fns fns = {key_dup, value_dup, dest};
+	g_hash_table_foreach(src, duplicate_values, &fns);
+	return dest;
+}
+
+gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint,
+				  GValue                *return_accu,
+				  const GValue          *handler_return,
+				  gpointer               dummy)
+{
+	gboolean continue_emission;
+	gboolean signal_handled;
+
+	signal_handled = g_value_get_boolean (handler_return);
+	g_value_set_boolean (return_accu, signal_handled);
+	continue_emission = !signal_handled;
+
+	return continue_emission;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntutils.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,36 @@
+#include <glib.h>
+
+#include "gnt.h"
+#include "gntwidget.h"
+
+typedef gpointer (*GDupFunc)(gconstpointer data);
+
+void gnt_util_get_text_bound(const char *text, int *width, int *height);
+
+/* excluding *end */
+int gnt_util_onscreen_width(const char *start, const char *end);
+
+const char *gnt_util_onscreen_width_to_pointer(const char *str, int len, int *w);
+
+/* Inserts newlines in 'string' where necessary so that its onscreen width is
+ * no more than 'maxw'.
+ * 'maxw' can be <= 0, in which case the maximum screen width is considered.
+ *
+ * Returns a newly allocated string.
+ */
+char *gnt_util_onscreen_fit_string(const char *string, int maxw);
+
+GHashTable *g_hash_table_duplicate(GHashTable *src, GHashFunc hash,
+		GEqualFunc equal, GDestroyNotify key_d, GDestroyNotify value_d,
+		GDupFunc key_dup, GDupFunc value_dup);
+
+
+/**
+ * To be used with g_signal_new. Look in the key_pressed signal-definition in
+ * gntwidget.c for usage.
+ */
+gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint,
+				  GValue                *return_accu,
+				  const GValue          *handler_return,
+				  gpointer               dummy);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntwidget.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,624 @@
+/* Stuff brutally ripped from Gflib */
+
+#include "gntwidget.h"
+#include "gntstyle.h"
+#include "gntmarshal.h"
+#include "gntutils.h"
+#include "gnt.h"
+
+enum
+{
+	SIG_DESTROY,
+	SIG_DRAW,
+	SIG_HIDE,
+	SIG_GIVE_FOCUS,
+	SIG_LOST_FOCUS,
+	SIG_KEY_PRESSED,
+	SIG_MAP,
+	SIG_ACTIVATE,
+	SIG_EXPOSE,
+	SIG_SIZE_REQUEST,
+	SIG_CONFIRM_SIZE,
+	SIG_SIZE_CHANGED,
+	SIG_POSITION,
+	SIG_CLICKED,
+	SIG_CONTEXT_MENU,
+	SIGS
+};
+
+static GObjectClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+
+static void init_widget(GntWidget *widget);
+
+static void
+gnt_widget_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	widget->priv.name = NULL;
+	GNTDEBUG;
+}
+
+static void
+gnt_widget_map(GntWidget *widget)
+{
+	/* Get some default size for the widget */
+	GNTDEBUG;
+	g_signal_emit(widget, signals[SIG_MAP], 0);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED);
+}
+
+static void
+gnt_widget_dispose(GObject *obj)
+{
+	GntWidget *self = GNT_WIDGET(obj);
+
+	if(!(GNT_WIDGET_FLAGS(self) & GNT_WIDGET_DESTROYING)) {
+		GNT_WIDGET_SET_FLAGS(self, GNT_WIDGET_DESTROYING);
+
+		g_signal_emit(self, signals[SIG_DESTROY], 0);
+
+		GNT_WIDGET_UNSET_FLAGS(self, GNT_WIDGET_DESTROYING);
+	}
+
+	parent_class->dispose(obj);
+	GNTDEBUG;
+}
+
+static void
+gnt_widget_focus_change(GntWidget *widget)
+{
+	if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)
+		gnt_widget_draw(widget);
+}
+
+static gboolean
+gnt_widget_dummy_confirm_size(GntWidget *widget, int width, int height)
+{
+	if (width < widget->priv.minw || height < widget->priv.minh)
+		return FALSE;
+	if (widget->priv.width != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X))
+		return FALSE;
+	if (widget->priv.height != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y))
+		return FALSE;
+	return TRUE;
+}
+
+static gboolean
+context_menu(GntBindable *bind, GList *null)
+{
+	gboolean ret = FALSE;
+	g_signal_emit(bind, signals[SIG_CONTEXT_MENU], 0, &ret);
+	return ret;
+}
+
+static void
+gnt_widget_class_init(GntWidgetClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	parent_class = g_type_class_peek_parent(klass);
+
+	obj_class->dispose = gnt_widget_dispose;
+
+	klass->destroy = gnt_widget_destroy;
+	klass->show = gnt_widget_show;
+	klass->draw = gnt_widget_draw;
+	klass->expose = gnt_widget_expose;
+	klass->map = gnt_widget_map;
+	klass->lost_focus = gnt_widget_focus_change;
+	klass->gained_focus = gnt_widget_focus_change;
+	klass->confirm_size = gnt_widget_dummy_confirm_size;
+	
+	klass->key_pressed = NULL;
+	klass->activate = NULL;
+	klass->clicked = NULL;
+	
+	signals[SIG_DESTROY] = 
+		g_signal_new("destroy",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, destroy),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_GIVE_FOCUS] = 
+		g_signal_new("gained-focus",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, gained_focus),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_LOST_FOCUS] = 
+		g_signal_new("lost-focus",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, lost_focus),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_ACTIVATE] = 
+		g_signal_new("activate",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, activate),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_MAP] = 
+		g_signal_new("map",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, map),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_DRAW] = 
+		g_signal_new("draw",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, draw),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_HIDE] = 
+		g_signal_new("hide",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, hide),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_EXPOSE] = 
+		g_signal_new("expose",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, expose),
+					 NULL, NULL,
+					 gnt_closure_marshal_VOID__INT_INT_INT_INT,
+					 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+	signals[SIG_POSITION] = 
+		g_signal_new("position-set",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, set_position),
+					 NULL, NULL,
+					 gnt_closure_marshal_VOID__INT_INT,
+					 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+	signals[SIG_SIZE_REQUEST] = 
+		g_signal_new("size_request",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, size_request),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__VOID,
+					 G_TYPE_NONE, 0);
+	signals[SIG_SIZE_CHANGED] = 
+		g_signal_new("size_changed",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, size_changed),
+					 NULL, NULL,
+					 gnt_closure_marshal_VOID__INT_INT,
+					 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+	signals[SIG_CONFIRM_SIZE] = 
+		g_signal_new("confirm_size",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, confirm_size),
+					 NULL, NULL,
+					 gnt_closure_marshal_BOOLEAN__INT_INT,
+					 G_TYPE_BOOLEAN, 2, G_TYPE_INT, G_TYPE_INT);
+	signals[SIG_KEY_PRESSED] = 
+		g_signal_new("key_pressed",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, key_pressed),
+					 gnt_boolean_handled_accumulator, NULL,
+					 gnt_closure_marshal_BOOLEAN__STRING,
+					 G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
+
+	signals[SIG_CLICKED] = 
+		g_signal_new("clicked",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWidgetClass, clicked),
+					 gnt_boolean_handled_accumulator, NULL,
+					 gnt_closure_marshal_BOOLEAN__INT_INT_INT,
+					 G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+	signals[SIG_CONTEXT_MENU] = 
+		g_signal_new("context-menu",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 0,
+					 gnt_boolean_handled_accumulator, NULL,
+					 gnt_closure_marshal_BOOLEAN__VOID,
+					 G_TYPE_BOOLEAN, 0);
+
+	/* This is relevant for all widgets */
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "context-menu", context_menu,
+				GNT_KEY_POPUP, NULL);
+	gnt_bindable_register_binding(GNT_BINDABLE_CLASS(klass), "context-menu", GNT_KEY_F11, NULL);
+
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntWidget API
+ *****************************************************************************/
+GType
+gnt_widget_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(GntWidgetClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_widget_class_init,
+			NULL,
+			NULL,					/* class_data		*/
+			sizeof(GntWidget),
+			0,						/* n_preallocs		*/
+			gnt_widget_init,					/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_BINDABLE,
+									  "GntWidget",
+									  &info, G_TYPE_FLAG_ABSTRACT);
+	}
+
+	return type;
+}
+
+void gnt_widget_set_take_focus(GntWidget *widget, gboolean can)
+{
+	if (can)
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
+	else
+		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
+}
+
+/**
+ * gnt_widget_destroy:
+ * @obj: The #GntWidget instance.
+ *
+ * Emits the "destroy" signal notifying all reference holders that they
+ * should release @obj.
+ */
+void
+gnt_widget_destroy(GntWidget *obj)
+{
+	g_return_if_fail(GNT_IS_WIDGET(obj));
+
+	gnt_widget_hide(obj);
+	delwin(obj->window);
+	if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING))
+		g_object_run_dispose(G_OBJECT(obj));
+	GNTDEBUG;
+}
+
+void
+gnt_widget_show(GntWidget *widget)
+{
+	gnt_widget_draw(widget);
+	gnt_screen_occupy(widget);
+}
+
+void
+gnt_widget_draw(GntWidget *widget)
+{
+	/* Draw the widget */
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING))
+		return;
+
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING);
+	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) {
+		gnt_widget_map(widget);
+	}
+
+	if (widget->window == NULL)
+	{
+		int x, y, maxx, maxy, w, h;
+		int oldw, oldh;
+		gboolean shadow = TRUE;
+
+		if (!gnt_widget_has_shadow(widget))
+			shadow = FALSE;
+
+		x = widget->priv.x;
+		y = widget->priv.y;
+		w = oldw = widget->priv.width + shadow;
+		h = oldh = widget->priv.height + shadow;
+
+		getmaxyx(stdscr, maxy, maxx);
+		maxy -= 1;		/* room for the taskbar */
+
+		x = MAX(0, x);
+		y = MAX(0, y);
+		if (x + w >= maxx)
+			x = MAX(0, maxx - w);
+		if (y + h >= maxy)
+			y = MAX(0, maxy - h);
+
+		w = MIN(w, maxx);
+		h = MIN(h, maxy);
+
+		widget->priv.x = x;
+		widget->priv.y = y;
+		if (w != oldw || h != oldh) {
+			widget->priv.width = w - shadow;
+			widget->priv.height = h - shadow;
+			g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh);
+		}
+
+		widget->window = newwin(widget->priv.height + shadow, widget->priv.width + shadow,
+						widget->priv.y, widget->priv.x);
+		init_widget(widget);
+	}
+
+	g_signal_emit(widget, signals[SIG_DRAW], 0);
+	gnt_widget_queue_update(widget);
+	GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING);
+}
+
+gboolean
+gnt_widget_key_pressed(GntWidget *widget, const char *keys)
+{
+	gboolean ret;
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS))
+		return FALSE;
+
+	if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), keys))
+		return TRUE;
+
+	keys = gnt_bindable_remap_keys(GNT_BINDABLE(widget), keys);
+	g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret);
+	return ret;
+}
+
+gboolean
+gnt_widget_clicked(GntWidget *widget, GntMouseEvent event, int x, int y)
+{
+	gboolean ret;
+	g_signal_emit(widget, signals[SIG_CLICKED], 0, event, x, y, &ret);
+	return ret;
+}
+
+void
+gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height)
+{
+	g_signal_emit(widget, signals[SIG_EXPOSE], 0, x, y, width, height);
+}
+
+void
+gnt_widget_hide(GntWidget *widget)
+{
+	g_signal_emit(widget, signals[SIG_HIDE], 0);
+	wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
+#if 0
+	/* XXX: I have no clue why, but this seemed to be necessary. */
+	if (gnt_widget_has_shadow(widget))
+		mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height);
+#endif
+	gnt_screen_release(widget);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE);
+	GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_MAPPED);
+}
+
+void
+gnt_widget_set_position(GntWidget *wid, int x, int y)
+{
+	g_signal_emit(wid, signals[SIG_POSITION], 0, x, y);
+	/* XXX: Need to install properties for these and g_object_notify */
+	wid->priv.x = x;
+	wid->priv.y = y;
+}
+
+void
+gnt_widget_get_position(GntWidget *wid, int *x, int *y)
+{
+	if (x)
+		*x = wid->priv.x;
+	if (y)
+		*y = wid->priv.y;
+}
+
+void
+gnt_widget_size_request(GntWidget *widget)
+{
+	g_signal_emit(widget, signals[SIG_SIZE_REQUEST], 0);
+}
+
+void
+gnt_widget_get_size(GntWidget *wid, int *width, int *height)
+{
+	gboolean shadow = TRUE;
+	if (!gnt_widget_has_shadow(wid))
+		shadow = FALSE;
+
+	if (width)
+		*width = wid->priv.width + shadow;
+	if (height)
+		*height = wid->priv.height + shadow;
+	
+}
+
+static void
+init_widget(GntWidget *widget)
+{
+	gboolean shadow = TRUE;
+
+	if (!gnt_widget_has_shadow(widget))
+		shadow = FALSE;
+
+	wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
+	werase(widget->window);
+
+	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
+	{
+		/* - This is ugly. */
+		/* - What's your point? */
+		mvwvline(widget->window, 0, 0, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.height);
+		mvwvline(widget->window, 0, widget->priv.width - 1,
+				ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.height);
+		mvwhline(widget->window, widget->priv.height - 1, 0,
+				ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.width);
+		mvwhline(widget->window, 0, 0, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), widget->priv.width);
+		mvwaddch(widget->window, 0, 0, ACS_ULCORNER | COLOR_PAIR(GNT_COLOR_NORMAL));
+		mvwaddch(widget->window, 0, widget->priv.width - 1,
+				ACS_URCORNER | COLOR_PAIR(GNT_COLOR_NORMAL));
+		mvwaddch(widget->window, widget->priv.height - 1, 0,
+				ACS_LLCORNER | COLOR_PAIR(GNT_COLOR_NORMAL));
+		mvwaddch(widget->window, widget->priv.height - 1, widget->priv.width - 1,
+				ACS_LRCORNER | COLOR_PAIR(GNT_COLOR_NORMAL));
+	}
+
+	if (shadow)
+	{
+		wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_SHADOW));
+		mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height);
+		mvwhline(widget->window, widget->priv.height, 1, ' ', widget->priv.width);
+	}
+}
+
+gboolean
+gnt_widget_set_size(GntWidget *widget, int width, int height)
+{
+	gboolean ret = TRUE;
+
+	if (gnt_widget_has_shadow(widget))
+	{
+		width--;
+		height--;
+	}
+	if (width <= 0)
+		width = widget->priv.width;
+	if (height <= 0)
+		height = widget->priv.height;
+
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		ret = gnt_widget_confirm_size(widget, width, height);
+	}
+
+	if (ret)
+	{
+		gboolean shadow = TRUE;
+		int oldw, oldh;
+
+		if (!gnt_widget_has_shadow(widget))
+			shadow = FALSE;
+
+		oldw = widget->priv.width;
+		oldh = widget->priv.height;
+
+		widget->priv.width = width;
+		widget->priv.height = height;
+
+		g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh);
+
+		if (widget->window)
+		{
+			wresize(widget->window, height + shadow, width + shadow);
+			init_widget(widget);
+		}
+		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+			init_widget(widget);
+		else
+			GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED);
+	}
+
+	return ret;
+}
+
+gboolean
+gnt_widget_set_focus(GntWidget *widget, gboolean set)
+{
+	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS))
+		return FALSE;
+
+	if (set && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS))
+	{
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS);
+		g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0);
+	}
+	else if (!set)
+	{
+		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS);
+		g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0);
+	}
+	else
+		return FALSE;
+
+	return TRUE;
+}
+
+void gnt_widget_set_name(GntWidget *widget, const char *name)
+{
+	g_free(widget->priv.name);
+	widget->priv.name = g_strdup(name);
+}
+
+const char *gnt_widget_get_name(GntWidget *widget)
+{
+	return widget->priv.name;
+}
+
+void gnt_widget_activate(GntWidget *widget)
+{
+	g_signal_emit(widget, signals[SIG_ACTIVATE], 0);
+}
+
+static gboolean
+update_queue_callback(gpointer data)
+{
+	GntWidget *widget = GNT_WIDGET(data);
+
+	if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update"))
+		return FALSE;
+	gnt_screen_update(widget);
+	g_object_set_data(G_OBJECT(widget), "gnt:queue_update", NULL);
+	return FALSE;
+}
+
+void gnt_widget_queue_update(GntWidget *widget)
+{
+	if (widget->window == NULL)
+		return;
+	while (widget->parent)
+		widget = widget->parent;
+	
+	if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update"))
+	{
+		int id = g_timeout_add(0, update_queue_callback, widget);
+		g_object_set_data_full(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id),
+				(GDestroyNotify)g_source_remove);
+	}
+}
+
+gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height)
+{
+	gboolean ret = FALSE;
+	g_signal_emit(widget, signals[SIG_CONFIRM_SIZE], 0, width, height, &ret);
+	return ret;
+}
+
+void gnt_widget_set_visible(GntWidget *widget, gboolean set)
+{
+	if (set)
+		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_INVISIBLE);
+	else
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE);
+}
+
+gboolean gnt_widget_has_shadow(GntWidget *widget)
+{
+	return (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW) &&
+			gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntwidget.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,152 @@
+#ifndef GNT_WIDGET_H
+#define GNT_WIDGET_H
+
+#include <stdio.h>
+#include <glib.h>
+#include <ncurses.h>
+
+#include "gntbindable.h"
+
+#define GNT_TYPE_WIDGET				(gnt_widget_get_gtype())
+#define GNT_WIDGET(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WIDGET, GntWidget))
+#define GNT_WIDGET_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_WIDGET, GntWidgetClass))
+#define GNT_IS_WIDGET(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WIDGET))
+#define GNT_IS_WIDGET_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WIDGET))
+#define GNT_WIDGET_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WIDGET, GntWidgetClass))
+
+#define GNT_WIDGET_FLAGS(obj)				(GNT_WIDGET(obj)->priv.flags)
+#define GNT_WIDGET_SET_FLAGS(obj, flags)		(GNT_WIDGET_FLAGS(obj) |= flags)
+#define GNT_WIDGET_UNSET_FLAGS(obj, flags)	(GNT_WIDGET_FLAGS(obj) &= ~(flags))
+#define GNT_WIDGET_IS_FLAG_SET(obj, flags)	(GNT_WIDGET_FLAGS(obj) & (flags))
+
+typedef struct _GnWidget			GntWidget;
+typedef struct _GnWidgetPriv		GntWidgetPriv;
+typedef struct _GnWidgetClass		GntWidgetClass;
+
+typedef enum _GnWidgetFlags
+{
+	GNT_WIDGET_DESTROYING     = 1 << 0,
+	GNT_WIDGET_CAN_TAKE_FOCUS = 1 << 1,
+	GNT_WIDGET_MAPPED         = 1 << 2,
+	/* XXX: Need to set the following two as properties, and setup a callback whenever these
+	 * get chnaged. */
+	GNT_WIDGET_NO_BORDER      = 1 << 3,
+	GNT_WIDGET_NO_SHADOW      = 1 << 4,
+	GNT_WIDGET_HAS_FOCUS      = 1 << 5,
+	GNT_WIDGET_DRAWING        = 1 << 6,
+	GNT_WIDGET_URGENT         = 1 << 7,
+	GNT_WIDGET_GROW_X         = 1 << 8,
+	GNT_WIDGET_GROW_Y         = 1 << 9,
+	GNT_WIDGET_INVISIBLE      = 1 << 10,
+	GNT_WIDGET_TRANSIENT      = 1 << 11,
+} GntWidgetFlags;
+
+/* XXX: This will probably move elsewhere */
+typedef enum _GnMouseEvent
+{
+	GNT_LEFT_MOUSE_DOWN = 1,
+	GNT_RIGHT_MOUSE_DOWN,
+	GNT_MIDDLE_MOUSE_DOWN,
+	GNT_MOUSE_UP,
+	GNT_MOUSE_SCROLL_UP,
+	GNT_MOUSE_SCROLL_DOWN
+} GntMouseEvent;
+
+/* XXX: I'll have to ask grim what he's using this for in guifications. */
+typedef enum _GnParamFlags
+{
+	GNT_PARAM_SERIALIZABLE	= 1 << G_PARAM_USER_SHIFT
+} GntParamFlags;
+
+struct _GnWidgetPriv
+{
+	int x, y;
+	int width, height;
+	GntWidgetFlags flags;
+	char *name;
+
+	int minw, minh;    /* Minimum size for the widget */
+};
+
+struct _GnWidget
+{
+	GntBindable inherit;
+
+	GntWidget *parent;
+
+	GntWidgetPriv priv;
+	WINDOW *window;
+
+    void (*gnt_reserved1)(void);
+    void (*gnt_reserved2)(void);
+    void (*gnt_reserved3)(void);
+    void (*gnt_reserved4)(void);
+};
+
+struct _GnWidgetClass
+{
+	GntBindableClass parent;
+
+	void (*map)(GntWidget *obj);
+	void (*show)(GntWidget *obj);		/* This will call draw() and take focus (if it can take focus) */
+	void (*destroy)(GntWidget *obj);
+	void (*draw)(GntWidget *obj);		/* This will draw the widget */
+	void (*hide)(GntWidget *obj);
+	void (*expose)(GntWidget *widget, int x, int y, int width, int height);
+	void (*gained_focus)(GntWidget *widget);
+	void (*lost_focus)(GntWidget *widget);
+
+	void (*size_request)(GntWidget *widget);
+	gboolean (*confirm_size)(GntWidget *widget, int x, int y);
+	void (*size_changed)(GntWidget *widget, int w, int h);
+	void (*set_position)(GntWidget *widget, int x, int y);
+	gboolean (*key_pressed)(GntWidget *widget, const char *key);
+	void (*activate)(GntWidget *widget);
+	gboolean (*clicked)(GntWidget *widget, GntMouseEvent event, int x, int y);
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_widget_get_gtype(void);
+void gnt_widget_destroy(GntWidget *widget);
+void gnt_widget_show(GntWidget *widget);
+void gnt_widget_draw(GntWidget *widget);
+void gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height);
+void gnt_widget_hide(GntWidget *widget);
+
+void gnt_widget_get_position(GntWidget *widget, int *x, int *y);
+void gnt_widget_set_position(GntWidget *widget, int x, int y);
+void gnt_widget_size_request(GntWidget *widget);
+void gnt_widget_get_size(GntWidget *widget, int *width, int *height);
+gboolean gnt_widget_set_size(GntWidget *widget, int width, int height);
+gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height);
+
+gboolean gnt_widget_key_pressed(GntWidget *widget, const char *keys);
+
+gboolean gnt_widget_clicked(GntWidget *widget, GntMouseEvent event, int x, int y);
+
+gboolean gnt_widget_set_focus(GntWidget *widget, gboolean set);
+void gnt_widget_activate(GntWidget *widget);
+
+void gnt_widget_set_name(GntWidget *widget, const char *name);
+
+const char *gnt_widget_get_name(GntWidget *widget);
+
+/* Widget-subclasses should call this from the draw-callback.
+ * Applications should just call gnt_widget_draw instead of this. */
+void gnt_widget_queue_update(GntWidget *widget);
+
+void gnt_widget_set_take_focus(GntWidget *widget, gboolean set);
+
+void gnt_widget_set_visible(GntWidget *widget, gboolean set);
+
+gboolean gnt_widget_has_shadow(GntWidget *widget);
+
+G_END_DECLS
+
+#endif /* GNT_WIDGET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntwindow.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,118 @@
+#include "gntstyle.h"
+#include "gntwindow.h"
+
+#include <string.h>
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntBoxClass *parent_class = NULL;
+
+static void (*org_destroy)(GntWidget *widget);
+
+static gboolean
+show_menu(GntBindable *bind, GList *null)
+{
+	GntWindow *win = GNT_WINDOW(bind);
+	if (win->menu) {
+		gnt_screen_menu_show(win->menu);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+gnt_window_destroy(GntWidget *widget)
+{
+	GntWindow *window = GNT_WINDOW(widget);
+	if (window->menu)
+		gnt_widget_destroy(GNT_WIDGET(window->menu));
+	org_destroy(widget);
+}
+
+static void
+gnt_window_class_init(GntWindowClass *klass)
+{
+	GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass);
+	GntWidgetClass *wid_class = GNT_WIDGET_CLASS(klass);
+	parent_class = GNT_BOX_CLASS(klass);
+
+	org_destroy = wid_class->destroy;
+	wid_class->destroy = gnt_window_destroy;
+
+	gnt_bindable_class_register_action(bindable, "show-menu", show_menu,
+				GNT_KEY_CTRL_O, NULL);
+	gnt_bindable_register_binding(bindable, "show-menu", GNT_KEY_F10, NULL);
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable);
+
+	GNTDEBUG;
+}
+
+static void
+gnt_window_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS);
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntWindow API
+ *****************************************************************************/
+GType
+gnt_window_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntWindowClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_window_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntWindow),
+			0,						/* n_preallocs		*/
+			gnt_window_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_BOX,
+									  "GntWindow",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_window_new()
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_WINDOW, NULL);
+
+	return widget;
+}
+
+GntWidget *gnt_window_box_new(gboolean homo, gboolean vert)
+{
+	GntWidget *wid = gnt_window_new();
+	GntBox *box = GNT_BOX(wid);
+
+	box->homogeneous = homo;
+	box->vertical = vert;
+	box->alignment = vert ? GNT_ALIGN_LEFT : GNT_ALIGN_MID;
+
+	return wid;
+}
+
+void gnt_window_set_menu(GntWindow *window, GntMenu *menu)
+{
+	/* If a menu already existed, then destroy that first. */
+	if (window->menu)
+		gnt_widget_destroy(GNT_WIDGET(window->menu));
+	window->menu = menu;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntwindow.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,56 @@
+#ifndef GNT_WINDOW_H
+#define GNT_WINDOW_H
+
+#include "gnt.h"
+#include "gntbox.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+#include "gntmenu.h"
+
+#define GNT_TYPE_WINDOW				(gnt_window_get_gtype())
+#define GNT_WINDOW(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WINDOW, GntWindow))
+#define GNT_WINDOW_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_WINDOW, GntWindowClass))
+#define GNT_IS_WINDOW(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WINDOW))
+#define GNT_IS_WINDOW_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WINDOW))
+#define GNT_WINDOW_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WINDOW, GntWindowClass))
+
+#define GNT_WINDOW_FLAGS(obj)				(GNT_WINDOW(obj)->priv.flags)
+#define GNT_WINDOW_SET_FLAGS(obj, flags)		(GNT_WINDOW_FLAGS(obj) |= flags)
+#define GNT_WINDOW_UNSET_FLAGS(obj, flags)	(GNT_WINDOW_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnWindow			GntWindow;
+typedef struct _GnWindowPriv		GntWindowPriv;
+typedef struct _GnWindowClass		GntWindowClass;
+
+struct _GnWindow
+{
+	GntBox parent;
+	GntMenu *menu;
+};
+
+struct _GnWindowClass
+{
+	GntBoxClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_window_get_gtype(void);
+
+#define gnt_vwindow_new(homo) gnt_window_box_new(homo, TRUE)
+#define gnt_hwindow_new(homo) gnt_window_box_new(homo, FALSE)
+
+GntWidget *gnt_window_new();
+
+GntWidget *gnt_window_box_new(gboolean homo, gboolean vert);
+
+void gnt_window_set_menu(GntWindow *window, GntMenu *menu);
+
+G_END_DECLS
+
+#endif /* GNT_WINDOW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntwm.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,1322 @@
+#define _GNU_SOURCE
+#if defined(__APPLE__)
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include "config.h"
+
+#include "gntwm.h"
+#include "gntstyle.h"
+#include "gntmarshal.h"
+#include "gnt.h"
+#include "gntbox.h"
+#include "gntmenu.h"
+#include "gnttextview.h"
+#include "gnttree.h"
+#include "gntutils.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum
+{
+	SIG_NEW_WIN,
+	SIG_DECORATE_WIN,
+	SIG_CLOSE_WIN,
+	SIG_CONFIRM_RESIZE,
+	SIG_RESIZED,
+	SIG_CONFIRM_MOVE,
+	SIG_MOVED,
+	SIG_UPDATE_WIN,
+	SIG_GIVE_FOCUS,
+	SIG_KEY_PRESS,
+	SIG_MOUSE_CLICK,
+	SIGS
+};
+
+static guint signals[SIGS] = { 0 };
+static void gnt_wm_new_window_real(GntWM *wm, GntWidget *widget);
+static void gnt_wm_win_resized(GntWM *wm, GntNode *node);
+static void gnt_wm_win_moved(GntWM *wm, GntNode *node);
+static void gnt_wm_give_focus(GntWM *wm, GntWidget *widget);
+static void update_window_in_list(GntWM *wm, GntWidget *wid);
+
+static gboolean write_already(gpointer data);
+static int write_timeout;
+
+static GList *
+g_list_bring_to_front(GList *list, gpointer data)
+{
+	list = g_list_remove(list, data);
+	list = g_list_prepend(list, data);
+	return list;
+}
+
+static void
+free_node(gpointer data)
+{
+	GntNode *node = data;
+	hide_panel(node->panel);
+	del_panel(node->panel);
+	g_free(node);
+}
+
+static void
+draw_taskbar(GntWM *wm, gboolean reposition)
+{
+	static WINDOW *taskbar = NULL;
+	GList *iter;
+	int n, width = 0;
+	int i;
+
+	if (taskbar == NULL) {
+		taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0);
+	} else if (reposition) {
+		int Y_MAX = getmaxy(stdscr) - 1;
+		mvwin(taskbar, Y_MAX, 0);
+	}
+
+	wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
+	werase(taskbar);
+
+	n = g_list_length(wm->list);
+	if (n)
+		width = getmaxx(stdscr) / n;
+
+	for (i = 0, iter = wm->list; iter; iter = iter->next, i++)
+	{
+		GntWidget *w = iter->data;
+		int color;
+		const char *title;
+
+		if (w == wm->ordered->data) {
+			/* This is the current window in focus */
+			color = GNT_COLOR_TITLE;
+		} else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_URGENT)) {
+			/* This is a window with the URGENT hint set */
+			color = GNT_COLOR_URGENT;
+		} else {
+			color = GNT_COLOR_NORMAL;
+		}
+		wbkgdset(taskbar, '\0' | COLOR_PAIR(color));
+		if (iter->next)
+			mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), width);
+		else
+			mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), getmaxx(stdscr) - width * i);
+		title = GNT_BOX(w)->title;
+		mvwprintw(taskbar, 0, width * i, "%s", title ? title : "<gnt>");
+		if (i)
+			mvwaddch(taskbar, 0, width *i - 1, ACS_VLINE | A_STANDOUT | COLOR_PAIR(GNT_COLOR_NORMAL));
+
+		update_window_in_list(wm, w);
+	}
+
+	wrefresh(taskbar);
+}
+static gboolean
+update_screen(GntWM *wm)
+{
+	if (wm->menu) {
+		GntMenu *top = wm->menu;
+		while (top) {
+			GntNode *node = g_hash_table_lookup(wm->nodes, top);
+			if (node)
+				top_panel(node->panel);
+			top = top->submenu;
+		}
+	}
+	update_panels();
+	doupdate();
+	return TRUE;
+}
+
+static gboolean
+sanitize_position(GntWidget *widget, int *x, int *y)
+{
+	int X_MAX = getmaxx(stdscr);
+	int Y_MAX = getmaxy(stdscr) - 1;
+	int w, h;
+	int nx, ny;
+	gboolean changed = FALSE;
+
+	gnt_widget_get_size(widget, &w, &h);
+	if (x) {
+		if (*x + w > X_MAX) {
+			nx = MAX(0, X_MAX - w);
+			if (nx != *x) {
+				*x = nx;
+				changed = TRUE;
+			}
+		}
+	}
+	if (y) {
+		if (*y + h > Y_MAX) {
+			ny = MAX(0, Y_MAX - h);
+			if (ny != *y) {
+				*y = ny;
+				changed = TRUE;
+			}
+		}
+	}
+	return changed;
+}
+
+static void
+refresh_node(GntWidget *widget, GntNode *node, gpointer null)
+{
+	int x, y, w, h;
+	int nw, nh;
+
+	int X_MAX = getmaxx(stdscr);
+	int Y_MAX = getmaxy(stdscr) - 1;
+
+	gnt_widget_get_position(widget, &x, &y);
+	gnt_widget_get_size(widget, &w, &h);
+
+	if (sanitize_position(widget, &x, &y))
+		gnt_screen_move_widget(widget, x, y);
+
+	nw = MIN(w, X_MAX);
+	nh = MIN(h, Y_MAX);
+	if (nw != w || nh != h)
+		gnt_screen_resize_widget(widget, nw, nh);
+}
+
+static void
+read_window_positions(GntWM *wm)
+{
+#if GLIB_CHECK_VERSION(2,6,0)
+	GKeyFile *gfile = g_key_file_new();
+	char *filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL);
+	GError *error = NULL;
+	char **keys;
+	gsize nk;
+
+	if (!g_key_file_load_from_file(gfile, filename, G_KEY_FILE_NONE, &error)) {
+		g_printerr("GntWM: %s\n", error->message);
+		g_error_free(error);
+		g_free(filename);
+		return;
+	}
+
+	keys = g_key_file_get_keys(gfile, "positions", &nk, &error);
+	if (error) {
+		g_printerr("GntWM: %s\n", error->message);
+		g_error_free(error);
+		error = NULL;
+	} else {
+		while (nk--) {
+			char *title = keys[nk];
+			gsize l;
+			char **coords = g_key_file_get_string_list(gfile, "positions", title, &l, NULL);
+			if (l == 2) {
+				int x = atoi(coords[0]);
+				int y = atoi(coords[1]);
+				GntPosition *p = g_new0(GntPosition, 1);
+				p->x = x;
+				p->y = y;
+				g_hash_table_replace(wm->positions, g_strdup(title + 1), p);
+			} else {
+				g_printerr("GntWM: Invalid number of arguments for positioing a window.\n");
+			}
+			g_strfreev(coords);
+		}
+		g_strfreev(keys);
+	}
+
+	g_free(filename);
+#endif
+}
+
+static void
+gnt_wm_init(GTypeInstance *instance, gpointer class)
+{
+	GntWM *wm = GNT_WM(instance);
+	wm->list = NULL;
+	wm->ordered = NULL;
+	wm->event_stack = FALSE;
+	wm->windows = NULL;
+	wm->actions = NULL;
+	wm->nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node);
+	wm->positions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+	if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE))
+		read_window_positions(wm);
+}
+
+static void
+switch_window(GntWM *wm, int direction)
+{
+	GntWidget *w = NULL, *wid = NULL;
+	int pos;
+
+	if (wm->_list.window || wm->menu)
+		return;
+
+	if (!wm->ordered || !wm->ordered->next)
+		return;
+
+	w = wm->ordered->data;
+	pos = g_list_index(wm->list, w);
+	pos += direction;
+
+	if (pos < 0)
+		wid = g_list_last(wm->list)->data;
+	else if (pos >= g_list_length(wm->list))
+		wid = wm->list->data;
+	else if (pos >= 0)
+		wid = g_list_nth_data(wm->list, pos);
+
+	wm->ordered = g_list_bring_to_front(wm->ordered, wid);
+
+	gnt_wm_raise_window(wm, wm->ordered->data);
+
+	if (w != wid) {
+		gnt_widget_set_focus(w, FALSE);
+	}
+}
+
+static gboolean
+window_next(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	switch_window(wm, 1);
+	return TRUE;
+}
+
+static gboolean
+window_prev(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	switch_window(wm, -1);
+	return TRUE;
+}
+
+static gboolean
+switch_window_n(GntBindable *bind, GList *list)
+{
+	GntWM *wm = GNT_WM(bind);
+	GntWidget *w = NULL;
+	GList *l;
+	int n;
+
+	if (!wm->ordered)
+		return TRUE;
+
+	if (list)
+		n = GPOINTER_TO_INT(list->data);
+	else
+		n = 0;
+	
+	w = wm->ordered->data;
+
+	if ((l = g_list_nth(wm->list, n)) != NULL)
+	{
+		gnt_wm_raise_window(wm, l->data);
+	}
+
+	if (l && w != l->data)
+	{
+		gnt_widget_set_focus(w, FALSE);
+	}
+	return TRUE;
+}
+static gboolean
+window_close(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+
+	if (wm->_list.window)
+		return TRUE;
+
+	if (wm->ordered) {
+		gnt_widget_destroy(wm->ordered->data);
+	}
+
+	return TRUE;
+}
+
+static void
+destroy__list(GntWidget *widget, GntWM *wm)
+{
+	wm->_list.window = NULL;
+	wm->_list.tree = NULL;
+	wm->windows = NULL;
+	wm->actions = NULL;
+	update_screen(wm);
+}
+
+static void
+setup__list(GntWM *wm)
+{
+	GntWidget *tree, *win;
+	win = wm->_list.window = gnt_box_new(FALSE, FALSE);
+	gnt_box_set_toplevel(GNT_BOX(win), TRUE);
+	gnt_box_set_pad(GNT_BOX(win), 0);
+	GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_TRANSIENT);
+
+	tree = wm->_list.tree = gnt_tree_new();
+	gnt_box_add_widget(GNT_BOX(win), tree);
+
+	g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(destroy__list), wm);
+}
+
+static void
+window_list_activate(GntTree *tree, GntWM *wm)
+{
+	GntWidget *widget = gnt_tree_get_selection_data(GNT_TREE(tree));
+
+	if (!wm->ordered || !widget)
+		return;
+
+	gnt_widget_destroy(wm->_list.window);
+	gnt_wm_raise_window(wm, widget);
+}
+
+static gboolean
+window_list(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	GntWidget *tree, *win;
+	GList *iter;
+
+	if (wm->_list.window || wm->menu)
+		return TRUE;
+
+	if (!wm->ordered)
+		return TRUE;
+
+	setup__list(wm);
+	wm->windows = &wm->_list;
+
+	win = wm->windows->window;
+	tree = wm->windows->tree;
+
+	gnt_box_set_title(GNT_BOX(win), "Window List");
+
+	for (iter = wm->list; iter; iter = iter->next) {
+		GntBox *box = GNT_BOX(iter->data);
+
+		gnt_tree_add_row_last(GNT_TREE(tree), box,
+				gnt_tree_create_row(GNT_TREE(tree), box->title), NULL);
+		update_window_in_list(wm, GNT_WIDGET(box));
+	}
+
+	gnt_tree_set_selected(GNT_TREE(tree), wm->ordered->data);
+	g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), wm);
+
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, getmaxx(stdscr) / 3);
+	gnt_widget_set_size(tree, 0, getmaxy(stdscr) / 2);
+	gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4);
+
+	gnt_widget_show(win);
+	return TRUE;
+}
+
+static gboolean
+dump_screen(GntBindable *bindable, GList *null)
+{
+	int x, y;
+	chtype old = 0, now = 0;
+	FILE *file = fopen("dump.html", "w");
+
+	fprintf(file, "<pre>");
+	for (y = 0; y < getmaxy(stdscr); y++) {
+		for (x = 0; x < getmaxx(stdscr); x++) {
+			char ch;
+			now = mvwinch(curscr, y, x);
+			ch = now & A_CHARTEXT;
+			now ^= ch;
+
+#define CHECK(attr, start, end) \
+			do \
+			{  \
+				if (now & attr)  \
+				{  \
+					if (!(old & attr))  \
+						fprintf(file, "%s", start);  \
+				}  \
+				else if (old & attr)  \
+				{  \
+					fprintf(file, "%s", end);  \
+				}  \
+			} while (0) 
+
+			CHECK(A_BOLD, "<b>", "</b>");
+			CHECK(A_UNDERLINE, "<u>", "</u>");
+			CHECK(A_BLINK, "<blink>", "</blink>");
+
+			if ((now & A_COLOR) != (old & A_COLOR) ||
+				(now & A_REVERSE) != (old & A_REVERSE))
+			{
+				int ret;
+				short fgp, bgp, r, g, b;
+				struct
+				{
+					int r, g, b;
+				} fg, bg;
+
+				ret = pair_content(PAIR_NUMBER(now & A_COLOR), &fgp, &bgp);
+				if (fgp == -1)
+					fgp = COLOR_BLACK;
+				if (bgp == -1)
+					bgp = COLOR_WHITE;
+				if (now & A_REVERSE)
+					fgp ^= bgp ^= fgp ^= bgp;  /* *wink* */
+				ret = color_content(fgp, &r, &g, &b);
+				fg.r = r; fg.b = b; fg.g = g;
+				ret = color_content(bgp, &r, &g, &b);
+				bg.r = r; bg.b = b; bg.g = g;
+#define ADJUST(x) (x = x * 255 / 1000)
+				ADJUST(fg.r);
+				ADJUST(fg.g);
+				ADJUST(fg.b);
+				ADJUST(bg.r);
+				ADJUST(bg.b);
+				ADJUST(bg.g);
+				
+				if (x) fprintf(file, "</span>");
+				fprintf(file, "<span style=\"background:#%02x%02x%02x;color:#%02x%02x%02x\">",
+						bg.r, bg.g, bg.b, fg.r, fg.g, fg.b);
+			}
+			if (now & A_ALTCHARSET)
+			{
+				switch (ch)
+				{
+					case 'q':
+						ch = '-'; break;
+					case 't':
+					case 'u':
+					case 'x':
+						ch = '|'; break;
+					case 'v':
+					case 'w':
+					case 'l':
+					case 'm':
+					case 'k':
+					case 'j':
+					case 'n':
+						ch = '+'; break;
+					case '-':
+						ch = '^'; break;
+					case '.':
+						ch = 'v'; break;
+					case 'a':
+						ch = '#'; break;
+					default:
+						ch = ' '; break;
+				}
+			}
+			if (ch == '&')
+				fprintf(file, "&amp;");
+			else if (ch == '<')
+				fprintf(file, "&lt;");
+			else if (ch == '>')
+				fprintf(file, "&gt;");
+			else
+				fprintf(file, "%c", ch);
+			old = now;
+		}
+		fprintf(file, "</span>\n");
+		old = 0;
+	}
+	fprintf(file, "</pre>");
+	fclose(file);
+	return TRUE;
+}
+
+static void
+shift_window(GntWM *wm, GntWidget *widget, int dir)
+{
+	GList *all = wm->list;
+	GList *list = g_list_find(all, widget);
+	int length, pos;
+	if (!list)
+		return;
+
+	length = g_list_length(all);
+	pos = g_list_position(all, list);
+
+	pos += dir;
+	if (dir > 0)
+		pos++;
+
+	if (pos < 0)
+		pos = length;
+	else if (pos > length)
+		pos = 0;
+
+	all = g_list_insert(all, widget, pos);
+	all = g_list_delete_link(all, list);
+	wm->list = all;
+	draw_taskbar(wm, FALSE);
+}
+
+static gboolean
+shift_left(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	if (wm->_list.window)
+		return TRUE;
+
+	shift_window(wm, wm->ordered->data, -1);
+	return TRUE;
+}
+
+static gboolean
+shift_right(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	if (wm->_list.window)
+		return TRUE;
+
+	shift_window(wm, wm->ordered->data, 1);
+	return TRUE;
+}
+
+static void
+action_list_activate(GntTree *tree, GntWM *wm)
+{
+	GntAction *action = gnt_tree_get_selection_data(tree);
+	action->callback();
+	gnt_widget_destroy(wm->_list.window);
+}
+
+static int
+compare_action(gconstpointer p1, gconstpointer p2)
+{
+	const GntAction *a1 = p1;
+	const GntAction *a2 = p2;
+
+	return g_utf8_collate(a1->label, a2->label);
+}
+
+static gboolean
+list_actions(GntBindable *bindable, GList *null)
+{
+	GntWidget *tree, *win;
+	GList *iter;
+	GntWM *wm = GNT_WM(bindable);
+	if (wm->_list.window || wm->menu)
+		return TRUE;
+
+	if (wm->acts == NULL)
+		return TRUE;
+
+	setup__list(wm);
+	wm->actions = &wm->_list;
+
+	win = wm->actions->window;
+	tree = wm->actions->tree;
+
+	gnt_box_set_title(GNT_BOX(win), "Actions");
+	GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
+	/* XXX: Do we really want this? */
+	gnt_tree_set_compare_func(GNT_TREE(tree), compare_action);
+
+	for (iter = wm->acts; iter; iter = iter->next) {
+		GntAction *action = iter->data;
+		gnt_tree_add_row_last(GNT_TREE(tree), action,
+				gnt_tree_create_row(GNT_TREE(tree), action->label), NULL);
+	}
+	g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(action_list_activate), wm);
+	gnt_widget_set_size(tree, 0, g_list_length(wm->acts));
+	gnt_widget_set_position(win, 0, getmaxy(stdscr) - 3 - g_list_length(wm->acts));
+
+	gnt_widget_show(win);
+	return TRUE;
+}
+
+#ifndef NO_WIDECHAR
+static int
+widestringwidth(wchar_t *wide)
+{
+	int len, ret;
+	char *string;
+
+	len = wcstombs(NULL, wide, 0) + 1;
+	string = g_new0(char, len);
+	wcstombs(string, wide, len);
+	ret = gnt_util_onscreen_width(string, NULL);
+	g_free(string);
+	return ret;
+}
+#endif
+
+/* Returns the onscreen width of the character at the position */
+static int
+reverse_char(WINDOW *d, int y, int x, gboolean set)
+{
+#define DECIDE(ch) (set ? ((ch) | A_REVERSE) : ((ch) & ~A_REVERSE))
+
+#ifdef NO_WIDECHAR
+	chtype ch;
+	ch = mvwinch(d, y, x);
+	mvwaddch(d, y, x, DECIDE(ch));
+	return 1;
+#else
+	cchar_t ch;
+	int wc = 1;
+	if (mvwin_wch(d, y, x, &ch) == OK) {
+		wc = widestringwidth(ch.chars);
+		ch.attr = DECIDE(ch.attr);
+		ch.attr &= WA_ATTRIBUTES;   /* XXX: This is a workaround for a bug */
+		mvwadd_wch(d, y, x, &ch);
+	}
+
+	return wc;
+#endif
+}
+
+static void
+window_reverse(GntWidget *win, gboolean set)
+{
+	int i;
+	int w, h;
+	WINDOW *d;
+
+	if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER))
+		return;
+	
+	d = win->window;
+	gnt_widget_get_size(win, &w, &h);
+
+	if (gnt_widget_has_shadow(win)) {
+		--w;
+		--h;
+	}
+
+	/* the top and bottom */
+	for (i = 0; i < w; i += reverse_char(d, 0, i, set));
+	for (i = 0; i < w; i += reverse_char(d, h-1, i, set));
+
+	/* the left and right */
+	for (i = 0; i < h; i += reverse_char(d, i, 0, set));
+	for (i = 0; i < h; i += reverse_char(d, i, w-1, set));
+
+	wrefresh(win->window);
+}
+
+static gboolean
+start_move(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	if (wm->_list.window || wm->menu)
+		return TRUE;
+	if (!wm->ordered)
+		return TRUE;
+
+	wm->mode = GNT_KP_MODE_MOVE;
+	window_reverse(GNT_WIDGET(wm->ordered->data), TRUE);
+
+	return TRUE;
+}
+
+static gboolean
+start_resize(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	if (wm->_list.window || wm->menu)
+		return TRUE;
+	if (!wm->ordered)
+		return TRUE;
+
+	wm->mode = GNT_KP_MODE_RESIZE;
+	window_reverse(GNT_WIDGET(wm->ordered->data), TRUE);
+
+	return TRUE;
+}
+
+static gboolean
+wm_quit(GntBindable *bindable, GList *list)
+{
+	GntWM *wm = GNT_WM(bindable);
+	if (write_timeout)
+		write_already(wm);
+	g_main_loop_quit(wm->loop);
+	return TRUE;
+}
+
+static gboolean
+return_true(GntWM *wm, GntWidget *w, int *a, int *b)
+{
+	return TRUE;
+}
+
+static gboolean
+refresh_screen(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+
+	endwin();
+	refresh();
+	curs_set(0);   /* endwin resets the cursor to normal */
+
+	g_hash_table_foreach(wm->nodes, (GHFunc)refresh_node, NULL);
+	update_screen(wm);
+	draw_taskbar(wm, TRUE);
+
+	return FALSE;
+}
+
+static void
+gnt_wm_class_init(GntWMClass *klass)
+{
+	klass->new_window = gnt_wm_new_window_real;
+	klass->decorate_window = NULL;
+	klass->close_window = NULL;
+	klass->window_resize_confirm = return_true;
+	klass->window_resized = gnt_wm_win_resized;
+	klass->window_move_confirm = return_true;
+	klass->window_moved = gnt_wm_win_moved;
+	klass->window_update = NULL;
+	klass->key_pressed  = NULL;
+	klass->mouse_clicked = NULL;
+	klass->give_focus = gnt_wm_give_focus;
+	
+	signals[SIG_NEW_WIN] = 
+		g_signal_new("new_win",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, new_window),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals[SIG_DECORATE_WIN] = 
+		g_signal_new("decorate_win",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, decorate_window),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals[SIG_CLOSE_WIN] = 
+		g_signal_new("close_win",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, close_window),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals[SIG_CONFIRM_RESIZE] = 
+		g_signal_new("confirm_resize",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, window_resize_confirm),
+					 gnt_boolean_handled_accumulator, NULL,
+					 gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER,
+					 G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
+
+	signals[SIG_CONFIRM_MOVE] = 
+		g_signal_new("confirm_move",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, window_move_confirm),
+					 gnt_boolean_handled_accumulator, NULL,
+					 gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER,
+					 G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
+
+	signals[SIG_RESIZED] = 
+		g_signal_new("window_resized",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, window_resized),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals[SIG_MOVED] = 
+		g_signal_new("window_moved",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, window_moved),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals[SIG_UPDATE_WIN] = 
+		g_signal_new("window_update",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, window_update),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+	signals[SIG_GIVE_FOCUS] = 
+		g_signal_new("give_focus",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, give_focus),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__POINTER,
+					 G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+	signals[SIG_MOUSE_CLICK] = 
+		g_signal_new("mouse_clicked",
+					 G_TYPE_FROM_CLASS(klass),
+					 G_SIGNAL_RUN_LAST,
+					 G_STRUCT_OFFSET(GntWMClass, mouse_clicked),
+					 gnt_boolean_handled_accumulator, NULL,
+					 gnt_closure_marshal_BOOLEAN__INT_INT_INT_POINTER,
+					 G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER);
+
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-next", window_next,
+				"\033" "n", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-prev", window_prev,
+				"\033" "p", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-close", window_close,
+				"\033" "c", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-list", window_list,
+				"\033" "w", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "dump-screen", dump_screen,
+				"\033" "d", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "shift-left", shift_left,
+				"\033" ",", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "shift-right", shift_right,
+				"\033" ".", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "action-list", list_actions,
+				"\033" "a", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "start-move", start_move,
+				"\033" "m", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "start-resize", start_resize,
+				"\033" "r", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "wm-quit", wm_quit,
+				"\033" "q", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "refresh-screen", refresh_screen,
+				"\033" "l", NULL);
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "switch-window-n", switch_window_n,
+				NULL, NULL);
+
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntWM API
+ *****************************************************************************/
+GType
+gnt_wm_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(GntWMClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_wm_class_init,
+			NULL,
+			NULL,					/* class_data		*/
+			sizeof(GntWM),
+			0,						/* n_preallocs		*/
+			gnt_wm_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_BINDABLE,
+									  "GntWM",
+									  &info, 0);
+	}
+
+	return type;
+}
+static void
+update_window_in_list(GntWM *wm, GntWidget *wid)
+{
+	GntTextFormatFlags flag = 0;
+
+	if (wm->windows == NULL)
+		return;
+
+	if (wid == wm->ordered->data)
+		flag |= GNT_TEXT_FLAG_DIM;
+	else if (GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_URGENT))
+		flag |= GNT_TEXT_FLAG_BOLD;
+
+	gnt_tree_set_row_flags(GNT_TREE(wm->windows->tree), wid, flag);
+}
+
+static void
+gnt_wm_new_window_real(GntWM *wm, GntWidget *widget)
+{
+	GntNode *node;
+	gboolean transient = FALSE;
+
+	if (widget->window == NULL)
+		return;
+
+	node = g_new0(GntNode, 1);
+	node->me = widget;
+
+	g_hash_table_replace(wm->nodes, widget, node);
+
+	refresh_node(widget, node, NULL);
+
+	transient = !!GNT_WIDGET_IS_FLAG_SET(node->me, GNT_WIDGET_TRANSIENT);
+
+	node->panel = new_panel(node->me->window);
+	set_panel_userptr(node->panel, node);
+
+	if (!transient) {
+		if (node->me != wm->_list.window) {
+			GntWidget *w = NULL;
+
+			if (wm->ordered)
+				w = wm->ordered->data;
+
+			wm->list = g_list_append(wm->list, widget);
+
+			if (wm->event_stack)
+				wm->ordered = g_list_prepend(wm->ordered, widget);
+			else
+				wm->ordered = g_list_append(wm->ordered, widget);
+
+			gnt_widget_set_focus(widget, TRUE);
+			if (w)
+				gnt_widget_set_focus(w, FALSE);
+		}
+
+		if (wm->event_stack || node->me == wm->_list.window) {
+			gnt_wm_raise_window(wm, node->me);
+		} else {
+			bottom_panel(node->panel);     /* New windows should not grab focus */
+			gnt_widget_set_urgent(node->me);
+		}
+	}
+}
+
+void gnt_wm_new_window(GntWM *wm, GntWidget *widget)
+{
+	while (widget->parent)
+		widget = widget->parent;
+	
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_INVISIBLE) ||
+			g_hash_table_lookup(wm->nodes, widget)) {
+		update_screen(wm);
+		return;
+	}
+
+	if (GNT_IS_BOX(widget)) {
+		const char *title = GNT_BOX(widget)->title;
+		GntPosition *p = NULL;
+		if (title && (p = g_hash_table_lookup(wm->positions, title)) != NULL) {
+			sanitize_position(widget, &p->x, &p->y);
+			gnt_widget_set_position(widget, p->x, p->y);
+			mvwin(widget->window, p->y, p->x);
+		}
+	}
+
+	g_signal_emit(wm, signals[SIG_NEW_WIN], 0, widget);
+	g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget);
+
+	if (wm->windows && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) {
+		if ((GNT_IS_BOX(widget) && GNT_BOX(widget)->title) && wm->_list.window != widget
+				&& GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) {
+			gnt_tree_add_row_last(GNT_TREE(wm->windows->tree), widget,
+					gnt_tree_create_row(GNT_TREE(wm->windows->tree), GNT_BOX(widget)->title),
+					NULL);
+			update_window_in_list(wm, widget);
+		}
+	}
+
+	update_screen(wm);
+	draw_taskbar(wm, FALSE);
+}
+
+void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget)
+{
+	g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget);
+}
+
+void gnt_wm_window_close(GntWM *wm, GntWidget *widget)
+{
+	GntNode *node;
+	int pos;
+
+	if ((node = g_hash_table_lookup(wm->nodes, widget)) == NULL)
+		return;
+
+	g_signal_emit(wm, signals[SIG_CLOSE_WIN], 0, widget);
+	g_hash_table_remove(wm->nodes, widget);
+
+	if (wm->windows) {
+		gnt_tree_remove(GNT_TREE(wm->windows->tree), widget);
+	}
+
+	pos = g_list_index(wm->list, widget);
+
+	if (pos != -1) {
+		wm->list = g_list_remove(wm->list, widget);
+		wm->ordered = g_list_remove(wm->ordered, widget);
+
+		if (wm->ordered)
+			gnt_wm_raise_window(wm, wm->ordered->data);
+	}
+
+	update_screen(wm);
+	draw_taskbar(wm, FALSE);
+}
+
+void gnt_wm_process_input(GntWM *wm, const char *keys)
+{
+	keys = gnt_bindable_remap_keys(GNT_BINDABLE(wm), keys);
+
+	if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys))
+		return;
+
+	/* Do some manual checking */
+	if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) {
+		int xmin = 0, ymin = 0, xmax = getmaxx(stdscr), ymax = getmaxy(stdscr) - 1;
+		int x, y, w, h;
+		GntWidget *widget = GNT_WIDGET(wm->ordered->data);
+		int ox, oy, ow, oh;
+
+		gnt_widget_get_position(widget, &x, &y);
+		gnt_widget_get_size(widget, &w, &h);
+		ox = x;	oy = y;
+		ow = w;	oh = h;
+
+		if (wm->mode == GNT_KP_MODE_MOVE) {
+			if (strcmp(keys, GNT_KEY_LEFT) == 0) {
+				if (x > xmin)
+					x--;
+			} else if (strcmp(keys, GNT_KEY_RIGHT) == 0) {
+				if (x + w < xmax)
+					x++;
+			} else if (strcmp(keys, GNT_KEY_UP) == 0) {
+				if (y > ymin)
+					y--;
+			} else if (strcmp(keys, GNT_KEY_DOWN) == 0) {
+				if (y + h < ymax)
+					y++;
+			}
+			if (ox != x || oy != y) {
+				gnt_screen_move_widget(widget, x, y);
+				window_reverse(widget, TRUE);
+				return;
+			}
+		} else if (wm->mode == GNT_KP_MODE_RESIZE) {
+			if (strcmp(keys, GNT_KEY_LEFT) == 0) {
+				w--;
+			} else if (strcmp(keys, GNT_KEY_RIGHT) == 0) {
+				if (x + w < xmax)
+					w++;
+			} else if (strcmp(keys, GNT_KEY_UP) == 0) {
+				h--;
+			} else if (strcmp(keys, GNT_KEY_DOWN) == 0) {
+				if (y + h < ymax)
+					h++;
+			}
+			if (oh != h || ow != w) {
+				gnt_screen_resize_widget(widget, w, h);
+				window_reverse(widget, TRUE);
+				return;
+			}
+		}
+		if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) {
+			window_reverse(widget, FALSE);
+			wm->mode = GNT_KP_MODE_NORMAL;
+		}
+		return;
+	}
+
+	wm->event_stack = TRUE;
+
+	/* Escape to close the window-list or action-list window */
+	if (strcmp(keys, "\033") == 0) {
+		if (wm->_list.window) {
+			gnt_widget_destroy(wm->_list.window);
+			wm->event_stack = FALSE;
+			return;
+		}
+	} else if (keys[0] == '\033' && isdigit(keys[1]) && keys[2] == '\0') {
+		/* Alt+x for quick switch */
+		int n = *(keys + 1) - '0';
+		GList *list = NULL;
+
+		if (n == 0)
+			n = 10;
+
+		list = g_list_append(list, GINT_TO_POINTER(n - 1));
+		switch_window_n(GNT_BINDABLE(wm), list);
+		g_list_free(list);
+		return;
+	}
+
+	if (wm->menu)
+		gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys);
+	else if (wm->_list.window)
+		gnt_widget_key_pressed(wm->_list.window, keys);
+	else if (wm->ordered)
+		gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys);
+	wm->event_stack = FALSE;
+}
+
+static void
+gnt_wm_win_resized(GntWM *wm, GntNode *node)
+{
+	refresh_node(node->me, node, NULL);
+	replace_panel(node->panel, node->me->window);
+}
+
+static void
+gnt_wm_win_moved(GntWM *wm, GntNode *node)
+{
+	refresh_node(node->me, node, NULL);
+}
+
+void gnt_wm_resize_window(GntWM *wm, GntWidget *widget, int width, int height)
+{
+	gboolean ret = TRUE;
+	GntNode *node;
+	
+	while (widget->parent)
+		widget = widget->parent;
+	node = g_hash_table_lookup(wm->nodes, widget);
+	if (!node)
+		return;
+
+	g_signal_emit(wm, signals[SIG_CONFIRM_RESIZE], 0, widget, &width, &height, &ret);
+	if (!ret)
+		return;    /* resize is not permitted */
+	hide_panel(node->panel);
+	gnt_widget_set_size(widget, width, height);
+	gnt_widget_draw(widget);
+
+	g_signal_emit(wm, signals[SIG_RESIZED], 0, node);
+
+	show_panel(node->panel);
+	update_screen(wm);
+}
+
+static void
+write_gdi(gpointer key, gpointer value, gpointer data)
+{
+	GntPosition *p = value;
+	fprintf(data, ".%s = %d;%d\n", key, p->x, p->y);
+}
+
+static gboolean
+write_already(gpointer data)
+{
+	GntWM *wm = data;
+	FILE *file;
+	char *filename;
+
+	filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL);
+
+	file = fopen(filename, "wb");
+	if (file == NULL) {
+		g_printerr("GntWM: error opening file to save positions\n");
+	} else {
+		fprintf(file, "[positions]\n");
+		g_hash_table_foreach(wm->positions, write_gdi, file);
+		fclose(file);
+	}
+
+	g_free(filename);
+	g_source_remove(write_timeout);
+	write_timeout = 0;
+	return FALSE;
+}
+
+static void
+write_positions_to_file(GntWM *wm)
+{
+	if (write_timeout) {
+		g_source_remove(write_timeout);
+	}
+	write_timeout = g_timeout_add(10000, write_already, wm);
+}
+
+void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y)
+{
+	gboolean ret = TRUE;
+	GntNode *node;
+
+	while (widget->parent)
+		widget = widget->parent;
+	node = g_hash_table_lookup(wm->nodes, widget);
+	if (!node)
+		return;
+
+	g_signal_emit(wm, signals[SIG_CONFIRM_MOVE], 0, widget, &x, &y, &ret);
+	if (!ret)
+		return;    /* resize is not permitted */
+
+	gnt_widget_set_position(widget, x, y);
+	move_panel(node->panel, y, x);
+
+	g_signal_emit(wm, signals[SIG_MOVED], 0, node);
+	if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE) && GNT_IS_BOX(widget)) {
+		const char *title = GNT_BOX(widget)->title;
+		if (title) {
+			GntPosition *p = g_new0(GntPosition, 1);
+			GntWidget *wid = node->me;
+			p->x = wid->priv.x;
+			p->y = wid->priv.y;
+			g_hash_table_replace(wm->positions, g_strdup(title), p);
+			write_positions_to_file(wm);
+		}
+	}
+
+	update_screen(wm);
+}
+
+static void
+gnt_wm_give_focus(GntWM *wm, GntWidget *widget)
+{
+	GntNode *node = g_hash_table_lookup(wm->nodes, widget);
+
+	if (!node)
+		return;
+	
+	if (widget != wm->_list.window && !GNT_IS_MENU(widget) &&
+				wm->ordered->data != widget) {
+		GntWidget *w = wm->ordered->data;
+		wm->ordered = g_list_bring_to_front(wm->ordered, widget);
+		gnt_widget_set_focus(w, FALSE);
+	}
+
+	gnt_widget_set_focus(widget, TRUE);
+	GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_URGENT);
+	gnt_widget_draw(widget);
+	top_panel(node->panel);
+
+	if (wm->_list.window) {
+		GntNode *nd = g_hash_table_lookup(wm->nodes, wm->_list.window);
+		top_panel(nd->panel);
+	}
+	update_screen(wm);
+	draw_taskbar(wm, FALSE);
+}
+
+void gnt_wm_update_window(GntWM *wm, GntWidget *widget)
+{
+	GntNode *node;
+
+	while (widget->parent)
+		widget = widget->parent;
+	if (!GNT_IS_MENU(widget))
+		gnt_box_sync_children(GNT_BOX(widget));
+
+	node = g_hash_table_lookup(wm->nodes, widget);
+	if (node == NULL) {
+		gnt_wm_new_window(wm, widget);
+	} else
+		g_signal_emit(wm, signals[SIG_UPDATE_WIN], 0, node);
+
+	update_screen(wm);
+	draw_taskbar(wm, FALSE);
+}
+
+gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget)
+{
+	gboolean ret = TRUE;
+	g_signal_emit(wm, signals[SIG_MOUSE_CLICK], 0, event, x, y, widget, &ret);
+	return ret;
+}
+
+void gnt_wm_raise_window(GntWM *wm, GntWidget *widget)
+{
+	g_signal_emit(wm, signals[SIG_GIVE_FOCUS], 0, widget);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gntwm.h	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,164 @@
+
+#include "gntwidget.h"
+#include "gntmenu.h"
+
+#include <panel.h>
+
+#define GNT_TYPE_WM				(gnt_wm_get_gtype())
+#define GNT_WM(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WM, GntWM))
+#define GNT_WM_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_WM, GntWMClass))
+#define GNT_IS_WM(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WM))
+#define GNT_IS_WM_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WM))
+#define GNT_WM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WM, GntWMClass))
+
+typedef enum
+{
+	GNT_KP_MODE_NORMAL,
+	GNT_KP_MODE_RESIZE,
+	GNT_KP_MODE_MOVE,
+} GntKeyPressMode;
+
+typedef struct
+{
+	GntWidget *me;
+
+	PANEL *panel;
+} GntNode;
+
+typedef struct _GntWM GntWM;
+
+typedef struct _GnPosition
+{
+	int x;
+	int y;
+} GntPosition;
+
+/**
+ * An application can register actions which will show up in a 'start-menu' like popup
+ */
+typedef struct _GnAction
+{
+	const char *label;
+	void (*callback)();
+} GntAction;
+
+struct _GntWM
+{
+	GntBindable inherit;
+
+	GMainLoop *loop;
+
+	GList *list;      /* List of windows ordered on their creation time */
+	GList *ordered;   /* List of windows ordered on their focus */
+
+	struct {
+		GntWidget *window;
+		GntWidget *tree;
+	} _list,
+		*windows,         /* Window-list window */
+		*actions;         /* Action-list window */
+
+	GHashTable *nodes;    /* GntWidget -> GntNode */
+
+	GList *acts;          /* List of actions */
+
+	/**
+	 * There can be at most one menu at a time on the screen.
+	 * If there is a menu being displayed, then all the keystrokes will be sent to
+	 * the menu until it is closed, either when the user activates a menuitem, or
+	 * presses Escape to cancel the menu.
+	 */
+	GntMenu *menu;        /* Currently active menu */
+
+	/**
+	 * 'event_stack' will be set to TRUE when a user-event, ie. a mouse-click
+	 * or a key-press is being processed. This variable will be used to determine
+	 * whether to give focus to a new window.
+	 */
+	gboolean event_stack;
+	
+	GntKeyPressMode mode;
+
+	GHashTable *positions;
+
+	void *res1;
+	void *res2;
+	void *res3;
+	void *res4;
+};
+
+typedef struct _GnWMClass GntWMClass;
+
+struct _GnWMClass
+{
+	GntBindableClass parent;
+
+	/* This is called when a new window is shown */
+	void (*new_window)(GntWM *wm, GntWidget *win);
+
+	void (*decorate_window)(GntWM *wm, GntWidget *win);
+	/* This is called when a window is being closed */
+	gboolean (*close_window)(GntWM *wm, GntWidget *win);
+
+	/* The WM may want to confirm a size for a window first */
+	gboolean (*window_resize_confirm)(GntWM *wm, GntWidget *win, int *w, int *h);
+
+	void (*window_resized)(GntWM *wm, GntNode *node);
+
+	/* The WM may want to confirm the position of a window */
+	gboolean (*window_move_confirm)(GntWM *wm, GntWidget *win, int *x, int *y);
+
+	void (*window_moved)(GntWM *wm, GntNode *node);
+
+	/* This gets called when:
+	 * 	 - the title of the window changes
+	 * 	 - the 'urgency' of the window changes
+	 */
+	void (*window_update)(GntWM *wm, GntNode *node);
+
+	/* This should usually return NULL if the keys were processed by the WM.
+	 * If not, the WM can simply return the original string, which will be
+	 * processed by the default WM. The custom WM can also return a different
+	 * static string for the default WM to process.
+	 */
+	gboolean (*key_pressed)(GntWM *wm, const char *key);
+
+	gboolean (*mouse_clicked)(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget);
+
+	/* Whatever the WM wants to do when a window is given focus */
+	void (*give_focus)(GntWM *wm, GntWidget *widget);
+
+	/* List of windows. Although the WM can keep a list of its own for the windows,
+	 * it'd be better if there was a way to share between the 'core' and the WM.
+	 */
+	/*const GList *(*window_list)();*/
+
+	void (*res1)(void);
+	void (*res2)(void);
+	void (*res3)(void);
+	void (*res4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_wm_get_gtype(void);
+
+void gnt_wm_new_window(GntWM *wm, GntWidget *widget);
+
+void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget);
+
+void gnt_wm_window_close(GntWM *wm, GntWidget *widget);
+
+void gnt_wm_process_input(GntWM *wm, const char *string);
+
+gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget);
+
+void gnt_wm_resize_window(GntWM *wm, GntWidget *widget, int width, int height);
+
+void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y);
+
+void gnt_wm_update_window(GntWM *wm, GntWidget *widget);
+
+void gnt_wm_raise_window(GntWM *wm, GntWidget *widget);
+
+G_END_DECLS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,125 @@
+#include "gntbutton.h"
+#include "gnt.h"
+#include "gntkeys.h"
+#include "gnttree.h"
+#include "gntbox.h"
+
+static gboolean
+key_pressed(GntWidget *widget, const char *text, gpointer null)
+{
+	GntWidget *w = null;
+	GntWidget *box = gnt_box_new(FALSE, FALSE);
+	GntWidget *label = gnt_label_new("so wassup!!");
+
+	gnt_box_add_widget(GNT_BOX(box), label);
+	GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+	gnt_box_set_title(GNT_BOX(box), "This is a test");
+
+	gnt_widget_show(box);
+#if 0
+
+	gnt_widget_set_focus(w, TRUE);
+
+	/* XXX: This is to just test stuff */
+	if (text[0] == 27)
+	{
+		if (strcmp(text+1, GNT_KEY_LEFT) == 0 && w->priv.x)
+			(w->priv.x)--;
+		else if (strcmp(text+1, GNT_KEY_RIGHT) == 0)
+			(w->priv.x)++;
+		else if (strcmp(text+1, GNT_KEY_UP) == 0 && w->priv.y)
+			(w->priv.y)--;
+		else if (strcmp(text+1, GNT_KEY_DOWN) == 0)
+			(w->priv.y)++;
+	}
+
+	gnt_widget_draw(w);
+#endif
+
+	return FALSE;
+}
+
+static void
+button1(GntWidget *widget, gpointer null)
+{
+	printf("OLAAA");
+	gnt_widget_destroy(null);
+}
+
+static void
+button2(GntWidget *widget, gpointer null)
+{
+	printf("BOOYAA");
+}
+
+static gboolean
+w_scroll(GntWidget *tree)
+{
+	g_return_val_if_fail(GNT_IS_TREE(tree), FALSE);
+	gnt_tree_scroll(GNT_TREE(tree), 1);
+	/*wscrl(tree->window, 1);*/
+	/*box(tree->window, ACS_VLINE, ACS_HLINE);*/
+	/*wrefresh(tree->window);*/
+	/*char *s = 0;*/
+	/**s = 'a';*/
+	return TRUE;
+}
+
+int main()
+{
+	gnt_init();
+
+	GntWidget *widget = gnt_button_new("Button 1");
+	GntWidget *widget2 = gnt_button_new("Button 2 has a longish text with a UTF-8 thing …");
+	GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\nSo this is, like,\nthe third line!! \\o/");
+	GntWidget *vbox, *hbox, *tree;
+	WINDOW *test;
+
+	box(stdscr, 0, 0);
+	wrefresh(stdscr);
+
+	vbox = gnt_box_new(FALSE, FALSE);
+	hbox = gnt_box_new(FALSE, TRUE);
+
+	gnt_widget_set_name(vbox, "vbox");
+	gnt_widget_set_name(hbox, "hbox");
+	gnt_widget_set_name(widget, "widget");
+	gnt_widget_set_name(widget2, "widget2");
+
+	gnt_box_add_widget(GNT_BOX(vbox), widget);
+	gnt_box_add_widget(GNT_BOX(vbox), widget2);
+
+	gnt_box_add_widget(GNT_BOX(hbox), label);
+	/*gnt_box_add_widget(GNT_BOX(hbox), vbox);*/
+
+	gnt_box_add_widget(GNT_BOX(hbox), gnt_entry_new("a"));
+
+	tree = gnt_tree_new();
+	gnt_box_add_widget(GNT_BOX(hbox), tree);
+
+	gnt_tree_add_row_after(GNT_TREE(tree), "a", "a", NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "c", "c", NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "d", "d", NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "e", "e", "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "b", "b", "d", NULL);
+
+	GNT_WIDGET_UNSET_FLAGS(hbox, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+	gnt_box_set_title(GNT_BOX(hbox), "111111111111111111111111111111111111111111111111111111111111111This is the title …");
+
+	/*gnt_widget_set_take_focus(vbox, TRUE);*/
+	/*gnt_widget_set_take_focus(hbox, TRUE);*/
+	/*gnt_widget_set_position(hbox, 10, 10);*/
+
+	gnt_widget_show(hbox);
+
+	g_signal_connect(hbox, "key_pressed", G_CALLBACK(key_pressed), tree);
+	g_signal_connect(widget, "activate", G_CALLBACK(button1), hbox);
+	g_signal_connect(widget2, "activate", G_CALLBACK(button2), hbox);
+
+	/*g_timeout_add(1000, (GSourceFunc)w_scroll, tree);*/
+
+	gnt_main();
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/Makefile	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,16 @@
+CC=gcc
+CFLAGS=`pkg-config --cflags gobject-2.0 gmodule-2.0` -g -I../ -DSTANDALONE
+LDFLAGS=`pkg-config --libs gobject-2.0 gmodule-2.0 gnt` -pg
+
+EXAMPLES=combo focus tv multiwin keys menu
+
+all:
+	make examples
+
+clean:
+	rm -f $(EXAMPLES) *.so wm
+
+WM: wm
+	for i in $(EXAMPLES); do gcc -shared $(CFLAGS) -USTANDALONE $(LDFLAGS) $${i}.c -o $${i}.so ; done
+
+examples: $(EXAMPLES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/combo.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,82 @@
+#include <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntcheckbox.h>
+#include <gntcombobox.h>
+#include <gntlabel.h>
+
+static void
+button_activated(GntWidget *b, GntComboBox *combo)
+{
+	GntWidget *w = b->parent;
+
+	gnt_box_add_widget(GNT_BOX(w),
+			gnt_label_new(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))));
+	fprintf(stderr, "%s\n", gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)));
+	gnt_box_readjust(GNT_BOX(w->parent));
+}
+
+int main()
+{
+	GntWidget *box, *combo, *button;
+	GntWidget *hbox;
+
+#ifdef STANDALONE
+	freopen(".error", "w", stderr);
+	gnt_init();
+#endif
+	
+	box = gnt_box_new(FALSE, TRUE);
+	gnt_widget_set_name(box, "box");
+	gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID);
+	gnt_box_set_pad(GNT_BOX(box), 0);
+
+	gnt_box_set_toplevel(GNT_BOX(box), TRUE);
+	gnt_box_set_title(GNT_BOX(box), "Checkbox");
+
+	hbox = gnt_box_new(FALSE, FALSE);
+	gnt_box_set_pad(GNT_BOX(hbox), 0);
+	gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+	gnt_widget_set_name(hbox, "upper");
+
+	combo = gnt_combo_box_new();
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "1", "1");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "2", "2");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "3", "3abcdefghijklmnopqrstuvwxyz");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "4", "4");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "5", "5");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "6", "6");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "7", "7");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "8", "8");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "9", "9");
+
+	GntWidget *l = gnt_label_new("Select");
+	gnt_box_add_widget(GNT_BOX(hbox), l);
+	gnt_widget_set_size(l, 0, 1);
+	gnt_box_add_widget(GNT_BOX(hbox), combo);
+
+	gnt_box_add_widget(GNT_BOX(box), hbox);
+
+	hbox = gnt_box_new(TRUE, FALSE);
+	gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+	gnt_widget_set_name(hbox, "lower");
+
+	button = gnt_button_new("OK");
+	gnt_box_add_widget(GNT_BOX(hbox), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(button_activated), combo);
+
+	gnt_box_add_widget(GNT_BOX(box), hbox);
+
+	gnt_box_add_widget(GNT_BOX(box), gnt_check_box_new("check box"));
+
+	gnt_widget_show(box);
+
+#ifdef STANDALONE
+	gnt_main();
+
+	gnt_quit();
+#endif
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/focus.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,92 @@
+#include "gntbutton.h"
+#include "gnt.h"
+#include "gntkeys.h"
+#include "gnttree.h"
+#include "gntbox.h"
+#include "gntentry.h"
+#include "gntlabel.h"
+
+static void
+toggled(GntWidget *tree, gpointer key, gpointer null)
+{
+	GntWidget *w = gnt_box_new(FALSE, FALSE);
+
+	gnt_box_set_toplevel(GNT_BOX(w), TRUE);
+
+	gnt_box_add_widget(GNT_BOX(w),
+			gnt_label_new(gnt_tree_get_choice(GNT_TREE(tree), key) ? "Selected" : "NOT"));
+	gnt_widget_show(w);
+}
+
+int main()
+{
+#ifdef STANDALONE
+	freopen(".error", "w", stderr);
+	gnt_init();
+#endif
+	
+	GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\u4e0a1\u6d772\u67003\u4f4e4\u67085\nSo this is, like,\nthe third line!! \\o/");
+	GntWidget *vbox, *hbox, *tree, *box, *button;
+	WINDOW *test;
+
+	vbox = gnt_box_new(FALSE, FALSE);
+	hbox = gnt_box_new(FALSE, TRUE);
+	gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+
+	gnt_widget_set_name(vbox, "vbox");
+	gnt_widget_set_name(hbox, "hbox");
+
+	gnt_box_add_widget(GNT_BOX(hbox), label);
+
+	GntWidget *entry = gnt_entry_new("a");
+	gnt_widget_set_name(entry, "entry");
+	gnt_box_add_widget(GNT_BOX(hbox), entry);
+
+	box = gnt_box_new(FALSE, FALSE);
+	tree = gnt_tree_new();
+	gnt_tree_set_compare_func(GNT_TREE(tree), g_utf8_collate);
+	gnt_widget_set_name(tree, "tree");
+	gnt_box_add_widget(GNT_BOX(box), tree);
+	gnt_box_add_widget(GNT_BOX(hbox), box);
+
+	gnt_tree_add_row_after(GNT_TREE(tree), "c", gnt_tree_create_row(GNT_TREE(tree), "c"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "a", gnt_tree_create_row(GNT_TREE(tree), "a"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "z", gnt_tree_create_row(GNT_TREE(tree), "z"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "y", gnt_tree_create_row(GNT_TREE(tree), "y"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "g", gnt_tree_create_row(GNT_TREE(tree), "g"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "d", gnt_tree_create_row(GNT_TREE(tree), "d"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "x", gnt_tree_create_row(GNT_TREE(tree), "x"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "k", gnt_tree_create_row(GNT_TREE(tree), "k"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "e", gnt_tree_create_row(GNT_TREE(tree), "e"), "a", NULL);
+	gnt_tree_add_choice(GNT_TREE(tree), "b", gnt_tree_create_row(GNT_TREE(tree), "b"), "d", NULL);
+
+	GNT_WIDGET_UNSET_FLAGS(hbox, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW);
+	gnt_box_set_title(GNT_BOX(hbox), "\u4e0a\u6d77\u6700\u4f4e\u6708\u5de5 \u4e0a\u6d77\u6700\u4f4e\u6708\u5de5 ……\u4e0a\u6d77\u6700\u4f4e\u6708\u5de5 …");
+
+	g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(toggled), NULL);
+
+	button = gnt_button_new("one");
+	gnt_widget_set_name(button, "one");
+	gnt_box_add_widget(GNT_BOX(vbox), button);
+
+	button = gnt_button_new("two");
+	gnt_widget_set_name(button, "two");
+	gnt_box_add_widget(GNT_BOX(vbox), button);
+
+	button = gnt_button_new("three");
+	gnt_widget_set_name(button, "three");
+	gnt_box_add_widget(GNT_BOX(vbox), button);
+
+	gnt_box_add_widget(GNT_BOX(hbox), vbox);
+	
+	gnt_widget_show(hbox);
+
+#ifdef STANDALONE
+	gnt_main();
+
+	gnt_quit();
+#endif
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/key.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,18 @@
+#include <ncurses.h>
+
+int main()
+{
+	int ch;
+	initscr();
+
+	noecho();
+
+	while ((ch = getch()) != 27) {
+		printw("%d ", ch);
+		refresh();
+	}
+
+	endwin();
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/keys.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,60 @@
+#include <gnt.h>
+#include <gntbox.h>
+#include <gntentry.h>
+#include <gntlabel.h>
+
+static gboolean
+print_keycode(GntEntry *entry, const char *text, gpointer null)
+{
+	char *s = g_strdup_printf("%s ", text);
+	gnt_entry_set_text(entry, s);
+	g_free(s);
+	if (text[0] == 27)
+	{
+		if (strncmp(text + 1, "[M ", 3) == 0)
+		{
+			int x = (unsigned)text[4];
+			int y = (unsigned)text[5];
+			if (x < 0)	x += 256;
+			if (y < 0)	y += 256;
+			x -= 33;
+			y -= 33;
+			s = g_strdup_printf("ldown %d %d", x, y);
+			gnt_entry_set_text(entry, s);
+			g_free(s);
+		}
+		else if (strncmp(text + 1, "[M#", 3) == 0)
+			gnt_entry_set_text(entry, "up");
+		else
+			return FALSE;
+		return TRUE;
+	}
+	else
+		return TRUE;
+}
+
+int main()
+{
+	GntWidget *window, *entry;
+
+	gnt_init();
+
+	freopen(".error", "w", stderr);
+
+	window = gnt_hbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
+
+	gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Press any key: "));
+
+	entry = gnt_entry_new(NULL);
+	gnt_box_add_widget(GNT_BOX(window), entry);
+	g_signal_connect(G_OBJECT(entry), "key_pressed", G_CALLBACK(print_keycode), NULL);
+
+	gnt_widget_set_position(window, getmaxx(stdscr) / 2 - 12, getmaxy(stdscr) / 2 - 3);
+	gnt_widget_show(window);
+
+	gnt_main();
+	gnt_quit();
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/menu.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,64 @@
+#include "gnt.h"
+#include "gntbox.h"
+#include "gntlabel.h"
+#include "gntmenu.h"
+#include "gntmenuitem.h"
+#include "gntwindow.h"
+
+void dothis(GntMenuItem *item, gpointer null)
+{
+	GntWidget *w = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(w), TRUE);
+	gnt_box_add_widget(GNT_BOX(w),
+			gnt_label_new("Callback to a menuitem"));
+	gnt_widget_show(w);
+}
+
+int main()
+{
+	freopen(".error", "w", stderr);
+	gnt_init();
+
+	GntWidget *menu = gnt_menu_new(GNT_MENU_TOPLEVEL);
+	GObject *item = gnt_menuitem_new("File");
+
+	gnt_menu_add_item(GNT_MENU(menu), GNT_MENUITEM(item));
+
+	item = gnt_menuitem_new("Edit");
+	gnt_menu_add_item(GNT_MENU(menu), GNT_MENUITEM(item));
+
+	item = gnt_menuitem_new("Help");
+	gnt_menu_add_item(GNT_MENU(menu), GNT_MENUITEM(item));
+
+	GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
+	gnt_menuitem_set_submenu(GNT_MENUITEM(item), GNT_MENU(sub));
+
+	item = gnt_menuitem_new("Online Help");
+	gnt_menu_add_item(GNT_MENU(sub), GNT_MENUITEM(item));
+
+	item = gnt_menuitem_new("About");
+	gnt_menu_add_item(GNT_MENU(sub), GNT_MENUITEM(item));
+
+	sub = gnt_menu_new(GNT_MENU_POPUP);
+	gnt_menuitem_set_submenu(GNT_MENUITEM(item), GNT_MENU(sub));
+
+	item = gnt_menuitem_new("Online Help");
+	gnt_menu_add_item(GNT_MENU(sub), GNT_MENUITEM(item));
+	gnt_menuitem_set_callback(GNT_MENUITEM(item), dothis, NULL);
+
+	gnt_screen_menu_show(menu);
+
+	GntWidget *win = gnt_window_new();
+	gnt_box_add_widget(GNT_BOX(win),
+		gnt_label_new("..."));
+	gnt_box_set_title(GNT_BOX(win), "Title");
+	gnt_window_set_menu(GNT_WINDOW(win), GNT_MENU(menu));
+	gnt_widget_show(win);
+
+	gnt_main();
+
+	gnt_quit();
+
+	return  0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/multiwin.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,87 @@
+#include "gnt.h"
+#include "gntbutton.h"
+#include "gntentry.h"
+#include "gntkeys.h"
+#include "gntlabel.h"
+#include "gnttree.h"
+#include "gntbox.h"
+
+gboolean show(GntWidget *w)
+{
+	return FALSE;
+}
+
+int main()
+{
+#ifdef STANDALONE
+	freopen(".error", "w", stderr);
+	gnt_init();
+#endif
+
+	GntWidget *hbox, *tree, *box2;
+
+	hbox = gnt_box_new(FALSE, TRUE);
+	box2 = gnt_box_new(FALSE, TRUE);
+
+	gnt_widget_set_name(hbox, "hbox");
+	gnt_widget_set_name(box2, "box2");
+
+	tree = gnt_tree_new_with_columns(3);
+	GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER);
+	gnt_tree_set_column_titles(GNT_TREE(tree), "12345678901234567890", "column 2", "column3");
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+	gnt_widget_set_name(tree, "tree");
+	gnt_box_add_widget(GNT_BOX(hbox), tree);
+
+	gnt_box_set_toplevel(GNT_BOX(hbox), TRUE);
+	gnt_box_set_title(GNT_BOX(hbox), "Testing the tree widget");
+
+	gnt_box_set_toplevel(GNT_BOX(box2), TRUE);
+	gnt_box_set_title(GNT_BOX(box2), "On top");
+
+	gnt_box_add_widget(GNT_BOX(box2), gnt_label_new("asdasd"));
+	gnt_box_add_widget(GNT_BOX(box2), gnt_entry_new(NULL));
+
+	gnt_widget_show(hbox);
+	gnt_widget_set_position(box2, 80, 40);
+	gnt_widget_show(box2);
+
+	gnt_tree_add_row_after(GNT_TREE(tree), "a",
+			gnt_tree_create_row(GNT_TREE(tree), "alaskdjfkashfashfah kfalkdhflsiafhlasf", " long text", "a2"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "c",
+			gnt_tree_create_row(GNT_TREE(tree), "casdgertqhyeqgasfeytwfga fg arf  agfwa ", " long text", "a2"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "d", gnt_tree_create_row(GNT_TREE(tree), "d", " long text", "a2"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "e", gnt_tree_create_row(GNT_TREE(tree), "e", " long text", "a2"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "b", gnt_tree_create_row(GNT_TREE(tree), "b", "this is", "a2"), "d", NULL);
+
+	gnt_tree_add_choice(GNT_TREE(tree), "1", gnt_tree_create_row(GNT_TREE(tree), "1", " long text", "a2"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "2", gnt_tree_create_row(GNT_TREE(tree), "2", " long text", "a2"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "3", gnt_tree_create_row(GNT_TREE(tree), "3", " long text", "a2"), NULL, NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "4", gnt_tree_create_row(GNT_TREE(tree), "4", " long text", "a2"), "a", NULL);
+	gnt_tree_add_row_after(GNT_TREE(tree), "5", gnt_tree_create_row(GNT_TREE(tree), "5", " long text", "a2"), "d", NULL);
+
+	gnt_tree_add_row_after(GNT_TREE(tree), "6", gnt_tree_create_row(GNT_TREE(tree), "6", " long text", "a2"), "4", NULL);
+
+	int i;
+	for (i = 110; i < 430; i++)
+	{
+		char *s;
+		s = g_strdup_printf("%d", i); /* XXX: yes, leaking */
+		gnt_tree_add_row_after(GNT_TREE(tree), s, gnt_tree_create_row(GNT_TREE(tree), s, " long text", "a2"), "4", NULL);
+	}
+
+	gnt_tree_set_row_flags(GNT_TREE(tree), "e", GNT_TEXT_FLAG_DIM);
+
+	gnt_tree_set_selected(GNT_TREE(tree), "2");
+
+	g_timeout_add(5000, (GSourceFunc)show, box2);
+
+#ifdef STANDALONE
+	gnt_main();
+
+	gnt_quit();
+#endif
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/tv.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,106 @@
+#include "gntbutton.h"
+#include "gnt.h"
+#include "gntkeys.h"
+#include "gnttree.h"
+#include "gntbox.h"
+#include "gntentry.h"
+#include "gnttextview.h"
+
+static gboolean
+key_pressed(GntWidget *w, const char *key, GntWidget *view)
+{
+	if (key[0] == '\r' && key[1] == 0)
+	{
+		gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view),
+				gnt_entry_get_text(GNT_ENTRY(w)),
+				GNT_TEXT_FLAG_UNDERLINE | GNT_TEXT_FLAG_HIGHLIGHT);
+		gnt_entry_add_to_history(GNT_ENTRY(w), gnt_entry_get_text(GNT_ENTRY(w)));
+		gnt_text_view_next_line(GNT_TEXT_VIEW(view));
+		gnt_entry_clear(GNT_ENTRY(w));
+		if (gnt_text_view_get_lines_below(GNT_TEXT_VIEW(view)) <= 1)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(view), 0);
+		gnt_entry_remove_suggest(GNT_ENTRY(w), "acb");
+
+		return TRUE;
+	}
+	else if (key[0] == 27)
+	{
+		if (strcmp(key, GNT_KEY_UP) == 0)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(view), -1);
+		else if (strcmp(key, GNT_KEY_DOWN) == 0)
+			gnt_text_view_scroll(GNT_TEXT_VIEW(view), 1);
+		else
+			return FALSE;
+		return TRUE;
+	}
+		
+	return FALSE;
+}
+
+int main()
+{
+	GntWidget *hbox, *entry, *view;
+
+#ifdef STANDALONE
+	freopen(".error", "w", stderr);
+
+	gnt_init();
+#endif
+
+	hbox = gnt_box_new(FALSE, TRUE);
+	gnt_widget_set_name(hbox, "hbox");
+	gnt_box_set_toplevel(GNT_BOX(hbox), TRUE);
+	gnt_box_set_fill(GNT_BOX(hbox), FALSE);
+	gnt_box_set_title(GNT_BOX(hbox), "Textview test");
+	gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID);
+
+	entry = gnt_entry_new(NULL);
+	gnt_widget_set_name(entry, "entry");
+	GNT_WIDGET_SET_FLAGS(entry, GNT_WIDGET_CAN_TAKE_FOCUS);
+
+	gnt_entry_set_word_suggest(GNT_ENTRY(entry), TRUE);
+	gnt_entry_set_always_suggest(GNT_ENTRY(entry), FALSE);
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "a");
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "ab");
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "abe");
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "abc");
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "abcde");
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "abcd");
+	gnt_entry_add_suggest(GNT_ENTRY(entry), "acb");
+
+	view = gnt_text_view_new();
+	gnt_widget_set_name(view, "view");
+
+	gnt_widget_set_size(view, 20, 15);
+	gnt_widget_set_size(entry, 20, 1);
+
+	gnt_box_add_widget(GNT_BOX(hbox), view);
+	gnt_box_add_widget(GNT_BOX(hbox), entry);
+	gnt_box_add_widget(GNT_BOX(hbox), gnt_button_new("OK"));
+
+	gnt_widget_show(hbox);
+
+	gnt_entry_set_history_length(GNT_ENTRY(entry), -1);
+	g_signal_connect_after(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), view);
+
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 1st line\n", GNT_TEXT_FLAG_NORMAL);
+
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 2nd line\n", GNT_TEXT_FLAG_NORMAL);
+
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 3rd line\n", GNT_TEXT_FLAG_NORMAL);
+
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD);
+	gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 4th line\n", GNT_TEXT_FLAG_NORMAL);
+
+#ifdef STANDALONE
+	gnt_main();
+
+	gnt_quit();
+#endif
+
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/test/wm.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,67 @@
+#include <gmodule.h>
+
+#include <gnt.h>
+#include <gntbox.h>
+#include <gntentry.h>
+#include <gntlabel.h>
+
+static gboolean
+key_pressed(GntEntry *entry, const char *text, gpointer null)
+{
+	if (*text != '\r')
+		return FALSE;
+
+	{
+		const char *cmd;
+		void *handle;
+		void (*func)();
+
+		cmd = gnt_entry_get_text(entry);
+		handle = g_module_open(cmd, G_MODULE_BIND_LOCAL);
+		if (handle && g_module_symbol(handle, "main", (gpointer)&func))
+		{
+			char *argv[] = {cmd, NULL};
+			gnt_entry_clear(entry);
+			func(1, argv);
+		}
+		else
+		{
+			GntWidget *widget = gnt_vbox_new(FALSE);
+			gnt_box_set_toplevel(GNT_BOX(widget), TRUE);
+			gnt_box_set_title(GNT_BOX(widget), "Error");
+			gnt_box_add_widget(GNT_BOX(widget), gnt_label_new("Could not execute."));
+			gnt_box_add_widget(GNT_BOX(widget), gnt_label_new(g_module_error()));
+
+			gnt_widget_show(widget);
+		}
+	}
+	
+	return TRUE;
+}
+
+int main()
+{
+	GntWidget *window, *entry;
+
+	freopen(".error", "w", stderr);
+
+	gnt_init();
+
+	window = gnt_hbox_new(FALSE);
+
+	gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Command"));
+
+	entry = gnt_entry_new(NULL);
+	g_signal_connect(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), NULL);
+	gnt_box_add_widget(GNT_BOX(window), entry);
+
+	gnt_widget_set_position(window, 0, getmaxy(stdscr) - 2);
+	gnt_widget_show(window);
+
+	gnt_main();
+
+	gnt_quit();
+	
+	return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/wms/Makefile.am	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,26 @@
+s_la_LDFLAGS             = -module -avoid-version
+
+plugin_LTLIBRARIES = \
+	s.la
+
+plugindir = $(libdir)/gaim
+
+s_la_SOURCES = s.c
+s_la_LIBADD =  \
+  $(GLIB_LIBS) \
+  $(top_builddir)/console/libgnt/libgnt.la \
+  $(top_builddir)/libgaim/libgaim.la
+
+EXTRA_DIST = 
+
+AM_CPPFLAGS = \
+	-DDATADIR=\"$(datadir)\" \
+	-DVERSION=\"$(VERSION)\" \
+	-I$(top_srcdir)/libgaim \
+	-I$(top_srcdir)/console \
+	-I$(top_srcdir)/console/libgnt \
+	$(DEBUG_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(GNT_CFLAGS) \
+	$(PLUGIN_CFLAGS)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/wms/s.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,216 @@
+#include "gnt.h"
+#include "gntbox.h"
+#include "gntmenu.h"
+#include "gntstyle.h"
+#include "gntwm.h"
+
+#include "blist.h"
+
+#include <string.h>
+
+#define TYPE_S				(s_get_gtype())
+
+typedef struct _S
+{
+	GntWM inherit;
+} S;
+
+typedef struct _SClass
+{
+	GntWMClass inherit;
+} SClass;
+
+GType s_get_gtype(void);
+void gntwm_init(GntWM **wm);
+
+static void (*org_new_window)(GntWM *wm, GntWidget *win);
+
+static void
+envelope_buddylist(GntWidget *win)
+{
+	int w, h;
+	gnt_widget_get_size(win, &w, &h);
+	wresize(win->window, h, w + 1);
+	mvwvline(win->window, 0, w, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), h);
+	touchwin(win->window);
+}
+
+static void
+envelope_normal_window(GntWidget *win)
+{
+	int w, h;
+
+	if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT))
+		return;
+
+	gnt_widget_get_size(win, &w, &h);
+	wbkgdset(win->window, ' ' | COLOR_PAIR(GNT_COLOR_NORMAL));
+	mvwprintw(win->window, 0, w - 4, "[X]");
+}
+
+static void
+s_decorate_window(GntWM *wm, GntWidget *win)
+{
+	const char *name;
+
+	name = gnt_widget_get_name(win);
+	if (name && strcmp(name, "buddylist") == 0) {
+		envelope_buddylist(win);
+	} else {
+		envelope_normal_window(win);
+	}
+}
+
+static void
+s_window_update(GntWM *wm, GntNode *node)
+{
+	s_decorate_window(wm, node->me);
+}
+
+static void
+s_new_window(GntWM *wm, GntWidget *win)
+{
+	int x, y, w, h;
+	int maxx, maxy;
+	const char *name;
+	gboolean blist = FALSE;
+
+	if (!GNT_IS_MENU(win)) {
+		getmaxyx(stdscr, maxy, maxx);
+
+		gnt_widget_get_position(win, &x, &y);
+		gnt_widget_get_size(win, &w, &h);
+
+		name = gnt_widget_get_name(win);
+
+		if (name && strcmp(name, "buddylist") == 0) {
+			/* The buddylist doesn't have no border nor nothing! */
+			x = 0;
+			y = 0;
+			h = maxy - 1;
+			blist = TRUE;
+
+			gnt_box_set_toplevel(GNT_BOX(win), FALSE);
+			GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_CAN_TAKE_FOCUS);
+
+			gnt_widget_set_position(win, x, y);
+			mvwin(win->window, y, x);
+
+			gnt_widget_set_size(win, -1, h + 2);  /* XXX: Why is the +2 needed here? -- sadrul */
+		} else if (!GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_TRANSIENT)) {
+			const char *title = GNT_BOX(win)->title;
+			if (title == NULL || !g_hash_table_lookup(wm->positions, title)) {
+				/* In the middle of the screen */
+				x = (maxx - w) / 2;
+				y = (maxy - h) / 2;
+
+				gnt_widget_set_position(win, x, y);
+				mvwin(win->window, y, x);
+			}
+		}
+	}
+	org_new_window(wm, win);
+
+	if (blist)
+		gnt_wm_raise_window(wm, win);
+}
+
+static GntWidget *
+find_widget(GntWM *wm, const char *wname)
+{
+	const GList *iter = wm->list;
+	for (; iter; iter = iter->next) {
+		GntWidget *widget = iter->data;
+		const char *name = gnt_widget_get_name(widget);
+		if (name && strcmp(name, wname) == 0) {
+			return widget;
+		}
+	}
+	return NULL;
+}
+
+static gboolean
+s_mouse_clicked(GntWM *wm, GntMouseEvent event, int cx, int cy, GntWidget *widget)
+{
+	int x, y, w, h;
+
+	if (!widget)
+		return FALSE;
+		/* This might be a place to bring up a context menu */
+	
+	if (event != GNT_LEFT_MOUSE_DOWN ||
+			GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))
+		return FALSE;
+	
+	gnt_widget_get_position(widget, &x, &y);
+	gnt_widget_get_size(widget, &w, &h);
+
+	if (cy == y && cx == x + w - 3) {
+		gnt_widget_destroy(widget);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+toggle_buddylist(GntBindable *bindable, GList *null)
+{
+	GntWM *wm = GNT_WM(bindable);
+	GntWidget *blist = find_widget(wm, "buddylist");
+	if (blist)
+		gnt_widget_destroy(blist);
+	else
+		gaim_blist_show();
+	return TRUE;
+}
+
+static void
+s_class_init(SClass *klass)
+{
+	GntWMClass *pclass = GNT_WM_CLASS(klass);
+
+	org_new_window = pclass->new_window;
+
+	pclass->new_window = s_new_window;
+	pclass->decorate_window = s_decorate_window;
+	pclass->window_update = s_window_update;
+	pclass->mouse_clicked = s_mouse_clicked;
+
+	gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-buddylist",
+				toggle_buddylist, "\033" "b", NULL);
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
+	GNTDEBUG;
+}
+
+void gntwm_init(GntWM **wm)
+{
+	*wm = g_object_new(TYPE_S, NULL);
+}
+
+GType s_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(SClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)s_class_init,
+			NULL,
+			NULL,                   /* class_data		*/
+			sizeof(S),
+			0,                      /* n_preallocs		*/
+			NULL,	            /* instance_init	*/
+			NULL
+		};
+
+		type = g_type_register_static(GNT_TYPE_WM,
+									  "GntS",
+									  &info, 0);
+	}
+
+	return type;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/plugins/Makefile.am	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,51 @@
+gntgf_la_LDFLAGS      = -module -avoid-version
+gnthistory_la_LDFLAGS = -module -avoid-version
+gntlastlog_la_LDFLAGS    = -module -avoid-version
+
+if PLUGINS
+
+plugin_LTLIBRARIES = \
+	gntgf.la \
+	gnthistory.la \
+	gntlastlog.la
+
+plugindir = $(libdir)/gaim
+
+gntgf_la_SOURCES      = gntgf.c
+gnthistory_la_SOURCES = gnthistory.c
+gntlastlog_la_SOURCES = lastlog.c
+
+gntgf_la_CFLAGS = $(X11_CFLAGS)
+
+gntgf_la_LIBADD       = $(GLIB_LIBS) $(X11_LIBS) $(top_builddir)/console/libgnt/libgnt.la
+gnthistory_la_LIBADD  = $(GLIB_LIBS)
+gntlastlog_la_LIBADD  = $(GLIB_LIBS)
+
+endif # PLUGINS
+
+EXTRA_DIST = 
+
+AM_CPPFLAGS = \
+	-DDATADIR=\"$(datadir)\" \
+	-DVERSION=\"$(VERSION)\" \
+	-I$(top_builddir)/libgaim \
+	-I$(top_srcdir)/libgaim \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/console \
+	-I$(top_srcdir)/console/libgnt \
+	$(DEBUG_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(GNT_CFLAGS) \
+	$(PLUGIN_CFLAGS)
+
+#
+# This part allows people to build their own plugins in here.
+# Yes, it's a mess.
+#
+SUFFIXES = .c .so
+.c.so:
+	$(LIBTOOL) --mode=compile $(CC) -DHAVE_CONFIG_H -I$(top_srcdir) $(AM_CPPFLAGS) $(CFLAGS) -c $< -o tmp$@.lo $(PLUGIN_CFLAGS)
+	$(LIBTOOL) --mode=link    $(CC) $(CFLAGS) -o libtmp$@.la -rpath $(plugindir) tmp$@.lo $(LIBS) $(LDFLAGS) -module -avoid-version $(PLUGIN_LIBS)
+	@rm -f tmp$@.lo tmp$@.o libtmp$@.la
+	@cp .libs/libtmp$@.so* $@
+	@rm -f .libs/libtmp$@.*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/plugins/gntgf.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,390 @@
+/**
+ * @file gntgf.c Minimal toaster plugin in Gnt.
+ *
+ * Copyright (C) 2006 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
+ *
+ * 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 "internal.h"
+
+#define PLUGIN_STATIC_NAME	"GntGf"
+
+#define PREFS_PREFIX          "/plugins/gnt/gntgf"
+#define PREFS_EVENT           PREFS_PREFIX "/events"
+#define PREFS_EVENT_SIGNONF   PREFS_EVENT "/signonf"
+#define PREFS_EVENT_IM_MSG    PREFS_EVENT "/immsg"
+#define PREFS_EVENT_CHAT_MSG  PREFS_EVENT "/chatmsg"
+#define PREFS_EVENT_CHAT_NICK PREFS_EVENT "/chatnick"
+#define PREFS_BEEP            PREFS_PREFIX "/beep"
+
+#define MAX_COLS	3
+
+#ifdef HAVE_X11
+#define PREFS_URGENT          PREFS_PREFIX "/urgent"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+
+#include <glib.h>
+
+#include <plugin.h>
+#include <version.h>
+#include <blist.h>
+#include <conversation.h>
+#include <debug.h>
+#include <util.h>
+
+#include <gnt.h>
+#include <gntbox.h>
+#include <gntbutton.h>
+#include <gntcheckbox.h>
+#include <gntlabel.h>
+#include <gnttree.h>
+
+#include <gntplugin.h>
+
+typedef struct
+{
+	GntWidget *window;
+	int timer;
+	int column;
+} GntToast;
+
+static GList *toasters;
+static int gpsy[MAX_COLS];
+static int gpsw[MAX_COLS];
+
+static void
+destroy_toaster(GntToast *toast)
+{
+	toasters = g_list_remove(toasters, toast);
+	gnt_widget_destroy(toast->window);
+	g_source_remove(toast->timer);
+	g_free(toast);
+}
+
+static gboolean
+remove_toaster(GntToast *toast)
+{
+	GList *iter;
+	int h;
+	int col;
+	int nwin[MAX_COLS];
+
+	gnt_widget_get_size(toast->window, NULL, &h);
+	gpsy[toast->column] -= h;
+	col = toast->column;
+
+	memset(&nwin, 0, sizeof(nwin));
+	destroy_toaster(toast);
+
+	for (iter = toasters; iter; iter = iter->next)
+	{
+		int x, y;
+		toast = iter->data;
+		nwin[toast->column]++;
+		if (toast->column != col) continue;
+		gnt_widget_get_position(toast->window, &x, &y);
+		y += h;
+		gnt_screen_move_widget(toast->window, x, y);
+	}
+
+	if (nwin[col] == 0)
+		gpsw[col] = 0;
+
+	return FALSE;
+}
+
+#ifdef HAVE_X11
+static void
+urgent()
+{
+	/* This is from deryni/tuomov's urgent_test.c */
+	Display *dpy;
+	Window id;
+	const char *ids;
+	XWMHints *hints;
+
+	ids = getenv("WINDOWID");
+	if (ids == NULL)
+		return;
+	
+	id = atoi(ids);
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL)
+		return;
+
+	hints = XGetWMHints(dpy, id);
+	hints->flags|=XUrgencyHint;
+	XSetWMHints(dpy, id, hints);
+
+	XFlush(dpy);
+	XCloseDisplay(dpy);
+}
+#endif
+
+static void
+notify(const char *fmt, ...)
+{
+	GntWidget *window;
+	GntToast *toast;
+	char *str;
+	int h, w, i;
+	va_list args;
+
+	if (gaim_prefs_get_bool(PREFS_BEEP))
+		beep();
+#ifdef HAVE_X11
+	if (gaim_prefs_get_bool(PREFS_URGENT))
+		urgent();
+#endif
+
+	window = gnt_vbox_new(FALSE);
+	GNT_WIDGET_SET_FLAGS(window, GNT_WIDGET_TRANSIENT);
+	GNT_WIDGET_UNSET_FLAGS(window, GNT_WIDGET_NO_BORDER);
+
+	va_start(args, fmt);
+	str = g_strdup_vprintf(fmt, args);
+	va_end(args);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new_with_format(str, GNT_TEXT_FLAG_HIGHLIGHT));
+
+	g_free(str);
+	gnt_widget_size_request(window);
+	gnt_widget_get_size(window, &w, &h);
+	for (i = 0; i < MAX_COLS && gpsy[i] + h >= getmaxy(stdscr) ; ++i)
+		;
+	if (i >= MAX_COLS) {
+		gaim_debug_warning("GntGf", "Dude, that's way too many popups\n");
+		gnt_widget_destroy(window);
+		return;
+	}
+
+	toast = g_new0(GntToast, 1);
+	toast->window = window;
+	toast->column = i;
+	gpsy[i] += h;
+	if (w > gpsw[i]) {
+		if (i == 0)
+			gpsw[i] = w;
+		else
+			gpsw[i] = gpsw[i - 1] + w + 1;
+	}
+
+	if (i == 0 || (w + gpsw[i - 1] >= getmaxx(stdscr))) {
+		/* if it's going to be too far left, overlap. */
+		gnt_widget_set_position(window, getmaxx(stdscr) - w - 1,
+				getmaxy(stdscr) - gpsy[i] - 1);
+	} else {
+		gnt_widget_set_position(window, getmaxx(stdscr) - gpsw[i - 1] - w - 1,
+				getmaxy(stdscr) - gpsy[i] - 1);
+	}
+	gnt_widget_draw(window);
+
+	toast->timer = g_timeout_add(4000, (GSourceFunc)remove_toaster, toast);
+	toasters = g_list_prepend(toasters, toast);
+}
+
+static void
+buddy_signed_on(GaimBuddy *buddy, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_SIGNONF))
+		notify(_("%s just signed on"), gaim_buddy_get_alias(buddy));
+}
+
+static void
+buddy_signed_off(GaimBuddy *buddy, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_SIGNONF))
+		notify(_("%s just signed off"), gaim_buddy_get_alias(buddy));
+}
+
+static void
+received_im_msg(GaimAccount *account, const char *sender, const char *msg,
+		GaimConversation *conv, GaimMessageFlags flags, gpointer null)
+{
+	if (gaim_prefs_get_bool(PREFS_EVENT_IM_MSG))
+		notify(_("%s sent you a message"), sender);
+}
+
+static void
+received_chat_msg(GaimAccount *account, const char *sender, const char *msg,
+		GaimConversation *conv, GaimMessageFlags flags, gpointer null)
+{
+	const char *nick;
+
+	if (flags & GAIM_MESSAGE_WHISPER)
+		return;
+	
+	nick = GAIM_CONV_CHAT(conv)->nick;
+
+	if (g_utf8_collate(sender, nick) == 0)
+		return;
+
+	if (gaim_prefs_get_bool(PREFS_EVENT_CHAT_NICK) &&
+			(gaim_utf8_has_word(msg, nick)))
+		notify(_("%s said your nick in %s"), sender, gaim_conversation_get_name(conv));
+	else if (gaim_prefs_get_bool(PREFS_EVENT_CHAT_MSG))
+		notify(_("%s sent a message in %s"), sender, gaim_conversation_get_name(conv));
+}
+
+static gboolean
+plugin_load(GaimPlugin *plugin)
+{
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", plugin,
+			GAIM_CALLBACK(buddy_signed_on), NULL);
+	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", plugin,
+			GAIM_CALLBACK(buddy_signed_off), NULL);
+	gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", plugin,
+			GAIM_CALLBACK(received_im_msg), NULL);
+	gaim_signal_connect(gaim_conversations_get_handle(), "received-chat-msg", plugin,
+			GAIM_CALLBACK(received_chat_msg), NULL);
+
+	memset(&gpsy, 0, sizeof(gpsy));
+	memset(&gpsw, 0, sizeof(gpsw));
+
+	return TRUE;
+}
+
+static gboolean
+plugin_unload(GaimPlugin *plugin)
+{
+	while (toasters)
+	{
+		GntToast *toast = toasters->data;
+		destroy_toaster(toast);
+	}
+	return TRUE;
+}
+
+static struct
+{
+	char *pref;
+	char *display;
+} prefs[] =
+{
+	{PREFS_EVENT_SIGNONF, N_("Buddy signs on/off")},
+	{PREFS_EVENT_IM_MSG, N_("You receive an IM")},
+	{PREFS_EVENT_CHAT_MSG, N_("Someone speaks in a chat")},
+	{PREFS_EVENT_CHAT_NICK, N_("Someone says your name in a chat")},
+	{NULL, NULL}
+};
+
+static void
+pref_toggled(GntTree *tree, char *key, gpointer null)
+{
+	gaim_prefs_set_bool(key, gnt_tree_get_choice(tree, key));
+}
+
+static void
+toggle_option(GntCheckBox *check, gpointer str)
+{
+	gaim_prefs_set_bool(str, gnt_check_box_get_checked(check));
+}
+
+static GntWidget *
+config_frame()
+{
+	GntWidget *window, *tree, *check;
+	int i;
+
+	window = gnt_vbox_new(FALSE);
+	gnt_box_set_pad(GNT_BOX(window), 0);
+	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
+	gnt_box_set_fill(GNT_BOX(window), TRUE);
+
+	gnt_box_add_widget(GNT_BOX(window),
+			gnt_label_new(_("Notify with a toaster when")));
+
+	tree = gnt_tree_new();
+	gnt_box_add_widget(GNT_BOX(window), tree);
+
+	for (i = 0; prefs[i].pref; i++)
+	{
+		gnt_tree_add_choice(GNT_TREE(tree), prefs[i].pref,
+				gnt_tree_create_row(GNT_TREE(tree), prefs[i].display), NULL, NULL);
+		gnt_tree_set_choice(GNT_TREE(tree), prefs[i].pref,
+				gaim_prefs_get_bool(prefs[i].pref));
+	}
+	gnt_tree_set_col_width(GNT_TREE(tree), 0, 40);
+	g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(pref_toggled), NULL);
+
+	check = gnt_check_box_new(_("Beep too!"));
+	gnt_check_box_set_checked(GNT_CHECK_BOX(check), gaim_prefs_get_bool(PREFS_BEEP));
+	g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(toggle_option), PREFS_BEEP);
+	gnt_box_add_widget(GNT_BOX(window), check);
+
+#ifdef HAVE_X11
+	check = gnt_check_box_new(_("Set URGENT for the terminal window."));
+	gnt_check_box_set_checked(GNT_CHECK_BOX(check), gaim_prefs_get_bool(PREFS_URGENT));
+	g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(toggle_option), PREFS_URGENT);
+	gnt_box_add_widget(GNT_BOX(window), check);
+#endif
+
+	return window;
+}
+
+static GaimPluginInfo info =
+{
+	GAIM_PLUGIN_MAGIC,
+	GAIM_MAJOR_VERSION,
+	GAIM_MINOR_VERSION,
+	GAIM_PLUGIN_STANDARD,
+	GAIM_GNT_PLUGIN_TYPE,
+	0,
+	NULL,
+	GAIM_PRIORITY_DEFAULT,
+	"gntgf",
+	N_("GntGf"),
+	VERSION,
+	N_("Toaster plugin for Gaim-Text."),
+	N_("Toaster plugin for Gaim-Text."),
+	"Sadrul H Chowdhury <sadrul@users.sourceforge.net>",
+	"http://gaim.sourceforge.net",
+	plugin_load,
+	plugin_unload,
+	NULL,
+	config_frame,
+	NULL,
+	NULL,
+	NULL
+};
+
+static void
+init_plugin(GaimPlugin *plugin)
+{
+	gaim_prefs_add_none("/plugins");
+	gaim_prefs_add_none("/plugins/gnt");
+	
+	gaim_prefs_add_none("/plugins/gnt/gntgf");
+	gaim_prefs_add_none(PREFS_EVENT);
+
+	gaim_prefs_add_bool(PREFS_EVENT_SIGNONF, TRUE);
+	gaim_prefs_add_bool(PREFS_EVENT_IM_MSG, TRUE);
+	gaim_prefs_add_bool(PREFS_EVENT_CHAT_MSG, TRUE);
+	gaim_prefs_add_bool(PREFS_EVENT_CHAT_NICK, TRUE);
+
+	gaim_prefs_add_bool(PREFS_BEEP, TRUE);
+#ifdef HAVE_X11
+	gaim_prefs_add_bool(PREFS_URGENT, FALSE);
+#endif
+}
+
+GAIM_INIT_PLUGIN(PLUGIN_STATIC_NAME, init_plugin, info)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/plugins/gnthistory.c	Sun May 20 06:19:49 2007 +0000
@@ -0,0 +1,202 @@
+/**
+ * @file gnthistory.c Show log from previous conversation
+ *
+ * Copyright (C) 2006 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
+ *
+ * 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
+ */
+
+/* Ripped from gtk/plugins/history.c */
+
+#include "internal.h"
+
+#include "conversation.h"
+#include "debug.h"
+#include "log.h"
+#include "notify.h"
+#include "prefs.h"
+#include "signals.h"
+#include "util.h"
+#include "version.h"
+
+#include "gntplugin.h"
+
+#define HISTORY_PLUGIN_ID "gnt-history"
+
+#define HISTORY_SIZE (4 * 1024)
+
+static void historize(GaimConversation *c)
+{
+	GaimAccount *account = gaim_conversation_get_account(c);
+	const char *name = gaim_conversation_get_name(c);
+	GaimConversationType convtype;
+	GList *logs = NULL;
+	const char *alias = name;
+	GaimLogReadFlags flags;
+	char *history;
+	char *header;
+	GaimMessageFlags mflag;
+
+	convtype = gaim_conversation_get_type(c);
+	if (convtype == GAIM_CONV_TYPE_IM)
+	{
+		GSList *buddies;
+		GSList *cur;
+
+		/* If we're not logging, don't show anything.
+		 * Otherwise, we might show a very old log. */
+		if (!gaim_prefs_get_bool("/core/logging/log_ims"))
+			return;
+
+		/* Find buddies for this conversation. */
+	        buddies = gaim_find_buddies(account, name);
+
+		/* If we found at least one buddy, save the first buddy's alias. */
+		if (buddies != NULL)
+			alias = gaim_buddy_get_contact_alias((GaimBuddy *)buddies->data);
+
+	        for (cur = buddies; cur != NULL; cur = cur->next)
+	        {
+	                GaimBlistNode *node = cur->data;
+	                if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
+	                {
+				GaimBlistNode *node2;
+
+				alias = gaim_buddy_get_contact_alias((GaimBuddy *)node);
+
+				/* We've found a buddy that matches this conversation.  It's part of a
+				 * GaimContact with more than one GaimBuddy.  Loop through the GaimBuddies
+				 * in the contact and get all the logs. */
+				for (node2 = node->parent->child ; node2 != NULL ; node2 = node2->next)
+				{
+					logs = g_list_concat(
+						gaim_log_get_logs(GAIM_LOG_IM,
+							gaim_buddy_get_name((GaimBuddy *)node2),
+							gaim_buddy_get_account((GaimBuddy *)node2)),
+						logs);
+				}
+				break;
+	                }
+	        }
+	        g_slist_free(buddies);
+
+		if (logs == NULL)
+			logs = gaim_log_get_logs(GAIM_LOG_IM, name, account);
+		else
+			logs = g_list_sort(logs, gaim_log_compare);
+	}
+	else if (convtype == GAIM_CONV_TYPE_CHAT)
+	{
+		/* If we're not logging, don't show anything.
+		 * Otherwise, we might show a very old log. */
+		if (!gaim_prefs_get_bool("/core/logging/log_chats"))
+			return;
+
+		logs = gaim_log_get_logs(GAIM_LOG_CHAT, name, account);
+	}
+
+	if (logs == NULL)
+		return;
+
+	mflag = GAIM_MESSAGE_NO_LOG | GAIM_MESSAGE_SYSTEM | GAIM_MESSAGE_DELAYED;
+	history = gaim_log_read((GaimLog*)logs->data, &flags);
+
+	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), alias,
+							 gaim_date_format_full(localtime(&((GaimLog *)logs->data)->time)));
+	gaim_conversation_write(c, "", header, mflag, time(NULL));
+	g_free(header);
+
+	if (flags & GAIM_LOG_READ_NO_NEWLINE)
+		gaim_str_strip_char(history, '\n');
+	gaim_conversation_write(c, "", history, mflag, time(NULL));
+	g_free(history);
+
+	gaim_conversation_write(c, "", "<hr>", mflag, time(NULL));
+
+	g_list_foreach(logs, (GFunc)gaim_log_free, NULL);
+	g_list_free(logs);
+}
+
+static void
+history_prefs_check(GaimPlugin *plugin)
+{
+	if (!gaim_prefs_get_bool("/core/logging/log_ims") &&
+	    !gaim_prefs_get_bool("/core/logging/log_chats"))
+	{
+		gaim_notify_warning(plugin, NULL, _("History Plugin Requires Logging"),
+							_("Logging can be enabled from Tools -> Preferences -> Logging.\n\n"
+							  "Enabling logs for instant messages and/or chats will activate "
+							  "history for the same conversation type(s)."));
+	}
+}
+
+static void history_prefs_cb(const char *name, GaimPrefType type,
+							 gconstpointer val, gpointer data)
+{
+	history_prefs_check((GaimPlugin *)data);
+}
+
+static gboolean
+plugin_load(GaimPlugin *plugin)
+{
+	gaim_signal_connect(gaim_conversations_get_handle(),
+						"conversation-created",
+						plugin, GAIM_CALLBACK(historize), NULL);
+
+	gaim_prefs_connect_callback(plugin, "/core/logging/log_ims",
+								history_prefs_cb, plugin);
+	gaim_prefs_connect_callback(plugin, "/core/logging/log_chats",
+								history_prefs_cb, plugin);
+
+	history_prefs_check(plugin);
+
+	return TRUE;
+}
+
+static GaimPluginInfo info =
+{
+	GAIM_PLUGIN_MAGIC,
+	GAIM_MAJOR_VERSION,
+	GAIM_MINOR_VERSION,
+	GAIM_PLUGIN_STANDARD,
+	NULL,
+	0,
+	NULL,
+	GAIM_PRIORITY_DEFAULT,
+	HISTORY_PLUGIN_ID,
+	N_("GntHistory"),
+	VERSION,
+	N_("Shows recently logged conversations in new conversations."),
+	N_("When a new conversation is opened this plugin will insert "
+	   "the last conversation into the current conversation."),
+	"Sean Egan <seanegan@gmail.com>\n"
+	"Sadrul H Chowdhury <sadrul@users.sourceforge.net>",
+	GAIM_WEBSITE,
+	plugin_load,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,