Commit 0b13f24c authored by Konstantin Khomoutov's avatar Konstantin Khomoutov

Imported Upstream version 0.11.0

This diff is collapsed.
This diff is collapsed.
# $Id: Makefile 1458 2008-06-08 13:46:46Z sergei $
PREFIX = /usr/local
TKABBERPLUGINSDIR = $(PREFIX)/share/tkabber-plugins
DOCDIR = $(PREFIX)/share/doc/tkabber-plugins
SUBDIRS = aniemoticons \
attline \
bc \
browser \
checkers \
chess \
ctcomp \
custom-urls \
cyrillize \
debug \
ejabberd \
floatinglog \
georoster \
gmail \
iconsets \
jidlink \
latex \
mute \
openurl \
osd \
presencecmd \
quiz \
receipts \
renju \
reversi \
socials \
spy \
tclchat \
tkabber-khim \
traffic \
unixkeys \
install: install-bin install-doc
echo ""
echo ""
echo ""
echo "To enable desired plugins copy or link their directories to ~/.tkabber/plugins/"
echo ""
echo ""
echo ""
mkdir -p $(DESTDIR)/$(DOCDIR)
.PHONY: install install-bin install-doc
External Plugins for Tkabber
To install the desired plugins copy the plugin directories to
$HOME/.tkabber/plugins (on UNIX), to %APPDATA%\Tkabber\plugins (on Windows),
or to $HOME/Library/Application Support/Tkabber (on MacOS X) directory.
Tkabber will automatically load the plugins when it's started.
The plugins that you will surely want to try are: Chess, GeoRoster
and Whiteboard.
Short Description of the Included Plugins
Plugin which adds support of animated emoticons.
Plugin which draws so-called attention line - a line before the first
message in a chat window where the window has lost keyboard focus. All
messages after the line are unread messages.
A word game. Inludes a russian file.
Plugin which implements Jabber Browser (XEP-0011). This protocol is
deprecated in favor of Service Discovery (XEP-0030), but may be useful
for pre-XMPP servers/transports.
Checkers game for two players (including Straight, Russian,
Spanish, Brazilian, Pool, Italian checkers). When installed,
you can send an invitation to your contact (contextual menu on the
roster). If the other player has also Tkabber and the plugin
installed, he will recieve the invitation. If he accepts, a window
will open on both.
Chess game for two players. When installed, you can send an invitation
to your contact (contextual menu on the roster). If the other player
has also Tkabber and the plugin installed, he will recieve the
invitation. If he accepts, a window will open on both.
Plugin adds support for "text completion" in Tkabber's chat
input windows. The source of completed words is a chat log window.
Provides regexp-based mechanism to convert strings with numbers to URLs
in chat windows.
Utility to translate misprinted characters to cyrillic pressing Ctrl+'.
Allows to see debug messages in separate tab/window.
Utility to check your Ejabberd Jabber server remotely.
Plugin reports incoming messages, presence changes, status changes in a
separate floating window.
World map. It tries to position your contacts using the data on vcard.
You can also drag and drop your contacts from the roster on their
Plugin allows Gmail/Googlemail users to receive mail notifications.
Several iconsets, borrowed from other Jabber clients, now are represented
in this plugin.
Implements Jidlink file transfer protocol. It's undocumented and obsolete,
but may be useful for transferring files to old Tkabber versions.
Displays formulas in LaTeX notation as embedded images, generated
by LaTeX and ImageMagick.
Experimental implementation of XEP-0058: Multi-User Text Editing,
now deferred.
Plugin which adds several items to a URL popup menu. Each item allows to
open the URL in a certain browser.
Displays certain events (presence and chat messages) notification
using osd_cat utility.
Plugin which adds several commands in a chat window. They change user's
presence information (global or directed).
Adaptation of He3hauka (a russian quiz game for IRC).
Gomoku and Renju (in fact, renju is not implemented yet) game for two
players. When installed, you can send an invitation to your contact
(contextual menu on the roster). If the other player has also Tkabber
and the plugin installed, he will recieve the invitation. If he accepts,
a window will open on both.
Reversi (othello) game for two players. When installed, you can send
an invitation to your contact (contextual menu on the roster). If the
other player has also Tkabber and the plugin installed, he will
recieve the invitation. If he accepts, a window will open on both.
Adds many 'social' commands like /dance. Includes english and russian
Logs your contacts presence changes to a window or to a file. Allows
to setup alert window for certain contacts.
Plugin, which makes chatting in Tclers' chat ( easier.
It recognises a bot, which connects Jabber room with IRC channel, and maps
IRC users to Jabber conference participants.
Plugin that adds KHIM (an alternative input method by Kevin Kenny) support
to Tkabber.
Approximately accounts incoming and outgoing XMPP traffic by addressees.
Traffic estimation is good only if no stream compression or encryption
is used. But even if the absolute values are incorrect, it still allows
to find which remote JID consumes the highest traffic amount.
Shared whiteboard, allows two contacts or a whole chatroom to draw
# $Id: aniemoticons.tcl 1001 2007-03-04 10:32:59Z sergei $
namespace eval :: {
source [file join [file dirname [info script]] anigif.tcl]
namespace eval emoticons {
proc create_image {name file} {
if {[catch {::anigif::anigif $name $file} res]} {
image create photo $name -file $file
return $name
} else {
return $res
proc delete_image {name} {
::anigif::destroy $name
# AniGif Package written in pure Tcl/Tk
# anigif.tcl v1.3 2002-09-09 (c) 2001-2002 Ryan Casey
# AniGif is distributed under the same license as Tcl/Tk. As of
# AniGif 1.3, this license is applicable to all previous versions.
# Modified by Alexey Shchepin <>
# ############################### USAGE #################################
# ::anigif::anigif IMAGE FILENAME INDEX
# FILENAME: appropriate path and file to use for the animated gif
# INDEX: what image to begin on (first image is 0) (Default: 0)
# ::anigif::stop IMAGE
# ::anigif::restart IMAGE INDEX
# INDEX: defaults to next index in loop
# ::anigif::destroy IMAGE
# There is currently a -zoom and -subsample hack to keep transparency.
# Anigif does not handle interlaced gifs properly. The image will look
# distorted.
# A delay of 0 renders as fast as possible, per the GIF specification.
# This is currently set to 40 ms to approximate the IE default.
# If you experience a problem with a compressed gif, try uncompressing
# it. Search the web for gifsicle.
# ############################## HISTORY #################################
# 1.3: Fixed error in disposal flag handling.
# Added handling for non-valid comment/graphic blocks.
# Searches for actual loop control block. If it extists, loops.
# Added more comments.
# 1.2: Now handles single playthrough gifs or gifs with partial images
# Fixed bug in delay time (unsigned int was being treated as signed)
# 1.1: Reads default timing instead of 100 ms or user-defined.
# You can no longer set the delay manually.
# 1.0: Moved all anigif variables to the anigif namespace
# 0.9: Initial release
namespace eval ::anigif {
variable image_number 0
proc ::anigif::anigif2 {img list delay {idx 0}} {
if {$idx >= [llength $list]} {
set idx 0
if {$::anigif::img(repeat,$img) == 0} {
# Non-repeating GIF
::anigif::stop $img
set disposal_idx $idx
incr disposal_idx -1
if {$disposal_idx <= 0} {
set disposal_idx 0
if {$idx == 0} {
set dispflag "010"
} else {
set dispflag [lindex $::anigif::img(disposal,$img) $disposal_idx]
switch -- "$dispflag" {
"000" {
# Do nothing
"100" {
# Do not dispose
"010" {
# Restore to background
$::anigif::img(curimage,$img) blank
"110" {
# Restore to previous - not supported
# As recommended, since this is not supported, it is set to blank
[set ::anigif::img(curimage,$img)] blank
default { puts "no match: $dispflag" }
$::anigif::img(curimage,$img) copy [lindex $list $idx]
if {[lindex $delay $idx] == 0} {
::anigif::stop $img
# # # update
set ::anigif::img(asdf,$img) [list ::anigif::anigif2 $img $list]
set ::anigif::img(loop,$img) \
[after [lindex $delay $idx] \
[list eval $::anigif::img(asdf,$img) [list $delay [expr {$idx + 1}]]]]
set ::anigif::img(idx,$img) [incr idx]
proc ::anigif::anigif {img fnam {idx 0}} {
variable image_number
::anigif::stop $img
set n 0
set images {}
set delay {}
set disposal {}
set reserved {}
#set img anigifimage[incr image_number]
#set img [image create photo]
image create photo $img
set fin [open $fnam r]
fconfigure $fin -translation binary
set data [read $fin [file size $fnam]]
close $fin
# Find Loop Record
set start [string first "\x21\xFF\x0B" $data]
if {$start < 0} {
set repeat 0
} else {
set repeat 1
# Find Control Records
set start [string first "\x21\xF9\x04" $data]
while {![catch {image create photo xpic$n$img \
-file $fnam \
-format [list gif89 -index $n]}]} {
set stop [expr $start + 7]
set record [string range $data $start $stop]
binary scan $record @4s thisdelay
if {[info exists thisdelay]} {
# Change to unsigned integer
#set thisdelay [expr {$thisdelay & 0xFF}];
binary scan $record @3b5 disposalval
set disposalval [string range $disposalval 2 end]
lappend images pic$n$img
image create photo pic$n$img
pic$n$img copy xpic$n$img
image delete xpic$n$img
lappend disposal $disposalval
# Convert hundreths to thousandths for after
set thisdelay [expr {$thisdelay * 10}]
# If 0, set to fastest (25 ms min to seem to match browser default)
if {$thisdelay == 0} {set thisdelay 40}
lappend delay $thisdelay
unset thisdelay
incr n
if {($start >= 0) && ($stop >= 0)} {
set start [string first "\x21\xF9\x04" $data [expr {$stop + 1}]]
} else {
set ::anigif::img(repeat,$img) $repeat
set ::anigif::img(delay,$img) $delay
set ::anigif::img(disposal,$img) $disposal
set ::anigif::img(curimage,$img) $img
$img blank
$img copy pic0${img}
#$img configure -image [set ::anigif::img(curimage,$img)]
anigif2 $img $images $delay $idx
return $img
proc ::anigif::stop {img} {
catch {
after cancel $::anigif::img(loop,$img)
proc ::anigif::restart {img {idx -1}} {
if {$idx == -1} {
if {[lindex $::anigif::img(delay,$img) $idx] < 0} {
set idx 0
} else {
set idx $::anigif::img(idx,$img)
catch {
::anigif::stop $img
eval $::anigif::img(asdf,$img) [list $::anigif::img(delay,$img) $idx]
proc ::anigif::destroy {img} {
catch {
::anigif::stop $img
foreach imagename [image names] {
if {[regexp {^pic\d+(.*)} $imagename -> tail] && [string equal $tail $img]} {
image delete $imagename
image delete $img
array unset ::anigif::img *,$img
package provide anigif 2.0
Konstantin Khomoutov <>
As usually, copy this directory under the ~/.tkabber/plugins directory
so that you get a hierarchy like this:
Restart Tkabber, to get the plugin loaded.
Visit the Tkabber->Customize->Chat->Attention Line
block of settings, customize as you wish.
Consult the README file for the details about using this plugin.
$Id: README 1313 2007-11-14 18:43:51Z sergei $
"Attention line" -- chat plugin for Tkabber.
I. The idea
This plugin helps to track discussion flow in high-volume chats
by remembering the last message you have read in each chat
window when you're leaving it and drawing a horizontal line just
below that message when you return back to that chat window.
This line is called the "attention line" since its task is to
draw your attention to the point at which you stopped to attend
the chat when you're back.
"Leaving of the chat window" described above applies not only to
the physical top-level chat windows in windowed mode but
also to switching between chat tabs in tabbed mode. In tabbed
mode leaving the main window is also considered as leaving the
currently active chat tab, if any. So everywhere in this
document, when you see "chat window" you can safely interpret it
as "chat tab" if you're using tabbed mode in Tkabber.
II. Usage
The behaviour of the attention line is governed by its
"expiration timeout". When you switch to a chat window and the
chat log in that window contains unread messages, expiration
line is placed just below the last read message. At that time
the attention line expiration timer starts to tick. If you leave
the chat window again until the timeout expires, the attention
line is left intact as if you haven't switched to that window at
all. Otherwise, if the timeout expires while you're in this chat
window its attention line is considered "expired" and the chat